Skip to content

Commit fb35347

Browse files
committed
Auto merge of #144325 - matthiaskrgr:rollup-0jbo4dl, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #144094 (Ensure we codegen the main fn) - #144173 (Remove tidy checks for `tests/ui/issues/`) - #144218 (Use serde for target spec json deserialize) - #144221 (generate elf symbol version in raw-dylib) - #144234 (Fix broken TLS destructors on 32-bit win7) - #144256 (Don't ICE on non-TypeId metadata within TypeId) - #144272 (resolve: Make disambiguators for underscore bindings module-local (take 2)) - #144276 (Use less HIR in check_private_in_public.) r? `@ghost` `@rustbot` modify labels: rollup
2 parents a7a1618 + 845af3c commit fb35347

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1154
-2331
lines changed

Cargo.lock

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4563,7 +4563,10 @@ dependencies = [
45634563
"rustc_macros",
45644564
"rustc_serialize",
45654565
"rustc_span",
4566+
"serde",
4567+
"serde_derive",
45664568
"serde_json",
4569+
"serde_path_to_error",
45674570
"tracing",
45684571
]
45694572

@@ -4955,6 +4958,16 @@ dependencies = [
49554958
"serde",
49564959
]
49574960

4961+
[[package]]
4962+
name = "serde_path_to_error"
4963+
version = "0.1.17"
4964+
source = "registry+https://github.com/rust-lang/crates.io-index"
4965+
checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a"
4966+
dependencies = [
4967+
"itoa",
4968+
"serde",
4969+
]
4970+
49584971
[[package]]
49594972
name = "serde_spanned"
49604973
version = "0.6.9"

compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs

Lines changed: 78 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};
44

55
use rustc_abi::Endian;
66
use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN};
7-
use rustc_data_structures::fx::FxIndexMap;
7+
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
88
use rustc_data_structures::stable_hasher::StableHasher;
99
use rustc_hashes::Hash128;
1010
use rustc_session::Session;
@@ -230,40 +230,66 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
230230
Endian::Little => object::Endianness::Little,
231231
Endian::Big => object::Endianness::Big,
232232
};
233+
233234
let mut stub = write::Writer::new(endianness, true, &mut stub_buf);
234235

236+
let mut vers = Vec::new();
237+
let mut vers_map = FxHashMap::default();
238+
let mut syms = Vec::new();
239+
240+
for symbol in symbols {
241+
let symbol_name = symbol.name.as_str();
242+
if let Some((name, version_name)) = symbol_name.split_once('@') {
243+
assert!(!version_name.contains('@'));
244+
let dynstr = stub.add_dynamic_string(name.as_bytes());
245+
let ver = if let Some(&ver_id) = vers_map.get(version_name) {
246+
ver_id
247+
} else {
248+
let id = vers.len();
249+
vers_map.insert(version_name, id);
250+
let dynstr = stub.add_dynamic_string(version_name.as_bytes());
251+
vers.push((version_name, dynstr));
252+
id
253+
};
254+
syms.push((name, dynstr, Some(ver)));
255+
} else {
256+
let dynstr = stub.add_dynamic_string(symbol_name.as_bytes());
257+
syms.push((symbol_name, dynstr, None));
258+
}
259+
}
260+
261+
let soname = stub.add_dynamic_string(soname.as_bytes());
262+
235263
// These initial reservations don't reserve any bytes in the binary yet,
236264
// they just allocate in the internal data structures.
237265

238-
// First, we crate the dynamic symbol table. It starts with a null symbol
266+
// First, we create the dynamic symbol table. It starts with a null symbol
239267
// and then all the symbols and their dynamic strings.
240268
stub.reserve_null_dynamic_symbol_index();
241269

242-
let dynstrs = symbols
243-
.iter()
244-
.map(|sym| {
245-
stub.reserve_dynamic_symbol_index();
246-
(sym, stub.add_dynamic_string(sym.name.as_str().as_bytes()))
247-
})
248-
.collect::<Vec<_>>();
249-
250-
let soname = stub.add_dynamic_string(soname.as_bytes());
270+
for _ in syms.iter() {
271+
stub.reserve_dynamic_symbol_index();
272+
}
251273

252274
// Reserve the sections.
253275
// We have the minimal sections for a dynamic SO and .text where we point our dummy symbols to.
254276
stub.reserve_shstrtab_section_index();
255277
let text_section_name = stub.add_section_name(".text".as_bytes());
256278
let text_section = stub.reserve_section_index();
257-
stub.reserve_dynstr_section_index();
258279
stub.reserve_dynsym_section_index();
280+
stub.reserve_dynstr_section_index();
281+
stub.reserve_gnu_versym_section_index();
282+
stub.reserve_gnu_verdef_section_index();
259283
stub.reserve_dynamic_section_index();
260284

