summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2019-07-28 19:27:56 -0700
committerH. Peter Anvin <hpa@zytor.com>2019-07-28 19:27:56 -0700
commita68f6ef07a7b331be048615c8029f6ebd8cc358a (patch)
tree798de29ceac8a7179a420cb3fe3760124db154eb
parent4b691b81ce6a5607788ced4ce89f9bbbc4ec5d8a (diff)
downloadsamples-a68f6ef07a7b331be048615c8029f6ebd8cc358a.tar.gz
samples-a68f6ef07a7b331be048615c8029f6ebd8cc358a.tar.xz
samples-a68f6ef07a7b331be048615c8029f6ebd8cc358a.zip
elf2exe: relocation stub for 32-bit absolute relocations (currently unused)
Relocation stub which we could use to fix up 32-bit linear address relocations (R_386_RELATIVE).
-rw-r--r--elf2exe/rel32.asm89
1 files changed, 89 insertions, 0 deletions
diff --git a/elf2exe/rel32.asm b/elf2exe/rel32.asm
new file mode 100644
index 0000000..7288db2
--- /dev/null
+++ b/elf2exe/rel32.asm
@@ -0,0 +1,89 @@
+;
+; rel32.asm
+;
+; Simple stub to handle 32-bit absolute relocations, derived
+; from R_386_RELATIVE. This code gets stuffed at the end of the normal
+; file contents, followed by a short header and a relocation table in
+; the same format as the relocations in the EXE header. There is a
+; short header that needs to be filled in by elf2exe containing the
+; true entry point and the number of relocations.
+
+ cpu 8086
+ bits 16
+ ; On entry, DS = ES = PSP segment = load segment - 0x10
+_start:
+ push ds
+ push es
+ push ax
+ push bx
+ push cx
+ push dx
+ push si
+ push di
+ ; push bp ; Currently unused
+
+ mov ax,cs
+ mov ds,ax
+ mov si,reloc_tbl
+
+ mov bx,es ; = PSP segment
+ add bx,10h ; = load base segment
+ add [si+(entry.cs - reloc_tbl)],bx
+ ; Convert to an absolute address in DX:AX
+ mov ax,bx
+ xor dx,dx
+ add ax,ax
+ adc dx,dx
+ add ax,ax
+ adc dx,dx
+ add ax,ax
+ adc dx,dx
+ add ax,ax
+ adc dx,dx
+
+ mov cx,[si+(nrelocs - reloc_tbl)]
+
+ ; DX:AX = absolute base address
+ ; BX = segment base address
+ ; DS:SI = current relocation
+ ; CX = remaining relocation count
+ ; ES, DI, BP = free registers
+
+.relocloop:
+ mov di,[si+2]
+ add di,bx
+ mov es,di
+ mov di,[si]
+ add [es:di],ax
+ adc [es:di+2],dx
+ add si,4
+ jnc .ok
+ mov di,ds
+ add di,1000h
+ mov ds,di
+.ok:
+ loop .relocloop
+
+ ; pop bp
+ pop di
+ pop si
+ pop dx
+ pop cx
+ pop bx
+ pop es
+ pop ds
+
+ ; This aligns the following instruction to an address which
+ ; is congruent with 1 mod 4
+ times (1 - ($ - $$)) & 3 nop
+
+ jmp 0:0
+ ; This is the short header than needs to be filled in
+entry: ; Real entry point (vs load address)
+.ip: equ $-4
+.cs: equ $-2
+nrelocs: ; Relocation count
+ dw 0
+
+ ; This address will be aligned by 4
+reloc_tbl: ; Follows...