|
| 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, §ions, 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