Hi, I just put mine at 0x5000 for 32 and 64 bit, was easy to set up in secondary loader and then for the kernel to set up TSS, mine goes to 0x6038 to handle plenty of TSS entries. It looks like it will put at end, the size will depend on the variable you attach to it, and if you set it as global variable with variable set (NOLOAD not associated), no expert on linker script here. I set mine up slightly differently, I would go .GDT ALIGN(0x1000) : { *(.GDT) }. You can test it in code, print the address to screenonlyonemac wrote:I'm a bit confused about the linkscript though. Would this linkscript reserve space in the final binary for the global offset table, or would the global offset table "run over" the end of the binary into unallocated memory?Code: Select all
OUTPUT_FORMAT("elf32-i386") OUTPUT_ARCH(i386) ENTRY(start) SECTIONS { . = 0x00000000; .text : { *(.text) } .rodata : { *(.rodata) } . = ALIGN(4096); .data : { *(.data) } . = ALIGN(4096); .bss : { *(.bss) } . = ALIGN(4096); _GLOBAL_OFFSET_TABLE_ = .; . = ALIGN(4096); }
How to compile a flat position-independent binary with GCC?
Re: How to compile a flat position-independent binary with G
Re: How to compile a flat position-independent binary with G
I do not think that the elf32-i386 format would truncate the binary such that GOT is cut away. But see below for "binary".onlyonemac wrote: Would this linkscript reserve space in the final binary for the global offset table, or would the global offset table "run over" the end of the binary into unallocated memory?
I think the difference seen earlier could be a bug in linking when using OUTPUT_FORMAT("binary").
The binary created using that format has an empty GOT. i.e. the GOT is exactly at the offset equal to the size of the file.
So, if the binary is of 0x106c, the GOT is at offset 0x106c, and thus has to be necessarily empty.
The bug is in the way R_386_GOTOFF from the object is handled.
Below is the snippet.
Code: Select all
00000000 <.data>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 10 sub $0x10,%esp
6: e8 f5 0f 00 00 call 0x1000
b: 05 61 10 00 00 add $0x1061,%eax
10: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp)
17: 81 7d 08 be 00 00 00 cmpl $0xbe,0x8(%ebp)
1e: 0f 87 d3 00 00 00 ja 0xf7
24: 8b 55 08 mov 0x8(%ebp),%edx
27: c1 e2 02 shl $0x2,%edx
2a: 8b 94 02 1c 01 00 00 mov 0x11c(%edx,%eax,1),%edx
31: 01 d0 add %edx,%eax
33: ff e0 jmp *%eax
. . .
11a: eb fe jmp 0x11a
11c: 35 00 00 00 f7 xor $0xf7000000,%eax
. . .
147: 00 41 00 add %al,0x0(%ecx)
14a: 00 00 add %al,(%eax)
Code: Select all
2a: 8b 94 02 1c 01 00 00 mov 0x11c(%edx,%eax,1),%edx
Code: Select all
2a: 8b 94 02 b0 f0 ff ff mov -0xf50(%edx,%eax,1),%edx
About R_386_GOTOFF:
The distance of the jump table from GOT, as calculated in the working binary, isdetermine the distance from the GLOBAL_OFFSET_TABLE to the (local) "symbol"; store said distance in the dword at this location; create an entry in the GOT[]; change this reloc into a R_386_RELATIVE and point it at the GOT[] entry
Code: Select all
= symbol_addr - got_addr
= 0x11c - 0x106c
= -0xf50
Code: Select all
= symbol_addr - got_addr
= 0x11c - 0
= 0x11c.
for some relocations, the linker chose to use 0 as the GOT address instead of 0x106c. This shows inconsistency and possibly a bug.
I am writing to the binutils group to get more clarity.
Edit0: objcopy seems to be the way to go, instead of setting 'binary' directly (or even using output format switches). See here.
Edit1: BFD Information Loss