`__ehdr_start` should have bounds that span the program headers
__ehdr_start
is a linker provided symbol that points to the file header and program headers if there is some loadable segment which contains them both.
Glibc uses this symbol to access the program headers robustly.
In order to access those program headers through __ehdr_start
the capability based on the address of this symbol needs to have bounds which cover the program headers.
I believe the below test demonstrates that this is not the case (the PHDR segment contains the program headers, and is outside the bounds of the __ehdr_start
symbol).
N.b. it also looks like the __executable_start
symbol is similarly limited in bounds, I checked that one simply because it's defined in the same elf::addReservedSymbols
function (though there are others). I don't know of any code that uses that symbol so can't tell whether the bounds set on that symbol are fine or not.
vshcmd: > cat /home/matmal01/work-backup/matmal01/Documents/gnu-work/Morello/bare-metal-gnu/src/binutils-gdb/ld/testsuite/ld-aarch64/c64-ehdr-sized-reloc.s
.data
.global val
val:
.chericap __ehdr_start
.xword 0xffffffffffffffff
.chericap __executable_start
.size val, .-val
.align 4
.text
.global _start
_start:
ldr c0, [c0, :got_lo12:val]
testing [17:05:42] $
vshcmd: > ~/Documents/clang-current/bin/clang -fuse-ld=lld -Wl,-shared -target aarch64 -march=morello+c64 -mabi=purecap /home/matmal01/work-backup/matmal01/Documents/gnu-work/Morello/bare-metal-gnu/src/binutils-gdb/ld/testsuite/ld-aarch64/c64-ehdr-sized-reloc.s -nostdlib
testing [17:05:43] $
vshcmd: > aarch64-none-elf-readelf --sections --segments a.out
There are 14 section headers, starting at offset 0x5d8:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .dynsym DYNSYM 0000000080000200 00000200
0000000000000048 0000000000000018 A 4 1 64
[ 2] .gnu.hash GNU_HASH 0000000080000248 00000248
0000000000000024 0000000000000000 A 1 0 8
[ 3] .hash HASH 000000008000026c 0000026c
0000000000000020 0000000000000004 A 1 0 4
[ 4] .dynstr STRTAB 000000008000028c 0000028c
000000000000000c 0000000000000000 A 0 0 1
[ 5] .rela.dyn RELA 0000000080000298 00000298
0000000000000048 0000000000000018 A 1 0 8
[ 6] .text PROGBITS 00000000800102e0 000002e0
0000000000000004 0000000000000000 AX 0 0 4
[ 7] .dynamic DYNAMIC 00000000800202e8 000002e8
00000000000000b0 0000000000000010 WA 4 0 8
[ 8] .got PROGBITS 00000000800203a0 000003a0
0000000000000020 0000000000000000 WA 0 0 16
[ 9] .data PROGBITS 00000000800303c0 000003c0
0000000000000030 0000000000000000 WA 0 0 16
[10] .comment PROGBITS 0000000000000000 000003f0
000000000000007e 0000000000000001 MS 0 0 1
[11] .symtab SYMTAB 0000000000000000 00000470
00000000000000c0 0000000000000018 13 6 8
[12] .shstrtab STRTAB 0000000000000000 00000530
0000000000000068 0000000000000000 0 0 1
[13] .strtab STRTAB 0000000000000000 00000598
000000000000003f 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
p (processor specific)
Elf file type is DYN (Shared object file)
Entry point 0x800102e0
There are 8 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000080000040 0x0000000080000040
0x00000000000001c0 0x00000000000001c0 R 0x8
LOAD 0x0000000000000000 0x0000000080000000 0x0000000080000000
0x00000000000002e0 0x00000000000002e0 R 0x10000
LOAD 0x00000000000002e0 0x00000000800102e0 0x00000000800102e0
0x0000000000000004 0x0000000000000004 R E 0x10000
LOAD 0x00000000000002e8 0x00000000800202e8 0x00000000800202e8
0x00000000000000d8 0x00000000000000d8 RW 0x10000
LOAD 0x00000000000003c0 0x00000000800303c0 0x00000000800303c0
0x0000000000000030 0x0000000000000030 RW 0x10000
DYNAMIC 0x00000000000002e8 0x00000000800202e8 0x00000000800202e8
0x00000000000000b0 0x00000000000000b0 RW 0x8
GNU_RELRO 0x00000000000002e8 0x00000000800202e8 0x00000000800202e8
0x00000000000000d8 0x0000000000000d18 R 0x1
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x0
Section to Segment mapping:
Segment Sections...
00
01 .dynsym .gnu.hash .hash .dynstr .rela.dyn
02 .text
03 .dynamic .got
04 .data
05 .dynamic
06 .dynamic .got
07
testing [17:05:43] $
vshcmd: > aarch64-none-elf-objdump -dR -j .data -j .text a.out
a.out: file format elf64-littleaarch64
Disassembly of section .text:
00000000800102e0 <_start>:
800102e0: c240e800 ldr c0, [c0, #928]
Disassembly of section .data:
00000000800303c0 <val>:
800303c0: 80000000 .word 0x80000000
800303c0: R_MORELLO_RELATIVE *ABS*
800303c4: 00000000 .word 0x00000000
800303c8: 00000040 .word 0x00000040
800303cc: 01000000 .word 0x01000000
800303d0: ffffffff .word 0xffffffff
800303d4: ffffffff .word 0xffffffff
...
800303e0: 80000000 .word 0x80000000
800303e0: R_MORELLO_RELATIVE *ABS*
800303e4: 00000000 .word 0x00000000
800303e8: 00000040 .word 0x00000040
800303ec: 01000000 .word 0x01000000
testing [17:05:44] $