Commit 6569580d authored by Vivek Goyal's avatar Vivek Goyal Committed by Andi Kleen

[PATCH] i386: Distinguish absolute symbols

Ld knows about 2 kinds of symbols,  absolute and section
relative.  Section relative symbols symbols change value
when a section is moved and absolute symbols do not.

Currently in the linker script we have several labels
marking the beginning and ending of sections that
are outside of sections, making them absolute symbols.
Having a mixture of absolute and section relative
symbols refereing to the same data is currently harmless
but it is confusing.

This must be done carefully as newer revs of ld do not place
symbols that appear in sections without data and instead
ld makes those symbols global :(

My ultimate goal is to build a relocatable kernel.  The
safest and least intrusive technique is to generate
relocation entries so the kernel can be relocated at load
time.  The only penalty would be an increase in the size
of the kernel binary.  The problem is that if absolute and
relocatable symbols are not properly specified absolute symbols
will be relocated or section relative symbols won't be, which
is fatal.

The practical motivation is that when generating kernels that
will run from a reserved area for analyzing what caused
a kernel panic, it is simpler if you don't need to hard code
the physical memory location they will run at, especially
for the distributions.

[AK: and merged:]

o Also put a message so that in future people can be aware of it and
  avoid introducing absolute symbols.
Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
Signed-off-by: default avatarVivek Goyal <vgoyal@in.ibm.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
parent 67fd44fe
/* ld script to make i386 Linux kernel /* ld script to make i386 Linux kernel
* Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>; * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
*
* Don't define absolute symbols until and unless you know that symbol
* value is should remain constant even if kernel image is relocated
* at run time. Absolute symbols are not relocated. If symbol value should
* change if kernel is relocated, make the symbol section relative and
* put it inside the section definition.
*/ */
#define LOAD_OFFSET __PAGE_OFFSET #define LOAD_OFFSET __PAGE_OFFSET
...@@ -24,31 +30,32 @@ SECTIONS ...@@ -24,31 +30,32 @@ SECTIONS
. = __KERNEL_START; . = __KERNEL_START;
phys_startup_32 = startup_32 - LOAD_OFFSET; phys_startup_32 = startup_32 - LOAD_OFFSET;
/* read-only */ /* read-only */
_text = .; /* Text and read-only data */
.text : AT(ADDR(.text) - LOAD_OFFSET) { .text : AT(ADDR(.text) - LOAD_OFFSET) {
_text = .; /* Text and read-only data */
*(.text) *(.text)
SCHED_TEXT SCHED_TEXT
LOCK_TEXT LOCK_TEXT
KPROBES_TEXT KPROBES_TEXT
*(.fixup) *(.fixup)
*(.gnu.warning) *(.gnu.warning)
} :text = 0x9090 _etext = .; /* End of text section */
} :text = 0x9090
_etext = .; /* End of text section */
. = ALIGN(16); /* Exception table */ . = ALIGN(16); /* Exception table */
__start___ex_table = .; __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } __start___ex_table = .;
__stop___ex_table = .; *(__ex_table)
__stop___ex_table = .;
}
RODATA RODATA
. = ALIGN(4); . = ALIGN(4);
__tracedata_start = .;
.tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
__tracedata_start = .;
*(.tracedata) *(.tracedata)
__tracedata_end = .;
} }
__tracedata_end = .;
/* writeable */ /* writeable */
. = ALIGN(4096); . = ALIGN(4096);
...@@ -58,10 +65,12 @@ SECTIONS ...@@ -58,10 +65,12 @@ SECTIONS
} :data } :data
. = ALIGN(4096); . = ALIGN(4096);
__nosave_begin = .; .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) } __nosave_begin = .;
. = ALIGN(4096); *(.data.nosave)
__nosave_end = .; . = ALIGN(4096);
__nosave_end = .;
}
. = ALIGN(4096); . = ALIGN(4096);
.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
...@@ -75,8 +84,10 @@ SECTIONS ...@@ -75,8 +84,10 @@ SECTIONS
/* rarely changed data like cpu maps */ /* rarely changed data like cpu maps */
. = ALIGN(32); . = ALIGN(32);
.data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) } .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
_edata = .; /* End of data section */ *(.data.read_mostly)
_edata = .; /* End of data section */
}
#ifdef CONFIG_STACK_UNWIND #ifdef CONFIG_STACK_UNWIND
. = ALIGN(4); . = ALIGN(4);
...@@ -94,54 +105,56 @@ SECTIONS ...@@ -94,54 +105,56 @@ SECTIONS
/* might get freed after init */ /* might get freed after init */
. = ALIGN(4096); . = ALIGN(4096);
__smp_alt_begin = .;
__smp_alt_instructions = .;
.smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) { .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) {
__smp_alt_begin = .;
__smp_alt_instructions = .;
*(.smp_altinstructions) *(.smp_altinstructions)
__smp_alt_instructions_end = .;
} }
__smp_alt_instructions_end = .;
. = ALIGN(4); . = ALIGN(4);
__smp_locks = .;
.smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
__smp_locks = .;
*(.smp_locks) *(.smp_locks)
__smp_locks_end = .;
} }
__smp_locks_end = .;
.smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) { .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) {
*(.smp_altinstr_replacement) *(.smp_altinstr_replacement)
__smp_alt_end = .;
} }
. = ALIGN(4096); . = ALIGN(4096);
__smp_alt_end = .;
/* will be freed after init */ /* will be freed after init */
. = ALIGN(4096); /* Init code and data */ . = ALIGN(4096); /* Init code and data */
__init_begin = .;
.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
__init_begin = .;
_sinittext = .; _sinittext = .;
*(.init.text) *(.init.text)
_einittext = .; _einittext = .;
} }
.init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
. = ALIGN(16); . = ALIGN(16);
__setup_start = .; .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
.init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) } __setup_start = .;
__setup_end = .; *(.init.setup)
__initcall_start = .; __setup_end = .;
}
.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
__initcall_start = .;
INITCALLS INITCALLS
__initcall_end = .;
} }
__initcall_end = .;
__con_initcall_start = .;
.con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
__con_initcall_start = .;
*(.con_initcall.init) *(.con_initcall.init)
__con_initcall_end = .;
} }
__con_initcall_end = .;
SECURITY_INIT SECURITY_INIT
. = ALIGN(4); . = ALIGN(4);
__alt_instructions = .;
.altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
__alt_instructions = .;
*(.altinstructions) *(.altinstructions)
__alt_instructions_end = .;
} }
__alt_instructions_end = .;
.altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
*(.altinstr_replacement) *(.altinstr_replacement)
} }
...@@ -150,32 +163,32 @@ SECTIONS ...@@ -150,32 +163,32 @@ SECTIONS
.exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
.exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
. = ALIGN(4096); . = ALIGN(4096);
__initramfs_start = .; .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
.init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } __initramfs_start = .;
__initramfs_end = .; *(.init.ramfs)
__initramfs_end = .;
}
. = ALIGN(L1_CACHE_BYTES); . = ALIGN(L1_CACHE_BYTES);
__per_cpu_start = .; .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
.data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } __per_cpu_start = .;
__per_cpu_end = .; *(.data.percpu)
__per_cpu_end = .;
}
. = ALIGN(4096); . = ALIGN(4096);
__init_end = .;
/* freed after init ends here */ /* freed after init ends here */
__bss_start = .; /* BSS */
.bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) {
*(.bss.page_aligned)
}
.bss : AT(ADDR(.bss) - LOAD_OFFSET) { .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
__init_end = .;
__bss_start = .; /* BSS */
*(.bss.page_aligned)
*(.bss) *(.bss)
. = ALIGN(4);
__bss_stop = .;
_end = . ;
/* This is where the kernel creates the early boot page tables */
. = ALIGN(4096);
pg0 = . ;
} }
. = ALIGN(4);
__bss_stop = .;
_end = . ;
/* This is where the kernel creates the early boot page tables */
. = ALIGN(4096);
pg0 = .;
/* Sections to be discarded */ /* Sections to be discarded */
/DISCARD/ : { /DISCARD/ : {
......
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
#define RODATA \ #define RODATA \
. = ALIGN(4096); \ . = ALIGN(4096); \
__start_rodata = .; \
.rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \ .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start_rodata) = .; \
*(.rodata) *(.rodata.*) \ *(.rodata) *(.rodata.*) \
*(__vermagic) /* Kernel version magic */ \ *(__vermagic) /* Kernel version magic */ \
} \ } \
...@@ -119,17 +119,17 @@ ...@@ -119,17 +119,17 @@
*(__ksymtab_strings) \ *(__ksymtab_strings) \
} \ } \
\ \
/* Unwind data binary search table */ \
EH_FRAME_HDR \
\
/* Built-in module parameters. */ \ /* Built-in module parameters. */ \
__param : AT(ADDR(__param) - LOAD_OFFSET) { \ __param : AT(ADDR(__param) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___param) = .; \ VMLINUX_SYMBOL(__start___param) = .; \
*(__param) \ *(__param) \
VMLINUX_SYMBOL(__stop___param) = .; \ VMLINUX_SYMBOL(__stop___param) = .; \
VMLINUX_SYMBOL(__end_rodata) = .; \
} \ } \
\ \
/* Unwind data binary search table */ \
EH_FRAME_HDR \
\
__end_rodata = .; \
. = ALIGN(4096); . = ALIGN(4096);
#define SECURITY_INIT \ #define SECURITY_INIT \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment