mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 11:39:26 +08:00
Fix seg-fault in the linker introduced by the previous delta.
PR ld/20636 * elf-bfd.h (struct elf_backend_data): Delete elf_backend_count_output_relocs callback and add elf_backend_update_relocs. * elf32-arm.c (elf32_arm_count_output_relocs): Deleted. (emit_relocs): Deleted. (elf32_arm_emit_relocs): Deleted. (elf_backend_emit_relocs): Updated not to use the old functions. (elf32_arm_update_relocs): New function. (elf_backend_update_relocs): New define. * elflink.c (bfd_elf_final_link): Add additional_reloc_count to the relocation count. Call elf_backend_emit_relocs. (_bfd_elf_size_reloc_section): Do not call elf_backend_count_output_relocs. * elfxx-target.h (elf_backend_count_output_relocs): Deleted. (elf_backend_update_relocs): New define.
This commit is contained in:

committed by
Nick Clifton

parent
de7fb42b57
commit
9eaff86138
@ -1,3 +1,22 @@
|
|||||||
|
2016-09-28 Akihiko Odaki <akihiko.odaki.4i@stu.hosei.ac.jp>
|
||||||
|
|
||||||
|
PR ld/20636
|
||||||
|
* elf-bfd.h (struct elf_backend_data): Delete
|
||||||
|
elf_backend_count_output_relocs callback and add
|
||||||
|
elf_backend_update_relocs.
|
||||||
|
* elf32-arm.c (elf32_arm_count_output_relocs): Deleted.
|
||||||
|
(emit_relocs): Deleted.
|
||||||
|
(elf32_arm_emit_relocs): Deleted.
|
||||||
|
(elf_backend_emit_relocs): Updated not to use the old functions.
|
||||||
|
(elf32_arm_update_relocs): New function.
|
||||||
|
(elf_backend_update_relocs): New define.
|
||||||
|
* elflink.c (bfd_elf_final_link): Add additional_reloc_count to the
|
||||||
|
relocation count. Call elf_backend_emit_relocs.
|
||||||
|
(_bfd_elf_size_reloc_section): Do not call
|
||||||
|
elf_backend_count_output_relocs.
|
||||||
|
* elfxx-target.h (elf_backend_count_output_relocs): Deleted.
|
||||||
|
(elf_backend_update_relocs): New define.
|
||||||
|
|
||||||
2016-09-28 Christophe Lyon <christophe.lyon@linaro.org>
|
2016-09-28 Christophe Lyon <christophe.lyon@linaro.org>
|
||||||
|
|
||||||
PR ld/20608
|
PR ld/20608
|
||||||
|
@ -756,6 +756,8 @@ typedef asection * (*elf_gc_mark_hook_fn)
|
|||||||
(asection *, struct bfd_link_info *, Elf_Internal_Rela *,
|
(asection *, struct bfd_link_info *, Elf_Internal_Rela *,
|
||||||
struct elf_link_hash_entry *, Elf_Internal_Sym *);
|
struct elf_link_hash_entry *, Elf_Internal_Sym *);
|
||||||
|
|
||||||
|
struct bfd_elf_section_reloc_data;
|
||||||
|
|
||||||
struct elf_backend_data
|
struct elf_backend_data
|
||||||
{
|
{
|
||||||
/* The architecture for this backend. */
|
/* The architecture for this backend. */
|
||||||
@ -1173,6 +1175,11 @@ struct elf_backend_data
|
|||||||
(bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *,
|
(bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *,
|
||||||
struct elf_link_hash_entry **);
|
struct elf_link_hash_entry **);
|
||||||
|
|
||||||
|
/* Update relocations. It is allowed to change the number and the order.
|
||||||
|
In such a case hashes should be invalidated. */
|
||||||
|
void (*elf_backend_update_relocs)
|
||||||
|
(asection *, struct bfd_elf_section_reloc_data *);
|
||||||
|
|
||||||
/* Count relocations. Not called for relocatable links
|
/* Count relocations. Not called for relocatable links
|
||||||
or if all relocs are being preserved in the output. */
|
or if all relocs are being preserved in the output. */
|
||||||
unsigned int (*elf_backend_count_relocs)
|
unsigned int (*elf_backend_count_relocs)
|
||||||
@ -1183,11 +1190,6 @@ struct elf_backend_data
|
|||||||
unsigned int (*elf_backend_count_additional_relocs)
|
unsigned int (*elf_backend_count_additional_relocs)
|
||||||
(asection *);
|
(asection *);
|
||||||
|
|
||||||
/* Count relocations to be output. The result may be different if the
|
|
||||||
input relocations are expected to be modified by the backend. */
|
|
||||||
unsigned int (* elf_backend_count_output_relocs)
|
|
||||||
(struct bfd_link_info *, asection *, bfd_boolean is_rela);
|
|
||||||
|
|
||||||
/* Say whether to sort relocs output by ld -r and ld --emit-relocs,
|
/* Say whether to sort relocs output by ld -r and ld --emit-relocs,
|
||||||
by r_offset. If NULL, default to true. */
|
by r_offset. If NULL, default to true. */
|
||||||
bfd_boolean (*sort_relocs_p)
|
bfd_boolean (*sort_relocs_p)
|
||||||
@ -1677,13 +1679,13 @@ struct output_elf_obj_tdata
|
|||||||
symbol type or STB_GNU_UNIQUE binding. Used to set the osabi
|
symbol type or STB_GNU_UNIQUE binding. Used to set the osabi
|
||||||
field in the ELF header structure. */
|
field in the ELF header structure. */
|
||||||
enum elf_gnu_symbols
|
enum elf_gnu_symbols
|
||||||
{
|
{
|
||||||
elf_gnu_symbol_none = 0,
|
elf_gnu_symbol_none = 0,
|
||||||
elf_gnu_symbol_any = 1 << 0,
|
elf_gnu_symbol_any = 1 << 0,
|
||||||
elf_gnu_symbol_ifunc = (elf_gnu_symbol_any | 1 << 1),
|
elf_gnu_symbol_ifunc = (elf_gnu_symbol_any | 1 << 1),
|
||||||
elf_gnu_symbol_unique = (elf_gnu_symbol_any | 1 << 2),
|
elf_gnu_symbol_unique = (elf_gnu_symbol_any | 1 << 2),
|
||||||
elf_gnu_symbol_all = (elf_gnu_symbol_ifunc | elf_gnu_symbol_unique)
|
elf_gnu_symbol_all = (elf_gnu_symbol_ifunc | elf_gnu_symbol_unique)
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct elf_section_list
|
typedef struct elf_section_list
|
||||||
{
|
{
|
||||||
@ -1692,7 +1694,6 @@ typedef struct elf_section_list
|
|||||||
struct elf_section_list * next;
|
struct elf_section_list * next;
|
||||||
} elf_section_list;
|
} elf_section_list;
|
||||||
|
|
||||||
|
|
||||||
/* Some private data is stashed away for future use using the tdata pointer
|
/* Some private data is stashed away for future use using the tdata pointer
|
||||||
in the bfd structure. */
|
in the bfd structure. */
|
||||||
|
|
||||||
@ -2157,9 +2158,6 @@ extern bfd_boolean _bfd_elf_link_output_relocs
|
|||||||
(bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *,
|
(bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *,
|
||||||
struct elf_link_hash_entry **);
|
struct elf_link_hash_entry **);
|
||||||
|
|
||||||
extern unsigned int _bfd_elf_default_count_output_relocs
|
|
||||||
(struct bfd_link_info * ATTRIBUTE_UNUSED, asection *, bfd_boolean);
|
|
||||||
|
|
||||||
extern bfd_boolean _bfd_elf_adjust_dynamic_copy
|
extern bfd_boolean _bfd_elf_adjust_dynamic_copy
|
||||||
(struct bfd_link_info *, struct elf_link_hash_entry *, asection *);
|
(struct bfd_link_info *, struct elf_link_hash_entry *, asection *);
|
||||||
|
|
||||||
|
386
bfd/elf32-arm.c
386
bfd/elf32-arm.c
@ -14862,6 +14862,167 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
elf32_arm_update_relocs (asection *o,
|
||||||
|
struct bfd_elf_section_reloc_data *reldata)
|
||||||
|
{
|
||||||
|
void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
|
||||||
|
void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
|
||||||
|
const struct elf_backend_data *bed;
|
||||||
|
_arm_elf_section_data *eado;
|
||||||
|
struct bfd_link_order *p;
|
||||||
|
bfd_byte *erela_head, *erela;
|
||||||
|
Elf_Internal_Rela *irela_head, *irela;
|
||||||
|
Elf_Internal_Shdr *rel_hdr;
|
||||||
|
bfd *abfd;
|
||||||
|
unsigned int count;
|
||||||
|
|
||||||
|
eado = get_arm_elf_section_data (o);
|
||||||
|
|
||||||
|
if (!eado || eado->elf.this_hdr.sh_type != SHT_ARM_EXIDX)
|
||||||
|
return;
|
||||||
|
|
||||||
|
abfd = o->owner;
|
||||||
|
bed = get_elf_backend_data (abfd);
|
||||||
|
rel_hdr = reldata->hdr;
|
||||||
|
|
||||||
|
if (rel_hdr->sh_entsize == bed->s->sizeof_rel)
|
||||||
|
{
|
||||||
|
swap_in = bed->s->swap_reloc_in;
|
||||||
|
swap_out = bed->s->swap_reloc_out;
|
||||||
|
}
|
||||||
|
else if (rel_hdr->sh_entsize == bed->s->sizeof_rela)
|
||||||
|
{
|
||||||
|
swap_in = bed->s->swap_reloca_in;
|
||||||
|
swap_out = bed->s->swap_reloca_out;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
erela_head = rel_hdr->contents;
|
||||||
|
irela_head = (Elf_Internal_Rela *) bfd_zmalloc
|
||||||
|
((NUM_SHDR_ENTRIES (rel_hdr) + 1) * sizeof (*irela_head));
|
||||||
|
|
||||||
|
erela = erela_head;
|
||||||
|
irela = irela_head;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
for (p = o->map_head.link_order; p; p = p->next)
|
||||||
|
{
|
||||||
|
if (p->type == bfd_section_reloc_link_order
|
||||||
|
|| p->type == bfd_symbol_reloc_link_order)
|
||||||
|
{
|
||||||
|
(*swap_in) (abfd, erela, irela);
|
||||||
|
erela += rel_hdr->sh_entsize;
|
||||||
|
irela++;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
else if (p->type == bfd_indirect_link_order)
|
||||||
|
{
|
||||||
|
struct bfd_elf_section_reloc_data *input_reldata;
|
||||||
|
arm_unwind_table_edit *edit_list, *edit_tail;
|
||||||
|
_arm_elf_section_data *eadi;
|
||||||
|
bfd_size_type j;
|
||||||
|
bfd_vma offset;
|
||||||
|
asection *i;
|
||||||
|
|
||||||
|
i = p->u.indirect.section;
|
||||||
|
|
||||||
|
eadi = get_arm_elf_section_data (i);
|
||||||
|
edit_list = eadi->u.exidx.unwind_edit_list;
|
||||||
|
edit_tail = eadi->u.exidx.unwind_edit_tail;
|
||||||
|
offset = o->vma + i->output_offset;
|
||||||
|
|
||||||
|
if (eadi->elf.rel.hdr &&
|
||||||
|
eadi->elf.rel.hdr->sh_entsize == rel_hdr->sh_entsize)
|
||||||
|
input_reldata = &eadi->elf.rel;
|
||||||
|
else if (eadi->elf.rela.hdr &&
|
||||||
|
eadi->elf.rela.hdr->sh_entsize == rel_hdr->sh_entsize)
|
||||||
|
input_reldata = &eadi->elf.rela;
|
||||||
|
else
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
if (edit_list)
|
||||||
|
{
|
||||||
|
for (j = 0; j < NUM_SHDR_ENTRIES (input_reldata->hdr); j++)
|
||||||
|
{
|
||||||
|
arm_unwind_table_edit *edit_node, *edit_next;
|
||||||
|
bfd_vma bias;
|
||||||
|
bfd_vma index;
|
||||||
|
|
||||||
|
(*swap_in) (abfd, erela, irela);
|
||||||
|
index = (irela->r_offset - offset) / 8;
|
||||||
|
|
||||||
|
bias = 0;
|
||||||
|
edit_node = edit_list;
|
||||||
|
for (edit_next = edit_list;
|
||||||
|
edit_next && edit_next->index <= index;
|
||||||
|
edit_next = edit_node->next)
|
||||||
|
{
|
||||||
|
bias++;
|
||||||
|
edit_node = edit_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edit_node->type != DELETE_EXIDX_ENTRY
|
||||||
|
|| edit_node->index != index)
|
||||||
|
{
|
||||||
|
irela->r_offset -= bias * 8;
|
||||||
|
irela++;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
erela += rel_hdr->sh_entsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edit_tail->type == INSERT_EXIDX_CANTUNWIND_AT_END)
|
||||||
|
{
|
||||||
|
/* New relocation entity. */
|
||||||
|
asection *text_sec = edit_tail->linked_section;
|
||||||
|
asection *text_out = text_sec->output_section;
|
||||||
|
bfd_vma exidx_offset = offset + i->size - 8;
|
||||||
|
|
||||||
|
irela->r_addend = 0;
|
||||||
|
irela->r_offset = exidx_offset;
|
||||||
|
irela->r_info = ELF32_R_INFO
|
||||||
|
(text_out->target_index, R_ARM_PREL31);
|
||||||
|
irela++;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (j = 0; j < NUM_SHDR_ENTRIES (input_reldata->hdr); j++)
|
||||||
|
{
|
||||||
|
(*swap_in) (abfd, erela, irela);
|
||||||
|
erela += rel_hdr->sh_entsize;
|
||||||
|
irela++;
|
||||||
|
}
|
||||||
|
|
||||||
|
count += NUM_SHDR_ENTRIES (input_reldata->hdr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reldata->count = count;
|
||||||
|
rel_hdr->sh_size = count * rel_hdr->sh_entsize;
|
||||||
|
|
||||||
|
erela = erela_head;
|
||||||
|
irela = irela_head;
|
||||||
|
while (count > 0)
|
||||||
|
{
|
||||||
|
(*swap_out) (abfd, irela, erela);
|
||||||
|
erela += rel_hdr->sh_entsize;
|
||||||
|
irela++;
|
||||||
|
count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
free (irela_head);
|
||||||
|
|
||||||
|
/* Hashes are no longer valid. */
|
||||||
|
free (reldata->hashes);
|
||||||
|
reldata->hashes = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Unwinding tables are not referenced directly. This pass marks them as
|
/* Unwinding tables are not referenced directly. This pass marks them as
|
||||||
required if the corresponding code section is marked. Similarly, ARMv8-M
|
required if the corresponding code section is marked. Similarly, ARMv8-M
|
||||||
secure entry functions can only be referenced by SG veneers which are
|
secure entry functions can only be referenced by SG veneers which are
|
||||||
@ -17778,7 +17939,6 @@ stm32l4xx_create_replacing_stub_ldmia (struct elf32_arm_link_hash_table * htab,
|
|||||||
create_instruction_branch_absolute
|
create_instruction_branch_absolute
|
||||||
(initial_insn_addr - current_stub_contents));
|
(initial_insn_addr - current_stub_contents));
|
||||||
|
|
||||||
|
|
||||||
/* Fill the remaining of the stub with deterministic contents. */
|
/* Fill the remaining of the stub with deterministic contents. */
|
||||||
current_stub_contents =
|
current_stub_contents =
|
||||||
stm32l4xx_fill_stub_udf (htab, output_bfd,
|
stm32l4xx_fill_stub_udf (htab, output_bfd,
|
||||||
@ -19054,80 +19214,6 @@ elf32_arm_count_additional_relocs (asection *sec)
|
|||||||
return arm_data == NULL ? 0 : arm_data->additional_reloc_count;
|
return arm_data == NULL ? 0 : arm_data->additional_reloc_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int
|
|
||||||
elf32_arm_count_output_relocs (struct bfd_link_info * info,
|
|
||||||
asection * o,
|
|
||||||
bfd_boolean rela)
|
|
||||||
{
|
|
||||||
struct bfd_elf_section_data *esdo;
|
|
||||||
struct bfd_link_order *p;
|
|
||||||
bfd_size_type count;
|
|
||||||
|
|
||||||
esdo = elf_section_data (o->output_section);
|
|
||||||
if (esdo->this_hdr.sh_type != SHT_ARM_EXIDX)
|
|
||||||
return _bfd_elf_default_count_output_relocs (info, o, rela);
|
|
||||||
|
|
||||||
/* PR 20595: Skip relocations for deleted exidx entries. */
|
|
||||||
count = 0;
|
|
||||||
for (p = o->map_head.link_order; p != NULL; p = p->next)
|
|
||||||
{
|
|
||||||
struct _arm_elf_section_data *arm_data;
|
|
||||||
struct bfd_elf_section_data *esd;
|
|
||||||
arm_unwind_table_edit *edit_list;
|
|
||||||
Elf_Internal_Rela *relocs;
|
|
||||||
asection *sec;
|
|
||||||
bfd_size_type num_rel;
|
|
||||||
bfd_size_type num_rela;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (p->type == bfd_section_reloc_link_order
|
|
||||||
|| p->type == bfd_symbol_reloc_link_order)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
sec = p->u.indirect.section;
|
|
||||||
arm_data = get_arm_elf_section_data (sec);
|
|
||||||
esd = &arm_data->elf;
|
|
||||||
|
|
||||||
if (arm_data->additional_reloc_count)
|
|
||||||
count += arm_data->additional_reloc_count;
|
|
||||||
|
|
||||||
edit_list = arm_data->u.exidx.unwind_edit_list;
|
|
||||||
if (!edit_list)
|
|
||||||
{
|
|
||||||
count += sec->reloc_count;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
relocs = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL,
|
|
||||||
info->keep_memory);
|
|
||||||
num_rel = esd->rel.hdr ? NUM_SHDR_ENTRIES (esd->rel.hdr) : 0;
|
|
||||||
num_rela = esd->rela.hdr ? NUM_SHDR_ENTRIES (esd->rela.hdr) : 0;
|
|
||||||
if (rela)
|
|
||||||
relocs += num_rel;
|
|
||||||
|
|
||||||
for (i = 0; i < (rela ? num_rela : num_rel); i++)
|
|
||||||
{
|
|
||||||
arm_unwind_table_edit *edit_node;
|
|
||||||
unsigned int index;
|
|
||||||
|
|
||||||
index = (relocs[i].r_offset - sec->vma) / 8;
|
|
||||||
|
|
||||||
for (edit_node = edit_list;
|
|
||||||
edit_node->next && edit_node->next->index > index;
|
|
||||||
edit_node++);
|
|
||||||
|
|
||||||
if (edit_node->type != DELETE_EXIDX_ENTRY
|
|
||||||
|| edit_node->index != index)
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which
|
/* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which
|
||||||
has a type >= SHT_LOOS. Returns TRUE if these fields were initialised
|
has a type >= SHT_LOOS. Returns TRUE if these fields were initialised
|
||||||
FALSE otherwise. ISECTION is the best guess matching section from the
|
FALSE otherwise. ISECTION is the best guess matching section from the
|
||||||
@ -19256,139 +19342,6 @@ elf32_arm_backend_symbol_processing (bfd *abfd, asymbol *sym)
|
|||||||
sym->flags |= BSF_KEEP;
|
sym->flags |= BSF_KEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bfd_boolean
|
|
||||||
emit_relocs (bfd * output_bfd,
|
|
||||||
asection * input_section,
|
|
||||||
Elf_Internal_Shdr * input_rel_hdr,
|
|
||||||
Elf_Internal_Rela * internal_relocs,
|
|
||||||
struct elf_link_hash_entry ** rel_hash,
|
|
||||||
bfd_boolean (* fallback) (bfd *, asection *,
|
|
||||||
Elf_Internal_Shdr *,
|
|
||||||
Elf_Internal_Rela *,
|
|
||||||
struct elf_link_hash_entry **))
|
|
||||||
{
|
|
||||||
_arm_elf_section_data *arm_data;
|
|
||||||
struct bfd_elf_section_reloc_data *output_reldata;
|
|
||||||
Elf_Internal_Shdr *output_rel_hdr;
|
|
||||||
Elf_Internal_Rela *irela;
|
|
||||||
Elf_Internal_Rela *irelaend;
|
|
||||||
asection *output_section;
|
|
||||||
const struct elf_backend_data *bed;
|
|
||||||
void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
|
|
||||||
struct bfd_elf_section_data *esdo;
|
|
||||||
arm_unwind_table_edit *edit_list, *edit_tail;
|
|
||||||
bfd_byte *erel;
|
|
||||||
bfd_vma offset;
|
|
||||||
|
|
||||||
arm_data = get_arm_elf_section_data (input_section);
|
|
||||||
|
|
||||||
if (!arm_data || arm_data->elf.this_hdr.sh_type != SHT_ARM_EXIDX)
|
|
||||||
goto fallback_label;
|
|
||||||
|
|
||||||
edit_list = arm_data->u.exidx.unwind_edit_list;
|
|
||||||
edit_tail = arm_data->u.exidx.unwind_edit_tail;
|
|
||||||
|
|
||||||
if (!edit_list)
|
|
||||||
goto fallback_label;
|
|
||||||
|
|
||||||
output_section = input_section->output_section;
|
|
||||||
offset = output_section->vma + input_section->output_offset;
|
|
||||||
|
|
||||||
bed = get_elf_backend_data (output_bfd);
|
|
||||||
esdo = elf_section_data (output_section);
|
|
||||||
if (esdo->rel.hdr && esdo->rel.hdr->sh_entsize == input_rel_hdr->sh_entsize)
|
|
||||||
{
|
|
||||||
output_reldata = &esdo->rel;
|
|
||||||
swap_out = bed->s->swap_reloc_out;
|
|
||||||
}
|
|
||||||
else if (esdo->rela.hdr
|
|
||||||
&& esdo->rela.hdr->sh_entsize == input_rel_hdr->sh_entsize)
|
|
||||||
{
|
|
||||||
output_reldata = &esdo->rela;
|
|
||||||
swap_out = bed->s->swap_reloca_out;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
(*_bfd_error_handler)
|
|
||||||
(_("%B: relocation size mismatch in %B section %A"),
|
|
||||||
output_bfd, input_section->owner, input_section);
|
|
||||||
bfd_set_error (bfd_error_wrong_format);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
output_rel_hdr = output_reldata->hdr;
|
|
||||||
erel = output_rel_hdr->contents;
|
|
||||||
erel += output_reldata->count * input_rel_hdr->sh_entsize;
|
|
||||||
|
|
||||||
irela = internal_relocs;
|
|
||||||
irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr)
|
|
||||||
* bed->s->int_rels_per_ext_rel);
|
|
||||||
while (irela < irelaend)
|
|
||||||
{
|
|
||||||
arm_unwind_table_edit *edit_node, *edit_next;
|
|
||||||
Elf_Internal_Rela rel;
|
|
||||||
bfd_vma bias;
|
|
||||||
bfd_vma index;
|
|
||||||
|
|
||||||
index = (irela->r_offset - offset) / 8;
|
|
||||||
|
|
||||||
bias = 0;
|
|
||||||
edit_node = edit_list;
|
|
||||||
for (edit_next = edit_list;
|
|
||||||
edit_next && edit_next->index <= index;
|
|
||||||
edit_next = edit_node->next)
|
|
||||||
{
|
|
||||||
bias++;
|
|
||||||
edit_node = edit_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (edit_node->type != DELETE_EXIDX_ENTRY || edit_node->index != index)
|
|
||||||
{
|
|
||||||
rel.r_offset = irela->r_offset - bias * 8;
|
|
||||||
rel.r_info = irela->r_info;
|
|
||||||
rel.r_addend = irela->r_addend;
|
|
||||||
|
|
||||||
(*swap_out) (output_bfd, &rel, erel);
|
|
||||||
erel += output_rel_hdr->sh_entsize;
|
|
||||||
output_reldata->count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
irela += bed->s->int_rels_per_ext_rel;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (edit_tail->type == INSERT_EXIDX_CANTUNWIND_AT_END)
|
|
||||||
{
|
|
||||||
/* New relocation entity. */
|
|
||||||
asection *text_sec = edit_tail->linked_section;
|
|
||||||
asection *text_out = text_sec->output_section;
|
|
||||||
bfd_vma exidx_offset = offset + input_section->size - 8;
|
|
||||||
Elf_Internal_Rela rel;
|
|
||||||
|
|
||||||
rel.r_addend = 0;
|
|
||||||
rel.r_offset = exidx_offset;
|
|
||||||
rel.r_info = ELF32_R_INFO (text_out->target_index, R_ARM_PREL31);
|
|
||||||
(*swap_out) (output_bfd, &rel, erel);
|
|
||||||
output_reldata->count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
fallback_label:
|
|
||||||
return fallback (output_bfd, input_section, input_rel_hdr,
|
|
||||||
internal_relocs, rel_hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bfd_boolean
|
|
||||||
elf32_arm_emit_relocs (bfd * output_bfd,
|
|
||||||
asection * input_section,
|
|
||||||
Elf_Internal_Shdr * input_rel_hdr,
|
|
||||||
Elf_Internal_Rela * internal_relocs,
|
|
||||||
struct elf_link_hash_entry ** rel_hash)
|
|
||||||
{
|
|
||||||
return emit_relocs (output_bfd, input_section, input_rel_hdr, internal_relocs,
|
|
||||||
rel_hash, _bfd_elf_link_output_relocs);
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef elf_backend_copy_special_section_fields
|
#undef elf_backend_copy_special_section_fields
|
||||||
#define elf_backend_copy_special_section_fields elf32_arm_copy_special_section_fields
|
#define elf_backend_copy_special_section_fields elf32_arm_copy_special_section_fields
|
||||||
|
|
||||||
@ -19419,12 +19372,12 @@ elf32_arm_emit_relocs (bfd * output_bfd,
|
|||||||
#define bfd_elf32_bfd_final_link elf32_arm_final_link
|
#define bfd_elf32_bfd_final_link elf32_arm_final_link
|
||||||
#define bfd_elf32_get_synthetic_symtab elf32_arm_get_synthetic_symtab
|
#define bfd_elf32_get_synthetic_symtab elf32_arm_get_synthetic_symtab
|
||||||
|
|
||||||
#define elf_backend_emit_relocs elf32_arm_emit_relocs
|
|
||||||
#define elf_backend_get_symbol_type elf32_arm_get_symbol_type
|
#define elf_backend_get_symbol_type elf32_arm_get_symbol_type
|
||||||
#define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook
|
#define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook
|
||||||
#define elf_backend_gc_mark_extra_sections elf32_arm_gc_mark_extra_sections
|
#define elf_backend_gc_mark_extra_sections elf32_arm_gc_mark_extra_sections
|
||||||
#define elf_backend_gc_sweep_hook elf32_arm_gc_sweep_hook
|
#define elf_backend_gc_sweep_hook elf32_arm_gc_sweep_hook
|
||||||
#define elf_backend_check_relocs elf32_arm_check_relocs
|
#define elf_backend_check_relocs elf32_arm_check_relocs
|
||||||
|
#define elf_backend_update_relocs elf32_arm_update_relocs
|
||||||
#define elf_backend_relocate_section elf32_arm_relocate_section
|
#define elf_backend_relocate_section elf32_arm_relocate_section
|
||||||
#define elf_backend_write_section elf32_arm_write_section
|
#define elf_backend_write_section elf32_arm_write_section
|
||||||
#define elf_backend_adjust_dynamic_symbol elf32_arm_adjust_dynamic_symbol
|
#define elf_backend_adjust_dynamic_symbol elf32_arm_adjust_dynamic_symbol
|
||||||
@ -19449,7 +19402,6 @@ elf32_arm_emit_relocs (bfd * output_bfd,
|
|||||||
#define elf_backend_begin_write_processing elf32_arm_begin_write_processing
|
#define elf_backend_begin_write_processing elf32_arm_begin_write_processing
|
||||||
#define elf_backend_add_symbol_hook elf32_arm_add_symbol_hook
|
#define elf_backend_add_symbol_hook elf32_arm_add_symbol_hook
|
||||||
#define elf_backend_count_additional_relocs elf32_arm_count_additional_relocs
|
#define elf_backend_count_additional_relocs elf32_arm_count_additional_relocs
|
||||||
#define elf_backend_count_output_relocs elf32_arm_count_output_relocs
|
|
||||||
#define elf_backend_symbol_processing elf32_arm_backend_symbol_processing
|
#define elf_backend_symbol_processing elf32_arm_backend_symbol_processing
|
||||||
|
|
||||||
#define elf_backend_can_refcount 1
|
#define elf_backend_can_refcount 1
|
||||||
@ -19616,17 +19568,6 @@ elf32_arm_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
|
|||||||
elf_vxworks_final_write_processing (abfd, linker);
|
elf_vxworks_final_write_processing (abfd, linker);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bfd_boolean
|
|
||||||
elf32_arm_vxworks_emit_relocs (bfd * output_bfd,
|
|
||||||
asection * input_section,
|
|
||||||
Elf_Internal_Shdr * input_rel_hdr,
|
|
||||||
Elf_Internal_Rela * internal_relocs,
|
|
||||||
struct elf_link_hash_entry ** rel_hash)
|
|
||||||
{
|
|
||||||
return emit_relocs (output_bfd, input_section, input_rel_hdr, internal_relocs,
|
|
||||||
rel_hash, elf_vxworks_emit_relocs);
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef elf32_bed
|
#undef elf32_bed
|
||||||
#define elf32_bed elf32_arm_vxworks_bed
|
#define elf32_bed elf32_arm_vxworks_bed
|
||||||
|
|
||||||
@ -19635,7 +19576,7 @@ elf32_arm_vxworks_emit_relocs (bfd * output_bfd,
|
|||||||
#undef elf_backend_final_write_processing
|
#undef elf_backend_final_write_processing
|
||||||
#define elf_backend_final_write_processing elf32_arm_vxworks_final_write_processing
|
#define elf_backend_final_write_processing elf32_arm_vxworks_final_write_processing
|
||||||
#undef elf_backend_emit_relocs
|
#undef elf_backend_emit_relocs
|
||||||
#define elf_backend_emit_relocs elf32_arm_vxworks_emit_relocs
|
#define elf_backend_emit_relocs elf_vxworks_emit_relocs
|
||||||
|
|
||||||
#undef elf_backend_may_use_rel_p
|
#undef elf_backend_may_use_rel_p
|
||||||
#define elf_backend_may_use_rel_p 0
|
#define elf_backend_may_use_rel_p 0
|
||||||
@ -19999,7 +19940,6 @@ elf32_arm_symbian_plt_sym_val (bfd_vma i, const asection *plt,
|
|||||||
(SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED)
|
(SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED)
|
||||||
|
|
||||||
#undef elf_backend_emit_relocs
|
#undef elf_backend_emit_relocs
|
||||||
#define elf_backend_emit_relocs elf32_arm_emit_relocs
|
|
||||||
|
|
||||||
#undef bfd_elf32_bfd_link_hash_table_create
|
#undef bfd_elf32_bfd_link_hash_table_create
|
||||||
#define bfd_elf32_bfd_link_hash_table_create elf32_arm_symbian_link_hash_table_create
|
#define bfd_elf32_bfd_link_hash_table_create elf32_arm_symbian_link_hash_table_create
|
||||||
|
@ -2449,23 +2449,13 @@ _bfd_elf_link_read_relocs (bfd *abfd,
|
|||||||
section header for a section containing relocations for O. */
|
section header for a section containing relocations for O. */
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
_bfd_elf_link_size_reloc_section (bfd *abfd, struct bfd_link_info *info,
|
_bfd_elf_link_size_reloc_section (bfd *abfd,
|
||||||
asection *o, bfd_boolean rela)
|
struct bfd_elf_section_reloc_data *reldata)
|
||||||
{
|
{
|
||||||
struct bfd_elf_section_data *esdo;
|
Elf_Internal_Shdr *rel_hdr = reldata->hdr;
|
||||||
const struct elf_backend_data *bed;
|
|
||||||
struct bfd_elf_section_reloc_data *reldata;
|
|
||||||
Elf_Internal_Shdr *rel_hdr;
|
|
||||||
unsigned int count;
|
|
||||||
|
|
||||||
esdo = elf_section_data (o);
|
|
||||||
reldata = rela ? &esdo->rela : &esdo->rel;
|
|
||||||
rel_hdr = reldata->hdr;
|
|
||||||
|
|
||||||
/* That allows us to calculate the size of the section. */
|
/* That allows us to calculate the size of the section. */
|
||||||
bed = get_elf_backend_data (abfd);
|
rel_hdr->sh_size = rel_hdr->sh_entsize * reldata->count;
|
||||||
count = (*bed->elf_backend_count_output_relocs) (info, o, rela);
|
|
||||||
rel_hdr->sh_size = count * rel_hdr->sh_entsize;
|
|
||||||
|
|
||||||
/* The contents field must last into write_object_contents, so we
|
/* The contents field must last into write_object_contents, so we
|
||||||
allocate it with bfd_alloc rather than malloc. Also since we
|
allocate it with bfd_alloc rather than malloc. Also since we
|
||||||
@ -2553,20 +2543,6 @@ _bfd_elf_link_output_relocs (bfd *output_bfd,
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
|
||||||
_bfd_elf_default_count_output_relocs (struct bfd_link_info * info ATTRIBUTE_UNUSED,
|
|
||||||
asection * o,
|
|
||||||
bfd_boolean rela)
|
|
||||||
{
|
|
||||||
struct bfd_elf_section_data *esdo;
|
|
||||||
struct bfd_elf_section_reloc_data *reldata;
|
|
||||||
|
|
||||||
esdo = elf_section_data (o);
|
|
||||||
reldata = rela ? &esdo->rela : &esdo->rel;
|
|
||||||
|
|
||||||
return reldata->count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make weak undefined symbols in PIE dynamic. */
|
/* Make weak undefined symbols in PIE dynamic. */
|
||||||
|
|
||||||
@ -8354,6 +8330,7 @@ ext64b_r_offset (const void *p)
|
|||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
elf_link_adjust_relocs (bfd *abfd,
|
elf_link_adjust_relocs (bfd *abfd,
|
||||||
|
asection *sec,
|
||||||
struct bfd_elf_section_reloc_data *reldata,
|
struct bfd_elf_section_reloc_data *reldata,
|
||||||
bfd_boolean sort)
|
bfd_boolean sort)
|
||||||
{
|
{
|
||||||
@ -8412,6 +8389,9 @@ elf_link_adjust_relocs (bfd *abfd,
|
|||||||
(*swap_out) (abfd, irela, erela);
|
(*swap_out) (abfd, irela, erela);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bed->elf_backend_update_relocs)
|
||||||
|
(*bed->elf_backend_update_relocs) (sec, reldata);
|
||||||
|
|
||||||
if (sort && count != 0)
|
if (sort && count != 0)
|
||||||
{
|
{
|
||||||
bfd_vma (*ext_r_off) (const void *);
|
bfd_vma (*ext_r_off) (const void *);
|
||||||
@ -11310,12 +11290,12 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
for (o = abfd->sections; o != NULL; o = o->next)
|
for (o = abfd->sections; o != NULL; o = o->next)
|
||||||
{
|
{
|
||||||
struct bfd_elf_section_data *esdo = elf_section_data (o);
|
struct bfd_elf_section_data *esdo = elf_section_data (o);
|
||||||
unsigned int additional_reloc_count = 0;
|
|
||||||
o->reloc_count = 0;
|
o->reloc_count = 0;
|
||||||
|
|
||||||
for (p = o->map_head.link_order; p != NULL; p = p->next)
|
for (p = o->map_head.link_order; p != NULL; p = p->next)
|
||||||
{
|
{
|
||||||
unsigned int reloc_count = 0;
|
unsigned int reloc_count = 0;
|
||||||
|
unsigned int additional_reloc_count = 0;
|
||||||
struct bfd_elf_section_data *esdi = NULL;
|
struct bfd_elf_section_data *esdi = NULL;
|
||||||
|
|
||||||
if (p->type == bfd_section_reloc_link_order
|
if (p->type == bfd_section_reloc_link_order
|
||||||
@ -11401,14 +11381,21 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
if (reloc_count == 0)
|
if (reloc_count == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
reloc_count += additional_reloc_count;
|
||||||
o->reloc_count += reloc_count;
|
o->reloc_count += reloc_count;
|
||||||
|
|
||||||
if (p->type == bfd_indirect_link_order && emit_relocs)
|
if (p->type == bfd_indirect_link_order && emit_relocs)
|
||||||
{
|
{
|
||||||
if (esdi->rel.hdr)
|
if (esdi->rel.hdr)
|
||||||
|
{
|
||||||
esdo->rel.count += NUM_SHDR_ENTRIES (esdi->rel.hdr);
|
esdo->rel.count += NUM_SHDR_ENTRIES (esdi->rel.hdr);
|
||||||
|
esdo->rel.count += additional_reloc_count;
|
||||||
|
}
|
||||||
if (esdi->rela.hdr)
|
if (esdi->rela.hdr)
|
||||||
|
{
|
||||||
esdo->rela.count += NUM_SHDR_ENTRIES (esdi->rela.hdr);
|
esdo->rela.count += NUM_SHDR_ENTRIES (esdi->rela.hdr);
|
||||||
|
esdo->rela.count += additional_reloc_count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -11419,7 +11406,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o->reloc_count > 0 || additional_reloc_count > 0)
|
if (o->reloc_count > 0)
|
||||||
o->flags |= SEC_RELOC;
|
o->flags |= SEC_RELOC;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -11457,11 +11444,11 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
if ((o->flags & SEC_RELOC) != 0)
|
if ((o->flags & SEC_RELOC) != 0)
|
||||||
{
|
{
|
||||||
if (esdo->rel.hdr
|
if (esdo->rel.hdr
|
||||||
&& !(_bfd_elf_link_size_reloc_section (abfd, info, o, FALSE)))
|
&& !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rel)))
|
||||||
goto error_return;
|
goto error_return;
|
||||||
|
|
||||||
if (esdo->rela.hdr
|
if (esdo->rela.hdr
|
||||||
&& !(_bfd_elf_link_size_reloc_section (abfd, info, o, TRUE)))
|
&& !(_bfd_elf_link_size_reloc_section (abfd, &esdo->rela)))
|
||||||
goto error_return;
|
goto error_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11963,10 +11950,10 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
|
|||||||
|
|
||||||
sort = bed->sort_relocs_p == NULL || (*bed->sort_relocs_p) (o);
|
sort = bed->sort_relocs_p == NULL || (*bed->sort_relocs_p) (o);
|
||||||
if (esdo->rel.hdr != NULL
|
if (esdo->rel.hdr != NULL
|
||||||
&& !elf_link_adjust_relocs (abfd, &esdo->rel, sort))
|
&& !elf_link_adjust_relocs (abfd, o, &esdo->rel, sort))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (esdo->rela.hdr != NULL
|
if (esdo->rela.hdr != NULL
|
||||||
&& !elf_link_adjust_relocs (abfd, &esdo->rela, sort))
|
&& !elf_link_adjust_relocs (abfd, o, &esdo->rela, sort))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Set the reloc_count field to 0 to prevent write_relocs from
|
/* Set the reloc_count field to 0 to prevent write_relocs from
|
||||||
|
@ -548,15 +548,15 @@
|
|||||||
#ifndef elf_backend_emit_relocs
|
#ifndef elf_backend_emit_relocs
|
||||||
#define elf_backend_emit_relocs _bfd_elf_link_output_relocs
|
#define elf_backend_emit_relocs _bfd_elf_link_output_relocs
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef elf_backend_update_relocs
|
||||||
|
#define elf_backend_update_relocs NULL
|
||||||
|
#endif
|
||||||
#ifndef elf_backend_count_relocs
|
#ifndef elf_backend_count_relocs
|
||||||
#define elf_backend_count_relocs NULL
|
#define elf_backend_count_relocs NULL
|
||||||
#endif
|
#endif
|
||||||
#ifndef elf_backend_count_additional_relocs
|
#ifndef elf_backend_count_additional_relocs
|
||||||
#define elf_backend_count_additional_relocs NULL
|
#define elf_backend_count_additional_relocs NULL
|
||||||
#endif
|
#endif
|
||||||
#ifndef elf_backend_count_output_relocs
|
|
||||||
#define elf_backend_count_output_relocs _bfd_elf_default_count_output_relocs
|
|
||||||
#endif
|
|
||||||
#ifndef elf_backend_sort_relocs_p
|
#ifndef elf_backend_sort_relocs_p
|
||||||
#define elf_backend_sort_relocs_p NULL
|
#define elf_backend_sort_relocs_p NULL
|
||||||
#endif
|
#endif
|
||||||
@ -778,9 +778,9 @@ static struct elf_backend_data elfNN_bed =
|
|||||||
elf_backend_get_target_dtag,
|
elf_backend_get_target_dtag,
|
||||||
elf_backend_ignore_undef_symbol,
|
elf_backend_ignore_undef_symbol,
|
||||||
elf_backend_emit_relocs,
|
elf_backend_emit_relocs,
|
||||||
|
elf_backend_update_relocs,
|
||||||
elf_backend_count_relocs,
|
elf_backend_count_relocs,
|
||||||
elf_backend_count_additional_relocs,
|
elf_backend_count_additional_relocs,
|
||||||
elf_backend_count_output_relocs,
|
|
||||||
elf_backend_sort_relocs_p,
|
elf_backend_sort_relocs_p,
|
||||||
elf_backend_grok_prstatus,
|
elf_backend_grok_prstatus,
|
||||||
elf_backend_grok_psinfo,
|
elf_backend_grok_psinfo,
|
||||||
|
Reference in New Issue
Block a user