diff --git a/crates/examples/src/readobj/elf.rs b/crates/examples/src/readobj/elf.rs index f83bf356..8a0091c9 100644 --- a/crates/examples/src/readobj/elf.rs +++ b/crates/examples/src/readobj/elf.rs @@ -398,11 +398,15 @@ fn print_section_symbols( for (index, symbol) in symbols.iter().enumerate() { p.group("Symbol", |p| { p.field("Index", index); - p.field_string( - "Name", - symbol.st_name(endian), - symbol.name(endian, symbols.strings()), - ); + if index == 0 { + p.field_hex("Name", symbol.st_name(endian)); + } else { + p.field_string( + "Name", + symbol.st_name(endian), + symbol.name(endian, symbols.strings()), + ); + } if let Some(versions) = versions.as_ref() { let version_index = versions.version_index(endian, index); print_version(p, Some(versions), version_index); @@ -511,6 +515,10 @@ fn print_rel_symbol( symbols: Option>, sym: u32, ) { + if sym == 0 { + p.field_hex("Symbol", sym); + return; + } let name = symbols.and_then(|symbols| { symbols .symbol(sym as usize) diff --git a/crates/examples/testfiles/elf/base-aarch64.o.readobj b/crates/examples/testfiles/elf/base-aarch64.o.readobj index e8c64b46..1b76f983 100644 --- a/crates/examples/testfiles/elf/base-aarch64.o.readobj +++ b/crates/examples/testfiles/elf/base-aarch64.o.readobj @@ -167,7 +167,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" (0x0) + Name: 0x0 Value: 0x0 Size: 0x0 Type: STT_NOTYPE (0x0) diff --git a/crates/examples/testfiles/elf/base-aarch64.readobj b/crates/examples/testfiles/elf/base-aarch64.readobj index 168fc5b1..640ab74d 100644 --- a/crates/examples/testfiles/elf/base-aarch64.readobj +++ b/crates/examples/testfiles/elf/base-aarch64.readobj @@ -338,7 +338,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" (0x0) + Name: 0x0 Version: VER_NDX_LOCAL (0x0) Value: 0x0 Size: 0x0 @@ -559,37 +559,37 @@ SectionHeader { Relocation { Offset: 0x10D80 Type: R_AARCH64_RELATIVE (0x403) - Symbol: "" (0x0) + Symbol: 0x0 Addend: 0x720 } Relocation { Offset: 0x10D88 Type: R_AARCH64_RELATIVE (0x403) - Symbol: "" (0x0) + Symbol: 0x0 Addend: 0x6D8 } Relocation { Offset: 0x10FC8 Type: R_AARCH64_RELATIVE (0x403) - Symbol: "" (0x0) + Symbol: 0x0 Addend: 0x7C8 } Relocation { Offset: 0x10FE8 Type: R_AARCH64_RELATIVE (0x403) - Symbol: "" (0x0) + Symbol: 0x0 Addend: 0x748 } Relocation { Offset: 0x10FF0 Type: R_AARCH64_RELATIVE (0x403) - Symbol: "" (0x0) + Symbol: 0x0 Addend: 0x724 } Relocation { Offset: 0x11008 Type: R_AARCH64_RELATIVE (0x403) - Symbol: "" (0x0) + Symbol: 0x0 Addend: 0x11008 } Relocation { @@ -971,7 +971,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" (0x0) + Name: 0x0 Value: 0x0 Size: 0x0 Type: STT_NOTYPE (0x0) diff --git a/crates/examples/testfiles/elf/base-mips64el.o.readobj b/crates/examples/testfiles/elf/base-mips64el.o.readobj index 761cf16a..190d89d3 100644 --- a/crates/examples/testfiles/elf/base-mips64el.o.readobj +++ b/crates/examples/testfiles/elf/base-mips64el.o.readobj @@ -269,7 +269,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" (0x0) + Name: 0x0 Value: 0x0 Size: 0x0 Type: STT_NOTYPE (0x0) diff --git a/crates/examples/testfiles/elf/base-mips64el.readobj b/crates/examples/testfiles/elf/base-mips64el.readobj index ebfdd97b..76d870b8 100644 --- a/crates/examples/testfiles/elf/base-mips64el.readobj +++ b/crates/examples/testfiles/elf/base-mips64el.readobj @@ -442,7 +442,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" (0x0) + Name: 0x0 Version: VER_NDX_LOCAL (0x0) Value: 0x0 Size: 0x0 @@ -984,7 +984,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" (0x0) + Name: 0x0 Value: 0x0 Size: 0x0 Type: STT_NOTYPE (0x0) diff --git a/crates/examples/testfiles/elf/base.o.readobj b/crates/examples/testfiles/elf/base.o.readobj index 9895bdcb..8b34b813 100644 --- a/crates/examples/testfiles/elf/base.o.readobj +++ b/crates/examples/testfiles/elf/base.o.readobj @@ -197,7 +197,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" (0x0) + Name: 0x0 Value: 0x0 Size: 0x0 Type: STT_NOTYPE (0x0) diff --git a/crates/examples/testfiles/elf/base.readobj b/crates/examples/testfiles/elf/base.readobj index 09130663..c1a43e2d 100644 --- a/crates/examples/testfiles/elf/base.readobj +++ b/crates/examples/testfiles/elf/base.readobj @@ -371,7 +371,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" (0x0) + Name: 0x0 Version: VER_NDX_LOCAL (0x0) Value: 0x0 Size: 0x0 @@ -547,19 +547,19 @@ SectionHeader { Relocation { Offset: 0x200DA8 Type: R_X86_64_RELATIVE (0x8) - Symbol: "" (0x0) + Symbol: 0x0 Addend: 0x670 } Relocation { Offset: 0x200DB0 Type: R_X86_64_RELATIVE (0x8) - Symbol: "" (0x0) + Symbol: 0x0 Addend: 0x630 } Relocation { Offset: 0x201008 Type: R_X86_64_RELATIVE (0x8) - Symbol: "" (0x0) + Symbol: 0x0 Addend: 0x201008 } Relocation { @@ -959,7 +959,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" (0x0) + Name: 0x0 Value: 0x0 Size: 0x0 Type: STT_NOTYPE (0x0) diff --git a/crates/examples/testfiles/elf/nostd-mipsel.o.readobj b/crates/examples/testfiles/elf/nostd-mipsel.o.readobj index d3536ff5..6de02f3f 100644 --- a/crates/examples/testfiles/elf/nostd-mipsel.o.readobj +++ b/crates/examples/testfiles/elf/nostd-mipsel.o.readobj @@ -227,7 +227,7 @@ SectionHeader { EntrySize: 0x10 Symbol { Index: 0 - Name: "" (0x0) + Name: 0x0 Value: 0x0 Size: 0x0 Type: STT_NOTYPE (0x0) diff --git a/crates/examples/testfiles/elf/nostd-mipsel.readobj b/crates/examples/testfiles/elf/nostd-mipsel.readobj index 654999e3..c6afcdf0 100644 --- a/crates/examples/testfiles/elf/nostd-mipsel.readobj +++ b/crates/examples/testfiles/elf/nostd-mipsel.readobj @@ -185,7 +185,7 @@ SectionHeader { EntrySize: 0x10 Symbol { Index: 0 - Name: "" (0x0) + Name: 0x0 Value: 0x0 Size: 0x0 Type: STT_NOTYPE (0x0) diff --git a/crates/rewrite/testfiles/elf/base.delete-symbol b/crates/rewrite/testfiles/elf/base.delete-symbol index fe21bfb4..759fc813 100644 --- a/crates/rewrite/testfiles/elf/base.delete-symbol +++ b/crates/rewrite/testfiles/elf/base.delete-symbol @@ -211,7 +211,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" + Name: 0x0 Version: VER_NDX_LOCAL (0x0) Value: 0x0 Size: 0x0 @@ -583,7 +583,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" + Name: 0x0 Value: 0x0 Size: 0x0 Type: STT_NOTYPE (0x0) diff --git a/crates/rewrite/testfiles/elf/base.noop b/crates/rewrite/testfiles/elf/base.noop index c6f27c14..46a73128 100644 --- a/crates/rewrite/testfiles/elf/base.noop +++ b/crates/rewrite/testfiles/elf/base.noop @@ -371,7 +371,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" + Name: 0x0 Version: VER_NDX_LOCAL (0x0) Value: 0x0 Size: 0x0 @@ -547,19 +547,19 @@ SectionHeader { Relocation { Offset: 0x200DA8 Type: R_X86_64_RELATIVE (0x8) - Symbol: "" + Symbol: 0x0 Addend: 0x670 } Relocation { Offset: 0x200DB0 Type: R_X86_64_RELATIVE (0x8) - Symbol: "" + Symbol: 0x0 Addend: 0x630 } Relocation { Offset: 0x201008 Type: R_X86_64_RELATIVE (0x8) - Symbol: "" + Symbol: 0x0 Addend: 0x201008 } Relocation { @@ -959,7 +959,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" + Name: 0x0 Value: 0x0 Size: 0x0 Type: STT_NOTYPE (0x0) diff --git a/crates/rewrite/testfiles/elf/base.rename-symbol b/crates/rewrite/testfiles/elf/base.rename-symbol index e80ee6dd..0475711d 100644 --- a/crates/rewrite/testfiles/elf/base.rename-symbol +++ b/crates/rewrite/testfiles/elf/base.rename-symbol @@ -222,7 +222,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" + Name: 0x0 Version: VER_NDX_LOCAL (0x0) Value: 0x0 Size: 0x0 @@ -605,7 +605,7 @@ SectionHeader { EntrySize: 0x18 Symbol { Index: 0 - Name: "" + Name: 0x0 Value: 0x0 Size: 0x0 Type: STT_NOTYPE (0x0) diff --git a/src/build/elf.rs b/src/build/elf.rs index 04d2862b..9e78d3a3 100644 --- a/src/build/elf.rs +++ b/src/build/elf.rs @@ -1034,15 +1034,21 @@ impl<'data> Builder<'data> { return Err(Error::new( ".symtab.shndx section is needed but not present", )); + } else if symtab_shndx_id.is_some() { + writer.require_symtab_shndx(); } if strtab_id.is_none() && writer.strtab_needed() { return Err(Error::new(".strtab section is needed but not present")); + } else if strtab_id.is_some() { + writer.require_strtab(); } if dynsym_id.is_none() && !out_dynsyms.is_empty() { return Err(Error::new(".dynsym section is needed but not present")); } if dynstr_id.is_none() && writer.dynstr_needed() { return Err(Error::new(".dynstr section is needed but not present")); + } else if dynstr_id.is_some() { + writer.require_dynstr(); } if gnu_verdef_id.is_none() && verdef_count > 0 { return Err(Error::new( diff --git a/src/read/elf/section.rs b/src/read/elf/section.rs index f2d3d78b..ae835528 100644 --- a/src/read/elf/section.rs +++ b/src/read/elf/section.rs @@ -86,6 +86,7 @@ impl<'data, Elf: FileHeader, R: ReadRef<'data>> SectionTable<'data, Elf, R> { /// Return the string table at the given section index. /// + /// Returns an empty string table if the index is 0. /// Returns an error if the section is not a string table. #[inline] pub fn strings( @@ -94,6 +95,9 @@ impl<'data, Elf: FileHeader, R: ReadRef<'data>> SectionTable<'data, Elf, R> { data: R, index: SectionIndex, ) -> read::Result> { + if index == SectionIndex(0) { + return Ok(StringTable::default()); + } self.section(index)? .strings(endian, data)? .read_error("Invalid ELF string section type") diff --git a/src/write/elf/writer.rs b/src/write/elf/writer.rs index 368ee0ea..246f4f54 100644 --- a/src/write/elf/writer.rs +++ b/src/write/elf/writer.rs @@ -641,6 +641,11 @@ impl<'a> Writer<'a> { self.need_strtab } + /// Require the string table even if no strings were added. + pub fn require_strtab(&mut self) { + self.need_strtab = true; + } + /// Reserve the range for the string table. /// /// This range is used for a section named `.strtab`. @@ -719,8 +724,6 @@ impl<'a> Writer<'a> { debug_assert_eq!(self.symtab_offset, 0); debug_assert_eq!(self.symtab_num, 0); self.symtab_num = 1; - // The symtab must link to a strtab. - self.need_strtab = true; SymbolIndex(0) } @@ -741,8 +744,6 @@ impl<'a> Writer<'a> { debug_assert_eq!(self.symtab_shndx_offset, 0); if self.symtab_num == 0 { self.symtab_num = 1; - // The symtab must link to a strtab. - self.need_strtab = true; } let index = self.symtab_num; self.symtab_num += 1; @@ -893,6 +894,12 @@ impl<'a> Writer<'a> { self.need_symtab_shndx } + /// Require the extended section indices for the symbol table even + /// if no section indices are too large. + pub fn require_symtab_shndx(&mut self) { + self.need_symtab_shndx = true; + } + /// Reserve the range for the extended section indices for the symbol table. /// /// This range is used for a section named `.symtab_shndx`. @@ -992,6 +999,11 @@ impl<'a> Writer<'a> { self.need_dynstr } + /// Require the dynamic string table even if no strings were added. + pub fn require_dynstr(&mut self) { + self.need_dynstr = true; + } + /// Reserve the range for the dynamic string table. /// /// This range is used for a section named `.dynstr`. @@ -1000,9 +1012,6 @@ impl<'a> Writer<'a> { /// This must be called after [`Self::add_dynamic_string`]. pub fn reserve_dynstr(&mut self) -> usize { debug_assert_eq!(self.dynstr_offset, 0); - if !self.need_dynstr { - return 0; - } // Start with null string. self.dynstr_data = vec![0]; self.dynstr.write(1, &mut self.dynstr_data); @@ -1014,9 +1023,6 @@ impl<'a> Writer<'a> { /// /// This must be called after [`Self::reserve_dynstr`]. pub fn dynstr_len(&mut self) -> usize { - if !self.need_dynstr { - return 0; - } debug_assert_ne!(self.dynstr_offset, 0); self.dynstr_data.len() } @@ -1087,8 +1093,6 @@ impl<'a> Writer<'a> { debug_assert_eq!(self.dynsym_offset, 0); debug_assert_eq!(self.dynsym_num, 0); self.dynsym_num = 1; - // The symtab must link to a strtab. - self.need_dynstr = true; SymbolIndex(0) } @@ -1105,8 +1109,6 @@ impl<'a> Writer<'a> { debug_assert_eq!(self.dynsym_offset, 0); if self.dynsym_num == 0 { self.dynsym_num = 1; - // The symtab must link to a strtab. - self.need_dynstr = true; } let index = self.dynsym_num; self.dynsym_num += 1;