This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Problem with AMD64 ld with linker script


Hi list,

I'm developing a kernel for amd64 platforms. I'd prefer it to be in
ELF format with 4k-alignment between sections. Also, I have to specify
a load address and a link address for use in the output, as it's used
by my boot loader. The addresses are in the higher-half of the address
space, all code is compiled with -mcmodel=kernel with gcc 4.1.1. I'm
using binutils 2.17.

When I link the kernel without a linker script, the sections are
aligned according to their minimum alignment (which is 2^4 for most,
2^12 for bss since I had to put a page-aligned thing in it). I can't
specify the load and the virtual address however.

As soon as I use a linker script, the alignments for all sections
immediately jump to 2^20, with no possible way to get the alignment
down. As a result of that, the .text is at 0x100000, .data is at
0x200000 and .init (kernel-specific section) is at 0x300000. That
results in a binary over 3 megabytes in size, albeit very sparse,
where I wanted about a 64k binary.

I've tried a load of forms in the linker file that could have worked,
most did nothing, some of which enlarged it even more. I'm out of
options and I still can't figure out where the alignment is coming
from.

Here's my linker script, it's linking from a single object file.

--------- script-
UTPUT_FORMAT("elf64-x86-64")
ENTRY("_start")

PHDRS {
       header PT_PHDR FILEHDR PHDRS;
       init PT_LOAD AT(0x90000);
       text PT_LOAD AT(0x100000);
       data PT_LOAD AT(0x100000 + LENGTH(text));
}

SECTIONS {
 . = ALIGN(0x1000);
 .init 0xFFFFFFFFD0000000 : {
       KEEP(*(.init*))
       init_ctors_begin = .;
       KEEP(*(.ctors))
       init_ctors_end = .;
 } :init
 . = ALIGN(0x1000);
 .text 0xFFFFFFFFC0000000 : {
       KEEP (*(.text*))
       KEEP (*(.rodata))
 } :text
 . = ALIGN(0x1000);
 .data 0xFFFFFFFFC4000000 : {
       KEEP (*(.data))
       KEEP (*(COMMON))
       kernel_max_mem = .;
 } :data
 .bss (ADDR(.data) + SIZEOF(.data)) : {
       KEEP (*(.bss))
 } :data
       /DISCARD/ : {
               *(.eh_frame)
               *(.fini*)
               *(.dtors)
               *(.rel*)
       }
}
-------- end script

The phdrs statement is probably wrong on the data bit, but that
shouldn't make it 3mb.

Am I doing something very wrong, is this a bug or what is causing my inability?

Thanks in advance,
Peter Bindels


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]