Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 115 additions & 1 deletion elf2flt.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ const char *elf2flt_progname;
#include <elf/bfin.h>
#elif defined(TARGET_h8300)
#include <elf/h8.h>
#elif defined(TARGET_lm32)
#include <elf/lm32.h>
#elif defined(TARGET_m68k)
#include <elf/m68k.h>
#elif defined(TARGET_microblaze)
Expand Down Expand Up @@ -115,6 +117,12 @@ const char *elf2flt_progname;
#define ARCH "sh2"
#elif defined(TARGET_h8300)
#define ARCH "h8300"
#elif defined(TARGET_lm32)
#define ARCH "lm32"
#define FLAT_LM32_RELOC_TYPE_32_BIT 0
#define FLAT_LM32_RELOC_TYPE_HI16_BIT 1
#define FLAT_LM32_RELOC_TYPE_LO16_BIT 2
#define FLAT_LM32_RELOC_TYPE_PERSIST 3
#elif defined(TARGET_microblaze)
#define ARCH "microblaze"
#elif defined(TARGET_e1)
Expand Down Expand Up @@ -375,7 +383,7 @@ output_relocs (
int bad_relocs = 0;
asymbol **symb;
long nsymb;
#ifdef TARGET_bfin
#if defined(TARGET_bfin) || defined(TARGET_lm32)
unsigned long persistent_data = 0;
#endif

Expand Down Expand Up @@ -692,6 +700,40 @@ output_relocs (
break;
default:
goto bad_resolved_reloc;
#elif defined(TARGET_lm32)
case R_LM32_HI16:
case R_LM32_LO16:
sym_vma = elf2flt_bfd_section_vma(sym_section);
sym_addr += sym_vma + q->addend;
/* remember the upper 16 bits */
if ((0xFFFF0000UL & 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 = 0xFFFF0000UL & sym_addr;
pflags = FLAT_LM32_RELOC_TYPE_PERSIST;
pflags <<= 29;
flat_relocs[flat_reloc_count++] = pflags | (sym_addr >> 16);
}
pflags = q->howto->type == R_LM32_HI16 ?
FLAT_LM32_RELOC_TYPE_HI16_BIT :
FLAT_LM32_RELOC_TYPE_LO16_BIT;
pflags <<= 29;
relocation_needed = 1;
break;
case R_LM32_32:
sym_vma = elf2flt_bfd_section_vma(sym_section);
sym_addr += sym_vma + q->addend;
pflags = FLAT_LM32_RELOC_TYPE_32_BIT;
pflags <<= 29;
relocation_needed = 1;
break;
case R_LM32_CALL:
relocation_needed = 0;
break;
default:
goto bad_resolved_reloc;
#elif defined(TARGET_m68k)
case R_68K_32:
goto good_32bit_resolved_reloc;
Expand Down Expand Up @@ -1056,6 +1098,63 @@ output_relocs (
continue;
#endif

#ifdef TARGET_lm32
case R_LM32_HI16:
case R_LM32_LO16:
sym_vma = elf2flt_bfd_section_vma(sym_section);
sym_addr += sym_vma + q->addend;
/* remember the upper 16 bits */
if ((0xFFFF0000UL & 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 = 0xFFFF0000UL & sym_addr;
pflags = FLAT_LM32_RELOC_TYPE_PERSIST;
pflags <<= 29;
flat_relocs[flat_reloc_count++] = pflags | (sym_addr >> 16);
}
pflags = q->howto->type == R_LM32_HI16 ?
FLAT_LM32_RELOC_TYPE_HI16_BIT :
FLAT_LM32_RELOC_TYPE_LO16_BIT;
pflags <<= 29;
relocation_needed = 1;
break;
case R_LM32_32:
sym_vma = elf2flt_bfd_section_vma(sym_section);
sym_addr += sym_vma + q->addend;
pflags = FLAT_LM32_RELOC_TYPE_32_BIT;
pflags <<= 29;
relocation_needed = 1;
break;
case R_LM32_CALL:
sym_vma = 0;
sym_addr += sym_vma + q->addend;
sym_addr -= q->address;
sym_addr = (int32_t)sym_addr >> q->howto->rightshift;
{
union {
uint32_t u;
int32_t s;
} rangecheck;

rangecheck.u = (unsigned)sym_addr << 6;
rangecheck.s >>= 6;
if (rangecheck.u != sym_addr) {
printf("ERROR: Relocation overflow for R_LM32_CALL relocation against %s\n", sym_name);
++bad_relocs;
continue;
}
}
relocation_needed = 0;
r_mem[0] = (r_mem[0] & 0xFCU) |
((sym_addr >> 24) & 0x03U);
r_mem[1] = (sym_addr >> 16) & 0xFFU;
r_mem[2] = (sym_addr >> 8) & 0xFFU;
r_mem[3] = sym_addr & 0xFFU;
break;
#endif

#ifdef TARGET_microblaze
case R_MICROBLAZE_64:
/* work out the relocation */
Expand Down Expand Up @@ -1625,6 +1724,21 @@ output_relocs (
break;
#endif

#ifdef TARGET_lm32
case R_LM32_HI16:
case R_LM32_LO16:
r_mem[2] = (sym_addr >> 8) & 0xFFU;
r_mem[3] = sym_addr & 0xFFU;
break;
case R_LM32_CALL:
/*
* use_resolved=…
* 0: already written above
* 1: no write necessary
*/
break;
#endif

default:
/* The alignment of the build host
might be stricter than that of the
Expand Down
2 changes: 2 additions & 0 deletions elf2flt.ld.in
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ W_RODAT: *(.rodata)
W_RODAT: *(.rodata1)
W_RODAT: *(.rodata.*)
W_RODAT: *(.gnu.linkonce.r*)
W_RODAT: *(.rofixup)

/* .ARM.extab name sections containing exception unwinding information */
*(.ARM.extab* .gnu.linkonce.armextab.*)
Expand Down Expand Up @@ -109,6 +110,7 @@ R_RODAT: *(.rodata)
R_RODAT: *(.rodata1)
R_RODAT: *(.rodata.*)
R_RODAT: *(.gnu.linkonce.r*)
R_RODAT: *(.rofixup)
*(.data)
*(.data1)
*(.data.*)
Expand Down
2 changes: 2 additions & 0 deletions flthdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ const char *elf2flt_progname;

#if defined TARGET_bfin
# define flat_get_relocate_addr(addr) (addr & 0x03ffffff)
#elif defined(TARGET_lm32)
# define flat_get_relocate_addr(addr) ((addr) & 0x1FFFFFFFU)
#else
# define flat_get_relocate_addr(addr) (addr)
#endif
Expand Down
Loading