Compare commits

...

2 Commits

View File

@ -178,6 +178,7 @@ pub struct Linker<'a> {
section_map: HashMap<usize, usize>, section_map: HashMap<usize, usize>,
image: Vec<u8>, image: Vec<u8>,
load_offset: u32, load_offset: u32,
image_offset: u32,
rela_dyn_relas: Vec<Elf32_Rela>, rela_dyn_relas: Vec<Elf32_Rela>,
} }
@ -196,15 +197,26 @@ impl<'a> Linker<'a> {
// Maintain alignment requirement specified in sh_addralign // Maintain alignment requirement specified in sh_addralign
let align = shdr.sh_addralign; let align = shdr.sh_addralign;
let padding = (align - (self.load_offset % align)) % align; let load_padding = (align - (self.load_offset % align)) % align;
self.load_offset += padding; let image_padding = (align - (self.image_offset % align)) % align;
elf_shdr.sh_addr = let section_load_offset = if (shdr.sh_flags as usize & SHF_ALLOC) == SHF_ALLOC {
if (shdr.sh_flags as usize & SHF_ALLOC) == SHF_ALLOC { self.load_offset } else { 0 }; self.load_offset + load_padding
elf_shdr.sh_offset = self.load_offset; } else {
0
};
let section_image_offset = self.image_offset + image_padding;
elf_shdr.sh_addr = section_load_offset;
elf_shdr.sh_offset = section_image_offset;
self.elf_shdrs.push(SectionRecord { shdr: elf_shdr, name: sh_name_str, data }); self.elf_shdrs.push(SectionRecord { shdr: elf_shdr, name: sh_name_str, data });
self.load_offset += shdr.sh_size; if (shdr.sh_flags as usize & SHF_ALLOC) == SHF_ALLOC {
self.load_offset = section_load_offset + shdr.sh_size;
}
if shdr.sh_type as usize != SHT_NOBITS {
self.image_offset = section_image_offset + shdr.sh_size;
}
self.elf_shdrs.len() - 1 self.elf_shdrs.len() - 1
} }
@ -754,6 +766,7 @@ impl<'a> Linker<'a> {
section_map, section_map,
image, image,
load_offset: elf_sh_data_off as u32, load_offset: elf_sh_data_off as u32,
image_offset: elf_sh_data_off as u32,
rela_dyn_relas, rela_dyn_relas,
}; };
@ -1302,8 +1315,7 @@ impl<'a> Linker<'a> {
let bss_elf_index = linker.load_section( let bss_elf_index = linker.load_section(
shdr, shdr,
section_name, section_name,
data[shdr.sh_offset as usize..(shdr.sh_offset + shdr.sh_size) as usize] vec![0; 0], // NOBITS section has no data
.to_vec(),
); );
linker.section_map.insert(bss_section_index, bss_elf_index); linker.section_map.insert(bss_section_index, bss_elf_index);
@ -1401,10 +1413,12 @@ impl<'a> Linker<'a> {
linker.implement_eh_frame_hdr()?; linker.implement_eh_frame_hdr()?;
} }
// Load all section data into the image // Load all non-NOBITS section data into the image
for rec in &linker.elf_shdrs[1..] { for rec in &linker.elf_shdrs[1..] {
linker.image.extend(vec![0; (rec.shdr.sh_offset as usize) - linker.image.len()]); if rec.shdr.sh_type as usize != SHT_NOBITS {
linker.image.extend(&rec.data); linker.image.extend(vec![0; (rec.shdr.sh_offset as usize) - linker.image.len()]);
linker.image.extend(&rec.data);
}
} }
// Load all section headers to the image // Load all section headers to the image