Skip to content

Commit 53d60bb

Browse files
committed
Auto merge of #154039 - Zalathar:rollup-Emyd5AO, r=Zalathar
Rollup of 3 pull requests Successful merges: - #153580 (Handle statics and TLS in raw-dylib for ELF) - #154020 (Moved tests/ui/issues/issue-23891.rs to tests/ui/macros/) - #154028 (Rename trait `IntoQueryParam` to `IntoQueryKey`)
2 parents 70dd5b8 + 205d100 commit 53d60bb

16 files changed

Lines changed: 260 additions & 159 deletions

File tree

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

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_data_structures::stable_hasher::StableHasher;
99
use rustc_hashes::Hash128;
1010
use rustc_hir::attrs::NativeLibKind;
1111
use rustc_session::Session;
12-
use rustc_session::cstore::DllImport;
12+
use rustc_session::cstore::{DllImport, DllImportSymbolType};
1313
use rustc_span::Symbol;
1414
use rustc_target::spec::Arch;
1515

@@ -95,14 +95,14 @@ pub(super) fn create_raw_dylib_dll_import_libs<'a>(
9595
true,
9696
)
9797
}),
98-
is_data: !import.is_fn,
98+
is_data: import.symbol_type != DllImportSymbolType::Function,
9999
}
100100
} else {
101101
ImportLibraryItem {
102102
name: import.name.to_string(),
103103
ordinal: import.ordinal(),
104104
symbol_name: None,
105-
is_data: !import.is_fn,
105+
is_data: import.symbol_type != DllImportSymbolType::Function,
106106
}
107107
}
108108
})
@@ -271,10 +271,10 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
271271
vers.push((version_name, dynstr));
272272
id
273273
};
274-
syms.push((name, dynstr, Some(ver), symbol.is_fn));
274+
syms.push((name, dynstr, Some(ver), symbol.symbol_type, symbol.size));
275275
} else {
276276
let dynstr = stub.add_dynamic_string(symbol_name.as_bytes());
277-
syms.push((symbol_name, dynstr, None, symbol.is_fn));
277+
syms.push((symbol_name, dynstr, None, symbol.symbol_type, symbol.size));
278278
}
279279
}
280280

@@ -296,6 +296,8 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
296296
stub.reserve_shstrtab_section_index();
297297
let text_section_name = stub.add_section_name(".text".as_bytes());
298298
let text_section = stub.reserve_section_index();
299+
let data_section_name = stub.add_section_name(".data".as_bytes());
300+
let data_section = stub.reserve_section_index();
299301
stub.reserve_dynsym_section_index();
300302
stub.reserve_dynstr_section_index();
301303
if !vers.is_empty() {
@@ -375,7 +377,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
375377
// Section headers
376378
stub.write_null_section_header();
377379
stub.write_shstrtab_section_header();
378-
// Create a dummy .text section for our dummy symbols.
380+
// Create a dummy .text section for our dummy non-data symbols.
379381
stub.write_section_header(&write::SectionHeader {
380382
name: Some(text_section_name),
381383
sh_type: elf::SHT_PROGBITS,
@@ -385,7 +387,20 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
385387
sh_size: 0,
386388
sh_link: 0,
387389
sh_info: 0,
388-
sh_addralign: 1,
390+
sh_addralign: 16,
391+
sh_entsize: 0,
392+
});
393+
// And also a dummy .data section for our dummy data symbols.
394+
stub.write_section_header(&write::SectionHeader {
395+
name: Some(data_section_name),
396+
sh_type: elf::SHT_PROGBITS,
397+
sh_flags: (elf::SHF_WRITE | elf::SHF_ALLOC) as u64,
398+
sh_addr: 0,
399+
sh_offset: 0,
400+
sh_size: 0,
401+
sh_link: 0,
402+
sh_info: 0,
403+
sh_addralign: 16,
389404
sh_entsize: 0,
390405
});
391406
stub.write_dynsym_section_header(0, 1);
@@ -398,17 +413,28 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
398413

399414
// .dynsym
400415
stub.write_null_dynamic_symbol();
401-
for (_name, dynstr, _ver, is_fn) in syms.iter().copied() {
402-
let sym_type = if is_fn { elf::STT_FUNC } else { elf::STT_NOTYPE };
416+
// Linkers like LLD require at least somewhat reasonable symbol values rather than zero,
417+
// otherwise all the symbols might get put at the same address. Thus we increment the value
418+
// every time we write a symbol.
419+
let mut st_value = 0;
420+
for (_name, dynstr, _ver, symbol_type, size) in syms.iter().copied() {
421+
let sym_type = match symbol_type {
422+
DllImportSymbolType::Function => elf::STT_FUNC,
423+
DllImportSymbolType::Static => elf::STT_OBJECT,
424+
DllImportSymbolType::ThreadLocal => elf::STT_TLS,
425+
};
426+
let section =
427+
if symbol_type == DllImportSymbolType::Static { data_section } else { text_section };
403428
stub.write_dynamic_symbol(&write::Sym {
404429
name: Some(dynstr),
405430
st_info: (elf::STB_GLOBAL << 4) | sym_type,
406431
st_other: elf::STV_DEFAULT,
407-
section: Some(text_section),
432+
section: Some(section),
408433
st_shndx: 0, // ignored by object in favor of the `section` field
409-
st_value: 0,
410-
st_size: 0,
434+
st_value,
435+
st_size: size.bytes(),
411436
});
437+
st_value += 8;
412438
}
413439

414440
// .dynstr
@@ -418,7 +444,7 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
418444
if !vers.is_empty() {
419445
// .gnu_version
420446
stub.write_null_gnu_versym();
421-
for (_name, _dynstr, ver, _is_fn) in syms.iter().copied() {
447+
for (_name, _dynstr, ver, _symbol_type, _size) in syms.iter().copied() {
422448
stub.write_gnu_versym(if let Some(ver) = ver {
423449
assert!((2 + ver as u16) < elf::VERSYM_HIDDEN);
424450
elf::VERSYM_HIDDEN | (2 + ver as u16)

compiler/rustc_codegen_ssa/src/common.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_hir::attrs::PeImportNameType;
55
use rustc_middle::ty::layout::TyAndLayout;
66
use rustc_middle::ty::{self, Instance, TyCtxt};
77
use rustc_middle::{bug, mir, span_bug};
8-
use rustc_session::cstore::{DllCallingConvention, DllImport};
8+
use rustc_session::cstore::{DllCallingConvention, DllImport, DllImportSymbolType};
99
use rustc_span::Span;
1010
use rustc_target::spec::{Abi, Env, Os, Target};
1111

@@ -199,15 +199,15 @@ pub fn i686_decorated_name(
199199
decorated_name.push('\x01');
200200
}
201201

202-
let prefix = if add_prefix && dll_import.is_fn {
202+
let prefix = if add_prefix && dll_import.symbol_type == DllImportSymbolType::Function {
203203
match dll_import.calling_convention {
204204
DllCallingConvention::C | DllCallingConvention::Vectorcall(_) => None,
205205
DllCallingConvention::Stdcall(_) => (!mingw
206206
|| dll_import.import_name_type == Some(PeImportNameType::Decorated))
207207
.then_some('_'),
208208
DllCallingConvention::Fastcall(_) => Some('@'),
209209
}
210-
} else if !dll_import.is_fn && !mingw {
210+
} else if dll_import.symbol_type != DllImportSymbolType::Function && !mingw {
211211
// For static variables, prefix with '_' on MSVC.
212212
Some('_')
213213
} else {
@@ -219,7 +219,7 @@ pub fn i686_decorated_name(
219219

220220
decorated_name.push_str(name);
221221

222-
if add_suffix && dll_import.is_fn {
222+
if add_suffix && dll_import.symbol_type == DllImportSymbolType::Function {
223223
use std::fmt::Write;
224224

225225
match dll_import.calling_convention {

compiler/rustc_metadata/src/native_libs.rs

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@ use rustc_abi::ExternAbi;
55
use rustc_attr_parsing::eval_config_entry;
66
use rustc_data_structures::fx::FxHashSet;
77
use rustc_hir::attrs::{NativeLibKind, PeImportNameType};
8+
use rustc_hir::def::DefKind;
89
use rustc_hir::find_attr;
10+
use rustc_middle::bug;
11+
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
912
use rustc_middle::query::LocalCrate;
1013
use rustc_middle::ty::{self, List, Ty, TyCtxt};
1114
use rustc_session::Session;
1215
use rustc_session::config::CrateType;
13-
use rustc_session::cstore::{DllCallingConvention, DllImport, ForeignModule, NativeLib};
16+
use rustc_session::cstore::{
17+
DllCallingConvention, DllImport, DllImportSymbolType, ForeignModule, NativeLib,
18+
};
1419
use rustc_session::search_paths::PathKind;
1520
use rustc_span::Symbol;
1621
use rustc_span::def_id::{DefId, LOCAL_CRATE};
@@ -451,12 +456,32 @@ impl<'tcx> Collector<'tcx> {
451456
}
452457
}
453458

454-
DllImport {
455-
name,
456-
import_name_type,
457-
calling_convention,
458-
span,
459-
is_fn: self.tcx.def_kind(item).is_fn_like(),
460-
}
459+
let def_kind = self.tcx.def_kind(item);
460+
let symbol_type = if def_kind.is_fn_like() {
461+
DllImportSymbolType::Function
462+
} else if matches!(def_kind, DefKind::Static { .. }) {
463+
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
464+
DllImportSymbolType::ThreadLocal
465+
} else {
466+
DllImportSymbolType::Static
467+
}
468+
} else {
469+
bug!("Unexpected type for raw-dylib: {}", def_kind.descr(item));
470+
};
471+
472+
let size = match symbol_type {
473+
// We cannot determine the size of a function at compile time, but it shouldn't matter anyway.
474+
DllImportSymbolType::Function => rustc_abi::Size::ZERO,
475+
DllImportSymbolType::Static | DllImportSymbolType::ThreadLocal => {
476+
let ty = self.tcx.type_of(item).instantiate_identity();
477+
self.tcx
478+
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty))
479+
.ok()
480+
.map(|layout| layout.size)
481+
.unwrap_or_else(|| bug!("Non-function symbols must have a size"))
482+
}
483+
};
484+
485+
DllImport { name, import_name_type, calling_convention, span, symbol_type, size }
461486
}
462487
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use rustc_hir::OwnerId;
2+
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, ModDefId};
3+
4+
/// Argument-conversion trait used by some queries and other `TyCtxt` methods.
5+
///
6+
/// A function that accepts an `impl IntoQueryKey<DefId>` argument can be thought
7+
/// of as taking a [`DefId`], except that callers can also pass a [`LocalDefId`]
8+
/// or values of other narrower ID types, as long as they have a trivial conversion
9+
/// to `DefId`.
10+
///
11+
/// Using a dedicated trait instead of [`Into`] makes the purpose of the conversion
12+
/// more explicit, and makes occurrences easier to search for.
13+
pub trait IntoQueryKey<K> {
14+
/// Argument conversion from `Self` to `K`.
15+
/// This should always be a very cheap conversion, e.g. [`LocalDefId::to_def_id`].
16+
fn into_query_key(self) -> K;
17+
}
18+
19+
/// Any type can be converted to itself.
20+
///
21+
/// This is useful in generic or macro-generated code where we don't know whether
22+
/// conversion is actually needed, so that we can do a conversion unconditionally.
23+
impl<K> IntoQueryKey<K> for K {
24+
#[inline(always)]
25+
fn into_query_key(self) -> K {
26+
self
27+
}
28+
}
29+
30+
impl IntoQueryKey<LocalDefId> for OwnerId {
31+
#[inline(always)]
32+
fn into_query_key(self) -> LocalDefId {
33+
self.def_id
34+
}
35+
}
36+
37+
impl IntoQueryKey<DefId> for LocalDefId {
38+
#[inline(always)]
39+
fn into_query_key(self) -> DefId {
40+
self.to_def_id()
41+
}
42+
}
43+
44+
impl IntoQueryKey<DefId> for OwnerId {
45+
#[inline(always)]
46+
fn into_query_key(self) -> DefId {
47+
self.to_def_id()
48+
}
49+
}
50+
51+
impl IntoQueryKey<DefId> for ModDefId {
52+
#[inline(always)]
53+
fn into_query_key(self) -> DefId {
54+
self.to_def_id()
55+
}
56+
}
57+
58+
impl IntoQueryKey<DefId> for LocalModDefId {
59+
#[inline(always)]
60+
fn into_query_key(self) -> DefId {
61+
self.to_def_id()
62+
}
63+
}
64+
65+
impl IntoQueryKey<LocalDefId> for LocalModDefId {
66+
#[inline(always)]
67+
fn into_query_key(self) -> LocalDefId {
68+
self.into()
69+
}
70+
}

compiler/rustc_middle/src/query/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use rustc_hir::def_id::LocalDefId;
22

33
pub use self::caches::{DefIdCache, DefaultCache, QueryCache, SingleCache, VecCache};
4+
pub use self::into_query_key::IntoQueryKey;
45
pub use self::job::{QueryJob, QueryJobId, QueryLatch, QueryWaiter};
56
pub use self::keys::{AsLocalQueryKey, LocalCrate, QueryKey};
67
pub use self::plumbing::{
7-
ActiveKeyStatus, CycleError, EnsureMode, IntoQueryParam, QueryMode, QueryState, QuerySystem,
8-
QueryVTable, TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk, TyCtxtEnsureResult,
8+
ActiveKeyStatus, CycleError, EnsureMode, QueryMode, QueryState, QuerySystem, QueryVTable,
9+
TyCtxtAt, TyCtxtEnsureDone, TyCtxtEnsureOk, TyCtxtEnsureResult,
910
};
1011
pub use self::stack::QueryStackFrame;
1112
pub use crate::queries::Providers;
@@ -15,6 +16,7 @@ pub(crate) mod arena_cached;
1516
mod caches;
1617
pub mod erase;
1718
pub(crate) mod inner;
19+
mod into_query_key;
1820
mod job;
1921
mod keys;
2022
pub(crate) mod modifiers;

0 commit comments

Comments
 (0)