[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