123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214 |
- 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; i<number_of_symbols; i++) {
- - printf(" NAME=%s VALUE=0x%"BFD_VMA_FMT"x\n",
- + printf(" NAME=%s VALUE=0x%x\n",
- symbol_table[i]->name, 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 <gerg@snapgear.com>
- - * 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 <os@emlix.com>
- - * (c) 2006 Support the -a (use_resolved) option for TARGET_arm.
- - * Shaun Jackman <sjackman@gmail.com>
- - * (c) 2004, Nios II support, Wentao Xu <wentao@microtronix.com>
- - * (c) 2003, H8 support, ktrace <davidm@snapgear.com>
- - * (c) 2003-2004, MicroBlaze support, John Williams <jwilliams@itee.uq.edu.au>
- - * (c) 2001-2003, arm/arm-pic/arm-big-endian support <davidm@snapgear.com>
- - * (c) 2001, v850 changes, Mile Bader <miles@lsi.nec.co.jp>
- - * (c) 2003, SuperH support, Paul Mundt <lethal@linux-sh.org>
- - * (c) 2001, zflat support <davidm@snapgear.com>
- - * (c) 2001, Changes for GOT entries Paul Dale <pauli@snapgear.com> and
- - * David McCullough <davidm@snapgear.com>
- - *
- - * 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 <kjahds@kjahds.com>
- - * (c) 1998, D. Jeff Dionne
- - * (c) 1998, The Silver Hammer Group Ltd.
- - * (c) 1996, 1997 Dionne & Associates <jeff@ryeham.ee.ryerson.ca>
- - *
- - * 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 <inttypes.h> /* All the standard PRI define times for printf */
- -#include <stdio.h> /* Userland pieces of the ANSI C standard I/O package */
- -#include <stdlib.h> /* Userland prototypes of the ANSI C std lib functions */
- -#include <stdarg.h> /* Allows va_list to exist in the these namespaces */
- -#include <string.h> /* Userland prototypes of the string handling funcs */
- -#include <strings.h>
- -#include <unistd.h> /* Userland prototypes of the Unix std system calls */
- -#include <fcntl.h> /* Flag value for file handling functions */
- -#include <time.h>
- -#include <errno.h>
- -
- -/* from $(INSTALLDIR)/include */
- -#include <bfd.h> /* Main header file for the BFD library */
- -#include <libiberty.h>
- -
- -#include "stubs.h"
- -const char *elf2flt_progname;
- -
- -/* Include the right header file for the R_xxx defines. */
- -#if defined(TARGET_arm)
- -#include <elf/arm.h>
- -#elif defined(TARGET_bfin)
- -#include <elf/bfin.h>
- -#elif defined(TARGET_h8300)
- -#include <elf/h8.h>
- -#elif defined(TARGET_m68k)
- -#include <elf/m68k.h>
- -#elif defined(TARGET_microblaze)
- -#include <elf/microblaze.h>
- -#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 <elf/nios2.h>
- -#elif defined(TARGET_sh)
- -#include <elf/sh.h>
- -#elif defined(TARGET_sparc)
- -#include <elf/sparc.h>
- -#elif defined(TARGET_v850)
- -#include <elf/v850.h>
- -#elif defined(TARGET_xtensa)
- -#include <elf/xtensa.h>
- -#elif defined(TARGET_riscv64)
- -#include <elf/riscv.h>
- -#endif
- -
- -#if defined(__MINGW32__)
- -#include <getopt.h>
- -#endif
- -
- -/* from uClinux-x.x.x/include/linux */
- -#include "flat.h" /* Binary flat header description */
- -#include "compress.h"
- -
- -#ifdef TARGET_e1
- -#include <e1.h>
- -#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; i<number_of_symbols; i++) {
- - printf(" NAME=%s VALUE=0x%"BFD_VMA_FMT"x\n",
- - symbol_table[i]->name, 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; i<number_of_symbols; i++) {
- - if (symbol_table[i]->section == 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; i<number_of_symbols; i++) {
- - if (!strcmp(symbol_table[i]->name, "_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; i<number_of_symbols; i++) {
- - if (strcmp("*COM*", symbol_table[i]->section->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 <CONST31>\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 <CONST31_PCREL>\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 <DIS29W_PCREL>\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 <DIS29W>\n");
- - goto DIS29_RELOCATION;
- - case R_E1_DIS29H:
- - DBG_E1("Handling Reloc <DIS29H>\n");
- - goto DIS29_RELOCATION;
- - case R_E1_DIS29B:
- - DBG_E1("Handling Reloc <DIS29B>\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 <IMM32_PCREL>\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 <IMM32>\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 <WORD>\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 <abs-pic-file>] [-s stack-size] "
- - "[-o <output-file>] <elf-file>\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<reloc_len; i++) reloc[i] = htonl(reloc[i]);
- -
- - if (verbose) {
- - printf("SIZE: .text=0x%04x, .data=0x%04x, .bss=0x%04x",
- - text_len, data_len, bss_len);
- - if (reloc)
- - printf(", relocs=0x%04x", reloc_len);
- - printf("\n");
- - }
- -
- - if (!ofile) {
- - ofile = xmalloc(strlen(fname) + 5 + 1); /* 5 to add suffix */
- - strcpy(ofile, fname);
- - strcat(ofile, ".bflt");
- - }
- -
- - if ((fd = open (ofile, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0744)) < 0)
- - fatal_perror("Can't open output file %s", ofile);
- -
- - if (write(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
- - fatal_perror("Couldn't write file %s", ofile);
- - close(fd);
- -
- - if (fopen_stream_u(&gf, ofile, "a" BINARY_FILE_OPTS))
- - fatal_perror("Can't open file %s for writing", ofile);
- -
- - if (docompress == 1)
- - reopen_stream_compressed(&gf);
- -
- - /* Fill in any hole at the beginning of the text segment. */
- - if (verbose)
- - printf("ZERO before text len=0x%x\n", text_offs);
- - write_zeroes(text_offs, &gf);
- -
- - /* Write the text segment. */
- - fwrite_stream(text, text_len, 1, &gf);
- -
- - if (docompress == 2)
- - reopen_stream_compressed(&gf);
- -
- - /* Write the data segment. */
- - fwrite_stream(data, data_len, 1, &gf);
- -
- - if (reloc)
- - fwrite_stream(reloc, reloc_len * 4, 1, &gf);
- -
- - fclose_stream(&gf);
- -
- - exit(0);
- -}
- -
- -
- -/*
- - * this __MUST__ be at the VERY end of the file - do NOT move!!
- - *
- - * Local Variables:
- - * c-basic-offset: 4
- - * tab-width: 8
- - * end:
- - * vi: tabstop=8 shiftwidth=4 textwidth=79 noexpandtab
- - */
|