}
}
+#[derive(Clone, Copy, PartialEq, Hash, Debug)]
+pub enum RelocModel {
+ Static,
+ Pic,
+ DynamicNoPic,
+ Ropi,
+ Rwpi,
+ RopiRwpi,
+}
+
+impl FromStr for RelocModel {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<RelocModel, ()> {
+ Ok(match s {
+ "static" => RelocModel::Static,
+ "pic" => RelocModel::Pic,
+ "dynamic-no-pic" => RelocModel::DynamicNoPic,
+ "ropi" => RelocModel::Ropi,
+ "rwpi" => RelocModel::Rwpi,
+ "ropi-rwpi" => RelocModel::RopiRwpi,
+ _ => return Err(()),
+ })
+ }
+}
+
+impl ToJson for RelocModel {
+ fn to_json(&self) -> Json {
+ match *self {
+ RelocModel::Static => "static",
+ RelocModel::Pic => "pic",
+ RelocModel::DynamicNoPic => "dynamic-no-pic",
+ RelocModel::Ropi => "ropi",
+ RelocModel::Rwpi => "rwpi",
+ RelocModel::RopiRwpi => "ropi-rwpi",
+ }
+ .to_json()
+ }
+}
+
+#[derive(Clone, Copy, PartialEq, Hash, Debug)]
+pub enum TlsModel {
+ GeneralDynamic,
+ LocalDynamic,
+ InitialExec,
+ LocalExec,
+}
+
+impl FromStr for TlsModel {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<TlsModel, ()> {
+ Ok(match s {
+ // Note the difference "general" vs "global" difference. The model name is "general",
+ // but the user-facing option name is "global" for consistency with other compilers.
+ "global-dynamic" => TlsModel::GeneralDynamic,
+ "local-dynamic" => TlsModel::LocalDynamic,
+ "initial-exec" => TlsModel::InitialExec,
+ "local-exec" => TlsModel::LocalExec,
+ _ => return Err(()),
+ })
+ }
+}
+
+impl ToJson for TlsModel {
+ fn to_json(&self) -> Json {
+ match *self {
+ TlsModel::GeneralDynamic => "global-dynamic",
+ TlsModel::LocalDynamic => "local-dynamic",
+ TlsModel::InitialExec => "initial-exec",
+ TlsModel::LocalExec => "local-exec",
+ }
+ .to_json()
+ }
+}
+
pub enum LoadTargetError {
BuiltinTargetNotFound(String),
Other(String),
/// libraries. Defaults to false.
pub executables: bool,
/// Relocation model to use in object file. Corresponds to `llc
- /// -relocation-model=$relocation_model`. Defaults to "pic".
- pub relocation_model: String,
+ /// -relocation-model=$relocation_model`. Defaults to `Pic`.
+ pub relocation_model: RelocModel,
/// Code model to use. Corresponds to `llc -code-model=$code_model`.
pub code_model: Option<String>,
/// TLS model to use. Options are "global-dynamic" (default), "local-dynamic", "initial-exec"
/// and "local-exec". This is similar to the -ftls-model option in GCC/Clang.
- pub tls_model: String,
+ pub tls_model: TlsModel,
/// Do not emit code that uses the "red zone", if the ABI has one. Defaults to false.
pub disable_redzone: bool,
/// Eliminate frame pointers from stack frames if possible. Defaults to true.
dynamic_linking: false,
only_cdylib: false,
executables: false,
- relocation_model: "pic".to_string(),
+ relocation_model: RelocModel::Pic,
code_model: None,
- tls_model: "global-dynamic".to_string(),
+ tls_model: TlsModel::GeneralDynamic,
disable_redzone: false,
eliminate_frame_pointer: true,
function_sections: true,
macro_rules! key {
($key_name:ident) => ( {
let name = (stringify!($key_name)).replace("_", "-");
- obj.find(&name[..]).map(|o| o.as_string()
- .map(|s| base.options.$key_name = s.to_string()));
+ if let Some(s) = obj.find(&name).and_then(Json::as_string) {
+ base.options.$key_name = s.to_string();
+ }
} );
($key_name:ident, bool) => ( {
let name = (stringify!($key_name)).replace("_", "-");
- obj.find(&name[..])
- .map(|o| o.as_boolean()
- .map(|s| base.options.$key_name = s));
+ if let Some(s) = obj.find(&name).and_then(Json::as_boolean) {
+ base.options.$key_name = s;
+ }
} );
($key_name:ident, Option<u64>) => ( {
let name = (stringify!($key_name)).replace("_", "-");
- obj.find(&name[..])
- .map(|o| o.as_u64()
- .map(|s| base.options.$key_name = Some(s)));
+ if let Some(s) = obj.find(&name).and_then(Json::as_u64) {
+ base.options.$key_name = Some(s);
+ }
} );
($key_name:ident, MergeFunctions) => ( {
let name = (stringify!($key_name)).replace("_", "-");
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
+ ($key_name:ident, RelocModel) => ( {
+ let name = (stringify!($key_name)).replace("_", "-");
+ obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
+ match s.parse::<RelocModel>() {
+ Ok(relocation_model) => base.options.$key_name = relocation_model,
+ _ => return Some(Err(format!("'{}' is not a valid relocation model. \
+ Run `rustc --print relocation-models` to \
+ see the list of supported values.", s))),
+ }
+ Some(Ok(()))
+ })).unwrap_or(Ok(()))
+ } );
+ ($key_name:ident, TlsModel) => ( {
+ let name = (stringify!($key_name)).replace("_", "-");
+ obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
+ match s.parse::<TlsModel>() {
+ Ok(tls_model) => base.options.$key_name = tls_model,
+ _ => return Some(Err(format!("'{}' is not a valid TLS model. \
+ Run `rustc --print tls-models` to \
+ see the list of supported values.", s))),
+ }
+ Some(Ok(()))
+ })).unwrap_or(Ok(()))
+ } );
($key_name:ident, PanicStrategy) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
} );
($key_name:ident, list) => ( {
let name = (stringify!($key_name)).replace("_", "-");
- obj.find(&name[..]).map(|o| o.as_array()
- .map(|v| base.options.$key_name = v.iter()
- .map(|a| a.as_string().unwrap().to_string()).collect()
- )
- );
+ if let Some(v) = obj.find(&name).and_then(Json::as_array) {
+ base.options.$key_name = v.iter()
+ .map(|a| a.as_string().unwrap().to_string())
+ .collect();
+ }
} );
($key_name:ident, opt_list) => ( {
let name = (stringify!($key_name)).replace("_", "-");
- obj.find(&name[..]).map(|o| o.as_array()
- .map(|v| base.options.$key_name = Some(v.iter()
- .map(|a| a.as_string().unwrap().to_string()).collect())
- )
- );
+ if let Some(v) = obj.find(&name).and_then(Json::as_array) {
+ base.options.$key_name = Some(v.iter()
+ .map(|a| a.as_string().unwrap().to_string())
+ .collect());
+ }
} );
($key_name:ident, optional) => ( {
let name = (stringify!($key_name)).replace("_", "-");
key!(dynamic_linking, bool);
key!(only_cdylib, bool);
key!(executables, bool);
- key!(relocation_model);
+ key!(relocation_model, RelocModel)?;
key!(code_model, optional);
- key!(tls_model);
+ key!(tls_model, TlsModel)?;
key!(disable_redzone, bool);
key!(eliminate_frame_pointer, bool);
key!(function_sections, bool);