Merge branch 'pie' into 'master'
Fix bugs in handling non pie elfs See merge request redox-os/relibc!285
This commit is contained in:
+65
-15
@@ -10,6 +10,7 @@ use core::{
|
||||
};
|
||||
use goblin::{
|
||||
elf::{
|
||||
header::ET_DYN,
|
||||
program_header,
|
||||
r#dyn::{Dyn, DT_DEBUG},
|
||||
reloc, sym, Elf,
|
||||
@@ -199,7 +200,11 @@ impl Linker {
|
||||
let value: usize;
|
||||
if let Some(name_res) = elf.dynstrtab.get(sym.st_name) {
|
||||
name = name_res?.to_string();
|
||||
value = mmap.as_ptr() as usize + sym.st_value as usize;
|
||||
value = if is_pie_enabled(elf) {
|
||||
mmap.as_ptr() as usize + sym.st_value as usize
|
||||
} else {
|
||||
sym.st_value as usize
|
||||
};
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@@ -256,7 +261,7 @@ impl Linker {
|
||||
None => return Ok(()),
|
||||
};
|
||||
let elf = Elf::parse(self.objects.get(&root.name).unwrap())?;
|
||||
for section in elf.section_headers {
|
||||
for section in &elf.section_headers {
|
||||
let name = match elf.shdr_strtab.get(section.sh_name) {
|
||||
Some(x) => match x {
|
||||
Ok(y) => y,
|
||||
@@ -265,7 +270,11 @@ impl Linker {
|
||||
_ => continue,
|
||||
};
|
||||
if name == ".init_array" {
|
||||
let addr = mmap.as_ptr() as usize + section.vm_range().start;
|
||||
let addr = if is_pie_enabled(&elf) {
|
||||
mmap.as_ptr() as usize + section.vm_range().start
|
||||
} else {
|
||||
section.vm_range().start
|
||||
};
|
||||
for i in (0..section.sh_size).step_by(8) {
|
||||
unsafe { call_inits_finis(addr + i as usize) };
|
||||
}
|
||||
@@ -287,7 +296,7 @@ impl Linker {
|
||||
None => return Ok(()),
|
||||
};
|
||||
let elf = Elf::parse(self.objects.get(&root.name).unwrap())?;
|
||||
for section in elf.section_headers {
|
||||
for section in &elf.section_headers {
|
||||
let name = match elf.shdr_strtab.get(section.sh_name) {
|
||||
Some(x) => match x {
|
||||
Ok(y) => y,
|
||||
@@ -296,7 +305,11 @@ impl Linker {
|
||||
_ => continue,
|
||||
};
|
||||
if name == ".fini_array" {
|
||||
let addr = mmap.as_ptr() as usize + section.vm_range().start;
|
||||
let addr = if is_pie_enabled(&elf) {
|
||||
mmap.as_ptr() as usize + section.vm_range().start
|
||||
} else {
|
||||
section.vm_range().start
|
||||
};
|
||||
for i in (0..section.sh_size).step_by(8) {
|
||||
unsafe { call_inits_finis(addr + i as usize) };
|
||||
}
|
||||
@@ -396,7 +409,12 @@ impl Linker {
|
||||
};
|
||||
if same_elf {
|
||||
let addr = dso.as_ref().unwrap().base_addr;
|
||||
let size = bounds.1;
|
||||
let size = if is_pie_enabled(&elf) {
|
||||
bounds.1
|
||||
} else {
|
||||
bounds.1 - bounds.0
|
||||
};
|
||||
|
||||
// Fill the gaps i the binary
|
||||
let mut ranges = Vec::new();
|
||||
for ph in elf.program_headers.iter() {
|
||||
@@ -405,7 +423,11 @@ impl Linker {
|
||||
let vaddr = ph.p_vaddr as usize - voff;
|
||||
let vsize = ((ph.p_memsz as usize + voff + PAGE_SIZE - 1) / PAGE_SIZE)
|
||||
* PAGE_SIZE;
|
||||
ranges.push((vaddr, vsize));
|
||||
if is_pie_enabled(&elf) {
|
||||
ranges.push((vaddr, vsize));
|
||||
} else {
|
||||
ranges.push((vaddr - addr, vsize));
|
||||
}
|
||||
}
|
||||
}
|
||||
ranges.sort();
|
||||
@@ -651,7 +673,11 @@ impl Linker {
|
||||
(0, 0)
|
||||
};
|
||||
|
||||
let ptr = unsafe { mmap.as_mut_ptr().add(rel.r_offset as usize) };
|
||||
let ptr = if is_pie_enabled(&elf) {
|
||||
unsafe { mmap.as_mut_ptr().add(rel.r_offset as usize) }
|
||||
} else {
|
||||
rel.r_offset as *mut u8
|
||||
};
|
||||
|
||||
let set_u64 = |value| {
|
||||
// println!(" set_u64 {:#x}", value);
|
||||
@@ -717,7 +743,12 @@ impl Linker {
|
||||
};
|
||||
let bytes: [u8; size_of::<Dyn>() / 2] =
|
||||
unsafe { transmute((&_r_debug) as *const RTLDDebug as usize) };
|
||||
let start = dyn_start_addr + i * size_of::<Dyn>() + size_of::<Dyn>() / 2;
|
||||
let start = if is_pie_enabled(elf) {
|
||||
dyn_start_addr + i * size_of::<Dyn>() + size_of::<Dyn>() / 2
|
||||
} else {
|
||||
dyn_start_addr + i * size_of::<Dyn>() + size_of::<Dyn>() / 2
|
||||
- mmap.as_mut_ptr() as usize
|
||||
};
|
||||
mmap[start..start + size_of::<Dyn>() / 2].clone_from_slice(&bytes);
|
||||
}
|
||||
}
|
||||
@@ -748,7 +779,11 @@ impl Linker {
|
||||
None => continue,
|
||||
};
|
||||
let res = unsafe {
|
||||
let ptr = mmap.as_mut_ptr().add(vaddr);
|
||||
let ptr = if is_pie_enabled(elf) {
|
||||
mmap.as_mut_ptr().add(vaddr)
|
||||
} else {
|
||||
vaddr as *const u8
|
||||
};
|
||||
if self.verbose {
|
||||
println!(" prot {:#x}, {:#x}: {:p}, {:#x}", vaddr, vsize, ptr, prot);
|
||||
}
|
||||
@@ -780,7 +815,11 @@ impl Linker {
|
||||
println!("entry {}", elf_name);
|
||||
}
|
||||
if Some(*elf_name) == primary_opt {
|
||||
entry_opt = Some(mmap.as_mut_ptr() as usize + elf.header.e_entry as usize);
|
||||
if is_pie_enabled(&elf) {
|
||||
entry_opt = Some(mmap.as_mut_ptr() as usize + elf.header.e_entry as usize);
|
||||
} else {
|
||||
entry_opt = Some(elf.header.e_entry as usize);
|
||||
}
|
||||
}
|
||||
|
||||
// Relocate
|
||||
@@ -815,7 +854,6 @@ impl Linker {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Protect pages
|
||||
for ph in elf.program_headers.iter() {
|
||||
if let program_header::PT_LOAD = ph.p_type {
|
||||
@@ -838,7 +876,11 @@ impl Linker {
|
||||
}
|
||||
|
||||
let res = unsafe {
|
||||
let ptr = mmap.as_mut_ptr().add(vaddr);
|
||||
let ptr = if is_pie_enabled(&elf) {
|
||||
mmap.as_mut_ptr().add(vaddr)
|
||||
} else {
|
||||
vaddr as *const u8
|
||||
};
|
||||
if self.verbose {
|
||||
println!(" prot {:#x}, {:#x}: {:p}, {:#x}", vaddr, vsize, ptr, prot);
|
||||
}
|
||||
@@ -852,12 +894,20 @@ impl Linker {
|
||||
}
|
||||
}
|
||||
unsafe { _r_debug.state = RTLDState::RT_CONSISTENT };
|
||||
_dl_debug_state();
|
||||
//_dl_debug_state();
|
||||
Ok(entry_opt)
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn call_inits_finis(addr: usize) {
|
||||
unsafe fn call_inits_finis(addr: usize) {
|
||||
let func = transmute::<usize, *const Option<extern "C" fn()>>(addr);
|
||||
(*func).map(|x| x());
|
||||
}
|
||||
|
||||
fn is_pie_enabled(elf: &Elf) -> bool {
|
||||
if elf.header.e_type == ET_DYN {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user