35 #define XTENSA_NO_NOP_REMOVAL 0
41 static char *vsprint_msg (
const char *,
const char *,
int, ...)
ATTRIBUTE_PRINTF(2,4);
46 static
void do_fix_for_final_link
58 static
int get_relocation_slot (
int);
101 static
asection *get_elf_r_symndx_section (
bfd *,
unsigned long);
103 (
bfd *,
unsigned long);
104 static
bfd_vma get_elf_r_symndx_offset (
bfd *,
unsigned long);
111 static
int internal_reloc_compare (
const void *,
const void *);
112 static
int internal_reloc_matches (
const void *,
const void *);
119 typedef
void (*deps_callback_t)
121 extern
bfd_boolean xtensa_callback_required_dependence
130 int elf32xtensa_size_opt;
137 typedef struct xtensa_relax_info_struct xtensa_relax_info;
153 #if !defined(HAVE_DOS_BASED_FILE_SYSTEM) \
154 && !defined(HAVE_CASE_INSENSITIVE_FILE_SYSTEM)
155 return strcmp(
s1,
s2);
162 #if defined (HAVE_CASE_INSENSITIVE_FILE_SYSTEM)
167 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
200 int elf32xtensa_no_literal_movement = 1;
205 #define reloc_done sec_flg0
210 bfd_elf_xtensa_reloc,
"RZ_XTENSA_NONE",
213 bfd_elf_xtensa_reloc,
"RZ_XTENSA_32",
234 bfd_elf_xtensa_reloc,
"RZ_XTENSA_PLT",
241 bfd_elf_xtensa_reloc,
"RZ_XTENSA_OP0",
FALSE, 0, 0,
TRUE),
243 bfd_elf_xtensa_reloc,
"RZ_XTENSA_OP1",
FALSE, 0, 0,
TRUE),
245 bfd_elf_xtensa_reloc,
"RZ_XTENSA_OP2",
FALSE, 0, 0,
TRUE),
249 bfd_elf_xtensa_reloc,
"RZ_XTENSA_ASM_EXPAND",
FALSE, 0, 0,
TRUE),
252 bfd_elf_xtensa_reloc,
"RZ_XTENSA_ASM_SIMPLIFY",
FALSE, 0, 0,
TRUE),
257 bfd_elf_xtensa_reloc,
"RZ_XTENSA_32_PCREL",
262 NULL,
"RZ_XTENSA_GNU_VTINHERIT",
271 bfd_elf_xtensa_reloc,
"RZ_XTENSA_DIFF8",
FALSE, 0, 0xff,
FALSE),
273 bfd_elf_xtensa_reloc,
"RZ_XTENSA_DIFF16",
FALSE, 0, 0xffff,
FALSE),
275 bfd_elf_xtensa_reloc,
"RZ_XTENSA_DIFF32",
FALSE, 0, 0xffffffff,
FALSE),
279 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT0_OP",
FALSE, 0, 0,
TRUE),
281 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT1_OP",
FALSE, 0, 0,
TRUE),
283 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT2_OP",
FALSE, 0, 0,
TRUE),
285 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT3_OP",
FALSE, 0, 0,
TRUE),
287 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT4_OP",
FALSE, 0, 0,
TRUE),
289 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT5_OP",
FALSE, 0, 0,
TRUE),
291 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT6_OP",
FALSE, 0, 0,
TRUE),
293 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT7_OP",
FALSE, 0, 0,
TRUE),
295 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT8_OP",
FALSE, 0, 0,
TRUE),
297 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT9_OP",
FALSE, 0, 0,
TRUE),
299 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT10_OP",
FALSE, 0, 0,
TRUE),
301 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT11_OP",
FALSE, 0, 0,
TRUE),
303 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT12_OP",
FALSE, 0, 0,
TRUE),
305 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT13_OP",
FALSE, 0, 0,
TRUE),
307 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT14_OP",
FALSE, 0, 0,
TRUE),
311 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT0_ALT",
FALSE, 0, 0,
TRUE),
313 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT1_ALT",
FALSE, 0, 0,
TRUE),
315 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT2_ALT",
FALSE, 0, 0,
TRUE),
317 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT3_ALT",
FALSE, 0, 0,
TRUE),
319 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT4_ALT",
FALSE, 0, 0,
TRUE),
321 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT5_ALT",
FALSE, 0, 0,
TRUE),
323 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT6_ALT",
FALSE, 0, 0,
TRUE),
325 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT7_ALT",
FALSE, 0, 0,
TRUE),
327 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT8_ALT",
FALSE, 0, 0,
TRUE),
329 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT9_ALT",
FALSE, 0, 0,
TRUE),
331 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT10_ALT",
FALSE, 0, 0,
TRUE),
333 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT11_ALT",
FALSE, 0, 0,
TRUE),
335 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT12_ALT",
FALSE, 0, 0,
TRUE),
337 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT13_ALT",
FALSE, 0, 0,
TRUE),
339 bfd_elf_xtensa_reloc,
"RZ_XTENSA_SLOT14_ALT",
FALSE, 0, 0,
TRUE),
343 bfd_elf_xtensa_reloc,
"RZ_XTENSA_TLSDESC_FN",
346 bfd_elf_xtensa_reloc,
"RZ_XTENSA_TLSDESC_ARG",
349 bfd_elf_xtensa_reloc,
"RZ_XTENSA_TLS_DTPOFF",
352 bfd_elf_xtensa_reloc,
"RZ_XTENSA_TLS_TPOFF",
355 bfd_elf_xtensa_reloc,
"RZ_XTENSA_TLS_FUNC",
358 bfd_elf_xtensa_reloc,
"RZ_XTENSA_TLS_ARG",
361 bfd_elf_xtensa_reloc,
"RZ_XTENSA_TLS_CALL",
367 fprintf (stderr, "Xtensa bfd reloc lookup %d (%s)\n", code, str)
379 TRACE (
"BFD_RELOC_NONE");
380 return &elf_howto_table[(
unsigned) RZ_XTENSA_NONE ];
383 TRACE (
"BFD_RELOC_32");
384 return &elf_howto_table[(
unsigned) RZ_XTENSA_32 ];
387 TRACE (
"BFD_RELOC_32_PCREL");
388 return &elf_howto_table[(
unsigned) RZ_XTENSA_32_PCREL ];
391 TRACE (
"BFD_RELOC_XTENSA_DIFF8");
392 return &elf_howto_table[(
unsigned) RZ_XTENSA_DIFF8 ];
395 TRACE (
"BFD_RELOC_XTENSA_DIFF16");
396 return &elf_howto_table[(
unsigned) RZ_XTENSA_DIFF16 ];
399 TRACE (
"BFD_RELOC_XTENSA_DIFF32");
400 return &elf_howto_table[(
unsigned) RZ_XTENSA_DIFF32 ];
403 TRACE (
"BFD_RELOC_XTENSA_RTLD");
404 return &elf_howto_table[(
unsigned) RZ_XTENSA_RTLD ];
407 TRACE (
"BFD_RELOC_XTENSA_GLOB_DAT");
408 return &elf_howto_table[(
unsigned) RZ_XTENSA_GLOB_DAT ];
411 TRACE (
"BFD_RELOC_XTENSA_JMP_SLOT");
412 return &elf_howto_table[(
unsigned) RZ_XTENSA_JMP_SLOT ];
415 TRACE (
"BFD_RELOC_XTENSA_RELATIVE");
416 return &elf_howto_table[(
unsigned) RZ_XTENSA_RELATIVE ];
419 TRACE (
"BFD_RELOC_XTENSA_PLT");
420 return &elf_howto_table[(
unsigned) RZ_XTENSA_PLT ];
423 TRACE (
"BFD_RELOC_XTENSA_OP0");
424 return &elf_howto_table[(
unsigned) RZ_XTENSA_OP0 ];
427 TRACE (
"BFD_RELOC_XTENSA_OP1");
428 return &elf_howto_table[(
unsigned) RZ_XTENSA_OP1 ];
431 TRACE (
"BFD_RELOC_XTENSA_OP2");
432 return &elf_howto_table[(
unsigned) RZ_XTENSA_OP2 ];
435 TRACE (
"BFD_RELOC_XTENSA_ASM_EXPAND");
436 return &elf_howto_table[(
unsigned) RZ_XTENSA_ASM_EXPAND ];
439 TRACE (
"BFD_RELOC_XTENSA_ASM_SIMPLIFY");
440 return &elf_howto_table[(
unsigned) RZ_XTENSA_ASM_SIMPLIFY ];
443 TRACE (
"BFD_RELOC_VTABLE_INHERIT");
444 return &elf_howto_table[(
unsigned) RZ_XTENSA_GNU_VTINHERIT ];
447 TRACE (
"BFD_RELOC_VTABLE_ENTRY");
448 return &elf_howto_table[(
unsigned) RZ_XTENSA_GNU_VTENTRY ];
450 case BFD_RELOC_XTENSA_TLSDESC_FN:
451 TRACE (
"BFD_RELOC_XTENSA_TLSDESC_FN");
452 return &elf_howto_table[(
unsigned) RZ_XTENSA_TLSDESC_FN ];
454 case BFD_RELOC_XTENSA_TLSDESC_ARG:
455 TRACE (
"BFD_RELOC_XTENSA_TLSDESC_ARG");
456 return &elf_howto_table[(
unsigned) RZ_XTENSA_TLSDESC_ARG ];
458 case BFD_RELOC_XTENSA_TLS_DTPOFF:
459 TRACE (
"BFD_RELOC_XTENSA_TLS_DTPOFF");
460 return &elf_howto_table[(
unsigned) RZ_XTENSA_TLS_DTPOFF ];
462 case BFD_RELOC_XTENSA_TLS_TPOFF:
463 TRACE (
"BFD_RELOC_XTENSA_TLS_TPOFF");
464 return &elf_howto_table[(
unsigned) RZ_XTENSA_TLS_TPOFF ];
466 case BFD_RELOC_XTENSA_TLS_FUNC:
467 TRACE (
"BFD_RELOC_XTENSA_TLS_FUNC");
468 return &elf_howto_table[(
unsigned) RZ_XTENSA_TLS_FUNC ];
470 case BFD_RELOC_XTENSA_TLS_ARG:
471 TRACE (
"BFD_RELOC_XTENSA_TLS_ARG");
472 return &elf_howto_table[(
unsigned) RZ_XTENSA_TLS_ARG ];
474 case BFD_RELOC_XTENSA_TLS_CALL:
475 TRACE (
"BFD_RELOC_XTENSA_TLS_CALL");
476 return &elf_howto_table[(
unsigned) RZ_XTENSA_TLS_CALL ];
482 unsigned n = (RZ_XTENSA_SLOT0_OP +
484 return &elf_howto_table[
n];
490 unsigned n = (RZ_XTENSA_SLOT0_ALT +
492 return &elf_howto_table[
n];
508 for (
i = 0;
i <
sizeof (elf_howto_table) /
sizeof (elf_howto_table[0]);
i++)
511 return &elf_howto_table[
i];
527 if (rz_type >= (
unsigned int) RZ_XTENSA_max)
529 _bfd_error_handler (
_(
"%B: invalid XTENSA reloc number: %d"), abfd, rz_type);
532 cache_ptr->
howto = &elf_howto_table[rz_type];
541 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so"
547 #define PLT_ENTRY_SIZE 16
559 #define PLT_ENTRIES_PER_CHUNK 254
566 static const bfd_byte elf_xtensa_be_plt_entry[PLT_ENTRY_SIZE] =
576 static const bfd_byte elf_xtensa_le_plt_entry[PLT_ENTRY_SIZE] =
589 struct elf_xtensa_link_hash_entry
595 #define GOT_UNKNOWN 0
599 #define GOT_TLS_ANY (GOT_TLS_GD | GOT_TLS_IE)
600 unsigned char tls_type;
603 #define elf_xtensa_hash_entry(ent) ((struct elf_xtensa_link_hash_entry *)(ent))
605 struct elf_xtensa_obj_tdata
610 char *local_got_tls_type;
615 #define elf_xtensa_tdata(abfd) \
616 ((struct elf_xtensa_obj_tdata *) (abfd)->tdata.any)
618 #define elf_xtensa_local_got_tls_type(abfd) \
619 (elf_xtensa_tdata (abfd)->local_got_tls_type)
621 #define elf_xtensa_local_tlsfunc_refcounts(abfd) \
622 (elf_xtensa_tdata (abfd)->local_tlsfunc_refcounts)
624 #define is_xtensa_elf(bfd) \
625 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
626 && elf_tdata (bfd) != NULL \
627 && elf_object_id (bfd) == XTENSA_ELF_DATA)
630 elf_xtensa_mkobject (
bfd *abfd)
632 return bfd_elf_allocate_object (abfd,
sizeof (
struct elf_xtensa_obj_tdata),
638 struct elf_xtensa_link_hash_table
659 struct elf_xtensa_link_hash_entry *tlsbase;
664 #define elf_xtensa_hash_table(p) \
665 (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
666 == XTENSA_ELF_DATA ? ((struct elf_xtensa_link_hash_table *) ((p)->hash)) : NULL)
680 sizeof (
struct elf_xtensa_link_hash_entry));
689 struct elf_xtensa_link_hash_entry *eh = elf_xtensa_hash_entry (
entry);
690 eh->tlsfunc_refcount = 0;
691 eh->tls_type = GOT_UNKNOWN;
700 elf_xtensa_link_hash_table_create (
bfd *abfd)
703 struct elf_xtensa_link_hash_table *ret;
704 bfd_size_type amt =
sizeof (
struct elf_xtensa_link_hash_table);
706 ret = bfd_zmalloc (amt);
711 elf_xtensa_link_hash_newfunc,
712 sizeof (
struct elf_xtensa_link_hash_entry),
726 ret->tlsbase = elf_xtensa_hash_entry (tlsbase);
727 ret->tlsbase->tls_type = GOT_UNKNOWN;
729 return &ret->elf.root;
739 struct elf_xtensa_link_hash_entry *edir, *eind;
741 edir = elf_xtensa_hash_entry (dir);
742 eind = elf_xtensa_hash_entry (
ind);
746 edir->tlsfunc_refcount += eind->tlsfunc_refcount;
747 eind->tlsfunc_refcount = 0;
751 edir->tls_type = eind->tls_type;
752 eind->tls_type = GOT_UNKNOWN;
774 property_table_compare (
const void *ap,
const void *bp)
779 if (
a->address ==
b->address)
781 if (
a->size !=
b->size)
782 return (
a->size -
b->size);
799 return (
a->flags -
b->flags);
802 return (
a->address -
b->address);
807 property_table_matches (
const void *ap,
const void *bp)
813 if ((
b->address >=
a->address &&
b->address < (
a->address +
a->size))
814 || (
a->address >=
b->address &&
a->address < (
b->address +
b->size)))
817 return (
a->address -
b->address);
826 xtensa_read_table_entries (
bfd *abfd,
829 const char *sec_name,
836 int blk, block_count;
851 table_section = xtensa_get_property_section (
section, sec_name);
853 table_size = table_section->
size;
861 predef_flags = xtensa_get_property_predef_flags (table_section);
862 table_entry_size = 12;
864 table_entry_size -= 4;
866 num_records = table_size / table_entry_size;
867 table_data = retrieve_contents (abfd, table_section,
TRUE);
873 section_addr =
section->output_section->vma +
section->output_offset;
877 internal_relocs = retrieve_internal_relocs (abfd, table_section,
TRUE);
878 if (internal_relocs && !table_section->
reloc_done)
882 irel = internal_relocs;
888 rel_end = internal_relocs + table_section->
reloc_count;
890 for (
off = 0;
off < table_size;
off += table_entry_size)
913 if (get_elf_r_symndx_section (abfd, rz_symndx) !=
section)
916 sym_off = get_elf_r_symndx_offset (abfd, rz_symndx);
917 BFD_ASSERT (sym_off == 0);
918 address += (section_addr + sym_off + irel->
rz_addend);
922 if (address < section_addr
923 || address >= section_addr + section_limit)
927 blocks[block_count].address = address;
930 blocks[block_count].flags = predef_flags;
936 release_contents (table_section, table_data);
937 release_internal_relocs (table_section, internal_relocs);
943 property_table_compare);
947 for (blk = 1; blk < block_count; blk++)
956 (*_bfd_error_handler) (
_(
"%B(%A): invalid property table"),
972 int property_table_size,
978 if (property_table_size == 0)
985 rv = bsearch (&
entry, property_table, property_table_size,
996 if (elf_xtensa_find_property_entry (lit_table, lit_table_size,
addr))
1007 elf_xtensa_check_relocs (
bfd *abfd,
1012 struct elf_xtensa_link_hash_table *htab;
1021 BFD_ASSERT (is_xtensa_elf (abfd));
1023 htab = elf_xtensa_hash_table (
info);
1027 symtab_hdr = &
elf_tdata (abfd)->symtab_hdr;
1031 for (rel =
relocs; rel < rel_end; rel++)
1033 unsigned int rz_type;
1034 unsigned long rz_symndx;
1036 struct elf_xtensa_link_hash_entry *eh;
1037 int tls_type, old_tls_type;
1047 (*_bfd_error_handler) (
_(
"%B: bad symbol index: %d"),
1052 if (rz_symndx >= symtab_hdr->
sh_info)
1054 h = sym_hashes[rz_symndx - symtab_hdr->
sh_info];
1061 h->root.non_ir_ref = 1;
1063 eh = elf_xtensa_hash_entry (
h);
1067 case RZ_XTENSA_TLSDESC_FN:
1070 tls_type = GOT_TLS_GD;
1075 tls_type = GOT_TLS_IE;
1078 case RZ_XTENSA_TLSDESC_ARG:
1081 tls_type = GOT_TLS_GD;
1086 tls_type = GOT_TLS_IE;
1087 if (
h && elf_xtensa_hash_entry (
h) != htab->tlsbase)
1092 case RZ_XTENSA_TLS_DTPOFF:
1094 tls_type = GOT_TLS_GD;
1096 tls_type = GOT_TLS_IE;
1099 case RZ_XTENSA_TLS_TPOFF:
1100 tls_type = GOT_TLS_IE;
1103 if (
info->shared ||
h)
1108 tls_type = GOT_NORMAL;
1113 tls_type = GOT_NORMAL;
1117 case RZ_XTENSA_GNU_VTINHERIT:
1124 case RZ_XTENSA_GNU_VTENTRY:
1127 BFD_ASSERT (
h !=
NULL);
1142 if (
h->plt.refcount <= 0)
1145 h->plt.refcount = 1;
1148 h->plt.refcount += 1;
1153 htab->plt_reloc_count += 1;
1157 if (! add_extra_plt_sections (
info, htab->plt_reloc_count))
1163 if (
h->got.refcount <= 0)
1164 h->got.refcount = 1;
1166 h->got.refcount += 1;
1170 eh->tlsfunc_refcount += 1;
1172 old_tls_type = eh->tls_type;
1190 elf_xtensa_local_got_tls_type (abfd) = (
char *)
mem;
1195 elf_xtensa_local_tlsfunc_refcounts (abfd)
1200 if (is_got || is_plt)
1204 elf_xtensa_local_tlsfunc_refcounts (abfd) [rz_symndx] += 1;
1206 old_tls_type = elf_xtensa_local_got_tls_type (abfd) [rz_symndx];
1209 if ((old_tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_IE))
1210 tls_type |= old_tls_type;
1213 else if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
1214 && ((old_tls_type & GOT_TLS_GD) == 0
1215 || (tls_type & GOT_TLS_IE) == 0))
1217 if ((old_tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_GD))
1218 tls_type = old_tls_type;
1219 else if ((old_tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GD))
1220 tls_type |= old_tls_type;
1223 (*_bfd_error_handler)
1224 (
_(
"%B: `%s' accessed both as normal and thread local symbol"),
1226 h ?
h->root.root.string :
"<local>");
1231 if (old_tls_type != tls_type)
1234 eh->tls_type = tls_type;
1236 elf_xtensa_local_got_tls_type (abfd) [rz_symndx] = tls_type;
1250 if (
h->plt.refcount > 0)
1254 if (
h->got.refcount < 0)
1255 h->got.refcount = 0;
1256 h->got.refcount +=
h->plt.refcount;
1257 h->plt.refcount = 0;
1263 h->plt.refcount = 0;
1264 h->got.refcount = 0;
1276 elf_xtensa_make_sym_local (
info,
h);
1286 elf_xtensa_gc_mark_hook (
asection *sec,
1302 if (xtensa_is_property_section (sec))
1308 case RZ_XTENSA_GNU_VTINHERIT:
1309 case RZ_XTENSA_GNU_VTENTRY:
1321 elf_xtensa_gc_sweep_hook (
bfd *abfd,
1329 struct elf_xtensa_link_hash_table *htab;
1331 htab = elf_xtensa_hash_table (
info);
1335 if (
info->relocatable)
1341 symtab_hdr = &
elf_tdata (abfd)->symtab_hdr;
1345 for (rel =
relocs; rel < relend; rel++)
1347 unsigned long rz_symndx;
1348 unsigned int rz_type;
1350 struct elf_xtensa_link_hash_entry *eh;
1356 if (rz_symndx >= symtab_hdr->
sh_info)
1358 h = sym_hashes[rz_symndx - symtab_hdr->
sh_info];
1363 eh = elf_xtensa_hash_entry (
h);
1368 case RZ_XTENSA_TLSDESC_FN:
1376 case RZ_XTENSA_TLSDESC_ARG:
1381 if (
h && elf_xtensa_hash_entry (
h) != htab->tlsbase)
1386 case RZ_XTENSA_TLS_TPOFF:
1387 if (
info->shared ||
h)
1409 if (
h->plt.refcount > 0)
1416 if (
h->got.refcount > 0)
1421 if (eh->tlsfunc_refcount > 0)
1422 eh->tlsfunc_refcount--;
1427 if (is_got || is_plt)
1431 if (*got_refcount > 0)
1437 = &elf_xtensa_local_tlsfunc_refcounts (abfd) [rz_symndx];
1438 if (*tlsfunc_refcount > 0)
1439 *tlsfunc_refcount -= 1;
1453 struct elf_xtensa_link_hash_table *htab;
1456 htab = elf_xtensa_hash_table (
info);
1463 htab->splt = bfd_get_linker_section (dynobj,
".plt");
1464 htab->srelplt = bfd_get_linker_section (dynobj,
".rela.plt");
1465 htab->sgot = bfd_get_linker_section (dynobj,
".got");
1466 htab->sgotplt = bfd_get_linker_section (dynobj,
".got.plt");
1467 htab->srelgot = bfd_get_linker_section (dynobj,
".rela.got");
1471 if (! add_extra_plt_sections (
info, htab->plt_reloc_count))
1479 if (htab->sgotplt ==
NULL
1486 if (htab->sgotloc ==
NULL
1493 if (htab->spltlittbl ==
NULL
1516 if (elf_xtensa_get_plt_section (
info,
chunk))
1558 h->root.u.def.section =
h->u.weakdef->root.u.def.section;
1559 h->root.u.def.value =
h->u.weakdef->root.u.def.value;
1576 struct elf_xtensa_link_hash_table *htab;
1577 struct elf_xtensa_link_hash_entry *eh = elf_xtensa_hash_entry (
h);
1583 htab = elf_xtensa_hash_table (
info);
1589 if ((eh->tls_type & GOT_TLS_IE) != 0)
1591 BFD_ASSERT (
h->got.refcount >= eh->tlsfunc_refcount);
1592 h->got.refcount -= eh->tlsfunc_refcount;
1595 if (! elf_xtensa_dynamic_symbol_p (
h,
info))
1596 elf_xtensa_make_sym_local (
info,
h);
1598 if (
h->plt.refcount > 0)
1601 if (
h->got.refcount > 0)
1611 struct elf_xtensa_link_hash_table *htab;
1614 htab = elf_xtensa_hash_table (
info);
1618 for (
i =
info->input_bfds;
i;
i =
i->link.next)
1625 if (!local_got_refcounts)
1631 for (j = 0; j < cnt; ++j)
1635 if ((elf_xtensa_local_got_tls_type (
i) [j] & GOT_TLS_IE) != 0)
1638 = &elf_xtensa_local_tlsfunc_refcounts (
i) [j];
1639 BFD_ASSERT (local_got_refcounts[j] >= *tlsfunc_refcount);
1640 local_got_refcounts[j] -= *tlsfunc_refcount;
1643 if (local_got_refcounts[j] > 0)
1644 htab->srelgot->size += (local_got_refcounts[j]
1657 struct elf_xtensa_link_hash_table *htab;
1659 asection *
s, *srelplt, *splt, *sgotplt, *srelgot, *spltlittbl, *sgotloc;
1661 int plt_entries, plt_chunks,
chunk;
1666 htab = elf_xtensa_hash_table (
info);
1673 srelgot = htab->srelgot;
1674 srelplt = htab->srelplt;
1678 BFD_ASSERT (htab->srelgot !=
NULL
1679 && htab->srelplt !=
NULL
1680 && htab->sgot !=
NULL
1681 && htab->spltlittbl !=
NULL
1682 && htab->sgotloc !=
NULL);
1685 if (
info->executable)
1687 s = bfd_get_linker_section (dynobj,
".interp");
1690 s->size =
sizeof ELF_DYNAMIC_INTERPRETER;
1691 s->contents = (
unsigned char *) ELF_DYNAMIC_INTERPRETER;
1695 htab->sgot->size = 4;
1701 elf_xtensa_allocate_dynrelocs,
1708 elf_xtensa_allocate_local_got_size (
info);
1715 spltlittbl = htab->spltlittbl;
1718 (plt_entries + PLT_ENTRIES_PER_CHUNK - 1) / PLT_ENTRIES_PER_CHUNK;
1729 sgotplt = elf_xtensa_get_gotplt_section (
info,
chunk);
1730 BFD_ASSERT (sgotplt !=
NULL);
1732 if (
chunk < plt_chunks - 1)
1733 chunk_entries = PLT_ENTRIES_PER_CHUNK;
1734 else if (
chunk == plt_chunks - 1)
1735 chunk_entries = plt_entries - (
chunk * PLT_ENTRIES_PER_CHUNK);
1739 if (chunk_entries != 0)
1741 sgotplt->
size = 4 * (chunk_entries + 2);
1742 splt->
size = PLT_ENTRY_SIZE * chunk_entries;
1744 spltlittbl->
size += 8;
1755 sgotloc = htab->sgotloc;
1757 for (abfd =
info->input_bfds; abfd !=
NULL; abfd = abfd->link.
next)
1763 if (! discarded_section (
s)
1764 && xtensa_is_littable_section (
s)
1766 sgotloc->
size +=
s->size;
1789 if (strcmp (
name,
".rela.plt") == 0)
1791 else if (strcmp (
name,
".rela.got") == 0)
1801 && strcmp (
name,
".got") != 0
1802 && strcmp (
name,
".plt") != 0
1803 && strcmp (
name,
".got.plt") != 0
1804 && strcmp (
name,
".xt.lit.plt") != 0
1805 && strcmp (
name,
".got.loc") != 0)
1828 if (
s->contents ==
NULL)
1860 #define add_dynamic_entry(TAG, VAL) \
1861 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1863 if (
info->executable)
1865 if (!add_dynamic_entry (
DT_DEBUG, 0))
1879 if (!add_dynamic_entry (
DT_RELA, 0)
1890 #undef add_dynamic_entry
1896 elf_xtensa_always_size_sections (
bfd *output_bfd,
1899 struct elf_xtensa_link_hash_table *htab;
1902 htab = elf_xtensa_hash_table (
info);
1906 tls_sec = htab->elf.tls_sec;
1908 if (tls_sec && (htab->tlsbase->tls_type & GOT_TLS_ANY) != 0)
1915 if (!(_bfd_generic_link_add_one_symbol
1963 #define CALL_SEGMENT_BITS (30)
1964 #define CALL_SEGMENT_SIZE (1 << CALL_SEGMENT_BITS)
1974 char **error_message)
1999 switch (howto->
type)
2001 case RZ_XTENSA_NONE:
2002 case RZ_XTENSA_DIFF8:
2003 case RZ_XTENSA_DIFF16:
2004 case RZ_XTENSA_DIFF32:
2005 case RZ_XTENSA_TLS_FUNC:
2006 case RZ_XTENSA_TLS_ARG:
2007 case RZ_XTENSA_TLS_CALL:
2010 case RZ_XTENSA_ASM_EXPAND:
2014 opcode = get_expanded_call_opcode (contents + address,
2015 input_size - address, 0);
2016 if (is_windowed_call_opcode (opcode))
2018 if ((self_address >> CALL_SEGMENT_BITS)
2019 != (relocation >> CALL_SEGMENT_BITS))
2021 *error_message =
"windowed longcall crosses 1GB boundary; "
2029 case RZ_XTENSA_ASM_SIMPLIFY:
2033 elf_xtensa_do_asm_simplify (contents, address, input_size,
2041 howto = &elf_howto_table[(
unsigned) RZ_XTENSA_SLOT0_OP ];
2054 case RZ_XTENSA_32_PCREL:
2055 bfd_put_32 (abfd, relocation - self_address, contents + address);
2059 case RZ_XTENSA_TLSDESC_FN:
2060 case RZ_XTENSA_TLSDESC_ARG:
2061 case RZ_XTENSA_TLS_DTPOFF:
2062 case RZ_XTENSA_TLS_TPOFF:
2063 bfd_put_32 (abfd, relocation, contents + address);
2068 slot = get_relocation_slot (howto->
type);
2071 *error_message =
"unexpected relocation";
2077 input_size - address);
2081 *error_message =
"cannot decode instruction format";
2090 *error_message =
"cannot decode instruction opcode";
2095 if (is_alt_relocation (howto->
type))
2097 if (opcode == get_l32r_opcode ())
2104 *error_message =
"relocation references missing .lit4 section";
2107 self_address = ((lit4_sec->
vma & ~0xfff)
2109 newval = relocation;
2112 else if (opcode == get_const16_opcode ())
2115 newval = relocation >> 16;
2121 *error_message =
"unexpected relocation";
2127 if (opcode == get_const16_opcode ())
2129 newval = relocation & 0xffff;
2137 opnd = get_relocation_opnd (opcode, howto->
type);
2140 *error_message =
"unexpected relocation";
2146 *error_message =
"expected PC-relative relocation";
2150 newval = relocation;
2163 msg =
"cannot encode";
2164 if (is_direct_call_opcode (opcode))
2166 if ((relocation & 0x3) != 0)
2167 msg =
"misaligned call target";
2169 msg =
"call target out of range";
2171 else if (opcode == get_l32r_opcode ())
2173 if ((relocation & 0x3) != 0)
2174 msg =
"misaligned literal target";
2175 else if (is_alt_relocation (howto->
type))
2176 msg =
"literal target out of range (too many literals)";
2177 else if (self_address > relocation)
2178 msg =
"literal target out of range (try using text-section-literals)";
2180 msg =
"literal placed after use";
2183 *error_message = vsprint_msg (opname,
": %s", strlen (
msg) + 2,
msg);
2188 if (is_direct_call_opcode (opcode)
2189 && is_windowed_call_opcode (opcode))
2191 if ((self_address >> CALL_SEGMENT_BITS)
2192 != (relocation >> CALL_SEGMENT_BITS))
2195 "windowed call crosses 1GB boundary; return may fail";
2203 input_size - address);
2209 vsprint_msg (
const char *origmsg,
const char *fmt,
int arglen, ...)
2219 va_start (ap, arglen);
2221 is_append = (origmsg ==
message);
2223 orig_len = strlen (origmsg);
2224 len = orig_len + strlen (fmt) + arglen + 20;
2225 if (
len > alloc_size)
2249 bfd_elf_xtensa_reloc (
bfd *abfd,
2255 char **error_message)
2262 asection *reloc_target_output_section;
2296 relocation = symbol->
value;
2302 || reloc_target_output_section ==
NULL)
2305 output_base = reloc_target_output_section->
vma;
2310 relocation += reloc_entry->
addend;
2324 reloc_entry->
addend = relocation;
2337 flag = elf_xtensa_do_reloc (howto, abfd, input_section, relocation,
2339 is_weak_undef, error_message);
2344 if (! *error_message)
2345 *error_message =
"";
2346 *error_message = vsprint_msg (*error_message,
": (%s + 0x%lx)",
2347 strlen (symbol->
name) + 17,
2349 (
unsigned long) reloc_entry->
addend);
2361 unsigned reloc_index)
2365 bfd_vma code_offset, lit_offset;
2368 chunk = reloc_index / PLT_ENTRIES_PER_CHUNK;
2369 splt = elf_xtensa_get_plt_section (
info,
chunk);
2370 sgotplt = elf_xtensa_get_gotplt_section (
info,
chunk);
2371 BFD_ASSERT (splt !=
NULL && sgotplt !=
NULL);
2376 lit_offset = 8 + (reloc_index % PLT_ENTRIES_PER_CHUNK) * 4;
2377 code_offset = (reloc_index % PLT_ENTRIES_PER_CHUNK) * PLT_ENTRY_SIZE;
2387 ? elf_xtensa_be_plt_entry
2388 : elf_xtensa_le_plt_entry),
2390 bfd_put_16 (output_bfd, l32r_offset (got_base + 0,
2391 plt_base + code_offset + 3),
2393 bfd_put_16 (output_bfd, l32r_offset (got_base + 4,
2394 plt_base + code_offset + 6),
2396 bfd_put_16 (output_bfd, l32r_offset (got_base + lit_offset,
2397 plt_base + code_offset + 9),
2398 splt->
contents + code_offset + 10);
2400 return plt_base + code_offset;
2412 char **error_message)
2421 unsigned dest_reg, src_reg;
2437 *error_message =
"cannot decode instruction format";
2447 *error_message =
"cannot decode instruction opcode";
2454 case RZ_XTENSA_TLS_FUNC:
2455 case RZ_XTENSA_TLS_ARG:
2456 if (old_op != get_l32r_opcode ()
2458 sbuff, &dest_reg) != 0)
2460 *error_message =
"cannot extract L32R destination for TLS access";
2465 case RZ_XTENSA_TLS_CALL:
2466 if (! get_indirect_call_dest_reg (old_op, &dest_reg)
2468 sbuff, &src_reg) != 0)
2470 *error_message =
"cannot extract CALLXn operands for TLS access";
2483 case RZ_XTENSA_TLS_FUNC:
2484 case RZ_XTENSA_TLS_ARG:
2500 *error_message =
"cannot encode OR for TLS access";
2508 *error_message =
"cannot encode NOP for TLS access";
2514 case RZ_XTENSA_TLS_CALL:
2520 sbuff, dest_reg + 2) != 0)
2522 *error_message =
"cannot encode RUR.THREADPTR for TLS access";
2532 case RZ_XTENSA_TLS_FUNC:
2537 sbuff, dest_reg) != 0)
2539 *error_message =
"cannot encode RUR.THREADPTR for TLS access";
2544 case RZ_XTENSA_TLS_ARG:
2548 case RZ_XTENSA_TLS_CALL:
2556 sbuff, dest_reg + 2) != 0
2558 sbuff, dest_reg + 2) != 0
2560 sbuff, src_reg) != 0)
2562 *error_message =
"cannot encode ADD for TLS access";
2577 #define IS_XTENSA_TLS_RELOC(RZ_TYPE) \
2578 ((RZ_TYPE) == RZ_XTENSA_TLSDESC_FN \
2579 || (RZ_TYPE) == RZ_XTENSA_TLSDESC_ARG \
2580 || (RZ_TYPE) == RZ_XTENSA_TLS_DTPOFF \
2581 || (RZ_TYPE) == RZ_XTENSA_TLS_TPOFF \
2582 || (RZ_TYPE) == RZ_XTENSA_TLS_FUNC \
2583 || (RZ_TYPE) == RZ_XTENSA_TLS_ARG \
2584 || (RZ_TYPE) == RZ_XTENSA_TLS_CALL)
2590 elf_xtensa_relocate_section (
bfd *output_bfd,
2599 struct elf_xtensa_link_hash_table *htab;
2606 char *local_got_tls_types;
2607 char *error_message =
NULL;
2614 BFD_ASSERT (is_xtensa_elf (input_bfd));
2616 htab = elf_xtensa_hash_table (
info);
2620 symtab_hdr = &
elf_tdata (input_bfd)->symtab_hdr;
2622 local_got_tls_types = elf_xtensa_local_got_tls_type (input_bfd);
2626 ltblsize = xtensa_read_table_entries (input_bfd, input_section,
2637 for (; rel < relend; rel++)
2641 unsigned long rz_symndx;
2655 if (rz_type == (
int) RZ_XTENSA_GNU_VTINHERIT
2656 || rz_type == (
int) RZ_XTENSA_GNU_VTENTRY)
2659 if (rz_type < 0 || rz_type >= (
int) RZ_XTENSA_max)
2664 howto = &elf_howto_table[rz_type];
2671 is_weak_undef =
FALSE;
2672 unresolved_reloc =
FALSE;
2685 if (rz_symndx < symtab_hdr->sh_info)
2687 sym = local_syms + rz_symndx;
2689 sec = local_sections[rz_symndx];
2697 rz_symndx, symtab_hdr, sym_hashes,
2699 unresolved_reloc, warned, ignored);
2702 && !unresolved_reloc
2704 is_weak_undef =
TRUE;
2709 if (sec !=
NULL && discarded_section (sec))
2710 RELOC_AGAINST_DISCARDED_SECTION (
info, input_bfd, input_section,
2711 rel, 1, relend, howto, 0, contents);
2713 if (
info->relocatable)
2716 asection * sym_sec = get_elf_r_symndx_section (input_bfd, rz_symndx);
2726 if (relaxing_section)
2729 if (!do_fix_for_relocatable_link (rel, input_bfd, input_section,
2735 + get_elf_r_symndx_offset (input_bfd, rz_symndx) + rel->
rz_addend;
2737 if (rz_type == RZ_XTENSA_ASM_SIMPLIFY)
2739 error_message =
NULL;
2742 r = contract_asm_expansion (contents, input_size, rel,
2746 if (!((*
info->callbacks->reloc_dangerous)
2747 (
info, error_message, input_bfd, input_section,
2758 if (rz_symndx < symtab_hdr->sh_info)
2760 sym = local_syms + rz_symndx;
2763 sec = local_sections[rz_symndx];
2774 howto = &elf_howto_table[rz_type];
2777 r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
2792 if (rz_type >= RZ_XTENSA_SLOT0_OP && rz_type <= RZ_XTENSA_SLOT14_OP &&
2795 r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
2796 dest_addr, contents,
2803 if (!((*
info->callbacks->reloc_dangerous)
2804 (
info, error_message, input_bfd, input_section,
2815 if (relaxing_section)
2818 do_fix_for_final_link (rel, input_bfd, input_section, contents,
2826 (*_bfd_error_handler)
2827 (
_(
"%B(%A+0x%lx): relocation offset out of range (size=0x%x)"),
2828 input_bfd, input_section, rel->
rz_offset, input_size);
2834 name =
h->root.root.string;
2844 && rz_type != RZ_XTENSA_NONE
2848 && IS_XTENSA_TLS_RELOC (rz_type) != (sym_type ==
STT_TLS))
2850 (*_bfd_error_handler)
2852 ?
_(
"%B(%A+0x%lx): %s used with TLS symbol %s")
2853 :
_(
"%B(%A+0x%lx): %s used with non-TLS symbol %s")),
2856 (
long) rel->rz_offset,
2861 dynamic_symbol = elf_xtensa_dynamic_symbol_p (
h,
info);
2863 tls_type = GOT_UNKNOWN;
2865 tls_type = elf_xtensa_hash_entry (
h)->tls_type;
2866 else if (local_got_tls_types)
2867 tls_type = local_got_tls_types [rz_symndx];
2875 && (dynamic_symbol ||
info->shared))
2881 if (dynamic_symbol && rz_type == RZ_XTENSA_PLT)
2882 srel = htab->srelplt;
2884 srel = htab->srelgot;
2886 BFD_ASSERT (srel !=
NULL);
2893 memset (&outrel, 0,
sizeof outrel);
2902 && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
2906 _(
"dynamic relocation in read-only section");
2907 if (!((*
info->callbacks->reloc_dangerous)
2908 (
info, error_message, input_bfd, input_section,
2918 if (rz_type == RZ_XTENSA_32)
2933 elf_xtensa_create_plt_entry (
info, output_bfd,
2936 unresolved_reloc =
FALSE;
2952 else if (rz_type == RZ_XTENSA_ASM_EXPAND && dynamic_symbol)
2961 case RZ_XTENSA_TLS_TPOFF:
2963 if (!
info->shared && ! dynamic_symbol)
2965 relocation = tpoff (
info, relocation);
2970 case RZ_XTENSA_TLSDESC_FN:
2971 case RZ_XTENSA_TLSDESC_ARG:
2973 if (rz_type == RZ_XTENSA_TLSDESC_FN)
2975 if (!
info->shared || (tls_type & GOT_TLS_IE) != 0)
2976 rz_type = RZ_XTENSA_NONE;
2978 else if (rz_type == RZ_XTENSA_TLSDESC_ARG)
2982 if ((tls_type & GOT_TLS_IE) != 0)
2983 rz_type = RZ_XTENSA_TLS_TPOFF;
2987 rz_type = RZ_XTENSA_TLS_TPOFF;
2988 if (! dynamic_symbol)
2990 relocation = tpoff (
info, relocation);
2996 if (rz_type == RZ_XTENSA_NONE)
3003 _(
"TLS relocation invalid without dynamic sections");
3004 if (!((*
info->callbacks->reloc_dangerous)
3005 (
info, error_message, input_bfd, input_section,
3023 && ! elf_xtensa_in_literal_pool (lit_table, ltblsize,
3027 _(
"dynamic relocation in read-only section");
3028 if (!((*
info->callbacks->reloc_dangerous)
3029 (
info, error_message, input_bfd, input_section,
3034 indx =
h &&
h->dynindx != -1 ?
h->dynindx : 0;
3043 unresolved_reloc =
FALSE;
3055 case RZ_XTENSA_TLS_DTPOFF:
3058 relocation = tpoff (
info, relocation);
3060 relocation -= dtpoff_base (
info);
3063 case RZ_XTENSA_TLS_FUNC:
3064 case RZ_XTENSA_TLS_ARG:
3065 case RZ_XTENSA_TLS_CALL:
3067 if ((tls_type & GOT_TLS_IE) != 0)
3070 (
h && elf_xtensa_hash_entry (
h) == htab->tlsbase);
3071 if (! replace_tls_insn (rel, input_bfd, input_section, contents,
3072 is_ld_model, &error_message))
3074 if (!((*
info->callbacks->reloc_dangerous)
3075 (
info, error_message, input_bfd, input_section,
3080 if (rz_type != RZ_XTENSA_TLS_ARG || is_ld_model)
3083 while (rel + 1 < relend && rel[1].rz_offset == rel->
rz_offset)
3091 && dynamic_symbol && (is_operand_relocation (rz_type)
3092 || rz_type == RZ_XTENSA_32_PCREL))
3095 vsprint_msg (
"invalid relocation for dynamic symbol",
": %s",
3097 if (!((*
info->callbacks->reloc_dangerous)
3098 (
info, error_message, input_bfd, input_section,
3109 if (unresolved_reloc
3115 (*_bfd_error_handler)
3116 (
_(
"%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
3126 howto = &elf_howto_table[rz_type];
3130 r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
3132 contents, rel->
rz_offset, is_weak_undef,
3138 BFD_ASSERT (error_message !=
NULL);
3141 error_message = vsprint_msg (error_message,
": %s",
3144 error_message = vsprint_msg (error_message,
": (%s+0x%x)",
3148 if (!((*
info->callbacks->reloc_dangerous)
3149 (
info, error_message, input_bfd, input_section,
3173 if (
h->needs_plt && !
h->def_regular)
3182 if (!
h->ref_regular_nonweak)
3205 elf_xtensa_combine_prop_entries (
bfd *output_bfd,
3215 section_size = sxtlit->
size;
3216 BFD_ASSERT (section_size % 8 == 0);
3217 num = section_size / 8;
3219 sgotloc_size = sgotloc->
size;
3220 if (sgotloc_size != section_size)
3222 (*_bfd_error_handler)
3223 (
_(
"internal inconsistency in size of .got.loc section"));
3249 for (
n = 0;
n <
num;
n++)
3257 for (
n = 0;
n <
num;
n++)
3261 if (table[
n].
size == 0)
3262 remove_entry =
TRUE;
3264 && (table[
n-1].address + table[
n-1].
size == table[
n].address))
3267 remove_entry =
TRUE;
3285 for (
n = 0;
n <
num;
n++)
3294 memset (&contents[
num * 8], 0, section_size -
num * 8);
3312 elf_xtensa_finish_dynamic_sections (
bfd *output_bfd,
3315 struct elf_xtensa_link_hash_table *htab;
3317 asection *sdyn, *srelplt, *sgot, *sxtlit, *sgotloc;
3319 int num_xtlit_entries = 0;
3324 htab = elf_xtensa_hash_table (
info);
3329 sdyn = bfd_get_linker_section (dynobj,
".dynamic");
3330 BFD_ASSERT (sdyn !=
NULL);
3337 BFD_ASSERT (sgot->
size == 4);
3346 srelplt = htab->srelplt;
3347 if (srelplt && srelplt->
size != 0)
3349 asection *sgotplt, *srelgot, *spltlittbl;
3350 int chunk, plt_chunks, plt_entries;
3353 unsigned rtld_reloc;
3355 srelgot = htab->srelgot;
3356 spltlittbl = htab->spltlittbl;
3357 BFD_ASSERT (srelgot !=
NULL && spltlittbl !=
NULL);
3361 for (rtld_reloc = 0; rtld_reloc < srelgot->
reloc_count; rtld_reloc++)
3368 BFD_ASSERT (rtld_reloc < srelgot->reloc_count);
3372 (plt_entries + PLT_ENTRIES_PER_CHUNK - 1) / PLT_ENTRIES_PER_CHUNK;
3376 int chunk_entries = 0;
3378 sgotplt = elf_xtensa_get_gotplt_section (
info,
chunk);
3379 BFD_ASSERT (sgotplt !=
NULL);
3392 BFD_ASSERT (rtld_reloc <= srelgot->reloc_count);
3404 BFD_ASSERT (rtld_reloc <= srelgot->reloc_count);
3407 if (
chunk < plt_chunks - 1)
3408 chunk_entries = PLT_ENTRIES_PER_CHUNK;
3410 chunk_entries = plt_entries - (
chunk * PLT_ENTRIES_PER_CHUNK);
3412 BFD_ASSERT ((
unsigned) (
chunk + 1) * 8 <= spltlittbl->
size);
3417 8 + (chunk_entries * 4),
3444 BFD_ASSERT (!
info->relocatable);
3446 sgotloc = htab->sgotloc;
3447 BFD_ASSERT (sgotloc);
3451 elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc);
3452 if (num_xtlit_entries < 0)
3458 for (; dyncon < dynconend; dyncon++)
3474 dyn.
d_un.
d_ptr = htab->sgotloc->output_section->vma;
3478 dyn.
d_un.
d_ptr = htab->sgot->output_section->vma;
3482 dyn.
d_un.
d_ptr = htab->srelplt->output_section->vma;
3486 dyn.
d_un.
d_val = htab->srelplt->output_section->size;
3497 dyn.
d_un.
d_val -= htab->srelplt->output_section->size;
3514 elf_xtensa_merge_private_bfd_data (
bfd *ibfd,
bfd *obfd)
3516 unsigned out_mach, in_mach;
3520 if (!_bfd_generic_verify_endian_match (ibfd, obfd))
3533 if (out_mach != in_mach)
3535 (*_bfd_error_handler)
3536 (
_(
"%B: incompatible machine type. Output is 0x%x. Input is 0x%x"),
3537 ibfd, out_mach, in_mach);
3579 elf_xtensa_print_private_bfd_data (
bfd *abfd,
void *farg)
3584 fprintf (
f,
"\nXtensa header:\n");
3586 fprintf (
f,
"\nMachine = Base\n");
3590 fprintf (
f,
"Insn tables = %s\n",
3593 fprintf (
f,
"Literal tables = %s\n",
3603 elf_xtensa_object_p (
bfd *abfd)
3627 elf_xtensa_final_write_processing (
bfd *abfd,
3654 case RZ_XTENSA_RELATIVE:
3656 case RZ_XTENSA_JMP_SLOT:
3665 elf_xtensa_discard_info_for_section (
bfd *abfd,
3679 if (xtensa_is_proptable_section (sec))
3684 if (sec->
size == 0 || sec->
size % entry_size != 0)
3687 contents = retrieve_contents (abfd, sec,
info->keep_memory);
3691 cookie->
rels = retrieve_internal_relocs (abfd, sec,
info->keep_memory);
3694 release_contents (sec, contents);
3701 internal_reloc_compare);
3708 actual_offset =
offset - removed_bytes;
3731 memmove (&contents[actual_offset],
3732 &contents[actual_offset + entry_size],
3734 removed_bytes += entry_size;
3755 if (removed_bytes != 0)
3767 memset (&contents[sec->
size - removed_bytes], 0, removed_bytes);
3769 pin_contents (sec, contents);
3770 pin_internal_relocs (sec, cookie->
rels);
3775 sec->
size -= removed_bytes;
3777 if (xtensa_is_littable_section (sec))
3779 asection *sgotloc = elf_xtensa_hash_table (
info)->sgotloc;
3781 sgotloc->
size -= removed_bytes;
3786 release_contents (sec, contents);
3787 release_internal_relocs (sec, cookie->
rels);
3790 return (removed_bytes != 0);
3795 elf_xtensa_discard_info (
bfd *abfd,
3804 if (xtensa_is_property_section (sec))
3806 if (elf_xtensa_discard_info_for_section (abfd, cookie,
info, sec))
3816 elf_xtensa_ignore_discarded_relocs (
asection *sec)
3818 return xtensa_is_property_section (sec);
3823 elf_xtensa_action_discarded (
asection *sec)
3825 if (strcmp (
".xt_except_table", sec->
name) == 0)
3828 if (strcmp (
".xt_except_desc", sec->
name) == 0)
3905 init_call_opcodes (
void)
3924 init_call_opcodes ();
3925 return (opcode == callx0_op
3926 || opcode == callx4_op
3927 || opcode == callx8_op
3928 || opcode == callx12_op);
3935 init_call_opcodes ();
3936 return (opcode == call0_op
3937 || opcode == call4_op
3938 || opcode == call8_op
3939 || opcode == call12_op);
3946 init_call_opcodes ();
3947 return (opcode == call4_op
3948 || opcode == call8_op
3949 || opcode == call12_op
3950 || opcode == callx4_op
3951 || opcode == callx8_op
3952 || opcode == callx12_op);
3957 get_indirect_call_dest_reg (
xtensa_opcode opcode,
unsigned *pdst)
3961 init_call_opcodes ();
3962 if (opcode == callx0_op)
3964 else if (opcode == callx4_op)
3966 else if (opcode == callx8_op)
3968 else if (opcode == callx12_op)
3971 if (
dst == (
unsigned) -1)
3980 get_const16_opcode (
void)
3989 return const16_opcode;
3994 get_l32r_opcode (
void)
4014 BFD_ASSERT ((
offset & ((1 << 2) - 1)) == 0);
4016 BFD_ASSERT ((
signed int)
offset >> 16 == -1);
4025 int last_immed, last_opnd, opi;
4035 for (opi = last_opnd - 1; opi >= 0; opi--)
4053 if (rz_type >= RZ_XTENSA_OP0 && rz_type <= RZ_XTENSA_OP2)
4055 int reloc_opnd = rz_type - RZ_XTENSA_OP0;
4056 if (reloc_opnd != last_immed)
4065 get_relocation_slot (
int rz_type)
4075 if (rz_type >= RZ_XTENSA_SLOT0_OP && rz_type <= RZ_XTENSA_SLOT14_OP)
4076 return rz_type - RZ_XTENSA_SLOT0_OP;
4077 if (rz_type >= RZ_XTENSA_SLOT0_ALT && rz_type <= RZ_XTENSA_SLOT14_ALT)
4078 return rz_type - RZ_XTENSA_SLOT0_ALT;
4089 get_relocation_opcode (
bfd *abfd,
4100 if (contents ==
NULL)
4125 is_l32r_relocation (
bfd *abfd,
4133 opcode = get_relocation_opcode (abfd, sec, contents, irel);
4134 return (opcode == get_l32r_opcode ());
4139 get_asm_simplify_size (
bfd_byte *contents,
4146 insnlen = insn_decode_len (contents, content_len,
offset);
4152 insnlen = insn_decode_len (contents, content_len,
offset +
size);
4162 is_alt_relocation (
int rz_type)
4164 return (rz_type >= RZ_XTENSA_SLOT0_ALT
4165 && rz_type <= RZ_XTENSA_SLOT14_ALT);
4170 is_operand_relocation (
int rz_type)
4180 if (rz_type >= RZ_XTENSA_SLOT0_OP && rz_type <= RZ_XTENSA_SLOT14_OP)
4182 if (rz_type >= RZ_XTENSA_SLOT0_ALT && rz_type <= RZ_XTENSA_SLOT14_ALT)
4191 #define MIN_INSN_LENGTH 2
4196 insn_decode_len (
bfd_byte *contents,
4205 if (
offset + MIN_INSN_LENGTH > content_len)
4226 insn_decode_opcode (
bfd_byte *contents,
4236 if (
offset + MIN_INSN_LENGTH > content_len)
4239 if (insnbuf ==
NULL)
4263 check_branch_target_aligned (
bfd_byte *contents,
4271 return check_branch_target_aligned_address (address, insn_len);
4276 check_loop_aligned (
bfd_byte *contents,
4284 opcode = insn_decode_opcode (contents, content_length,
offset, 0);
4292 loop_len = insn_decode_len (contents, content_length,
offset);
4293 insn_len = insn_decode_len (contents, content_length,
offset + loop_len);
4294 if (loop_len == 0 || insn_len == 0)
4300 return check_branch_target_aligned_address (address + loop_len, insn_len);
4308 return (
addr % 8 == 0);
4325 init_op_single_format_table (
void)
4333 if (op_single_fmt_table)
4341 for (opcode = 0; opcode < num_opcodes; opcode++)
4353 op_single_fmt_table[opcode] = fmt;
4364 init_op_single_format_table ();
4365 return op_single_fmt_table[opcode];
4381 struct string_pair narrowable[] =
4384 {
"addi",
"addi.n" },
4385 {
"addmi",
"addi.n" },
4386 {
"l32i",
"l32i.n" },
4387 {
"movi",
"movi.n" },
4389 {
"retw",
"retw.n" },
4390 {
"s32i",
"s32i.n" },
4394 struct string_pair widenable[] =
4397 {
"addi",
"addi.n" },
4398 {
"addmi",
"addi.n" },
4399 {
"beqz",
"beqz.n" },
4400 {
"bnez",
"bnez.n" },
4401 {
"l32i",
"l32i.n" },
4402 {
"movi",
"movi.n" },
4404 {
"retw",
"retw.n" },
4405 {
"s32i",
"s32i.n" },
4428 if (o_insnbuf ==
NULL)
4434 for (opi = 0; opi < (
sizeof (narrowable)/
sizeof (
struct string_pair)); opi++)
4436 bfd_boolean is_or = (strcmp (
"or", narrowable[opi].wide) == 0);
4441 int i, operand_count, o_operand_count;
4451 o_fmt = get_single_format (o_opcode);
4473 uint32 rawval0, rawval1, rawval2;
4475 if (o_operand_count + 1 != operand_count
4477 fmt, 0, slotbuf, &rawval0) != 0
4479 fmt, 0, slotbuf, &rawval1) != 0
4481 fmt, 0, slotbuf, &rawval2) != 0
4482 || rawval1 != rawval2
4483 || rawval0 == rawval1 )
4487 for (
i = 0;
i < o_operand_count; ++
i)
4520 narrow_instruction (
bfd_byte *contents,
4533 if (insnbuf ==
NULL)
4539 BFD_ASSERT (
offset < content_length);
4541 if (content_length < 2)
4547 content_length -
offset);
4559 if (insn_len > content_length)
4562 o_insnbuf = can_narrow_instruction (slotbuf, fmt, opcode);
4566 content_length -
offset);
4592 if (o_insnbuf ==
NULL)
4598 for (opi = 0; opi < (
sizeof (widenable)/
sizeof (
struct string_pair)); opi++)
4600 bfd_boolean is_or = (strcmp (
"or", widenable[opi].wide) == 0);
4602 || strcmp (
"bnez", widenable[opi].wide) == 0);
4607 int i, operand_count, o_operand_count, check_operand_count;
4617 o_fmt = get_single_format (o_opcode);
4628 check_operand_count = o_operand_count;
4642 if (o_operand_count != operand_count + 1
4644 fmt, 0, slotbuf, &rawval0) != 0
4646 fmt, 0, slotbuf, &rawval1) != 0
4647 || rawval0 == rawval1 )
4651 check_operand_count--;
4653 for (
i = 0;
i < check_operand_count;
i++)
4656 if (is_or &&
i == o_operand_count - 1)
4689 widen_instruction (
bfd_byte *contents,
4702 if (insnbuf ==
NULL)
4708 BFD_ASSERT (
offset < content_length);
4710 if (content_length < 2)
4716 content_length -
offset);
4728 if (insn_len > content_length)
4731 o_insnbuf = can_widen_instruction (slotbuf, fmt, opcode);
4735 content_length -
offset);
4745 elf_xtensa_do_asm_simplify (
bfd_byte *contents,
4748 char **error_message)
4756 bfd_byte *chbuf = contents + address;
4759 if (insnbuf ==
NULL)
4765 if (content_length < address)
4767 *error_message =
_(
"Attempt to convert L32R/CALLX to CALL failed");
4771 opcode = get_expanded_call_opcode (chbuf, content_length - address, 0);
4772 direct_call_opcode = swap_callx_for_call_opcode (opcode);
4775 *error_message =
_(
"Attempt to convert L32R/CALLX to CALL failed");
4783 for (opn = 0; opn < 3; opn++)
4801 content_length - address - 3);
4808 contract_asm_expansion (
bfd_byte *contents,
4811 char **error_message)
4814 elf_xtensa_do_asm_simplify (contents, irel->
rz_offset, content_length,
4831 init_call_opcodes ();
4833 if (opcode == callx0_op)
return call0_op;
4834 if (opcode == callx4_op)
return call4_op;
4835 if (opcode == callx8_op)
return call8_op;
4836 if (opcode == callx12_op)
return call12_op;
4847 #define L32R_TARGET_REG_OPERAND 0
4848 #define CONST16_TARGET_REG_OPERAND 0
4849 #define CALLN_SOURCE_OPERAND 0
4859 uint32 regno, const16_regno, call_regno;
4862 if (insnbuf ==
NULL)
4878 if (opcode == get_l32r_opcode ())
4881 *p_uses_l32r =
TRUE;
4883 fmt, 0, slotbuf, ®no)
4888 else if (opcode == get_const16_opcode ())
4891 *p_uses_l32r =
FALSE;
4893 fmt, 0, slotbuf, ®no)
4906 if (opcode != get_const16_opcode ())
4910 fmt, 0, slotbuf, &const16_regno)
4913 || const16_regno != regno)
4928 || !is_indirect_call_opcode (opcode))
4932 fmt, 0, slotbuf, &call_regno)
4937 if (call_regno != regno)
4963 typedef struct rz_reloc_struct rz_reloc;
4965 struct rz_reloc_struct
4981 rz_reloc_is_const (
const rz_reloc *rz_rel)
4983 return (rz_rel->abfd ==
NULL);
4988 rz_reloc_get_target_offset (
const rz_reloc *rz_rel)
4991 unsigned long rz_symndx;
4993 BFD_ASSERT (!rz_reloc_is_const (rz_rel));
4995 target_offset = get_elf_r_symndx_offset (rz_rel->abfd, rz_symndx);
4996 return (target_offset + rz_rel->rela.rz_addend);
5001 rz_reloc_get_hash_entry (
const rz_reloc *rz_rel)
5003 unsigned long rz_symndx =
ELF32_R_SYM (rz_rel->rela.rz_info);
5004 return get_elf_r_symndx_hash_entry (rz_rel->abfd, rz_symndx);
5009 rz_reloc_get_section (
const rz_reloc *rz_rel)
5011 unsigned long rz_symndx =
ELF32_R_SYM (rz_rel->rela.rz_info);
5012 return get_elf_r_symndx_section (rz_rel->abfd, rz_symndx);
5017 rz_reloc_is_defined (
const rz_reloc *rz_rel)
5023 sec = rz_reloc_get_section (rz_rel);
5033 rz_reloc_init (rz_reloc *rz_rel,
5044 rz_rel->rela = *irel;
5045 rz_rel->abfd = abfd;
5046 rz_rel->target_offset = rz_reloc_get_target_offset (rz_rel);
5047 rz_rel->virtual_offset = 0;
5049 howto = &elf_howto_table[rz_type];
5053 BFD_ASSERT (rz_rel->rela.rz_offset < content_length);
5055 inplace_val =
bfd_get_32 (abfd, &contents[rz_rel->rela.rz_offset]);
5056 rz_rel->target_offset += inplace_val;
5060 memset (rz_rel, 0,
sizeof (rz_reloc));
5067 print_r_reloc (
FILE *fp,
const rz_reloc *rz_rel)
5069 if (rz_reloc_is_defined (rz_rel))
5071 asection *sec = rz_reloc_get_section (rz_rel);
5074 else if (rz_reloc_get_hash_entry (rz_rel))
5075 fprintf (fp,
" %s + ", rz_reloc_get_hash_entry (rz_rel)->
root.root.string);
5077 fprintf (fp,
" ?? + ");
5080 if (rz_rel->virtual_offset)
5082 fprintf (fp,
" + ");
5109 typedef struct source_reloc_struct source_reloc;
5111 struct source_reloc_struct
5123 init_source_reloc (source_reloc *reloc,
5125 const rz_reloc *rz_rel,
5130 reloc->source_sec = source_sec;
5131 reloc->rz_rel = *rz_rel;
5132 reloc->opcode = opcode;
5134 reloc->is_null =
FALSE;
5135 reloc->is_abs_literal = is_abs_literal;
5143 static source_reloc *
5144 find_source_reloc (source_reloc *src_relocs,
5151 for (
i = 0;
i < src_count;
i++)
5153 if (src_relocs[
i].source_sec == sec
5154 && src_relocs[
i].rz_rel.rela.rz_offset == irel->
rz_offset
5157 return &src_relocs[
i];
5165 source_reloc_compare (
const void *ap,
const void *bp)
5167 const source_reloc *
a = (
const source_reloc *) ap;
5168 const source_reloc *
b = (
const source_reloc *) bp;
5170 if (
a->rz_rel.target_offset !=
b->rz_rel.target_offset)
5171 return (
a->rz_rel.target_offset -
b->rz_rel.target_offset);
5180 if ((!
a->is_null) - (!
b->is_null))
5181 return ((!
a->is_null) - (!
b->is_null));
5182 return internal_reloc_compare (&
a->rz_rel.rela, &
b->rz_rel.rela);
5199 typedef struct literal_value_struct literal_value;
5200 typedef struct value_map_struct value_map;
5201 typedef struct value_map_hash_table_struct value_map_hash_table;
5203 struct literal_value_struct
5206 unsigned long value;
5210 struct value_map_struct
5217 struct value_map_hash_table_struct
5219 unsigned bucket_count;
5220 value_map **buckets;
5228 init_literal_value (literal_value *lit,
5229 const rz_reloc *rz_rel,
5230 unsigned long value,
5233 lit->rz_rel = *rz_rel;
5235 lit->is_abs_literal = is_abs_literal;
5240 literal_value_equal (
const literal_value *src1,
5241 const literal_value *src2,
5246 if (rz_reloc_is_const (&src1->rz_rel) != rz_reloc_is_const (&src2->rz_rel))
5249 if (rz_reloc_is_const (&src1->rz_rel))
5250 return (src1->value == src2->value);
5256 if (src1->rz_rel.target_offset != src2->rz_rel.target_offset)
5259 if (src1->rz_rel.virtual_offset != src2->rz_rel.virtual_offset)
5262 if (src1->value != src2->value)
5267 h1 = rz_reloc_get_hash_entry (&src1->rz_rel);
5268 h2 = rz_reloc_get_hash_entry (&src2->rz_rel);
5269 if (rz_reloc_is_defined (&src1->rz_rel)
5270 && (final_static_link
5274 if (rz_reloc_get_section (&src1->rz_rel)
5275 != rz_reloc_get_section (&src2->rz_rel))
5285 if (src1->is_abs_literal != src2->is_abs_literal)
5293 #define INITIAL_HASH_RELOC_BUCKET_COUNT 1024
5295 static value_map_hash_table *
5296 value_map_hash_table_init (
void)
5298 value_map_hash_table *values;
5300 values = (value_map_hash_table *)
5301 bfd_zmalloc (
sizeof (value_map_hash_table));
5302 values->bucket_count = INITIAL_HASH_RELOC_BUCKET_COUNT;
5304 values->buckets = (value_map **)
5305 bfd_zmalloc (
sizeof (value_map *) * values->bucket_count);
5306 if (values->buckets ==
NULL)
5311 values->has_last_loc =
FALSE;
5318 value_map_hash_table_delete (value_map_hash_table *table)
5320 free (table->buckets);
5328 return (
val >> 2) + (
val >> 10);
5333 literal_value_hash (
const literal_value *
src)
5337 hash_val = hash_bfd_vma (
src->value);
5338 if (!rz_reloc_is_const (&
src->rz_rel))
5342 hash_val += hash_bfd_vma (
src->is_abs_literal * 1000);
5343 hash_val += hash_bfd_vma (
src->rz_rel.target_offset);
5344 hash_val += hash_bfd_vma (
src->rz_rel.virtual_offset);
5347 if (rz_reloc_is_defined (&
src->rz_rel))
5348 sec_or_hash = rz_reloc_get_section (&
src->rz_rel);
5350 sec_or_hash = rz_reloc_get_hash_entry (&
src->rz_rel);
5351 hash_val += hash_bfd_vma ((
bfd_vma) (
size_t) sec_or_hash);
5360 value_map_get_cached_value (value_map_hash_table *
map,
5361 const literal_value *
val,
5368 idx = literal_value_hash (
val);
5370 bucket =
map->buckets[
idx];
5371 for (map_e = bucket; map_e; map_e = map_e->next)
5373 if (literal_value_equal (&map_e->val,
val, final_static_link))
5384 add_value_map (value_map_hash_table *
map,
5385 const literal_value *
val,
5386 const rz_reloc *loc,
5389 value_map **bucket_p;
5392 value_map *val_e = (value_map *) bfd_zmalloc (
sizeof (value_map));
5399 BFD_ASSERT (!value_map_get_cached_value (
map,
val, final_static_link));
5403 idx = literal_value_hash (
val);
5405 bucket_p = &
map->buckets[
idx];
5407 val_e->next = *bucket_p;
5443 typedef struct text_action_struct text_action;
5444 typedef struct text_action_list_struct text_action_list;
5445 typedef enum text_action_enum_t text_action_t;
5447 enum text_action_enum_t
5452 ta_convert_longcall,
5462 struct text_action_struct
5469 literal_value
value;
5472 struct removal_by_action_entry_struct
5477 int eq_removed_before_fill;
5479 typedef struct removal_by_action_entry_struct removal_by_action_entry;
5481 struct removal_by_action_map_struct
5484 removal_by_action_entry *
entry;
5486 typedef struct removal_by_action_map_struct removal_by_action_map;
5490 struct text_action_list_struct
5494 removal_by_action_map
map;
5498 static text_action *
5510 splay_tree_node node = splay_tree_lookup (l->tree, (splay_tree_key)&
a);
5512 return (text_action *)node->value;
5518 compute_removed_action_diff (
const text_action *ta,
5522 int removable_space)
5525 int current_removed = 0;
5528 current_removed = ta->removed_bytes;
5530 BFD_ASSERT (ta ==
NULL || ta->offset ==
offset);
5531 BFD_ASSERT (ta ==
NULL || ta->action == ta_fill);
5535 new_removed = removable_space - 0;
5539 int added = -removed - current_removed;
5542 new_removed = (-added);
5545 space = removable_space - new_removed;
5546 new_removed = (removable_space
5549 return (new_removed - current_removed);
5554 adjust_fill_action (text_action *ta,
int fill_diff)
5556 ta->removed_bytes += fill_diff;
5561 text_action_compare (splay_tree_key
a, splay_tree_key
b)
5563 text_action *pa = (text_action *)
a;
5564 text_action *pb = (text_action *)
b;
5565 static const int action_priority[] =
5569 [ta_convert_longcall] = 2,
5570 [ta_narrow_insn] = 3,
5571 [ta_remove_insn] = 4,
5572 [ta_remove_longcall] = 5,
5573 [ta_remove_literal] = 6,
5574 [ta_widen_insn] = 7,
5575 [ta_add_literal] = 8,
5578 if (pa->offset == pb->offset)
5580 if (pa->action == pb->action)
5582 return action_priority[pa->action] - action_priority[pb->action];
5585 return pa->offset < pb->offset ? -1 : 1;
5588 static text_action *
5589 action_first (text_action_list *action_list)
5591 splay_tree_node node = splay_tree_min (action_list->tree);
5592 return node ? (text_action *)node->value :
NULL;
5595 static text_action *
5596 action_next (text_action_list *action_list, text_action *
action)
5598 splay_tree_node node = splay_tree_successor (action_list->tree,
5600 return node ? (text_action *)node->value :
NULL;
5609 text_action_add (text_action_list *l,
5623 if (
action == ta_fill && removed == 0)
5631 splay_tree_node node = splay_tree_lookup (l->tree, (splay_tree_key)&
a);
5635 ta = (text_action *)node->value;
5636 ta->removed_bytes += removed;
5641 BFD_ASSERT (splay_tree_lookup (l->tree, (splay_tree_key)&
a) ==
NULL);
5643 ta = (text_action *) bfd_zmalloc (
sizeof (text_action));
5647 ta->removed_bytes = removed;
5648 splay_tree_insert (l->tree, (splay_tree_key)ta, (splay_tree_value)ta);
5654 text_action_add_literal (text_action_list *l,
5656 const rz_reloc *loc,
5657 const literal_value *
value,
5661 asection *sec = rz_reloc_get_section (loc);
5663 bfd_vma virtual_offset = loc->virtual_offset;
5665 BFD_ASSERT (
action == ta_add_literal);
5668 ta = (text_action *) bfd_zmalloc (
sizeof (text_action));
5672 ta->virtual_offset = virtual_offset;
5674 ta->removed_bytes = removed;
5676 BFD_ASSERT (splay_tree_lookup (l->tree, (splay_tree_key)ta) ==
NULL);
5677 splay_tree_insert (l->tree, (splay_tree_key)ta, (splay_tree_value)ta);
5689 removed_by_actions (text_action_list *action_list,
5690 text_action **p_start_action,
5697 r = *p_start_action;
5700 splay_tree_node node = splay_tree_lookup (action_list->tree,
5702 BFD_ASSERT (node !=
NULL &&
r == (text_action *)node->value);
5711 && (before_fill ||
r->action != ta_fill ||
r->removed_bytes >= 0))
5714 removed +=
r->removed_bytes;
5716 r = action_next (action_list,
r);
5719 *p_start_action =
r;
5725 offset_with_removed_text (text_action_list *action_list,
bfd_vma offset)
5727 text_action *
r = action_first (action_list);
5734 action_list_count (text_action_list *action_list)
5736 return action_list->count;
5739 typedef struct map_action_fn_context_struct map_action_fn_context;
5740 struct map_action_fn_context_struct
5743 removal_by_action_map
map;
5748 map_action_fn (splay_tree_node node,
void *
p)
5750 map_action_fn_context *
ctx =
p;
5751 text_action *
r = (text_action *)node->value;
5752 removal_by_action_entry *ientry =
ctx->map.entry +
ctx->map.n_entries;
5754 if (
ctx->map.n_entries && (ientry - 1)->offset ==
r->offset)
5760 ++
ctx->map.n_entries;
5762 ientry->offset =
r->offset;
5763 ientry->eq_removed_before_fill =
ctx->removed;
5766 if (!
ctx->eq_complete)
5768 if (
r->action != ta_fill ||
r->removed_bytes >= 0)
5770 ientry->eq_removed =
ctx->removed;
5774 ientry->eq_removed =
ctx->removed +
r->removed_bytes;
5777 ctx->removed +=
r->removed_bytes;
5778 ientry->removed =
ctx->removed;
5783 map_removal_by_action (text_action_list *action_list)
5785 map_action_fn_context
ctx;
5788 ctx.map.n_entries = 0;
5789 ctx.map.entry =
bfd_malloc (action_list_count (action_list) *
5790 sizeof (removal_by_action_entry));
5793 splay_tree_foreach (action_list->tree, map_action_fn, &
ctx);
5794 action_list->map =
ctx.map;
5798 removed_by_actions_map (text_action_list *action_list,
bfd_vma offset,
5803 if (!action_list->map.entry)
5804 map_removal_by_action (action_list);
5806 if (!action_list->map.n_entries)
5810 b = action_list->map.n_entries;
5814 unsigned c = (
a +
b) / 2;
5816 if (action_list->map.entry[
c].offset <=
offset)
5822 if (action_list->map.entry[
a].offset <
offset)
5824 return action_list->map.entry[
a].removed;
5826 else if (action_list->map.entry[
a].offset ==
offset)
5828 return before_fill ?
5829 action_list->map.entry[
a].eq_removed_before_fill :
5830 action_list->map.entry[
a].eq_removed;
5839 offset_with_removed_text_map (text_action_list *action_list,
bfd_vma offset)
5841 int removed = removed_by_actions_map (action_list,
offset,
FALSE);
5848 static text_action *
5849 find_insn_action (text_action_list *action_list,
bfd_vma offset)
5851 static const text_action_t
action[] =
5853 ta_convert_longcall,
5865 splay_tree_node node;
5868 node = splay_tree_lookup (action_list->tree, (splay_tree_key)&
a);
5870 return (text_action *)node->value;
5879 print_action (
FILE *fp, text_action *
r)
5881 const char *t =
"unknown";
5884 case ta_remove_insn:
5885 t =
"remove_insn";
break;
5886 case ta_remove_longcall:
5887 t =
"remove_longcall";
break;
5888 case ta_convert_longcall:
5889 t =
"convert_longcall";
break;
5890 case ta_narrow_insn:
5891 t =
"narrow_insn";
break;
5893 t =
"widen_insn";
break;
5898 case ta_remove_literal:
5899 t =
"remove_literal";
break;
5900 case ta_add_literal:
5901 t =
"add_literal";
break;
5904 fprintf (fp,
"%s: %s[0x%lx] \"%s\" %d\n",
5905 r->sec->owner->filename,
5906 r->sec->name, (
unsigned long)
r->offset, t,
r->removed_bytes);
5910 print_action_list_fn (splay_tree_node node,
void *
p)
5912 text_action *
r = (text_action *)node->value;
5914 print_action (
p,
r);
5919 print_action_list (
FILE *fp, text_action_list *action_list)
5921 fprintf (fp,
"Text Action\n");
5922 splay_tree_foreach (action_list->tree, print_action_list_fn, fp);
5936 typedef struct removed_literal_struct removed_literal;
5937 typedef struct removed_literal_map_entry_struct removed_literal_map_entry;
5938 typedef struct removed_literal_list_struct removed_literal_list;
5940 struct removed_literal_struct
5944 removed_literal *next;
5947 struct removed_literal_map_entry_struct
5953 struct removed_literal_list_struct
5955 removed_literal *
head;
5956 removed_literal *tail;
5959 removed_literal_map_entry *
map;
5967 add_removed_literal (removed_literal_list *removed_list,
5968 const rz_reloc *
from,
5971 removed_literal *
r, *new_r, *next_r;
5973 new_r = (removed_literal *) bfd_zmalloc (
sizeof (removed_literal));
5975 new_r->from = *
from;
5979 new_r->to.abfd =
NULL;
5982 r = removed_list->head;
5985 removed_list->head = new_r;
5986 removed_list->tail = new_r;
5989 else if (removed_list->tail->from.target_offset <
from->target_offset)
5991 removed_list->tail->next = new_r;
5992 removed_list->tail = new_r;
5996 while (
r->from.target_offset <
from->target_offset &&
r->next)
6002 new_r->next = next_r;
6004 removed_list->tail = new_r;
6009 map_removed_literal (removed_literal_list *removed_list)
6013 removed_literal_map_entry *
map =
NULL;
6014 removed_literal *
r = removed_list->head;
6016 for (
i = 0;
r; ++
i,
r =
r->next)
6020 n_map = (n_map * 2) + 2;
6021 map = bfd_realloc (
map, n_map *
sizeof (*
map));
6023 map[
i].addr =
r->from.target_offset;
6026 removed_list->map =
map;
6027 removed_list->n_map =
i;
6031 removed_literal_compare (
const void *
a,
const void *
b)
6033 const removed_literal_map_entry *pa =
a;
6034 const removed_literal_map_entry *pb =
b;
6036 if (pa->addr == pb->addr)
6039 return pa->addr < pb->addr ? -1 : 1;
6045 static removed_literal *
6046 find_removed_literal (removed_literal_list *removed_list,
bfd_vma addr)
6048 removed_literal_map_entry *
p;
6049 removed_literal *
r =
NULL;
6051 if (removed_list->map ==
NULL)
6052 map_removed_literal (removed_list);
6054 p = bsearch (&
addr, removed_list->map, removed_list->n_map,
6055 sizeof (*removed_list->map), removed_literal_compare);
6058 while (
p != removed_list->map && (
p - 1)->addr ==
addr)
6069 print_removed_literals (
FILE *fp, removed_literal_list *removed_list)
6072 r = removed_list->head;
6074 fprintf (fp,
"Removed Literals\n");
6075 for (;
r !=
NULL;
r =
r->next)
6077 print_r_reloc (fp, &
r->from);
6078 fprintf (fp,
" => ");
6079 if (
r->to.abfd ==
NULL)
6080 fprintf (fp,
"REMOVED");
6082 print_r_reloc (fp, &
r->to);
6092 typedef struct reloc_bfd_fix_struct reloc_bfd_fix;
6094 struct xtensa_relax_info_struct
6100 source_reloc *src_relocs;
6104 removed_literal_list removed_list;
6105 text_action_list action_list;
6107 reloc_bfd_fix *fix_list;
6108 reloc_bfd_fix *fix_array;
6109 unsigned fix_array_count;
6117 unsigned relocs_count;
6118 unsigned allocated_relocs_count;
6121 struct elf_xtensa_section_data
6124 xtensa_relax_info relax_info;
6129 elf_xtensa_new_section_hook (
bfd *abfd,
asection *sec)
6133 struct elf_xtensa_section_data *sdata;
6146 static xtensa_relax_info *
6147 get_xtensa_relax_info (
asection *sec)
6149 struct elf_xtensa_section_data *section_data;
6156 return §ion_data->relax_info;
6161 init_xtensa_relax_info (
asection *sec)
6163 xtensa_relax_info *relax_info = get_xtensa_relax_info (sec);
6165 relax_info->is_relaxable_literal_section =
FALSE;
6166 relax_info->is_relaxable_asm_section =
FALSE;
6167 relax_info->visited = 0;
6169 relax_info->src_relocs =
NULL;
6170 relax_info->src_count = 0;
6171 relax_info->src_next = 0;
6173 relax_info->removed_list.head =
NULL;
6174 relax_info->removed_list.tail =
NULL;
6176 relax_info->action_list.tree = splay_tree_new (text_action_compare,
6178 relax_info->action_list.map.n_entries = 0;
6179 relax_info->action_list.map.entry =
NULL;
6181 relax_info->fix_list =
NULL;
6182 relax_info->fix_array =
NULL;
6183 relax_info->fix_array_count = 0;
6185 relax_info->allocated_relocs =
NULL;
6186 relax_info->relocs_count = 0;
6187 relax_info->allocated_relocs_count = 0;
6200 struct reloc_bfd_fix_struct
6210 reloc_bfd_fix *next;
6214 static reloc_bfd_fix *
6215 reloc_bfd_fix_init (
asection *src_sec,
6224 fix = (reloc_bfd_fix *)
bfd_malloc (
sizeof (reloc_bfd_fix));
6225 fix->src_sec = src_sec;
6226 fix->src_offset = src_offset;
6227 fix->src_type = src_type;
6228 fix->target_sec = target_sec;
6229 fix->target_offset = target_offset;
6230 fix->translated = translated;
6237 add_fix (
asection *src_sec, reloc_bfd_fix *fix)
6239 xtensa_relax_info *relax_info;
6241 relax_info = get_xtensa_relax_info (src_sec);
6242 fix->next = relax_info->fix_list;
6243 relax_info->fix_list = fix;
6248 fix_compare (
const void *ap,
const void *bp)
6250 const reloc_bfd_fix *
a = (
const reloc_bfd_fix *) ap;
6251 const reloc_bfd_fix *
b = (
const reloc_bfd_fix *) bp;
6253 if (
a->src_offset !=
b->src_offset)
6254 return (
a->src_offset -
b->src_offset);
6255 return (
a->src_type -
b->src_type);
6264 xtensa_relax_info *relax_info = get_xtensa_relax_info (sec);
6266 if (relax_info ==
NULL)
6268 if (relax_info->fix_list ==
NULL)
6271 for (
r = relax_info->fix_list;
r !=
NULL;
r =
r->next)
6274 relax_info->fix_array =
6276 relax_info->fix_array_count =
count;
6278 r = relax_info->fix_list;
6281 relax_info->fix_array[
count - 1 -
i] = *
r;
6282 relax_info->fix_array[
count - 1 -
i].next =
NULL;
6285 qsort (relax_info->fix_array, relax_info->fix_array_count,
6286 sizeof (reloc_bfd_fix), fix_compare);
6290 static reloc_bfd_fix *
6293 xtensa_relax_info *relax_info = get_xtensa_relax_info (sec);
6297 if (relax_info ==
NULL)
6299 if (relax_info->fix_list ==
NULL)
6302 if (relax_info->fix_array ==
NULL)
6303 cache_fix_array (sec);
6307 rv = bsearch (&
key, relax_info->fix_array, relax_info->fix_array_count,
6308 sizeof (reloc_bfd_fix), fix_compare);
6315 typedef struct section_cache_struct section_cache_t;
6317 struct section_cache_struct
6328 unsigned reloc_count;
6333 init_section_cache (section_cache_t *sec_cache)
6335 memset (sec_cache, 0,
sizeof (*sec_cache));
6340 free_section_cache (section_cache_t *sec_cache)
6344 release_contents (sec_cache->sec, sec_cache->contents);
6345 release_internal_relocs (sec_cache->sec, sec_cache->relocs);
6346 if (sec_cache->ptbl)
6347 free (sec_cache->ptbl);
6353 section_cache_section (section_cache_t *sec_cache,
6366 if (sec == sec_cache->sec)
6373 contents = retrieve_contents (abfd, sec, link_info->
keep_memory);
6374 if (contents ==
NULL && sec_size != 0)
6378 internal_relocs = retrieve_internal_relocs (abfd, sec,
6382 ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table,
6388 free_section_cache (sec_cache);
6389 init_section_cache (sec_cache);
6391 sec_cache->sec = sec;
6393 sec_cache->content_length = sec_size;
6394 sec_cache->relocs = internal_relocs;
6396 sec_cache->pte_count = ptblsize;
6397 sec_cache->ptbl = prop_table;
6402 release_contents (sec, contents);
6403 release_internal_relocs (sec, internal_relocs);
6421 typedef struct ebb_struct ebb_t;
6434 unsigned reloc_count;
6437 unsigned start_ptbl_idx;
6438 unsigned start_reloc_idx;
6441 unsigned end_ptbl_idx;
6442 unsigned end_reloc_idx;
6452 enum ebb_target_enum
6455 EBB_DESIRE_TGT_ALIGN,
6456 EBB_REQUIRE_TGT_ALIGN,
6457 EBB_REQUIRE_LOOP_ALIGN,
6470 typedef struct proposed_action_struct proposed_action;
6472 struct proposed_action_struct
6474 enum ebb_target_enum align_type;
6486 typedef struct ebb_constraint_struct ebb_constraint;
6488 struct ebb_constraint_struct
6494 int start_extra_space;
6496 enum ebb_target_enum start_align;
6501 int end_extra_space;
6503 unsigned action_count;
6504 unsigned action_allocated;
6507 proposed_action *actions;
6510 enum ebb_target_enum *action_aligns;
6515 init_ebb_constraint (ebb_constraint *
c)
6517 memset (
c, 0,
sizeof (ebb_constraint));
6522 free_ebb_constraint (ebb_constraint *
c)
6530 init_ebb (ebb_t *ebb,
6537 unsigned reloc_count)
6539 memset (ebb, 0,
sizeof (ebb_t));
6542 ebb->content_length = content_length;
6543 ebb->ptbl = prop_table;
6544 ebb->pte_count = ptblsize;
6545 ebb->relocs = internal_relocs;
6546 ebb->reloc_count = reloc_count;
6547 ebb->start_offset = 0;
6548 ebb->end_offset = ebb->content_length - 1;
6549 ebb->start_ptbl_idx = 0;
6550 ebb->end_ptbl_idx = ptblsize;
6551 ebb->start_reloc_idx = 0;
6552 ebb->end_reloc_idx = reloc_count;
6562 static bfd_boolean extend_ebb_bounds_forward (ebb_t *);
6563 static bfd_boolean extend_ebb_bounds_backward (ebb_t *);
6568 extend_ebb_bounds (ebb_t *ebb)
6570 if (!extend_ebb_bounds_forward (ebb))
6572 if (!extend_ebb_bounds_backward (ebb))
6579 extend_ebb_bounds_forward (ebb_t *ebb)
6583 the_entry = &ebb->ptbl[ebb->end_ptbl_idx];
6594 entry_end = the_entry->
address - ebb->sec->vma + the_entry->
size;
6596 insn_block_decodable_len (ebb->contents, ebb->content_length,
6598 entry_end - ebb->end_offset);
6599 if (insn_block_len != (entry_end - ebb->end_offset))
6601 (*_bfd_error_handler)
6602 (
_(
"%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"),
6603 ebb->sec->owner, ebb->sec, ebb->end_offset + insn_block_len);
6606 ebb->end_offset += insn_block_len;
6608 if (ebb->end_offset == ebb->sec->size)
6609 ebb->ends_section =
TRUE;
6612 while (ebb->end_reloc_idx + 1 < ebb->reloc_count
6613 && (ebb->relocs[ebb->end_reloc_idx + 1].rz_offset
6616 ebb->end_reloc_idx++;
6619 if (ebb->end_ptbl_idx + 1 == ebb->pte_count)
6622 new_entry = &ebb->ptbl[ebb->end_ptbl_idx + 1];
6631 the_entry = new_entry;
6632 ebb->end_ptbl_idx++;
6636 if (ebb->end_ptbl_idx + 1 == ebb->pte_count)
6638 if (ebb->end_offset == ebb->content_length)
6639 ebb->ends_section =
TRUE;
6643 new_entry = &ebb->ptbl[ebb->end_ptbl_idx + 1];
6646 ebb->ends_unreachable = new_entry;
6655 extend_ebb_bounds_backward (ebb_t *ebb)
6659 the_entry = &ebb->ptbl[ebb->start_ptbl_idx];
6670 block_begin = the_entry->
address - ebb->sec->vma;
6672 insn_block_decodable_len (ebb->contents, ebb->content_length,
6674 ebb->start_offset - block_begin);
6675 if (insn_block_len != ebb->start_offset - block_begin)
6677 (*_bfd_error_handler)
6678 (
_(
"%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"),
6679 ebb->sec->owner, ebb->sec, ebb->end_offset + insn_block_len);
6682 ebb->start_offset -= insn_block_len;
6685 while (ebb->start_reloc_idx > 0
6686 && (ebb->relocs[ebb->start_reloc_idx - 1].rz_offset
6687 >= ebb->start_offset))
6689 ebb->start_reloc_idx--;
6692 if (ebb->start_ptbl_idx == 0)
6695 new_entry = &ebb->ptbl[ebb->start_ptbl_idx - 1];
6703 the_entry = new_entry;
6704 ebb->start_ptbl_idx--;
6711 insn_block_decodable_len (
bfd_byte *contents,
6718 while (
offset < block_offset + block_len)
6722 insn_len = insn_decode_len (contents, content_len,
offset);
6724 return (
offset - block_offset);
6727 return (
offset - block_offset);
6732 ebb_propose_action (ebb_constraint *
c,
6733 enum ebb_target_enum align_type,
6740 proposed_action *act;
6742 if (
c->action_allocated <=
c->action_count)
6744 unsigned new_allocated,
i;
6745 proposed_action *new_actions;
6747 new_allocated = (
c->action_count + 2) * 2;
6748 new_actions = (proposed_action *)
6749 bfd_zmalloc (
sizeof (proposed_action) * new_allocated);
6751 for (
i = 0;
i <
c->action_count;
i++)
6752 new_actions[
i] =
c->actions[
i];
6755 c->actions = new_actions;
6756 c->action_allocated = new_allocated;
6759 act = &
c->actions[
c->action_count];
6760 act->align_type = align_type;
6761 act->alignment_pow = alignment_pow;
6764 act->removed_bytes = removed_bytes;
6765 act->do_action = do_action;
6789 if (internal_relocs ==
NULL)
6791 (abfd, sec,
NULL,
NULL, keep_memory));
6792 return internal_relocs;
6808 free (internal_relocs);
6821 if (contents ==
NULL && sec_size != 0)
6852 retrieve_local_syms (
bfd *input_bfd)
6858 symtab_hdr = &
elf_tdata (input_bfd)->symtab_hdr;
6859 locsymcount = symtab_hdr->
sh_info;
6862 if (isymbuf ==
NULL && locsymcount != 0)
6868 symtab_hdr->
contents = (
unsigned char *) isymbuf;
6889 static bfd_boolean compute_ebb_proposed_actions (ebb_constraint *);
6890 static bfd_boolean compute_ebb_actions (ebb_constraint *);
6891 typedef struct reloc_range_list_struct reloc_range_list;
6894 reloc_range_list *,
const ebb_constraint *,
6896 static bfd_boolean check_section_ebb_reduces (
const ebb_constraint *);
6897 static void text_action_add_proposed
6898 (text_action_list *,
const ebb_constraint *,
asection *);
6907 (
const source_reloc *,
int,
const source_reloc *,
int,
asection *,
6917 static bfd_boolean relocations_reach (source_reloc *,
int,
const rz_reloc *);
6922 int,
const rz_reloc *,
const literal_value *, section_cache_t *);
6927 static bfd_boolean translate_reloc_bfd_fix (reloc_bfd_fix *);
6928 static asection *translate_reloc (
const rz_reloc *, rz_reloc *,
asection *);
6929 static void shrink_dynamic_reloc_sections
6942 elf_xtensa_relax_section (
bfd *abfd,
6947 static value_map_hash_table *values =
NULL;
6949 xtensa_relax_info *relax_info;
6951 if (!relocations_analyzed)
6954 values = value_map_hash_table_init ();
6957 relaxing_section =
TRUE;
6958 if (!analyze_relocations (link_info))
6960 relocations_analyzed =
TRUE;
6968 relax_info = get_xtensa_relax_info (sec);
6969 BFD_ASSERT (relax_info !=
NULL);
6971 switch (relax_info->visited)
6977 if (!compute_removed_literals (abfd, sec, link_info, values))
6984 value_map_hash_table_delete (values);
6986 if (!relax_section (abfd, sec, link_info))
6992 if (!relax_section_symbols (abfd, sec))
6997 relax_info->visited++;
7027 init_xtensa_relax_info (sec);
7034 if (!find_relaxable_sections (abfd, sec, link_info, &is_relaxable))
7046 xtensa_relax_info *relax_info;
7048 relax_info = get_xtensa_relax_info (sec);
7049 if (relax_info->is_relaxable_literal_section
7050 || relax_info->is_relaxable_asm_section)
7052 relax_info->src_relocs = (source_reloc *)
7053 bfd_malloc (relax_info->src_count * sizeof (source_reloc));
7056 relax_info->src_count = 0;
7063 if (!collect_source_relocs (abfd, sec, link_info))
7071 if (!compute_text_actions (abfd, sec, link_info))
7090 find_relaxable_sections (
bfd *abfd,
7099 xtensa_relax_info *source_relax_info;
7102 internal_relocs = retrieve_internal_relocs (abfd, sec,
7104 if (internal_relocs ==
NULL)
7107 contents = retrieve_contents (abfd, sec, link_info->
keep_memory);
7108 if (contents ==
NULL && sec->
size != 0)
7114 source_relax_info = get_xtensa_relax_info (sec);
7120 xtensa_relax_info *target_relax_info;
7126 if (source_relax_info
7127 && !source_relax_info->is_relaxable_asm_section
7131 if (is_resolvable_asm_expansion (abfd, sec, contents, irel,
7132 link_info, &is_reachable)
7135 source_relax_info->is_relaxable_asm_section =
TRUE;
7136 *is_relaxable_p =
TRUE;
7140 rz_reloc_init (&rz_rel, abfd, irel, contents,
7143 target_sec = rz_reloc_get_section (&rz_rel);
7144 target_relax_info = get_xtensa_relax_info (target_sec);
7145 if (!target_relax_info)
7151 is_l32r_reloc =
FALSE;
7155 get_relocation_opcode (abfd, sec, contents, irel);
7158 is_l32r_reloc = (opcode == get_l32r_opcode ());
7161 target_relax_info->src_count++;
7165 if (is_l32r_reloc && rz_reloc_is_defined (&rz_rel))
7168 target_relax_info->is_relaxable_literal_section =
TRUE;
7169 *is_relaxable_p =
TRUE;
7174 release_contents (sec, contents);
7175 release_internal_relocs (sec, internal_relocs);
7185 collect_source_relocs (
bfd *abfd,
7195 internal_relocs = retrieve_internal_relocs (abfd, sec,
7197 if (internal_relocs ==
NULL)
7201 contents = retrieve_contents (abfd, sec, link_info->
keep_memory);
7202 if (contents ==
NULL && sec_size != 0)
7214 xtensa_relax_info *target_relax_info;
7216 rz_reloc_init (&rz_rel, abfd, irel, contents, sec_size);
7218 target_sec = rz_reloc_get_section (&rz_rel);
7219 target_relax_info = get_xtensa_relax_info (target_sec);
7221 if (target_relax_info
7222 && (target_relax_info->is_relaxable_literal_section
7223 || target_relax_info->is_relaxable_asm_section))
7235 opcode = get_relocation_opcode (abfd, sec, contents, irel);
7236 if (opcode == get_l32r_opcode ())
7238 is_abs_literal =
TRUE;
7246 opcode = get_relocation_opcode (abfd, sec, contents, irel);
7252 int src_next = target_relax_info->src_next++;
7253 source_reloc *s_reloc = &target_relax_info->src_relocs[src_next];
7255 init_source_reloc (s_reloc, sec, &rz_rel, opcode, opnd,
7272 if (!is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info,
7281 xtensa_relax_info *target_relax_info;
7286 l32r_irel = find_associated_l32r_irel (abfd, sec, contents,
7287 irel, internal_relocs);
7288 if (l32r_irel ==
NULL)
7291 rz_reloc_init (&rz_rel, abfd, l32r_irel, contents, sec_size);
7293 target_sec = rz_reloc_get_section (&rz_rel);
7294 target_relax_info = get_xtensa_relax_info (target_sec);
7296 if (target_relax_info
7297 && (target_relax_info->is_relaxable_literal_section
7298 || target_relax_info->is_relaxable_asm_section))
7300 source_reloc *s_reloc;
7306 s_reloc = find_source_reloc (target_relax_info->src_relocs,
7307 target_relax_info->src_next,
7309 BFD_ASSERT (s_reloc);
7310 s_reloc->is_null =
TRUE;
7315 RZ_XTENSA_ASM_SIMPLIFY);
7318 pin_internal_relocs (sec, internal_relocs);
7326 pin_internal_relocs (sec, internal_relocs);
7331 release_contents (sec, contents);
7332 release_internal_relocs (sec, internal_relocs);
7344 is_resolvable_asm_expansion (
bfd *abfd,
7360 *is_reachable_p =
FALSE;
7362 if (contents ==
NULL)
7369 opcode = get_expanded_call_opcode (contents + irel->
rz_offset,
7370 sec_size - irel->
rz_offset, &uses_l32r);
7375 direct_call_opcode = swap_callx_for_call_opcode (opcode);
7380 rz_reloc_init (&rz_rel, abfd, irel, contents, sec_size);
7381 if (!rz_reloc_is_defined (&rz_rel))
7384 target_sec = rz_reloc_get_section (&rz_rel);
7385 target_offset = rz_rel.target_offset;
7399 || is_reloc_sym_weak (abfd, irel)))
7429 dest_address = (dest_address + 3) & ~3;
7440 *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0,
7441 self_address, dest_address);
7443 if ((self_address >> CALL_SEGMENT_BITS) !=
7444 (dest_address >> CALL_SEGMENT_BITS))
7452 find_associated_l32r_irel (
bfd *abfd,
7464 if (irel == other_irel)
7468 if (is_l32r_relocation (abfd, sec, contents, irel))
7477 build_reloc_opcodes (
bfd *abfd,
7488 reloc_opcodes[
i] = get_relocation_opcode (abfd, sec, contents, irel);
7490 return reloc_opcodes;
7493 struct reloc_range_struct
7498 unsigned irel_index;
7500 typedef struct reloc_range_struct reloc_range;
7502 typedef struct reloc_range_list_entry_struct reloc_range_list_entry;
7503 struct reloc_range_list_entry_struct
7505 reloc_range_list_entry *next;
7506 reloc_range_list_entry *prev;
7512 struct reloc_range_list_struct
7524 reloc_range_list_entry *reloc;
7525 reloc_range_list_entry list_root;
7529 reloc_range_compare (
const void *
a,
const void *
b)
7531 const reloc_range *ra =
a;
7532 const reloc_range *rb =
b;
7534 if (ra->addr != rb->addr)
7535 return ra->addr < rb->addr ? -1 : 1;
7536 if (ra->add != rb->add)
7537 return ra->add ? -1 : 1;
7546 reloc_range_list *
list)
7551 reloc_range *ranges =
NULL;
7552 reloc_range_list_entry *reloc =
7565 if (rz_type == RZ_XTENSA_ASM_SIMPLIFY
7566 || rz_type == RZ_XTENSA_32_PCREL
7570 rz_reloc_init (&rz_rel, abfd, irel, contents,
7573 if (rz_reloc_get_section (&rz_rel) != sec)
7578 max_n = (max_n + 2) * 2;
7579 ranges = bfd_realloc (ranges, max_n *
sizeof (*ranges));
7583 ranges[
n + 1].addr = rz_rel.target_offset;
7585 ranges[
n].add = ranges[
n].addr < ranges[
n + 1].addr;
7586 ranges[
n + 1].add = !ranges[
n].add;
7588 ranges[
n].irel_index =
i;
7589 ranges[
n + 1].irel_index =
i;
7593 reloc[
i].irel = irel;
7608 opcode = reloc_opcodes[
i];
7610 opcode = get_relocation_opcode (abfd, sec, contents, irel);
7627 reloc[
i].opcode = opcode;
7628 reloc[
i].opnum = opnum;
7634 ranges = bfd_realloc (ranges,
n *
sizeof (*ranges));
7635 qsort (ranges,
n,
sizeof (*ranges), reloc_range_compare);
7638 list->range = ranges;
7639 list->reloc = reloc;
7640 list->list_root.prev = &
list->list_root;
7641 list->list_root.next = &
list->list_root;
7650 static void reloc_range_list_append (reloc_range_list *
list,
7651 unsigned irel_index)
7653 reloc_range_list_entry *
entry =
list->reloc + irel_index;
7662 static void reloc_range_list_remove (reloc_range_list *
list,
7663 unsigned irel_index)
7665 reloc_range_list_entry *
entry =
list->reloc + irel_index;
7675 static void reloc_range_list_update_range (reloc_range_list *
list,
7681 if ((
list->last > 0 &&
list->range[
list->last - 1].addr > last) ||
7682 (
list->first > 0 &&
list->range[
list->first - 1].addr >= first))
7687 list->list_root.next = &
list->list_root;
7688 list->list_root.prev = &
list->list_root;
7689 fprintf (stderr,
"%s: move backwards requested\n", __func__);
7692 for (;
list->last <
list->n_range &&
7695 reloc_range_list_append (
list,
list->range[
list->last].irel_index);
7697 for (;
list->first <
list->n_range &&
7700 reloc_range_list_remove (
list,
list->range[
list->first].irel_index);
7703 static void free_reloc_range_list (reloc_range_list *
list)
7721 compute_text_actions (
bfd *abfd,
7726 xtensa_relax_info *relax_info;
7734 reloc_range_list relevant_relocs;
7736 relax_info = get_xtensa_relax_info (sec);
7737 BFD_ASSERT (relax_info);
7738 BFD_ASSERT (relax_info->src_next == relax_info->src_count);
7741 if (!relax_info->is_relaxable_asm_section)
7744 internal_relocs = retrieve_internal_relocs (abfd, sec,
7747 if (internal_relocs)
7749 internal_reloc_compare);
7752 contents = retrieve_contents (abfd, sec, link_info->
keep_memory);
7753 if (contents ==
NULL && sec_size != 0)
7759 ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table,
7768 reloc_opcodes = build_reloc_opcodes (abfd, sec, contents, internal_relocs);
7770 build_reloc_ranges (abfd, sec, contents, internal_relocs, reloc_opcodes,
7780 ebb_constraint ebb_table;
7787 simplify_size = get_asm_simplify_size (contents, sec_size, rz_offset);
7788 if (simplify_size == 0)
7790 (*_bfd_error_handler)
7791 (
_(
"%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"),
7792 sec->
owner, sec, rz_offset);
7798 the_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
7802 text_action_add (&relax_info->action_list,
7803 ta_convert_longcall, sec, rz_offset,
7810 ptbl_idx = the_entry - prop_table;
7812 && the_entry->
size == 0
7813 && ptbl_idx + 1 < ptblsize
7814 && (prop_table[ptbl_idx + 1].address
7815 == prop_table[ptbl_idx].address))
7825 init_ebb_constraint (&ebb_table);
7826 ebb = &ebb_table.ebb;
7827 init_ebb (ebb, sec, contents, sec_size, prop_table, ptblsize,
7829 ebb->start_offset = rz_offset + simplify_size;
7830 ebb->end_offset = rz_offset + simplify_size;
7831 ebb->start_ptbl_idx = ptbl_idx;
7832 ebb->end_ptbl_idx = ptbl_idx;
7833 ebb->start_reloc_idx =
i;
7834 ebb->end_reloc_idx =
i;
7836 if (!extend_ebb_bounds (ebb)
7837 || !compute_ebb_proposed_actions (&ebb_table)
7838 || !compute_ebb_actions (&ebb_table)
7839 || !check_section_ebb_pcrels_fit (abfd, sec, contents,
7842 &ebb_table, reloc_opcodes)
7843 || !check_section_ebb_reduces (&ebb_table))
7849 text_action_add (&relax_info->action_list,
7850 ta_convert_longcall, sec, rz_offset, 0);
7851 i = ebb_table.ebb.end_reloc_idx;
7852 free_ebb_constraint (&ebb_table);
7856 text_action_add_proposed (&relax_info->action_list, &ebb_table, sec);
7860 i = ebb_table.ebb.end_reloc_idx;
7861 free_ebb_constraint (&ebb_table);
7864 free_reloc_range_list (&relevant_relocs);
7867 if (action_list_count (&relax_info->action_list))
7868 print_action_list (stderr, &relax_info->action_list);
7872 release_contents (sec, contents);
7873 release_internal_relocs (sec, internal_relocs);
7877 free (reloc_opcodes);
7887 prev_instr_is_a_loop (
bfd_byte *contents,
7895 prev_opcode = insn_decode_opcode (contents, content_length,
offset-3, 0);
7903 compute_ebb_proposed_actions (ebb_constraint *ebb_table)
7905 const ebb_t *ebb = &ebb_table->ebb;
7906 unsigned rel_idx = ebb->start_reloc_idx;
7914 if (insnbuf ==
NULL)
7920 start_entry = &ebb->ptbl[ebb->start_ptbl_idx];
7921 end_entry = &ebb->ptbl[ebb->end_ptbl_idx];
7925 bfd_vma start_offset, end_offset;
7928 start_offset =
entry->address - ebb->sec->vma;
7931 if (
entry == start_entry)
7932 start_offset = ebb->start_offset;
7933 if (
entry == end_entry)
7934 end_offset = ebb->end_offset;
7940 enum ebb_target_enum align_type = EBB_DESIRE_TGT_ALIGN;
7941 BFD_ASSERT (
offset != end_offset);
7942 if (
offset == end_offset)
7945 insn_len = insn_decode_len (ebb->contents, ebb->content_length,
7950 if (check_branch_target_aligned_address (
offset, insn_len))
7951 align_type = EBB_REQUIRE_TGT_ALIGN;
7953 ebb_propose_action (ebb_table, align_type, 0,
7957 while (
offset != end_offset)
7962 while (rel_idx < ebb->end_reloc_idx
7963 && (ebb->relocs[rel_idx].rz_offset <
offset
7964 || (ebb->relocs[rel_idx].rz_offset ==
offset
7966 != RZ_XTENSA_ASM_SIMPLIFY))))
7970 irel = &ebb->relocs[rel_idx];
7976 simplify_size = get_asm_simplify_size (ebb->contents,
7977 ebb->content_length,
7979 if (simplify_size == 0)
7982 ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
7989 if (
offset + MIN_INSN_LENGTH > ebb->content_length)
7992 ebb->content_length -
offset);
8013 && can_narrow_instruction (slotbuf, fmt, opcode) != 0)
8016 ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
8020 && can_widen_instruction (slotbuf, fmt, opcode) != 0
8021 && ! prev_instr_is_a_loop (ebb->contents,
8022 ebb->content_length,
offset))
8025 ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
8031 ebb_propose_action (ebb_table, EBB_REQUIRE_LOOP_ALIGN, 0,
8039 if (ebb->ends_unreachable)
8041 ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
8042 ta_fill, ebb->end_offset, 0,
TRUE);
8048 (*_bfd_error_handler)
8049 (
_(
"%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"),
8050 ebb->sec->owner, ebb->sec,
offset);
8073 compute_ebb_actions (ebb_constraint *ebb_table)
8077 int removed_bytes = 0;
8078 ebb_t *ebb = &ebb_table->ebb;
8079 unsigned seg_idx_start = 0;
8080 unsigned seg_idx_end = 0;
8089 for (seg_idx_end = 0; seg_idx_end < ebb_table->action_count; seg_idx_end++)
8092 unsigned longcall_count = 0;
8093 unsigned longcall_convert_count = 0;
8094 unsigned narrowable_count = 0;
8095 unsigned narrowable_convert_count = 0;
8096 unsigned widenable_count = 0;
8097 unsigned widenable_convert_count = 0;
8100 int align = (1 << ebb_table->ebb.sec->alignment_power);
8102 seg_idx_start = seg_idx_end;
8104 for (
i = seg_idx_start;
i < ebb_table->action_count;
i++)
8106 action = &ebb_table->actions[
i];
8107 if (
action->action == ta_convert_longcall)
8109 if (
action->action == ta_narrow_insn)
8111 if (
action->action == ta_widen_insn)
8113 if (
action->action == ta_fill)
8115 if (
action->align_type == EBB_REQUIRE_LOOP_ALIGN)
8117 if (
action->align_type == EBB_REQUIRE_TGT_ALIGN
8118 && !elf32xtensa_size_opt)
8123 if (seg_idx_end == ebb_table->action_count && !ebb->ends_unreachable)
8124 requires_text_end_align =
TRUE;
8126 if (elf32xtensa_size_opt && !requires_text_end_align
8127 &&
action->align_type != EBB_REQUIRE_LOOP_ALIGN
8128 &&
action->align_type != EBB_REQUIRE_TGT_ALIGN)
8130 longcall_convert_count = longcall_count;
8131 narrowable_convert_count = narrowable_count;
8132 widenable_convert_count = 0;
8137 narrowable_convert_count = 0;
8138 longcall_convert_count = 0;
8139 widenable_convert_count = 0;
8141 for (j = 0; j < longcall_count; j++)
8143 int removed = (longcall_count - j) * 3 & (align - 1);
8144 unsigned desire_narrow = (align - removed) & (align - 1);
8145 unsigned desire_widen = removed;
8146 if (desire_narrow <= narrowable_count)
8148 narrowable_convert_count = desire_narrow;
8149 narrowable_convert_count +=
8150 (align * ((narrowable_count - narrowable_convert_count)
8152 longcall_convert_count = (longcall_count - j);
8153 widenable_convert_count = 0;
8156 if (desire_widen <= widenable_count && !elf32xtensa_size_opt)
8158 narrowable_convert_count = 0;
8159 longcall_convert_count = longcall_count - j;
8160 widenable_convert_count = desire_widen;
8167 for (
i = seg_idx_start;
i < seg_idx_end;
i++)
8169 action = &ebb_table->actions[
i];
8172 case ta_convert_longcall:
8173 if (longcall_convert_count != 0)
8175 action->action = ta_remove_longcall;
8177 action->removed_bytes += 3;
8178 longcall_convert_count--;
8181 case ta_narrow_insn:
8182 if (narrowable_convert_count != 0)
8185 action->removed_bytes += 1;
8186 narrowable_convert_count--;
8190 if (widenable_convert_count != 0)
8193 action->removed_bytes -= 1;
8194 widenable_convert_count--;
8206 if (ebb_table->ebb.ends_section || ebb_table->ebb.ends_unreachable)
8209 for (
i = 0;
i < ebb_table->action_count;
i++)
8211 int old_removed_bytes = removed_bytes;
8212 proposed_action *
action = &ebb_table->actions[
i];
8214 if (
action->do_action &&
action->action == ta_convert_longcall)
8218 for (j =
i + 1; j < ebb_table->action_count; j++)
8220 proposed_action *new_action = &ebb_table->actions[j];
8222 if (new_action->align_type == EBB_REQUIRE_TGT_ALIGN)
8224 if (!check_branch_target_aligned
8225 (ebb_table->ebb.contents,
8226 ebb_table->ebb.content_length,
8229 bad_alignment =
TRUE;
8233 if (new_action->align_type == EBB_REQUIRE_LOOP_ALIGN)
8235 if (!check_loop_aligned (ebb_table->ebb.contents,
8236 ebb_table->ebb.content_length,
8240 bad_alignment =
TRUE;
8244 if (new_action->action == ta_narrow_insn
8245 && !new_action->do_action
8246 && ebb_table->ebb.sec->alignment_power == 2)
8249 new_action->do_action =
TRUE;
8250 new_action->removed_bytes += 1;
8251 bad_alignment =
FALSE;
8254 if (new_action->action == ta_widen_insn
8255 && new_action->do_action
8256 && ebb_table->ebb.sec->alignment_power == 2)
8259 new_action->do_action =
FALSE;
8260 new_action->removed_bytes += 1;
8261 bad_alignment =
FALSE;
8264 if (new_action->do_action)
8265 removed_bytes += new_action->removed_bytes;
8269 action->removed_bytes += 3;
8270 action->action = ta_remove_longcall;
8274 removed_bytes = old_removed_bytes;
8276 removed_bytes +=
action->removed_bytes;
8281 for (
i = 0;
i < ebb_table->action_count; ++
i)
8283 proposed_action *
action = &ebb_table->actions[
i];
8285 removed_bytes +=
action->removed_bytes;
8288 if ((removed_bytes % (1 << ebb_table->ebb.sec->alignment_power)) != 0
8289 && ebb->ends_unreachable)
8295 BFD_ASSERT (ebb_table->action_count != 0);
8296 action = &ebb_table->actions[ebb_table->action_count - 1];
8297 BFD_ASSERT (
action->action == ta_fill);
8300 extra_space = compute_fill_extra_space (ebb->ends_unreachable);
8301 br =
action->removed_bytes + removed_bytes + extra_space;
8302 br =
br & ((1 << ebb->sec->alignment_power ) - 1);
8304 action->removed_bytes = extra_space -
br;
8314 typedef struct xlate_map_entry xlate_map_entry_t;
8315 typedef struct xlate_map xlate_map_t;
8317 struct xlate_map_entry
8319 unsigned orig_address;
8320 unsigned new_address;
8326 unsigned entry_count;
8327 xlate_map_entry_t *
entry;
8332 xlate_compare (
const void *a_v,
const void *b_v)
8334 const xlate_map_entry_t *
a = (
const xlate_map_entry_t *) a_v;
8335 const xlate_map_entry_t *
b = (
const xlate_map_entry_t *) b_v;
8336 if (
a->orig_address <
b->orig_address)
8338 if (
a->orig_address > (
b->orig_address +
b->size - 1))
8345 xlate_offset_with_removed_text (
const xlate_map_t *
map,
8346 text_action_list *action_list,
8350 xlate_map_entry_t *
e;
8353 return offset_with_removed_text (action_list,
offset);
8355 if (
map->entry_count == 0)
8359 sizeof (xlate_map_entry_t), &xlate_compare);
8360 e = (xlate_map_entry_t *)
r;
8362 BFD_ASSERT (
e !=
NULL);
8365 return e->new_address -
e->orig_address +
offset;
8368 typedef struct xlate_map_context_struct xlate_map_context;
8369 struct xlate_map_context_struct
8372 xlate_map_entry_t *current_entry;
8377 xlate_map_fn (splay_tree_node node,
void *
p)
8379 text_action *
r = (text_action *)node->value;
8380 xlate_map_context *
ctx =
p;
8381 unsigned orig_size = 0;
8386 case ta_remove_insn:
8387 case ta_convert_longcall:
8388 case ta_remove_literal:
8389 case ta_add_literal:
8391 case ta_remove_longcall:
8394 case ta_narrow_insn:
8403 ctx->current_entry->size =
8404 r->offset + orig_size -
ctx->current_entry->orig_address;
8405 if (
ctx->current_entry->size != 0)
8407 ctx->current_entry++;
8408 ctx->map->entry_count++;
8410 ctx->current_entry->orig_address =
r->offset + orig_size;
8411 ctx->removed +=
r->removed_bytes;
8412 ctx->current_entry->new_address =
r->offset + orig_size -
ctx->removed;
8413 ctx->current_entry->size = 0;
8420 static xlate_map_t *
8421 build_xlate_map (
asection *sec, xtensa_relax_info *relax_info)
8423 text_action_list *action_list = &relax_info->action_list;
8424 unsigned num_actions = 0;
8425 xlate_map_context
ctx;
8427 ctx.map = (xlate_map_t *)
bfd_malloc (
sizeof (xlate_map_t));
8432 num_actions = action_list_count (action_list);
8433 ctx.map->entry = (xlate_map_entry_t *)
8434 bfd_malloc (
sizeof (xlate_map_entry_t) * (num_actions + 1));
8440 ctx.map->entry_count = 0;
8443 ctx.current_entry = &
ctx.map->entry[0];
8445 ctx.current_entry->orig_address = 0;
8446 ctx.current_entry->new_address = 0;
8447 ctx.current_entry->size = 0;
8449 splay_tree_foreach (action_list->tree, xlate_map_fn, &
ctx);
8452 -
ctx.current_entry->orig_address);
8453 if (
ctx.current_entry->size != 0)
8454 ctx.map->entry_count++;
8463 free_xlate_map (xlate_map_t *
map)
8477 check_section_ebb_pcrels_fit (
bfd *abfd,
8481 reloc_range_list *relevant_relocs,
8482 const ebb_constraint *constraint,
8488 xlate_map_t *xmap =
NULL;
8490 xtensa_relax_info *relax_info;
8493 relax_info = get_xtensa_relax_info (sec);
8497 xmap = build_xlate_map (sec, relax_info);
8502 if (relevant_relocs && constraint->action_count)
8504 if (!relevant_relocs->ok)
8511 bfd_vma min_offset, max_offset;
8512 min_offset = max_offset = constraint->actions[0].offset;
8514 for (
i = 1;
i < constraint->action_count; ++
i)
8516 proposed_action *
action = &constraint->actions[
i];
8524 reloc_range_list_update_range (relevant_relocs, min_offset,
8526 n = relevant_relocs->n_list;
8527 entry = &relevant_relocs->list_root;
8532 relevant_relocs =
NULL;
8535 for (
i = 0;
i <
n;
i++)
8538 bfd_vma orig_self_offset, orig_target_offset;
8539 bfd_vma self_offset, target_offset;
8542 int self_removed_bytes, target_removed_bytes;
8544 if (relevant_relocs)
8551 irel = internal_relocs +
i;
8555 howto = &elf_howto_table[rz_type];
8560 if (rz_type == RZ_XTENSA_ASM_SIMPLIFY
8561 || rz_type == RZ_XTENSA_32_PCREL
8565 rz_reloc_init (&rz_rel, abfd, irel, contents,
8568 if (rz_reloc_get_section (&rz_rel) != sec)
8572 orig_target_offset = rz_rel.target_offset;
8574 self_offset = orig_self_offset;
8575 target_offset = orig_target_offset;
8580 xlate_offset_with_removed_text (xmap, &relax_info->action_list,
8583 xlate_offset_with_removed_text (xmap, &relax_info->action_list,
8584 orig_target_offset);
8587 self_removed_bytes = 0;
8588 target_removed_bytes = 0;
8590 for (j = 0; j < constraint->action_count; ++j)
8592 proposed_action *
action = &constraint->actions[j];
8594 int removed_bytes =
action->removed_bytes;
8595 if (
offset < orig_self_offset
8596 || (
offset == orig_self_offset &&
action->action == ta_fill
8597 &&
action->removed_bytes < 0))
8598 self_removed_bytes += removed_bytes;
8599 if (
offset < orig_target_offset
8600 || (
offset == orig_target_offset &&
action->action == ta_fill
8601 &&
action->removed_bytes < 0))
8602 target_removed_bytes += removed_bytes;
8604 self_offset -= self_removed_bytes;
8605 target_offset -= target_removed_bytes;
8618 if (relevant_relocs)
8620 opcode =
entry->opcode;
8621 opnum =
entry->opnum;
8626 opcode = reloc_opcodes[relevant_relocs ?
8629 opcode = get_relocation_opcode (abfd, sec, contents, irel);
8644 if (!pcrel_reloc_fits (opcode, opnum, self_offset, target_offset))
8653 free_xlate_map (xmap);
8660 check_section_ebb_reduces (
const ebb_constraint *constraint)
8665 for (
i = 0;
i < constraint->action_count;
i++)
8667 const proposed_action *
action = &constraint->actions[
i];
8669 removed +=
action->removed_bytes;
8679 text_action_add_proposed (text_action_list *l,
8680 const ebb_constraint *ebb_table,
8685 for (
i = 0;
i < ebb_table->action_count;
i++)
8687 proposed_action *
action = &ebb_table->actions[
i];
8693 case ta_remove_insn:
8694 case ta_remove_longcall:
8695 case ta_convert_longcall:
8696 case ta_narrow_insn:
8699 case ta_remove_literal:
8700 text_action_add (l,
action->action, sec,
action->offset,
8716 int fill_extra_space;
8730 int nsm = (1 << pow) - 1;
8733 fill_extra_space += align_fill;
8735 return fill_extra_space;
8748 compute_removed_literals (
bfd *abfd,
8751 value_map_hash_table *values)
8753 xtensa_relax_info *relax_info;
8756 source_reloc *src_relocs, *rel;
8762 bfd_vma last_target_offset = 0;
8763 section_cache_t target_sec_cache;
8766 init_section_cache (&target_sec_cache);
8769 relax_info = get_xtensa_relax_info (sec);
8770 BFD_ASSERT (relax_info);
8771 if (!relax_info->is_relaxable_literal_section)
8774 internal_relocs = retrieve_internal_relocs (abfd, sec,
8778 contents = retrieve_contents (abfd, sec, link_info->
keep_memory);
8779 if (contents ==
NULL && sec_size != 0)
8786 src_relocs = relax_info->src_relocs;
8787 qsort (src_relocs, relax_info->src_count,
8788 sizeof (source_reloc), source_reloc_compare);
8790 internal_reloc_compare);
8792 ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table,
8801 for (
i = 0;
i < relax_info->src_count;
i++)
8805 rel = &src_relocs[
i];
8806 if (get_l32r_opcode () != rel->opcode)
8808 irel = get_irel_at_offset (sec, internal_relocs,
8809 rel->rz_rel.target_offset);
8821 if (
i != 0 && prev_i != -1
8822 && src_relocs[
i-1].rz_rel.target_offset == rel->rz_rel.target_offset)
8826 if (last_loc_is_prev &&
8827 last_target_offset + 4 != rel->rz_rel.target_offset)
8828 last_loc_is_prev =
FALSE;
8833 if (is_removable_literal (rel,
i, src_relocs, relax_info->src_count,
8834 sec, prop_table, ptblsize))
8836 if (!remove_dead_literal (abfd, sec, link_info, internal_relocs,
8837 irel, rel, prop_table, ptblsize))
8842 last_target_offset = rel->rz_rel.target_offset;
8846 if (!identify_literal_placement (abfd, sec, contents, link_info,
8848 &last_loc_is_prev, irel,
8849 relax_info->src_count -
i, rel,
8850 prop_table, ptblsize,
8851 &target_sec_cache, rel->is_abs_literal))
8856 last_target_offset = rel->rz_rel.target_offset;
8860 print_removed_literals (stderr, &relax_info->removed_list);
8861 print_action_list (stderr, &relax_info->action_list);
8867 free_section_cache (&target_sec_cache);
8869 release_contents (sec, contents);
8870 release_internal_relocs (sec, internal_relocs);
8885 if (!internal_relocs)
8896 i = irel - internal_relocs;
8899 if (internal_relocs[
i-1].rz_offset !=
offset)
8905 irel = &internal_relocs[
i];
8916 is_removable_literal (
const source_reloc *rel,
8918 const source_reloc *src_relocs,
8924 const source_reloc *curr_rel;
8930 entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
8931 sec->
vma + rel->rz_rel.target_offset);
8935 for (++
i;
i < src_count; ++
i)
8937 curr_rel = &src_relocs[
i];
8939 if (curr_rel->rz_rel.target_offset != rel->rz_rel.target_offset)
8942 if (!curr_rel->is_null
8943 && !xtensa_is_property_section (curr_rel->source_sec)
8952 remove_dead_literal (
bfd *abfd,
8962 xtensa_relax_info *relax_info;
8964 relax_info = get_xtensa_relax_info (sec);
8968 entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
8969 sec->
vma + rel->rz_rel.target_offset);
8972 add_removed_literal (&relax_info->removed_list, &rel->rz_rel,
NULL);
8974 text_action_add (&relax_info->action_list,
8975 ta_remove_literal, sec, rel->rz_rel.target_offset, 4);
8980 int fill_extra_space;
8989 entry_sec_offset = rel->rz_rel.target_offset + 4;
8993 the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
8995 fill_extra_space = compute_fill_extra_space (the_add_entry);
8997 fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset);
8998 removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset,
8999 -4, fill_extra_space);
9001 adjust_fill_action (fa, removed_diff);
9003 text_action_add (&relax_info->action_list,
9004 ta_fill, sec, entry_sec_offset, removed_diff);
9011 shrink_dynamic_reloc_sections (link_info, abfd, sec, irel);
9014 pin_internal_relocs (sec, internal_relocs);
9023 identify_literal_placement (
bfd *abfd,
9027 value_map_hash_table *values,
9030 int remaining_src_rels,
9034 section_cache_t *target_sec_cache,
9039 xtensa_relax_info *relax_info;
9042 unsigned long value;
9046 relax_info = get_xtensa_relax_info (sec);
9067 rz_reloc_init (&rz_rel, abfd, irel, contents, sec_size);
9070 BFD_ASSERT (rel->rz_rel.target_offset < sec_size);
9073 init_literal_value (&
val, &rz_rel,
value, is_abs_literal);
9077 val_map = value_map_get_cached_value (values, &
val, final_static_link);
9080 && (rz_reloc_get_section (&val_map->loc)->output_section
9082 && relocations_reach (rel, remaining_src_rels, &val_map->loc)
9083 && coalesce_shared_literal (sec, rel, prop_table, ptblsize, val_map))
9086 literal_placed =
TRUE;
9093 && values->has_last_loc && !(*last_loc_is_prev_p))
9095 asection *target_sec = rz_reloc_get_section (&values->last_loc);
9099 rz_reloc try_loc = values->last_loc;
9100 try_loc.virtual_offset += 4;
9103 if (relocations_reach (rel, remaining_src_rels, &try_loc)
9104 && move_shared_literal (sec, link_info, rel,
9105 prop_table, ptblsize,
9106 &try_loc, &
val, target_sec_cache))
9108 values->last_loc.virtual_offset += 4;
9109 literal_placed =
TRUE;
9111 val_map = add_value_map (values, &
val, &try_loc,
9114 val_map->loc = try_loc;
9119 if (!literal_placed)
9122 values->has_last_loc =
TRUE;
9123 values->last_loc = rel->rz_rel;
9125 val_map = add_value_map (values, &
val, &rel->rz_rel, final_static_link);
9127 val_map->loc = rel->rz_rel;
9128 *last_loc_is_prev_p =
TRUE;
9147 relocations_reach (source_reloc *reloc,
9148 int remaining_relocs,
9149 const rz_reloc *rz_rel)
9151 bfd_vma from_offset, source_address, dest_address;
9155 if (!rz_reloc_is_defined (rz_rel))
9158 sec = rz_reloc_get_section (rz_rel);
9159 from_offset = reloc[0].rz_rel.target_offset;
9161 for (
i = 0;
i < remaining_relocs;
i++)
9163 if (reloc[
i].rz_rel.target_offset != from_offset)
9172 if (rz_reloc_get_section (&reloc[
i].rz_rel)->output_section
9178 if (reloc[
i].is_abs_literal)
9182 if (reloc[
i].opnd != -1)
9185 source_address = (reloc[
i].source_sec->output_section->vma
9186 + reloc[
i].source_sec->output_offset
9187 + reloc[
i].rz_rel.rela.rz_offset);
9190 + rz_rel->target_offset);
9192 if (!pcrel_reloc_fits (reloc[
i].opcode, reloc[
i].opnd,
9193 source_address, dest_address))
9206 coalesce_shared_literal (
asection *sec,
9216 xtensa_relax_info *relax_info;
9218 relax_info = get_xtensa_relax_info (sec);
9222 entry = elf_xtensa_find_property_entry
9223 (prop_table, ptblsize, sec->
vma + rel->rz_rel.target_offset);
9228 add_removed_literal (&relax_info->removed_list, &rel->rz_rel, &val_map->loc);
9230 text_action_add (&relax_info->action_list,
9231 ta_remove_literal, sec, rel->rz_rel.target_offset, 4);
9236 int fill_extra_space;
9242 entry_sec_offset = rel->rz_rel.target_offset + 4;
9246 fill_extra_space = 0;
9247 the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
9250 fill_extra_space = the_add_entry->
size;
9252 fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset);
9253 removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset,
9254 -4, fill_extra_space);
9256 adjust_fill_action (fa, removed_diff);
9258 text_action_add (&relax_info->action_list,
9259 ta_fill, sec, entry_sec_offset, removed_diff);
9271 move_shared_literal (
asection *sec,
9276 const rz_reloc *target_loc,
9277 const literal_value *lit_value,
9278 section_cache_t *target_sec_cache)
9281 text_action *fa, *target_fa;
9283 xtensa_relax_info *relax_info, *target_relax_info;
9286 ebb_constraint ebb_table;
9291 if (elf32xtensa_no_literal_movement)
9294 relax_info = get_xtensa_relax_info (sec);
9298 target_sec = rz_reloc_get_section (target_loc);
9299 target_relax_info = get_xtensa_relax_info (target_sec);
9306 src_entry = elf_xtensa_find_property_entry
9307 (prop_table, ptblsize, sec->
vma + rel->rz_rel.target_offset);
9309 if (!section_cache_section (target_sec_cache, target_sec, link_info))
9312 target_entry = elf_xtensa_find_property_entry
9313 (target_sec_cache->ptbl, target_sec_cache->pte_count,
9314 target_sec->
vma + target_loc->target_offset);
9322 init_ebb_constraint (&ebb_table);
9323 ebb = &ebb_table.ebb;
9324 init_ebb (ebb, target_sec_cache->sec, target_sec_cache->contents,
9325 target_sec_cache->content_length,
9326 target_sec_cache->ptbl, target_sec_cache->pte_count,
9327 target_sec_cache->relocs, target_sec_cache->reloc_count);
9331 ebb_propose_action (&ebb_table, EBB_NO_ALIGN, 0,
9332 ta_fill, target_loc->target_offset,
9336 relocs_fit = check_section_ebb_pcrels_fit (target_sec->
owner, target_sec,
9337 target_sec_cache->contents,
9338 target_sec_cache->relocs,
NULL,
9344 text_action_add_literal (&target_relax_info->action_list,
9345 ta_add_literal, target_loc, lit_value, -4);
9350 int fill_extra_space;
9358 fill_extra_space = 0;
9360 elf_xtensa_find_property_entry (target_sec_cache->ptbl,
9361 target_sec_cache->pte_count,
9364 fill_extra_space = the_add_entry->
size;
9366 target_fa = find_fill_action (&target_relax_info->action_list,
9367 target_sec, entry_sec_offset);
9368 removed_diff = compute_removed_action_diff (target_fa, target_sec,
9369 entry_sec_offset, 4,
9372 adjust_fill_action (target_fa, removed_diff);
9374 text_action_add (&target_relax_info->action_list,
9375 ta_fill, target_sec, entry_sec_offset, removed_diff);
9379 add_removed_literal (&relax_info->removed_list, &rel->rz_rel, target_loc);
9382 text_action_add (&relax_info->action_list,
9383 ta_remove_literal, sec, rel->rz_rel.target_offset, 4);
9388 int fill_extra_space;
9392 entry_sec_offset = src_entry->
address - sec->
vma + src_entry->
size;
9394 entry_sec_offset = rel->rz_rel.target_offset+4;
9398 fill_extra_space = 0;
9399 the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
9402 fill_extra_space = the_add_entry->
size;
9404 fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset);
9405 removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset,
9406 -4, fill_extra_space);
9408 adjust_fill_action (fa, removed_diff);
9410 text_action_add (&relax_info->action_list,
9411 ta_fill, sec, entry_sec_offset, removed_diff);
9421 action_remove_bytes_fn (splay_tree_node node,
void *
p)
9424 text_action *
action = (text_action *)node->value;
9426 *final_size -=
action->removed_bytes;
9438 xtensa_relax_info *relax_info;
9447 relax_info = get_xtensa_relax_info (sec);
9448 BFD_ASSERT (relax_info);
9451 translate_section_fixes (sec);
9454 if (xtensa_is_property_section (sec))
9456 BFD_ASSERT (!relax_info->is_relaxable_literal_section);
9457 return relax_property_section (abfd, sec, link_info);
9460 internal_relocs = retrieve_internal_relocs (abfd, sec,
9462 if (!internal_relocs && !action_list_count (&relax_info->action_list))
9465 contents = retrieve_contents (abfd, sec, link_info->
keep_memory);
9466 if (contents ==
NULL && sec_size != 0)
9472 if (internal_relocs)
9477 xtensa_relax_info *target_relax_info;
9478 bfd_vma source_offset, old_source_offset;
9489 irel = &internal_relocs[
i];
9491 old_source_offset = source_offset;
9494 rz_reloc_init (&rz_rel, abfd, irel, contents,
9500 if (relax_info->is_relaxable_literal_section
9501 || relax_info->is_relaxable_asm_section)
9503 pin_internal_relocs (sec, internal_relocs);
9505 if (rz_type != RZ_XTENSA_NONE
9506 && find_removed_literal (&relax_info->removed_list,
9511 shrink_dynamic_reloc_sections (link_info, abfd, sec, irel);
9513 irel->
rz_offset = offset_with_removed_text_map
9514 (&relax_info->action_list, irel->
rz_offset);
9518 if (rz_type == RZ_XTENSA_ASM_SIMPLIFY)
9521 find_insn_action (&relax_info->action_list,
9524 ||
action->action == ta_remove_longcall))
9527 char *error_message =
NULL;
9529 retval = contract_asm_expansion (contents, sec_size,
9530 irel, &error_message);
9534 (link_info, error_message, abfd, sec,
9546 if (
action->action == ta_remove_longcall)
9547 action->action = ta_remove_insn;
9549 action->action = ta_none;
9551 rz_reloc_init (&rz_rel, abfd, irel, contents, sec_size);
9556 source_offset = offset_with_removed_text_map
9557 (&relax_info->action_list, irel->
rz_offset);
9564 target_sec = rz_reloc_get_section (&rz_rel);
9571 if (! elf_xtensa_ignore_discarded_relocs (sec)
9572 && elf_xtensa_action_discarded (sec) ==
PRETEND
9574 && target_sec !=
NULL
9575 && discarded_section (target_sec))
9596 if (strcmp (
s->name, target_sec->
name) == 0)
9614 target_relax_info = get_xtensa_relax_info (target_sec);
9615 if (target_relax_info
9616 && (target_relax_info->is_relaxable_literal_section
9617 || target_relax_info->is_relaxable_asm_section))
9620 target_sec = translate_reloc (&rz_rel, &new_reloc, target_sec);
9622 if (rz_type == RZ_XTENSA_DIFF8
9623 || rz_type == RZ_XTENSA_DIFF16
9624 || rz_type == RZ_XTENSA_DIFF32)
9627 bfd_vma new_end_offset, diff_mask = 0;
9632 (link_info,
_(
"invalid relocation address"),
9633 abfd, sec, old_source_offset);
9639 case RZ_XTENSA_DIFF8:
9643 case RZ_XTENSA_DIFF16:
9647 case RZ_XTENSA_DIFF32:
9653 new_end_offset = offset_with_removed_text_map
9654 (&target_relax_info->action_list,
9655 rz_rel.target_offset + diff_value);
9656 diff_value = new_end_offset - new_reloc.target_offset;
9660 case RZ_XTENSA_DIFF8:
9663 &contents[old_source_offset]);
9665 case RZ_XTENSA_DIFF16:
9668 &contents[old_source_offset]);
9670 case RZ_XTENSA_DIFF32:
9671 diff_mask = 0x7fffffff;
9673 &contents[old_source_offset]);
9678 if ((diff_value & ~diff_mask) != 0 &&
9679 (diff_value & ~diff_mask) != (-1 & ~diff_mask))
9682 (link_info,
_(
"overflow after relaxation"),
9683 abfd, sec, old_source_offset);
9687 pin_contents (sec, contents);
9693 if (target_sec->
owner == abfd)
9695 unsigned rz_symndx =
ELF32_R_SYM (new_reloc.rela.rz_info);
9697 irel->
rz_addend = new_reloc.rela.rz_addend;
9698 pin_internal_relocs (sec, internal_relocs);
9705 addend_displacement =
9706 new_reloc.target_offset + new_reloc.virtual_offset;
9707 fix = reloc_bfd_fix_init (sec, source_offset, rz_type,
9709 addend_displacement,
TRUE);
9716 if ((relax_info->is_relaxable_literal_section
9717 || relax_info->is_relaxable_asm_section)
9718 && action_list_count (&relax_info->action_list))
9736 final_size = sec->
size;
9738 splay_tree_foreach (relax_info->action_list.tree,
9739 action_remove_bytes_fn, &final_size);
9740 scratch = (
bfd_byte *) bfd_zmalloc (final_size);
9741 dup_contents = (
bfd_byte *) bfd_zmalloc (final_size);
9745 print_action_list (stderr, &relax_info->action_list);
9748 for (
action = action_first (&relax_info->action_list);
action;
9749 action = action_next (&relax_info->action_list,
action))
9751 virtual_action =
FALSE;
9752 if (
action->offset > orig_dot)
9754 orig_dot += orig_dot_copied;
9755 orig_dot_copied = 0;
9760 if (
action->offset > orig_dot)
9762 copy_size =
action->offset - orig_dot;
9763 memmove (&dup_contents[dup_dot], &contents[orig_dot], copy_size);
9764 orig_dot += copy_size;
9765 dup_dot += copy_size;
9766 BFD_ASSERT (
action->offset == orig_dot);
9768 else if (
action->offset < orig_dot)
9770 if (
action->action == ta_fill
9775 else if (
action->action == ta_add_literal)
9780 if (
action->offset == orig_dot)
9782 if (
action->virtual_offset > orig_dot_vo)
9784 if (orig_dot_vo == 0)
9787 copy_size =
action->virtual_offset - orig_dot_vo;
9788 memmove (&dup_contents[dup_dot],
9789 &contents[orig_dot], copy_size);
9790 orig_dot_copied = copy_size;
9791 dup_dot += copy_size;
9793 virtual_action =
TRUE;
9796 BFD_ASSERT (
action->virtual_offset <= orig_dot_vo);
9800 case ta_remove_literal:
9801 case ta_remove_insn:
9802 BFD_ASSERT (
action->removed_bytes >= 0);
9803 orig_dot +=
action->removed_bytes;
9806 case ta_narrow_insn:
9809 memmove (scratch, &contents[orig_dot], orig_insn_size);
9810 BFD_ASSERT (
action->removed_bytes == 1);
9811 rv = narrow_instruction (scratch, final_size, 0);
9813 memmove (&dup_contents[dup_dot], scratch, copy_size);
9814 orig_dot += orig_insn_size;
9815 dup_dot += copy_size;
9819 if (
action->removed_bytes >= 0)
9820 orig_dot +=
action->removed_bytes;
9825 dup_dot += (-
action->removed_bytes);
9830 BFD_ASSERT (
action->removed_bytes == 0);
9833 case ta_convert_longcall:
9834 case ta_remove_longcall:
9842 memmove (scratch, &contents[orig_dot], orig_insn_size);
9843 BFD_ASSERT (
action->removed_bytes == -1);
9844 rv = widen_instruction (scratch, final_size, 0);
9846 memmove (&dup_contents[dup_dot], scratch, copy_size);
9847 orig_dot += orig_insn_size;
9848 dup_dot += copy_size;
9851 case ta_add_literal:
9854 BFD_ASSERT (
action->removed_bytes == -4);
9857 memset (&dup_contents[dup_dot], 0, 4);
9858 pin_internal_relocs (sec, internal_relocs);
9859 pin_contents (sec, contents);
9861 if (!move_literal (abfd, link_info, sec, dup_dot, dup_contents,
9862 relax_info, &internal_relocs, &
action->value))
9866 orig_dot_vo += copy_size;
9868 orig_dot += orig_insn_size;
9869 dup_dot += copy_size;
9878 BFD_ASSERT (dup_dot <= final_size);
9879 BFD_ASSERT (orig_dot <= orig_size);
9882 orig_dot += orig_dot_copied;
9883 orig_dot_copied = 0;
9885 if (orig_dot != orig_size)
9887 copy_size = orig_size - orig_dot;
9888 BFD_ASSERT (orig_size > orig_dot);
9889 BFD_ASSERT (dup_dot + copy_size == final_size);
9890 memmove (&dup_contents[dup_dot], &contents[orig_dot], copy_size);
9891 orig_dot += copy_size;
9892 dup_dot += copy_size;
9894 BFD_ASSERT (orig_size == orig_dot);
9895 BFD_ASSERT (final_size == dup_dot);
9898 if (final_size > orig_size)
9904 contents = dup_contents;
9905 pin_contents (sec, contents);
9909 BFD_ASSERT (final_size <= orig_size);
9910 memset (contents, 0, orig_size);
9911 memcpy (contents, dup_contents, final_size);
9912 free (dup_contents);
9915 pin_contents (sec, contents);
9919 sec->
size = final_size;
9923 release_internal_relocs (sec, internal_relocs);
9924 release_contents (sec, contents);
9930 translate_section_fixes (
asection *sec)
9932 xtensa_relax_info *relax_info;
9935 relax_info = get_xtensa_relax_info (sec);
9939 for (
r = relax_info->fix_list;
r !=
NULL;
r =
r->next)
9940 if (!translate_reloc_bfd_fix (
r))
9951 translate_reloc_bfd_fix (reloc_bfd_fix *fix)
9953 reloc_bfd_fix new_fix;
9955 xtensa_relax_info *relax_info;
9956 removed_literal *removed;
9957 bfd_vma new_offset, target_offset;
9959 if (fix->translated)
9962 sec = fix->target_sec;
9963 target_offset = fix->target_offset;
9965 relax_info = get_xtensa_relax_info (sec);
9968 fix->translated =
TRUE;
9975 if (!relax_info->is_relaxable_literal_section
9976 && !relax_info->is_relaxable_asm_section)
9978 fix->translated =
TRUE;
9988 if (is_operand_relocation (fix->src_type))
9992 removed = find_removed_literal (&relax_info->removed_list,
10002 BFD_ASSERT (removed->to.abfd !=
NULL);
10005 new_sec = rz_reloc_get_section (&removed->to);
10006 if (new_sec != sec)
10009 relax_info = get_xtensa_relax_info (sec);
10011 (!relax_info->is_relaxable_literal_section
10012 && !relax_info->is_relaxable_asm_section))
10014 target_offset = removed->to.target_offset;
10015 new_fix.target_sec = new_sec;
10016 new_fix.target_offset = target_offset;
10017 new_fix.translated =
TRUE;
10022 target_offset = removed->to.target_offset;
10023 new_fix.target_sec = new_sec;
10027 new_offset = offset_with_removed_text (&relax_info->action_list,
10030 new_fix.target_offset = new_offset;
10031 new_fix.target_offset = new_offset;
10032 new_fix.translated =
TRUE;
10041 translate_reloc (
const rz_reloc *orig_rel, rz_reloc *new_rel,
asection *sec)
10043 xtensa_relax_info *relax_info;
10044 removed_literal *removed;
10045 bfd_vma target_offset, base_offset;
10047 *new_rel = *orig_rel;
10049 if (!rz_reloc_is_defined (orig_rel))
10052 relax_info = get_xtensa_relax_info (sec);
10053 BFD_ASSERT (relax_info && (relax_info->is_relaxable_literal_section
10054 || relax_info->is_relaxable_asm_section));
10056 target_offset = orig_rel->target_offset;
10059 if (is_operand_relocation (
ELF32_R_TYPE (orig_rel->rela.rz_info)))
10063 removed = find_removed_literal (&relax_info->removed_list,
10066 if (removed && removed->to.abfd)
10072 BFD_ASSERT (removed->to.abfd !=
NULL);
10076 *new_rel = removed->to;
10077 new_sec = rz_reloc_get_section (new_rel);
10078 if (new_sec != sec)
10081 relax_info = get_xtensa_relax_info (sec);
10083 || (!relax_info->is_relaxable_literal_section
10084 && !relax_info->is_relaxable_asm_section))
10087 target_offset = new_rel->target_offset;
10097 base_offset = rz_reloc_get_target_offset (new_rel) - new_rel->rela.rz_addend;
10098 if (base_offset <= target_offset)
10100 int base_removed = removed_by_actions_map (&relax_info->action_list,
10101 base_offset,
FALSE);
10102 int addend_removed = removed_by_actions_map (&relax_info->action_list,
10103 target_offset,
FALSE) -
10106 new_rel->target_offset = target_offset - base_removed - addend_removed;
10107 new_rel->rela.rz_addend -= addend_removed;
10112 int tgt_removed = removed_by_actions_map (&relax_info->action_list,
10113 target_offset,
FALSE);
10114 int addend_removed = removed_by_actions_map (&relax_info->action_list,
10115 base_offset,
FALSE) -
10118 new_rel->target_offset = target_offset - tgt_removed;
10119 new_rel->rela.rz_addend += addend_removed;
10141 struct elf_xtensa_link_hash_table *htab;
10144 unsigned long rz_symndx;
10149 htab = elf_xtensa_hash_table (
info);
10153 symtab_hdr = &
elf_tdata (abfd)->symtab_hdr;
10159 if (rz_symndx < symtab_hdr->sh_info)
10162 h = sym_hashes[rz_symndx - symtab_hdr->
sh_info];
10164 dynamic_symbol = elf_xtensa_dynamic_symbol_p (
h,
info);
10166 if ((rz_type == RZ_XTENSA_32 || rz_type == RZ_XTENSA_PLT)
10168 && (dynamic_symbol ||
info->shared))
10173 if (dynamic_symbol && rz_type == RZ_XTENSA_PLT)
10175 srel = htab->srelplt;
10179 srel = htab->srelgot;
10182 BFD_ASSERT (srel !=
NULL);
10188 asection *splt, *sgotplt, *srelgot;
10189 int reloc_index,
chunk;
10199 chunk = reloc_index / PLT_ENTRIES_PER_CHUNK;
10200 splt = elf_xtensa_get_plt_section (
info,
chunk);
10201 sgotplt = elf_xtensa_get_gotplt_section (
info,
chunk);
10202 BFD_ASSERT (splt !=
NULL && sgotplt !=
NULL);
10205 if (reloc_index % PLT_ENTRIES_PER_CHUNK == 0)
10208 srelgot = htab->srelgot;
10209 BFD_ASSERT (srelgot !=
NULL);
10212 sgotplt->
size -= 8;
10216 BFD_ASSERT (sgotplt->
size == 4);
10217 BFD_ASSERT (splt->
size == PLT_ENTRY_SIZE);
10220 BFD_ASSERT (sgotplt->
size >= 4);
10221 BFD_ASSERT (splt->
size >= PLT_ENTRY_SIZE);
10223 sgotplt->
size -= 4;
10224 splt->
size -= PLT_ENTRY_SIZE;
10238 move_literal (
bfd *abfd,
10243 xtensa_relax_info *relax_info,
10245 const literal_value *lit)
10248 size_t new_relocs_count = 0;
10250 const rz_reloc *rz_rel;
10252 rz_rel = &lit->rz_rel;
10255 if (rz_reloc_is_const (rz_rel))
10261 reloc_bfd_fix *fix;
10262 unsigned insert_at;
10270 rz_rel->target_offset - rz_reloc_get_target_offset (rz_rel);
10275 fix = reloc_bfd_fix_init (sec,
offset, rz_type,
10276 rz_reloc_get_section (rz_rel),
10277 rz_rel->target_offset + rz_rel->virtual_offset,
10282 translate_reloc_bfd_fix (fix);
10284 add_fix (sec, fix);
10292 if (this_rela.
rz_offset < (*internal_relocs_p)[
i].rz_offset)
10299 if (*internal_relocs_p != relax_info->allocated_relocs
10300 || sec->
reloc_count + 1 > relax_info->allocated_relocs_count)
10302 BFD_ASSERT (relax_info->allocated_relocs ==
NULL
10303 || sec->
reloc_count == relax_info->relocs_count);
10305 if (relax_info->allocated_relocs_count == 0)
10308 new_relocs_count = (relax_info->allocated_relocs_count + 2) * 2;
10316 if (insert_at != 0)
10317 memcpy (new_relocs, *internal_relocs_p,
10320 new_relocs[insert_at] = this_rela;
10323 memcpy (new_relocs + insert_at + 1,
10324 (*internal_relocs_p) + insert_at,
10328 if (*internal_relocs_p != relax_info->allocated_relocs)
10334 free (*internal_relocs_p);
10337 free (*internal_relocs_p);
10338 relax_info->allocated_relocs = new_relocs;
10339 relax_info->allocated_relocs_count = new_relocs_count;
10343 *internal_relocs_p = new_relocs;
10351 (*internal_relocs_p)[
idx] = (*internal_relocs_p)[
idx-1];
10353 (*internal_relocs_p)[insert_at] = this_rela;
10355 if (relax_info->allocated_relocs)
10369 relax_property_section (
bfd *abfd,
10378 size_t last_zfill_target_offset = 0;
10384 internal_relocs = retrieve_internal_relocs (abfd, sec,
10386 contents = retrieve_contents (abfd, sec, link_info->
keep_memory);
10387 if (contents ==
NULL && sec_size != 0)
10393 is_full_prop_section = xtensa_is_proptable_section (sec);
10394 if (is_full_prop_section)
10399 if (internal_relocs)
10404 xtensa_relax_info *target_relax_info;
10416 irel = &internal_relocs[
i];
10418 if (rz_type == RZ_XTENSA_NONE)
10422 rz_reloc_init (&
val.rz_rel, abfd, irel, contents, sec_size);
10423 size_p = &contents[irel->
rz_offset + 4];
10425 if (is_full_prop_section)
10426 flags_p = &contents[irel->
rz_offset + 8];
10427 BFD_ASSERT (irel->
rz_offset + entry_size <= sec_size);
10429 target_sec = rz_reloc_get_section (&
val.rz_rel);
10430 target_relax_info = get_xtensa_relax_info (target_sec);
10432 if (target_relax_info
10433 && (target_relax_info->is_relaxable_literal_section
10434 || target_relax_info->is_relaxable_asm_section ))
10437 bfd_vma old_offset =
val.rz_rel.target_offset;
10439 long old_size, new_size;
10440 int removed_by_old_offset =
10441 removed_by_actions_map (&target_relax_info->action_list,
10442 old_offset,
FALSE);
10443 new_offset = old_offset - removed_by_old_offset;
10447 new_size = old_size;
10459 if (last_zfill_target_sec == 0
10460 || last_zfill_target_sec != target_sec
10461 || last_zfill_target_offset != old_offset)
10463 bfd_vma new_end_offset = new_offset;
10467 removed_by_old_offset =
10468 removed_by_actions_map (&target_relax_info->action_list,
10470 new_offset = old_offset - removed_by_old_offset;
10478 new_size = new_end_offset - new_offset;
10480 last_zfill_target_sec = target_sec;
10481 last_zfill_target_offset = old_offset;
10487 int removed_by_old_offset_size =
10488 removed_by_actions_map (&target_relax_info->action_list,
10489 old_offset + old_size,
TRUE);
10490 new_size -= removed_by_old_offset_size - removed_by_old_offset;
10493 if (new_size != old_size)
10496 pin_contents (sec, contents);
10499 if (new_offset != old_offset)
10501 bfd_vma diff = new_offset - old_offset;
10503 pin_internal_relocs (sec, internal_relocs);
10514 || xtensa_is_littable_section (sec)))
10518 int removed_bytes = 0;
10522 predef_flags = xtensa_get_property_predef_flags (sec);
10527 internal_reloc_compare);
10529 pin_internal_relocs (sec, internal_relocs);
10530 pin_contents (sec, contents);
10532 next_rel = internal_relocs;
10535 BFD_ASSERT (sec->
size % entry_size == 0);
10550 for (irel = next_rel; irel < rel_end; irel++)
10567 for (irel = offset_rel + 1; irel < rel_end; irel++)
10586 next_rel = offset_rel;
10597 next_rel = offset_rel;
10603 offset_rel->
rz_offset -= removed_bytes;
10604 next_rel = offset_rel + 1;
10610 remove_this_rel =
FALSE;
10611 bytes_to_remove = 0;
10612 actual_offset =
offset - removed_bytes;
10615 if (is_full_prop_section)
10618 flags = predef_flags;
10625 bytes_to_remove = entry_size;
10627 remove_this_rel =
TRUE;
10629 else if (offset_rel
10642 +
bfd_get_32 (abfd, &contents[actual_offset]));
10643 if (is_full_prop_section)
10645 (abfd, &contents[last_irel->
rz_offset + 8]);
10647 old_flags = predef_flags;
10651 && old_address + old_size == new_address
10652 && old_flags ==
flags
10659 bytes_to_remove = entry_size;
10660 remove_this_rel =
TRUE;
10663 last_irel = offset_rel;
10666 last_irel = offset_rel;
10669 if (remove_this_rel)
10675 if (bytes_to_remove != 0)
10677 removed_bytes += bytes_to_remove;
10679 memmove (&contents[actual_offset],
10680 &contents[actual_offset + bytes_to_remove],
10688 for (irel = next_rel; irel < rel_end; irel++)
10692 memset (&contents[sec->
size - removed_bytes], 0, removed_bytes);
10696 sec->
size -= removed_bytes;
10698 if (xtensa_is_littable_section (sec))
10700 asection *sgotloc = elf_xtensa_hash_table (link_info)->sgotloc;
10702 sgotloc->
size -= removed_bytes;
10708 release_internal_relocs (sec, internal_relocs);
10709 release_contents (sec, contents);
10721 xtensa_relax_info *relax_info;
10722 unsigned int sec_shndx;
10725 unsigned i, num_syms, num_locals;
10727 relax_info = get_xtensa_relax_info (sec);
10728 BFD_ASSERT (relax_info);
10730 if (!relax_info->is_relaxable_literal_section
10731 && !relax_info->is_relaxable_asm_section)
10736 symtab_hdr = &
elf_tdata (abfd)->symtab_hdr;
10737 isymbuf = retrieve_local_syms (abfd);
10740 num_locals = symtab_hdr->
sh_info;
10743 for (
i = 0;
i < num_locals;
i++)
10750 int removed = removed_by_actions_map (&relax_info->action_list,
10756 removed_by_actions_map (&relax_info->action_list,
10763 for (
i = 0;
i < (num_syms - num_locals);
i++)
10774 && sym_hash->
root.
u.
def.section == sec)
10777 int removed = removed_by_actions_map (&relax_info->action_list,
10780 sym_hash->
root.
u.
def.value -= removed;
10784 removed_by_actions_map (&relax_info->action_list,
10806 reloc_bfd_fix *fix;
10808 if (rz_type == RZ_XTENSA_NONE)
10811 fix = get_bfd_fix (input_section, rel->
rz_offset, rz_type);
10815 rz_reloc_init (&rz_rel, input_bfd, rel, contents,
10817 old_sec = rz_reloc_get_section (&rz_rel);
10818 old_offset = rz_rel.target_offset;
10820 if (!old_sec || !rz_reloc_is_defined (&rz_rel))
10822 if (rz_type != RZ_XTENSA_ASM_EXPAND)
10824 (*_bfd_error_handler)
10825 (
_(
"%B(%A+0x%lx): unexpected fix for %s relocation"),
10826 input_bfd, input_section, rel->
rz_offset,
10827 elf_howto_table[rz_type].
name);
10834 sec = fix->target_sec;
10851 reloc_bfd_fix *fix;
10854 if (rz_type == RZ_XTENSA_NONE)
10857 fix = get_bfd_fix (input_section, rel->
rz_offset, rz_type);
10861 sec = fix->target_sec;
10864 if (elf_howto_table[fix->src_type].partial_inplace)
10867 BFD_ASSERT (fix->src_offset
10869 inplace_val =
bfd_get_32 (input_bfd, &contents[fix->src_offset]);
10870 fixup_diff += inplace_val;
10875 + fix->target_offset - fixup_diff);
10884 struct elf_xtensa_link_hash_table *htab;
10890 htab = elf_xtensa_hash_table (
info);
10899 return bfd_get_linker_section (dynobj, plt_name);
10906 struct elf_xtensa_link_hash_table *htab;
10912 htab = elf_xtensa_hash_table (
info);
10915 return htab->sgotplt;
10920 return bfd_get_linker_section (dynobj, got_name);
10933 get_elf_r_symndx_section (
bfd *abfd,
unsigned long rz_symndx)
10937 if (rz_symndx < symtab_hdr->sh_info)
10940 unsigned int section_index;
10942 isymbuf = retrieve_local_syms (abfd);
10943 section_index = isymbuf[rz_symndx].
st_shndx;
10947 else if (section_index ==
SHN_ABS)
10956 unsigned long indx = rz_symndx - symtab_hdr->
sh_info;
10963 switch (
h->root.type)
10967 target_sec =
h->root.u.def.section;
10986 get_elf_r_symndx_hash_entry (
bfd *abfd,
unsigned long rz_symndx)
10988 unsigned long indx;
10992 if (rz_symndx < symtab_hdr->sh_info)
11007 get_elf_r_symndx_offset (
bfd *abfd,
unsigned long rz_symndx)
11012 if (rz_symndx < symtab_hdr->sh_info)
11015 isymbuf = retrieve_local_syms (abfd);
11020 unsigned long indx = rz_symndx - symtab_hdr->
sh_info;
11029 offset =
h->root.u.def.value;
11041 h = get_elf_r_symndx_hash_entry (abfd, rz_symndx);
11055 uint32 valp = dest_address;
11064 xtensa_is_property_section (
asection *sec)
11066 if (xtensa_is_insntable_section (sec)
11067 || xtensa_is_littable_section (sec)
11068 || xtensa_is_proptable_section (sec))
11076 xtensa_is_insntable_section (
asection *sec)
11087 xtensa_is_littable_section (
asection *sec)
11098 xtensa_is_proptable_section (
asection *sec)
11109 internal_reloc_compare (
const void *ap,
const void *bp)
11114 if (
a->rz_offset !=
b->rz_offset)
11115 return (
a->rz_offset -
b->rz_offset);
11124 if (
a->rz_info !=
b->rz_info)
11125 return (
a->rz_info -
b->rz_info);
11127 return (
a->rz_addend -
b->rz_addend);
11132 internal_reloc_matches (
const void *ap,
const void *bp)
11139 return (
a->rz_offset -
b->rz_offset);
11148 const char *gname =
inf;
11151 return (group_name == gname
11152 || (group_name !=
NULL
11154 && strcmp (group_name, gname) == 0));
11158 static int linkonce_len =
sizeof (
".gnu.linkonce.") - 1;
11161 xtensa_property_section_name (
asection *sec,
const char *base_name)
11163 const char *
suffix, *group_name;
11164 char *prop_sec_name;
11172 prop_sec_name = (
char *)
bfd_malloc (strlen (base_name) + 1
11174 strcpy (prop_sec_name, base_name);
11176 strcat (prop_sec_name,
suffix);
11178 else if (strncmp (sec->
name,
".gnu.linkonce.", linkonce_len) == 0)
11180 char *linkonce_kind = 0;
11183 linkonce_kind =
"x.";
11185 linkonce_kind =
"p.";
11187 linkonce_kind =
"prop.";
11192 + strlen (linkonce_kind) + 1);
11193 memcpy (prop_sec_name,
".gnu.linkonce.", linkonce_len);
11194 strcpy (prop_sec_name + linkonce_len, linkonce_kind);
11201 strcat (prop_sec_name + linkonce_len,
suffix);
11204 prop_sec_name =
strdup (base_name);
11206 return prop_sec_name;
11211 xtensa_get_property_section (
asection *sec,
const char *base_name)
11213 char *prop_sec_name;
11216 prop_sec_name = xtensa_property_section_name (sec, base_name);
11218 match_section_group,
11220 free (prop_sec_name);
11226 xtensa_make_property_section (
asection *sec,
const char *base_name)
11228 char *prop_sec_name;
11232 prop_sec_name = xtensa_property_section_name (sec, base_name);
11234 match_section_group,
11251 free (prop_sec_name);
11257 xtensa_get_property_predef_flags (
asection *sec)
11259 if (xtensa_is_insntable_section (sec))
11264 if (xtensa_is_littable_section (sec))
11276 xtensa_callback_required_dependence (
bfd *abfd,
11279 deps_callback_t callback,
11298 if (sec->
name[4] ==
'\0')
11299 sgotplt = bfd_get_linker_section (sec->
owner,
".got.plt");
11305 BFD_ASSERT (sec->
name[4] ==
'.');
11309 sgotplt = bfd_get_linker_section (sec->
owner, got_name);
11311 BFD_ASSERT (sgotplt);
11316 (*callback) (sec, sec_size, sgotplt, 0, closure);
11324 internal_relocs = retrieve_internal_relocs (abfd, sec,
11326 if (internal_relocs ==
NULL
11331 contents = retrieve_contents (abfd, sec, link_info->
keep_memory);
11332 if (contents ==
NULL && sec_size != 0)
11344 if (is_l32r_relocation (abfd, sec, contents, irel))
11350 rz_reloc_init (&l32r_rel, abfd, irel, contents, sec_size);
11354 if (rz_reloc_is_defined (&l32r_rel))
11356 target_sec = rz_reloc_get_section (&l32r_rel);
11357 target_offset = l32r_rel.target_offset;
11359 (*callback) (sec, irel->
rz_offset, target_sec, target_offset,
11365 release_internal_relocs (sec, internal_relocs);
11366 release_contents (sec, contents);
11378 { STRING_COMMA_LEN (
".xtensa.info"), 0,
SHT_NOTE, 0 },
11379 {
NULL, 0, 0, 0, 0 }
11382 #define ELF_TARGET_ID XTENSA_ELF_DATA
11384 #define TARGET_LITTLE_SYM xtensa_elf32_le_vec
11385 #define TARGET_LITTLE_NAME "elf32-xtensa-le"
11386 #define TARGET_BIG_SYM xtensa_elf32_be_vec
11387 #define TARGET_BIG_NAME "elf32-xtensa-be"
11388 #define ELF_ARCH bfd_arch_xtensa
11390 #define ELF_MACHINE_CODE EM_XTENSA
11391 #define ELF_MACHINE_ALT1 EM_XTENSA_OLD
11394 #define ELF_MAXPAGESIZE (1 << XCHAL_MMU_MIN_PTE_PAGE_SIZE)
11396 #define ELF_MAXPAGESIZE 1
11400 #define elf_backend_can_gc_sections 1
11401 #define elf_backend_can_refcount 1
11402 #define elf_backend_plt_readonly 1
11403 #define elf_backend_got_header_size 4
11404 #define elf_backend_want_dynbss 0
11405 #define elf_backend_want_got_plt 1
11407 #define elf_info_to_howto elf_xtensa_info_to_howto_rela
11409 #define bfd_elf32_mkobject elf_xtensa_mkobject
11411 #define bfd_elf32_bfd_merge_private_bfd_data elf_xtensa_merge_private_bfd_data
11412 #define bfd_elf32_new_section_hook elf_xtensa_new_section_hook
11413 #define bfd_elf32_bfd_print_private_bfd_data elf_xtensa_print_private_bfd_data
11414 #define bfd_elf32_bfd_relax_section elf_xtensa_relax_section
11415 #define bfd_elf32_bfd_reloc_type_lookup elf_xtensa_reloc_type_lookup
11416 #define bfd_elf32_bfd_reloc_name_lookup \
11417 elf_xtensa_reloc_name_lookup
11418 #define bfd_elf32_bfd_set_private_flags elf_xtensa_set_private_flags
11419 #define bfd_elf32_bfd_link_hash_table_create elf_xtensa_link_hash_table_create
11421 #define elf_backend_adjust_dynamic_symbol elf_xtensa_adjust_dynamic_symbol
11422 #define elf_backend_check_relocs elf_xtensa_check_relocs
11423 #define elf_backend_create_dynamic_sections elf_xtensa_create_dynamic_sections
11424 #define elf_backend_discard_info elf_xtensa_discard_info
11425 #define elf_backend_ignore_discarded_relocs elf_xtensa_ignore_discarded_relocs
11426 #define elf_backend_final_write_processing elf_xtensa_final_write_processing
11427 #define elf_backend_finish_dynamic_sections elf_xtensa_finish_dynamic_sections
11428 #define elf_backend_finish_dynamic_symbol elf_xtensa_finish_dynamic_symbol
11429 #define elf_backend_gc_mark_hook elf_xtensa_gc_mark_hook
11430 #define elf_backend_gc_sweep_hook elf_xtensa_gc_sweep_hook
11431 #define elf_backend_grok_prstatus elf_xtensa_grok_prstatus
11432 #define elf_backend_grok_psinfo elf_xtensa_grok_psinfo
11433 #define elf_backend_hide_symbol elf_xtensa_hide_symbol
11434 #define elf_backend_object_p elf_xtensa_object_p
11435 #define elf_backend_reloc_type_class elf_xtensa_reloc_type_class
11436 #define elf_backend_relocate_section elf_xtensa_relocate_section
11437 #define elf_backend_size_dynamic_sections elf_xtensa_size_dynamic_sections
11438 #define elf_backend_always_size_sections elf_xtensa_always_size_sections
11439 #define elf_backend_omit_section_dynsym \
11440 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
11441 #define elf_backend_special_sections elf_xtensa_special_sections
11442 #define elf_backend_action_discarded elf_xtensa_action_discarded
11443 #define elf_backend_copy_indirect_symbol elf_xtensa_copy_indirect_symbol
11445 #include "elf32-target.h"
lsl lsr asr ror lsl lsr asr ror lsl lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror c1
lsl lsr asr ror lsl lsr asr ror lsl lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror c2
@ bfd_link_hash_undefweak
@ bfd_link_hash_undefined
RzBinInfo * info(RzBinFile *bf)
RzList * relocs(RzBinFile *bf)
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags long
static int is_null(const ut8 *buf, int size)
void bfd_elf32_swap_dyn_in(bfd *, const void *, Elf_Internal_Dyn *)
#define elf_local_got_refcounts(bfd)
bfd_reloc_status_type bfd_elf_generic_reloc(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **)
bfd_boolean bfd_elf_gc_record_vtinherit(bfd *, asection *, struct elf_link_hash_entry *, bfd_vma)
bfd_boolean _bfd_elf_print_private_bfd_data(bfd *, void *)
Elf_Internal_Sym * bfd_elf_get_elf_syms(bfd *, Elf_Internal_Shdr *, size_t, size_t, Elf_Internal_Sym *, void *, Elf_External_Sym_Shndx *)
#define NUM_SHDR_ENTRIES(shdr)
Elf_Internal_Rela * _bfd_elf_link_read_relocs(bfd *, asection *, void *, Elf_Internal_Rela *, bfd_boolean)
void _bfd_elf_link_hash_hide_symbol(struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean)
#define RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel, rz_symndx, symtab_hdr, sym_hashes, h, sec, relocation, unresolved_reloc, warned)
bfd_boolean _bfd_elf_new_section_hook(bfd *, asection *)
#define elf_group_name(sec)
void bfd_elf32_swap_dyn_out(bfd *, const Elf_Internal_Dyn *, void *)
#define elf_link_hash_traverse(table, func, info)
bfd_boolean bfd_elf_gc_record_vtentry(bfd *, asection *, struct elf_link_hash_entry *, bfd_vma)
bfd_vma _bfd_elf_rela_local_sym(bfd *, Elf_Internal_Sym *, asection **, Elf_Internal_Rela *)
bfd_boolean _bfd_elfcore_make_pseudosection(bfd *, char *, size_t, ufile_ptr)
void bfd_elf32_swap_reloca_out(bfd *, const Elf_Internal_Rela *, bfd_byte *)
bfd_boolean _bfd_elf_link_hash_table_init(struct elf_link_hash_table *, bfd *, struct bfd_hash_entry *(*)(struct bfd_hash_entry *, struct bfd_hash_table *, const char *), unsigned int)
void _bfd_elf_link_hash_copy_indirect(struct bfd_link_info *, struct elf_link_hash_entry *, struct elf_link_hash_entry *)
#define elf_flags_init(bfd)
bfd_boolean _bfd_elf_dynamic_symbol_p(struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean)
char * _bfd_elfcore_strndup(bfd *, char *, size_t)
#define elf_section_data(sec)
bfd_vma _bfd_elf_section_offset(bfd *, struct bfd_link_info *, asection *, bfd_vma)
bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn(bfd *, arelent *, struct bfd_symbol *, void *, asection *, bfd *, char **)
char * bfd_elf_string_from_elf_section(bfd *, unsigned, unsigned)
bfd_boolean _bfd_elf_create_dynamic_sections(bfd *, struct bfd_link_info *)
#define elf_hash_table(p)
#define get_elf_backend_data(abfd)
struct bfd_hash_entry * _bfd_elf_link_hash_newfunc(struct bfd_hash_entry *, struct bfd_hash_table *, const char *)
#define elf_next_in_group(sec)
#define elf_elfheader(bfd)
void bfd_elf32_swap_reloca_in(bfd *, const bfd_byte *, Elf_Internal_Rela *)
asection * _bfd_elf_gc_mark_hook(asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)
asection * bfd_section_from_elf_index(bfd *, unsigned int)
#define elf_link_hash_lookup(table, string, create, copy, follow)
bfd_boolean bfd_elf_reloc_symbol_deleted_p(bfd_vma, void *)
#define elf_sym_hashes(bfd)
int _bfd_elf_section_from_bfd_section(bfd *, asection *)
#define XTENSA_NO_NOP_REMOVAL
int filename_cmp(const char *s1, const char *s2)
xtensa_isa xtensa_default_isa
size_t map(int syms, int left, int len)
unsigned char suffix[65536]
RZ_API void Ht_() free(HtName_(Ht) *ht)
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
#define ATTRIBUTE_PRINTF(m, n)
#define ELF32_R_INFO(s, t)
static void list(RzEgg *egg)
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
static void struct sockaddr socklen_t static fromlen static backlog static fork char char char static envp int struct rusage static rusage struct utsname static buf struct sembuf unsigned
static void literal(lzma_lzma1_encoder *coder, lzma_mf *mf, uint32_t position)
bfd_boolean bfd_malloc_and_get_section(bfd *abfd, asection *section, bfd_byte **buf)
bfd_boolean bfd_set_section_flags(bfd *abfd, asection *sec, flagword flags)
unsigned int _bfd_elf_default_action_discarded(struct bfd_section *)
BFD_HOST_64_BIT bfd_signed_vma
BFD_HOST_U_64_BIT bfd_size_type
asection * bfd_get_section_by_name(bfd *abfd, const char *name)
enum bfd_reloc_code_real bfd_reloc_code_real_type
#define SEC_LINKER_CREATED
enum bfd_reloc_status bfd_reloc_status_type
#define bfd_get_signed_32(abfd, ptr)
#define bfd_is_abs_section(sec)
#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC)
#define bfd_is_com_section(ptr)
#define CONST_STRNEQ(STR1, STR2)
const bfd_arch_info_type * bfd_get_arch_info(bfd *abfd)
#define bfd_get_signed_16(abfd, ptr)
asection * bfd_get_section_by_name_if(bfd *abfd, const char *name, bfd_boolean(*func)(bfd *abfd, asection *sect, void *obj), void *obj)
BFD_HOST_U_64_BIT bfd_vma
#define bfd_get_signed_8(abfd, ptr)
#define bfd_section_name(bfd, ptr)
#define bfd_big_endian(abfd)
unsigned long bfd_get_mach(bfd *abfd)
#define bfd_get_section_flags(bfd, ptr)
#define bfd_get_section_name(bfd, ptr)
#define bfd_abs_section_ptr
#define bfd_get_16(abfd, ptr)
void * bfd_hash_allocate(struct bfd_hash_table *, unsigned int)
void bfd_set_error(bfd_error_type error_tag)
unsigned int bfd_octets_per_byte(bfd *abfd)
#define bfd_get_flavour(abfd)
#define fprintf_vma(s, x)
#define bfd_set_section_alignment(bfd, ptr, val)
#define bfd_und_section_ptr
@ BFD_RELOC_XTENSA_RELATIVE
@ BFD_RELOC_XTENSA_ASM_EXPAND
@ BFD_RELOC_XTENSA_SLOT0_OP
@ BFD_RELOC_XTENSA_JMP_SLOT
@ BFD_RELOC_XTENSA_SLOT0_ALT
@ BFD_RELOC_XTENSA_DIFF32
@ BFD_RELOC_XTENSA_ASM_SIMPLIFY
@ BFD_RELOC_XTENSA_SLOT14_OP
@ BFD_RELOC_XTENSA_SLOT14_ALT
@ BFD_RELOC_VTABLE_INHERIT
@ BFD_RELOC_XTENSA_DIFF16
@ BFD_RELOC_XTENSA_GLOB_DAT
asection * bfd_make_section_anyway_with_flags(bfd *abfd, const char *name, flagword flags)
#define bfd_put_signed_32
#define align_power(addr, align)
#define bfd_put_32(abfd, val, ptr)
#define bfd_get_section_limit(bfd, sec)
#define bfd_put_16(abfd, val, ptr)
#define bfd_is_und_section(sec)
@ complain_overflow_bitfield
@ complain_overflow_signed
#define SEC_LINK_DUPLICATES
enum bfd_architecture bfd_get_arch(bfd *abfd)
#define bfd_set_arch_mach(abfd, arch, mach)
#define bfd_put_signed_16
bfd_boolean bfd_set_section_contents(bfd *abfd, asection *section, const void *data, file_ptr offset, bfd_size_type count)
#define bfd_get_32(abfd, ptr)
#define bfd_com_section_ptr
v0.v4.v8.v15.v3.v30.v14.v1. h2
void qsort(void *a, size_t n, size_t es, int(*cmp)(const void *, const void *))
RZ_API int rz_str_casecmp(const char *dst, const char *orig)
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen const void const struct sockaddr to
static struct sockaddr static addrlen static backlog const void static flags void flags
static struct sockaddr static addrlen static backlog const void msg
#define br(opcode, mask, lose, flags)
bfd_boolean(* reloc_dangerous)(struct bfd_link_info *, const char *message, bfd *abfd, asection *section, bfd_vma address)
struct bfd_link_hash_entry::@70::@73 i
union bfd_link_hash_entry::@70 u
struct bfd_link_hash_entry::@70::@72 def
enum bfd_link_hash_type type
struct bfd_link_hash_entry::@70::@71 undef
const struct bfd_link_callbacks * callbacks
struct bfd_section * next
unsigned int alignment_power
struct bfd_section * kept_section
unsigned int sec_info_type
struct bfd_section * output_section
struct bfd_section * section
struct bfd_section * sections
void(* elf_backend_hide_symbol)(struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean)
union elf_internal_dyn::@82 d_un
union elf_link_hash_entry::gotplt_union got
struct bfd_link_hash_entry root
Elf_Internal_Rela * relend
bfd_boolean partial_inplace
if(dbg->bits==RZ_SYS_BITS_64)
int xtensa_operand_is_PCrelative(xtensa_isa isa, xtensa_opcode opc, int opnd)
int xtensa_isa_num_opcodes(xtensa_isa isa)
int xtensa_format_get_slot(xtensa_isa isa, xtensa_format fmt, int slot, const xtensa_insnbuf insn, xtensa_insnbuf slotbuf)
int xtensa_opcode_is_loop(xtensa_isa isa, xtensa_opcode opc)
int xtensa_operand_encode(xtensa_isa isa, xtensa_opcode opc, int opnd, uint32 *valp)
int xtensa_operand_do_reloc(xtensa_isa isa, xtensa_opcode opc, int opnd, uint32 *valp, uint32 pc)
int xtensa_format_num_slots(xtensa_isa isa, xtensa_format fmt)
int xtensa_format_set_slot(xtensa_isa isa, xtensa_format fmt, int slot, xtensa_insnbuf insn, const xtensa_insnbuf slotbuf)
int xtensa_operand_set_field(xtensa_isa isa, xtensa_opcode opc, int opnd, xtensa_format fmt, int slot, xtensa_insnbuf slotbuf, uint32 val)
int xtensa_operand_is_register(xtensa_isa isa, xtensa_opcode opc, int opnd)
int xtensa_isa_num_formats(xtensa_isa isa)
xtensa_opcode xtensa_opcode_decode(xtensa_isa isa, xtensa_format fmt, int slot, const xtensa_insnbuf slotbuf)
int xtensa_opcode_num_operands(xtensa_isa isa, xtensa_opcode opc)
xtensa_insnbuf_word * xtensa_insnbuf
int xtensa_format_encode(xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn)
int xtensa_operand_get_field(xtensa_isa isa, xtensa_opcode opc, int opnd, xtensa_format fmt, int slot, const xtensa_insnbuf slotbuf, uint32 *valp)
int xtensa_operand_decode(xtensa_isa isa, xtensa_opcode opc, int opnd, uint32 *valp)
int xtensa_format_length(xtensa_isa isa, xtensa_format fmt)
int xtensa_insnbuf_to_chars(xtensa_isa isa, const xtensa_insnbuf insn, unsigned char *cp, int num_chars)
xtensa_format xtensa_format_decode(xtensa_isa isa, const xtensa_insnbuf insn)
void xtensa_insnbuf_from_chars(xtensa_isa isa, xtensa_insnbuf insn, const unsigned char *cp, int num_chars)
xtensa_isa xtensa_isa_init(xtensa_isa_status *errno_p, char **error_msg_p)
int xtensa_operand_is_visible(xtensa_isa isa, xtensa_opcode opc, int opnd)
xtensa_opcode xtensa_opcode_lookup(xtensa_isa isa, const char *opname)
void xtensa_insnbuf_free(xtensa_isa isa, xtensa_insnbuf buf)
xtensa_format xtensa_format_lookup(xtensa_isa isa, const char *fmtname)
int xtensa_opcode_encode(xtensa_isa isa, xtensa_format fmt, int slot, xtensa_insnbuf slotbuf, xtensa_opcode opc)
const char * xtensa_opcode_name(xtensa_isa isa, xtensa_opcode opc)
xtensa_insnbuf xtensa_insnbuf_alloc(xtensa_isa isa)
#define DT_XTENSA_GOT_LOC_SZ
#define XTENSA_PROP_SEC_NAME
#define XTENSA_PROP_LITERAL
#define DT_XTENSA_GOT_LOC_OFF
#define EF_XTENSA_XT_INSN
#define XTENSA_PROP_UNREACHABLE
#define GET_XTENSA_PROP_ALIGNMENT(flag)
#define XTENSA_PROP_INSN_NO_REORDER
#define XTENSA_LIT_SEC_NAME
#define XTENSA_INSN_SEC_NAME
#define XTENSA_PROP_NO_TRANSFORM
#define XTENSA_PROP_INSN_BRANCH_TARGET
#define XTENSA_PROP_INSN_NO_DENSITY
#define XTENSA_PROP_ALIGN
#define XTENSA_PROP_INSN_LOOP_TARGET
static int indx(const char **ptr, const char **list, int error, const char **expr)
int inf(FILE *source, FILE *dest)