Jivin Mike Frysinger lays it down ... > Signed-off-by: Mike Frysinger <vap...@gentoo.org>
Applied, Thanks, Davidm > --- > elf2flt.c | 337 > ++++++++++++++++++++++++------------------------------------- > 1 files changed, 130 insertions(+), 207 deletions(-) > > diff --git a/elf2flt.c b/elf2flt.c > index 889ea98..9b1ea37 100644 > --- a/elf2flt.c > +++ b/elf2flt.c > @@ -102,13 +102,6 @@ > #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) > @@ -152,6 +145,9 @@ int use_resolved = 0; /* If true, get the value of symbol > references from */ > /* versions of GNU ld will give you a fully resolved */ > /* output file with relocation entries). */ > > +/* Set if the text section contains any relocations. If it does, we must > + set the load_to_ram flag. */ > +int text_has_relocs = 0; > const char *progname, *filename; > int lineno; > > @@ -335,51 +331,52 @@ weak_und_symbol(const char *reloc_section_name, > } > > static int > -bfin_set_reloc (uint32_t *reloc, > - const char *reloc_section_name, > +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) > + int sp, int32_t offset) > { > - unsigned int type; > + unsigned int type = 0; > 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; > + if (strstr (reloc_section_name, "stack")) { > + if (verbose) > + printf ("Stack-relative reloc, offset %08lx\n", offset); > + /* This must be a stack_start reloc for stack checking. */ > + type = 1; > } > - > - val = (offset & ((1 << 26) - 1)) << 6; > - val |= (sp & (1 << 3) - 1) << 3; > - val |= (hilo & 1) << 2; > - val |= (type & (1 << 2) - 1); > + val = (offset & ((1 << 26) - 1)); > + val |= (sp & (1 << 3) - 1) << 26; > + val |= type << 29; > *reloc = val; > return 0; > } > -#endif > > +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 = bfd_section_vma(compare_relocs_bfd, > + (*(ra->sym_ptr_ptr))->section); > + b_vma = bfd_section_vma(compare_relocs_bfd, > + (*(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 > > uint32_t * > output_relocs ( > @@ -406,6 +403,9 @@ output_relocs ( > 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,synbols=0x%x,number_of_symbols=%d" > @@ -505,6 +505,10 @@ dump_symbols(symbols, number_of_symbols); > __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; > int relocation_needed = 0; > @@ -603,7 +607,7 @@ dump_symbols(symbols, number_of_symbols); > * Fixup offset in the actual section. > */ > addstr[0] = 0; > -#ifndef TARGET_e1 > +#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; > @@ -723,6 +727,76 @@ dump_symbols(symbols, number_of_symbols); > continue; > default: > goto bad_resolved_reloc; > +#elif defined TARGET_bfin > + case R_rimm16: > + case R_luimm16: > + sym_vma = bfd_section_vma(abs_bfd, > 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_rimm16 && > (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, section_vma + > q->address)) > + bad_relocs++; > + if (a->flags & SEC_CODE) > + text_has_relocs = 1; > + flat_reloc_count++; > + break; > + > + case R_huimm16: > + sym_vma = bfd_section_vma(abs_bfd, > 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 + 2) * sizeof (uint32_t))); > + if ((0xFFFF0000 & sym_addr) != > persistent_data) { > + if (verbose) > + printf ("New persistent > data for %08lx\n", sym_addr); > + persistent_data = 0xFFFF0000 & > sym_addr; > + flat_relocs[flat_reloc_count++] > + = (sym_addr >> 16) | (3 << > 26); > + } > + > + if (bfin_set_reloc (flat_relocs + > flat_reloc_count, > + sym_section->name, > sym_name, > + (*(q->sym_ptr_ptr)), > + 1, section_vma + > q->address)) > + bad_relocs++; > + if (a->flags & SEC_CODE) > + text_has_relocs = 1; > + flat_reloc_count++; > + break; > + > + case R_byte4_data: > + sym_vma = bfd_section_vma(abs_bfd, > 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; > #else > default: > /* The default is to assume that the > @@ -1181,112 +1255,6 @@ NIOS2_RELOC_ERR: > 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: > @@ -1536,48 +1504,6 @@ DIS29_RELOCATION: > *(uint32_t *)r_mem = htonl(hl); > else > *(uint32_t *)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) { > @@ -1604,7 +1530,17 @@ DIS29_RELOCATION: > exit(0); > break; > } > -#else /* ! TARGET_arm && ! TARGET_e1 */ > +#elif defined TARGET_bfin > + 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 */ > + bfd_putl16 (sym_addr, sectionp + > q->address); > + } else if ((*p)->howto->type == R_byte4_data) { > + bfd_putl32 (sym_addr, sectionp + > q->address); > + } > +#else /* ! TARGET_arm && ! TARGET_e1 && ! TARGET_bfin */ > > switch (q->howto->type) { > #ifdef TARGET_v850 > @@ -1657,19 +1593,6 @@ DIS29_RELOCATION: > #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 " > @@ -1718,7 +1641,7 @@ DIS29_RELOCATION: > } > #endif > flat_reloc_count++; > -#endif > +#endif //TARGET_bfin > relocation_needed = 0; > pflags = 0; > } > @@ -2065,7 +1988,7 @@ int main(int argc, char *argv[]) > 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) > + | (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) > -- > 1.6.2.5 > > _______________________________________________ > uClinux-dev mailing list > uClinux-dev@uclinux.org > http://mailman.uclinux.org/mailman/listinfo/uclinux-dev > This message was resent by uclinux-dev@uclinux.org > To unsubscribe see: > http://mailman.uclinux.org/mailman/options/uclinux-dev > -- David McCullough, david_mccullo...@securecomputing.com, Ph:+61 734352815 McAfee - SnapGear http://www.snapgear.com http://www.uCdot.org _______________________________________________ uClinux-dev mailing list uClinux-dev@uclinux.org http://mailman.uclinux.org/mailman/listinfo/uclinux-dev This message was resent by uclinux-dev@uclinux.org To unsubscribe see: http://mailman.uclinux.org/mailman/options/uclinux-dev