Skip to content

Commit e162bad

Browse files
committed
elfcopy: Add support for SHT_GNU_ATTRIBUTES aka .gnu.attributes section
1 parent e8a36ef commit e162bad

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

crates/examples/src/bin/elfcopy.rs

+44
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
101101
let mut in_versym = None;
102102
let mut in_verdef = None;
103103
let mut in_verneed = None;
104+
let mut in_attrib = None;
104105
let mut out_sections = Vec::with_capacity(in_sections.len());
105106
let mut out_sections_index = Vec::with_capacity(in_sections.len());
106107
for (i, in_section) in in_sections.iter().enumerate() {
@@ -185,6 +186,11 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
185186
debug_assert!(in_verneed.is_some());
186187
index = writer.reserve_gnu_verneed_section_index();
187188
}
189+
elf::SHT_GNU_ATTRIBUTES => {
190+
in_attrib = in_section.gnu_attributes(endian, in_data)?;
191+
debug_assert!(in_attrib.is_some());
192+
index = writer.reserve_gnu_attributes_section_index();
193+
}
188194
other => {
189195
panic!("Unsupported section type {:x}", other);
190196
}
@@ -344,6 +350,14 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
344350
}
345351
}
346352

353+
// Add one byte for the version field at the start of the section
354+
let mut gnu_attributes_size = 1;
355+
if let Some((_version, mut vsections, _link)) = in_attrib.clone() {
356+
while let Some((section_length, _vendor_name, _tags)) = vsections.next()? {
357+
gnu_attributes_size += section_length.get(endian) as usize;
358+
}
359+
}
360+
347361
// Start reserving file ranges.
348362
writer.reserve_file_header();
349363

@@ -355,6 +369,7 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
355369
let mut dynamic_addr = 0;
356370
let mut dynsym_addr = 0;
357371
let mut dynstr_addr = 0;
372+
let mut attributes_addr = 0;
358373

359374
let mut alloc_sections = Vec::new();
360375
if in_segments.is_empty() {
@@ -458,6 +473,10 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
458473
in_section.sh_addralign(endian).into() as usize,
459474
);
460475
}
476+
elf::SHT_GNU_ATTRIBUTES => {
477+
attributes_addr = in_section.sh_addr(endian).into();
478+
writer.reserve_gnu_attributes(gnu_attributes_size);
479+
}
461480
_ => {}
462481
}
463482
}
@@ -690,6 +709,28 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
690709
debug_assert_eq!(out_sections[i].offset, writer.len());
691710
writer.write(in_section.data(endian, in_data)?);
692711
}
712+
elf::SHT_GNU_ATTRIBUTES => {
713+
writer.write_align_gnu_attributes();
714+
let (version, mut vsections, _link) = in_attrib.clone().unwrap();
715+
writer.write_gnu_attributes_version(version);
716+
println!(".gnu.attributes version {}", version);
717+
while let Some((section_length, vendor_name, mut tags)) = vsections.next()? {
718+
writer.write_gnu_attributes_subsection(
719+
section_length.get(endian),
720+
vendor_name,
721+
);
722+
println!(
723+
"Attrib section with length {}, and vendor {}",
724+
section_length.get(endian),
725+
std::str::from_utf8(vendor_name).unwrap(),
726+
);
727+
728+
while let Some((tag, tag_data)) = tags.next()? {
729+
writer.write_gnu_attributes_tag(tag, tag_data);
730+
println!("Got tag {}", tag);
731+
}
732+
}
733+
}
693734
_ => {}
694735
}
695736
}
@@ -851,6 +892,9 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
851892
elf::SHT_GNU_VERNEED => {
852893
writer.write_gnu_verneed_section_header(verneed_addr);
853894
}
895+
elf::SHT_GNU_ATTRIBUTES => {
896+
writer.write_gnu_attributes_section_header(attributes_addr);
897+
}
854898
other => {
855899
panic!("Unsupported section type {:x}", other);
856900
}

0 commit comments

Comments
 (0)