Add a test to verify that libstd doesn't use protected symbols · rust-lang/rust@c1285b4 (original) (raw)
``
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:🧝:{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:🧝:FileHeader64;
`
``
14
`+
type SymbolTable<'data> = run_make_support::object::read:🧝: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:🧝:SHT_SYMTAB {
`
``
46
`+
let symbols =
`
``
47
`+
SymbolTable::parse(endian, data, §ions, section_index, section).unwrap();
`
``
48
`+
for symbol in symbols.symbols() {
`
``
49
`+
if symbol.st_visibility() == object:🧝: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
`+
}
`