[aarch64-port-dev ] Help debugging problem with large code cache
Edward Nevill
edward.nevill at gmail.com
Thu Dec 3 10:15:32 UTC 2015
On Thu, 2015-12-03 at 09:36 +0000, Andrew Haley wrote:
> On 03/12/15 07:41, Edward Nevill wrote:
> > Because if the code has not been relocated yet, then the adrp could be pointing somewhere randomly within the code buffer, and it just happens sometimes to point to a valid trampoline stub.
>
> If you can catch adrp being used where it randomly points somewhere
> in a code buffer, then that undoubtedly would be a bug.
I assert it is
I have trapped it in gdb at the point where it is making the incorrect relocation.
Winding back the call trace to CallRelocation::fix_relocation_after_move
void CallRelocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
// Usually a self-relative reference to an external routine.
// On some platforms, the reference is absolute (not self-relative).
// The enhanced use of pd_call_destination sorts this all out.
address orig_addr = old_addr_for(addr(), src, dest);
address callee = pd_call_destination(orig_addr);
// Reassert the callee address, this time in the new copy of the code.
pd_set_call_destination(callee);
}
(gdb) p/x callee
$9 = 0x3ff68ab2300
(gdb) p/x orig_addr ;; Relocating from 0x3ff68d16f28 -> 0x3ff691f02e8
$10 = 0x3ff68d16f28
(gdb) p/x addr()
$11 = 0x3ff691f02e8
(gdb) x/2i orig_addr
0x3ff68d16f28: adrp x8, 0x3ff68d16000 ;; Original call destination
0x3ff68d16f2c: add x8, x8, #0x500 ;; == 0x3ff68d16500
(gdb) x/2i addr()
0x3ff691f02e8: adrp x8, 0x3ff691f0000 ;; Copied but not relocated
0x3ff691f02ec: add x8, x8, #0x500 ;; dest == 0x3ff691f0500
(gdb) x/2i 0x3ff68d16500
0x3ff68d16500: stp x29, x30, [sp,#-16]! ;; overflow_counter stub
0x3ff68d16504: mov x29, sp ;; pointed to by original call dest above
(gdb) x/2i 0x3ff691f0500
0x3ff691f0500: ldr x8, 0x3ff691f0508 ;; copied but not relocated dest points here
0x3ff691f0504: br x8 ;; to a trampoline stub, but only by accident
;; essentially pointing to a random place in
;; the codebuf
(gdb) x/g 0x3ff691f0508
0x3ff691f0508: 0x000003ff68ab2300 ;; so since it thinks it is a trampoline stub
;; it picks up this address as the final adr
;; which we see in callee above
This is because it is using addr() in pd_call_destination, rather than orig_addr. IE. it is using the copied, but not relocated version, therefore the adrp is transiently pointing into garbage. Using the orig_addr should be correct.
More information about the aarch64-port-dev
mailing list