mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
Update GOT relocations
This commit is contained in:
parent
f0f37bfe03
commit
a188720a16
2 changed files with 62 additions and 23 deletions
|
@ -177,18 +177,18 @@ pub fn preprocess(matches: &ArgMatches) -> io::Result<i32> {
|
||||||
let name = sym.name().unwrap().to_string();
|
let name = sym.name().unwrap().to_string();
|
||||||
// special exceptions for memcpy and memset.
|
// special exceptions for memcpy and memset.
|
||||||
if &name == "roc_memcpy" {
|
if &name == "roc_memcpy" {
|
||||||
md.roc_func_addresses
|
md.roc_symbol_vaddresses
|
||||||
.insert("memcpy".to_string(), sym.address() as u64);
|
.insert("memcpy".to_string(), sym.address() as u64);
|
||||||
} else if name == "roc_memset" {
|
} else if name == "roc_memset" {
|
||||||
md.roc_func_addresses
|
md.roc_symbol_vaddresses
|
||||||
.insert("memset".to_string(), sym.address() as u64);
|
.insert("memset".to_string(), sym.address() as u64);
|
||||||
}
|
}
|
||||||
md.roc_func_addresses.insert(name, sym.address() as u64);
|
md.roc_symbol_vaddresses.insert(name, sym.address() as u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"Found roc function definitions: {:x?}",
|
"Found roc symbol definitions: {:x?}",
|
||||||
md.roc_func_addresses
|
md.roc_symbol_vaddresses
|
||||||
);
|
);
|
||||||
|
|
||||||
let exec_parsing_duration = exec_parsing_start.elapsed().unwrap();
|
let exec_parsing_duration = exec_parsing_start.elapsed().unwrap();
|
||||||
|
@ -749,6 +749,16 @@ pub fn preprocess(matches: &ArgMatches) -> io::Result<i32> {
|
||||||
let r_offset = rel.r_offset.get(NativeEndian);
|
let r_offset = rel.r_offset.get(NativeEndian);
|
||||||
if md.virtual_shift_start <= r_offset {
|
if md.virtual_shift_start <= r_offset {
|
||||||
rel.r_offset = endian::U64::new(LittleEndian, r_offset + md.added_byte_count);
|
rel.r_offset = endian::U64::new(LittleEndian, r_offset + md.added_byte_count);
|
||||||
|
// Deal with potential adjusts to absolute jumps.
|
||||||
|
match rel.r_type(LittleEndian, false) {
|
||||||
|
elf::R_X86_64_RELATIVE => {
|
||||||
|
let r_addend = rel.r_addend.get(LittleEndian);
|
||||||
|
rel.r_addend
|
||||||
|
.set(LittleEndian, r_addend + md.added_byte_count as i64);
|
||||||
|
}
|
||||||
|
// TODO: Verify other relocation types.
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -988,6 +998,7 @@ pub fn surgery(matches: &ArgMatches) -> io::Result<i32> {
|
||||||
let mut sh_tab = vec![];
|
let mut sh_tab = vec![];
|
||||||
sh_tab.extend_from_slice(&exec_mmap[sh_offset as usize..sh_offset as usize + sh_size]);
|
sh_tab.extend_from_slice(&exec_mmap[sh_offset as usize..sh_offset as usize + sh_size]);
|
||||||
|
|
||||||
|
// TODO: I think this can move in by sh_size.
|
||||||
let mut offset = md.exec_len as usize;
|
let mut offset = md.exec_len as usize;
|
||||||
offset = aligned_offset(offset);
|
offset = aligned_offset(offset);
|
||||||
// TODO: Switch to using multiple segments.
|
// TODO: Switch to using multiple segments.
|
||||||
|
@ -1049,10 +1060,13 @@ pub fn surgery(matches: &ArgMatches) -> io::Result<i32> {
|
||||||
exec_mmap[offset..offset + data.len()].copy_from_slice(&data);
|
exec_mmap[offset..offset + data.len()].copy_from_slice(&data);
|
||||||
for sym in symbols.iter() {
|
for sym in symbols.iter() {
|
||||||
if sym.section() == SymbolSection::Section(sec.index()) {
|
if sym.section() == SymbolSection::Section(sec.index()) {
|
||||||
symbol_offset_map.insert(
|
let name = sym.name().unwrap_or_default().to_string();
|
||||||
sym.index().0,
|
if !md.roc_symbol_vaddresses.contains_key(&name) {
|
||||||
offset + sym.address() as usize - new_segment_offset,
|
symbol_offset_map.insert(
|
||||||
);
|
sym.index().0,
|
||||||
|
offset + sym.address() as usize - new_segment_offset,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
offset += size;
|
offset += size;
|
||||||
|
@ -1076,6 +1090,7 @@ pub fn surgery(matches: &ArgMatches) -> io::Result<i32> {
|
||||||
let new_text_section_offset = offset;
|
let new_text_section_offset = offset;
|
||||||
let mut app_func_size_map: MutMap<String, u64> = MutMap::default();
|
let mut app_func_size_map: MutMap<String, u64> = MutMap::default();
|
||||||
let mut app_func_segment_offset_map: MutMap<String, usize> = MutMap::default();
|
let mut app_func_segment_offset_map: MutMap<String, usize> = MutMap::default();
|
||||||
|
let mut got_sections: Vec<(u64, u64)> = vec![];
|
||||||
for sec in text_sections {
|
for sec in text_sections {
|
||||||
let data = match sec.uncompressed_data() {
|
let data = match sec.uncompressed_data() {
|
||||||
Ok(data) => data,
|
Ok(data) => data,
|
||||||
|
@ -1103,11 +1118,13 @@ pub fn surgery(matches: &ArgMatches) -> io::Result<i32> {
|
||||||
let current_section_offset = (offset - new_segment_offset) as i64;
|
let current_section_offset = (offset - new_segment_offset) as i64;
|
||||||
for sym in symbols.iter() {
|
for sym in symbols.iter() {
|
||||||
if sym.section() == SymbolSection::Section(sec.index()) {
|
if sym.section() == SymbolSection::Section(sec.index()) {
|
||||||
symbol_offset_map.insert(
|
|
||||||
sym.index().0,
|
|
||||||
offset + sym.address() as usize - new_segment_offset,
|
|
||||||
);
|
|
||||||
let name = sym.name().unwrap_or_default().to_string();
|
let name = sym.name().unwrap_or_default().to_string();
|
||||||
|
if !md.roc_symbol_vaddresses.contains_key(&name) {
|
||||||
|
symbol_offset_map.insert(
|
||||||
|
sym.index().0,
|
||||||
|
offset + sym.address() as usize - new_segment_offset,
|
||||||
|
);
|
||||||
|
}
|
||||||
if md.app_functions.contains(&name) {
|
if md.app_functions.contains(&name) {
|
||||||
app_func_segment_offset_map.insert(
|
app_func_segment_offset_map.insert(
|
||||||
name.clone(),
|
name.clone(),
|
||||||
|
@ -1117,7 +1134,8 @@ pub fn surgery(matches: &ArgMatches) -> io::Result<i32> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut got_offset = aligned_offset(offset + size);
|
offset = aligned_offset(offset + size);
|
||||||
|
let mut got_offset = offset;
|
||||||
for rel in sec.relocations() {
|
for rel in sec.relocations() {
|
||||||
if verbose {
|
if verbose {
|
||||||
println!("\tFound Relocation: {:x?}", rel);
|
println!("\tFound Relocation: {:x?}", rel);
|
||||||
|
@ -1130,7 +1148,7 @@ pub fn surgery(matches: &ArgMatches) -> io::Result<i32> {
|
||||||
} else if let Ok(sym) = app_obj.symbol_by_index(index) {
|
} else if let Ok(sym) = app_obj.symbol_by_index(index) {
|
||||||
// Not one of the apps symbols, check if it is from the roc host.
|
// Not one of the apps symbols, check if it is from the roc host.
|
||||||
if let Ok(name) = sym.name() {
|
if let Ok(name) = sym.name() {
|
||||||
if let Some(address) = md.roc_func_addresses.get(name) {
|
if let Some(address) = md.roc_symbol_vaddresses.get(name) {
|
||||||
Some(
|
Some(
|
||||||
(*address + md.added_byte_count) as i64
|
(*address + md.added_byte_count) as i64
|
||||||
- new_segment_vaddr as i64,
|
- new_segment_vaddr as i64,
|
||||||
|
@ -1156,15 +1174,33 @@ pub fn surgery(matches: &ArgMatches) -> io::Result<i32> {
|
||||||
if verbose {
|
if verbose {
|
||||||
println!("GOT hacking this may not work right");
|
println!("GOT hacking this may not work right");
|
||||||
}
|
}
|
||||||
let got_val = target_offset as u64 + new_segment_vaddr;
|
// TODO: This doesn't actually work. We also need to add a relocatoin to the rela section.
|
||||||
let target_offset = (got_offset - new_segment_offset) as i64;
|
// These offsets are not actually global offsets due to aslr.
|
||||||
let data = got_val.to_le_bytes();
|
// We either need to actually put these in the GOT, add a new GOT section, or some other hack.
|
||||||
|
// Putting them in the real GOT is the most correct solution.
|
||||||
|
|
||||||
|
// Another solution may be to make the host define all global data.
|
||||||
|
// The follow code assumes that is the case and will generate invalid code otherwise.
|
||||||
|
// Also, I wonder if it is possible to avoid true globals somehow.
|
||||||
|
let target_vaddr = target_offset + new_segment_vaddr as i64;
|
||||||
|
let data = target_vaddr.to_le_bytes();
|
||||||
exec_mmap[got_offset..got_offset + 8].copy_from_slice(&data);
|
exec_mmap[got_offset..got_offset + 8].copy_from_slice(&data);
|
||||||
got_offset = aligned_offset(got_offset + 8);
|
got_offset = aligned_offset(got_offset + 8);
|
||||||
target_offset - (rel.0 as i64 + current_section_offset)
|
let target_offset = (got_offset - new_segment_offset) as i64;
|
||||||
+ rel.1.addend()
|
let base_offset = rel.0 as i64 + current_section_offset;
|
||||||
|
if verbose {
|
||||||
|
println!(
|
||||||
|
"\tThe base offset is: 0x{:x}",
|
||||||
|
base_offset + current_section_offset
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"\tThe got target is: 0x{:x}",
|
||||||
|
target_offset + current_section_offset
|
||||||
|
);
|
||||||
|
println!("\tThe final target is: 0x{:x}", target_vaddr);
|
||||||
|
}
|
||||||
|
target_offset - base_offset + rel.1.addend()
|
||||||
}
|
}
|
||||||
RelocationKind::Absolute => target_offset + new_segment_vaddr as i64,
|
|
||||||
x => {
|
x => {
|
||||||
println!("Relocation Kind not yet support: {:?}", x);
|
println!("Relocation Kind not yet support: {:?}", x);
|
||||||
return Ok(-1);
|
return Ok(-1);
|
||||||
|
@ -1202,7 +1238,10 @@ pub fn surgery(matches: &ArgMatches) -> io::Result<i32> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
offset = got_offset;
|
if got_offset != offset {
|
||||||
|
got_sections.push((offset, got_offset - offset));
|
||||||
|
offset = got_offset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if verbose {
|
if verbose {
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub struct Metadata {
|
||||||
pub plt_addresses: MutMap<String, (u64, u64)>,
|
pub plt_addresses: MutMap<String, (u64, u64)>,
|
||||||
pub surgeries: MutMap<String, Vec<SurgeryEntry>>,
|
pub surgeries: MutMap<String, Vec<SurgeryEntry>>,
|
||||||
pub dynamic_symbol_indices: MutMap<String, u64>,
|
pub dynamic_symbol_indices: MutMap<String, u64>,
|
||||||
pub roc_func_addresses: MutMap<String, u64>,
|
pub roc_symbol_vaddresses: MutMap<String, u64>,
|
||||||
pub dynamic_section_offset: u64,
|
pub dynamic_section_offset: u64,
|
||||||
pub dynamic_lib_count: u64,
|
pub dynamic_lib_count: u64,
|
||||||
pub shared_lib_index: u64,
|
pub shared_lib_index: u64,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue