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::{
|
||||
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,
|
||||
};
|
||||
|
||||
|
@ -1232,6 +1232,10 @@ fn surgery_elf_help(
|
|||
RelocationKind::Relative | RelocationKind::PltRelative => {
|
||||
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 => {
|
||||
internal_error!("Relocation Kind not yet support: {:?}", x);
|
||||
}
|
||||
|
@ -1315,7 +1319,7 @@ fn surgery_elf_help(
|
|||
section_headers[section_headers.len() - 2] = elf::SectionHeader64 {
|
||||
sh_name: endian::U32::new(LE, 0),
|
||||
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_offset: endian::U64::new(LE, new_rodata_section_offset as u64),
|
||||
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!(
|
||||
r#"
|
||||
const std = @import("std");
|
||||
|
||||
extern fn roc_magic1() callconv(.C) u64;
|
||||
extern fn roc_magic1(usize) callconv(.C) [*]const u8;
|
||||
|
||||
pub fn main() !void {
|
||||
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!(
|
||||
r#"
|
||||
export fn roc_magic1() u64 {
|
||||
return 42;
|
||||
const X = [_][]const u8 { "foo" };
|
||||
|
||||
export fn roc_magic1(index: usize) [*]const u8 {
|
||||
return X[index].ptr;
|
||||
}
|
||||
"#
|
||||
);
|
||||
|
@ -1562,6 +1569,7 @@ mod tests {
|
|||
.args(&[
|
||||
"build-obj",
|
||||
"app.zig",
|
||||
"-fPIC",
|
||||
"-target",
|
||||
"x86_64-linux-gnu",
|
||||
"-OReleaseFast",
|
||||
|
@ -1643,12 +1651,11 @@ mod tests {
|
|||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn link_zig_host_and_app_windows() {
|
||||
fn static_relocation() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
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"))
|
||||
.current_dir(dir)
|
||||
|
@ -1666,6 +1673,6 @@ mod tests {
|
|||
|
||||
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}")) }
|
||||
}
|
||||
|
||||
/// # 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