mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
add support for absolute relocations
This commit is contained in:
parent
fdbb0c8e3c
commit
b725b36697
2 changed files with 59 additions and 11 deletions
|
@ -19,7 +19,7 @@ use std::time::{Duration, Instant};
|
||||||
use crate::metadata::{self, Metadata, VirtualOffset};
|
use crate::metadata::{self, Metadata, VirtualOffset};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
align_by_constraint, align_to_offset_by_constraint, load_struct_inplace,
|
align_by_constraint, align_to_offset_by_constraint, dbg_hex, load_struct_inplace,
|
||||||
load_struct_inplace_mut, load_structs_inplace_mut, open_mmap, open_mmap_mut,
|
load_struct_inplace_mut, load_structs_inplace_mut, open_mmap, open_mmap_mut,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1232,6 +1232,10 @@ fn surgery_elf_help(
|
||||||
RelocationKind::Relative | RelocationKind::PltRelative => {
|
RelocationKind::Relative | RelocationKind::PltRelative => {
|
||||||
target_offset - virt_base as i64 + rel.1.addend()
|
target_offset - virt_base as i64 + rel.1.addend()
|
||||||
}
|
}
|
||||||
|
RelocationKind::Absolute => {
|
||||||
|
// NOTE: this relies on our app using position-independent code (PIC)
|
||||||
|
target_offset + rel.1.addend()
|
||||||
|
}
|
||||||
x => {
|
x => {
|
||||||
internal_error!("Relocation Kind not yet support: {:?}", x);
|
internal_error!("Relocation Kind not yet support: {:?}", x);
|
||||||
}
|
}
|
||||||
|
@ -1315,7 +1319,7 @@ fn surgery_elf_help(
|
||||||
section_headers[section_headers.len() - 2] = elf::SectionHeader64 {
|
section_headers[section_headers.len() - 2] = elf::SectionHeader64 {
|
||||||
sh_name: endian::U32::new(LE, 0),
|
sh_name: endian::U32::new(LE, 0),
|
||||||
sh_type: endian::U32::new(LE, elf::SHT_PROGBITS),
|
sh_type: endian::U32::new(LE, elf::SHT_PROGBITS),
|
||||||
sh_flags: endian::U64::new(LE, (elf::SHF_ALLOC) as u64),
|
sh_flags: endian::U64::new(LE, elf::SHF_ALLOC as u64),
|
||||||
sh_addr: endian::U64::new(LE, new_rodata_section_vaddr as u64),
|
sh_addr: endian::U64::new(LE, new_rodata_section_vaddr as u64),
|
||||||
sh_offset: endian::U64::new(LE, new_rodata_section_offset as u64),
|
sh_offset: endian::U64::new(LE, new_rodata_section_offset as u64),
|
||||||
sh_size: endian::U64::new(LE, new_rodata_section_size),
|
sh_size: endian::U64::new(LE, new_rodata_section_size),
|
||||||
|
@ -1529,24 +1533,27 @@ mod tests {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn link_zig_host_and_app_help(dir: &Path) {
|
/// This zig code sample containts a static relocation
|
||||||
|
fn static_relocation_help(dir: &Path) {
|
||||||
let host_zig = indoc!(
|
let host_zig = indoc!(
|
||||||
r#"
|
r#"
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
extern fn roc_magic1() callconv(.C) u64;
|
extern fn roc_magic1(usize) callconv(.C) [*]const u8;
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
try stdout.print("Hello {}\n", .{roc_magic1()});
|
try stdout.print("Hello {s}\n", .{roc_magic1(0)[0..3]});
|
||||||
}
|
}
|
||||||
"#
|
"#
|
||||||
);
|
);
|
||||||
|
|
||||||
let app_zig = indoc!(
|
let app_zig = indoc!(
|
||||||
r#"
|
r#"
|
||||||
export fn roc_magic1() u64 {
|
const X = [_][]const u8 { "foo" };
|
||||||
return 42;
|
|
||||||
|
export fn roc_magic1(index: usize) [*]const u8 {
|
||||||
|
return X[index].ptr;
|
||||||
}
|
}
|
||||||
"#
|
"#
|
||||||
);
|
);
|
||||||
|
@ -1562,6 +1569,7 @@ mod tests {
|
||||||
.args(&[
|
.args(&[
|
||||||
"build-obj",
|
"build-obj",
|
||||||
"app.zig",
|
"app.zig",
|
||||||
|
"-fPIC",
|
||||||
"-target",
|
"-target",
|
||||||
"x86_64-linux-gnu",
|
"x86_64-linux-gnu",
|
||||||
"-OReleaseFast",
|
"-OReleaseFast",
|
||||||
|
@ -1643,12 +1651,11 @@ mod tests {
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
#[test]
|
#[test]
|
||||||
fn link_zig_host_and_app_windows() {
|
fn static_relocation() {
|
||||||
let dir = tempfile::tempdir().unwrap();
|
let dir = tempfile::tempdir().unwrap();
|
||||||
let dir = dir.path();
|
let dir = dir.path();
|
||||||
let dir = Path::new("/tmp/roc/");
|
|
||||||
|
|
||||||
link_zig_host_and_app_help(dir);
|
static_relocation_help(dir);
|
||||||
|
|
||||||
let output = std::process::Command::new(&dir.join("final"))
|
let output = std::process::Command::new(&dir.join("final"))
|
||||||
.current_dir(dir)
|
.current_dir(dir)
|
||||||
|
@ -1666,6 +1673,6 @@ mod tests {
|
||||||
|
|
||||||
let output = String::from_utf8_lossy(&output.stdout);
|
let output = String::from_utf8_lossy(&output.stdout);
|
||||||
|
|
||||||
assert_eq!("Hello 42\n", output);
|
assert_eq!("Hello foo\n", output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -372,3 +372,44 @@ pub(crate) fn open_mmap_mut(path: &Path, length: usize) -> MmapMut {
|
||||||
|
|
||||||
unsafe { MmapMut::map_mut(&out_file).unwrap_or_else(|e| internal_error!("{e}")) }
|
unsafe { MmapMut::map_mut(&out_file).unwrap_or_else(|e| internal_error!("{e}")) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # dbg_hex
|
||||||
|
/// display dbg result in hexadecimal `{:#x?}` format.
|
||||||
|
///
|
||||||
|
/// # usage
|
||||||
|
/// Replace `dbg!()` with `dbg_hex!()`
|
||||||
|
///
|
||||||
|
/// # example
|
||||||
|
/// ```rust, no_run
|
||||||
|
/// use dbg_hex::dbg_hex;
|
||||||
|
/// dbg_hex!(0x16 + 0x16);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// output
|
||||||
|
/// ```text
|
||||||
|
/// [src/lib.rs:38] 0x16 + 0x16 = 0x2c
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! dbg_hex {
|
||||||
|
// NOTE: We cannot use `concat!` to make a static string as a format argument
|
||||||
|
// of `eprintln!` because `file!` could contain a `{` or
|
||||||
|
// `$val` expression could be a block (`{ .. }`), in which case the `eprintln!`
|
||||||
|
// will be malformed.
|
||||||
|
() => {
|
||||||
|
eprintln!("[{}:{}]", file!(), line!());
|
||||||
|
};
|
||||||
|
($val:expr $(,)?) => {
|
||||||
|
// Use of `match` here is intentional because it affects the lifetimes
|
||||||
|
// of temporaries - https://stackoverflow.com/a/48732525/1063961
|
||||||
|
match $val {
|
||||||
|
tmp => {
|
||||||
|
eprintln!("[{}:{}] {} = {:#x?}",
|
||||||
|
file!(), line!(), stringify!($val), &tmp);
|
||||||
|
tmp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
($($val:expr),+ $(,)?) => {
|
||||||
|
($($crate::dbg_hex!($val)),+,)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue