Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

My bootloader can't be compiled with gcc 4.6 and 4.7 ... only 4.5

I created my bootloader before 2 years under debian squeeze/stable with gcc 4.5. Now in debian wheezy/sid can't be compiled with 4.6 and 4.7 because creates bigger sections from these i expecting to produce the final binary by hand. This is not problem for me now since in debian wheezy/sid the gcc 4.5 is still there but i 'd like to make it possible to be compiled with gcc 4.6 and 4.7.

I produce the final binary like this:

the source files are compiled with:

gcc-4.5 -Wall -O3 -c -m32 -I. -o assemblybin-objects/vga_pm.S.o vga_pm.S

linked with:

ld -nostdlib -T binary.ld assemblybin-objects/vga_pm.S.o ... and other objects here ... -o bootloader.bin

the contents of the binary.ld is:

OUTPUT_FORMAT("binary","binary","binary")
OUTPUT_ARCH(i386)

SECTIONS
{
. = 0;
.bootloader : {
    . = 0x600;
    *(.bootstrap);
    . = 0x7fa;
    BYTE(0x11);
    BYTE(0x33);
    BYTE(0x55);
    BYTE(0x77);
    BYTE(0x55);
    BYTE(0xaa);
    _bootstrap_end = .;
    . = 0x800;
    *(.sysinit);
    _sysinit_end = .;
    . = 0x1000;
    *(.pages);
    _pages_end = .;
    . = 0x5000;
    *(.sysconf);
    *(.presystem);
    *(.system);
    *(.library);
    *(.text);
    *(.data);
    *(.bss);
    *(.rodata);
    *(.rodata.*);
    . = 0xeffc;
    BYTE(0x11);
    BYTE(0x33);
    BYTE(0x55);
    BYTE(0x77);
    _system_end = .;
}

. = ASSERT(_bootstrap_end <= 0x800,"Bootstrap section big!");
. = ASSERT(_sysinit_end <= 0x1000,"Sysinit section big!");
. = ASSERT(_pages_end <= 0x5000,"Pages section big!");
. = ASSERT(_system_end <= 0xf000,"System initialization section big!");
}

at last creating the final binary with dd.

I saw that when compiled with gcc 4.6 and 4.7 the linker adds some bytes (250-300) at the begin of the bootloader.bin.

I'm using the ld from binutils 2.22 and cook with my own recipes for the build process.

My actual questions are:

What are the differences between these versions of the gcc compiler and they produce bigger sections or instructing the linker through the elf object files to add these bytes at the begin of the bootloader.bin file?

Is there any command line argument for gcc 4.6 and/or 4.7 which will turn off a feature that may produce bigger sections than the gcc 4.5 or to remove the instructions those saying the linker to add these bytes at the begin of the bootloader.bin file?

edit 17-08-2012: I'm lil busy these days but soon i 'll update with the results of tests i did.

Answer to @strnk and @Dan Aloni: when i saw this problem the first i did is to exclude useless sections but the results are the same ... i think because the bootloader.bin is a simple binary with the linked code of the needed sections at the right position as the linker instructed to do, without section names, relocation and debug informations and symbols ... bootloader.bin file is not an elf object file.

Please consider the changes of the actual questions. Thanks for everything ... i 'll be back soon

edit 31-08-2012: Okay guys thanks for your help. The answer given by @Dan Aloni and accomplished with ldscript as @strnk shows

/DISCARD/ : {
    *(.eh_frame)
    *(.eh_frame_hdr)
}

after the asserts.

like image 784
Memos Electron Avatar asked Aug 05 '12 20:08

Memos Electron


1 Answers

By compiling a trivial C file with the flags you provided, between gcc-4.5 and gcc-4.6, and using objdump -h to examine the output, it seems that the .eh_frame section is introduced in gcc-4.6.

The ld script you provided does not take care of that section, and it probably should. You can use strip -R .eh_frame -R .eh_frame_hdr to remove that section and others from the object files prior to linking.

Anyway, since the linker is the same for both gcc versions, objdump -h on the object files will hint at the difference that causes this problem.

like image 200
Dan Aloni Avatar answered Oct 13 '22 10:10

Dan Aloni