summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/mips/Kconfig18
-rw-r--r--arch/mips/config.mk2
-rw-r--r--arch/mips/cpu/u-boot.lds20
-rw-r--r--tools/mips-relocs.c30
4 files changed, 40 insertions, 30 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 071dea04ec7..6d646ef9997 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -248,6 +248,24 @@ config MIPS_CACHE_INDEX_BASE
Normally this is CKSEG0. If the MIPS system needs to move this block
to some SRAM or ScratchPad RAM, adapt this option accordingly.
+config MIPS_RELOCATION_TABLE_SIZE
+ hex "Relocation table size"
+ range 0x100 0x10000
+ default "0x8000"
+ ---help---
+ A table of relocation data will be appended to the U-Boot binary
+ and parsed in relocate_code() to fix up all offsets in the relocated
+ U-Boot.
+
+ This option allows the amount of space reserved for the table to be
+ adjusted in a range from 256 up to 64k. The default is 32k and should
+ be ok in most cases. Reduce this value to shrink the size of U-Boot
+ binary.
+
+ The build will fail and a valid size suggested if this is too small.
+
+ If unsure, leave at the default value.
+
endmenu
menu "OS boot interface"
diff --git a/arch/mips/config.mk b/arch/mips/config.mk
index 8aa45fc45c2..22223a0f3e9 100644
--- a/arch/mips/config.mk
+++ b/arch/mips/config.mk
@@ -55,7 +55,7 @@ PLATFORM_ELFFLAGS += -B mips $(OBJCOPYFLAGS)
# MODFLAGS += -mlong-calls
#
ifndef CONFIG_SPL_BUILD
-OBJCOPYFLAGS += -j .got -j .rel -j .padding -j .dtb.init.rodata
+OBJCOPYFLAGS += -j .data.reloc -j .dtb.init.rodata
LDFLAGS_FINAL += --emit-relocs
endif
diff --git a/arch/mips/cpu/u-boot.lds b/arch/mips/cpu/u-boot.lds
index f2c9f94f74e..fd0f1b5d4f4 100644
--- a/arch/mips/cpu/u-boot.lds
+++ b/arch/mips/cpu/u-boot.lds
@@ -41,16 +41,22 @@ SECTIONS
__image_copy_end = .;
__init_end = .;
- /*
- * .rel must come last so that the mips-relocs tool can shrink
- * the section size & the PT_LOAD program header filesz.
- */
- .rel : {
+ .data.reloc : {
__rel_start = .;
- BYTE(0x0)
- . += (32 * 1024) - 1;
+ /*
+ * Space for relocation table
+ * This needs to be filled so that the
+ * mips-reloc tool can overwrite the content.
+ * An invalid value is left at the start of the
+ * section to abort relocation if the table
+ * has not been filled in.
+ */
+ LONG(0xFFFFFFFF);
+ FILL(0);
+ . += CONFIG_MIPS_RELOCATION_TABLE_SIZE - 4;
}
+ . = ALIGN(4);
_end = .;
.bss __rel_start (OVERLAY) : {
diff --git a/tools/mips-relocs.c b/tools/mips-relocs.c
index 442cc8f6d22..625258085b6 100644
--- a/tools/mips-relocs.c
+++ b/tools/mips-relocs.c
@@ -195,15 +195,13 @@ static int compare_relocs(const void *a, const void *b)
int main(int argc, char *argv[])
{
unsigned int i, j, i_rel_shdr, sh_type, sh_entsize, sh_entries;
- size_t rel_size, rel_actual_size, load_sz;
+ size_t rel_size, rel_actual_size;
const char *shstrtab, *sh_name, *rel_pfx;
int (*parse_fn)(const void *rel);
uint8_t *buf_start, *buf;
const Elf32_Ehdr *ehdr32;
const Elf64_Ehdr *ehdr64;
uintptr_t sh_offset;
- Elf32_Phdr *phdr32;
- Elf64_Phdr *phdr64;
Elf32_Shdr *shdr32;
Elf64_Shdr *shdr64;
struct stat st;
@@ -285,8 +283,6 @@ int main(int argc, char *argv[])
goto out_free_relocs;
}
- phdr32 = elf + ehdr_field(e_phoff);
- phdr64 = elf + ehdr_field(e_phoff);
shdr32 = elf + ehdr_field(e_shoff);
shdr64 = elf + ehdr_field(e_shoff);
shstrtab = elf + shdr_field(ehdr_field(e_shstrndx), sh_offset);
@@ -295,7 +291,7 @@ int main(int argc, char *argv[])
for (i = 0; i < ehdr_field(e_shnum); i++) {
sh_name = shstr(shdr_field(i, sh_name));
- if (!strcmp(sh_name, ".rel")) {
+ if (!strcmp(sh_name, ".data.reloc")) {
i_rel_shdr = i;
continue;
}
@@ -397,22 +393,12 @@ int main(int argc, char *argv[])
rel_size = shdr_field(i_rel_shdr, sh_size);
rel_actual_size = buf - buf_start;
if (rel_actual_size > rel_size) {
- fprintf(stderr, "Relocs overflowed .rel section\n");
- return -ENOMEM;
- }
-
- /* Update the .rel section's size */
- set_shdr_field(i_rel_shdr, sh_size, rel_actual_size);
-
- /* Shrink the PT_LOAD program header filesz (ie. shrink u-boot.bin) */
- for (i = 0; i < ehdr_field(e_phnum); i++) {
- if (phdr_field(i, p_type) != PT_LOAD)
- continue;
-
- load_sz = phdr_field(i, p_filesz);
- load_sz -= rel_size - rel_actual_size;
- set_phdr_field(i, p_filesz, load_sz);
- break;
+ fprintf(stderr, "Relocations overflow available space of 0x%lx (required 0x%lx)!\n",
+ rel_size, rel_actual_size);
+ fprintf(stderr, "Please adjust CONFIG_MIPS_RELOCATION_TABLE_SIZE to at least 0x%lx\n",
+ (rel_actual_size + 0x100) & ~0xFF);
+ err = -ENOMEM;
+ goto out_free_relocs;
}
/* Make sure data is written back to the file */