Code: Select all
PHDRS
{
phdr_text PT_LOAD FLAGS(5); /* read + execute */
phdr_rodata PT_LOAD FLAGS(4); /* read */
phdr_data PT_LOAD FLAGS(6); /* read + write */
phdr_tls PT_TLS FLAGS(4);
}
SECTIONS
{
. = 0x00010000;
.text :
{
*(.text*)
} :phdr_text
...
Code: Select all
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x001000 0x00010000 0x00010000 0x3ee02 0x3ee02 R E 0x1000
LOAD 0x040000 0x0004f000 0x0004f000 0x12ebf 0x12ebf R 0x1000
LOAD 0x053000 0x00062000 0x00062000 0x00258 0x00898 RW 0x1000
TLS 0x053258 0x00063000 0x00063000 0x00000 0x00060 R 0x4
Code: Select all
PHDRS
{
phdr_phdrs PT_PHDR PHDRS;
phdr_text PT_LOAD PHDRS FLAGS(5); /* read + execute */
phdr_rodata PT_LOAD FLAGS(4); /* read */
phdr_data PT_LOAD FLAGS(6); /* read + write */
phdr_tls PT_TLS FLAGS(4);
}
SECTIONS
{
. = 0x00010000 + SIZEOF_HEADERS;
.text :
{
*(.text*)
} :phdr_text
Code: Select all
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x00010034 0x00010034 0x000a0 0x000a0 R 0x4
LOAD 0x000034 0x00010034 0x00010034 0x3eeae 0x3eeae R E 0x1000
LOAD 0x03f000 0x0004f000 0x0004f000 0x12ebf 0x12ebf R 0x1000
LOAD 0x052000 0x00062000 0x00062000 0x00258 0x00898 RW 0x1000
TLS 0x052258 0x00063000 0x00063000 0x00000 0x00060 R 0x4
My problem is on x86_64 where I basically use identical linker scripts (except for OUTPUT_FORMAT and OUTPUT_ARCH). The result of applying the changes doesn't result in the same behaviour.
Without PT_PHDR:
Code: Select all
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align
LOAD 0x0000000000010000 0x0000000000010000 0x0000000000010000 0x0000000000046782 0x0000000000046782 R E 0x200000
LOAD 0x0000000000057000 0x0000000000057000 0x0000000000057000 0x000000000001c69b 0x000000000001c69b R 0x200000
LOAD 0x0000000000074000 0x0000000000074000 0x0000000000074000 0x0000000000000308 0x0000000000000ee0 RW 0x200000
TLS 0x0000000000074308 0x0000000000075000 0x0000000000075000 0x0000000000000000 0x00000000000000b0 R 0x8
Code: Select all
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040 0x0000000000000118 0x0000000000000118 R 0x8
LOAD 0x0000000000000040 0x0000000000000040 0x0000000000000040 0x00000000000568a2 0x00000000000568a2 R E 0x200000
LOAD 0x0000000000057000 0x0000000000057000 0x0000000000057000 0x000000000001c69b 0x000000000001c69b R 0x200000
LOAD 0x0000000000074000 0x0000000000074000 0x0000000000074000 0x0000000000000308 0x0000000000000ee0 RW 0x200000
TLS 0x0000000000074308 0x0000000000075000 0x0000000000075000 0x0000000000000000 0x00000000000000b0 R 0x8
If I don't set the program counter at all and base my image at 0, it works the same in both cases (ia32 and x86_64). This results in an image based at 0. But I'd like my image to start at 0x10000 as I don't want to be relocating executables.
Anyone has ideas here and/or a different way to approach this?