261285
// These reservations now determine the actual layout order of the object file.
262286
stub.reserve_file_header();
263287
stub.reserve_shstrtab();
264288
stub.reserve_section_headers();
265-
stub.reserve_dynstr();
266289
stub.reserve_dynsym();
290+
stub.reserve_dynstr();
291+
stub.reserve_gnu_versym();
292+
stub.reserve_gnu_verdef(1 + vers.len(), 1 + vers.len());
267293
stub.reserve_dynamic(2); // DT_SONAME, DT_NULL
268294

269295
// First write the ELF header with the arch information.
@@ -342,18 +368,17 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
342368
sh_addralign: 1,
343369
sh_entsize: 0,
344370
});
345-
stub.write_dynstr_section_header(0);
346371
stub.write_dynsym_section_header(0, 1);
372+
stub.write_dynstr_section_header(0);
373+
stub.write_gnu_versym_section_header(0);
374+
stub.write_gnu_verdef_section_header(0);
347375
stub.write_dynamic_section_header(0);
348376

349-
// .dynstr
350-
stub.write_dynstr();
351-
352377
// .dynsym
353378
stub.write_null_dynamic_symbol();
354-
for (_, name) in dynstrs {
379+
for (_name, dynstr, _ver) in syms.iter().copied() {
355380
stub.write_dynamic_symbol(&write::Sym {
356-
name: Some(name),
381+
name: Some(dynstr),
357382
st_info: (elf::STB_GLOBAL << 4) | elf::STT_NOTYPE,
358383
st_other: elf::STV_DEFAULT,
359384
section: Some(text_section),
@@ -363,10 +388,44 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
363388
});
364389
}
365390

391+
// .dynstr
392+
stub.write_dynstr();
393+
394+
// .gnu_version
395+
stub.write_null_gnu_versym();
396+
for (_name, _dynstr, ver) in syms.iter().copied() {
397+
stub.write_gnu_versym(if let Some(ver) = ver {
398+
assert!((2 + ver as u16) < elf::VERSYM_HIDDEN);
399+
elf::VERSYM_HIDDEN | (2 + ver as u16)
400+
} else {
401+
1
402+
});
403+
}
404+
405+
// .gnu_version_d
406+
stub.write_align_gnu_verdef();
407+
stub.write_gnu_verdef(&write::Verdef {
408+
version: elf::VER_DEF_CURRENT,
409+
flags: elf::VER_FLG_BASE,
410+
index: 1,
411+
aux_count: 1,
412+
name: soname,
413+
});
414+
for (ver, (_name, dynstr)) in vers.into_iter().enumerate() {
415+
stub.write_gnu_verdef(&write::Verdef {
416+
version: elf::VER_DEF_CURRENT,
417+
flags: 0,
418+
index: 2 + ver as u16,
419+
aux_count: 1,
420+
name: dynstr,
421+
});
422+
}
423+
366424
// .dynamic
367425
// the DT_SONAME will be used by the linker to populate DT_NEEDED
368426
// which the loader uses to find the library.
369427
// DT_NULL terminates the .dynamic table.
428+
stub.write_align_dynamic();
370429
stub.write_dynamic_string(elf::DT_SONAME, soname);
371430
stub.write_dynamic(elf::DT_NULL, 0);
372431

compiler/rustc_const_eval/src/interpret/memory.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
10001000
ptr: Pointer<Option<M::Provenance>>,
10011001
) -> InterpResult<'tcx, (Ty<'tcx>, u64)> {
10021002
let (alloc_id, offset, _meta) = self.ptr_get_alloc_id(ptr, 0)?;
1003-
let GlobalAlloc::TypeId { ty } = self.tcx.global_alloc(alloc_id) else {
1003+
let Some(GlobalAlloc::TypeId { ty }) = self.tcx.try_get_global_alloc(alloc_id) else {
10041004
throw_ub_format!("invalid `TypeId` value: not all bytes carry type id metadata")
10051005
};
10061006
interp_ok((ty, offset.bytes()))

compiler/rustc_metadata/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,3 +330,6 @@ metadata_wasm_import_form =
330330
331331
metadata_whole_archive_needs_static =
332332
linking modifier `whole-archive` is only compatible with `static` linking kind
333+
334+
metadata_raw_dylib_malformed =
335+
link name must be well-formed if link kind is `raw-dylib`

compiler/rustc_metadata/src/errors.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,3 +815,10 @@ pub struct AsyncDropTypesInDependency {
815815
pub extern_crate: Symbol,
816816
pub local_crate: Symbol,
817817
}
818+
819+
#[derive(Diagnostic)]
820+
#[diag(metadata_raw_dylib_malformed)]
821+
pub struct RawDylibMalformed {
822+
#[primary_span]
823+
pub span: Span,
824+
}

compiler/rustc_metadata/src/native_libs.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,8 +700,21 @@ impl<'tcx> Collector<'tcx> {
700700
.link_ordinal
701701
.map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord)));
702702

