Bug 22170 – interface thunk doesn't set EBX to GOT
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86
OS
Linux
Creation time
2021-08-02T17:38:19Z
Last change time
2021-08-04T16:53:24Z
Keywords
backend, pull, wrong-code
Assigned to
No Owner
Creator
Iain Buclaw
Comments
Comment #0 by ibuclaw — 2021-08-02T17:38:19Z
Issue 9729 has regressed during the fix for issue 10462 (https://github.com/dlang/dmd/pull/2278)
We still need to load the GOT within the interface thunk because only the thunk can load the correct GOT.
Comment #1 by ibuclaw — 2021-08-02T22:58:46Z
It looks like what DMD is doing is loading the GOT into EBX before every function call.
i.e: Abridged version of objdump
---
push %ebp
mov %esp,%ebp
sub $0x28,%esp
mov %ebx,-0x28(%ebp)
mov %esi,-0x24(%ebp)
mov -0x1c(%ebp),%ebx
call 147c8 <_D5mydll10multiply10FiZi@plt>
mov -0x1c(%ebp),%ebx
call *%esi
mov -0x1c(%ebp),%ebx
call 145b0 <_D5mydll1S3addMFiZi@plt>
mov -0x1c(%ebp),%ebx
call 145b0 <_D5mydll1S3addMFiZi@plt>
mov -0x1c(%ebp),%ebx
call 14560 <_D5mydll1I6createFZCQs1C@plt>
mov -0x1c(%ebp),%ebx
mov (%eax),%ecx
call *0x4(%ecx)
xor %eax,%eax
mov -0x28(%ebp),%ebx
mov -0x24(%ebp),%esi
leave
ret
---
Surely it'd be more efficient to load GOT in the prologue, then restore the previous in the epilogue.
i.e: The above rewritten:
---
push %ebp
mov %esp,%ebp
sub $0x28,%esp
mov %ebx,-0x28(%ebp) # <- looks like a save (better push %ebx?)
mov %esi,-0x24(%ebp)
mov -0x1c(%ebp),%ebx # <- Added load GOT here
call 147c8 <_D5mydll10multiply10FiZi@plt>
call *%esi
call 145b0 <_D5mydll1S3addMFiZi@plt>
call 145b0 <_D5mydll1S3addMFiZi@plt>
call 14560 <_D5mydll1I6createFZCQs1C@plt>
mov (%eax),%ecx
call *0x4(%ecx)
xor %eax,%eax
mov -0x28(%ebp),%ebx # <- looks like a restore (better pop %ebx?)
mov -0x24(%ebp),%esi
leave
ret
---
So it seems that the save/restore is already being done for normal functions, but this isn't being done for thunks.
Comment #2 by ibuclaw — 2021-08-03T06:35:44Z
GDC doesn't run into this by calling the aliased symbol directly in the thunk, e.g:
GDC
---
subl $0x8,0x4(%esp)
jmp 0xf7f34ffb <_D5mydll1C3fooMFCQp1IZCQvQr>
---
DMD
---
sub $0x8,%eax
jmp 0xf7f06970 <_D5mydll1C3fooMFCQp1IZCQvQr@plt>
---
GDC only generates thunks for symbols that are being emitted in this compilation, AFAIK it's not possible to have a thunk for an external symbol in DMD as well?
Comment #3 by ibuclaw — 2021-08-03T06:43:21Z
The fact that GOT is loaded into EBX before every function call is at best a performance bug and not related to this issue, so moved it to issue 22172.
Comment #4 by ibuclaw — 2021-08-03T08:38:18Z
(In reply to Iain Buclaw from comment #2)
> DMD
> ---
> sub $0x8,%eax
> jmp 0xf7f06970 <_D5mydll1C3fooMFCQp1IZCQvQr@plt>
> ---
Removing the PLT (same as PIE https://github.com/dlang/dmd/blob/master/src/dmd/backend/elfobj.d#L3125), DMD only ever seems to generate a jmp to an offset of the target function.
---
sub $0x8,%eax
jmp 0xf7f06970 <_D5mydll1C3fooMFCQp1IZCQvQr+4>
---
Which also looks wrong in comparison to GDC and triggers a segfault.
Comment #5 by dlang-bot — 2021-08-03T09:33:33Z
@ibuclaw created dlang/dmd pull request #12950 "fix Issue 22170 - interface thunk doesn't set EBX to GOT" fixing this issue:
- fix Issue 22170 - interface thunk doesn't set EBX to GOT
https://github.com/dlang/dmd/pull/12950
Comment #6 by dlang-bot — 2021-08-03T15:06:01Z
dlang/dmd pull request #12950 "fix Issue 22170 - interface thunk doesn't set EBX to GOT" was merged into stable:
- 1f723f0f17bc9fc9557e22cbfefc913bdfab6037 by Iain Buclaw:
fix Issue 22170 - interface thunk doesn't set EBX to GOT
https://github.com/dlang/dmd/pull/12950
Comment #7 by dlang-bot — 2021-08-04T16:53:24Z
dlang/dmd pull request #12953 "merge stable" was merged into master:
- d0406f3afea2c8365eef162cf6c6636aaef5a105 by Iain Buclaw:
fix Issue 22170 - interface thunk doesn't set EBX to GOT (#12950)
* fix Issue 22170 - interface thunk doesn't set EBX to GOT
* dshell: Add dll tests for issue 10462
https://github.com/dlang/dmd/pull/12953