cat > bug.d << CODE
void foo() {}
void bug()
{
asm { naked; }
foo();
asm { ret; }
}
CODE
--------------------
dmd -c -m32 -fPIC bug.d
--------------------
_D3bug3bugFZv PROC NEAR
call ?_003 ; 0000 _ E8, 00000000
?_003 LABEL NEAR
pop eax ; 0005 _ 58
add eax, offset _GLOBAL_OFFSET_TABLE_-$+1H ; 0006 _ 05, 00000002(GOT r)
mov dword ptr [ebp-4H], eax ; 000B _ 89. 45, FC
mov ebx, dword ptr [ebp-4H] ; 000E _ 8B. 5D, FC
call _D3bug3fooFZv ; 0011 _ E8, FFFFFFFC(PLT r)
ret ; 0016 _ C3
_D3bug3bugFZv ENDP
EBP isn't set up so storing the localgot will overwrite some other memory.
Not sure if we want to fix this because one might argue that non-asm is invalid in naked asm blocks.
Comment #1 by bugzilla — 2013-03-19T17:08:47Z
You're pretty much on your own with naked asm, that's the point of it!
Comment #2 by code — 2013-03-19T23:17:05Z
The GOT loading code sequence doesn't work because I have no detailed control about the emitted relocations. This uses a R_386_GOT32 relocation instead of the needed R_386_GOTPC one.
----
extern(C) __gshared extern void* _GLOBAL_OFFSET_TABLE_;
void loadGOT()
{
asm
{
naked;
call Lgot;
Lgot: pop EBX;
add EBX, offsetof _GLOBAL_OFFSET_TABLE_ + 3;
}
}
----
Comment #3 by bugzilla — 2013-03-19T23:46:44Z
The inline assembler doesn't give access to the complete set of relocation types. For those, it's best not to use naked and let the compiler set it up for you.
Comment #4 by clugdbug — 2013-03-20T04:40:43Z
Reopening this as a spec bug. I think the docs for 'naked' should mention this, since it's not at all obvious that any variables are being used in the example code.
Comment #5 by code — 2013-03-20T13:19:46Z
(In reply to comment #3)
> The inline assembler doesn't give access to the complete set of relocation
> types. For those, it's best not to use naked and let the compiler set it up for
> you.
BTW, this means I can't fix _trace_epi_n which gets called without saving registers that belong to the callee.
Naked asm doesn't work because of the mentioned memory corruption and
the inability to load the GOT otherwise.
Normal asm doesn't work either, because the compiler trashes EAX when loading the GOT.
I think the best solution would be to let the compiler do the regsave as it does now for _c_trace_pro.
Also note that D doesn't have a possibility to mark a function local, i.e. C++'s static, which wouldn't require a GOT entry to call in the first place.
Comment #6 by code — 2015-07-21T07:49:36Z
*** Issue 7354 has been marked as a duplicate of this issue. ***
Comment #7 by robert.schadek — 2024-12-13T18:04:59Z