703+
let name = codegen_fn_attrs.link_name.unwrap_or_else(|| self.tcx.item_name(item));
704+
705+
if self.tcx.sess.target.binary_format == BinaryFormat::Elf {
706+
let name = name.as_str();
707+
if name.contains('\0') {
708+
self.tcx.dcx().emit_err(errors::RawDylibMalformed { span });
709+
} else if let Some((left, right)) = name.split_once('@')
710+
&& (left.is_empty() || right.is_empty() || right.contains('@'))
711+
{
712+
self.tcx.dcx().emit_err(errors::RawDylibMalformed { span });
713+
}
714+
}
715+
703716
DllImport {
704-
name: codegen_fn_attrs.link_name.unwrap_or_else(|| self.tcx.item_name(item)),
717+
name,
705718
import_name_type,
706719
calling_convention,
707720
span,

compiler/rustc_middle/src/mir/mono.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,8 @@ impl<'tcx> MonoItem<'tcx> {
143143
};
144144

145145
// Similarly, the executable entrypoint must be instantiated exactly once.
146-
if let Some((entry_def_id, _)) = tcx.entry_fn(()) {
147-
if instance.def_id() == entry_def_id {
148-
return InstantiationMode::GloballyShared { may_conflict: false };
149-
}
146+
if tcx.is_entrypoint(instance.def_id()) {
147+
return InstantiationMode::GloballyShared { may_conflict: false };
150148
}
151149

152150
// If the function is #[naked] or contains any other attribute that requires exactly-once

compiler/rustc_middle/src/ty/context.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3410,6 +3410,20 @@ impl<'tcx> TyCtxt<'tcx> {
34103410
pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
34113411
self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
34123412
}
3413+
3414+
/// Whether this def is one of the special bin crate entrypoint functions that must have a
3415+
/// monomorphization and also not be internalized in the bin crate.
3416+
pub fn is_entrypoint(self, def_id: DefId) -> bool {
3417+
if self.is_lang_item(def_id, LangItem::Start) {
3418+
return true;
3419+
}
3420+
if let Some((entry_def_id, _)) = self.entry_fn(())
3421+
&& entry_def_id == def_id
3422+
{
3423+
return true;
3424+
}
3425+
false
3426+
}
34133427
}
34143428

34153429
/// Parameter attributes that can only be determined by examining the body of a function instead

compiler/rustc_monomorphize/src/collector.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,6 +1582,15 @@ impl<'v> RootCollector<'_, 'v> {
15821582
return;
15831583
};
15841584

1585+
let main_instance = Instance::mono(self.tcx, main_def_id);
1586+
if self.tcx.should_codegen_locally(main_instance) {
1587+
self.output.push(create_fn_mono_item(
1588+
self.tcx,
1589+
main_instance,
1590+
self.tcx.def_span(main_def_id),
1591+
));
1592+
}
1593+
15851594
let Some(start_def_id) = self.tcx.lang_items().start_fn() else {
15861595
self.tcx.dcx().emit_fatal(errors::StartNotFound);
15871596
};

compiler/rustc_monomorphize/src/partitioning.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,7 @@ where
223223
// So even if its mode is LocalCopy, we need to treat it like a root.
224224
match mono_item.instantiation_mode(cx.tcx) {
225225
InstantiationMode::GloballyShared { .. } => {}
226-
InstantiationMode::LocalCopy => {
227-
if !cx.tcx.is_lang_item(mono_item.def_id(), LangItem::Start) {
228-
continue;
229-
}
230-
}
226+
InstantiationMode::LocalCopy => continue,
231227
}
232228

233229
let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
@@ -821,10 +817,9 @@ fn mono_item_visibility<'tcx>(
821817
| InstanceKind::FnPtrAddrShim(..) => return Visibility::Hidden,
822818
};
823819

824-
// The `start_fn` lang item is actually a monomorphized instance of a
825-
// function in the standard library, used for the `main` function. We don't
826-
// want to export it so we tag it with `Hidden` visibility but this symbol
827-
// is only referenced from the actual `main` symbol which we unfortunately
820+
// Both the `start_fn` lang item and `main` itself should not be exported,
821+
// so we give them with `Hidden` visibility but these symbols are
822+
// only referenced from the actual `main` symbol which we unfortunately
828823
// don't know anything about during partitioning/collection. As a result we
829824
// forcibly keep this symbol out of the `internalization_candidates` set.
830825
//
@@ -834,7 +829,7 @@ fn mono_item_visibility<'tcx>(
834829
// from the `main` symbol we'll generate later.
835830
//
836831
// This may be fixable with a new `InstanceKind` perhaps? Unsure!
837-
if tcx.is_lang_item(def_id, LangItem::Start) {
832+
if tcx.is_entrypoint(def_id) {
838833
*can_be_internalized = false;
839834
return Visibility::Hidden;
840835
}

0 commit comments

Comments
 (0)