summaryrefslogtreecommitdiffstats
path: root/toolchain/elf2flt/elf2flt/elf2flt.c
diff options
context:
space:
mode:
Diffstat (limited to 'toolchain/elf2flt/elf2flt/elf2flt.c')
-rw-r--r--toolchain/elf2flt/elf2flt/elf2flt.c2152
1 files changed, 0 insertions, 2152 deletions
diff --git a/toolchain/elf2flt/elf2flt/elf2flt.c b/toolchain/elf2flt/elf2flt/elf2flt.c
deleted file mode 100644
index 65a116c6c..000000000
--- a/toolchain/elf2flt/elf2flt/elf2flt.c
+++ /dev/null
@@ -1,2152 +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) 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 <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>
-#ifndef WIN32
-#include <netinet/in.h> /* Consts and structs defined by the internet system */
-#define BINARY_FILE_OPTS
-#else
-#include <winsock2.h>
-#define BINARY_FILE_OPTS "b"
-#endif
-
-/* from $(INSTALLDIR)/include */
-#include <bfd.h> /* Main header file for the BFD library */
-
-#if defined(TARGET_h8300)
-#include <elf/h8.h> /* TARGET_* ELF support for the BFD library */
-#elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(TARGET_nios) || defined(TARGET_nios2)
-#include "cygwin-elf.h" /* Cygwin uses a local copy */
-#elif defined(TARGET_microblaze)
-#include <elf/microblaze.h> /* TARGET_* ELF support for the BFD library */
-#elif defined(TARGET_bfin)
-#include "elf/bfin.h"
-#else
-#include <elf.h> /* TARGET_* ELF support for the BFD library */
-#endif
-
-#if defined(__MINGW32__)
-#include <getopt.h>
-#endif
-
-/* from uClinux-x.x.x/include/linux */
-#include "flat.h" /* Binary flat header description */
-
-#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"
-#define FLAT_RELOC_TYPE_TEXT 0
-#define FLAT_RELOC_TYPE_DATA 1
-#define FLAT_RELOC_TYPE_BSS 2
-#define FLAT_RELOC_TYPE_STACK 3
-#define FLAT_RELOC_PART_LO 0
-#define FLAT_RELOC_PART_HI 1
-#define PCREL24_MAGIC_OFFSET -1
-#elif defined(TARGET_nios)
-#define ARCH "nios"
-#elif defined(TARGET_nios2)
-#define ARCH "nios2"
-#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
-
-
-int verbose = 0; /* extra output when running */
-int pic_with_got = 0; /* do elf/got processing with PIC code */
-int load_to_ram = 0; /* instruct loader to allocate everything into RAM */
-int ktrace = 0; /* instruct loader output kernel trace on load */
-int compress = 0; /* 1 = compress everything, 2 = compress data only */
-int use_resolved = 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). */
-
-const char *progname, *filename;
-int lineno;
-
-int nerrors = 0;
-int nwarnings = 0;
-
-static char where[200];
-
-enum {
- /* Use exactly one of these: */
- E_NOFILE = 0, /* "progname: " */
- E_FILE = 1, /* "filename: " */
- E_FILELINE = 2, /* "filename:lineno: " */
- E_FILEWHERE = 3, /* "filename:%s: " -- set %s with ewhere() */
-
- /* Add in any of these with |': */
- E_WARNING = 0x10,
- E_PERROR = 0x20
-};
-
-void ewhere (const char *format, ...);
-void einfo (int type, const char *format, ...);
-
-
-void
-ewhere (const char *format, ...) {
- va_list args;
- va_start (args, format);
- vsprintf (where, format, args);
- va_end (args);
-}
-
-
-void
-einfo (int type, const char *format, ...) {
- va_list args;
-
- switch (type & 0x0f) {
- case E_NOFILE:
- fprintf (stderr, "%s: ", progname);
- break;
- case E_FILE:
- fprintf (stderr, "%s: ", filename);
- break;
- case E_FILELINE:
- ewhere ("%d", lineno);
- /* fall-through */
- case E_FILEWHERE:
- fprintf (stderr, "%s:%s: ", filename, where);
- break;
- }
-
- if (type & E_WARNING) {
- fprintf (stderr, "warning: ");
- nwarnings++;
- } else {
- nerrors++;
- }
-
- va_start (args, format);
- vfprintf (stderr, format, args);
- va_end (args);
-
- if (type & E_PERROR)
- perror ("");
- else
- fprintf (stderr, "\n");
-}
-
-
-asymbol**
-get_symbols (bfd *abfd, long *num)
-{
- long 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 = (asymbol **) malloc (storage_needed);
-
- number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
-
- if (number_of_symbols < 0)
- abort ();
-
- *num = number_of_symbols;
- return symbol_table;
-}
-
-
-
-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%x\n", symbol_table[i]->name,
- symbol_table[i]->value);
- }
- printf("\n");
- return(0);
-}
-
-
-
-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;
-}
-
-
-
-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;
-}
-
-
-
-long
-add_com_to_bss(asymbol **symbol_table, long number_of_symbols, long bss_len)
-{
- long i, comsize;
- long 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, int hilo, int32_t offset)
-{
- unsigned int type;
- uint32_t val;
-
- if (strstr (reloc_section_name, "text"))
- type = FLAT_RELOC_TYPE_TEXT;
- else if (strstr (reloc_section_name, "data"))
- type = FLAT_RELOC_TYPE_DATA;
- else if (strstr (reloc_section_name, "bss"))
- type = FLAT_RELOC_TYPE_BSS;
- else if (strstr (reloc_section_name, "stack"))
- type = FLAT_RELOC_TYPE_STACK;
- else if (symbol->flags & BSF_WEAK){
- /* weak symbol support ... if a weak symbol is undefined at the
- end of a final link, it should return 0 rather than error
- We will assume text section for the moment.
- */
- type = FLAT_RELOC_TYPE_TEXT;
- } else if (strstr (reloc_section_name, "*ABS*")){
- /* (A data section initialization of something in the shared libc's text section
- does not resolve - i.e. a global pointer to function initialized with
- a libc function).
- The text section here is appropriate as the section information
- of the shared library is lost. The loader will do some calcs.
- */
- type = FLAT_RELOC_TYPE_TEXT;
- } else {
- printf ("Unknown Type - relocation for %s in bad section - %s\n", sym_name, reloc_section_name);
- return 1;
- }
-
- val = (offset & ((1 << 26) - 1)) << 6;
- val |= (sp & (1 << 3) - 1) << 3;
- val |= (hilo & 1) << 2;
- val |= (type & (1 << 2) - 1);
- *reloc = val;
- return 0;
-}
-#endif
-
-
-uint32_t *
-output_relocs (
- bfd *abs_bfd,
- asymbol **symbols,
- int number_of_symbols,
- unsigned long *n_relocs,
- unsigned char *text, int text_len, unsigned long text_vma,
- unsigned char *data, int data_len, unsigned long 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[16];
- long 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;
-
-#if 0
- printf("%s(%d): output_relocs(abs_bfd=%d,synbols=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);
-#endif
-
- *n_relocs = 0;
- flat_relocs = NULL;
- flat_reloc_count = 0;
- rc = 0;
- pflags = 0;
-
- /* 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) {
- unsigned long *lp = (unsigned long *)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 %d entries (%d bytes)\n",
- got_size/sizeof(unsigned long), got_size);
-#ifdef TARGET_m68k
- if (got_size > GOT_LIMIT) {
- fprintf(stderr, "GOT too large: %d bytes (limit = %d bytes)\n",
- got_size, GOT_LIMIT);
- exit(1);
- }
-#endif
- }
-
- for (a = abs_bfd->sections; (a != (asection *) NULL); a = a->next) {
- section_vma = bfd_section_vma(abs_bfd, a);
-
- if (verbose)
- printf("SECTION: %s [0x%x]: flags=0x%x vma=0x%x\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 data sections if we are PIC/GOT.
- * otherwise do text as well
- */
- if (!pic_with_got && (a->flags & SEC_CODE))
- 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 [0x%x]: flags=0x%x vma=0x%x\n", r->name, r,
- r->flags, bfd_section_vma(abs_bfd, 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=0x%x\n",
- __FILE__, __LINE__, r->name);
- continue;
- }
-
- symb = get_symbols(rel_bfd, &nsymb);
- relpp = (arelent **) 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 {
- for (p = relpp; (relcount && (*p != NULL)); p++, relcount--) {
- unsigned char *r_mem;
- int relocation_needed = 0;
-
-#ifdef TARGET_microblaze
- /* The MICROBLAZE_XX_NONE relocs can be skipped.
- They represent PC relative branches that the
- linker has already resolved */
-
- switch ((*p)->howto->type)
- {
- case R_MICROBLAZE_NONE:
- case R_MICROBLAZE_64_NONE:
- continue;
- }
-#endif /* TARGET_microblaze */
-
-#ifdef TARGET_v850
- /* Skip this relocation entirely if possible (we
- do this early, before doing any other
- processing on it). */
- switch ((*p)->howto->type) {
-#ifdef R_V850_9_PCREL
- case R_V850_9_PCREL:
-#endif
-#ifdef R_V850_22_PCREL
- case R_V850_22_PCREL:
-#endif
-#ifdef R_V850_SDA_16_16_OFFSET
- case R_V850_SDA_16_16_OFFSET:
-#endif
-#ifdef R_V850_SDA_15_16_OFFSET
- case R_V850_SDA_15_16_OFFSET:
-#endif
-#ifdef R_V850_ZDA_15_16_OFFSET
- case R_V850_ZDA_15_16_OFFSET:
-#endif
-#ifdef R_V850_TDA_6_8_OFFSET
- case R_V850_TDA_6_8_OFFSET:
-#endif
-#ifdef R_V850_TDA_7_8_OFFSET
- case R_V850_TDA_7_8_OFFSET:
-#endif
-#ifdef R_V850_TDA_7_7_OFFSET
- case R_V850_TDA_7_7_OFFSET:
-#endif
-#ifdef R_V850_TDA_16_16_OFFSET
- case R_V850_TDA_16_16_OFFSET:
-#endif
-#ifdef R_V850_TDA_4_5_OFFSET
- case R_V850_TDA_4_5_OFFSET:
-#endif
-#ifdef R_V850_TDA_4_4_OFFSET
- case R_V850_TDA_4_4_OFFSET:
-#endif
-#ifdef R_V850_SDA_16_16_SPLIT_OFFSET
- case R_V850_SDA_16_16_SPLIT_OFFSET:
-#endif
-#ifdef R_V850_CALLT_6_7_OFFSET
- case R_V850_CALLT_6_7_OFFSET:
-#endif
-#ifdef R_V850_CALLT_16_16_OFFSET
- case R_V850_CALLT_16_16_OFFSET:
-#endif
- /* 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;
-#ifndef TARGET_e1
- 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) {
- int r2_type;
-#ifdef TARGET_v850
- 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_arm)
- case R_ARM_ABS32:
- relocation_needed = 1;
- break;
- case R_ARM_REL32:
- case R_ARM_THM_PC11:
- case R_ARM_THM_PC22:
- 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;
-#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;
- 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. */
- sym_reloc_size = bfd_get_reloc_size(q->howto);
-
-#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 = bfd_section_vma(abs_bfd, 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%x, address=0x%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,
- *(unsigned long *)r_mem);
- sym_vma = bfd_section_vma(abs_bfd, 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%x, address=0x%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,
- *(unsigned long *)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_32:
- relocation_needed = 1;
- sym_vma = bfd_section_vma(abs_bfd, sym_section);
- sym_addr += sym_vma + q->addend;
- break;
-#if defined(R_V850_ZDA_16_16_OFFSET) || defined(R_V850_ZDA_16_16_SPLIT_OFFSET)
-#ifdef R_V850_ZDA_16_16_OFFSET
- case R_V850_ZDA_16_16_OFFSET:
-#endif
-#ifdef R_V850_ZDA_16_16_SPLIT_OFFSET
- case R_V850_ZDA_16_16_SPLIT_OFFSET:
-#endif
- /* Can't support zero-relocations. */
- printf ("ERROR: %s+0x%x: zero relocations not supported\n",
- sym_name, q->addend);
- continue;
-#endif /* R_V850_ZDA_16_16_OFFSET || R_V850_ZDA_16_16_SPLIT_OFFSET */
-#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 = bfd_section_vma(abs_bfd, 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 = bfd_section_vma(abs_bfd, sym_section);
- sym_addr += sym_vma + q->addend;
- break;
- case R_H8_DIR32:
- case R_H8_DIR32A16: /* currently 32, could be made 16 */
- 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 = bfd_section_vma(abs_bfd, sym_section);
- sym_addr += sym_vma + q->addend;
- break;
- case R_H8_PCREL16:
- 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:
- 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:
- /* The symbol is split over two consecutive instructions.
- Flag this to the flat loader by setting the high bit of
- the relocation symbol. */
- {
- unsigned char *p = r_mem;
- unsigned long offset;
- pflags=0x80000000;
-
- /* work out the relocation */
- sym_vma = bfd_section_vma(abs_bfd, sym_section);
- /* grab any offset from the text */
- offset = (p[2]<<24) + (p[3] << 16) + (p[6] << 8) + (p[7]);
- /* Update the address */
- sym_addr += offset + sym_vma + q->addend;
- /* Write relocated pointer back */
- p[2] = (sym_addr >> 24) & 0xff;
- p[3] = (sym_addr >> 16) & 0xff;
- p[6] = (sym_addr >> 8) & 0xff;
- p[7] = sym_addr & 0xff;
-
- /* create a new reloc entry */
- flat_relocs = realloc(flat_relocs,
- (flat_reloc_count + 1) * sizeof(uint32_t));
- flat_relocs[flat_reloc_count] = pflags | (section_vma + q->address);
- flat_reloc_count++;
- relocation_needed = 0;
- pflags = 0;
- sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
- bfd_section_vma(abs_bfd, sym_section));
- if (verbose)
- printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
- "section=%s size=%d "
- "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%x\n", flat_reloc_count,
- section_vma + q->address);
-
- continue;
- }
- case R_MICROBLAZE_32:
- {
- unsigned char *p = r_mem;
- unsigned long offset;
-
- /* grab any offset from the text */
- offset = (p[0]<<24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
- sym_vma = bfd_section_vma(abs_bfd, sym_section);
- /* This is a horrible kludge. For some
- reason, *sometimes* the offset is in
- both addend and the code. Detect
- it, and cancel the effect. Otherwise
- the offset gets added twice - ouch.
- There should be a better test
- for this condition, based on the
- BFD data structures */
- if(offset==q->addend)
- offset=0;
-
- sym_addr += offset + sym_vma + q->addend;
- relocation_needed = 1;
- break;
- }
- case R_MICROBLAZE_64_PCREL:
- sym_vma = 0;
- //sym_addr = (*(q->sym_ptr_ptr))->value;
- 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;
-
-#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 = bfd_section_vma(abs_bfd, 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 = bfd_section_vma(abs_bfd, 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 %d\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 = 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 = bfd_section_vma(abs_bfd, 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%x symbol=%s%s "
- "section=%s size=%d "
- "fixup=0x%x (reloc=0x%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%x symbol=%s%s "
- "section=%s size=%d "
- "fixup=0x%x (reloc=0x%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%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 = bfd_section_vma(abs_bfd, 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(*(unsigned long *)r_mem)
- & 0xc0000000
- );
- break;
- case R_SPARC_HI22:
- relocation_needed = 1;
- pflags = 0x80000000;
- sym_vma = bfd_section_vma(abs_bfd, sym_section);
- sym_addr += sym_vma + q->addend;
- sym_addr |= (
- htonl(*(unsigned long *)r_mem)
- & 0xffc00000
- );
- break;
- case R_SPARC_LO10:
- relocation_needed = 1;
- pflags = 0x40000000;
- sym_vma = bfd_section_vma(abs_bfd, sym_section);
- sym_addr += sym_vma + q->addend;
- sym_addr &= 0x000003ff;
- sym_addr |= (
- htonl(*(unsigned long *)r_mem)
- & 0xfffffc00
- );
- break;
-#endif /* TARGET_sparc */
-
-#ifdef TARGET_bfin
- case R_pcrel12_jump:
- case R_pcrel12_jump_s:
- case R_pcrel24:
- case R_pcrel24_jump_l:
- case R_pcrel24_jump_x:
- case R_pcrel24_call_x:
- case R_pcrel10:
- case R_pcrel11:
- case R_pcrel5m2:
- sym_addr += q->addend;// get the symbol addr
- sym_vma = bfd_section_vma(abs_bfd, sym_section);
- sym_addr -= q->address; // make it PC relative
- // implicitly assumes code section and symbol section are same
- break;
- case R_got:
- /* Ignore these. */
- break;
-
- case R_rimm16:
- sym_addr += q->addend;
- if(weak_und_symbol(sym_section->name, (*(q->sym_ptr_ptr))))
- continue;
- if(0xFFFF0000 & sym_addr){
- fprintf (stderr, "Relocation overflow for rN = %s\n",sym_name);
- bad_relocs++;
- }
- 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)),
- 0, FLAT_RELOC_PART_LO,
- section_vma + q->address))
- bad_relocs++;
- flat_reloc_count++;
- break;
-
- case R_luimm16:
- case R_huimm16:
- {
- unsigned int sp;
- unsigned int reloc_count_incr;
- unsigned int hi_lo;
-
- if (q->howto->type == R_luimm16)
- hi_lo = FLAT_RELOC_PART_LO;
- else
- hi_lo = FLAT_RELOC_PART_HI;
-
- sym_addr += q->addend;
-
- flat_relocs = (uint32_t *)
- (realloc (flat_relocs, (flat_reloc_count + 2) * sizeof (uint32_t)));
- reloc_count_incr = 1;
- if (weak_und_symbol (sym_section->name, (*(q->sym_ptr_ptr))))
- continue;
- if (0xFFFF0000 & sym_addr) {
- /* value is > 16 bits - use an extra field */
- /* see if we have already output that symbol */
- /* reloc may be addend from symbol and */
- /* we can only store 16 bit offsets */
- sp = 1;
- if ((*(q->sym_ptr_ptr))->udata.i == 0
- || flat_relocs[(*(q->sym_ptr_ptr))->udata.i] != sym_addr
- || ((*(q->sym_ptr_ptr))->udata.i & 0xFFFF0000))
- {
- reloc_count_incr = 2;
- flat_relocs[flat_reloc_count + 1] = sym_addr;
- (*(q->sym_ptr_ptr))->udata.i = flat_reloc_count + 1;
- sym_addr = 0; // indication to loader to read next
- } else{
- sym_addr = (*(q->sym_ptr_ptr))->udata.i;
- }
- } else {
- sp = 0;
- }
-
- if (bfin_set_reloc (flat_relocs + flat_reloc_count,
- sym_section->name, sym_name,
- (*(q->sym_ptr_ptr)),
- sp, hi_lo,
- section_vma + q->address))
- bad_relocs++;
- flat_reloc_count += reloc_count_incr;
- break;
- }
- case R_byte4_data:
- sym_addr += 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, FLAT_RELOC_PART_LO,
- section_vma + q->address))
- bad_relocs++;
-
- flat_reloc_count++;
- break;
-
-#endif //TARGET_bfin
-
-#ifdef TARGET_sh
- case R_SH_DIR32:
- relocation_needed = 1;
- sym_vma = bfd_section_vma(abs_bfd, 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 = bfd_section_vma(abs_bfd, 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 = bfd_section_vma(abs_bfd, 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 = bfd_section_vma(abs_bfd, 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 = bfd_section_vma(abs_bfd, 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 = bfd_section_vma(abs_bfd, 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 = bfd_section_vma(abs_bfd, 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 = bfd_section_vma(abs_bfd, 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 %d\n", (*p)->howto->type);
- bad_relocs++;
- continue;
- }
- }
-
- sprintf(&addstr[0], "+0x%x", sym_addr - (*(q->sym_ptr_ptr))->value -
- bfd_section_vma(abs_bfd, sym_section));
-
-
- /*
- * for full elf relocation we have to write back the
- * start_code relative value to use.
- */
- if (!pic_with_got) {
-#if defined(TARGET_arm)
- union {
- unsigned char c[4];
- unsigned long l;
- } tmp;
- long 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 = *(unsigned long *)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)
- *(unsigned long *)r_mem = htonl(hl);
- else
- *(unsigned long *)r_mem = tmp.l;
-
-#elif defined(TARGET_bfin)
- if ((*p)->howto->type == R_pcrel24
- || (*p)->howto->type == R_pcrel24_jump_l
- || (*p)->howto->type == R_pcrel24_jump_x
- || (*p)->howto->type == R_pcrel24_call_x)
- {
- sym_addr += 2*-1*PCREL24_MAGIC_OFFSET;
- *((unsigned short *)(sectionp + q->address) + 1 + PCREL24_MAGIC_OFFSET)
- = (sym_addr >> 1) & 0xffff;
- *((unsigned short *)(sectionp + q->address) + PCREL24_MAGIC_OFFSET)
- = (0xff00 & *((unsigned short *) (sectionp + q->address) + PCREL24_MAGIC_OFFSET)
- | ((sym_addr >> 17) & 0xff));
- } else if ((*p)->howto->type == R_byte4_data) {
- *((uint32_t *)(sectionp + q->address)) = sym_addr;
- } else if ((*p)->howto->type == R_pcrel12_jump
- || (*p)->howto->type == R_pcrel12_jump_s) {
- *((unsigned short *)(sectionp + q->address))
- = (0xf000 & *((unsigned short *)(sectionp + q->address))
- | ((sym_addr >> 1) & 0xfff));
- } else if ((*p)->howto->type == R_pcrel10) {
- *((unsigned short *)(sectionp + q->address))
- = (~0x3ff & *((unsigned short *)(sectionp + q->address))
- | ((sym_addr >> 1) & 0x3ff));
- } else if ((*p)->howto->type == R_rimm16
- || (*p)->howto->type == R_huimm16
- || (*p)->howto->type == R_luimm16) {
- /* for l and h we set the lower 16 bits which is only when it will be used */
- *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
- } else if ((*p)->howto->type == R_pcrel5m2) {
- *((unsigned short *)(sectionp + q->address))
- = (0xfff0 & *((unsigned short *)(sectionp + q->address))
- | ((sym_addr >> 1) & 0xf));
- } else if ((*p)->howto->type == R_pcrel11){
- *((unsigned short *)(sectionp + q->address))
- = (0xfc00 & *((unsigned short *)(sectionp + q->address))
- | ((sym_addr >> 1) & 0x3ff));
- } else if (0xE0 <= (*p)->howto->type && 0xF3 >= (*p)->howto->type) {
- //arith relocs dont generate a real relocation
- } else {
- printf("Blackfin relocation fail for reloc type: 0x%x\n", (*p)->howto->type);
- }
-#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:
- printf("ERROR:Unhandled Relocation. Exiting...\n");
- exit(0);
- break;
- }
-#else /* ! TARGET_arm && ! TARGET_e1 */
-
- 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 */
- }
-
-#ifdef TARGET_bfin
- else {
- if ((*p)->howto->type == R_rimm16
- || (*p)->howto->type == R_huimm16
- || (*p)->howto->type == R_luimm16)
- {
- /* for l and h we set the lower 16 bits which is only when it will be used */
- *((unsigned short *) (sectionp + q->address)) = (unsigned short) sym_addr;
- } else if ((*p)->howto->type == R_byte4_data) {
- *((uint32_t *)(sectionp + q->address)) = sym_addr;
- }
- }
-#endif
- if (verbose)
- printf(" RELOC[%d]: offset=0x%x symbol=%s%s "
- "section=%s size=%d "
- "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);
-
- /*
- * Create relocation entry (PC relative doesn't need this).
- */
- if (relocation_needed) {
-#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);
-
- if (verbose)
- printf("reloc[%d] = 0x%x\n", flat_reloc_count,
- 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
- 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) {
- printf("%d bad relocs\n", bad_relocs);
- exit(1);
- }
-
- if (rc < 0)
- return(0);
-
- *n_relocs = flat_reloc_count;
- return flat_relocs;
-}
-
-
-
-static char * program;
-
-static void usage(void)
-{
- fprintf(stderr, "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",
- program);
- fprintf(stderr, "Compiled for " ARCH " architecture\n\n");
- exit(2);
-}
-
-
-/* Write NUM zeroes to STREAM. */
-static void write_zeroes (unsigned long num, FILE *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(zeroes, sizeof(zeroes), 1, stream);
- num -= sizeof(zeroes);
- }
- if (num > 0)
- fwrite(zeroes, num, 1, stream);
- }
-}
-
-
-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;
- char cmd[1024];
- FILE *gf = NULL;
-
- asymbol **symbol_table;
- long number_of_symbols;
-
- unsigned long data_len = 0;
- unsigned long bss_len = 0;
- unsigned long text_len = 0;
- unsigned long reloc_len;
-
- unsigned long data_vma = ~0;
- unsigned long bss_vma = ~0;
- unsigned long text_vma = ~0;
-
- unsigned long text_offs;
-
- void *text;
- void *data;
- uint32_t *reloc;
-
- struct flat_hdr hdr;
-
- int gf_is_pipe = 0;
-
- program = argv[0];
- progname = argv[0];
-
- if (argc < 2)
- usage();
-
- if (sizeof(hdr) != 64) {
- fprintf(stderr,
- "Potential flat header incompatibility detected\n"
- "header size should be 64 but is %d\n",
- sizeof(hdr));
- exit(64);
- }
-
-#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, "avzdrkp:s:o:R:")) != -1) {
- switch (opt) {
- case 'v':
- verbose++;
- break;
- case 'r':
- load_to_ram++;
- break;
- case 'k':
- ktrace++;
- break;
- case 'z':
- compress = 1;
- break;
- case 'd':
- compress = 2;
- break;
- case 'p':
- pfile = optarg;
- break;
- case 'o':
- ofile = optarg;
- break;
- case 'a':
- use_resolved = 1;
- break;
- case 's':
- stack = atoi(optarg);
- break;
- case 'R':
- rel_file = optarg;
- break;
- default:
- fprintf(stderr, "%s Unknown option\n", argv[0]);
- usage();
- 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;
-
- filename = 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))) {
- fprintf(stderr, "Can't open %s\n", rel_file);
- exit(1);
- }
-
- if (bfd_check_format (rel_bfd, bfd_object) == 0) {
- fprintf(stderr, "File is not an object file\n");
- exit(2);
- }
-
- if (abs_file == rel_file)
- abs_bfd = rel_bfd; /* one file does all */
- else {
- if (!(abs_bfd = bfd_openr(abs_file, 0))) {
- fprintf(stderr, "Can't open %s\n", abs_file);
- exit(1);
- }
-
- if (bfd_check_format (abs_bfd, bfd_object) == 0) {
- fprintf(stderr, "File is not an object file\n");
- exit(2);
- }
- }
-
- if (! (bfd_get_file_flags(rel_bfd) & HAS_RELOC)) {
- fprintf (stderr, "%s: Input file contains no relocation info\n", rel_file);
- exit (2);
- }
-
- if (use_resolved && !(bfd_get_file_flags(abs_bfd) & EXEC_P)) {
- /* `Absolute' file is not absolute, so neither are address
- contained therein. */
- fprintf (stderr,
- "%s: `-a' option specified with non-fully-resolved input file\n",
- bfd_get_filename (abs_bfd));
- exit (2);
- }
-
- 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) {
- unsigned long *vma, *len;
- bfd_size_type sec_size;
- bfd_vma sec_vma;
-
- if (s->flags & SEC_CODE) {
- 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 = bfd_section_size(abs_bfd, s);
- sec_vma = bfd_section_vma(abs_bfd, 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) {
- fprintf (stderr, "%s: no .text section", abs_file);
- exit (2);
- }
-
- text = malloc(text_len);
-
- if (verbose)
- printf("TEXT -> vma=0x%x len=0x%x\n", text_vma, text_len);
-
- /* Read in all text sections. */
- for (s = abs_bfd->sections; s != NULL; s = s->next)
- if (s->flags & SEC_CODE)
- if (!bfd_get_section_contents(abs_bfd, s,
- text + (s->vma - text_vma), 0,
- bfd_section_size(abs_bfd, s)))
- {
- fprintf(stderr, "read error section %s\n", s->name);
- exit(2);
- }
-
- if (data_len == 0) {
- fprintf (stderr, "%s: no .data section", abs_file);
- exit (2);
- }
- data = malloc(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) {
- printf("ERROR: text=0x%x overlaps data=0x%x ?\n", text_len, data_vma);
- exit(1);
- }
- 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 in all data sections. */
- for (s = abs_bfd->sections; s != NULL; s = s->next)
- if (s->flags & SEC_DATA)
- if (!bfd_get_section_contents(abs_bfd, s,
- data + (s->vma - data_vma), 0,
- bfd_section_size(abs_bfd, s)))
- {
- fprintf(stderr, "read error section %s\n", s->name);
- exit(2);
- }
-
- /* 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) {
- printf("ERROR: text=0x%x + data=0x%x overlaps bss=0x%x ?\n", text_len,
- data_len, bss_vma);
- exit(1);
- }
- 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 = 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)
- 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 ? FLAT_FLAG_RAM : 0)
- | (ktrace ? FLAT_FLAG_KTRACE : 0)
- | (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
- | (compress ? (compress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
- );
- hdr.build_date = htonl((unsigned long)time(NULL));
- 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 = malloc(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) {
- fprintf (stderr, "Can't open output file %s\n", ofile);
- exit(4);
- }
-
- write(fd, &hdr, sizeof(hdr));
- close(fd);
-
- /*
- * get the compression command ready
- */
- sprintf(cmd, "gzip -f -9 >> %s", ofile);
-
-#define START_COMPRESSOR do { \
- if (gf) \
- if (gf_is_pipe) \
- pclose(gf); \
- else \
- fclose(gf); \
- if (!(gf = popen(cmd, "w" BINARY_FILE_OPTS))) { \
- fprintf(stderr, "Can't run cmd %s\n", cmd); \
- exit(4); \
- } \
- gf_is_pipe = 1; \
- } while (0)
-
- gf = fopen(ofile, "ab"); /* Add 'b' to support non-posix (ie windows) */
- if (!gf) {
- fprintf(stderr, "Can't open file %s for writing\n", ofile); \
- exit(4);
- }
-
- if (compress == 1)
- START_COMPRESSOR;
-
- /* 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(text, text_len, 1, gf);
-
- if (compress == 2)
- START_COMPRESSOR;
-
- /* Write the data segment. */
- fwrite(data, data_len, 1, gf);
-
- if (reloc)
- fwrite(reloc, reloc_len * 4, 1, gf);
-
- if(gf_is_pipe)
- pclose(gf);
- else
- fclose(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
- */