-
Notifications
You must be signed in to change notification settings - Fork 13k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a test to verify that libstd doesn't use protected symbols
- Loading branch information
1 parent
9fa9ef3
commit c1285b4
Showing
1 changed file
with
63 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// If libstd was compiled to use protected symbols, then linking would fail if GNU ld < 2.40 were | ||
// used. This might not be noticed, since usually we use LLD for linking, so we could end up | ||
// distributing a version of libstd that would cause link errors for such users. | ||
|
||
//@ only-x86_64-unknown-linux-gnu | ||
|
||
use run_make_support::object::Endianness; | ||
use run_make_support::object::read::archive::ArchiveFile; | ||
use run_make_support::object::read::elf::{FileHeader as _, SectionHeader as _}; | ||
use run_make_support::rfs::{read, read_dir}; | ||
use run_make_support::{has_prefix, has_suffix, object, path, rustc, shallow_find_files, target}; | ||
|
||
type FileHeader = run_make_support::object::elf::FileHeader64<Endianness>; | ||
type SymbolTable<'data> = run_make_support::object::read::elf::SymbolTable<'data, FileHeader>; | ||
|
||
fn main() { | ||
// Find libstd-...rlib | ||
let sysroot = rustc().print("sysroot").run().stdout_utf8(); | ||
let sysroot = sysroot.trim(); | ||
let target_sysroot = path(sysroot).join("lib/rustlib").join(target()).join("lib"); | ||
let mut libs = shallow_find_files(&target_sysroot, |path| { | ||
has_prefix(path, "libstd-") && has_suffix(path, ".rlib") | ||
}); | ||
assert_eq!(libs.len(), 1); | ||
let libstd_path = libs.pop().unwrap(); | ||
let archive_data = read(libstd_path); | ||
|
||
// Parse all the object files within the libstd archive, checking defined symbols. | ||
let mut num_protected = 0; | ||
let mut num_symbols = 0; | ||
|
||
let archive = ArchiveFile::parse(&*archive_data).unwrap(); | ||
for member in archive.members() { | ||
let member = member.unwrap(); | ||
if member.name() == b"lib.rmeta" { | ||
continue; | ||
} | ||
let data = member.data(&*archive_data).unwrap(); | ||
|
||
let header = FileHeader::parse(data).unwrap(); | ||
let endian = header.endian().unwrap(); | ||
let sections = header.sections(endian, data).unwrap(); | ||
|
||
for (section_index, section) in sections.enumerate() { | ||
if section.sh_type(endian) == object::elf::SHT_SYMTAB { | ||
let symbols = | ||
SymbolTable::parse(endian, data, §ions, section_index, section).unwrap(); | ||
for symbol in symbols.symbols() { | ||
if symbol.st_visibility() == object::elf::STV_PROTECTED { | ||
num_protected += 1; | ||
} | ||
num_symbols += 1; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// If there were no symbols at all, then something is wrong with the test. | ||
assert_ne!(num_symbols, 0); | ||
|
||
// The purpose of this test - check that no symbols have protected visibility. | ||
assert_eq!(num_protected, 0); | ||
} |