Jivin Mike Frysinger lays it down ...
> Signed-off-by: Mike Frysinger <[email protected]>
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
> [email protected]
> http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
> This message was resent by [email protected]
> To unsubscribe see:
> http://mailman.uclinux.org/mailman/options/uclinux-dev
>
--
David McCullough, [email protected], Ph:+61 734352815
McAfee - SnapGear http://www.snapgear.com http://www.uCdot.org
_______________________________________________
uClinux-dev mailing list
[email protected]
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by [email protected]
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev