ld inserts zeros without changing pointers
Posted: Tue Aug 16, 2011 3:16 pm
I'm linking my files with ld but it adds zeros into it where none should be.
The command is
The data section in file_a.o is really 0x824 bytes long and so on.
If I look at the start of the .data sector of file file_a.o it is:
But in the result file the data sections starts with a lot of 00 bytes:
There are more extra zeros after the .data section of file_a.o.
At the end of the .data section of the result file there should be the data of file_e.o and I think some garbage because of the length. 0x824+0x1C+0x140=0x980 and the whole data section should be 0xA00. But if I look at the end there is just the half of .data of file_e.o and then the 0xA00 bytes of the sections end with result that some data of file_e.o is missing.
There are some pointers in these memory dumps. If there were no zeros the pointers would be correct. The same is for the pointers in the code sections - without zeros everything would be fine.
In conclusion it seems to me that ld correctly collecting all data, calculated the new file and reset the pointers but by writing the file it adds the zeros truncating everything over the previously calculated size. As a result of this the created file is nothing more than trash.
I don't know the reason for this. Thus is why I am writing this post.
Why does ld do this and how can I tell it to create correct files?
Some more information:
I am working on Windows, using cygwin and using the integrated gcc (4.3.4 20090804, also tried 4.5.0) and ld (GNU Binutils 2.21.53.20110731). Thus it create a PE file. As a result of this I set up a multiboot header at nearly the start of the first section. QEMU is able to load the file and if I delete the extra zeros the OS also runs how it should be. But this is only possible because of the fact that I don't use file_e.o up to now. Without deleting the zeros QEMU just run into a triple fault while executing the fourth assembler line of the kernel because of the wrong GDT (just some garbage in memory).
An elf cross compiler is no option.
The command is
If I look into the map file it looks fine:ld -e entry -T misc/sections -Map ./test.txt [files] -o [output]
Code: Select all
[...]
.data 0x001018c0 0xa00
*(.data)
.data 0x001018c0 0x0 crtbegin.o
.data 0x001018c0 0x824 file_a.o
.data 0x001020e4 0x0 file_b.o
[...]
*fill* 0x001020e4 0x1c 00
.data 0x00102100 0x140 file_e.o
.data 0x00102240 0x0 file_f.o
[...]
.data 0x00102240 0x0 crtend.o
[...]
If I look at the start of the .data sector of file file_a.o it is:
Code: Select all
.data:00000848 18 00 54 08 00 00 00 08
.data:00000850 6C 08 00 00 00 00 00 00 00 00 00 00 FF FF 00 00
.data:00000860 00 9A CF 00 FF FF 00 00 00 92 CF 00 00 00 08 00
.data:00000870 00 EF 00 00 00 00 08 00 00 EF 00 00 00 00 08 00
.data:00000880 00 EF 00 00 00 00 08 00 [...]
Code: Select all
.data:001018C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[...]
.data:00101970 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
.data:00101980 18 00 CC 18 10 00 00 08 E4 18 10 00 00 00 00 00
.data:00101990 00 00 00 00 FF FF 00 00 00 9A CF 00 FF FF 00 00
.data:001019A0 00 92 CF 00 00 00 08 00 00 EF 00 00 00 00 08 00
.data:001019B0 00 EF 00 00 00 00 08 00 00 EF 00 00 00 00 08 00
At the end of the .data section of the result file there should be the data of file_e.o and I think some garbage because of the length. 0x824+0x1C+0x140=0x980 and the whole data section should be 0xA00. But if I look at the end there is just the half of .data of file_e.o and then the 0xA00 bytes of the sections end with result that some data of file_e.o is missing.
There are some pointers in these memory dumps. If there were no zeros the pointers would be correct. The same is for the pointers in the code sections - without zeros everything would be fine.
In conclusion it seems to me that ld correctly collecting all data, calculated the new file and reset the pointers but by writing the file it adds the zeros truncating everything over the previously calculated size. As a result of this the created file is nothing more than trash.
I don't know the reason for this. Thus is why I am writing this post.
Why does ld do this and how can I tell it to create correct files?
Some more information:
I am working on Windows, using cygwin and using the integrated gcc (4.3.4 20090804, also tried 4.5.0) and ld (GNU Binutils 2.21.53.20110731). Thus it create a PE file. As a result of this I set up a multiboot header at nearly the start of the first section. QEMU is able to load the file and if I delete the extra zeros the OS also runs how it should be. But this is only possible because of the fact that I don't use file_e.o up to now. Without deleting the zeros QEMU just run into a triple fault while executing the fourth assembler line of the kernel because of the wrong GDT (just some garbage in memory).
An elf cross compiler is no option.