Hi: I have a cross compiling LD from binutils 2.20 which targets i586-elf, and was compiled using a my native ubuntu pre-installed GCC 4.4.1 toolchain. I use the cross compiler to generate ELF binaries for a freestanding environment.
Here is the output of objdump as run on two output final binaries from the same project: grava...@gravaera-pc:/osdev/zbz$ objdump -p -h zambezii.zxe tmp/zambezii.zxe zambezii.zxe: file format elf32-i386 Program Header: LOAD off 0x00001000 vaddr 0x00100000 paddr 0x00100000 align 2**12 filesz 0x00000030 memsz 0x00000030 flags rw- LOAD off 0x00002000 vaddr 0xc0005000 paddr 0x00105000 align 2**12 filesz 0x000000b1 memsz 0x000000b1 flags r-x LOAD off 0x00003000 vaddr 0xc0006000 paddr 0x00106000 align 2**12 filesz 0x00007138 memsz 0x00014690 flags rwx STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2 filesz 0x00000000 memsz 0x00000000 flags rwx Sections: Idx Name Size VMA LMA File off Algn 0 .__kheaders 00000030 00100000 00100000 00001000 2**2 CONTENTS, ALLOC, LOAD, DATA 1 .__ksetup 00004000 00101000 00101000 0000b000 2**12 CONTENTS, READONLY 2 .__korientation 000000b1 c0005000 00105000 00002000 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 3 .ctor 00000010 c0006000 00106000 00003000 2**2 CONTENTS, ALLOC, LOAD, DATA 4 .text 000059ab c0007000 00107000 00004000 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 5 .data 00000138 c000d000 0010d000 0000a000 2**3 CONTENTS, ALLOC, LOAD, DATA 6 .bss 0000c690 c000e000 0010e000 0000a138 2**5 ALLOC tmp/zambezii.zxe: file format elf32-i386 Program Header: LOAD off 0x00001000 vaddr 0x00100000 paddr 0x00100000 align 2**12 filesz 0x00005000 memsz 0x00005000 flags rw- LOAD off 0x00006000 vaddr 0xc0005000 paddr 0x00105000 align 2**12 filesz 0x000000b1 memsz 0x000000b1 flags r-x LOAD off 0x00007000 vaddr 0xc0006000 paddr 0x00106000 align 2**12 filesz 0x00007138 memsz 0x00014690 flags rwx STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2 filesz 0x00000000 memsz 0x00000000 flags rwx Sections: Idx Name Size VMA LMA File off Algn 0 .__kheaders 00000030 00100000 00100000 00001000 2**2 CONTENTS, ALLOC, LOAD, DATA 1 .__ksetup 00004000 00101000 00101000 00002000 2**12 CONTENTS, ALLOC, LOAD, DATA 2 .__korientation 000000b1 c0005000 00105000 00006000 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 3 .ctor 00000014 c0006000 00106000 00007000 2**2 CONTENTS, ALLOC, LOAD, DATA 4 .text 00005a5b c0007000 00107000 00008000 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 5 .data 00000138 c000d000 0010d000 0000e000 2**3 CONTENTS, ALLOC, LOAD, DATA 6 .bss 0000c690 c000e000 0010e000 0000e138 2**5 ALLOC ---------------------------------------- The first file is the one which is generated as of this email. The second is the one which used to be generated before I made a minor change in my source. The problem is this: I generate page tables statically in my kernel image, and have them placed in a section '.__ksetup', which is set, by my custom linker script, to link to the same virtual address as the physical load address. The rest of the sections (other than .__kheaders) are linked to 0xC0000000. As you can see, .__ksetup section is of size 16KB in the final image of both files, and should be loaded with the rest of the file into memory, and the LOAD header in the second (the former output) reflects this. However, as of this writing, the output binary excludes the .__ksetup section from the LOAD headers, even though .__ksetup section is actually included in the kernel binary. I have verified this with a hexdump. Both output files are created with the same cross compiler. The simple change I made to the source of my project was that I had been generating a top level table in ASM, and several lower tables which were pointed to by the top level table in C++. There are four tables in all, each 4KB, (thus 16KB). I found that G++ seemed to think that the linker could do with some 'help', and G++ tended to, instead of inserting references to symbols in a relocation table for the linker to resolve, it would generate a constructor for any relocations to be done on symbols for data relocations. So the G++ compiler would generate a constructor to do the relocation at runtime before the program started. Needless to say, this is undesirable in a kernel. So I replaced the tables which were done in C++ with their equivalents in assembly, and ensured that they linked. They did. I ensured they linked and were relocated at link time properly with a hexdump. You can rest assured that the page tables are in the kernel image since I had to do extensive debugging to find out why my kernel was triple faulting on code that used to work. You can see for yourself: the .__ksetup section in the final image of both files is 16KB large. To conclude: For some reason, LD has decided that a section should not be placed into the LOAD headers, *even though* ALL of the tables are referenced externally and would need to be resolved and copied into the final image (which is WHY they appear there. They are not optimized out.). Note that the problem has several hacky fixes: but this IS strange behaviour, and I can see no cogent reason why the linker just randomly decided to exclude a section from being loaded, so I thought it a good idea to let the dev team know instead of just quietly fixing the problem for myself with a hack and moving on. As per (http://web.mit.edu/~sdavies/MacData/afs/athena/project/rhel-doc/3/rhel-ld-en-3/bug-reporting.html), I am giving environment info here: Invocation: i586-elf-ld -T platform/__klinkScript.ld -o ../zambezii.zxe \ -\( __kthreads.a kernel.a platform.a memoryTrib.a numaTrib.a cpuTrib.a firmware.a chipset.a arch.a __kclasses.a __kcxxabi.a __kstdlib.a __kcxxlib.a __kclib.a lang.a -\) make[1]: Leaving directory `/osdev/zbz/core' I use an HP G71t notebook, with an Intel T4300 processor, and have 3GB of RAM. I would have liked to paste in the tables I generate, but...they are pretty large in source form. About 120KB. Lots of lines of scrolling for something that is not the problem: I can vouch that those tables are relocated properly and that they appear, properly resolved, in the final image. ------------------------------------- I debugged the problem, and have got LD to stop cutting out the page tables from the program headers. What I did was redo the page tables in C++, then look that the output asm from i586-elf-g++ -S (assmbly output), and the only difference was that GCC placed these lines above the tables: .file "__kpagingLevel1Hll.cpp" .globl __kpagingLevel1Tables .section .__ksetupDataS,"aw",@progbits .align 4096 .type __kpagingLevel1Tables, @object .size __kpagingLevel1Tables, 12288 It goes without saying that I had the .globl pseudo op in my hand-written ASM, so that wasn't the issue. It's probably the .type or .size directives. Anyway, I placed that into mine, and now LD behaves itself. But this is still abnormal behaviour, so I've sent in the bug report. There's no reason why LD should leave out a section in the program header when it's clearly referenced in the program. Hope I helped stamp something bad out. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils