Fix stubs for shlib with only 2 PT_LOAD

This commit is contained in:
John Reiser
2023-07-22 11:46:44 -07:00
committed by Markus F.X.J. Oberhumer
parent 670aae2e11
commit 05539ad5b6
12 changed files with 6475 additions and 6387 deletions
+1185 -1172
View File
File diff suppressed because it is too large Load Diff
+1640 -1630
View File
File diff suppressed because it is too large Load Diff
+1653 -1643
View File
File diff suppressed because it is too large Load Diff
+1050 -1040
View File
File diff suppressed because it is too large Load Diff
+815 -804
View File
File diff suppressed because it is too large Load Diff
+11 -6
View File
@@ -115,10 +115,11 @@ __NR_readlink= 89
O_BINFO: .globl O_BINFO # ignored dummy needed by elf-entry.o
Pmap: .globl Pmap
mov %arg1,%rax; and $0xfff,%eax
sub %rax,%arg1 # page align lo end
add %rax,%arg2
mmap: .globl mmap
mov %arg1,%r10; and $0xfff,%r10
sub %r10,%arg1 # page align lo end
add %r10,%arg2
push $ __NR_mmap
sys_4args:
movq %arg4,%sys4
@@ -148,6 +149,12 @@ sysgo: # NOTE: kernel demands 4th arg in %sys4, NOT %arg4
syscall; cmp $-4096,%rax; jb 0f; int3; 0:
ret
Punmap: .globl Punmap // page-align the lo end
mov %arg1,%rax; and $0xfff,%eax
sub %rax,%arg1
add %rax,%arg2
munmap: .globl munmap
push $__NR_munmap; 5: jmp sysgo
exit: .globl exit
push $ __NR_exit; 5: jmp 5f
ftruncate: .globl ftruncate
@@ -162,15 +169,13 @@ write: .globl write
push $__NR_write; 5: jmp 5f
read: .globl read
push $ __NR_read; 5: jmp 5f
munmap: .globl munmap
push $__NR_munmap; 5: jmp sysgo
// Sometimes Linux enforces page-aligned address for mprotect
Pprotect: .globl Pprotect
mprotect: .globl mprotect
mov %rdi,%rax; and $-1+ (1<<12),%rax
sub %rax,%rdi
add %rax,%rsi
mprotect: .globl mprotect
push $ __NR_mprotect; 5: jmp sysgo
// section SO_MAIN inserted here
+18 -17
View File
@@ -34,6 +34,8 @@
// Pprotect is mprotect, but page-aligned on the lo end (Linux requirement)
unsigned Pprotect(void *, size_t, unsigned);
void *Pmap(void *, size_t, unsigned, unsigned, int, size_t);
int Punmap(void *, size_t);
extern void f_int3(int arg);
@@ -435,7 +437,7 @@ typedef struct {
typedef struct {
unsigned off_reloc; // distance back to &Elf64_Ehdr
unsigned off_user_DT_INIT;
unsigned off_xct_off; // where un-compressed bytes end [unused?]
unsigned off_xct_off; // where un-compressed bytes end
unsigned off_info; // xct_off: {l_info; p_info; b_info; compressed data)
} So_info;
@@ -527,10 +529,9 @@ upx_so_main( // returns &escape_hatch
if ((phdr->p_filesz + phdr->p_offset) <= so_infc.off_xct_off) {
continue; // below compressed region
}
Elf64_Addr pfx = so_infc.off_xct_off - phdr->p_offset;
if ( so_infc.off_xct_off < phdr->p_offset) {
pfx = 0; // no more partially-compressed PT_LOAD
}
Elf64_Addr const pfx = (so_infc.off_xct_off < phdr->p_offset)
? 0 // entire PT_LOAD is compressed
: so_infc.off_xct_off - phdr->p_offset ; // below xct_off is not
x0.size = sizeof(struct b_info);
xread(&x0, (char *)&al_bi, x0.size); // aligned binfo
x0.buf -= sizeof(al_bi); // back up (the xread() was a peek)
@@ -539,13 +540,13 @@ upx_so_main( // returns &escape_hatch
// Using .p_memsz implicitly handles .bss via MAP_ANONYMOUS.
// Omit any non-tcompressed prefix (below xct_off)
x1.buf = (char *)(phdr->p_vaddr + pfx + base);
x1.buf = (char *)(pfx + phdr->p_vaddr + base);
x1.size = phdr->p_memsz - pfx;
pfx = (phdr->p_vaddr + pfx) & ~PAGE_MASK; // lo fragment on page
x1.buf -= pfx;
x1.size += pfx;
DPRINTF("phdr(%%p %%p) xct_off=%%x pfx=%%x\\n", x1.buf, x1.size, xct_off, pfx);
unsigned const frag = (phdr->p_vaddr + pfx) & ~PAGE_MASK; // lo fragment on page
x1.buf -= frag;
x1.size += frag;
DPRINTF("phdr(%%p %%p) xct_off=%%x frag=%%x\\n", x1.buf, x1.size, xct_off, frag);
int mfd = 0;
char *mfd_addr = 0;
@@ -555,7 +556,7 @@ upx_so_main( // returns &escape_hatch
// to hold the contents.
mfd = memfd_create(addr_string("upx"), 0); // the directory entry
ftruncate(mfd, x1.size); // Allocate the pages in the file.
write(mfd, x1.buf, pfx); // Save lo fragment of contents on first page.
write(mfd, x1.buf, frag); // Save lo fragment of contents on first page.
mfd_addr = mmap(0, x1.size, PROT_READ|PROT_WRITE, MAP_SHARED, mfd, 0);
DPRINTF("mfd_addr= %%p\\n", mfd_addr); // Now "somewhere" in RAM,
// and ready to receive de-compressed bytes, and remember them in the
@@ -563,14 +564,14 @@ upx_so_main( // returns &escape_hatch
// Must keep the original compressed data until now, in order to
// prevent the mmap(0, ...) from stealing that address range.
munmap(x1.buf, x1.size); // Discard original page frames in RAM.
x1.buf = mfd_addr; // will add pfx soon
Punmap(x1.buf, x1.size); // Discard original page frames in RAM.
x1.buf = mfd_addr; // will add frag soon
}
else {
underlay(x1.size, x1.buf, pfx); // also makes PROT_WRITE
underlay(x1.size, x1.buf, frag); // also makes PROT_WRITE
}
x1.buf += pfx;
x1.buf += frag;
x1.size = al_bi.sz_unc;
x0.size = al_bi.sz_cpr + sizeof(struct b_info);
DPRINTF("befor unpack x0=(%%p %%p x1=(%%p %%p)\\n", x0.size, x0.buf, x1.size, x1.buf);
@@ -590,8 +591,8 @@ upx_so_main( // returns &escape_hatch
if (phdr->p_flags & PF_X) { // SELinux
// Map the contents of mfd as per *phdr.
DPRINTF("mfd mmap addr=%%p len=%%p\\n", (phdr->p_vaddr + base + pfx), al_bi.sz_unc);
munmap(mfd_addr, pfx + al_bi.sz_unc); // Discard RW mapping; mfd has the bytes
mmap((char *)(phdr->p_vaddr + base + pfx), al_bi.sz_unc, PF_to_PROT(phdr),
munmap(mfd_addr, frag + al_bi.sz_unc); // Discard RW mapping; mfd has the bytes
Pmap((char *)(phdr->p_vaddr + base + pfx), al_bi.sz_unc, PF_to_PROT(phdr),
MAP_FIXED|MAP_PRIVATE, mfd, 0);
close(mfd);
}
+15 -7
View File
@@ -182,10 +182,6 @@ brk:
readlink:
do_sys __NR_readlink; ret
.globl munmap
munmap:
do_sys __NR_munmap; ret
ftruncate: .globl ftruncate
do_sys __NR_ftruncate; ret
@@ -194,15 +190,19 @@ memfd_create: .globl memfd_create
// Sometimes Linux enforces page-aligned address
Pprotect: .globl Pprotect
mprotect: .globl mprotect
ldr r12,m_off4k
and r12,r12,r0
sub r0,r0,r12
add r1,r1,r12
mprotect: .globl mprotect
do_sys __NR_mprotect; ret
.globl mmap
mmap:
Pmap: .globl Pmap
ldr r12,m_off4k
and r12,r12,r0
sub r0,r0,r12
add r1,r1,r12
mmap: .globl mmap
stmdb sp!,{r4,r5,lr}
ldr r5,[sp,#4*4]
ldr r4,[sp,#3*4]
@@ -215,6 +215,14 @@ mmap_do:
do_sys __NR_mmap2
ldmia sp!,{r4,r5,pc}
Punmap: .globl Punmap
ldr r12,m_off4k
and r12,r12,r0
sub r0,r0,r12
add r1,r1,r12
munmap: .globl munmap
do_sys __NR_munmap; ret
m_off4k:
.word -1+ (1<<PAGE_SHIFT) // offset mask for 4KiB
+7 -4
View File
@@ -146,8 +146,11 @@ brk:
readlink:
do_sys __NR_readlink; ret
.globl munmap
munmap:
Punmap: .globl Punmap
and x8,x0,#-1+ (1<<12) // FIXME: variable PAGE_MASK
sub x0,x0,x8
add x1,x1,x8
munmap: .globl munmap
do_sys __NR_munmap; ret
// Sometimes Linux enforces page-aligned address
@@ -170,11 +173,11 @@ mmap_privanon: .globl mmap_privanon
mov x5,#0 // offset= 0
// FALL THROUGH to mmap
.globl mmap
mmap:
Pmap: .globl Pmap
and x8,x0,#-1+ (1<<12) // FIXME: variable PAGE_MASK
sub x0,x0,x8
add x1,x1,x8
mmap: .globl mmap
do_sys __NR_mmap; ret
get_sys_munmap: .globl get_sys_munmap // r0= system call instruction
+15 -1
View File
@@ -121,6 +121,7 @@ __NR_exit= 1
__NR_readlink= 85
Pmap: .globl Pmap
mmap: .globl mmap // oldmmap: %ebx -> 6 word parameters
push %ebx // save C-lang register
lea 2*NBPW(%esp),%ebx
@@ -156,7 +157,7 @@ mmap: .globl mmap // oldmmap: %ebx -> 6 word parameters
#endif //}
// Sometimes linux enforces page-aligned address
Pprotect: .globl Pprotect
Pprotect: .globl Pprotect // from C
xchg %ebx,1*NBPW(%esp) // save reg, %ebx= address
mov %ebx,%ecx // copy address
and $~0<<12,%ebx // page align
@@ -168,6 +169,19 @@ Pprotect: .globl Pprotect
mov 1*NBPW(%esp),%ebx // restore reg
ret
Punmap: .globl Punmap // from C
push %ebp; mov %esp,%ebp
push %ebx
mov (0+2)*NBPW(%ebp),%ebx // addr
mov %ebx,%eax; and $-1+ (1<<12),%eax
sub %eax,%ebx
mov (1+2)*NBPW(%ebp),%ecx // len
add %eax,%ecx
push $__NR_munmap; pop %eax; int $0x80
cmp $-0x1000,%eax; jna 0f; hlt; 0:
pop %ebx; pop %ebp
ret
memfd_create: .globl memfd_create
int3
push $__NR_memfd_create; 5: jmp 5f
+14 -13
View File
@@ -39,6 +39,9 @@ extern void my_bkpt(void const *arg1, ...);
// Pprotect is mprotect, but page-aligned on the lo end (Linux requirement)
unsigned Pprotect(void *, size_t, unsigned);
void *mmap(void *, size_t, int, int, int, off_t);
void *Pmap(void *, size_t, int, int, int, off_t);
int Punmap(void *, size_t);
#if defined(__i386__) || defined(__mips__) || defined(__powerpc__) //{
# define mmap_privanon(addr,len,prot,flgs) mmap((addr),(len),(prot), \
MAP_PRIVATE|MAP_ANONYMOUS|(flgs),-1,0)
@@ -581,10 +584,9 @@ upx_so_main( // returns &escape_hatch
if ((phdr->p_filesz + phdr->p_offset) <= so_infc.off_xct_off) {
continue; // below compressed region
}
Elf32_Addr pfx = so_infc.off_xct_off - phdr->p_offset;
if ( so_infc.off_xct_off < phdr->p_offset) {
pfx = 0; // no more partially-compressed PT_LOAD
}
Elf32_Addr const pfx = (so_infc.off_xct_off < phdr->p_offset)
? 0 // entire PT_LOAD is compressed
: so_infc.off_xct_off - phdr->p_offset ; // below xct_off is not
x0.size = sizeof(struct b_info);
xread(&x0, (char *)&al_bi, x0.size); // aligned binfo
x0.buf -= sizeof(al_bi); // back up (the xread() was a peek)
@@ -596,10 +598,10 @@ upx_so_main( // returns &escape_hatch
x1.buf = (char *)(phdr->p_vaddr + pfx + base);
x1.size = phdr->p_memsz - pfx;
pfx = (phdr->p_vaddr + pfx) & ~page_mask; // lo fragment on page
x1.buf -= pfx;
x1.size += pfx;
DPRINTF("phdr(%%p %%p) xct_off=%%x pfx=%%x\\n", x1.buf, x1.size, xct_off, pfx);
unsigned const frag = (phdr->p_vaddr + pfx) & ~page_mask; // lo fragment on page
x1.buf -= frag;
x1.size += frag;
DPRINTF("phdr(%%p %%p) xct_off=%%x frag=%%x\\n", x1.buf, x1.size, xct_off, frag);
int mfd = 0;
char *mfd_addr = 0;
@@ -609,7 +611,7 @@ upx_so_main( // returns &escape_hatch
// to hold the contents.
mfd = memfd_create(addr_string("upx"), 0); // the directory entry
ftruncate(mfd, x1.size); // Allocate the pages in the file.
write(mfd, x1.buf, pfx); // Save lo fragment of contents on first page.
write(mfd, x1.buf, frag); // Save lo fragment of contents on first page.
mfd_addr = mmap(0, x1.size, PROT_READ|PROT_WRITE, MAP_SHARED, mfd, 0);
DPRINTF("mfd_addr= %%p\\n", mfd_addr); // Now "somewhere" in RAM,
// and ready to receive de-compressed bytes, and remember them in the
@@ -619,13 +621,12 @@ upx_so_main( // returns &escape_hatch
// prevent the mmap(0, ...) from stealing that address range.
munmap(x1.buf, x1.size); // Discard original page frames in RAM.
x1.buf = mfd_addr; // will add pfx soon
DPRINTF("mfd_addr= %%p\\n", mfd_addr);
}
else {
underlay(x1.size, x1.buf, pfx, phdr->p_flags); // also makes PROT_WRITE
underlay(x1.size, x1.buf, frag, phdr->p_flags); // also makes PROT_WRITE
}
x1.buf += pfx;
x1.buf += frag;
x1.size = al_bi.sz_unc;
x0.size = al_bi.sz_cpr + sizeof(struct b_info);
DPRINTF("befor unpack x0=(%%p %%p x1=(%%p %%p)\\n", x0.size, x0.buf, x1.size, x1.buf);
@@ -647,7 +648,7 @@ upx_so_main( // returns &escape_hatch
// Map the contents of mfd as per *phdr.
DPRINTF("mfd mmap addr=%%p len=%%p\\n", (phdr->p_vaddr + base + pfx), al_bi.sz_unc);
munmap(mfd_addr, pfx + al_bi.sz_unc); // Discard RW mapping; mfd has the bytes
mmap((char *)(phdr->p_vaddr + base + pfx), al_bi.sz_unc, PF_to_PROT(phdr),
Pmap((char *)(phdr->p_vaddr + base + pfx), al_bi.sz_unc, PF_to_PROT(phdr),
MAP_FIXED|MAP_PRIVATE, mfd, 0);
close(mfd);
}
+52 -50
View File
@@ -2,19 +2,19 @@ file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn Flags
0 SO_MAIN 01229 0 0 040 2**4 CONTENTS
1 EXP_HEAD 0e0 0 0 01269 2**0 CONTENTS
2 NRV2E 0e5 0 0 01349 2**0 CONTENTS
3 NRV2D 0d7 0 0 0142e 2**0 CONTENTS
4 NRV2B 0c1 0 0 01505 2**0 CONTENTS
5 SO_HEAD 02c 0 0 015c6 2**0 CONTENTS
6 ptr_NEXT 0 0 0 015f2 2**0 CONTENTS
7 SO_TAIL 08c 0 0 015f2 2**0 CONTENTS
8 LZMA_ELF00 064 0 0 0167e 2**0 CONTENTS
9 LZMA_DEC10 09f7 0 0 016e2 2**0 CONTENTS
10 LZMA_DEC20 09f7 0 0 020d9 2**0 CONTENTS
11 LZMA_DEC30 018 0 0 02ad0 2**0 CONTENTS
12 EXP_TAIL 0c 0 0 02ae8 2**0 CONTENTS
0 SO_MAIN 01259 0 0 040 2**4 CONTENTS
1 EXP_HEAD 0e0 0 0 01299 2**0 CONTENTS
2 NRV2E 0e5 0 0 01379 2**0 CONTENTS
3 NRV2D 0d7 0 0 0145e 2**0 CONTENTS
4 NRV2B 0c1 0 0 01535 2**0 CONTENTS
5 SO_HEAD 02c 0 0 015f6 2**0 CONTENTS
6 ptr_NEXT 0 0 0 01622 2**0 CONTENTS
7 SO_TAIL 098 0 0 01622 2**0 CONTENTS
8 LZMA_ELF00 064 0 0 016ba 2**0 CONTENTS
9 LZMA_DEC10 09f7 0 0 0171e 2**0 CONTENTS
10 LZMA_DEC20 09f7 0 0 02115 2**0 CONTENTS
11 LZMA_DEC30 018 0 0 02b0c 2**0 CONTENTS
12 EXP_TAIL 0c 0 0 02b24 2**0 CONTENTS
SYMBOL TABLE:
0000000000000000 l d EXP_HEAD 0 EXP_HEAD
0000000000000000 l d LZMA_DEC30 0 LZMA_DEC30
@@ -29,26 +29,28 @@ SYMBOL TABLE:
0000000000000000 l d LZMA_ELF00 0 LZMA_ELF00
0000000000000000 l d LZMA_DEC10 0 LZMA_DEC10
0000000000000000 l d LZMA_DEC20 0 LZMA_DEC20
0000000000000031 g SO_TAIL 0 Pmap
0000000000000000 g EXP_HEAD 0 f_expand
0000000000000075 g SO_TAIL 0 munmap
000000000000005f g SO_TAIL 0 munmap
000000000000001c g SO_TAIL 0 memcpy
0000000000000000 g F SO_MAIN 030 dprint8
0000000000000031 g SO_TAIL 0 O_BINFO
0000000000000057 g SO_TAIL 0 ftruncate
0000000000000031 g SO_TAIL 0 mmap
0000000000000067 g SO_TAIL 0 ftruncate
000000000000003f g SO_TAIL 0 mmap
0000000000000000 g F SO_TAIL 0 eof
000000000000006d g SO_TAIL 0 write
000000000000007d g SO_TAIL 0 write
0000000000000680 g F SO_MAIN 01d PF_to_PROT
000000000000005b g SO_TAIL 0 memfd_create
0000000000000071 g SO_TAIL 0 read
000000000000006b g SO_TAIL 0 memfd_create
0000000000000081 g SO_TAIL 0 read
0000000000000013 g SO_TAIL 0 memset
0000000000000011 g SO_TAIL 0 my_bkpt
0000000000000079 g SO_TAIL 0 Pprotect
0000000000000053 g SO_TAIL 0 exit
0000000000000066 g SO_TAIL 0 openat
0000000000000079 g SO_TAIL 0 mprotect
0000000000000062 g SO_TAIL 0 close
000000000000069d g F SO_MAIN 07c8 upx_so_main
0000000000000085 g SO_TAIL 0 Pprotect
0000000000000051 g SO_TAIL 0 Punmap
0000000000000063 g SO_TAIL 0 exit
0000000000000076 g SO_TAIL 0 openat
0000000000000094 g SO_TAIL 0 mprotect
0000000000000072 g SO_TAIL 0 close
000000000000069d g F SO_MAIN 0800 upx_so_main
RELOCATION RECORDS FOR [SO_MAIN]:
OFFSET TYPE VALUE
@@ -68,31 +70,31 @@ OFFSET TYPE VALUE
0000000000000654 R_X86_64_PLT32 memcpy+0xfffffffffffffffc
000000000000079c R_X86_64_PLT32 mmap+0xfffffffffffffffc
00000000000007d1 R_X86_64_PLT32 memcpy+0xfffffffffffffffc
00000000000008f3 R_X86_64_PLT32 memfd_create+0xfffffffffffffffc
000000000000090c R_X86_64_PLT32 write+0xfffffffffffffffc
0000000000000920 R_X86_64_PLT32 write+0xfffffffffffffffc
000000000000092f R_X86_64_PLT32 munmap+0xfffffffffffffffc
0000000000000937 R_X86_64_PLT32 PF_to_PROT+0xfffffffffffffffc
0000000000000952 R_X86_64_PLT32 mmap+0xfffffffffffffffc
0000000000000959 R_X86_64_PLT32 close+0xfffffffffffffffc
0000000000000bde R_X86_64_PLT32 memfd_create+0xfffffffffffffffc
0000000000000bf0 R_X86_64_PLT32 ftruncate+0xfffffffffffffffc
0000000000000c03 R_X86_64_PLT32 write+0xfffffffffffffffc
0000000000000c28 R_X86_64_PLT32 mmap+0xfffffffffffffffc
0000000000000c61 R_X86_64_PLT32 munmap+0xfffffffffffffffc
0000000000000d72 R_X86_64_PLT32 munmap+0xfffffffffffffffc
0000000000000d7a R_X86_64_PLT32 PF_to_PROT+0xfffffffffffffffc
0000000000000da0 R_X86_64_PLT32 mmap+0xfffffffffffffffc
0000000000000da8 R_X86_64_PLT32 close+0xfffffffffffffffc
0000000000000db2 R_X86_64_PLT32 PF_to_PROT+0xfffffffffffffffc
0000000000000dc8 R_X86_64_PLT32 Pprotect+0xfffffffffffffffc
0000000000000de3 R_X86_64_PLT32 munmap+0xfffffffffffffffc
0000000000001043 R_X86_64_PLT32 write+0xfffffffffffffffc
00000000000010aa R_X86_64_PLT32 write+0xfffffffffffffffc
00000000000010fc R_X86_64_PLT32 write+0xfffffffffffffffc
0000000000001150 R_X86_64_PLT32 write+0xfffffffffffffffc
00000000000011ac R_X86_64_PLT32 write+0xfffffffffffffffc
0000000000001208 R_X86_64_PLT32 write+0xfffffffffffffffc
00000000000008f9 R_X86_64_PLT32 memfd_create+0xfffffffffffffffc
0000000000000912 R_X86_64_PLT32 write+0xfffffffffffffffc
0000000000000926 R_X86_64_PLT32 write+0xfffffffffffffffc
0000000000000935 R_X86_64_PLT32 munmap+0xfffffffffffffffc
000000000000093d R_X86_64_PLT32 PF_to_PROT+0xfffffffffffffffc
0000000000000958 R_X86_64_PLT32 mmap+0xfffffffffffffffc
000000000000095f R_X86_64_PLT32 close+0xfffffffffffffffc
0000000000000bf6 R_X86_64_PLT32 memfd_create+0xfffffffffffffffc
0000000000000c09 R_X86_64_PLT32 ftruncate+0xfffffffffffffffc
0000000000000c1d R_X86_64_PLT32 write+0xfffffffffffffffc
0000000000000c44 R_X86_64_PLT32 mmap+0xfffffffffffffffc
0000000000000c7f R_X86_64_PLT32 Punmap+0xfffffffffffffffc
0000000000000da4 R_X86_64_PLT32 munmap+0xfffffffffffffffc
0000000000000dac R_X86_64_PLT32 PF_to_PROT+0xfffffffffffffffc
0000000000000dd7 R_X86_64_PLT32 Pmap+0xfffffffffffffffc
0000000000000de0 R_X86_64_PLT32 close+0xfffffffffffffffc
0000000000000dea R_X86_64_PLT32 PF_to_PROT+0xfffffffffffffffc
0000000000000e00 R_X86_64_PLT32 Pprotect+0xfffffffffffffffc
0000000000000e1b R_X86_64_PLT32 munmap+0xfffffffffffffffc
0000000000001078 R_X86_64_PLT32 write+0xfffffffffffffffc
00000000000010da R_X86_64_PLT32 write+0xfffffffffffffffc
000000000000112c R_X86_64_PLT32 write+0xfffffffffffffffc
0000000000001180 R_X86_64_PLT32 write+0xfffffffffffffffc
00000000000011dc R_X86_64_PLT32 write+0xfffffffffffffffc
0000000000001238 R_X86_64_PLT32 write+0xfffffffffffffffc
RELOCATION RECORDS FOR [NRV2E]:
OFFSET TYPE VALUE