CensoredUsername / dynasm-rs

A dynasm-like tool for rust.
https://censoredusername.github.io/dynasm-rs/language/index.html
Mozilla Public License 2.0
705 stars 52 forks source link

Impossible relocation on x86 #58

Closed vfsfitvnm closed 2 years ago

vfsfitvnm commented 2 years ago

Hi! I'm probably missing something like I always do; however I'm trying to assemble the following snippet, but I get a Errors were encountered when committing before finalization: ImpossibleRelocation(Global("hello")) error.

use dynasmrt::{dynasm, DynasmLabelApi};

let mut ops = dynasmrt::x86::Assembler::new().unwrap();

dynasm!(ops
    ; .arch x86
    ; lea eax, [->hello]
    ; ->hello:
    ; .bytes "hello".as_bytes()
);

println!("{:?}", ops.labels().resolve_global("hello")); // Ok(AssemblyOffset(6))

ops.finalize().unwrap();

I expected [->hello] to be resolved as 6... what am I doing wrong?

CensoredUsername commented 2 years ago

I think you're confusing instruction sets. X86 is a 32 bit architecture that uses absolute offsets, while you seem to be expecting the result to be a rip-relative offset (like x64 uses).

While dynasm is capable of handling the relocations necessary for absolute offsets in x86 mode, for dynamic assemblers this only works reliably if the rustc target architecture is x86. Because if the assembling buffer is not located in the lowest 32 bits of the address space, it is simply impossible to generate such an offset.

So either use an x64 assembler, use an assembler like VecAssembler if you're not intending to run the actual code, or use a rustc targetting x86.

vfsfitvnm commented 2 years ago

Thanks for the reply. I was indeed expecting the absolute offset (that example is unfortunate). VecAssembler was all I wanted to know!

let mut ops = VecAssembler::<X86Relocation>::new(0);

Thanks :+1: