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