32-bit x86 code fixup after GC transport can ruin the object
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Fix Released
|
Undecided
|
Douglas Katzman |
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-
; E4: 09 BYTE #X09 ; ECX
The code bounds are #x9000004A through #x900000E4. The call offset is #x900000A9.
So this test in gencgc_
/* 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*
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.
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 |
Changed in sbcl: | |
assignee: | nobody → Douglas Katzman (dougk) |
status: | New → Fix Released |