Skip to content

Commit 4c40119

Browse files
authored
Rollup merge of #132432 - davidlattimore:std-interposable, r=Mark-Simulacrum
Add a test to verify that libstd doesn't use protected symbols
2 parents 3f86edd + c1285b4 commit 4c40119

File tree

1 file changed

+63
-0
lines changed
  • tests/run-make/libstd-no-protected

1 file changed

+63
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// If libstd was compiled to use protected symbols, then linking would fail if GNU ld < 2.40 were
2+
// used. This might not be noticed, since usually we use LLD for linking, so we could end up
3+
// distributing a version of libstd that would cause link errors for such users.
4+
5+
//@ only-x86_64-unknown-linux-gnu
6+
7+
use run_make_support::object::Endianness;
8+
use run_make_support::object::read::archive::ArchiveFile;
9+
use run_make_support::object::read::elf::{FileHeader as _, SectionHeader as _};
10+
use run_make_support::rfs::{read, read_dir};
11+
use run_make_support::{has_prefix, has_suffix, object, path, rustc, shallow_find_files, target};
12+
13+
type FileHeader = run_make_support::object::elf::FileHeader64<Endianness>;
14+
type SymbolTable<'data> = run_make_support::object::read::elf::SymbolTable<'data, FileHeader>;
15+
16+
fn main() {
17+
// Find libstd-...rlib
18+
let sysroot = rustc().print("sysroot").run().stdout_utf8();
19+
let sysroot = sysroot.trim();
20+
let target_sysroot = path(sysroot).join("lib/rustlib").join(target()).join("lib");
21+
let mut libs = shallow_find_files(&target_sysroot, |path| {
22+
has_prefix(path, "libstd-") && has_suffix(path, ".rlib")
23+
});
24+
assert_eq!(libs.len(), 1);
25+
let libstd_path = libs.pop().unwrap();
26+
let archive_data = read(libstd_path);
27+
28+
// Parse all the object files within the libstd archive, checking defined symbols.
29+
let mut num_protected = 0;
30+
let mut num_symbols = 0;
31+
32+
let archive = ArchiveFile::parse(&*archive_data).unwrap();
33+
for member in archive.members() {
34+
let member = member.unwrap();
35+
if member.name() == b"lib.rmeta" {
36+
continue;
37+
}
38+
let data = member.data(&*archive_data).unwrap();
39+
40+
let header = FileHeader::parse(data).unwrap();
41+
let endian = header.endian().unwrap();
42+
let sections = header.sections(endian, data).unwrap();
43+
44+
for (section_index, section) in sections.enumerate() {
45+
if section.sh_type(endian) == object::elf::SHT_SYMTAB {
46+
let symbols =
47+
SymbolTable::parse(endian, data, &sections, section_index, section).unwrap();
48+
for symbol in symbols.symbols() {
49+
if symbol.st_visibility() == object::elf::STV_PROTECTED {
50+
num_protected += 1;
51+
}
52+
num_symbols += 1;
53+
}
54+
}
55+
}
56+
}
57+
58+
// If there were no symbols at all, then something is wrong with the test.
59+
assert_ne!(num_symbols, 0);
60+
61+
// The purpose of this test - check that no symbols have protected visibility.
62+
assert_eq!(num_protected, 0);
63+
}

0 commit comments

Comments
 (0)