mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-24 20:49:43 +00:00
bfd/
* bfd-in.h (bfd_elf32_arm_set_target_relocs): Add prototype. (bfd_elf32_arm_process_before_allocation): Update prototype. * bfd-in2.h: Regenerate. * bfd/elf32-arm.h (elf32_arm_link_hash_table): Add target2_reloc. (elf32_arm_link_hash_table_create): Set it. (bfd_elf32_arm_process_before_allocation): Remove target1_is_rel. (bfd_elf32_arm_set_target_relocs): New function. (arm_real_reloc_type): New function. (elf32_arm_final_link_relocate): Use it. Handle R_ARM_PREL31 and R_ARM_GOT_PREL. Remove R_ARM_TARGET1. (elf32_arm_gc_sweep_hook): Ditto. (elf32_arm_check_relocs): Ditto. (elf32_arm_relocate_section): Handle R_ARM_GOT_PREL. * elfarm-nabi.c (elf32_arm_howto_table): Add R_ARM_PREL31 and R_ARM_GOT_TARGET2. (elf32_arm_got_prel): New variable. (elf32_arm_howto_from_type): New function. (elf32_arm_info_to_howto): Use it. (elf32_arm_reloc_map): Add BFD_RELOC_ARM_PREL31 and BFD_RELOC_ARM_TARGET2. * libbfd.h: Regenerate. * reloc.c: Add BFD_RELOC_ARM_TARGET2 and BFD_RELOC_ARM_PREL31. gas/ * config/tc-arm.c (s_arm_rel31): New funciton. (md_pseudo_table): Add .rel31. (md_apply_fix3): Handle BFD_RELOC_ARM_TARGET2, BFD_RELOC_32_PCREL and BFD_RELOC_ARM_PREL31. (tc_gen_reloc): Handle BFD_RELOC_ARM_PREL31 and BFD_RELOC_ARM_TARGET2. (arm_fix_adjustable): Return 0 for BFD_RELOC_ARM_TARGET2. (arm_parse_reloc): Add (target2). gas/testsuite/ * gas/arm/pic.s: Add (target2). * gas/arm/pic.d: Ditto. include/ * elf/arm.h: Remove R_ARM_STKCHK and R_ARM_THM_STKCHK. Add R_ARM_TARGET2, R_ARM_PREL31, R_ARM_GOT_ABS, R_ARM_GOT_PREL, R_ARM_GOT_BREL12, R_ARM_GOTOFF12 and R_ARM_GOTRELAX. ld/ * ld.texinfo: Rename arm-specific section. Document --target* * emulparams/armelf_fbsd.sh: Set TARGET2_TYPE. * emulparams/armelf_linux.sh: Ditto. * emulparams/armelf_nbsd.sh: Ditto. * emultempl/armelf.em: Set default for TARGET2_TYPE. (target2_type): New variable. (arm_elf_before_allocation): Don't pass target1_type. (arm_elf_create_output_section_statements): New function. (PARSE_AND_LIST_PROLOGUE): Add OPTION_TARGET2. (PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS): Add --target=. (PARSE_AND_LIST_ARGS_CASES): Handle OPTION_TARGET2. (LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS): Set. * emultempl/armelf_oabi.em (_before_allocation): Remove extra argument to bfd_elf32_arm_process_before_allocation. ld/testsuite/ * ld-arm/arm-target1-{abs,rel}.d}: New files. * ld-arm/arm-target1.s: New file. * ld-arm/arm-target2-{,got-}rel.d: New files. * ld-arm/arm-target2.s: New file. * ld-arm/arm-rel31.d: New files. * ld-arm/arm-rel31.s: New files. * ld-arm/arm.ld: New file. * ld-arm/arm-elf.exp: Add new tests.
This commit is contained in:
parent
3674e28ad0
commit
eb043451b1
@ -1,3 +1,28 @@
|
||||
2004-09-17 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* bfd-in.h (bfd_elf32_arm_set_target_relocs): Add prototype.
|
||||
(bfd_elf32_arm_process_before_allocation): Update prototype.
|
||||
* bfd-in2.h: Regenerate.
|
||||
* bfd/elf32-arm.h (elf32_arm_link_hash_table): Add target2_reloc.
|
||||
(elf32_arm_link_hash_table_create): Set it.
|
||||
(bfd_elf32_arm_process_before_allocation): Remove target1_is_rel.
|
||||
(bfd_elf32_arm_set_target_relocs): New function.
|
||||
(arm_real_reloc_type): New function.
|
||||
(elf32_arm_final_link_relocate): Use it. Handle R_ARM_PREL31 and
|
||||
R_ARM_GOT_PREL. Remove R_ARM_TARGET1.
|
||||
(elf32_arm_gc_sweep_hook): Ditto.
|
||||
(elf32_arm_check_relocs): Ditto.
|
||||
(elf32_arm_relocate_section): Handle R_ARM_GOT_PREL.
|
||||
* elfarm-nabi.c (elf32_arm_howto_table): Add R_ARM_PREL31 and
|
||||
R_ARM_GOT_TARGET2.
|
||||
(elf32_arm_got_prel): New variable.
|
||||
(elf32_arm_howto_from_type): New function.
|
||||
(elf32_arm_info_to_howto): Use it.
|
||||
(elf32_arm_reloc_map): Add BFD_RELOC_ARM_PREL31 and
|
||||
BFD_RELOC_ARM_TARGET2.
|
||||
* libbfd.h: Regenerate.
|
||||
* reloc.c: Add BFD_RELOC_ARM_TARGET2 and BFD_RELOC_ARM_PREL31.
|
||||
|
||||
2004-09-17 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* ecoff.c: Update u.undef.next refs.
|
||||
|
@ -814,7 +814,10 @@ extern bfd_boolean bfd_elf32_arm_allocate_interworking_sections
|
||||
(struct bfd_link_info *);
|
||||
|
||||
extern bfd_boolean bfd_elf32_arm_process_before_allocation
|
||||
(bfd *, struct bfd_link_info *, int, int, int);
|
||||
(bfd *, struct bfd_link_info *, int, int);
|
||||
|
||||
void bfd_elf32_arm_set_target_relocs
|
||||
(struct bfd_link_info *, int, char *);
|
||||
|
||||
extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
|
||||
(bfd *, struct bfd_link_info *);
|
||||
|
@ -821,7 +821,10 @@ extern bfd_boolean bfd_elf32_arm_allocate_interworking_sections
|
||||
(struct bfd_link_info *);
|
||||
|
||||
extern bfd_boolean bfd_elf32_arm_process_before_allocation
|
||||
(bfd *, struct bfd_link_info *, int, int, int);
|
||||
(bfd *, struct bfd_link_info *, int, int);
|
||||
|
||||
void bfd_elf32_arm_set_target_relocs
|
||||
(struct bfd_link_info *, int, char *);
|
||||
|
||||
extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
|
||||
(bfd *, struct bfd_link_info *);
|
||||
@ -2649,6 +2652,14 @@ entries in .init_array sections. */
|
||||
/* Data segment base relative address. */
|
||||
BFD_RELOC_ARM_SBREL32,
|
||||
|
||||
/* This reloc is used for References to RTTI dta from exception handling
|
||||
tables. The actual definition depends on the target. It may be a
|
||||
pc-relative or some form of GOT-indirect relocation. */
|
||||
BFD_RELOC_ARM_TARGET2,
|
||||
|
||||
/* 31-bit PC relative address. */
|
||||
BFD_RELOC_ARM_PREL31,
|
||||
|
||||
/* Renesas / SuperH SH relocs. Not all of these appear in object files. */
|
||||
BFD_RELOC_SH_PCDISP8BY2,
|
||||
BFD_RELOC_SH_PCDISP12BY2,
|
||||
|
271
bfd/elf32-arm.h
271
bfd/elf32-arm.h
@ -186,6 +186,9 @@ struct elf32_arm_link_hash_table
|
||||
Nonzero if R_ARM_TARGET1 means R_ARM_ABS32. */
|
||||
int target1_is_rel;
|
||||
|
||||
/* The relocation to use for R_ARM_TARGET2 relocations. */
|
||||
int target2_reloc;
|
||||
|
||||
/* The number of bytes in the initial entry in the PLT. */
|
||||
bfd_size_type plt_header_size;
|
||||
|
||||
@ -378,6 +381,7 @@ elf32_arm_link_hash_table_create (bfd *abfd)
|
||||
ret->no_pipeline_knowledge = 0;
|
||||
ret->byteswap_code = 0;
|
||||
ret->target1_is_rel = 0;
|
||||
ret->target2_reloc = R_ARM_NONE;
|
||||
#ifdef FOUR_WORD_PLT
|
||||
ret->plt_header_size = 16;
|
||||
ret->plt_entry_size = 16;
|
||||
@ -757,8 +761,7 @@ bfd_boolean
|
||||
bfd_elf32_arm_process_before_allocation (bfd *abfd,
|
||||
struct bfd_link_info *link_info,
|
||||
int no_pipeline_knowledge,
|
||||
int byteswap_code,
|
||||
int target1_is_rel)
|
||||
int byteswap_code)
|
||||
{
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
Elf_Internal_Rela *internal_relocs = NULL;
|
||||
@ -781,7 +784,7 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd,
|
||||
BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
|
||||
|
||||
globals->no_pipeline_knowledge = no_pipeline_knowledge;
|
||||
globals->target1_is_rel = target1_is_rel;
|
||||
|
||||
if (byteswap_code && !bfd_big_endian (abfd))
|
||||
{
|
||||
_bfd_error_handler (_("%B: BE8 images only valid in big-endian mode."),
|
||||
@ -906,6 +909,32 @@ error_return:
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef OLD_ARM_ABI
|
||||
/* Set target relocation values needed during linking. */
|
||||
|
||||
void
|
||||
bfd_elf32_arm_set_target_relocs (struct bfd_link_info *link_info,
|
||||
int target1_is_rel,
|
||||
char * target2_type)
|
||||
{
|
||||
struct elf32_arm_link_hash_table *globals;
|
||||
|
||||
globals = elf32_arm_hash_table (link_info);
|
||||
|
||||
globals->target1_is_rel = target1_is_rel;
|
||||
if (strcmp (target2_type, "rel") == 0)
|
||||
globals->target2_reloc = R_ARM_REL32;
|
||||
else if (strcmp (target2_type, "got-rel") == 0)
|
||||
globals->target2_reloc = R_ARM_GOT_PREL;
|
||||
else
|
||||
{
|
||||
_bfd_error_handler (_("Invalid TARGET2 relocation type '%s'."),
|
||||
target2_type);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The thumb form of a long branch is a bit finicky, because the offset
|
||||
encoding is split over two fields, each in it's own instruction. They
|
||||
can occur in any order. So given a thumb form of long branch, and an
|
||||
@ -1151,6 +1180,32 @@ elf32_arm_to_thumb_stub (struct bfd_link_info * info,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#ifndef OLD_ARM_ABI
|
||||
/* Some relocations map to different relocations depending on the
|
||||
target. Return the real relocation. */
|
||||
static int
|
||||
arm_real_reloc_type (struct elf32_arm_link_hash_table * globals,
|
||||
int r_type)
|
||||
{
|
||||
switch (r_type)
|
||||
{
|
||||
case R_ARM_TARGET1:
|
||||
if (globals->target1_is_rel)
|
||||
return R_ARM_REL32;
|
||||
else
|
||||
return R_ARM_ABS32;
|
||||
|
||||
case R_ARM_TARGET2:
|
||||
return globals->target2_reloc;
|
||||
|
||||
default:
|
||||
return r_type;
|
||||
}
|
||||
}
|
||||
#endif /* OLD_ARM_ABI */
|
||||
|
||||
|
||||
/* Perform a relocation as part of a final link. */
|
||||
|
||||
static bfd_reloc_status_type
|
||||
@ -1186,15 +1241,9 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||
#ifndef OLD_ARM_ABI
|
||||
/* Some relocation type map to different relocations depending on the
|
||||
target. We pick the right one here. */
|
||||
if (r_type == R_ARM_TARGET1)
|
||||
{
|
||||
if (globals->target1_is_rel)
|
||||
r_type = R_ARM_REL32;
|
||||
else
|
||||
r_type = R_ARM_ABS32;
|
||||
|
||||
howto = &elf32_arm_howto_table[r_type];
|
||||
}
|
||||
r_type = arm_real_reloc_type (globals, r_type);
|
||||
if (r_type != howto->type)
|
||||
howto = elf32_arm_howto_from_type (r_type);
|
||||
#endif /* OLD_ARM_ABI */
|
||||
|
||||
/* If the start address has been set, then set the EF_ARM_HASENTRY
|
||||
@ -1245,6 +1294,7 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||
case R_ARM_REL32:
|
||||
#ifndef OLD_ARM_ABI
|
||||
case R_ARM_XPC25:
|
||||
case R_ARM_PREL31:
|
||||
#endif
|
||||
case R_ARM_PLT32:
|
||||
/* r_symndx will be zero only for relocs against symbols
|
||||
@ -1257,7 +1307,11 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||
will use the symbol's value, which may point to a PLT entry, but we
|
||||
don't need to handle that here. If we created a PLT entry, all
|
||||
branches in this object should go to it. */
|
||||
if ((r_type != R_ARM_ABS32 && r_type != R_ARM_REL32)
|
||||
if ((r_type != R_ARM_ABS32 && r_type != R_ARM_REL32
|
||||
#ifndef OLD_ARM_ABI
|
||||
&& r_type != R_ARM_PREL31
|
||||
#endif
|
||||
)
|
||||
&& h != NULL
|
||||
&& splt != NULL
|
||||
&& h->plt.offset != (bfd_vma) -1)
|
||||
@ -1279,8 +1333,11 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||
into the output file to be resolved at run time. */
|
||||
if (info->shared
|
||||
&& (input_section->flags & SEC_ALLOC)
|
||||
&& (r_type != R_ARM_REL32
|
||||
|| !SYMBOL_CALLS_LOCAL (info, h))
|
||||
&& ((r_type != R_ARM_REL32
|
||||
#ifndef OLD_ARM_ABI
|
||||
&& r_type != R_ARM_PREL31
|
||||
#endif
|
||||
) || !SYMBOL_CALLS_LOCAL (info, h))
|
||||
&& (h == NULL
|
||||
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
||||
|| h->root.type != bfd_link_hash_undefweak)
|
||||
@ -1480,6 +1537,24 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||
+ input_section->output_offset + rel->r_offset);
|
||||
value += addend;
|
||||
break;
|
||||
|
||||
#ifndef OLD_ARM_ABI
|
||||
case R_ARM_PREL31:
|
||||
value -= (input_section->output_section->vma
|
||||
+ input_section->output_offset + rel->r_offset);
|
||||
value += signed_addend;
|
||||
if (! h || h->root.type != bfd_link_hash_undefweak)
|
||||
{
|
||||
/* Check for overflow */
|
||||
if ((value ^ (value >> 1)) & (1 << 30))
|
||||
return bfd_reloc_overflow;
|
||||
}
|
||||
value &= 0x7fffffff;
|
||||
value |= (bfd_get_32 (input_bfd, hit_data) & 0x80000000);
|
||||
if (sym_flags == STT_ARM_TFUNC)
|
||||
value |= 1;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
bfd_put_32 (input_bfd, value, hit_data);
|
||||
@ -1769,6 +1844,9 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||
(bfd_vma) 0);
|
||||
|
||||
case R_ARM_GOT32:
|
||||
#ifndef OLD_ARM_ABI
|
||||
case R_ARM_GOT_PREL:
|
||||
#endif
|
||||
/* Relocation is to the entry for this symbol in the
|
||||
global offset table. */
|
||||
if (sgot == NULL)
|
||||
@ -1857,6 +1935,8 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
|
||||
|
||||
value = sgot->output_offset + off;
|
||||
}
|
||||
if (r_type != R_ARM_GOT32)
|
||||
value += sgot->output_section->vma;
|
||||
|
||||
return _bfd_final_link_relocate (howto, input_bfd, input_section,
|
||||
contents, rel->r_offset, value,
|
||||
@ -2130,6 +2210,9 @@ elf32_arm_relocate_section (bfd * output_bfd,
|
||||
break;
|
||||
|
||||
case R_ARM_GOT32:
|
||||
#ifndef OLD_ARM_ABI
|
||||
case R_ARM_GOT_PREL:
|
||||
#endif
|
||||
if ((WILL_CALL_FINISH_DYNAMIC_SYMBOL
|
||||
(elf_hash_table (info)->dynamic_sections_created,
|
||||
info->shared, h))
|
||||
@ -2726,6 +2809,9 @@ elf32_arm_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
|
||||
const Elf_Internal_Rela *rel, *relend;
|
||||
unsigned long r_symndx;
|
||||
struct elf_link_hash_entry *h;
|
||||
struct elf32_arm_link_hash_table * globals;
|
||||
|
||||
globals = elf32_arm_hash_table (info);
|
||||
|
||||
elf_section_data (sec)->local_dynrel = NULL;
|
||||
|
||||
@ -2735,66 +2821,77 @@ elf32_arm_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
|
||||
|
||||
relend = relocs + sec->reloc_count;
|
||||
for (rel = relocs; rel < relend; rel++)
|
||||
switch (ELF32_R_TYPE (rel->r_info))
|
||||
{
|
||||
case R_ARM_GOT32:
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
if (r_symndx >= symtab_hdr->sh_info)
|
||||
{
|
||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||
if (h->got.refcount > 0)
|
||||
h->got.refcount -= 1;
|
||||
}
|
||||
else if (local_got_refcounts != NULL)
|
||||
{
|
||||
if (local_got_refcounts[r_symndx] > 0)
|
||||
local_got_refcounts[r_symndx] -= 1;
|
||||
}
|
||||
break;
|
||||
{
|
||||
int r_type;
|
||||
|
||||
case R_ARM_ABS32:
|
||||
case R_ARM_REL32:
|
||||
r_type = ELF32_R_TYPE (rel->r_info);
|
||||
#ifndef OLD_ARM_ABI
|
||||
case R_ARM_TARGET1:
|
||||
r_type = arm_real_reloc_type (globals, r_type);
|
||||
#endif
|
||||
case R_ARM_PC24:
|
||||
case R_ARM_PLT32:
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
if (r_symndx >= symtab_hdr->sh_info)
|
||||
{
|
||||
struct elf32_arm_link_hash_entry *eh;
|
||||
struct elf32_arm_relocs_copied **pp;
|
||||
struct elf32_arm_relocs_copied *p;
|
||||
|
||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||
|
||||
if (h->plt.refcount > 0)
|
||||
h->plt.refcount -= 1;
|
||||
|
||||
if (ELF32_R_TYPE (rel->r_info) == R_ARM_ABS32
|
||||
switch (r_type)
|
||||
{
|
||||
case R_ARM_GOT32:
|
||||
#ifndef OLD_ARM_ABI
|
||||
|| ELF32_R_TYPE (rel->r_info) == R_ARM_TARGET1
|
||||
case R_ARM_GOT_PREL:
|
||||
#endif
|
||||
|| ELF32_R_TYPE (rel->r_info) == R_ARM_REL32)
|
||||
{
|
||||
eh = (struct elf32_arm_link_hash_entry *) h;
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
if (r_symndx >= symtab_hdr->sh_info)
|
||||
{
|
||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||
if (h->got.refcount > 0)
|
||||
h->got.refcount -= 1;
|
||||
}
|
||||
else if (local_got_refcounts != NULL)
|
||||
{
|
||||
if (local_got_refcounts[r_symndx] > 0)
|
||||
local_got_refcounts[r_symndx] -= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
for (pp = &eh->relocs_copied; (p = *pp) != NULL;
|
||||
pp = &p->next)
|
||||
if (p->section == sec)
|
||||
{
|
||||
p->count -= 1;
|
||||
if (p->count == 0)
|
||||
*pp = p->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case R_ARM_ABS32:
|
||||
case R_ARM_REL32:
|
||||
case R_ARM_PC24:
|
||||
case R_ARM_PLT32:
|
||||
#ifndef OLD_ARM_ABI
|
||||
case R_ARM_PREL31:
|
||||
#endif
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
if (r_symndx >= symtab_hdr->sh_info)
|
||||
{
|
||||
struct elf32_arm_link_hash_entry *eh;
|
||||
struct elf32_arm_relocs_copied **pp;
|
||||
struct elf32_arm_relocs_copied *p;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||
|
||||
if (h->plt.refcount > 0)
|
||||
h->plt.refcount -= 1;
|
||||
|
||||
if (r_type == R_ARM_ABS32
|
||||
#ifndef OLD_ARM_ABI
|
||||
|| r_type == R_ARM_PREL31
|
||||
#endif
|
||||
|| r_type == R_ARM_REL32)
|
||||
{
|
||||
eh = (struct elf32_arm_link_hash_entry *) h;
|
||||
|
||||
for (pp = &eh->relocs_copied; (p = *pp) != NULL;
|
||||
pp = &p->next)
|
||||
if (p->section == sec)
|
||||
{
|
||||
p->count -= 1;
|
||||
if (p->count == 0)
|
||||
*pp = p->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -2837,16 +2934,24 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
{
|
||||
struct elf_link_hash_entry *h;
|
||||
unsigned long r_symndx;
|
||||
int r_type;
|
||||
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
r_type = ELF32_R_TYPE (rel->r_info);
|
||||
#ifndef OLD_ARM_ABI
|
||||
r_type = arm_real_reloc_type (htab, r_type);
|
||||
#endif
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
h = NULL;
|
||||
else
|
||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||
|
||||
switch (ELF32_R_TYPE (rel->r_info))
|
||||
switch (r_type)
|
||||
{
|
||||
case R_ARM_GOT32:
|
||||
#ifndef OLD_ARM_ABI
|
||||
case R_ARM_GOT_PREL:
|
||||
#endif
|
||||
/* This symbol requires a global offset table entry. */
|
||||
if (h != NULL)
|
||||
{
|
||||
@ -2871,7 +2976,9 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
}
|
||||
local_got_refcounts[r_symndx] += 1;
|
||||
}
|
||||
break;
|
||||
if (r_type == R_ARM_GOT32)
|
||||
break;
|
||||
/* Fall through. */
|
||||
|
||||
case R_ARM_GOTOFF:
|
||||
case R_ARM_GOTPC:
|
||||
@ -2886,11 +2993,11 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
|
||||
case R_ARM_ABS32:
|
||||
case R_ARM_REL32:
|
||||
#ifndef OLD_ARM_ABI
|
||||
case R_ARM_TARGET1:
|
||||
#endif
|
||||
case R_ARM_PC24:
|
||||
case R_ARM_PLT32:
|
||||
#ifndef OLD_ARM_ABI
|
||||
case R_ARM_PREL31:
|
||||
#endif
|
||||
if (h != NULL)
|
||||
{
|
||||
/* If this reloc is in a read-only section, we might
|
||||
@ -2906,8 +3013,8 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
refers to is in a different object. We can't tell for
|
||||
sure yet, because something later might force the
|
||||
symbol local. */
|
||||
if (ELF32_R_TYPE (rel->r_info) == R_ARM_PC24
|
||||
|| ELF32_R_TYPE (rel->r_info) == R_ARM_PLT32)
|
||||
if (r_type == R_ARM_PC24
|
||||
|| r_type == R_ARM_PLT32)
|
||||
h->needs_plt = 1;
|
||||
|
||||
/* If we create a PLT entry, this relocation will reference
|
||||
@ -2929,12 +3036,12 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
relocs_copied field of the hash table entry. */
|
||||
if (info->shared
|
||||
&& (sec->flags & SEC_ALLOC) != 0
|
||||
&& ((ELF32_R_TYPE (rel->r_info) != R_ARM_PC24
|
||||
&& ELF32_R_TYPE (rel->r_info) != R_ARM_PLT32
|
||||
&& ((r_type != R_ARM_PC24
|
||||
&& r_type != R_ARM_PLT32
|
||||
#ifndef OLD_ARM_ABI
|
||||
&& ELF32_R_TYPE (rel->r_info) != R_ARM_TARGET1
|
||||
&& r_type != R_ARM_PREL31
|
||||
#endif
|
||||
&& ELF32_R_TYPE (rel->r_info) != R_ARM_REL32)
|
||||
&& r_type != R_ARM_REL32)
|
||||
|| (h != NULL
|
||||
&& (! info->symbolic
|
||||
|| !h->def_regular))))
|
||||
@ -3017,11 +3124,11 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
p->count = 0;
|
||||
}
|
||||
|
||||
if (ELF32_R_TYPE (rel->r_info) == R_ARM_ABS32
|
||||
if (r_type == R_ARM_ABS32
|
||||
#ifndef OLD_ARM_ABI
|
||||
|| ELF32_R_TYPE (rel->r_info) == R_ARM_TARGET1
|
||||
|| r_type == R_ARM_PREL31
|
||||
#endif
|
||||
|| ELF32_R_TYPE (rel->r_info) == R_ARM_REL32)
|
||||
|| r_type == R_ARM_REL32)
|
||||
p->count += 1;
|
||||
}
|
||||
break;
|
||||
|
@ -636,6 +636,34 @@ static reloc_howto_type elf32_arm_howto_table[] =
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_ARM_TARGET2, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_signed,/* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_TARGET2", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
TRUE), /* pcrel_offset */
|
||||
|
||||
HOWTO (R_ARM_PREL31, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
31, /* bitsize */
|
||||
TRUE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_signed,/* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_PREL31", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0x7fffffff, /* src_mask */
|
||||
0x7fffffff, /* dst_mask */
|
||||
TRUE), /* pcrel_offset */
|
||||
};
|
||||
|
||||
/* GNU extension to record C++ vtable hierarchy */
|
||||
@ -702,44 +730,58 @@ static reloc_howto_type elf32_arm_thm_pc9_howto =
|
||||
0x000000ff, /* dst_mask */
|
||||
TRUE); /* pcrel_offset */
|
||||
|
||||
static void elf32_arm_info_to_howto
|
||||
PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
|
||||
/* Place relative GOT-indirect. */
|
||||
static reloc_howto_type elf32_arm_got_prel =
|
||||
HOWTO (R_ARM_GOT_PREL, /* type */
|
||||
0, /* rightshift */
|
||||
2, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
32, /* bitsize */
|
||||
TRUE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
bfd_elf_generic_reloc, /* special_function */
|
||||
"R_ARM_GOT_PREL", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
TRUE); /* pcrel_offset */
|
||||
|
||||
static reloc_howto_type *
|
||||
elf32_arm_howto_from_type (unsigned int r_type)
|
||||
{
|
||||
if (r_type < NUM_ELEM (elf32_arm_howto_table))
|
||||
return &elf32_arm_howto_table[r_type];
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
case R_ARM_GOT_PREL:
|
||||
return &elf32_arm_got_prel;
|
||||
|
||||
case R_ARM_GNU_VTINHERIT:
|
||||
return &elf32_arm_vtinherit_howto;
|
||||
|
||||
case R_ARM_GNU_VTENTRY:
|
||||
return &elf32_arm_vtentry_howto;
|
||||
|
||||
case R_ARM_THM_PC11:
|
||||
return &elf32_arm_thm_pc11_howto;
|
||||
|
||||
case R_ARM_THM_PC9:
|
||||
return &elf32_arm_thm_pc9_howto;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
|
||||
bfd * abfd ATTRIBUTE_UNUSED;
|
||||
arelent * bfd_reloc;
|
||||
Elf_Internal_Rela * elf_reloc;
|
||||
elf32_arm_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED, arelent * bfd_reloc,
|
||||
Elf_Internal_Rela * elf_reloc)
|
||||
{
|
||||
unsigned int r_type;
|
||||
|
||||
r_type = ELF32_R_TYPE (elf_reloc->r_info);
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
case R_ARM_GNU_VTINHERIT:
|
||||
bfd_reloc->howto = & elf32_arm_vtinherit_howto;
|
||||
break;
|
||||
|
||||
case R_ARM_GNU_VTENTRY:
|
||||
bfd_reloc->howto = & elf32_arm_vtentry_howto;
|
||||
break;
|
||||
|
||||
case R_ARM_THM_PC11:
|
||||
bfd_reloc->howto = & elf32_arm_thm_pc11_howto;
|
||||
break;
|
||||
|
||||
case R_ARM_THM_PC9:
|
||||
bfd_reloc->howto = & elf32_arm_thm_pc9_howto;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (r_type >= NUM_ELEM (elf32_arm_howto_table))
|
||||
bfd_reloc->howto = NULL;
|
||||
else
|
||||
bfd_reloc->howto = & elf32_arm_howto_table[r_type];
|
||||
break;
|
||||
}
|
||||
bfd_reloc->howto = elf32_arm_howto_from_type (r_type);
|
||||
}
|
||||
|
||||
struct elf32_arm_reloc_map
|
||||
@ -748,6 +790,7 @@ struct elf32_arm_reloc_map
|
||||
unsigned char elf_reloc_val;
|
||||
};
|
||||
|
||||
/* All entries in this list must also be present in elf32_arm_howto_table. */
|
||||
static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
|
||||
{
|
||||
{BFD_RELOC_NONE, R_ARM_NONE},
|
||||
@ -771,7 +814,9 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
|
||||
{BFD_RELOC_ARM_PLT32, R_ARM_PLT32},
|
||||
{BFD_RELOC_ARM_TARGET1, R_ARM_TARGET1},
|
||||
{BFD_RELOC_ARM_ROSEGREL32, R_ARM_ROSEGREL32},
|
||||
{BFD_RELOC_ARM_SBREL32, R_ARM_SBREL32}
|
||||
{BFD_RELOC_ARM_SBREL32, R_ARM_SBREL32},
|
||||
{BFD_RELOC_ARM_PREL31, R_ARM_PREL31},
|
||||
{BFD_RELOC_ARM_TARGET2, R_ARM_TARGET2}
|
||||
};
|
||||
|
||||
static reloc_howto_type *
|
||||
|
@ -1137,6 +1137,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
||||
"BFD_RELOC_ARM_TARGET1",
|
||||
"BFD_RELOC_ARM_ROSEGREL32",
|
||||
"BFD_RELOC_ARM_SBREL32",
|
||||
"BFD_RELOC_ARM_TARGET2",
|
||||
"BFD_RELOC_ARM_PREL31",
|
||||
"BFD_RELOC_SH_PCDISP8BY2",
|
||||
"BFD_RELOC_SH_PCDISP12BY2",
|
||||
"BFD_RELOC_SH_IMM3",
|
||||
|
10
bfd/reloc.c
10
bfd/reloc.c
@ -2621,6 +2621,16 @@ ENUM
|
||||
BFD_RELOC_ARM_SBREL32
|
||||
ENUMDOC
|
||||
Data segment base relative address.
|
||||
ENUM
|
||||
BFD_RELOC_ARM_TARGET2
|
||||
ENUMDOC
|
||||
This reloc is used for References to RTTI dta from exception handling
|
||||
tables. The actual definition depends on the target. It may be a
|
||||
pc-relative or some form of GOT-indirect relocation.
|
||||
ENUM
|
||||
BFD_RELOC_ARM_PREL31
|
||||
ENUMDOC
|
||||
31-bit PC relative address.
|
||||
|
||||
ENUM
|
||||
BFD_RELOC_SH_PCDISP8BY2
|
||||
|
@ -1,3 +1,13 @@
|
||||
2004-09-17 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* config/tc-arm.c (s_arm_rel31): New funciton.
|
||||
(md_pseudo_table): Add .rel31.
|
||||
(md_apply_fix3): Handle BFD_RELOC_ARM_TARGET2,
|
||||
BFD_RELOC_32_PCREL and BFD_RELOC_ARM_PREL31.
|
||||
(tc_gen_reloc): Handle BFD_RELOC_ARM_PREL31 and BFD_RELOC_ARM_TARGET2.
|
||||
(arm_fix_adjustable): Return 0 for BFD_RELOC_ARM_TARGET2.
|
||||
(arm_parse_reloc): Add (target2).
|
||||
|
||||
2004-09-17 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* Makefile.am: Run "make dep-am".
|
||||
|
@ -2445,6 +2445,7 @@ static void s_thumb_func PARAMS ((int));
|
||||
static void s_thumb_set PARAMS ((int));
|
||||
#ifdef OBJ_ELF
|
||||
static void s_arm_elf_cons PARAMS ((int));
|
||||
static void s_arm_rel31 (int nbytes);
|
||||
#endif
|
||||
|
||||
static int my_get_expression PARAMS ((expressionS *, char **));
|
||||
@ -2468,6 +2469,7 @@ const pseudo_typeS md_pseudo_table[] =
|
||||
#ifdef OBJ_ELF
|
||||
{ "word", s_arm_elf_cons, 4 },
|
||||
{ "long", s_arm_elf_cons, 4 },
|
||||
{ "rel31", s_arm_rel31, 0 },
|
||||
#else
|
||||
{ "word", cons, 4},
|
||||
#endif
|
||||
@ -12481,6 +12483,7 @@ md_apply_fix3 (fixP, valP, seg)
|
||||
#ifdef OBJ_ELF
|
||||
case BFD_RELOC_ARM_GOT32:
|
||||
case BFD_RELOC_ARM_GOTOFF:
|
||||
case BFD_RELOC_ARM_TARGET2:
|
||||
md_number_to_chars (buf, 0, 4);
|
||||
break;
|
||||
#endif
|
||||
@ -12490,6 +12493,7 @@ md_apply_fix3 (fixP, valP, seg)
|
||||
case BFD_RELOC_ARM_TARGET1:
|
||||
case BFD_RELOC_ARM_ROSEGREL32:
|
||||
case BFD_RELOC_ARM_SBREL32:
|
||||
case BFD_RELOC_32_PCREL:
|
||||
if (fixP->fx_done || fixP->fx_pcrel)
|
||||
md_number_to_chars (buf, value, 4);
|
||||
#ifdef OBJ_ELF
|
||||
@ -12502,6 +12506,20 @@ md_apply_fix3 (fixP, valP, seg)
|
||||
break;
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
case BFD_RELOC_ARM_PREL31:
|
||||
if (fixP->fx_done || fixP->fx_pcrel)
|
||||
{
|
||||
newval = md_chars_to_number (buf, 4) & 0x80000000;
|
||||
if ((value ^ (value >> 1)) & 0x40000000)
|
||||
{
|
||||
as_bad_where (fixP->fx_file, fixP->fx_line,
|
||||
_("rel31 relocation overflow"));
|
||||
}
|
||||
newval |= value & 0x7fffffff;
|
||||
md_number_to_chars (buf, newval, 4);
|
||||
}
|
||||
break;
|
||||
|
||||
case BFD_RELOC_ARM_PLT32:
|
||||
/* It appears the instruction is fully prepared at this point. */
|
||||
break;
|
||||
@ -12780,6 +12798,8 @@ tc_gen_reloc (section, fixp)
|
||||
case BFD_RELOC_ARM_TARGET1:
|
||||
case BFD_RELOC_ARM_ROSEGREL32:
|
||||
case BFD_RELOC_ARM_SBREL32:
|
||||
case BFD_RELOC_ARM_PREL31:
|
||||
case BFD_RELOC_ARM_TARGET2:
|
||||
code = fixp->fx_r_type;
|
||||
break;
|
||||
#endif
|
||||
@ -14090,7 +14110,8 @@ arm_fix_adjustable (fixP)
|
||||
/* Don't allow symbols to be discarded on GOT related relocs. */
|
||||
if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
|
||||
|| fixP->fx_r_type == BFD_RELOC_ARM_GOT32
|
||||
|| fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF)
|
||||
|| fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
|
||||
|| fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@ -14151,6 +14172,7 @@ arm_parse_reloc ()
|
||||
MAP ("(plt)", BFD_RELOC_ARM_PLT32),
|
||||
MAP ("(target1)", BFD_RELOC_ARM_TARGET1),
|
||||
MAP ("(sbrel)", BFD_RELOC_ARM_SBREL32),
|
||||
MAP ("(target2)", BFD_RELOC_ARM_TARGET2),
|
||||
{ NULL, 0, BFD_RELOC_UNUSED }
|
||||
#undef MAP
|
||||
};
|
||||
@ -14225,6 +14247,50 @@ s_arm_elf_cons (nbytes)
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
|
||||
/* Parse a .rel31 directive. */
|
||||
|
||||
static void
|
||||
s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
|
||||
{
|
||||
expressionS exp;
|
||||
char *p;
|
||||
valueT highbit;
|
||||
|
||||
SKIP_WHITESPACE ();
|
||||
|
||||
highbit = 0;
|
||||
if (*input_line_pointer == '1')
|
||||
highbit = 0x80000000;
|
||||
else if (*input_line_pointer != '0')
|
||||
as_bad (_("expected 0 or 1"));
|
||||
|
||||
input_line_pointer++;
|
||||
SKIP_WHITESPACE ();
|
||||
if (*input_line_pointer != ',')
|
||||
as_bad (_("missing comma"));
|
||||
input_line_pointer++;
|
||||
|
||||
#ifdef md_flush_pending_output
|
||||
md_flush_pending_output ();
|
||||
#endif
|
||||
|
||||
#ifdef md_cons_align
|
||||
md_cons_align (4);
|
||||
#endif
|
||||
|
||||
mapping_state (MAP_DATA);
|
||||
|
||||
expression (&exp);
|
||||
|
||||
p = frag_more (4);
|
||||
md_number_to_chars (p, highbit, 4);
|
||||
fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
|
||||
BFD_RELOC_ARM_PREL31);
|
||||
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
#endif /* OBJ_ELF */
|
||||
|
||||
/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
|
||||
|
@ -1,3 +1,8 @@
|
||||
2004-09-17 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* gas/arm/pic.s: Add (target2).
|
||||
* gas/arm/pic.d: Ditto.
|
||||
|
||||
2004-09-13 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* gas/arm/pic.d: Rename RELABS to TARGET1.
|
||||
|
@ -17,3 +17,4 @@ Disassembly of section .text:
|
||||
14: R_ARM_GOTPC _GLOBAL_OFFSET_TABLE_
|
||||
18: R_ARM_TARGET1 foo2
|
||||
1c: R_ARM_SBREL32 foo3
|
||||
20: R_ARM_TARGET2 foo4
|
||||
|
@ -11,3 +11,4 @@
|
||||
.word _GLOBAL_OFFSET_TABLE_ - 1b
|
||||
.word foo2(TARGET1)
|
||||
.word foo3(SBREL)
|
||||
.word foo4(TARGET2)
|
||||
|
@ -1,3 +1,9 @@
|
||||
2004-09-17 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* elf/arm.h: Remove R_ARM_STKCHK and R_ARM_THM_STKCHK.
|
||||
Add R_ARM_TARGET2, R_ARM_PREL31, R_ARM_GOT_ABS, R_ARM_GOT_PREL,
|
||||
R_ARM_GOT_BREL12, R_ARM_GOTOFF12 and R_ARM_GOTRELAX.
|
||||
|
||||
2004-09-17 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* bfdlink.h (struct bfd_link_hash_entry): Move und_next into elements
|
||||
|
@ -130,10 +130,15 @@ START_RELOC_NUMBERS (elf_arm_reloc_type)
|
||||
RELOC_NUMBER (R_ARM_TARGET1, 38)
|
||||
RELOC_NUMBER (R_ARM_ROSEGREL32, 39)
|
||||
RELOC_NUMBER (R_ARM_V4BX, 40)
|
||||
RELOC_NUMBER (R_ARM_STKCHK, 41)
|
||||
RELOC_NUMBER (R_ARM_THM_STKCHK, 42)
|
||||
RELOC_NUMBER (R_ARM_TARGET2, 41)
|
||||
RELOC_NUMBER (R_ARM_PREL31, 42)
|
||||
FAKE_RELOC (FIRST_INVALID_RELOC2, 43)
|
||||
FAKE_RELOC (LAST_INVALID_RELOC2, 99)
|
||||
FAKE_RELOC (LAST_INVALID_RELOC2, 94)
|
||||
RELOC_NUMBER (R_ARM_GOT_ABS, 95)
|
||||
RELOC_NUMBER (R_ARM_GOT_PREL, 96)
|
||||
RELOC_NUMBER (R_ARM_GOT_BREL12, 97)
|
||||
RELOC_NUMBER (R_ARM_GOTOFF12, 98)
|
||||
RELOC_NUMBER (R_ARM_GOTRELAX, 99)
|
||||
RELOC_NUMBER (R_ARM_GNU_VTENTRY, 100)
|
||||
RELOC_NUMBER (R_ARM_GNU_VTINHERIT, 101)
|
||||
RELOC_NUMBER (R_ARM_THM_PC11, 102) /* Cygnus extension to abi: Thumb unconditional branch. */
|
||||
|
Loading…
Reference in New Issue
Block a user