mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-11 22:03:15 +00:00
d263cda5ae
The relocate_code function was handling cache maintenance incorrectly. It copied U-Boot to its new location, flushed the caches & then proceeded to apply relocations & jump to the new code without flushing the caches again. This is problematic as the instruction cache could potentially have already fetched instructions that hadn't had relocs applied. Rework this to perform the flush_cache call using the code in the original copy of U-Boot, after having applied relocations to the new copy of U-Boot. The new U-Boot can then be jumped to safely once that cache flush has been performed. As part of this, since the old U-Boot is used up until after that cache flush, complexity around loading values from the GOT using a jump & link instruction & loads from a table is removed. Instead we can simply load the needed values with PTR_LA fromt the original GOT. Signed-off-by: Paul Burton <paul.burton@imgtec.com>
130 lines
1.7 KiB
Text
130 lines
1.7 KiB
Text
/*
|
|
* (C) Copyright 2003
|
|
* Wolfgang Denk Engineering, <wd@denx.de>
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
|
|
#if defined(CONFIG_64BIT)
|
|
#define PTR_COUNT_SHIFT 3
|
|
#else
|
|
#define PTR_COUNT_SHIFT 2
|
|
#endif
|
|
|
|
OUTPUT_ARCH(mips)
|
|
ENTRY(_start)
|
|
SECTIONS
|
|
{
|
|
. = 0x00000000;
|
|
|
|
. = ALIGN(4);
|
|
.text : {
|
|
__text_start = .;
|
|
*(.text*)
|
|
__text_end = .;
|
|
}
|
|
|
|
. = ALIGN(4);
|
|
.rodata : {
|
|
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
|
|
}
|
|
|
|
. = ALIGN(4);
|
|
.data : {
|
|
*(.data*)
|
|
}
|
|
|
|
. = .;
|
|
_gp = ALIGN(16) + 0x7ff0;
|
|
|
|
.got : {
|
|
*(.got)
|
|
}
|
|
|
|
num_got_entries = SIZEOF(.got) >> PTR_COUNT_SHIFT;
|
|
|
|
. = ALIGN(4);
|
|
.sdata : {
|
|
*(.sdata*)
|
|
}
|
|
|
|
. = ALIGN(4);
|
|
.u_boot_list : {
|
|
KEEP(*(SORT(.u_boot_list*)));
|
|
}
|
|
|
|
. = ALIGN(4);
|
|
__image_copy_end = .;
|
|
__init_end = .;
|
|
|
|
.rel.dyn : {
|
|
__rel_dyn_start = .;
|
|
*(.rel.dyn)
|
|
__rel_dyn_end = .;
|
|
}
|
|
|
|
.padding : {
|
|
/*
|
|
* Workaround for a binutils feature (or bug?).
|
|
*
|
|
* The GNU ld from binutils puts the dynamic relocation
|
|
* entries into the .rel.dyn section. Sometimes it
|
|
* allocates more dynamic relocation entries than it needs
|
|
* and the unused slots are set to R_MIPS_NONE entries.
|
|
*
|
|
* However the size of the .rel.dyn section in the ELF
|
|
* section header does not cover the unused entries, so
|
|
* objcopy removes those during stripping.
|
|
*
|
|
* Create a small section here to avoid that.
|
|
*/
|
|
LONG(0xFFFFFFFF)
|
|
}
|
|
|
|
_end = .;
|
|
|
|
.bss __rel_dyn_start (OVERLAY) : {
|
|
__bss_start = .;
|
|
*(.sbss.*)
|
|
*(.bss.*)
|
|
*(COMMON)
|
|
. = ALIGN(4);
|
|
__bss_end = .;
|
|
}
|
|
|
|
.dynsym _end : {
|
|
*(.dynsym)
|
|
}
|
|
|
|
.dynbss : {
|
|
*(.dynbss)
|
|
}
|
|
|
|
.dynstr : {
|
|
*(.dynstr)
|
|
}
|
|
|
|
.dynamic : {
|
|
*(.dynamic)
|
|
}
|
|
|
|
.plt : {
|
|
*(.plt)
|
|
}
|
|
|
|
.interp : {
|
|
*(.interp)
|
|
}
|
|
|
|
.gnu : {
|
|
*(.gnu*)
|
|
}
|
|
|
|
.MIPS.stubs : {
|
|
*(.MIPS.stubs)
|
|
}
|
|
|
|
.hash : {
|
|
*(.hash)
|
|
}
|
|
}
|