Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImpossibleRelocation error on seemingly valid AArch64 code #79

Closed
john-h-k opened this issue May 30, 2023 · 4 comments
Closed

ImpossibleRelocation error on seemingly valid AArch64 code #79

john-h-k opened this issue May 30, 2023 · 4 comments

Comments

@john-h-k
Copy link

Hey, this is my first time using this library, so I apologise if I've made a stupid mistake, but this is really stumping me:

dynasm!(asm
    ; .arch aarch64
    ; ldrb w1, [x0]
    ; cbs w1, =>end
    ; .align 4
    ; =>start
)

(the other part of the generation has ; .align 4; => end. both are dynamic labels)

But when I attempt to run this, I get an ImpossibleRelocation error, and I'm not sure why. As far as I know, provided it is within range (which it definitely is, this code isn't more than a few hundred bytes apart) and aligned to 4 bytes, these labels should be valid?

@CensoredUsername
Copy link
Owner

(I'm assuming the relevant instruction was cbz, not cbs 😉)

I'm not sure what's happening here unfortunately. cbz's target has to be a signed immediate multiple of 4, and the range is like +/- 1MB. As long as these requirements are met it should be able to work.

The relevant check that supposedly is creating the error would be here: https://github.com/CensoredUsername/dynasm-rs/blob/master/runtime/src/aarch64.rs#L70 . That'd probably be a good point to start debugging. Unfortunately with your example I really cannot really reproduce it easily. Do you may

Are you sure this is the location causing the error? I tried making a simple reproduction case:

    let mut ops = dynasmrt::VecAssembler::<dynasmrt::aarch64::Aarch64Relocation>::new(0);
    let start = ops.new_dynamic_label();
    let end = ops.new_dynamic_label();
    dynasm!(ops
        ; .arch aarch64
        ; ldrb w1, [x0]
        ; cbz w1, =>end
        ; .align 4
        ; =>start
        ; .bytes b"abcdef123"
        ; .align 4
        ; => end
    );
    let buf = ops.finalize().unwrap();

but that assembled just fine.

@john-h-k
Copy link
Author

Thanks, turns out it was user error, I'd managed to use dynasmrt::x64::Assembler accidentally and it seems that was causing the issue.

That's all resolved, but if I can point out one other issue - it seems mov w0, <immediate> expects a u64 and mov x0, <immediate> expects a u32, which to my understanding is the wrong way round

@CensoredUsername
Copy link
Owner

CensoredUsername commented May 30, 2023

Thanks, turns out it was user error, I'd managed to use dynasmrt::x64::Assembler accidentally and it seems that was causing the issue.

A yep, that'd do it. Due to a lack of nice to use associated types on structs in rust the interface between assemblers is somewhat weakly typed unfortunately.

That's all resolved, but if I can point out one other issue - it seems mov w0, expects a u64 and mov x0, expects a u32, which to my understanding is the wrong way round

Looking at the code both seem to actually expect an u64 if encoded at runtime, does that match your observations? That's indeed a bit useless for mov w0, . https://github.com/CensoredUsername/dynasm-rs/blob/master/plugin/src/arch/aarch64/compiler.rs#L609 is the offending line, but fixing that right now is both low priority and a breaking change.

It's probably an artifact from the fact that compile-time encoding of constants always uses u64's internally

@john-h-k
Copy link
Author

All resolved thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants