mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-19 14:57:15 +03:00
strip out what we don't need
This commit is contained in:
parent
0a2d976d50
commit
17e9866a5f
@ -54,17 +54,22 @@ struct DynamicSymbol {
|
||||
gnu_hash: Option<u32>,
|
||||
}
|
||||
|
||||
struct MySection {
|
||||
in_index: usize,
|
||||
section: SectionHeader64<object::Endianness>,
|
||||
}
|
||||
|
||||
struct Sections {
|
||||
hash: SectionHeader64<object::Endianness>,
|
||||
gnu_hash: SectionHeader64<object::Endianness>,
|
||||
dynsym: SectionHeader64<object::Endianness>,
|
||||
dynstr: SectionHeader64<object::Endianness>,
|
||||
eh_frame: SectionHeader64<object::Endianness>,
|
||||
dynamic: SectionHeader64<object::Endianness>,
|
||||
hash: MySection,
|
||||
gnu_hash: MySection,
|
||||
dynsym: MySection,
|
||||
dynstr: MySection,
|
||||
eh_frame: MySection,
|
||||
dynamic: MySection,
|
||||
}
|
||||
|
||||
impl Sections {
|
||||
fn iter(&self) -> impl Iterator<Item = (usize, &'_ SectionHeader64<object::Endianness>)> + '_ {
|
||||
fn iter(&self) -> impl Iterator<Item = (usize, &'_ MySection)> + '_ {
|
||||
[
|
||||
&self.hash,
|
||||
&self.gnu_hash,
|
||||
@ -96,10 +101,14 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result<Vec<u8>, Box<dyn
|
||||
let in_dynsyms = in_sections.symbols(endian, in_data, elf::SHT_DYNSYM)?;
|
||||
|
||||
let help = |name: &[u8]| {
|
||||
*in_sections
|
||||
let (in_index, section) = in_sections
|
||||
.section_by_name(Endianness::Little, name)
|
||||
.unwrap()
|
||||
.1
|
||||
.unwrap();
|
||||
|
||||
MySection {
|
||||
in_index,
|
||||
section: *section,
|
||||
}
|
||||
};
|
||||
|
||||
let sections = Sections {
|
||||
@ -118,12 +127,12 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result<Vec<u8>, Box<dyn
|
||||
let mut in_dynamic = None;
|
||||
let mut in_hash = None;
|
||||
let mut in_gnu_hash = None;
|
||||
let mut in_versym = None;
|
||||
let mut in_verdef = None;
|
||||
let mut in_verneed = 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() {
|
||||
for (_, my_section) in sections.iter() {
|
||||
let i = my_section.in_index;
|
||||
let in_section = &my_section.section;
|
||||
|
||||
let mut name = None;
|
||||
let index;
|
||||
match in_section.sh_type(endian) {
|
||||
@ -192,21 +201,6 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result<Vec<u8>, Box<dyn
|
||||
debug_assert!(in_gnu_hash.is_some());
|
||||
index = writer.reserve_gnu_hash_section_index();
|
||||
}
|
||||
elf::SHT_GNU_VERSYM => {
|
||||
in_versym = in_section.gnu_versym(endian, in_data)?;
|
||||
debug_assert!(in_versym.is_some());
|
||||
index = writer.reserve_gnu_versym_section_index();
|
||||
}
|
||||
elf::SHT_GNU_VERDEF => {
|
||||
in_verdef = in_section.gnu_verdef(endian, in_data)?;
|
||||
debug_assert!(in_verdef.is_some());
|
||||
index = writer.reserve_gnu_verdef_section_index();
|
||||
}
|
||||
elf::SHT_GNU_VERNEED => {
|
||||
in_verneed = in_section.gnu_verneed(endian, in_data)?;
|
||||
debug_assert!(in_verneed.is_some());
|
||||
index = writer.reserve_gnu_verneed_section_index();
|
||||
}
|
||||
other => {
|
||||
panic!("Unsupported section type {:x}", other);
|
||||
}
|
||||
@ -215,6 +209,8 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result<Vec<u8>, Box<dyn
|
||||
out_sections_index.push(index);
|
||||
}
|
||||
|
||||
dbg!(&out_sections_index);
|
||||
|
||||
// Assign dynamic strings.
|
||||
let mut out_dynamic = Vec::new();
|
||||
if let Some((in_dynamic, link)) = in_dynamic {
|
||||
@ -240,43 +236,6 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result<Vec<u8>, Box<dyn
|
||||
|
||||
// Assign dynamic symbol indices.
|
||||
let mut out_dynsyms = Vec::with_capacity(in_dynsyms.len());
|
||||
for (i, in_dynsym) in in_dynsyms.iter().enumerate().skip(1) {
|
||||
dbg!(i, in_dynsym);
|
||||
let section = match in_dynsyms.symbol_section(endian, in_dynsym, i)? {
|
||||
Some(in_section) => {
|
||||
// Skip symbols for sections we aren't copying.
|
||||
if out_sections_index[in_section.0].0 == 0 {
|
||||
dbg!(&in_section);
|
||||
continue;
|
||||
}
|
||||
Some(out_sections_index[in_section.0])
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
let mut name = None;
|
||||
let mut hash = None;
|
||||
let mut gnu_hash = None;
|
||||
if in_dynsym.st_name(endian) != 0 {
|
||||
let in_name = in_dynsyms.symbol_name(endian, in_dynsym)?;
|
||||
name = Some(writer.add_dynamic_string(in_name));
|
||||
if !in_name.is_empty() {
|
||||
hash = Some(elf::hash(in_name));
|
||||
if !in_dynsym.is_undefined(endian) {
|
||||
gnu_hash = Some(elf::gnu_hash(in_name));
|
||||
}
|
||||
}
|
||||
};
|
||||
out_dynsyms.push((
|
||||
Origin::Real,
|
||||
DynamicSymbol {
|
||||
in_sym: i,
|
||||
name,
|
||||
section,
|
||||
hash,
|
||||
gnu_hash,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
for (j, name) in custom_names.iter().enumerate() {
|
||||
let i = in_dynsyms.len().saturating_sub(1) + j;
|
||||
@ -315,19 +274,12 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result<Vec<u8>, Box<dyn
|
||||
out_dynsyms_index[out_dynsym.in_sym] = writer.reserve_dynamic_symbol_index();
|
||||
}
|
||||
|
||||
dbg!(
|
||||
in_dynsyms.len() + custom_names.len(),
|
||||
in_dynsyms.len(),
|
||||
custom_names.len()
|
||||
);
|
||||
|
||||
// Hash parameters.
|
||||
let hash_index_base = out_dynsyms
|
||||
.first()
|
||||
.map(|(_, sym)| out_dynsyms_index[sym.in_sym].0)
|
||||
.unwrap_or(0);
|
||||
let hash_chain_count = writer.dynamic_symbol_count();
|
||||
dbg!(hash_index_base, hash_chain_count);
|
||||
|
||||
// GNU hash parameters.
|
||||
let gnu_hash_index_base = out_dynsyms
|
||||
@ -350,11 +302,17 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result<Vec<u8>, Box<dyn
|
||||
let section = match in_syms.symbol_section(endian, in_sym, i)? {
|
||||
Some(in_section) => {
|
||||
// Skip symbols for sections we aren't copying.
|
||||
if out_sections_index[in_section.0].0 == 0 {
|
||||
out_syms_index.push(Default::default());
|
||||
continue;
|
||||
match out_sections_index.get(in_section.0) {
|
||||
None => continue,
|
||||
Some(index) => {
|
||||
if index.0 == 0 {
|
||||
out_syms_index.push(Default::default());
|
||||
continue;
|
||||
} else {
|
||||
Some(out_sections_index[in_section.0])
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(out_sections_index[in_section.0])
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
@ -388,120 +346,146 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result<Vec<u8>, Box<dyn
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Symbol version parameters.
|
||||
let mut verdef_count = 0;
|
||||
let mut verdaux_count = 0;
|
||||
if let Some((mut verdefs, link)) = in_verdef.clone() {
|
||||
let strings = in_sections.strings(endian, in_data, link)?;
|
||||
while let Some((verdef, mut verdauxs)) = verdefs.next()? {
|
||||
assert!(verdef.vd_cnt.get(endian) > 0);
|
||||
verdef_count += 1;
|
||||
while let Some(verdaux) = verdauxs.next()? {
|
||||
writer.add_dynamic_string(verdaux.name(endian, strings)?);
|
||||
verdaux_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut verneed_count = 0;
|
||||
let mut vernaux_count = 0;
|
||||
if let Some((mut verneeds, link)) = in_verneed.clone() {
|
||||
let strings = in_sections.strings(endian, in_data, link)?;
|
||||
while let Some((verneed, mut vernauxs)) = verneeds.next()? {
|
||||
writer.add_dynamic_string(verneed.file(endian, strings)?);
|
||||
verneed_count += 1;
|
||||
while let Some(vernaux) = vernauxs.next()? {
|
||||
writer.add_dynamic_string(vernaux.name(endian, strings)?);
|
||||
vernaux_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start reserving file ranges.
|
||||
writer.reserve_file_header();
|
||||
|
||||
let mut hash_addr = 0;
|
||||
let mut gnu_hash_addr = 0;
|
||||
let mut versym_addr = 0;
|
||||
let mut verdef_addr = 0;
|
||||
let mut verneed_addr = 0;
|
||||
let mut dynamic_addr = 0;
|
||||
let mut dynsym_addr = 0;
|
||||
let mut dynstr_addr = 0;
|
||||
|
||||
let mut alloc_sections = Vec::new();
|
||||
if in_segments.is_empty() {
|
||||
// Reserve sections at any offset.
|
||||
for (i, in_section) in in_sections.iter().enumerate() {
|
||||
// We don't support moving program headers.
|
||||
assert_eq!(in_elf.e_phoff(endian), writer.reserved_len() as u64);
|
||||
writer.reserve_program_headers(in_segments.len() as u32);
|
||||
|
||||
// Reserve alloc sections at original offsets.
|
||||
let alloc_sections: Vec<_> = in_sections
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, s)| s.sh_flags(endian) & u64::from(elf::SHF_ALLOC) != 0)
|
||||
.collect();
|
||||
|
||||
if true {
|
||||
let mut extra_offset: usize = 0;
|
||||
|
||||
// elf::SHT_HASH
|
||||
let in_section = §ions.hash.section;
|
||||
writer.reserve_until(in_section.sh_offset(endian) as usize);
|
||||
|
||||
hash_addr = in_section.sh_addr(endian);
|
||||
let hash = in_hash.as_ref().unwrap();
|
||||
// writer.reserve_hash(hash.bucket_count.get(endian), hash_chain_count);
|
||||
let reserved_before = writer.reserved_len();
|
||||
writer.reserve_hash(3, 13);
|
||||
let reserved_after = writer.reserved_len();
|
||||
|
||||
extra_offset += {
|
||||
let actual_size = reserved_after - reserved_before;
|
||||
|
||||
actual_size - sections.hash.section.sh_size(endian) as usize
|
||||
};
|
||||
|
||||
// elf::SHT_GNU_HASH
|
||||
let in_section = §ions.gnu_hash.section;
|
||||
writer.reserve_until(in_section.sh_offset(endian) as usize + extra_offset);
|
||||
|
||||
gnu_hash_addr = in_section.sh_addr(endian);
|
||||
let hash = in_gnu_hash.as_ref().unwrap();
|
||||
let reserved_before = writer.reserved_len();
|
||||
writer.reserve_gnu_hash(
|
||||
hash.bloom_count.get(endian),
|
||||
hash.bucket_count.get(endian),
|
||||
gnu_hash_symbol_count,
|
||||
);
|
||||
let reserved_after = writer.reserved_len();
|
||||
|
||||
extra_offset += {
|
||||
let actual_size = reserved_after - reserved_before;
|
||||
|
||||
actual_size - sections.gnu_hash.section.sh_size(endian) as usize
|
||||
};
|
||||
|
||||
// elf::SHT_DYNSYM
|
||||
let in_section = §ions.dynsym.section;
|
||||
writer.reserve_until(in_section.sh_offset(endian) as usize + extra_offset);
|
||||
|
||||
dynsym_addr = in_section.sh_addr(endian);
|
||||
let reserved_before = writer.reserved_len();
|
||||
writer.reserve_dynsym();
|
||||
let reserved_after = writer.reserved_len();
|
||||
|
||||
extra_offset += {
|
||||
let actual_size = reserved_after - reserved_before;
|
||||
|
||||
actual_size - sections.dynsym.section.sh_size(endian) as usize
|
||||
};
|
||||
|
||||
// elf::SHT_STRTAB
|
||||
let in_section = §ions.dynstr.section;
|
||||
writer.reserve_until(in_section.sh_offset(endian) as usize + extra_offset);
|
||||
|
||||
dynstr_addr = in_section.sh_addr(endian);
|
||||
let reserved_before = writer.reserved_len();
|
||||
writer.reserve_dynstr();
|
||||
let reserved_after = writer.reserved_len();
|
||||
|
||||
extra_offset += {
|
||||
let actual_size = reserved_after - reserved_before;
|
||||
|
||||
actual_size - sections.dynstr.section.sh_size(endian) as usize
|
||||
};
|
||||
|
||||
// elf::SHT_PROGBITS
|
||||
let in_section = §ions.eh_frame.section;
|
||||
writer.reserve_until(in_section.sh_offset(endian) as usize + extra_offset);
|
||||
// out_sections[*i].offset = writer.reserve(in_section.sh_size(endian) as usize, 1);
|
||||
let reserved_before = writer.reserved_len();
|
||||
let todo_unused = writer.reserve(in_section.sh_size(endian) as usize, 1);
|
||||
let reserved_after = writer.reserved_len();
|
||||
|
||||
extra_offset += {
|
||||
let actual_size = reserved_after - reserved_before;
|
||||
|
||||
actual_size - sections.eh_frame.section.sh_size(endian) as usize
|
||||
};
|
||||
|
||||
// elf::SHT_DYNAMIC
|
||||
let in_section = §ions.dynamic.section;
|
||||
writer.reserve_until(in_section.sh_offset(endian) as usize + extra_offset);
|
||||
|
||||
dynamic_addr = in_section.sh_addr(endian);
|
||||
writer.reserve_dynamic(out_dynamic.len());
|
||||
} else {
|
||||
for (i, in_section) in alloc_sections.iter() {
|
||||
writer.reserve_until(in_section.sh_offset(endian) as usize);
|
||||
match in_section.sh_type(endian) {
|
||||
elf::SHT_PROGBITS | elf::SHT_NOTE | elf::SHT_INIT_ARRAY | elf::SHT_FINI_ARRAY => {
|
||||
out_sections[i].offset = writer.reserve(
|
||||
in_section.sh_size(endian) as usize,
|
||||
in_section.sh_addralign(endian) as usize,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We don't support moving program headers.
|
||||
assert_eq!(in_elf.e_phoff(endian), writer.reserved_len() as u64);
|
||||
writer.reserve_program_headers(in_segments.len() as u32);
|
||||
|
||||
// Reserve alloc sections at original offsets.
|
||||
alloc_sections = in_sections
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, s)| s.sh_flags(endian) & u64::from(elf::SHF_ALLOC) != 0)
|
||||
.collect();
|
||||
// The data for alloc sections may need to be written in a different order
|
||||
// from their section headers.
|
||||
alloc_sections.sort_by_key(|(_, x)| x.sh_offset(endian));
|
||||
dbg!(alloc_sections.len());
|
||||
for (i, in_section) in alloc_sections.iter() {
|
||||
dbg!(i, in_section);
|
||||
writer.reserve_until(in_section.sh_offset(endian) as usize);
|
||||
match dbg!(in_section.sh_type(endian)) {
|
||||
elf::SHT_PROGBITS | elf::SHT_NOTE | elf::SHT_INIT_ARRAY | elf::SHT_FINI_ARRAY => {
|
||||
dbg!(i);
|
||||
out_sections[*i].offset =
|
||||
writer.reserve(in_section.sh_size(endian) as usize, 1);
|
||||
}
|
||||
elf::SHT_NOBITS => {
|
||||
out_sections[*i].offset = writer.reserved_len();
|
||||
}
|
||||
elf::SHT_REL => {
|
||||
let (rels, _link) = in_section.rel(endian, in_data)?.unwrap();
|
||||
out_sections[*i].offset = writer.reserve_relocations(rels.len(), false);
|
||||
}
|
||||
elf::SHT_RELA => {
|
||||
let (rels, _link) = in_section.rela(endian, in_data)?.unwrap();
|
||||
out_sections[*i].offset = writer.reserve_relocations(rels.len(), true);
|
||||
}
|
||||
elf::SHT_DYNAMIC => {
|
||||
dynamic_addr = in_section.sh_addr(endian).into();
|
||||
dynamic_addr = in_section.sh_addr(endian);
|
||||
writer.reserve_dynamic(out_dynamic.len());
|
||||
}
|
||||
elf::SHT_DYNSYM if *i == in_dynsyms.section().0 => {
|
||||
dynsym_addr = in_section.sh_addr(endian).into();
|
||||
dynsym_addr = in_section.sh_addr(endian);
|
||||
writer.reserve_dynsym();
|
||||
}
|
||||
elf::SHT_STRTAB if *i == in_dynsyms.string_section().0 => {
|
||||
dbg!("strtab");
|
||||
dynstr_addr = in_section.sh_addr(endian).into();
|
||||
dynstr_addr = in_section.sh_addr(endian);
|
||||
writer.reserve_dynstr();
|
||||
}
|
||||
elf::SHT_HASH => {
|
||||
hash_addr = in_section.sh_addr(endian).into();
|
||||
dbg!(writer.reserved_len());
|
||||
dbg!(hash_addr);
|
||||
hash_addr = in_section.sh_addr(endian);
|
||||
let hash = in_hash.as_ref().unwrap();
|
||||
// writer.reserve_hash(hash.bucket_count.get(endian), hash_chain_count);
|
||||
writer.reserve_hash(3, 13);
|
||||
}
|
||||
elf::SHT_GNU_HASH => {
|
||||
gnu_hash_addr = in_section.sh_addr(endian).into();
|
||||
dbg!(writer.reserved_len());
|
||||
dbg!(gnu_hash_addr);
|
||||
gnu_hash_addr = in_section.sh_addr(endian);
|
||||
let hash = in_gnu_hash.as_ref().unwrap();
|
||||
writer.reserve_gnu_hash(
|
||||
hash.bloom_count.get(endian),
|
||||
@ -509,38 +493,26 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result<Vec<u8>, Box<dyn
|
||||
gnu_hash_symbol_count,
|
||||
);
|
||||
}
|
||||
elf::SHT_GNU_VERSYM => {
|
||||
versym_addr = in_section.sh_addr(endian).into();
|
||||
writer.reserve_gnu_versym();
|
||||
}
|
||||
elf::SHT_GNU_VERDEF => {
|
||||
verdef_addr = in_section.sh_addr(endian).into();
|
||||
writer.reserve_gnu_verdef(verdef_count, verdaux_count);
|
||||
}
|
||||
elf::SHT_GNU_VERNEED => {
|
||||
verneed_addr = in_section.sh_addr(endian).into();
|
||||
writer.reserve_gnu_verneed(verneed_count, vernaux_count);
|
||||
}
|
||||
other => {
|
||||
panic!("Unsupported alloc section index {}, type {}", *i, other);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reserve non-alloc sections at any offset.
|
||||
for (i, in_section) in in_sections.iter().enumerate() {
|
||||
if in_section.sh_flags(endian) & u64::from(elf::SHF_ALLOC) != 0 {
|
||||
continue;
|
||||
}
|
||||
match in_section.sh_type(endian) {
|
||||
elf::SHT_PROGBITS | elf::SHT_NOTE => {
|
||||
out_sections[i].offset = writer.reserve(
|
||||
in_section.sh_size(endian) as usize,
|
||||
in_section.sh_addralign(endian) as usize,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
// Reserve non-alloc sections at any offset.
|
||||
for (i, in_section) in in_sections.iter().enumerate() {
|
||||
if in_section.sh_flags(endian) & u64::from(elf::SHF_ALLOC) != 0 {
|
||||
continue;
|
||||
}
|
||||
match in_section.sh_type(endian) {
|
||||
elf::SHT_PROGBITS | elf::SHT_NOTE => {
|
||||
out_sections[i].offset = writer.reserve(
|
||||
in_section.sh_size(endian) as usize,
|
||||
in_section.sh_addralign(endian) as usize,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -548,23 +520,6 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result<Vec<u8>, Box<dyn
|
||||
writer.reserve_symtab_shndx();
|
||||
writer.reserve_strtab();
|
||||
|
||||
for (i, in_section) in in_sections.iter().enumerate() {
|
||||
if !in_segments.is_empty() && in_section.sh_flags(endian) & u64::from(elf::SHF_ALLOC) != 0 {
|
||||
continue;
|
||||
}
|
||||
match in_section.sh_type(endian) {
|
||||
elf::SHT_REL => {
|
||||
let (rels, _link) = in_section.rel(endian, in_data)?.unwrap();
|
||||
out_sections[i].offset = writer.reserve_relocations(rels.len(), false);
|
||||
}
|
||||
elf::SHT_RELA => {
|
||||
let (rels, _link) = in_section.rela(endian, in_data)?.unwrap();
|
||||
out_sections[i].offset = writer.reserve_relocations(rels.len(), true);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
writer.reserve_shstrtab();
|
||||
writer.reserve_section_headers();
|
||||
|
||||
@ -573,210 +528,105 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result<Vec<u8>, Box<dyn
|
||||
abi_version: in_elf.e_ident().abi_version,
|
||||
e_type: in_elf.e_type(endian),
|
||||
e_machine: in_elf.e_machine(endian),
|
||||
e_entry: in_elf.e_entry(endian).into(),
|
||||
e_entry: in_elf.e_entry(endian),
|
||||
e_flags: in_elf.e_flags(endian),
|
||||
})?;
|
||||
|
||||
if in_segments.is_empty() {
|
||||
for (i, in_section) in in_sections.iter().enumerate() {
|
||||
match in_section.sh_type(endian) {
|
||||
elf::SHT_PROGBITS | elf::SHT_NOTE | elf::SHT_INIT_ARRAY | elf::SHT_FINI_ARRAY => {
|
||||
writer.write_align(in_section.sh_addralign(endian) as usize);
|
||||
debug_assert_eq!(out_sections[i].offset, writer.len());
|
||||
writer.write(in_section.data(endian, in_data)?);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
writer.write_align_program_headers();
|
||||
for in_segment in in_segments {
|
||||
writer.write_program_header(&object::write::elf::ProgramHeader {
|
||||
p_type: in_segment.p_type(endian),
|
||||
p_flags: in_segment.p_flags(endian),
|
||||
p_offset: in_segment.p_offset(endian).into(),
|
||||
p_vaddr: in_segment.p_vaddr(endian).into(),
|
||||
p_paddr: in_segment.p_paddr(endian).into(),
|
||||
p_filesz: in_segment.p_filesz(endian).into(),
|
||||
p_memsz: in_segment.p_memsz(endian).into(),
|
||||
p_align: in_segment.p_align(endian).into(),
|
||||
});
|
||||
}
|
||||
writer.write_align_program_headers();
|
||||
for in_segment in in_segments {
|
||||
writer.write_program_header(&object::write::elf::ProgramHeader {
|
||||
p_type: in_segment.p_type(endian),
|
||||
p_flags: in_segment.p_flags(endian),
|
||||
p_offset: in_segment.p_offset(endian),
|
||||
p_vaddr: in_segment.p_vaddr(endian),
|
||||
p_paddr: in_segment.p_paddr(endian),
|
||||
p_filesz: in_segment.p_filesz(endian),
|
||||
p_memsz: in_segment.p_memsz(endian),
|
||||
p_align: in_segment.p_align(endian),
|
||||
});
|
||||
}
|
||||
|
||||
for (i, in_section) in alloc_sections.iter() {
|
||||
writer.pad_until(in_section.sh_offset(endian) as usize);
|
||||
match in_section.sh_type(endian) {
|
||||
elf::SHT_PROGBITS | elf::SHT_NOTE | elf::SHT_INIT_ARRAY | elf::SHT_FINI_ARRAY => {
|
||||
debug_assert_eq!(out_sections[*i].offset, writer.len());
|
||||
writer.write(in_section.data(endian, in_data)?);
|
||||
}
|
||||
elf::SHT_NOBITS => {}
|
||||
elf::SHT_REL => {
|
||||
let (rels, _link) = in_section.rel(endian, in_data)?.unwrap();
|
||||
writer.write_align_relocation();
|
||||
for rel in rels {
|
||||
let in_sym = rel.r_sym(endian);
|
||||
let out_sym = if in_sym != 0 {
|
||||
out_dynsyms_index[in_sym as usize].0
|
||||
} else {
|
||||
0
|
||||
};
|
||||
writer.write_relocation(
|
||||
false,
|
||||
&object::write::elf::Rel {
|
||||
r_offset: rel.r_offset(endian).into(),
|
||||
r_sym: out_sym,
|
||||
r_type: rel.r_type(endian),
|
||||
r_addend: 0,
|
||||
},
|
||||
);
|
||||
for (i, in_section) in alloc_sections.iter() {
|
||||
writer.pad_until(in_section.sh_offset(endian) as usize);
|
||||
match in_section.sh_type(endian) {
|
||||
elf::SHT_PROGBITS | elf::SHT_NOTE | elf::SHT_INIT_ARRAY | elf::SHT_FINI_ARRAY => {
|
||||
debug_assert_eq!(out_sections[*i].offset, writer.len());
|
||||
writer.write(in_section.data(endian, in_data)?);
|
||||
}
|
||||
elf::SHT_DYNAMIC => {
|
||||
for d in &out_dynamic {
|
||||
if let Some(string) = d.string {
|
||||
writer.write_dynamic_string(d.tag, string);
|
||||
} else {
|
||||
// TODO: fix values
|
||||
let val = d.val;
|
||||
writer.write_dynamic(d.tag, val);
|
||||
}
|
||||
}
|
||||
elf::SHT_RELA => {
|
||||
let (rels, _link) = in_section.rela(endian, in_data)?.unwrap();
|
||||
writer.write_align_relocation();
|
||||
for rel in rels {
|
||||
let in_sym = rel.r_sym(endian, is_mips64el);
|
||||
let out_sym = if in_sym != 0 {
|
||||
out_dynsyms_index[in_sym as usize].0
|
||||
} else {
|
||||
0
|
||||
};
|
||||
writer.write_relocation(
|
||||
true,
|
||||
&object::write::elf::Rel {
|
||||
r_offset: rel.r_offset(endian).into(),
|
||||
r_sym: out_sym,
|
||||
r_type: rel.r_type(endian, is_mips64el),
|
||||
r_addend: rel.r_addend(endian).into(),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
elf::SHT_DYNAMIC => {
|
||||
for d in &out_dynamic {
|
||||
if let Some(string) = d.string {
|
||||
writer.write_dynamic_string(d.tag, string);
|
||||
} else {
|
||||
// TODO: fix values
|
||||
let val = d.val;
|
||||
writer.write_dynamic(d.tag, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
elf::SHT_DYNSYM if *i == in_dynsyms.section().0 => {
|
||||
writer.write_null_dynamic_symbol();
|
||||
dbg!("here");
|
||||
for (_, sym) in &out_dynsyms {
|
||||
let in_dynsym = in_dynsyms.symbol(sym.in_sym)?;
|
||||
writer.write_dynamic_symbol(&object::write::elf::Sym {
|
||||
name: sym.name,
|
||||
section: sym.section,
|
||||
st_info: in_dynsym.st_info(),
|
||||
st_other: in_dynsym.st_other(),
|
||||
st_shndx: in_dynsym.st_shndx(endian),
|
||||
st_value: in_dynsym.st_value(endian).into(),
|
||||
st_size: in_dynsym.st_size(endian).into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
elf::SHT_STRTAB if *i == in_dynsyms.string_section().0 => {
|
||||
writer.write_dynstr();
|
||||
}
|
||||
elf::SHT_HASH => {
|
||||
dbg!("here at the hash");
|
||||
let hash = in_hash.as_ref().unwrap();
|
||||
writer.write_hash(hash.bucket_count.get(endian), hash_chain_count, |index| {
|
||||
out_dynsyms
|
||||
.get(index.checked_sub(hash_index_base)? as usize)?
|
||||
.1
|
||||
.hash
|
||||
}
|
||||
elf::SHT_DYNSYM if *i == in_dynsyms.section().0 => {
|
||||
writer.write_null_dynamic_symbol();
|
||||
dbg!("here");
|
||||
for (_, sym) in &out_dynsyms {
|
||||
let in_dynsym = in_dynsyms.symbol(sym.in_sym)?;
|
||||
writer.write_dynamic_symbol(&object::write::elf::Sym {
|
||||
name: sym.name,
|
||||
section: sym.section,
|
||||
st_info: in_dynsym.st_info(),
|
||||
st_other: in_dynsym.st_other(),
|
||||
st_shndx: in_dynsym.st_shndx(endian),
|
||||
st_value: in_dynsym.st_value(endian),
|
||||
st_size: in_dynsym.st_size(endian),
|
||||
});
|
||||
}
|
||||
elf::SHT_GNU_HASH => {
|
||||
dbg!("here");
|
||||
let gnu_hash = in_gnu_hash.as_ref().unwrap();
|
||||
writer.write_gnu_hash(
|
||||
gnu_hash_symbol_base,
|
||||
gnu_hash.bloom_shift.get(endian),
|
||||
gnu_hash.bloom_count.get(endian),
|
||||
gnu_hash.bucket_count.get(endian),
|
||||
gnu_hash_symbol_count,
|
||||
|index| {
|
||||
out_dynsyms[gnu_hash_index_base + index as usize]
|
||||
.1
|
||||
.gnu_hash
|
||||
.unwrap()
|
||||
},
|
||||
);
|
||||
}
|
||||
elf::SHT_GNU_VERSYM => {
|
||||
dbg!("here");
|
||||
let (in_versym, _) = in_versym.as_ref().unwrap();
|
||||
writer.write_null_gnu_versym();
|
||||
for (_, out_dynsym) in &out_dynsyms {
|
||||
writer.write_gnu_versym(
|
||||
in_versym.get(out_dynsym.in_sym).unwrap().0.get(endian),
|
||||
);
|
||||
}
|
||||
}
|
||||
elf::SHT_GNU_VERDEF => {
|
||||
let (mut verdefs, link) = in_verdef.clone().unwrap();
|
||||
let strings = in_sections.strings(endian, in_data, link)?;
|
||||
writer.write_align_gnu_verdef();
|
||||
while let Some((verdef, mut verdauxs)) = verdefs.next()? {
|
||||
let verdaux = verdauxs.next()?.unwrap();
|
||||
writer.write_gnu_verdef(&object::write::elf::Verdef {
|
||||
version: verdef.vd_version.get(endian),
|
||||
flags: verdef.vd_flags.get(endian),
|
||||
index: verdef.vd_ndx.get(endian),
|
||||
aux_count: verdef.vd_cnt.get(endian),
|
||||
name: writer.get_dynamic_string(verdaux.name(endian, strings)?),
|
||||
});
|
||||
while let Some(verdaux) = verdauxs.next()? {
|
||||
writer.write_gnu_verdaux(
|
||||
writer.get_dynamic_string(verdaux.name(endian, strings)?),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
elf::SHT_GNU_VERNEED => {
|
||||
let (mut verneeds, link) = in_verneed.clone().unwrap();
|
||||
let strings = in_sections.strings(endian, in_data, link)?;
|
||||
writer.write_align_gnu_verneed();
|
||||
while let Some((verneed, mut vernauxs)) = verneeds.next()? {
|
||||
writer.write_gnu_verneed(&object::write::elf::Verneed {
|
||||
version: verneed.vn_version.get(endian),
|
||||
aux_count: verneed.vn_cnt.get(endian),
|
||||
file: writer.get_dynamic_string(verneed.file(endian, strings)?),
|
||||
});
|
||||
while let Some(vernaux) = vernauxs.next()? {
|
||||
writer.write_gnu_vernaux(&object::write::elf::Vernaux {
|
||||
flags: vernaux.vna_flags.get(endian),
|
||||
index: vernaux.vna_other.get(endian),
|
||||
name: writer.get_dynamic_string(vernaux.name(endian, strings)?),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
other => {
|
||||
panic!("Unsupported alloc section type {:x}", other);
|
||||
}
|
||||
}
|
||||
elf::SHT_STRTAB if *i == in_dynsyms.string_section().0 => {
|
||||
writer.write_dynstr();
|
||||
}
|
||||
elf::SHT_HASH => {
|
||||
dbg!("here at the hash");
|
||||
let hash = in_hash.as_ref().unwrap();
|
||||
writer.write_hash(hash.bucket_count.get(endian), hash_chain_count, |index| {
|
||||
out_dynsyms
|
||||
.get(index.checked_sub(hash_index_base)? as usize)?
|
||||
.1
|
||||
.hash
|
||||
});
|
||||
}
|
||||
elf::SHT_GNU_HASH => {
|
||||
dbg!("here");
|
||||
let gnu_hash = in_gnu_hash.as_ref().unwrap();
|
||||
writer.write_gnu_hash(
|
||||
gnu_hash_symbol_base,
|
||||
gnu_hash.bloom_shift.get(endian),
|
||||
gnu_hash.bloom_count.get(endian),
|
||||
gnu_hash.bucket_count.get(endian),
|
||||
gnu_hash_symbol_count,
|
||||
|index| {
|
||||
out_dynsyms[gnu_hash_index_base + index as usize]
|
||||
.1
|
||||
.gnu_hash
|
||||
.unwrap()
|
||||
},
|
||||
);
|
||||
}
|
||||
other => {
|
||||
panic!("Unsupported alloc section type {:x}", other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i, in_section) in in_sections.iter().enumerate() {
|
||||
if in_section.sh_flags(endian) & u64::from(elf::SHF_ALLOC) != 0 {
|
||||
continue;
|
||||
}
|
||||
match in_section.sh_type(endian) {
|
||||
elf::SHT_PROGBITS | elf::SHT_NOTE => {
|
||||
writer.write_align(in_section.sh_addralign(endian) as usize);
|
||||
debug_assert_eq!(out_sections[i].offset, writer.len());
|
||||
writer.write(in_section.data(endian, in_data)?);
|
||||
}
|
||||
_ => {}
|
||||
for (i, in_section) in in_sections.iter().enumerate() {
|
||||
if in_section.sh_flags(endian) & u64::from(elf::SHF_ALLOC) != 0 {
|
||||
continue;
|
||||
}
|
||||
match in_section.sh_type(endian) {
|
||||
elf::SHT_PROGBITS | elf::SHT_NOTE => {
|
||||
writer.write_align(in_section.sh_addralign(endian) as usize);
|
||||
debug_assert_eq!(out_sections[i].offset, writer.len());
|
||||
writer.write(in_section.data(endian, in_data)?);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -789,8 +639,8 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result<Vec<u8>, Box<dyn
|
||||
st_info: in_sym.st_info(),
|
||||
st_other: in_sym.st_other(),
|
||||
st_shndx: in_sym.st_shndx(endian),
|
||||
st_value: in_sym.st_value(endian).into(),
|
||||
st_size: in_sym.st_size(endian).into(),
|
||||
st_value: in_sym.st_value(endian),
|
||||
st_size: in_sym.st_size(endian),
|
||||
});
|
||||
}
|
||||
|
||||
@ -890,14 +740,14 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result<Vec<u8>, Box<dyn
|
||||
writer.write_section_header(&object::write::elf::SectionHeader {
|
||||
name: out_section.name,
|
||||
sh_type: in_section.sh_type(endian),
|
||||
sh_flags: in_section.sh_flags(endian).into(),
|
||||
sh_addr: in_section.sh_addr(endian).into(),
|
||||
sh_flags: in_section.sh_flags(endian),
|
||||
sh_addr: in_section.sh_addr(endian),
|
||||
sh_offset: out_section.offset as u64,
|
||||
sh_size: in_section.sh_size(endian).into(),
|
||||
sh_size: in_section.sh_size(endian),
|
||||
sh_link,
|
||||
sh_info,
|
||||
sh_addralign: in_section.sh_addralign(endian).into(),
|
||||
sh_entsize: in_section.sh_entsize(endian).into(),
|
||||
sh_addralign: in_section.sh_addralign(endian),
|
||||
sh_entsize: in_section.sh_entsize(endian),
|
||||
});
|
||||
}
|
||||
elf::SHT_STRTAB => {
|
||||
@ -936,21 +786,11 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result<Vec<u8>, Box<dyn
|
||||
writer.write_dynamic_section_header(dynamic_addr);
|
||||
}
|
||||
elf::SHT_HASH => {
|
||||
dbg!("this hash");
|
||||
writer.write_hash_section_header(hash_addr);
|
||||
}
|
||||
elf::SHT_GNU_HASH => {
|
||||
writer.write_gnu_hash_section_header(gnu_hash_addr);
|
||||
}
|
||||
elf::SHT_GNU_VERSYM => {
|
||||
writer.write_gnu_versym_section_header(versym_addr);
|
||||
}
|
||||
elf::SHT_GNU_VERDEF => {
|
||||
writer.write_gnu_verdef_section_header(verdef_addr);
|
||||
}
|
||||
elf::SHT_GNU_VERNEED => {
|
||||
writer.write_gnu_verneed_section_header(verneed_addr);
|
||||
}
|
||||
other => {
|
||||
panic!("Unsupported section type {:x}", other);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user