From 8d12c84b5b23a5fa9082d6246f788d25b50b8653 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Tue, 31 Jan 2023 11:33:33 +0100 Subject: binutils: update to 2.40 --- toolchain/elf2flt/Makefile | 3 + .../0008-remove_BFD_VMA_FMT.patch | 125 ++ .../patches/v2021.08/0008-remove_BFD_VMA_FMT.patch | 2214 ++++++++++++++++++++ 3 files changed, 2342 insertions(+) create mode 100644 toolchain/elf2flt/patches/453398f917d167f8c308c8f997270c48ae8f8b12/0008-remove_BFD_VMA_FMT.patch create mode 100644 toolchain/elf2flt/patches/v2021.08/0008-remove_BFD_VMA_FMT.patch (limited to 'toolchain/elf2flt') diff --git a/toolchain/elf2flt/Makefile b/toolchain/elf2flt/Makefile index d1db7c804..4faa2e687 100644 --- a/toolchain/elf2flt/Makefile +++ b/toolchain/elf2flt/Makefile @@ -9,6 +9,9 @@ include $(ADK_TOPDIR)/mk/buildhlp.mk ifeq ($(ADK_TOOLCHAIN_BINUTILS_GIT),y) BINUTILS_VERSION:= git endif +ifeq ($(ADK_TOOLCHAIN_BINUTILS_2_40),y) +BINUTILS_VERSION:= 2.40 +endif ifeq ($(ADK_TOOLCHAIN_BINUTILS_2_39),y) BINUTILS_VERSION:= 2.39 endif diff --git a/toolchain/elf2flt/patches/453398f917d167f8c308c8f997270c48ae8f8b12/0008-remove_BFD_VMA_FMT.patch b/toolchain/elf2flt/patches/453398f917d167f8c308c8f997270c48ae8f8b12/0008-remove_BFD_VMA_FMT.patch new file mode 100644 index 000000000..d20b993da --- /dev/null +++ b/toolchain/elf2flt/patches/453398f917d167f8c308c8f997270c48ae8f8b12/0008-remove_BFD_VMA_FMT.patch @@ -0,0 +1,125 @@ +diff -Nur elf2flt-453398f917d167f8c308c8f997270c48ae8f8b12.orig/elf2flt.c elf2flt-453398f917d167f8c308c8f997270c48ae8f8b12/elf2flt.c +--- elf2flt-453398f917d167f8c308c8f997270c48ae8f8b12.orig/elf2flt.c 2023-01-30 08:48:56.632981732 +0100 ++++ elf2flt-453398f917d167f8c308c8f997270c48ae8f8b12/elf2flt.c 2023-01-30 08:53:34.510426754 +0100 +@@ -222,7 +222,7 @@ + long i; + printf("SYMBOL TABLE:\n"); + for (i=0; iname, symbol_table[i]->value); + } + printf("\n"); +@@ -458,7 +458,7 @@ + if (r == NULL) + continue; + if (verbose) +- printf(" RELOCS: %s [%p]: flags=0x%x vma=0x%"BFD_VMA_FMT"x\n", ++ printf(" RELOCS: %s [%p]: flags=0x%x vma=0x%x\n", + r->name, r, r->flags, elf2flt_bfd_section_vma(abs_bfd, r)); + if ((r->flags & SEC_RELOC) == 0) + continue; +@@ -903,8 +903,8 @@ + if (verbose) + fprintf(stderr, + "%s vma=0x%x, " +- "value=0x%"BFD_VMA_FMT"x, " +- "address=0x%"BFD_VMA_FMT"x " ++ "value=0x%x, " ++ "address=0x%x " + "sym_addr=0x%x rs=0x%x, opcode=0x%x\n", + "ABS32", + sym_vma, (*(q->sym_ptr_ptr))->value, +@@ -922,8 +922,8 @@ + if (verbose) + fprintf(stderr, + "%s vma=0x%x, " +- "value=0x%"BFD_VMA_FMT"x, " +- "address=0x%"BFD_VMA_FMT"x " ++ "value=0x%x, " ++ "address=0x%x " + "sym_addr=0x%x rs=0x%x, opcode=0x%x\n", + "PLT32", + sym_vma, (*(q->sym_ptr_ptr))->value, +@@ -945,7 +945,7 @@ + case R_V850_ZDA_16_16_OFFSET: + case R_V850_ZDA_16_16_SPLIT_OFFSET: + /* Can't support zero-relocations. */ +- printf ("ERROR: %s+0x%"BFD_VMA_FMT"x: zero relocations not supported\n", ++ printf ("ERROR: %s+0x%x: zero relocations not supported\n", + sym_name, q->addend); + continue; + #endif /* TARGET_v850 */ +@@ -1038,15 +1038,15 @@ + sprintf(&addstr[0], "+0x%ld", sym_addr - (*(q->sym_ptr_ptr))->value - + elf2flt_bfd_section_vma(abs_bfd, sym_section)); + if (verbose) +- printf(" RELOC[%d]: offset=0x%"BFD_VMA_FMT"x symbol=%s%s " ++ printf(" RELOC[%d]: offset=0x%x symbol=%s%s " + "section=%s size=%d " +- "fixup=0x%x (reloc=0x%"BFD_VMA_FMT"x)\n", ++ "fixup=0x%x (reloc=0x%x)\n", + flat_reloc_count, + q->address, sym_name, addstr, + section_name, sym_reloc_size, + sym_addr, section_vma + q->address); + if (verbose) +- printf("reloc[%d] = 0x%"BFD_VMA_FMT"x\n", ++ printf("reloc[%d] = 0x%x\n", + flat_reloc_count, section_vma + q->address); + + continue; +@@ -1163,9 +1163,9 @@ + temp |= (exist_val & 0x3f); + *(unsigned long *)r_mem = htoniosl(temp); + if (verbose) +- printf("omit: offset=0x%"BFD_VMA_FMT"x symbol=%s%s " ++ printf("omit: offset=0x%x symbol=%s%s " + "section=%s size=%d " +- "fixup=0x%x (reloc=0x%"BFD_VMA_FMT"x) GPREL\n", ++ "fixup=0x%x (reloc=0x%x) GPREL\n", + q->address, sym_name, addstr, + section_name, sym_reloc_size, + sym_addr, section_vma + q->address); +@@ -1183,9 +1183,9 @@ + exist_val |= ((sym_addr & 0xFFFF) << 6); + *(unsigned long *)r_mem = htoniosl(exist_val); + if (verbose) +- printf("omit: offset=0x%"BFD_VMA_FMT"x symbol=%s%s " ++ printf("omit: offset=0x%x symbol=%s%s " + "section=%s size=%d " +- "fixup=0x%x (reloc=0x%"BFD_VMA_FMT"x) PCREL\n", ++ "fixup=0x%x (reloc=0x%x) PCREL\n", + q->address, sym_name, addstr, + section_name, sym_reloc_size, + sym_addr, section_vma + q->address); +@@ -1200,7 +1200,7 @@ + && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr) + && (p[-1]->addend == p[0]->addend)) { + if (verbose) +- printf("omit: offset=0x%"BFD_VMA_FMT"x symbol=%s%s " ++ printf("omit: offset=0x%x symbol=%s%s " + "section=%s size=%d LO16\n", + q->address, sym_name, addstr, + section_name, sym_reloc_size); +@@ -1610,9 +1610,9 @@ + } + + if (verbose) +- printf(" RELOC[%d]: offset=0x%"BFD_VMA_FMT"x symbol=%s%s " ++ printf(" RELOC[%d]: offset=0x%x symbol=%s%s " + "section=%s size=%d " +- "fixup=0x%x (reloc=0x%"BFD_VMA_FMT"x)\n", ++ "fixup=0x%x (reloc=0x%x)\n", + flat_reloc_count, + q->address, sym_name, addstr, + section_name, sym_reloc_size, +@@ -1630,7 +1630,7 @@ + (section_vma + q->address); + + if (verbose) +- printf("reloc[%d] = 0x%"BFD_VMA_FMT"x\n", ++ printf("reloc[%d] = 0x%x\n", + flat_reloc_count, section_vma + q->address); + #else + switch ((*p)->howto->type) { diff --git a/toolchain/elf2flt/patches/v2021.08/0008-remove_BFD_VMA_FMT.patch b/toolchain/elf2flt/patches/v2021.08/0008-remove_BFD_VMA_FMT.patch new file mode 100644 index 000000000..abb481186 --- /dev/null +++ b/toolchain/elf2flt/patches/v2021.08/0008-remove_BFD_VMA_FMT.patch @@ -0,0 +1,2214 @@ +diff -Nur elf2flt-v2021.08.orig/elf2flt.c elf2flt-v2021.08/elf2flt.c +--- elf2flt-v2021.08.orig/elf2flt.c 2023-01-29 16:47:24.791851890 +0100 ++++ elf2flt-v2021.08/elf2flt.c 2023-01-29 16:49:46.628476326 +0100 +@@ -222,7 +222,7 @@ + long i; + printf("SYMBOL TABLE:\n"); + for (i=0; iname, symbol_table[i]->value); + } + printf("\n"); +@@ -471,7 +471,7 @@ + if (r == NULL) + continue; + if (verbose) +- printf(" RELOCS: %s [%p]: flags=0x%x vma=0x%"BFD_VMA_FMT"x\n", ++ printf(" RELOCS: %s [%p]: flags=0x%x vma=0x%x\n", + r->name, r, r->flags, elf2flt_bfd_section_vma(r)); + if ((r->flags & SEC_RELOC) == 0) + continue; +@@ -966,8 +966,8 @@ + if (verbose) + fprintf(stderr, + "%s vma=0x%x, " +- "value=0x%"BFD_VMA_FMT"x, " +- "address=0x%"BFD_VMA_FMT"x " ++ "value=0x%x, " ++ "address=0x%x " + "sym_addr=0x%x rs=0x%x, opcode=0x%x\n", + "ABS32", + sym_vma, (*(q->sym_ptr_ptr))->value, +@@ -985,8 +985,8 @@ + if (verbose) + fprintf(stderr, + "%s vma=0x%x, " +- "value=0x%"BFD_VMA_FMT"x, " +- "address=0x%"BFD_VMA_FMT"x " ++ "value=0x%x, " ++ "address=0x%x " + "sym_addr=0x%x rs=0x%x, opcode=0x%x\n", + "PLT32", + sym_vma, (*(q->sym_ptr_ptr))->value, +@@ -1008,7 +1008,7 @@ + case R_V850_ZDA_16_16_OFFSET: + case R_V850_ZDA_16_16_SPLIT_OFFSET: + /* Can't support zero-relocations. */ +- printf ("ERROR: %s+0x%"BFD_VMA_FMT"x: zero relocations not supported\n", ++ printf ("ERROR: %s+0x%x: zero relocations not supported\n", + sym_name, q->addend); + continue; + #endif /* TARGET_v850 */ +@@ -1208,9 +1208,9 @@ + temp |= (exist_val & 0x3f); + *(unsigned long *)r_mem = htoniosl(temp); + if (verbose) +- printf("omit: offset=0x%"BFD_VMA_FMT"x symbol=%s%s " ++ printf("omit: offset=0x%x symbol=%s%s " + "section=%s size=%d " +- "fixup=0x%x (reloc=0x%"BFD_VMA_FMT"x) GPREL\n", ++ "fixup=0x%x (reloc=0x%x) GPREL\n", + q->address, sym_name, addstr, + section_name, sym_reloc_size, + sym_addr, section_vma + q->address); +@@ -1228,9 +1228,9 @@ + exist_val |= ((sym_addr & 0xFFFF) << 6); + *(unsigned long *)r_mem = htoniosl(exist_val); + if (verbose) +- printf("omit: offset=0x%"BFD_VMA_FMT"x symbol=%s%s " ++ printf("omit: offset=0x%x symbol=%s%s " + "section=%s size=%d " +- "fixup=0x%x (reloc=0x%"BFD_VMA_FMT"x) PCREL\n", ++ "fixup=0x%x (reloc=0x%x) PCREL\n", + q->address, sym_name, addstr, + section_name, sym_reloc_size, + sym_addr, section_vma + q->address); +@@ -1245,7 +1245,7 @@ + && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr) + && (p[-1]->addend == p[0]->addend)) { + if (verbose) +- printf("omit: offset=0x%"BFD_VMA_FMT"x symbol=%s%s " ++ printf("omit: offset=0x%x symbol=%s%s " + "section=%s size=%d LO16\n", + q->address, sym_name, addstr, + section_name, sym_reloc_size); +@@ -1660,9 +1660,9 @@ + */ + if (relocation_needed) { + if (verbose) +- printf(" RELOC[%d]: offset=0x%"BFD_VMA_FMT"x symbol=%s%s " ++ printf(" RELOC[%d]: offset=0x%x symbol=%s%s " + "section=%s size=%d " +- "fixup=0x%x (reloc=0x%"BFD_VMA_FMT"x)\n", ++ "fixup=0x%x (reloc=0x%x)\n", + flat_reloc_count, + q->address, sym_name, addstr, + section_name, sym_reloc_size, +diff -Nur elf2flt-v2021.08.orig/elf2flt.c.orig elf2flt-v2021.08/elf2flt.c.orig +--- elf2flt-v2021.08.orig/elf2flt.c.orig 2023-01-29 16:47:18.264007463 +0100 ++++ elf2flt-v2021.08/elf2flt.c.orig 1970-01-01 01:00:00.000000000 +0100 +@@ -1,2113 +0,0 @@ +-/* +- * elf2flt.c: Convert ELF (or any BFD format) to FLAT binary format +- * +- * (c) 1999-2002, Greg Ungerer +- * Created elf2flt from coff2flt (see copyrights below). Added all the +- * ELF format file handling. Extended relocation support for all of +- * text and data. +- * +- * (c) 2008-2009, Xtensa support, Oskar Schirmer +- * (c) 2006 Support the -a (use_resolved) option for TARGET_arm. +- * Shaun Jackman +- * (c) 2004, Nios II support, Wentao Xu +- * (c) 2003, H8 support, ktrace +- * (c) 2003-2004, MicroBlaze support, John Williams +- * (c) 2001-2003, arm/arm-pic/arm-big-endian support +- * (c) 2001, v850 changes, Mile Bader +- * (c) 2003, SuperH support, Paul Mundt +- * (c) 2001, zflat support +- * (c) 2001, Changes for GOT entries Paul Dale and +- * David McCullough +- * +- * Now supports PIC with GOT tables. This works by taking a '.elf' file +- * and a fully linked elf executable (at address 0) and produces a flat +- * file that can be loaded with some fixups. It still supports the old +- * style fully relocatable elf format files. +- * +- * Originally obj-res.c +- * +- * (c) 1998, Kenneth Albanowski +- * (c) 1998, D. Jeff Dionne +- * (c) 1998, The Silver Hammer Group Ltd. +- * (c) 1996, 1997 Dionne & Associates +- * +- * This is Free Software, under the GNU Public Licence v2 or greater. +- * +- * Relocation added March 1997, Kresten Krab Thorup +- * krab@california.daimi.aau.dk +- */ +- +-#include /* All the standard PRI define times for printf */ +-#include /* Userland pieces of the ANSI C standard I/O package */ +-#include /* Userland prototypes of the ANSI C std lib functions */ +-#include /* Allows va_list to exist in the these namespaces */ +-#include /* Userland prototypes of the string handling funcs */ +-#include +-#include /* Userland prototypes of the Unix std system calls */ +-#include /* Flag value for file handling functions */ +-#include +-#include +- +-/* from $(INSTALLDIR)/include */ +-#include /* Main header file for the BFD library */ +-#include +- +-#include "stubs.h" +-const char *elf2flt_progname; +- +-/* Include the right header file for the R_xxx defines. */ +-#if defined(TARGET_arm) +-#include +-#elif defined(TARGET_bfin) +-#include +-#elif defined(TARGET_h8300) +-#include +-#elif defined(TARGET_m68k) +-#include +-#elif defined(TARGET_microblaze) +-#include +-#elif defined(TARGET_nios) || defined(TARGET_nios2) +-/* Altera NIOS specific definitions. */ +-#define FLAT_NIOS2_R_32 0 /* Normal 32-bit reloc */ +-#define FLAT_NIOS2_R_HI_LO 1 +-#define FLAT_NIOS2_R_HIADJ_LO 2 +-#define FLAT_NIOS2_R_CALL26 4 +-#include +-#elif defined(TARGET_sh) +-#include +-#elif defined(TARGET_sparc) +-#include +-#elif defined(TARGET_v850) +-#include +-#elif defined(TARGET_xtensa) +-#include +-#elif defined(TARGET_riscv64) +-#include +-#endif +- +-#if defined(__MINGW32__) +-#include +-#endif +- +-/* from uClinux-x.x.x/include/linux */ +-#include "flat.h" /* Binary flat header description */ +-#include "compress.h" +- +-#ifdef TARGET_e1 +-#include +-#endif +- +-#ifdef TARGET_v850e +-#define TARGET_v850 +-#endif +- +-#if defined(TARGET_m68k) +-#define ARCH "m68k/coldfire" +-#elif defined(TARGET_arm) +-#define ARCH "arm" +-#elif defined(TARGET_sparc) +-#define ARCH "sparc" +-#elif defined(TARGET_v850) +-#define ARCH "v850" +-#elif defined(TARGET_sh) +-#define ARCH "sh" +-#elif defined(TARGET_h8300) +-#define ARCH "h8300" +-#elif defined(TARGET_microblaze) +-#define ARCH "microblaze" +-#elif defined(TARGET_e1) +-#define ARCH "e1-coff" +-#elif defined(TARGET_bfin) +-#define ARCH "bfin" +-#elif defined(TARGET_nios) +-#define ARCH "nios" +-#elif defined(TARGET_nios2) +-#define ARCH "nios2" +-#elif defined(TARGET_xtensa) +-#define ARCH "xtensa" +-#elif defined(TARGET_riscv64) +-#define ARCH "riscv64" +-#else +-#error "Don't know how to support your CPU architecture??" +-#endif +- +-#if defined(TARGET_m68k) || defined(TARGET_h8300) || defined(TARGET_bfin) +-/* +- * Define a maximum number of bytes allowed in the offset table. +- * We'll fail if the table is larger than this. +- * +- * This limit may be different for platforms other than m68k, but +- * 8000 entries is a lot, trust me :-) (davidm) +- */ +-#define GOT_LIMIT 32767 +-/* +- * we have to mask out the shared library id here and there, this gives +- * us the real address bits when needed +- */ +-#define real_address_bits(x) (pic_with_got ? ((x) & 0xffffff) : (x)) +-#else +-#define real_address_bits(x) (x) +-#endif +- +-#ifndef O_BINARY +-#define O_BINARY 0 +-#endif +- +-/* +- * The bfd parameter isn't actually used by any of the bfd_section funcs and +- * have been removed since binutils 2.34. +- */ +-#ifdef HAVE_BFD_SECTION_API_TAKES_BFD +-#define elf2flt_bfd_section_size(s) bfd_section_size(NULL, s) +-#define elf2flt_bfd_section_vma(s) bfd_section_vma(NULL, s) +-#else +-#define elf2flt_bfd_section_size(s) bfd_section_size(s) +-#define elf2flt_bfd_section_vma(s) bfd_section_vma(s) +-#endif +- +-/* Extra output when running. */ +-static int verbose = 0; +-/* Do ELF/GOT processing with PIC code. */ +-static int pic_with_got = 0; +-/* Instruct loader to allocate everything into RAM. */ +-static int load_to_ram = 0; +-/* Instruct kernel loader to output debug/trace info when loading. */ +-static int ktrace = 0; +-/* 1 = compress everything, 2 = compress data only. */ +-static int docompress = 0; +-/* If true, get the value of symbol references from the program contents, +- not from the relocation table. In this case, the input ELF file must +- be already fully resolved (using the `-q' flag with recent versions of +- GNU ld will give you a fully resolved output file with relocation +- entries). */ +-static int use_resolved = 0; +- +-/* Set if the text section contains any relocations. If it does, we must +- set the load_to_ram flag. */ +-static int text_has_relocs = 0; +- +-static asymbol ** +-get_symbols (bfd *abfd, long *num) +-{ +- int32_t storage_needed; +- asymbol **symbol_table; +- long number_of_symbols; +- +- storage_needed = bfd_get_symtab_upper_bound (abfd); +- +- if (storage_needed < 0) +- abort (); +- +- if (storage_needed == 0) +- return NULL; +- +- symbol_table = xmalloc (storage_needed); +- +- number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); +- +- if (number_of_symbols < 0) +- abort (); +- +- *num = number_of_symbols; +- return symbol_table; +-} +- +- +- +-static int +-dump_symbols(asymbol **symbol_table, long number_of_symbols) +-{ +- long i; +- printf("SYMBOL TABLE:\n"); +- for (i=0; iname, symbol_table[i]->value); +- } +- printf("\n"); +- return(0); +-} +- +- +- +-#if !defined TARGET_e1 && !defined TARGET_bfin +-static long +-get_symbol_offset(char *name, asection *sec, asymbol **symbol_table, long number_of_symbols) +-{ +- long i; +- for (i=0; isection == sec) { +- if (!strcmp(symbol_table[i]->name, name)) { +- return symbol_table[i]->value; +- } +- } +- } +- return -1; +-} +-#endif +- +- +- +-#ifdef TARGET_nios2 +-static long +-get_gp_value(asymbol **symbol_table, long number_of_symbols) +-{ +- long i; +- for (i=0; iname, "_gp")) +- return symbol_table[i]->value; +- } +- return -1; +-} +-#endif +- +- +- +-static int32_t +-add_com_to_bss(asymbol **symbol_table, int32_t number_of_symbols, int32_t bss_len) +-{ +- int32_t i, comsize; +- int32_t offset; +- +- comsize = 0; +- for (i=0; isection->name) == 0) { +- offset = bss_len + comsize; +- comsize += symbol_table[i]->value; +- symbol_table[i]->value = offset; +- } +- } +- return comsize; +-} +- +-#ifdef TARGET_bfin +-/* FUNCTION : weak_und_symbol +- ABSTRACT : return true if symbol is weak and undefined. +-*/ +-static int +-weak_und_symbol(const char *reloc_section_name, +- struct bfd_symbol *symbol) +-{ +- if (!(strstr (reloc_section_name, "text") +- || strstr (reloc_section_name, "data") +- || strstr (reloc_section_name, "bss"))) { +- if (symbol->flags & BSF_WEAK) { +-#ifdef DEBUG_BFIN +- fprintf(stderr, "found weak undefined symbol %s\n", symbol->name); +-#endif +- return TRUE; +- } +- } +- return FALSE; +-} +- +-static int +-bfin_set_reloc (uint32_t *reloc, +- const char *reloc_section_name, +- const char *sym_name, +- struct bfd_symbol *symbol, +- int sp, int32_t offset) +-{ +- unsigned int type = 0; +- uint32_t val; +- +- if (strstr (reloc_section_name, "stack")) { +- if (verbose) +- printf("Stack-relative reloc, offset %08"PRIx32"\n", offset); +- /* This must be a stack_start reloc for stack checking. */ +- type = 1; +- } +- val = (offset & ((1 << 26) - 1)); +- val |= (sp & ((1 << 3) - 1)) << 26; +- val |= type << 29; +- *reloc = val; +- return 0; +-} +- +-static bfd *compare_relocs_bfd; +- +-static int +-compare_relocs (const void *pa, const void *pb) +-{ +- const arelent *const *a = pa, *const *b = pb; +- const arelent *ra = *a, *rb = *b; +- unsigned long va, vb; +- uint32_t a_vma, b_vma; +- +- if (!ra->sym_ptr_ptr || !*ra->sym_ptr_ptr) +- return -1; +- else if (!rb->sym_ptr_ptr || !*rb->sym_ptr_ptr) +- return 1; +- +- a_vma = elf2flt_bfd_section_vma((*(ra->sym_ptr_ptr))->section); +- b_vma = elf2flt_bfd_section_vma((*(rb->sym_ptr_ptr))->section); +- va = (*(ra->sym_ptr_ptr))->value + a_vma + ra->addend; +- vb = (*(rb->sym_ptr_ptr))->value + b_vma + rb->addend; +- return va - vb; +-} +-#endif +- +-static bool +-ro_reloc_data_section_should_be_in_text(asection *s) +-{ +- if ((s->flags & (SEC_DATA | SEC_READONLY | SEC_RELOC)) == +- (SEC_DATA | SEC_READONLY | SEC_RELOC)) { +-#if defined(TARGET_m68k) || defined(TARGET_riscv64) || defined(TARGET_xtensa) +- if (!strcmp(".eh_frame", s->name)) +- return false; +-#endif +- return true; +- } +- return false; +-} +- +-static uint32_t * +-output_relocs ( +- bfd *abs_bfd, +- asymbol **symbols, +- int number_of_symbols, +- uint32_t *n_relocs, +- unsigned char *text, int text_len, uint32_t text_vma, +- unsigned char *data, int data_len, uint32_t data_vma, +- bfd *rel_bfd) +-{ +- uint32_t *flat_relocs; +- asection *a, *sym_section, *r; +- arelent **relpp, **p, *q; +- const char *sym_name, *section_name; +- unsigned char *sectionp; +- unsigned long pflags; +- char addstr[20]; +- uint32_t sym_addr, sym_vma, section_vma; +- int relsize, relcount; +- int flat_reloc_count; +- int sym_reloc_size, rc; +- int got_size = 0; +- int bad_relocs = 0; +- asymbol **symb; +- long nsymb; +-#ifdef TARGET_bfin +- unsigned long persistent_data = 0; +-#endif +- +-#if 0 +- printf("%s(%d): output_relocs(abs_bfd=%d,symbols=0x%x,number_of_symbols=%d," +- "n_relocs=0x%x,text=0x%x,text_len=%d,data=0x%x,data_len=%d)\n", +- __FILE__, __LINE__, abs_bfd, symbols, number_of_symbols, n_relocs, +- text, text_len, data, data_len); +-#endif +- +- if (0) +- dump_symbols(symbols, number_of_symbols); +- +- *n_relocs = 0; +- flat_relocs = NULL; +- flat_reloc_count = 0; +- sym_reloc_size = 0; +- rc = 0; +- pflags = 0; +- /* Silence gcc warnings */ +- (void) pflags; +- (void) sym_vma; +- +- /* Determine how big our offset table is in bytes. +- * This isn't too difficult as we've terminated the table with -1. +- * Also note that both the relocatable and absolute versions have this +- * terminator even though the relocatable one doesn't have the GOT! +- */ +- if (pic_with_got && !use_resolved) { +- uint32_t *lp = (uint32_t *)data; +- /* Should call ntohl(*lp) here but is isn't going to matter */ +- while (*lp != 0xffffffff) lp++; +- got_size = ((unsigned char *)lp) - data; +- if (verbose) +- printf("GOT table contains %zu entries (%d bytes)\n", +- got_size/sizeof(uint32_t), got_size); +-#ifdef TARGET_m68k +- if (got_size > GOT_LIMIT) +- fatal("GOT too large: %d bytes (limit = %d bytes)", +- got_size, GOT_LIMIT); +-#endif +- } +- +- for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) { +- section_vma = elf2flt_bfd_section_vma(a); +- +- if (verbose) +- printf("SECTION: %s [%p]: flags=0x%x vma=0x%"PRIx32"\n", +- a->name, a, a->flags, section_vma); +- +-// if (bfd_is_abs_section(a)) +-// continue; +- if (bfd_is_und_section(a)) +- continue; +- if (bfd_is_com_section(a)) +- continue; +-// if ((a->flags & SEC_RELOC) == 0) +-// continue; +- +- /* +- * Only relocate things in the writable data sections if we are PIC/GOT. +- * Otherwise do text (and read only data) as well. +- */ +- if ((!pic_with_got || ALWAYS_RELOC_TEXT) && +- ((a->flags & SEC_CODE) || +- ro_reloc_data_section_should_be_in_text(a))) +- sectionp = text + (a->vma - text_vma); +- else if (a->flags & SEC_DATA) +- sectionp = data + (a->vma - data_vma); +- else +- continue; +- +- /* Now search for the equivalent section in the relocation binary +- * and use that relocation information to build reloc entries +- * for this one. +- */ +- for (r=rel_bfd->sections; r != NULL; r=r->next) +- if (strcmp(a->name, r->name) == 0) +- break; +- if (r == NULL) +- continue; +- if (verbose) +- printf(" RELOCS: %s [%p]: flags=0x%x vma=0x%"BFD_VMA_FMT"x\n", +- r->name, r, r->flags, elf2flt_bfd_section_vma(r)); +- if ((r->flags & SEC_RELOC) == 0) +- continue; +- relsize = bfd_get_reloc_upper_bound(rel_bfd, r); +- if (relsize <= 0) { +- if (verbose) +- printf("%s(%d): no relocation entries section=%s\n", +- __FILE__, __LINE__, r->name); +- continue; +- } +- +- symb = get_symbols(rel_bfd, &nsymb); +- relpp = xmalloc(relsize); +- +- relcount = bfd_canonicalize_reloc(rel_bfd, r, relpp, symb); +- if (relcount <= 0) { +- if (verbose) +- printf("%s(%d): no relocation entries section=%s\n", +- __FILE__, __LINE__, r->name); +- continue; +- } else { +-#ifdef TARGET_bfin +- compare_relocs_bfd = abs_bfd; +- qsort (relpp, relcount, sizeof *relpp, compare_relocs); +-#endif +- for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) { +- unsigned char *r_mem = NULL; +- int relocation_needed = 0; +- /* Do we need to update the text segment? By default yes if not pic_with_got */ +- int update_text = !pic_with_got; +- +-#ifdef TARGET_v850 +- /* Skip this relocation entirely if possible (we +- do this early, before doing any other +- processing on it). */ +- switch ((*p)->howto->type) { +- case R_V850_9_PCREL: +- case R_V850_22_PCREL: +- case R_V850_SDA_16_16_OFFSET: +- case R_V850_SDA_15_16_OFFSET: +- case R_V850_ZDA_15_16_OFFSET: +- case R_V850_TDA_6_8_OFFSET: +- case R_V850_TDA_7_8_OFFSET: +- case R_V850_TDA_7_7_OFFSET: +- case R_V850_TDA_16_16_OFFSET: +- case R_V850_TDA_4_5_OFFSET: +- case R_V850_TDA_4_4_OFFSET: +- case R_V850_SDA_16_16_SPLIT_OFFSET: +- case R_V850_CALLT_6_7_OFFSET: +- case R_V850_CALLT_16_16_OFFSET: +- /* These are relative relocations, which +- have already been fixed up by the +- linker at this point, so just ignore +- them. */ +- continue; +- } +-#endif /* USE_V850_RELOCS */ +- +- q = *p; +- if (q->sym_ptr_ptr && *q->sym_ptr_ptr) { +- sym_name = (*(q->sym_ptr_ptr))->name; +- sym_section = (*(q->sym_ptr_ptr))->section; +- section_name=(*(q->sym_ptr_ptr))->section->name; +- } else { +- printf("ERROR: undefined relocation entry\n"); +- rc = -1; +- continue; +- } +-#ifndef TARGET_bfin +- /* Adjust the address to account for the GOT table which wasn't +- * present in the relative file link. +- */ +- if (pic_with_got && !use_resolved) +- q->address += got_size; +-#endif +- +- /* A pointer to what's being relocated, used often +- below. */ +- r_mem = sectionp + q->address; +- +- /* +- * Fixup offset in the actual section. +- */ +- addstr[0] = 0; +-#if !defined TARGET_e1 && !defined TARGET_bfin +- if ((sym_addr = get_symbol_offset((char *) sym_name, +- sym_section, symbols, number_of_symbols)) == -1) { +- sym_addr = 0; +- } +-#else +- sym_addr = (*(q->sym_ptr_ptr))->value; +-#endif +- if (use_resolved) { +- /* Use the address of the symbol already in +- the program text. How this is handled may +- still depend on the particular relocation +- though. */ +- switch (q->howto->type) { +-#ifdef TARGET_v850 +- int r2_type; +- case R_V850_HI16_S: +- /* We specially handle adjacent +- HI16_S/ZDA_15_16_OFFSET and +- HI16_S/LO16 pairs that reference the +- same address (these are usually +- movhi/ld and movhi/movea pairs, +- respectively). */ +- if (relcount == 0) +- r2_type = R_V850_NONE; +- else +- r2_type = p[1]->howto->type; +- if ((r2_type == R_V850_ZDA_15_16_OFFSET +- || r2_type == R_V850_LO16) +- && (p[0]->sym_ptr_ptr +- == p[1]->sym_ptr_ptr) +- && (p[0]->addend == p[1]->addend)) +- { +- relocation_needed = 1; +- +- switch (r2_type) { +- case R_V850_ZDA_15_16_OFFSET: +- pflags = 0x10000000; +- break; +- case R_V850_LO16: +- pflags = 0x20000000; +- break; +- } +- +- /* We don't really need the +- actual value -- the bits +- produced by the linker are +- what we want in the final +- flat file -- but get it +- anyway if useful for +- debugging. */ +- if (verbose) { +- unsigned char *r2_mem = +- sectionp +- + p[1]->address; +- /* little-endian */ +- int hi = r_mem[0] +- + (r_mem[1] << 8); +- int lo = r2_mem[0] +- + (r2_mem[1] << 8); +- /* Sign extend LO. */ +- lo = (lo ^ 0x8000) +- - 0x8000; +- +- /* Maybe ignore the LSB +- of LO, which is +- actually part of the +- instruction. */ +- if (r2_type != R_V850_LO16) +- lo &= ~1; +- +- sym_addr = +- (hi << 16) +- + lo; +- } +- } else +- goto bad_resolved_reloc; +- break; +- +- case R_V850_LO16: +- /* See if this is actually the +- 2nd half of a pair. */ +- if (p > relpp +- && (p[-1]->howto->type +- == R_V850_HI16_S) +- && (p[-1]->sym_ptr_ptr +- == p[0]->sym_ptr_ptr) +- && (p[-1]->addend == p[0]->addend)) +- break; /* not an error */ +- else +- goto bad_resolved_reloc; +- +- case R_V850_HI16: +- goto bad_resolved_reloc; +- default: +- goto good_32bit_resolved_reloc; +-#elif defined(TARGET_microblaze) +- case R_MICROBLAZE_64: +- sym_addr = +- (r_mem[2] << 24) +- + (r_mem[3] << 16) +- + (r_mem[6] << 8) +- + r_mem[7]; +- relocation_needed = 1; +- update_text = 0; +- pflags = 0x80000000; +- break; +- case R_MICROBLAZE_GOTPC_64: +- /* This is data-relative. We can't support this with bflt */ +- goto bad_resolved_reloc; +- case R_MICROBLAZE_GOT_64: +- /* This is a GOT relocation. But it is accessed via the GOT register (r20) +- * so doesn't need relocation +- */ +- relocation_needed = 0; +- break; +- case R_MICROBLAZE_32: +- goto good_32bit_resolved_reloc; +- /* These are already relocated for us as text-relative, or are dummy entries */ +- case R_MICROBLAZE_64_PCREL: +- case R_MICROBLAZE_PLT_64: +- case R_MICROBLAZE_NONE: +- case R_MICROBLAZE_64_NONE: +- case R_MICROBLAZE_32_PCREL_LO: +- relocation_needed = 0; +- continue; +- default: +- goto bad_resolved_reloc; +-#elif defined(TARGET_arm) +- case R_ARM_TARGET1: +- case R_ARM_TARGET2: +- case R_ARM_ABS32: +- relocation_needed = 1; +- break; +- case R_ARM_REL32: +- case R_ARM_JUMP24: +- case R_ARM_CALL: +- case R_ARM_THM_PC11: +- case R_ARM_THM_PC22: +- case R_ARM_THM_JUMP24: +- case R_ARM_PC24: +- case R_ARM_PLT32: +- case R_ARM_GOTPC: +- case R_ARM_GOT32: +- case R_ARM_PREL31: +- case R_ARM_V4BX: +- case R_ARM_NONE: +- relocation_needed = 0; +- break; +- default: +- goto bad_resolved_reloc; +-#elif defined(TARGET_m68k) +- case R_68K_32: +- goto good_32bit_resolved_reloc; +- case R_68K_PC32: +- case R_68K_PC16: +- /* The linker has already resolved +- PC relocs for us. In PIC links, +- the symbol must be in the data +- segment. */ +- case R_68K_NONE: +- continue; +- default: +- goto bad_resolved_reloc; +-#elif defined TARGET_bfin +- case R_BFIN_RIMM16: +- case R_BFIN_LUIMM16: +- case R_BFIN_HUIMM16: +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- +- if (weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr)))) +- continue; +- if (q->howto->type == R_BFIN_RIMM16 && (0xFFFF0000 & sym_addr)) { +- fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name); +- bad_relocs++; +- } +- if ((0xFFFF0000 & sym_addr) != persistent_data) { +- flat_relocs = (uint32_t *) +- (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t))); +- if (verbose) +- printf("New persistent data for %08"PRIx32"\n", sym_addr); +- persistent_data = 0xFFFF0000 & sym_addr; +- flat_relocs[flat_reloc_count++] +- = (sym_addr >> 16) | (3 << 26); +- } +- +- flat_relocs = (uint32_t *) +- (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t))); +- if (bfin_set_reloc (flat_relocs + flat_reloc_count, +- sym_section->name, sym_name, +- (*(q->sym_ptr_ptr)), +- q->howto->type == R_BFIN_HUIMM16 ? 1 : 0, +- section_vma + q->address)) +- bad_relocs++; +- if (a->flags & SEC_CODE) +- text_has_relocs = 1; +- flat_reloc_count++; +- break; +- +- case R_BFIN_BYTE4_DATA: +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- +- if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr)))) +- continue; +- +- flat_relocs = (uint32_t *) +- (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t))); +- if (bfin_set_reloc (flat_relocs + flat_reloc_count, +- sym_section->name, sym_name, +- (*(q->sym_ptr_ptr)), +- 2, section_vma + q->address)) +- bad_relocs++; +- if (a->flags & SEC_CODE) +- text_has_relocs = 1; +- +- flat_reloc_count++; +- break; +-#elif defined (TARGET_h8300) +- case R_H8_DIR32: +- case R_H8_DIR32A16: +- case R_H8_DISP32A16: +- r_mem[0] = 0; +- case R_H8_DIR24A8: +- case R_H8_DIR24R8: +- goto good_32bit_resolved_reloc; +- case R_H8_PCREL8: +- case R_H8_PCREL16: +- continue; +-#elif defined(TARGET_xtensa) +- case R_XTENSA_NONE: +- case R_XTENSA_OP0: +- case R_XTENSA_OP1: +- case R_XTENSA_OP2: +- case R_XTENSA_SLOT0_OP: +- case R_XTENSA_SLOT1_OP: +- case R_XTENSA_SLOT2_OP: +- case R_XTENSA_SLOT3_OP: +- case R_XTENSA_SLOT4_OP: +- case R_XTENSA_SLOT5_OP: +- case R_XTENSA_SLOT6_OP: +- case R_XTENSA_SLOT7_OP: +- case R_XTENSA_SLOT8_OP: +- case R_XTENSA_SLOT9_OP: +- case R_XTENSA_SLOT10_OP: +- case R_XTENSA_SLOT11_OP: +- case R_XTENSA_SLOT12_OP: +- case R_XTENSA_SLOT13_OP: +- case R_XTENSA_SLOT14_OP: +- case R_XTENSA_SLOT0_ALT: +- case R_XTENSA_SLOT1_ALT: +- case R_XTENSA_SLOT2_ALT: +- case R_XTENSA_SLOT3_ALT: +- case R_XTENSA_SLOT4_ALT: +- case R_XTENSA_SLOT5_ALT: +- case R_XTENSA_SLOT6_ALT: +- case R_XTENSA_SLOT7_ALT: +- case R_XTENSA_SLOT8_ALT: +- case R_XTENSA_SLOT9_ALT: +- case R_XTENSA_SLOT10_ALT: +- case R_XTENSA_SLOT11_ALT: +- case R_XTENSA_SLOT12_ALT: +- case R_XTENSA_SLOT13_ALT: +- case R_XTENSA_SLOT14_ALT: +- case R_XTENSA_ASM_EXPAND: +- case R_XTENSA_ASM_SIMPLIFY: +- case R_XTENSA_DIFF8: +- case R_XTENSA_DIFF16: +- case R_XTENSA_DIFF32: +-#if HAVE_BFD_XTENSA_PDIFF_RELOCS +- case R_XTENSA_PDIFF8: +- case R_XTENSA_PDIFF16: +- case R_XTENSA_PDIFF32: +- case R_XTENSA_NDIFF8: +- case R_XTENSA_NDIFF16: +- case R_XTENSA_NDIFF32: +-#endif +- case R_XTENSA_32_PCREL: +- continue; +- case R_XTENSA_32: +- case R_XTENSA_PLT: +- if (bfd_big_endian (abs_bfd)) +- sym_addr = +- (r_mem[0] << 24) +- + (r_mem[1] << 16) +- + (r_mem[2] << 8) +- + r_mem[3]; +- else +- sym_addr = +- r_mem[0] +- + (r_mem[1] << 8) +- + (r_mem[2] << 16) +- + (r_mem[3] << 24); +- relocation_needed = 1; +- break; +- default: +- goto bad_resolved_reloc; +-#elif defined(TARGET_riscv64) +- case R_RISCV_32_PCREL: +- case R_RISCV_ADD32: +- case R_RISCV_ADD64: +- case R_RISCV_SUB32: +- case R_RISCV_SUB64: +- continue; +- case R_RISCV_32: +- case R_RISCV_64: +- goto good_32bit_resolved_reloc; +- default: +- goto bad_resolved_reloc; +-#else +- default: +- /* The default is to assume that the +- relocation is relative and has +- already been fixed up by the +- linker (perhaps we ought to make +- give an error by default, and +- require `safe' relocations to be +- enumberated explicitly?). */ +- goto good_32bit_resolved_reloc; +-#endif +- good_32bit_resolved_reloc: +- if (bfd_big_endian (abs_bfd)) +- sym_addr = +- (r_mem[0] << 24) +- + (r_mem[1] << 16) +- + (r_mem[2] << 8) +- + r_mem[3]; +- else +- sym_addr = +- r_mem[0] +- + (r_mem[1] << 8) +- + (r_mem[2] << 16) +- + (r_mem[3] << 24); +- relocation_needed = 1; +- update_text = 0; +- break; +- +- bad_resolved_reloc: +- printf("ERROR: reloc type %s unsupported in this context\n", +- q->howto->name); +- bad_relocs++; +- break; +- } +- } else { +- /* Calculate the sym address ourselves. */ +-#if defined(TARGET_xtensa) +- /* For xtensa, calculation of addresses won't +- work this way. binutils "ld -r" generate +- different relocation types, among others +- type 20, R_XTENSA_SLOT0_OP. The latter is +- produced for various opcodes that differ +- in size and format, some will have the +- addend filled in when linking, others won't. +- For elf2flt to handle these relocations +- would involve analysing the opcodes in +- detail. Therefore, elf2flt for xtensa is +- patched to work with "-a" option solely, +- which will take output of "ld -q". +- */ +- fatal("ERROR: cannot run without '-a'"); +-#endif +- sym_reloc_size = bfd_get_reloc_size(q->howto); +- +- if (sym_reloc_size == 0) { +- /* These are dummy relocs that can be ignored */ +- continue; +- } +- +-#if !defined(TARGET_h8300) && !defined(TARGET_e1) && !defined(TARGET_bfin) && !defined(TARGET_m68k) +- if (sym_reloc_size != 4) { +- printf("ERROR: bad reloc type %d size=%d for symbol=%s\n", +- (*p)->howto->type, sym_reloc_size, sym_name); +- bad_relocs++; +- rc = -1; +- continue; +- } +-#endif +- +- switch ((*p)->howto->type) { +- +-#if defined(TARGET_m68k) +- case R_68K_32: +- relocation_needed = 1; +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- break; +- case R_68K_PC16: +- case R_68K_PC32: +- sym_vma = 0; +- sym_addr += sym_vma + q->addend; +- sym_addr -= q->address; +- break; +-#endif +- +-#if defined(TARGET_arm) +- case R_ARM_ABS32: +- relocation_needed = 1; +- if (verbose) +- fprintf(stderr, +- "%s vma=0x%x, " +- "value=0x%"BFD_VMA_FMT"x, " +- "address=0x%"BFD_VMA_FMT"x " +- "sym_addr=0x%x rs=0x%x, opcode=0x%x\n", +- "ABS32", +- sym_vma, (*(q->sym_ptr_ptr))->value, +- q->address, sym_addr, +- (*p)->howto->rightshift, +- *(uint32_t *)r_mem); +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- break; +- case R_ARM_GOT32: +- case R_ARM_GOTPC: +- /* Should be fine as is */ +- break; +- case R_ARM_PLT32: +- if (verbose) +- fprintf(stderr, +- "%s vma=0x%x, " +- "value=0x%"BFD_VMA_FMT"x, " +- "address=0x%"BFD_VMA_FMT"x " +- "sym_addr=0x%x rs=0x%x, opcode=0x%x\n", +- "PLT32", +- sym_vma, (*(q->sym_ptr_ptr))->value, +- q->address, sym_addr, +- (*p)->howto->rightshift, +- *(uint32_t *)r_mem); +- case R_ARM_PC24: +- sym_vma = 0; +- sym_addr = (sym_addr-q->address)>>(*p)->howto->rightshift; +- break; +-#endif +- +-#ifdef TARGET_v850 +- case R_V850_ABS32: +- relocation_needed = 1; +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- break; +- case R_V850_ZDA_16_16_OFFSET: +- case R_V850_ZDA_16_16_SPLIT_OFFSET: +- /* Can't support zero-relocations. */ +- printf ("ERROR: %s+0x%"BFD_VMA_FMT"x: zero relocations not supported\n", +- sym_name, q->addend); +- continue; +-#endif /* TARGET_v850 */ +- +-#ifdef TARGET_h8300 +- case R_H8_DIR24R8: +- if (sym_reloc_size != 4) { +- printf("R_H8_DIR24R8 size %d\n", sym_reloc_size); +- bad_relocs++; +- continue; +- } +- relocation_needed = 1; +- sym_addr = (*(q->sym_ptr_ptr))->value; +- q->address -= 1; +- r_mem -= 1; /* tracks q->address */ +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- sym_addr |= (*(unsigned char *)r_mem<<24); +- break; +- case R_H8_DIR24A8: +- if (sym_reloc_size != 4) { +- printf("R_H8_DIR24A8 size %d\n", sym_reloc_size); +- bad_relocs++; +- continue; +- } +- /* Absolute symbol done not relocation */ +- relocation_needed = !bfd_is_abs_section(sym_section); +- sym_addr = (*(q->sym_ptr_ptr))->value; +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- break; +- case R_H8_DIR32: +- case R_H8_DIR32A16: /* currently 32, could be made 16 */ +- case R_H8_DISP32A16: +- if (sym_reloc_size != 4) { +- printf("R_H8_DIR32 size %d\n", sym_reloc_size); +- bad_relocs++; +- continue; +- } +- relocation_needed = 1; +- sym_addr = (*(q->sym_ptr_ptr))->value; +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- break; +- case R_H8_PCREL16: +- relocation_needed = 0; +- sym_vma = 0; +- sym_addr = (*(q->sym_ptr_ptr))->value; +- sym_addr += sym_vma + q->addend; +- sym_addr -= (q->address + 2); +- if (bfd_big_endian(abs_bfd)) +- *(unsigned short *)r_mem = +- bfd_big_endian(abs_bfd) ? htons(sym_addr) : sym_addr; +- continue; +- case R_H8_PCREL8: +- relocation_needed = 0; +- sym_vma = 0; +- sym_addr = (*(q->sym_ptr_ptr))->value; +- sym_addr += sym_vma + q->addend; +- sym_addr -= (q->address + 1); +- *(unsigned char *)r_mem = sym_addr; +- continue; +-#endif +- +-#ifdef TARGET_microblaze +- case R_MICROBLAZE_64: +- /* work out the relocation */ +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- /* Write relocated pointer back */ +- r_mem[2] = (sym_addr >> 24) & 0xff; +- r_mem[3] = (sym_addr >> 16) & 0xff; +- r_mem[6] = (sym_addr >> 8) & 0xff; +- r_mem[7] = sym_addr & 0xff; +- relocation_needed = 1; +- /* The symbol is split over two consecutive instructions. +- Flag this to the flat loader by setting the high bit of +- the relocation symbol. */ +- pflags = 0x80000000; +- break; +- case R_MICROBLAZE_32: +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- relocation_needed = 1; +- break; +- case R_MICROBLAZE_64_PCREL: +- sym_vma = 0; +- sym_addr += sym_vma + q->addend; +- sym_addr -= (q->address + 4); +- sym_addr = htonl(sym_addr); +- /* insert 16 MSB */ +- * ((unsigned short *) (r_mem+2)) = (sym_addr) & 0xFFFF; +- /* then 16 LSB */ +- * ((unsigned short *) (r_mem+6)) = (sym_addr >> 16) & 0xFFFF; +- /* We've done all the work, so continue +- to next reloc instead of break */ +- continue; +- /* These are already relocated for us as text-relative, or are dummy entries */ +- case R_MICROBLAZE_PLT_64: +- case R_MICROBLAZE_NONE: +- case R_MICROBLAZE_64_NONE: +- case R_MICROBLAZE_32_PCREL_LO: +- relocation_needed = 0; +- continue; +- +-#endif /* TARGET_microblaze */ +- +-#ifdef TARGET_nios2 +-#define htoniosl(x) (x) +-#define niostohl(x) (x) +- case R_NIOS2_BFD_RELOC_32: +- relocation_needed = 1; +- pflags = (FLAT_NIOS2_R_32 << 28); +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- /* modify target, in target order */ +- *(unsigned long *)r_mem = htoniosl(sym_addr); +- break; +- case R_NIOS2_CALL26: +- { +- unsigned long exist_val; +- relocation_needed = 1; +- pflags = (FLAT_NIOS2_R_CALL26 << 28); +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- +- /* modify target, in target order */ +- // exist_val = niostohl(*(unsigned long *)r_mem); +- exist_val = ((sym_addr >> 2) << 6); +- *(unsigned long *)r_mem = htoniosl(exist_val); +- break; +- } +- case R_NIOS2_HIADJ16: +- case R_NIOS2_HI16: +- { +- unsigned long exist_val; +- int r2_type; +- /* handle the adjacent HI/LO pairs */ +- if (relcount == 0) +- r2_type = R_NIOS2_NONE; +- else +- r2_type = p[1]->howto->type; +- if ((r2_type == R_NIOS2_LO16) +- && (p[0]->sym_ptr_ptr == p[1]->sym_ptr_ptr) +- && (p[0]->addend == p[1]->addend)) +- { +- unsigned char * r2_mem = sectionp + p[1]->address; +- if (p[1]->address - q->address!=4) +- printf("Err: HI/LO not adjacent %ld\n", p[1]->address - q->address); +- relocation_needed = 1; +- pflags = (q->howto->type == R_NIOS2_HIADJ16) +- ? FLAT_NIOS2_R_HIADJ_LO : FLAT_NIOS2_R_HI_LO; +- pflags <<= 28; +- +- sym_vma = elf2flt_bfd_section_vma(abs_bfd, sym_section); +- sym_addr += sym_vma + q->addend; +- +- /* modify high 16 bits, in target order */ +- exist_val = niostohl(*(unsigned long *)r_mem); +- exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f); +- if (q->howto->type == R_NIOS2_HIADJ16) +- exist_val |= ((((sym_addr >> 16) + ((sym_addr >> 15) & 1)) & 0xFFFF) << 6); +- else +- exist_val |= (((sym_addr >> 16) & 0xFFFF) << 6); +- *(unsigned long *)r_mem = htoniosl(exist_val); +- +- /* modify low 16 bits, in target order */ +- exist_val = niostohl(*(unsigned long *)r2_mem); +- exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f); +- exist_val |= ((sym_addr & 0xFFFF) << 6); +- *(unsigned long *)r2_mem = htoniosl(exist_val); +- +- } else +- goto NIOS2_RELOC_ERR; +- } +- break; +- +- case R_NIOS2_GPREL: +- { +- unsigned long exist_val, temp; +- //long gp = get_symbol_offset("_gp", sym_section, symbols, number_of_symbols); +- long gp = get_gp_value(symbols, number_of_symbols); +- if (gp == -1) { +- printf("Err: unresolved symbol _gp when relocating %s\n", sym_name); +- goto NIOS2_RELOC_ERR; +- } +- /* _gp holds a absolute value, otherwise the ld cannot generate correct code */ +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- //printf("sym=%x, %d, _gp=%x, %d\n", sym_addr+sym_vma, sym_addr+sym_vma, gp, gp); +- sym_addr += sym_vma + q->addend; +- sym_addr -= gp; +- //printf("sym - _gp=%x, %d\n", sym_addr, sym_addr); +- /* modify the target, in target order (little_endian) */ +- exist_val = niostohl(*(unsigned long *)r_mem); +- temp = ((exist_val >> 6) & 0x3ff0000) | (sym_addr & 0xffff); +- temp <<= 6; +- temp |= (exist_val & 0x3f); +- *(unsigned long *)r_mem = htoniosl(temp); +- if (verbose) +- printf("omit: offset=0x%"BFD_VMA_FMT"x symbol=%s%s " +- "section=%s size=%d " +- "fixup=0x%x (reloc=0x%"BFD_VMA_FMT"x) GPREL\n", +- q->address, sym_name, addstr, +- section_name, sym_reloc_size, +- sym_addr, section_vma + q->address); +- continue; +- } +- case R_NIOS2_PCREL16: +- { +- unsigned long exist_val; +- sym_vma = 0; +- sym_addr += sym_vma + q->addend; +- sym_addr -= (q->address + 4); +- /* modify the target, in target order (little_endian) */ +- exist_val = niostohl(*(unsigned long *)r_mem); +- exist_val = ((exist_val >> 22) << 22) | (exist_val & 0x3f); +- exist_val |= ((sym_addr & 0xFFFF) << 6); +- *(unsigned long *)r_mem = htoniosl(exist_val); +- if (verbose) +- printf("omit: offset=0x%"BFD_VMA_FMT"x symbol=%s%s " +- "section=%s size=%d " +- "fixup=0x%x (reloc=0x%"BFD_VMA_FMT"x) PCREL\n", +- q->address, sym_name, addstr, +- section_name, sym_reloc_size, +- sym_addr, section_vma + q->address); +- continue; +- } +- +- case R_NIOS2_LO16: +- /* check if this is actually the 2nd half of a pair */ +- if ((p > relpp) +- && ((p[-1]->howto->type == R_NIOS2_HIADJ16) +- || (p[-1]->howto->type == R_NIOS2_HI16)) +- && (p[-1]->sym_ptr_ptr == p[0]->sym_ptr_ptr) +- && (p[-1]->addend == p[0]->addend)) { +- if (verbose) +- printf("omit: offset=0x%"BFD_VMA_FMT"x symbol=%s%s " +- "section=%s size=%d LO16\n", +- q->address, sym_name, addstr, +- section_name, sym_reloc_size); +- continue; +- } +- +- /* error, fall through */ +- +- case R_NIOS2_S16: +- case R_NIOS2_U16: +- case R_NIOS2_CACHE_OPX: +- case R_NIOS2_IMM5: +- case R_NIOS2_IMM6: +- case R_NIOS2_IMM8: +- case R_NIOS2_BFD_RELOC_16: +- case R_NIOS2_BFD_RELOC_8: +- case R_NIOS2_GNU_VTINHERIT: +- case R_NIOS2_GNU_VTENTRY: +- case R_NIOS2_UJMP: +- case R_NIOS2_CJMP: +- case R_NIOS2_CALLR: +-NIOS2_RELOC_ERR: +- printf("Err: unexpected reloc type %s(%d)\n", q->howto->name, q->howto->type); +- bad_relocs++; +- continue; +-#endif /* TARGET_nios2 */ +- +-#ifdef TARGET_sparc +- case R_SPARC_32: +- case R_SPARC_UA32: +- relocation_needed = 1; +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- break; +- case R_SPARC_PC22: +- sym_vma = 0; +- sym_addr += sym_vma + q->addend; +- sym_addr -= q->address; +- break; +- case R_SPARC_WDISP30: +- sym_addr = (((*(q->sym_ptr_ptr))->value- +- q->address) >> 2) & 0x3fffffff; +- sym_addr |= ( +- ntohl(*(uint32_t *)r_mem) +- & 0xc0000000 +- ); +- break; +- case R_SPARC_HI22: +- relocation_needed = 1; +- pflags = 0x80000000; +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- sym_addr |= ( +- htonl(*(uint32_t *)r_mem) +- & 0xffc00000 +- ); +- break; +- case R_SPARC_LO10: +- relocation_needed = 1; +- pflags = 0x40000000; +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- sym_addr &= 0x000003ff; +- sym_addr |= ( +- htonl(*(uint32_t *)r_mem) +- & 0xfffffc00 +- ); +- break; +-#endif /* TARGET_sparc */ +- +- +-#ifdef TARGET_sh +- case R_SH_DIR32: +- relocation_needed = 1; +- sym_vma = elf2flt_bfd_section_vma(sym_section); +- sym_addr += sym_vma + q->addend; +- break; +- case R_SH_REL32: +- sym_vma = 0; +- sym_addr += sym_vma + q->addend; +- sym_addr -= q->address; +- break; +-#endif /* TARGET_sh */ +- +-#ifdef TARGET_e1 +-#define htoe1l(x) htonl(x) +- +-#if 0 +-#define DEBUG_E1 +-#endif +- +-#ifdef DEBUG_E1 +-#define DBG_E1 printf +-#else +-#define DBG_E1(x, ... ) +-#endif +- +-#define _32BITS_RELOC 0x00000000 +-#define _30BITS_RELOC 0x80000000 +-#define _28BITS_RELOC 0x40000000 +- { +- char *p; +- unsigned long sec_vma, exist_val, S; +- case R_E1_CONST31: +- relocation_needed = 1; +- DBG_E1("Handling Reloc \n"); +- sec_vma = elf2flt_bfd_section_vma(sym_section); +- DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n", +- sec_vma, sym_addr, q->address); +- sym_addr = sec_vma + sym_addr; +- exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2); +- DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val); +- exist_val = htoe1l(exist_val); +- DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val); +- sym_addr += exist_val; +- pflags = _30BITS_RELOC; +- break; +- case R_E1_CONST31_PCREL: +- relocation_needed = 0; +- DBG_E1("Handling Reloc \n"); +- DBG_E1("DONT RELOCATE AT LOADING\n"); +- sec_vma = elf2flt_bfd_section_vma(sym_section); +- DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n", +- sec_vma, sym_addr, q->address); +- sym_addr = sec_vma + sym_addr; +- DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr ); +- +- DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address, +- section_vma ); +- q->address = q->address + section_vma; +- DBG_E1("q->address += section_vma : 0x%x\n", q->address ); +- +- if( (sym_addr = (sym_addr - q->address - 6)) < 0 ) +- DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n"); +- DBG_E1( "sym_addr := sym_addr - q->address - " +- "sizeof(CONST31_PCREL): [0x%x]\n", +- sym_addr ); +- exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2); +- DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val); +- exist_val = htoe1l(exist_val); +- DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val); +- sym_addr |= exist_val; +- DBG_E1("sym_addr |= exist_val) : [0x%x]\n", sym_addr ); +- break; +- case R_E1_DIS29W_PCREL: +- relocation_needed = 0; +- DBG_E1("Handling Reloc \n"); +- DBG_E1("DONT RELOCATE AT LOADING\n"); +- sec_vma = elf2flt_bfd_section_vma(sym_section); +- DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x], q->address : [0x%x]\n", +- sec_vma, sym_addr, q->address); +- sym_addr = sec_vma + sym_addr; +- DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr ); +- +- DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address, +- section_vma ); +- q->address = q->address + section_vma; +- DBG_E1("q->address += section_vma : 0x%x\n", q->address ); +- +- if( (sym_addr = (sym_addr - q->address - 6)) < 0 ) +- DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n"); +- DBG_E1( "sym_addr := sym_addr - q->address - " +- "sizeof(CONST31_PCREL): [0x%x]\n", +- sym_addr ); +- DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address ); +- exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2); +- DBG_E1("Original:exist_val : [0x%08x]\n",exist_val); +- exist_val = htoe1l(exist_val); +- DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val); +- sym_addr += exist_val; +- break; +- case R_E1_DIS29W: +- DBG_E1("Handling Reloc \n"); +- goto DIS29_RELOCATION; +- case R_E1_DIS29H: +- DBG_E1("Handling Reloc \n"); +- goto DIS29_RELOCATION; +- case R_E1_DIS29B: +- DBG_E1("Handling Reloc \n"); +-DIS29_RELOCATION: +- relocation_needed = 1; +- sec_vma = elf2flt_bfd_section_vma(sym_section); +- DBG_E1("sec_vma : [0x%x], sym_addr : [0x%08x]\n", +- sec_vma, sym_addr); +- sym_addr = sec_vma + sym_addr; +- DBG_E1("sym_addr = sec_vma + sym_addr : [0x%08x]\n", sym_addr); +- exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2); +- DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val); +- exist_val = htoe1l(exist_val); +- DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val); +- sym_addr += exist_val; +- DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr); +- pflags = _28BITS_RELOC; +- break; +- case R_E1_IMM32_PCREL: +- relocation_needed = 0; +- DBG_E1("Handling Reloc \n"); +- DBG_E1("DONT RELOCATE AT LOADING\n"); +- sec_vma = elf2flt_bfd_section_vma(sym_section); +- DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n", +- sec_vma, sym_addr); +- sym_addr = sec_vma + sym_addr; +- +- DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr ); +- DBG_E1("q->address : 0x%x, section_vma : 0x%x\n", q->address, +- section_vma ); +- q->address = q->address + section_vma; +- DBG_E1("q->address += section_vma : 0x%x\n", q->address ); +- +- if( (sym_addr = (sym_addr - q->address - 6 )) < 0 ) +- DBG_E1("NEGATIVE OFFSET in PC Relative instruction\n"); +- DBG_E1( "sym_addr := sym_addr - q->address - " +- "sizeof(CONST31_PCREL): [0x%x]\n", +- sym_addr ); +- DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address ); +- exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2); +- DBG_E1("Original:exist_val : [0x%08x]\n",exist_val); +- exist_val = htoe1l(exist_val); +- DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val); +- sym_addr += exist_val; +- break; +- case R_E1_IMM32: +- relocation_needed = 1; +- DBG_E1("Handling Reloc \n"); +- sec_vma = elf2flt_bfd_section_vma(sym_section); +- DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n", +- sec_vma, sym_addr); +- sym_addr = sec_vma + sym_addr; +- DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr ); +- DBG_E1("sectionp:[0x%x], q->address:[0x%x]\n", sectionp, q->address ); +- exist_val = *(unsigned long*)((unsigned long)sectionp + q->address + 2); +- DBG_E1("Original:exist_val : [0x%08x]\n",exist_val); +- exist_val = htoe1l(exist_val); +- DBG_E1("HtoBE:exist_val : [0x%08x]\n",exist_val); +- sym_addr += exist_val; +- pflags = _32BITS_RELOC; +- break; +- case R_E1_WORD: +- relocation_needed = 1; +- DBG_E1("Handling Reloc \n"); +- sec_vma = elf2flt_bfd_section_vma(sym_section); +- DBG_E1("sec_vma : [0x%x], sym_addr : [0x%x]\n", +- sec_vma, sym_addr); +- sym_addr = sec_vma + sym_addr; +- DBG_E1("sym_addr = sec_vma + sym_addr : [0x%x]\n", sym_addr ); +- exist_val = *(unsigned long*)((unsigned long)sectionp + q->address ); +- DBG_E1("Orig:exist_val : [0x%08x]\n", exist_val); +- exist_val = htoe1l(exist_val); +- DBG_E1("HtoBE:exist_val : [0x%08x]\n", exist_val); +- sym_addr += exist_val; +- DBG_E1("sym_addr += exist_val : [0x%08x]\n", sym_addr); +- pflags = _32BITS_RELOC; +- break; +- } +-#undef _32BITS_RELOC +-#undef _30BITS_RELOC +-#undef _28BITS_RELOC +-#endif +- default: +- /* missing support for other types of relocs */ +- printf("ERROR: bad reloc type (%s)%d\n", q->howto->name, (*p)->howto->type); +- bad_relocs++; +- continue; +- } +- } +- +- sprintf(&addstr[0], "+0x%lx", sym_addr - (*(q->sym_ptr_ptr))->value - +- elf2flt_bfd_section_vma(sym_section)); +- +- +- /* +- * for full elf relocation we have to write back the +- * start_code relative value to use. Not needed with pic_with_got +- * or if the fixup has already been done above (in which case update_text was set to 0) +- */ +- if (update_text) { +-#if defined(TARGET_arm) +- union { +- unsigned char c[4]; +- uint32_t l; +- } tmp; +- int32_t hl; +- int i0, i1, i2, i3; +- +- /* +- * horrible nasty hack to support different endianess +- */ +- if (!bfd_big_endian(abs_bfd)) { +- i0 = 0; +- i1 = 1; +- i2 = 2; +- i3 = 3; +- } else { +- i0 = 3; +- i1 = 2; +- i2 = 1; +- i3 = 0; +- } +- +- tmp.l = *(uint32_t *)r_mem; +- hl = tmp.c[i0] | (tmp.c[i1] << 8) | (tmp.c[i2] << 16); +- if (use_resolved || +- (((*p)->howto->type != R_ARM_PC24) && +- ((*p)->howto->type != R_ARM_PLT32))) +- hl |= (tmp.c[i3] << 24); +- else if (tmp.c[i2] & 0x80) +- hl |= 0xff000000; /* sign extend */ +- if (!use_resolved) +- hl += sym_addr; +- tmp.c[i0] = hl & 0xff; +- tmp.c[i1] = (hl >> 8) & 0xff; +- tmp.c[i2] = (hl >> 16) & 0xff; +- if (use_resolved || +- (((*p)->howto->type != R_ARM_PC24) && +- ((*p)->howto->type != R_ARM_PLT32))) +- tmp.c[i3] = (hl >> 24) & 0xff; +- if (((*p)->howto->type == R_ARM_ABS32) || +- ((*p)->howto->type == R_ARM_TARGET1) || +- ((*p)->howto->type == R_ARM_TARGET2)) +- *(uint32_t *)r_mem = htonl(hl); +- else +- *(uint32_t *)r_mem = tmp.l; +-#elif defined(TARGET_e1) +-#define OPCODE_SIZE 2 /* Add 2 bytes, counting the opcode size*/ +- switch ((*p)->howto->type) { +- case R_E1_CONST31: +- case R_E1_CONST31_PCREL: +- case R_E1_DIS29W_PCREL: +- case R_E1_DIS29W: +- case R_E1_DIS29H: +- case R_E1_DIS29B: +- case R_E1_IMM32_PCREL: +- case R_E1_IMM32: +- DBG_E1("In addr + 2:[0x%x] <- write [0x%x]\n", +- (sectionp + q->address + 2), sym_addr ); +- *((unsigned long *) (sectionp + q->address + OPCODE_SIZE)) = +- htonl(sym_addr); +- break; +- case R_E1_WORD: +- DBG_E1("In addr : [0x%x] <- write [0x%x]\n", +- (sectionp + q->address), sym_addr ); +- *((unsigned long *) (sectionp + q->address )) = htonl(sym_addr); +- break; +- default: +- fatal("ERROR: Unhandled Relocation: 0x%x", (*p)->howto->type); +- } +-#elif defined TARGET_bfin +- if ((*p)->howto->type == R_BFIN_RIMM16 +- || (*p)->howto->type == R_BFIN_HUIMM16 +- || (*p)->howto->type == R_BFIN_LUIMM16) +- { +- /* for l and h we set the lower 16 bits which is only when it will be used */ +- bfd_putl16 (sym_addr, sectionp + q->address); +- } else if ((*p)->howto->type == R_BFIN_BYTE4_DATA) { +- bfd_putl32 (sym_addr, sectionp + q->address); +- } +-#else /* ! TARGET_arm && ! TARGET_e1 && ! TARGET_bfin */ +- +- switch (q->howto->type) { +-#ifdef TARGET_v850 +- case R_V850_HI16_S: +- case R_V850_HI16: +- case R_V850_LO16: +- /* Do nothing -- for cases we handle, +- the bits produced by the linker are +- what we want in the final flat file +- (and other cases are errors). Note +- that unlike most relocated values, +- it is stored in little-endian order, +- but this is necessary to avoid +- trashing the low-bit, and the float +- loaders knows about it. */ +- break; +-#endif /* TARGET_V850 */ +- +-#ifdef TARGET_nios2 +- case R_NIOS2_BFD_RELOC_32: +- case R_NIOS2_CALL26: +- case R_NIOS2_HIADJ16: +- case R_NIOS2_HI16: +- /* do nothing */ +- break; +-#endif /* TARGET_nios2 */ +- +-#if defined(TARGET_m68k) +- case R_68K_PC16: +- if (sym_addr < -0x8000 || sym_addr > 0x7fff) { +- fprintf (stderr, "Relocation overflow for R_68K_PC16 relocation against %s\n", sym_name); +- bad_relocs++; +- } else { +- r_mem[0] = (sym_addr >> 8) & 0xff; +- r_mem[1] = sym_addr & 0xff; +- } +- break; +-#endif +- +- default: +- /* The alignment of the build host +- might be stricter than that of the +- target, so be careful. We store in +- network byte order. */ +- r_mem[0] = (sym_addr >> 24) & 0xff; +- r_mem[1] = (sym_addr >> 16) & 0xff; +- r_mem[2] = (sym_addr >> 8) & 0xff; +- r_mem[3] = sym_addr & 0xff; +- } +-#endif /* !TARGET_arm */ +- } +- +- /* +- * Create relocation entry (PC relative doesn't need this). +- */ +- if (relocation_needed) { +- if (verbose) +- printf(" RELOC[%d]: offset=0x%"BFD_VMA_FMT"x symbol=%s%s " +- "section=%s size=%d " +- "fixup=0x%x (reloc=0x%"BFD_VMA_FMT"x)\n", +- flat_reloc_count, +- q->address, sym_name, addstr, +- section_name, sym_reloc_size, +- sym_addr, section_vma + q->address); +- +-#ifndef TARGET_bfin +- flat_relocs = realloc(flat_relocs, +- (flat_reloc_count + 1) * sizeof(uint32_t)); +-#ifndef TARGET_e1 +- flat_relocs[flat_reloc_count] = pflags | +- (section_vma + q->address); +- +-#else +- switch ((*p)->howto->type) { +- case R_E1_CONST31: +- case R_E1_CONST31_PCREL: +- case R_E1_DIS29W_PCREL: +- case R_E1_DIS29W: +- case R_E1_DIS29H: +- case R_E1_DIS29B: +- case R_E1_IMM32_PCREL: +- case R_E1_IMM32: +- flat_relocs[flat_reloc_count] = pflags | +- (section_vma + q->address + OPCODE_SIZE); +- if (verbose) +- printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count, +- flat_relocs[flat_reloc_count] ); +- break; +- case R_E1_WORD: +- flat_relocs[flat_reloc_count] = pflags | +- (section_vma + q->address); +- if (verbose) +- printf("RELOCATION TABLE : reloc[%d] = [0x%x]\n", flat_reloc_count, +- flat_relocs[flat_reloc_count] ); +- break; +- } +-#endif +- flat_reloc_count++; +-#endif //TARGET_bfin +- relocation_needed = 0; +- pflags = 0; +- } +- +-#if 0 +-printf("%s(%d): symbol name=%s address=0x%x section=%s -> RELOC=0x%x\n", +- __FILE__, __LINE__, sym_name, q->address, section_name, +- flat_relocs[flat_reloc_count]); +-#endif +- } +- } +- } +- +- if (bad_relocs) +- fatal("%d bad relocs", bad_relocs); +- +- if (rc < 0) +- return(0); +- +- *n_relocs = flat_reloc_count; +- return flat_relocs; +-} +- +- +- +-static void usage(int status) +-{ +- fprintf(status ? stderr : stdout, +- "Usage: %s [vrzd] [-p ] [-s stack-size] " +- "[-o ] \n\n" +- " -v : verbose operation\n" +- " -r : force load to RAM\n" +- " -k : enable kernel trace on load (for debug)\n" +- " -z : compress code/data/relocs\n" +- " -d : compress data/relocs\n" +- " -a : use existing symbol references\n" +- " instead of recalculating from\n" +- " relocation info\n" +- " -R reloc-file : read relocations from a separate file\n" +- " -p abs-pic-file : GOT/PIC processing with files\n" +- " -s stacksize : set application stack size\n" +- " -o output-file : output file name\n\n" +- "Compiled for " ARCH " architecture\n\n", +- elf2flt_progname); +- exit(status); +-} +- +- +-/* Write NUM zeroes to STREAM. */ +-static void write_zeroes (unsigned long num, stream *stream) +-{ +- char zeroes[1024]; +- if (num > 0) { +- /* It'd be nice if we could just use fseek, but that doesn't seem to +- work for stdio output files. */ +- memset(zeroes, 0x00, 1024); +- while (num > sizeof(zeroes)) { +- fwrite_stream(zeroes, sizeof(zeroes), 1, stream); +- num -= sizeof(zeroes); +- } +- if (num > 0) +- fwrite_stream(zeroes, num, 1, stream); +- } +-} +- +- +-static time_t get_build_date(void) +-{ +- const char *sde; +- unsigned long long epoch; +- char *endptr; +- +- sde = getenv("SOURCE_DATE_EPOCH"); +- if (!sde) +- return time(NULL); +- +- /* Largely inspired from +- https://reproducible-builds.org/docs/source-date-epoch/ */ +- errno = 0; +- epoch = strtoull(sde, &endptr, 10); +- if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0)) +- || (errno != 0 && epoch == 0) +- || (endptr == sde) +- || (*endptr != '\0') +- || (epoch > ULONG_MAX)) +- fatal("Invalid SOURCE_DATE_EPOCH value"); +- +- return (time_t)epoch; +-} +- +- +-int main(int argc, char *argv[]) +-{ +- int fd; +- bfd *rel_bfd, *abs_bfd; +- asection *s; +- char *ofile=NULL, *pfile=NULL, *abs_file = NULL, *rel_file = NULL; +- char *fname = NULL; +- int opt; +- int i; +- int stack; +- stream gf; +- +- asymbol **symbol_table; +- long number_of_symbols; +- +- uint32_t data_len = 0; +- uint32_t bss_len = 0; +- uint32_t text_len = 0; +- uint32_t reloc_len; +- +- uint32_t data_vma = ~0; +- uint32_t bss_vma = ~0; +- uint32_t text_vma = ~0; +- +- uint32_t text_offs; +- +- void *text; +- void *data; +- uint32_t *reloc; +- +- struct flat_hdr hdr; +- +- elf2flt_progname = argv[0]; +- xmalloc_set_program_name(elf2flt_progname); +- +- if (argc < 2) +- usage(1); +- +- if (sizeof(hdr) != 64) +- fatal( +- "Potential flat header incompatibility detected\n" +- "header size should be 64 but is %d", +- sizeof(hdr)); +- +-#ifndef TARGET_e1 +- stack = 4096; +-#else /* We need plenty of stack for both of them (Aggregate and Register) */ +- stack = 0x2020; +-#endif +- +- while ((opt = getopt(argc, argv, "havzdrkp:s:o:R:")) != -1) { +- switch (opt) { +- case 'v': +- verbose++; +- break; +- case 'r': +- load_to_ram++; +- break; +- case 'k': +- ktrace++; +- break; +- case 'z': +- docompress = 1; +- break; +- case 'd': +- docompress = 2; +- break; +- case 'p': +- pfile = optarg; +- break; +- case 'o': +- ofile = optarg; +- break; +- case 'a': +- use_resolved = 1; +- break; +- case 's': +- if (sscanf(optarg, "%i", &stack) != 1) { +- fprintf(stderr, "%s invalid stack size %s\n", argv[0], optarg); +- usage(1); +- } +- break; +- case 'R': +- rel_file = optarg; +- break; +- case 'h': +- usage(0); +- break; +- default: +- fprintf(stderr, "%s Unknown option\n", argv[0]); +- usage(1); +- break; +- } +- } +- +- /* +- * if neither the -r or -p options was given, default to +- * a RAM load as that is the only option that makes sense. +- */ +- if (!load_to_ram && !pfile) +- load_to_ram = 1; +- +- fname = argv[argc-1]; +- +- if (pfile) { +- pic_with_got = 1; +- abs_file = pfile; +- } else +- abs_file = fname; +- +- if (! rel_file) +- rel_file = fname; +- +- if (!(rel_bfd = bfd_openr(rel_file, 0))) +- fatal_perror("Can't open '%s'", rel_file); +- +- if (bfd_check_format (rel_bfd, bfd_object) == 0) +- fatal("File is not an object file"); +- +- if (abs_file == rel_file) +- abs_bfd = rel_bfd; /* one file does all */ +- else { +- if (!(abs_bfd = bfd_openr(abs_file, 0))) +- fatal_perror("Can't open '%s'", abs_file); +- +- if (bfd_check_format (abs_bfd, bfd_object) == 0) +- fatal("File is not an object file"); +- } +- +- if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) +- fatal("%s: Input file contains no relocation info", rel_file); +- +- if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) +- /* `Absolute' file is not absolute, so neither are address +- contained therein. */ +- fatal("%s: `-a' option specified with non-fully-resolved input file", +- bfd_get_filename (abs_bfd)); +- +- symbol_table = get_symbols(abs_bfd, &number_of_symbols); +- +- /* Group output sections into text, data, and bss, and calc their sizes. */ +- for (s = abs_bfd->sections; s != NULL; s = s->next) { +- uint32_t *vma, *len; +- bfd_size_type sec_size; +- bfd_vma sec_vma; +- +- if ((s->flags & SEC_CODE) || +- ro_reloc_data_section_should_be_in_text(s)) { +- vma = &text_vma; +- len = &text_len; +- } else if (s->flags & SEC_DATA) { +- vma = &data_vma; +- len = &data_len; +- } else if (s->flags & SEC_ALLOC) { +- vma = &bss_vma; +- len = &bss_len; +- } else +- continue; +- +- sec_size = elf2flt_bfd_section_size(s); +- sec_vma = elf2flt_bfd_section_vma(s); +- +- if (sec_vma < *vma) { +- if (*len > 0) +- *len += sec_vma - *vma; +- else +- *len = sec_size; +- *vma = sec_vma; +- } else if (sec_vma + sec_size > *vma + *len) +- *len = sec_vma + sec_size - *vma; +- } +- +- if (text_len == 0) +- fatal("%s: no .text section", abs_file); +- +- text = xmalloc(text_len); +- +- if (verbose) +- printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len); +- +- /* Read input sections destined for the text output segment. +- * Includes code sections, but also includes read-only relocation +- * data sections.*/ +- for (s = abs_bfd->sections; s != NULL; s = s->next) +- if ((s->flags & SEC_CODE) || +- ro_reloc_data_section_should_be_in_text(s)) +- if (!bfd_get_section_contents(abs_bfd, s, +- text + (s->vma - text_vma), 0, +- elf2flt_bfd_section_size(s))) +- { +- fatal("read error section %s", s->name); +- } +- +- if (data_len == 0) +- fatal("%s: no .data section", abs_file); +- data = xmalloc(data_len); +- +- if (verbose) +- printf("DATA -> vma=0x%x len=0x%x\n", data_vma, data_len); +- +- if ((text_vma + text_len) != data_vma) { +- if ((text_vma + text_len) > data_vma) +- fatal("ERROR: text=0x%x overlaps data=0x%x ?", text_len, data_vma); +- if (verbose) +- printf("WARNING: data=0x%x does not directly follow text=0x%x\n", +- data_vma, text_len); +- text_len = data_vma - text_vma; +- } +- +- /* Read input sections destined for the data output segment. +- * Includes data sections, but not those read-only relocation +- * data sections already included in the text output section.*/ +- for (s = abs_bfd->sections; s != NULL; s = s->next) +- if ((s->flags & SEC_DATA) && +- !ro_reloc_data_section_should_be_in_text(s)) +- if (!bfd_get_section_contents(abs_bfd, s, +- data + (s->vma - data_vma), 0, +- elf2flt_bfd_section_size(s))) +- { +- fatal("read error section %s", s->name); +- } +- +- if (bss_vma == ~0) +- bss_vma = data_vma + data_len; +- +- /* Put common symbols in bss. */ +- bss_len += add_com_to_bss(symbol_table, number_of_symbols, bss_len); +- +- if (verbose) +- printf("BSS -> vma=0x%x len=0x%x\n", bss_vma, bss_len); +- +- if ((data_vma + data_len) != bss_vma) { +- if ((data_vma + data_len) > bss_vma) +- fatal("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?", text_len, +- data_len, bss_vma); +- if (verbose) +- printf("WARNING: bss=0x%x does not directly follow text=0x%x + data=0x%x(0x%x)\n", +- bss_vma, text_len, data_len, text_len + data_len); +- data_len = bss_vma - data_vma; +- } +- +- reloc = (uint32_t *) +- output_relocs(abs_bfd, symbol_table, number_of_symbols, &reloc_len, +- text, text_len, text_vma, data, data_len, data_vma, rel_bfd); +- +- if (reloc == NULL && verbose) +- printf("No relocations in code!\n"); +- +- text_offs = real_address_bits(text_vma); +- +- /* Fill in the binflt_flat header */ +- memcpy(hdr.magic,"bFLT",4); +- hdr.rev = htonl(FLAT_VERSION); +- hdr.entry = htonl(sizeof(hdr) + bfd_get_start_address(abs_bfd)); +- hdr.data_start = htonl(sizeof(hdr) + text_offs + text_len); +- hdr.data_end = htonl(sizeof(hdr) + text_offs + text_len +data_len); +- hdr.bss_end = htonl(sizeof(hdr) + text_offs + text_len +data_len+bss_len); +- hdr.stack_size = htonl(stack); /* FIXME */ +- hdr.reloc_start = htonl(sizeof(hdr) + text_offs + text_len +data_len); +- hdr.reloc_count = htonl(reloc_len); +- hdr.flags = htonl(0 +- | (load_to_ram || text_has_relocs ? FLAT_FLAG_RAM : 0) +- | (ktrace ? FLAT_FLAG_KTRACE : 0) +- | (pic_with_got ? FLAT_FLAG_GOTPIC : 0) +- | (docompress ? (docompress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0) +- ); +- hdr.build_date = htonl((uint32_t)get_build_date()); +- memset(hdr.filler, 0x00, sizeof(hdr.filler)); +- +- for (i=0; i