This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Problem with AMD64 ld with linker script
- From: "Peter Bindels" <dascandy at gmail dot com>
- To: binutils at sourceware dot org
- Date: Thu, 5 Oct 2006 19:00:33 +0200
- Subject: 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