32-bit x86 code fixup after GC transport can ruin the object

Bug #1749369 reported by Douglas Katzman on 2018-02-14
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Undecided
Unassigned

Bug Description

The heuristic for determining which fixups are absolute can be misled by seeing a call displacement that looks like an address.

The following disassembly shows a function that I've managed to get moved to around #x90000000 in an image where the readonly and static spaces were also moved upward.

; Size: 155 bytes. Origin: #x9000004A
; 4A: 648B0524000000 MOV EAX, FS:[#x24] ; no-arg-parsing entry point
; 51: 8945FC MOV [EBP-4], EAX
...
; 9A: E8A9000090 CALL #x20000148 ; GENERIC-+
...
; E1: CC0A BREAK 10 ; error trap
; E3: 02 BYTE #X02 ; INVALID-ARG-COUNT-ERROR
; E4: 09 BYTE #X09 ; ECX

The code bounds are #x9000004A through #x900000E4. The call offset is #x900000A9.
So this test in gencgc_apply_code_fixups() goes wrong - it's not an absolute fixup.

/* If it's within the old_code object then it must be an
 * absolute fixup (relative ones are not saved) */
if ((old_value >= old_addr) && (old_value < (old_addr + nwords*N_WORD_BYTES)))

Moving the spaces was just to facilitate finding this example.
Here's another that could occur with the more standard lower placement of readonly space:
 @ #x80800000: CALL #x1000000 (displacement = -7F800000 = #x80800000)
so again it looks like the displacement is an address in the code.

Douglas Katzman (dougk) on 2018-02-14
summary: - 32-bit x86 code fixup after transport can make incorrect abs/rel
- determination
+ 32-bit x86 code fixup after GC transport can ruin the object
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers