diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 071dea04ec..6d646ef999 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 8aa45fc45c..22223a0f3e 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 f2c9f94f74..fd0f1b5d4f 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 442cc8f6d2..625258085b 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 */