Skip to content

Commit f1e6437

Browse files
committed
obtain verdefnum from verdef section header
Similarly to #611 Rust's ELF raw-dylibs do not contain the information about verdef count. This goes against LSB, but all the other linkers can handle it, presumably by using `st_info` of`.gnu.version_d` section. I'm not sure if this is the right thing to do, maybe `sh_info` should be used just a fallback when `.dynamic` doesn't have `DT_VERDEFNUM` tag? On current main `tests/ui/linkage-attr/raw-dylib/elf/glibc-x86_64.rs` fails with: ``` wild: error: Failed to load symbols from `/tmp/rustcnCgdWG/raw-dylibs/lib105m6f543m4qw1t7khnttg751.so` Caused by: Invalid version index 1 ```
1 parent c9a95f0 commit f1e6437

File tree

2 files changed

+6
-18
lines changed

2 files changed

+6
-18
lines changed

libwild/src/elf.rs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use linker_utils::elf::extract_bits;
1616
use linker_utils::elf::sht;
1717
use object::LittleEndian;
1818
use object::read::elf::CompressionHeader;
19-
use object::read::elf::Dyn;
2019
use object::read::elf::FileHeader as _;
2120
use object::read::elf::RelocationSections;
2221
use object::read::elf::SectionHeader as _;
@@ -63,8 +62,8 @@ pub(crate) struct File<'data> {
6362
/// An iterator over the version definitions and the corresponding linked string table index.
6463
pub(crate) verdef: Option<(VerdefIterator<'data>, object::SectionIndex)>,
6564

66-
/// Number of verdef versions according to the dynamic table.
67-
pub(crate) verdefnum: u64,
65+
/// Number of verdef versions according to `sh_info` of `.gnu._version_d` section.
66+
pub(crate) verdefnum: u32,
6867

6968
/// e_flags from the header.
7069
pub(crate) eflags: u32,
@@ -85,10 +84,9 @@ impl<'data> File<'data> {
8584
let mut symbols = SymbolTable::default();
8685
let mut versym: &[Versym] = &[];
8786
let mut verdef = None;
88-
let mut dynamic = None;
8987
let mut verdefnum = 0;
9088

91-
// Find all the sections that we're interested in in a single scan of the section table so
89+
// Find all the sections that we're interested in a single scan of the section table so
9290
// as to avoid multiple scans.
9391
for (section_index, section) in sections.enumerate() {
9492
match SectionType::from_header(section) {
@@ -103,22 +101,12 @@ impl<'data> File<'data> {
103101
}
104102
sht::GNU_VERDEF => {
105103
verdef = section.gnu_verdef(endian, data)?;
106-
}
107-
sht::DYNAMIC => {
108-
dynamic = section.dynamic(endian, data)?;
104+
verdefnum = section.sh_info(endian);
109105
}
110106
_ => {}
111107
}
112108
}
113109

114-
if let Some((dynamic, _)) = dynamic {
115-
for dy in dynamic {
116-
if dy.d_tag(endian) == u64::from(object::elf::DT_VERDEFNUM) {
117-
verdefnum = dy.d_val(endian);
118-
}
119-
}
120-
}
121-
122110
Ok(Self {
123111
arch: architecture,
124112
data,

libwild/src/layout.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5282,9 +5282,9 @@ impl<'data> DynamicLayoutState<'data> {
52825282
resources: &GraphResources<'data, '_>,
52835283
queue: &mut LocalWorkQueue,
52845284
) -> Result {
5285-
let dt_info = DynamicTagValues::read(self.object)?;
5286-
self.symbol_versions_needed = vec![false; dt_info.verdefnum as usize];
5285+
self.symbol_versions_needed = vec![false; self.object.verdefnum as usize];
52875286

5287+
let dt_info = DynamicTagValues::read(self.object)?;
52885288
if let Some(soname) = dt_info.soname {
52895289
self.lib_name = soname;
52905290
}

0 commit comments

Comments
 (0)