diff -Nur elf2flt-6d80ab6c93409e796f85da404bde84b841231531.orig/elf2flt.c elf2flt-6d80ab6c93409e796f85da404bde84b841231531/elf2flt.c --- elf2flt-6d80ab6c93409e796f85da404bde84b841231531.orig/elf2flt.c 2017-09-27 06:06:04.000000000 +0200 +++ elf2flt-6d80ab6c93409e796f85da404bde84b841231531/elf2flt.c 2017-09-27 06:07:51.032597579 +0200 @@ -61,6 +61,8 @@ #include #elif defined(TARGET_h8300) #include +#elif defined(TARGET_lm32) +#include #elif defined(TARGET_m68k) #include #elif defined(TARGET_microblaze) @@ -120,6 +122,11 @@ #define ARCH "nios" #elif defined(TARGET_nios2) #define ARCH "nios2" +#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 #elif defined(TARGET_xtensa) #define ARCH "xtensa" #else @@ -357,7 +364,7 @@ int bad_relocs = 0; asymbol **symb; long nsymb; -#ifdef TARGET_bfin +#if defined (TARGET_bfin) || defined (TARGET_lm32) unsigned long persistent_data = 0; #endif @@ -682,6 +689,36 @@ break; default: goto bad_resolved_reloc; +#elif defined(TARGET_lm32) + case R_LM32_HI16: + case R_LM32_LO16: + if (q->howto->type == R_LM32_HI16) { + pflags = FLAT_LM32_RELOC_TYPE_HI16_BIT << 29; + } else { + pflags = FLAT_LM32_RELOC_TYPE_LO16_BIT << 29; + } + + relocation_needed = 1; + + /* remember the upper 16 bits */ + if ((0xffff0000 & sym_addr) != persistent_data) { + flat_relocs = (uint32_t *) + (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t))); + if (verbose) + printf ("New persistent data for %08lx\n", sym_addr); + persistent_data = 0xffff0000 & sym_addr; + flat_relocs[flat_reloc_count++] = (sym_addr >> 16) | (3 << 29); + } + break; + case R_LM32_32: + pflags = FLAT_LM32_RELOC_TYPE_32_BIT << 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; @@ -1459,6 +1496,63 @@ #undef _30BITS_RELOC #undef _28BITS_RELOC #endif +#ifdef TARGET_lm32 + case R_LM32_32: + { + pflags = FLAT_LM32_RELOC_TYPE_32_BIT << 29; + sym_vma = elf2flt_bfd_section_vma(abs_bfd, sym_section); + sym_addr += sym_vma + q->addend; + 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; + + if ((int32_t)sym_addr < -0x8000000 || (int32_t)sym_addr > 0x7ffffff) { + printf("ERROR: Relocation overflow for R_LM32_CALL relocation against %s\n", sym_name); + bad_relocs++; + continue; + } + + r_mem[0] |= (sym_addr >> 24) & 0x03; + r_mem[1] = (sym_addr >> 16) & 0xff; + r_mem[2] = (sym_addr >> 8) & 0xff; + r_mem[3] = sym_addr & 0xff; + break; + } + case R_LM32_HI16: + case R_LM32_LO16: + { + if (q->howto->type == R_LM32_HI16) { + pflags = FLAT_LM32_RELOC_TYPE_HI16_BIT << 29; + } else { + pflags = FLAT_LM32_RELOC_TYPE_LO16_BIT << 29; + } + + sym_vma = elf2flt_bfd_section_vma(abs_bfd, sym_section); + sym_addr += sym_vma + q->addend; + + relocation_needed = 1; + + /* remember the upper 16 bits */ + if ((0xffff0000 & sym_addr) != persistent_data) { + flat_relocs = (uint32_t *) + (realloc (flat_relocs, (flat_reloc_count + 1) * sizeof (uint32_t))); + if (verbose) + printf ("New persistent data for %08lx\n", sym_addr); + persistent_data = 0xffff0000 & sym_addr; + flat_relocs[flat_reloc_count++] = (sym_addr >> 16) | (3 << 29); + } + + r_mem[2] = (sym_addr >> 8) & 0xff; + r_mem[3] = sym_addr & 0xff; + break; + } +#endif /* TARGET_lm32 */ default: /* missing support for other types of relocs */ printf("ERROR: bad reloc type %d\n", (*p)->howto->type); @@ -1596,6 +1690,13 @@ break; #endif +#ifdef TARGET_lm32 + case R_LM32_HI16: + case R_LM32_LO16: + case R_LM32_CALL: + /* entry has already been written */ + break; +#endif default: /* The alignment of the build host might be stricter than that of the diff -Nur elf2flt-6d80ab6c93409e796f85da404bde84b841231531.orig/elf2flt.ld.in elf2flt-6d80ab6c93409e796f85da404bde84b841231531/elf2flt.ld.in --- elf2flt-6d80ab6c93409e796f85da404bde84b841231531.orig/elf2flt.ld.in 2017-09-27 06:06:04.000000000 +0200 +++ elf2flt-6d80ab6c93409e796f85da404bde84b841231531/elf2flt.ld.in 2017-09-29 18:11:30.999698955 +0200 @@ -34,6 +34,7 @@ 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.*)