Skip to content

Commit

Permalink
elfcopy: Add support for SHT_GNU_ATTRIBUTES aka .gnu.attributes section
Browse files Browse the repository at this point in the history
  • Loading branch information
amshafer committed Feb 8, 2023
1 parent e8a36ef commit e162bad
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions crates/examples/src/bin/elfcopy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
let mut in_versym = None;
let mut in_verdef = None;
let mut in_verneed = None;
let mut in_attrib = None;
let mut out_sections = Vec::with_capacity(in_sections.len());
let mut out_sections_index = Vec::with_capacity(in_sections.len());
for (i, in_section) in in_sections.iter().enumerate() {
Expand Down Expand Up @@ -185,6 +186,11 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
debug_assert!(in_verneed.is_some());
index = writer.reserve_gnu_verneed_section_index();
}
elf::SHT_GNU_ATTRIBUTES => {
in_attrib = in_section.gnu_attributes(endian, in_data)?;
debug_assert!(in_attrib.is_some());
index = writer.reserve_gnu_attributes_section_index();
}
other => {
panic!("Unsupported section type {:x}", other);
}
Expand Down Expand Up @@ -344,6 +350,14 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
}
}

// Add one byte for the version field at the start of the section
let mut gnu_attributes_size = 1;
if let Some((_version, mut vsections, _link)) = in_attrib.clone() {
while let Some((section_length, _vendor_name, _tags)) = vsections.next()? {
gnu_attributes_size += section_length.get(endian) as usize;
}
}

// Start reserving file ranges.
writer.reserve_file_header();

Expand All @@ -355,6 +369,7 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
let mut dynamic_addr = 0;
let mut dynsym_addr = 0;
let mut dynstr_addr = 0;
let mut attributes_addr = 0;

let mut alloc_sections = Vec::new();
if in_segments.is_empty() {
Expand Down Expand Up @@ -458,6 +473,10 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
in_section.sh_addralign(endian).into() as usize,
);
}
elf::SHT_GNU_ATTRIBUTES => {
attributes_addr = in_section.sh_addr(endian).into();
writer.reserve_gnu_attributes(gnu_attributes_size);
}
_ => {}
}
}
Expand Down Expand Up @@ -690,6 +709,28 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
debug_assert_eq!(out_sections[i].offset, writer.len());
writer.write(in_section.data(endian, in_data)?);
}
elf::SHT_GNU_ATTRIBUTES => {
writer.write_align_gnu_attributes();
let (version, mut vsections, _link) = in_attrib.clone().unwrap();
writer.write_gnu_attributes_version(version);
println!(".gnu.attributes version {}", version);
while let Some((section_length, vendor_name, mut tags)) = vsections.next()? {
writer.write_gnu_attributes_subsection(
section_length.get(endian),
vendor_name,
);
println!(
"Attrib section with length {}, and vendor {}",
section_length.get(endian),
std::str::from_utf8(vendor_name).unwrap(),
);

while let Some((tag, tag_data)) = tags.next()? {
writer.write_gnu_attributes_tag(tag, tag_data);
println!("Got tag {}", tag);
}
}
}
_ => {}
}
}
Expand Down Expand Up @@ -851,6 +892,9 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
elf::SHT_GNU_VERNEED => {
writer.write_gnu_verneed_section_header(verneed_addr);
}
elf::SHT_GNU_ATTRIBUTES => {
writer.write_gnu_attributes_section_header(attributes_addr);
}
other => {
panic!("Unsupported section type {:x}", other);
}
Expand Down

0 comments on commit e162bad

Please sign in to comment.