1
Fork 0

Merge remote-tracking branch 'origin/master' into frewsxcv-san

This commit is contained in:
Corey Farwell 2020-12-31 23:27:33 -05:00
commit d482de30ea
1600 changed files with 29527 additions and 21534 deletions

View file

@ -221,6 +221,23 @@ pub enum DebugInfo {
Full,
}
/// Some debuginfo requires link-time relocation and some does not. LLVM can partition the debuginfo
/// into sections depending on whether or not it requires link-time relocation. Split DWARF
/// provides a mechanism which allows the linker to skip the sections which don't require link-time
/// relocation - either by putting those sections into DWARF object files, or keeping them in the
/// object file in such a way that the linker will skip them.
#[derive(Clone, Copy, Debug, PartialEq, Hash)]
pub enum SplitDwarfKind {
/// Disabled.
None,
/// Sections which do not require relocation are written into the object file but ignored
/// by the linker.
Single,
/// Sections which do not require relocation are written into a DWARF object (`.dwo`) file,
/// which is skipped by the linker by virtue of being a different file.
Split,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
#[derive(Encodable, Decodable)]
pub enum OutputType {
@ -533,6 +550,7 @@ impl_stable_hash_via_hash!(OutputFilenames);
pub const RLINK_EXT: &str = "rlink";
pub const RUST_CGU_EXT: &str = "rcgu";
pub const DWARF_OBJECT_EXT: &str = "dwo";
impl OutputFilenames {
pub fn new(
@ -566,7 +584,12 @@ impl OutputFilenames {
self.temp_path_ext(extension, codegen_unit_name)
}
/// Like temp_path, but also supports things where there is no corresponding
/// Like `temp_path`, but specifically for dwarf objects.
pub fn temp_path_dwo(&self, codegen_unit_name: Option<&str>) -> PathBuf {
self.temp_path_ext(DWARF_OBJECT_EXT, codegen_unit_name)
}
/// Like `temp_path`, but also supports things where there is no corresponding
/// OutputType, like noopt-bitcode or lto-bitcode.
pub fn temp_path_ext(&self, ext: &str, codegen_unit_name: Option<&str>) -> PathBuf {
let mut extension = String::new();
@ -593,6 +616,37 @@ impl OutputFilenames {
path.set_extension(extension);
path
}
/// Returns the name of the Split DWARF file - this can differ depending on which Split DWARF
/// mode is being used, which is the logic that this function is intended to encapsulate.
pub fn split_dwarf_filename(
&self,
split_dwarf_kind: SplitDwarfKind,
cgu_name: Option<&str>,
) -> Option<PathBuf> {
self.split_dwarf_path(split_dwarf_kind, cgu_name)
.map(|path| path.strip_prefix(&self.out_directory).unwrap_or(&path).to_path_buf())
}
/// Returns the path for the Split DWARF file - this can differ depending on which Split DWARF
/// mode is being used, which is the logic that this function is intended to encapsulate.
pub fn split_dwarf_path(
&self,
split_dwarf_kind: SplitDwarfKind,
cgu_name: Option<&str>,
) -> Option<PathBuf> {
let obj_out = self.temp_path(OutputType::Object, cgu_name);
let dwo_out = self.temp_path_dwo(cgu_name);
match split_dwarf_kind {
SplitDwarfKind::None => None,
// Single mode doesn't change how DWARF is emitted, but does add Split DWARF attributes
// (pointing at the path which is being determined here). Use the path to the current
// object file.
SplitDwarfKind::Single => Some(obj_out),
// Split mode emits the DWARF into a different file, use that path.
SplitDwarfKind::Split => Some(dwo_out),
}
}
}
pub fn host_triple() -> &'static str {
@ -692,6 +746,10 @@ impl DebuggingOptions {
deduplicate_diagnostics: self.deduplicate_diagnostics,
}
}
pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
self.symbol_mangling_version.unwrap_or(SymbolManglingVersion::Legacy)
}
}
// The type of entry function, so users can have their own entry functions
@ -1296,8 +1354,10 @@ fn parse_output_types(
if !debugging_opts.parse_only {
for list in matches.opt_strs("emit") {
for output_type in list.split(',') {
let mut parts = output_type.splitn(2, '=');
let shorthand = parts.next().unwrap();
let (shorthand, path) = match output_type.split_once('=') {
None => (output_type, None),
Some((shorthand, path)) => (shorthand, Some(PathBuf::from(path))),
};
let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
early_error(
error_format,
@ -1308,7 +1368,6 @@ fn parse_output_types(
),
)
});
let path = parts.next().map(PathBuf::from);
output_types.insert(output_type, path);
}
}
@ -1432,7 +1491,7 @@ fn parse_target_triple(matches: &getopts::Matches, error_format: ErrorOutputType
early_error(error_format, &format!("target file {:?} does not exist", path))
})
}
Some(target) => TargetTriple::TargetTriple(target),
Some(target) => TargetTriple::from_alias(target),
_ => TargetTriple::from_triple(host_triple()),
}
}
@ -1452,11 +1511,10 @@ fn parse_opt_level(
let max_c = matches
.opt_strs_pos("C")
.into_iter()
.flat_map(
|(i, s)| {
if let Some("opt-level") = s.splitn(2, '=').next() { Some(i) } else { None }
},
)
.flat_map(|(i, s)| {
// NB: This can match a string without `=`.
if let Some("opt-level") = s.splitn(2, '=').next() { Some(i) } else { None }
})
.max();
if max_o > max_c {
OptLevel::Default
@ -1491,11 +1549,10 @@ fn select_debuginfo(
let max_c = matches
.opt_strs_pos("C")
.into_iter()
.flat_map(
|(i, s)| {
if let Some("debuginfo") = s.splitn(2, '=').next() { Some(i) } else { None }
},
)
.flat_map(|(i, s)| {
// NB: This can match a string without `=`.
if let Some("debuginfo") = s.splitn(2, '=').next() { Some(i) } else { None }
})
.max();
if max_g > max_c {
DebugInfo::Full
@ -1528,23 +1585,26 @@ fn parse_libs(
.map(|s| {
// Parse string of the form "[KIND=]lib[:new_name]",
// where KIND is one of "dylib", "framework", "static".
let mut parts = s.splitn(2, '=');
let kind = parts.next().unwrap();
let (name, kind) = match (parts.next(), kind) {
(None, name) => (name, NativeLibKind::Unspecified),
(Some(name), "dylib") => (name, NativeLibKind::Dylib),
(Some(name), "framework") => (name, NativeLibKind::Framework),
(Some(name), "static") => (name, NativeLibKind::StaticBundle),
(Some(name), "static-nobundle") => (name, NativeLibKind::StaticNoBundle),
(_, s) => {
early_error(
error_format,
&format!(
"unknown library kind `{}`, expected \
one of dylib, framework, or static",
s
),
);
let (name, kind) = match s.split_once('=') {
None => (s, NativeLibKind::Unspecified),
Some((kind, name)) => {
let kind = match kind {
"dylib" => NativeLibKind::Dylib,
"framework" => NativeLibKind::Framework,
"static" => NativeLibKind::StaticBundle,
"static-nobundle" => NativeLibKind::StaticNoBundle,
s => {
early_error(
error_format,
&format!(
"unknown library kind `{}`, expected \
one of dylib, framework, or static",
s
),
);
}
};
(name.to_string(), kind)
}
};
if kind == NativeLibKind::StaticNoBundle
@ -1556,10 +1616,11 @@ fn parse_libs(
accepted on the nightly compiler",
);
}
let mut name_parts = name.splitn(2, ':');
let name = name_parts.next().unwrap();
let new_name = name_parts.next();
(name.to_owned(), new_name.map(|n| n.to_owned()), kind)
let (name, new_name) = match name.split_once(':') {
None => (name, None),
Some((name, new_name)) => (name.to_string(), Some(new_name.to_owned())),
};
(name, new_name, kind)
})
.collect()
}
@ -1580,20 +1641,13 @@ pub fn parse_externs(
let is_unstable_enabled = debugging_opts.unstable_options;
let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
for arg in matches.opt_strs("extern") {
let mut parts = arg.splitn(2, '=');
let name = parts
.next()
.unwrap_or_else(|| early_error(error_format, "--extern value must not be empty"));
let path = parts.next().map(|s| s.to_string());
let mut name_parts = name.splitn(2, ':');
let first_part = name_parts.next();
let second_part = name_parts.next();
let (options, name) = match (first_part, second_part) {
(Some(opts), Some(name)) => (Some(opts), name),
(Some(name), None) => (None, name),
(None, None) => early_error(error_format, "--extern name must not be empty"),
_ => unreachable!(),
let (name, path) = match arg.split_once('=') {
None => (arg, None),
Some((name, path)) => (name.to_string(), Some(path.to_string())),
};
let (options, name) = match name.split_once(':') {
None => (None, name),
Some((opts, name)) => (Some(opts), name.to_string()),
};
let entry = externs.entry(name.to_owned());
@ -1682,17 +1736,12 @@ fn parse_remap_path_prefix(
matches
.opt_strs("remap-path-prefix")
.into_iter()
.map(|remap| {
let mut parts = remap.rsplitn(2, '='); // reverse iterator
let to = parts.next();
let from = parts.next();
match (from, to) {
(Some(from), Some(to)) => (PathBuf::from(from), PathBuf::from(to)),
_ => early_error(
error_format,
"--remap-path-prefix must contain '=' between FROM and TO",
),
}
.map(|remap| match remap.rsplit_once('=') {
None => early_error(
error_format,
"--remap-path-prefix must contain '=' between FROM and TO",
),
Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)),
})
.collect()
}
@ -1766,7 +1815,30 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
// and reversible name mangling. Note, LLVM coverage tools can analyze coverage over
// multiple runs, including some changes to source code; so mangled names must be consistent
// across compilations.
debugging_opts.symbol_mangling_version = SymbolManglingVersion::V0;
match debugging_opts.symbol_mangling_version {
None => {
debugging_opts.symbol_mangling_version = Some(SymbolManglingVersion::V0);
}
Some(SymbolManglingVersion::Legacy) => {
early_warn(
error_format,
"-Z instrument-coverage requires symbol mangling version `v0`, \
but `-Z symbol-mangling-version=legacy` was specified",
);
}
Some(SymbolManglingVersion::V0) => {}
}
if debugging_opts.mir_opt_level > 1 {
early_warn(
error_format,
&format!(
"`-Z mir-opt-level={}` (any level > 1) enables function inlining, which \
limits the effectiveness of `-Z instrument-coverage`.",
debugging_opts.mir_opt_level,
),
);
}
}
if let Ok(graphviz_font) = std::env::var("RUSTC_GRAPHVIZ_FONT") {
@ -2171,7 +2243,7 @@ crate mod dep_tracking {
impl_dep_tracking_hash_via_hash!(Edition);
impl_dep_tracking_hash_via_hash!(LinkerPluginLto);
impl_dep_tracking_hash_via_hash!(SwitchWithOptPath);
impl_dep_tracking_hash_via_hash!(SymbolManglingVersion);
impl_dep_tracking_hash_via_hash!(Option<SymbolManglingVersion>);
impl_dep_tracking_hash_via_hash!(Option<SourceFileHashAlgorithm>);
impl_dep_tracking_hash_via_hash!(TrimmedDefPaths);

View file

@ -76,7 +76,7 @@ impl<'a> FileSearch<'a> {
pub fn new(
sysroot: &'a Path,
triple: &'a str,
search_paths: &'a Vec<SearchPath>,
search_paths: &'a [SearchPath],
tlib_path: &'a SearchPath,
kind: PathKind,
) -> FileSearch<'a> {

View file

@ -1,6 +1,7 @@
#![feature(crate_visibility_modifier)]
#![feature(once_cell)]
#![feature(or_patterns)]
#![feature(str_split_once)]
#[macro_use]
extern crate bitflags;

View file

@ -179,9 +179,10 @@ macro_rules! options {
{
let mut op = $defaultfn();
for option in matches.opt_strs($prefix) {
let mut iter = option.splitn(2, '=');
let key = iter.next().unwrap();
let value = iter.next();
let (key, value) = match option.split_once('=') {
None => (option, None),
Some((k, v)) => (k.to_string(), Some(v)),
};
let option_to_lookup = key.replace("-", "_");
let mut found = false;
for &(candidate, setter, type_desc, _) in $stat {
@ -268,6 +269,7 @@ macro_rules! options {
pub const parse_switch_with_opt_path: &str =
"an optional path to the profiling data output directory";
pub const parse_merge_functions: &str = "one of: `disabled`, `trampolines`, or `aliases`";
pub const parse_split_dwarf_kind: &str = "one of: `none`, `single` or `split`";
pub const parse_symbol_mangling_version: &str = "either `legacy` or `v0` (RFC 2603)";
pub const parse_src_file_hash: &str = "either `md5` or `sha1`";
pub const parse_relocation_model: &str =
@ -675,13 +677,26 @@ macro_rules! options {
true
}
fn parse_symbol_mangling_version(
slot: &mut SymbolManglingVersion,
fn parse_split_dwarf_kind(
slot: &mut SplitDwarfKind,
v: Option<&str>,
) -> bool {
*slot = match v {
Some("legacy") => SymbolManglingVersion::Legacy,
Some("v0") => SymbolManglingVersion::V0,
Some("none") => SplitDwarfKind::None,
Some("split") => SplitDwarfKind::Split,
Some("single") => SplitDwarfKind::Single,
_ => return false,
};
true
}
fn parse_symbol_mangling_version(
slot: &mut Option<SymbolManglingVersion>,
v: Option<&str>,
) -> bool {
*slot = match v {
Some("legacy") => Some(SymbolManglingVersion::Legacy),
Some("v0") => Some(SymbolManglingVersion::V0),
_ => return false,
};
true
@ -1087,9 +1102,14 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"),
strip: Strip = (Strip::None, parse_strip, [UNTRACKED],
"tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`)"),
symbol_mangling_version: SymbolManglingVersion = (SymbolManglingVersion::Legacy,
split_dwarf: SplitDwarfKind = (SplitDwarfKind::None, parse_split_dwarf_kind, [UNTRACKED],
"enable generation of split dwarf"),
split_dwarf_inlining: bool = (true, parse_bool, [UNTRACKED],
"provide minimal debug info in the object/executable to facilitate online \
symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF"),
symbol_mangling_version: Option<SymbolManglingVersion> = (None,
parse_symbol_mangling_version, [TRACKED],
"which mangling version to use for symbol names"),
"which mangling version to use for symbol names ('legacy' (default) or 'v0')"),
teach: bool = (false, parse_bool, [TRACKED],
"show extended diagnostic help (default: no)"),
terminal_width: Option<usize> = (None, parse_opt_uint, [UNTRACKED],

View file

@ -119,6 +119,7 @@ pub struct ParseSess {
pub unstable_features: UnstableFeatures,
pub config: CrateConfig,
pub edition: Edition,
pub missing_fragment_specifiers: Lock<FxHashMap<Span, NodeId>>,
/// Places where raw identifiers were used. This is used for feature-gating raw identifiers.
pub raw_identifier_spans: Lock<Vec<Span>>,
/// Used to determine and report recursive module inclusions.
@ -152,6 +153,7 @@ impl ParseSess {
unstable_features: UnstableFeatures::from_environment(None),
config: FxHashSet::default(),
edition: ExpnId::root().expn_data().edition,
missing_fragment_specifiers: Default::default(),
raw_identifier_spans: Lock::new(Vec::new()),
included_mod_stack: Lock::new(vec![]),
source_map,

View file

@ -1109,10 +1109,7 @@ impl Session {
}
pub fn link_dead_code(&self) -> bool {
match self.opts.cg.link_dead_code {
Some(explicitly_set) => explicitly_set,
None => false,
}
self.opts.cg.link_dead_code.unwrap_or(false)
}
pub fn mark_attr_known(&self, attr: &Attribute) {