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

Bug with mov/lea in inline assembler #3963

Open
sr-tream opened this issue Apr 16, 2022 · 2 comments
Open

Bug with mov/lea in inline assembler #3963

sr-tream opened this issue Apr 16, 2022 · 2 comments

Comments

@sr-tream
Copy link

sr-tream commented Apr 16, 2022

Code:

import std.stdio;

extern (C)
{
    __gshared int xversion = 43;

    export int asm_test()
    {
        asm
        {
            naked;
            mov RAX, xversion;
            // lea RAX, xversion;
            // mov EAX, [RAX]; // also - crash
            ret;
        }
    }
}

void main()
{
    asm_test().writeln;
}

This code can be compiled only for Windows x86_64! On Linux, compilation failed with PIC error.

Base image address - 0x140000000

This code after compilation use invalid address of xversion - it reduces address to 4byte, but not use RIP-relative access. Instead of mov RAX, [0x1400a1000] generated mov RAX, [0x400a1000]. Some bug with lea

Code on C++ work fine:

#include <iostream>
#include <ostream>

extern "C" {
    static auto xversion = 43;

    int asm_test() __attribute__((naked));

    int asm_test(){
        __asm{
            mov RAX, xversion;
            ret;
        }
    }
}

int main(){
    std:: cout << asm_test() << std::endl;
    return 0;
}

Compiled with clang++ -fms-extensions. Flag -fms-extensions used to write asm with intal syntax, like on D.

Clang version - 13.0.1
ldc2 version - 1.28.1 (based on DMD v2.098.1 and LLVM 13.0.1)

P.S. dmd can't compile this code on x86_64.

P.P.S. rizin can compile this instruction properly - 0x00000000 10 48a100100a4001000000 movabs rax, qword [0x1400a1000]

@JohanEngelen
Copy link
Member

On Windows, you can probably make it work with [RIP + xversion] instead of xversion.
https://d.godbolt.org/z/WTafs6Tbv

On Linux with PIC, it's not so easy:
https://d.godbolt.org/z/bbrTE76h1

Does clang++ create a PIC executable?

@kinke
Copy link
Member

kinke commented May 4, 2022

Note that this only applies to naked DMD-style inline asm. This can also be expressed in non-naked DMD asm, but still making the function naked (and so I guess analogous to your clang example):

import ldc.attributes;
export int asm_test2() @naked
{
    asm
    {
        mov RAX, xversion;
        ret;
    }
}

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

3 participants