From 9efa02c56927bf320598ab7dddf6b70533d06fda Mon Sep 17 00:00:00 2001 From: Folkert Date: Sat, 20 Aug 2022 21:18:08 +0200 Subject: [PATCH] add more sections --- crates/linker/src/generate_dylib.rs | 352 +++++++++++----------------- 1 file changed, 138 insertions(+), 214 deletions(-) diff --git a/crates/linker/src/generate_dylib.rs b/crates/linker/src/generate_dylib.rs index ec9125e5f5..99ae204a75 100644 --- a/crates/linker/src/generate_dylib.rs +++ b/crates/linker/src/generate_dylib.rs @@ -55,9 +55,9 @@ struct DynamicSymbol { gnu_hash: Option, } +#[derive(Debug)] struct MySection { in_index: usize, - out_offset: usize, section: SectionHeader64, } @@ -68,6 +68,9 @@ struct Sections { dynstr: MySection, eh_frame: MySection, dynamic: MySection, + symtab: MySection, + strtab: MySection, + shstrtab: MySection, } impl Sections { @@ -79,6 +82,9 @@ impl Sections { &self.dynstr, &self.eh_frame, &self.dynamic, + &self.symtab, + &self.strtab, + &self.shstrtab, ] .into_iter() .enumerate() @@ -88,7 +94,6 @@ impl Sections { fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result, Box> { let in_elf: &elf::FileHeader64 = elf::FileHeader64::parse(in_data)?; let endian = in_elf.endian()?; - let is_mips64el = in_elf.is_mips64el(endian); let in_segments = in_elf.program_headers(endian, in_data)?; let in_sections = in_elf.sections(endian, in_data)?; let in_syms = in_sections.symbols(endian, in_data, elf::SHT_SYMTAB)?; @@ -102,17 +107,19 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result, Box Result, Box Result, Box Result, Box Result, Box { - out_sections[*i].offset = - writer.reserve(in_section.sh_size(endian) as usize, 1); - } - elf::SHT_DYNAMIC => { - 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); - writer.reserve_dynsym(); - } - elf::SHT_STRTAB if *i == in_dynsyms.string_section().0 => { - dynstr_addr = in_section.sh_addr(endian); - writer.reserve_dynstr(); - } - elf::SHT_HASH => { - 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); - let hash = in_gnu_hash.as_ref().unwrap(); - writer.reserve_gnu_hash( - hash.bloom_count.get(endian), - hash.bucket_count.get(endian), - gnu_hash_symbol_count, - ); - } - other => { - panic!("Unsupported alloc section index {}, type {}", *i, other); - } - } - } - } + let dynamic_addr = in_section.sh_addr(endian); + writer.reserve_dynamic(out_dynamic.len()); + + // strtab and shstrtab is ignored // Reserve non-alloc sections at any offset. for (i, in_section) in in_sections.iter().enumerate() { @@ -556,7 +519,6 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result, Box { for d in &out_dynamic { - dbg!(&d); if let Some(string) = d.string { writer.write_dynamic_string(d.tag, string); } else { @@ -574,8 +536,8 @@ fn copy_file(in_data: &[u8], custom_names: &[String]) -> Result, Box Result, Box Result, Box Result, Box {} - elf::SHT_PROGBITS - | elf::SHT_NOBITS - | elf::SHT_NOTE - | elf::SHT_REL - | elf::SHT_RELA - | elf::SHT_INIT_ARRAY - | elf::SHT_FINI_ARRAY => { - let out_section = &out_sections[i]; - let sh_link = out_sections_index[in_section.sh_link(endian) as usize].0 as u32; - let mut sh_info = in_section.sh_info(endian); - if in_section.sh_flags(endian) as u32 & elf::SHF_INFO_LINK != 0 { - sh_info = out_sections_index[sh_info as usize].0 as u32; - } - 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), - sh_addr: in_section.sh_addr(endian), - sh_offset: out_section.offset as u64, - sh_size: in_section.sh_size(endian), - sh_link, - sh_info, - sh_addralign: in_section.sh_addralign(endian), - sh_entsize: in_section.sh_entsize(endian), - }); - } - elf::SHT_STRTAB => { - if i == in_syms.string_section().0 { - writer.write_strtab_section_header(); - } else if i == in_dynsyms.string_section().0 { - writer.write_dynstr_section_header(dynstr_addr); - } else if i == in_elf.shstrndx(endian, in_data)? as usize { - writer.write_shstrtab_section_header(); - } else { - panic!("Unsupported string section {}", i); - } - } - elf::SHT_SYMTAB => { - if i == in_syms.section().0 { - writer.write_symtab_section_header(num_local); - } else { - panic!("Unsupported symtab section {}", i); - } - } - elf::SHT_SYMTAB_SHNDX => { - if i == in_syms.shndx_section().0 { - writer.write_symtab_shndx_section_header(); - } else { - panic!("Unsupported symtab shndx section {}", i); - } - } - elf::SHT_DYNSYM => { - if i == in_dynsyms.section().0 { - writer.write_dynsym_section_header(dynsym_addr, 1); - } else { - panic!("Unsupported dynsym section {}", i); - } - } - elf::SHT_DYNAMIC => { - writer.write_dynamic_section_header(dynamic_addr); - } - elf::SHT_HASH => { - writer.write_hash_section_header(hash_addr); - } - elf::SHT_GNU_HASH => { - writer.write_gnu_hash_section_header(gnu_hash_addr); - } - other => { - panic!("Unsupported section type {:x}", other); - } + writer.write_hash_section_header(hash_addr); + writer.write_gnu_hash_section_header(gnu_hash_addr); + writer.write_dynsym_section_header(dynsym_addr, 1); + + writer.write_dynstr_section_header(dynstr_addr); + + writer.write_symtab_section_header(num_local); + + writer.write_strtab_section_header(); + writer.write_shstrtab_section_header(); + + { + let in_section = §ions.eh_frame.section; + let out_section = &out_sections[5]; // 5 is a random choice + let sh_link = out_sections_index[in_section.sh_link(endian) as usize].0 as u32; + let mut sh_info = in_section.sh_info(endian); + if in_section.sh_flags(endian) as u32 & elf::SHF_INFO_LINK != 0 { + sh_info = out_sections_index[sh_info as usize].0 as u32; } + + 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), + sh_addr: in_section.sh_addr(endian), + sh_offset: offsets[4] as u64, + sh_size: in_section.sh_size(endian), + sh_link, + sh_info, + sh_addralign: in_section.sh_addralign(endian), + sh_entsize: in_section.sh_entsize(endian), + }); } + + writer.write_dynamic_section_header(dynamic_addr); + debug_assert_eq!(writer.reserved_len(), writer.len()); Ok(out_data)