summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2004-09-17 12:35:00 +0000
committerPaul Brook <paul@codesourcery.com>2004-09-17 12:35:00 +0000
commit1457945b402ce93b5d36e4a36c7c957aa9d9419e (patch)
tree7b2e01332bdc0bde0488ae010cf04b8143c3e6fe
parentadd5c81f9a2a5a91071965ed009f2a3fabef583f (diff)
downloadbinutils-redhat-1457945b402ce93b5d36e4a36c7c957aa9d9419e.tar.gz
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.
-rw-r--r--bfd/ChangeLog25
-rw-r--r--bfd/bfd-in.h5
-rw-r--r--bfd/bfd-in2.h13
-rw-r--r--bfd/elf32-arm.h265
-rw-r--r--bfd/elfarm-nabi.c95
-rw-r--r--bfd/libbfd.h2
-rw-r--r--bfd/reloc.c10
-rw-r--r--gas/ChangeLog10
-rw-r--r--gas/config/tc-arm.c68
-rw-r--r--gas/testsuite/ChangeLog5
-rw-r--r--gas/testsuite/gas/arm/pic.d1
-rw-r--r--gas/testsuite/gas/arm/pic.s1
-rw-r--r--include/ChangeLog6
-rw-r--r--include/elf/arm.h11
-rw-r--r--ld/ChangeLog17
-rw-r--r--ld/emulparams/armelf_fbsd.sh1
-rw-r--r--ld/emulparams/armelf_linux.sh1
-rw-r--r--ld/emulparams/armelf_nbsd.sh1
-rw-r--r--ld/emultempl/armelf.em25
-rw-r--r--ld/emultempl/armelf_oabi.em2
-rw-r--r--ld/ld.texinfo22
-rw-r--r--ld/testsuite/ChangeLog11
-rw-r--r--ld/testsuite/ld-arm/arm-elf.exp15
-rw-r--r--ld/testsuite/ld-arm/arm-rel31.d5
-rw-r--r--ld/testsuite/ld-arm/arm-rel31.s11
-rw-r--r--ld/testsuite/ld-arm/arm-target1-abs.d5
-rw-r--r--ld/testsuite/ld-arm/arm-target1-rel.d5
-rw-r--r--ld/testsuite/ld-arm/arm-target1.s6
-rw-r--r--ld/testsuite/ld-arm/arm-target2-got-rel.d7
-rw-r--r--ld/testsuite/ld-arm/arm-target2-rel.d5
-rw-r--r--ld/testsuite/ld-arm/arm-target2.s6
-rw-r--r--ld/testsuite/ld-arm/arm.ld16
32 files changed, 562 insertions, 116 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 29eee3d858..85eb10b428 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index da4c9746c2..04dfe69d49 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -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 *);
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 9f4c55aacc..4be38cf7a3 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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,
diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h
index 79e089a76b..27e74d9556 100644
--- a/bfd/elf32-arm.h
+++ b/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;
+ switch (r_type)
+ {
+ case R_ARM_GOT32:
+#ifndef OLD_ARM_ABI
+ case R_ARM_GOT_PREL:
+#endif
+ 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;
+
+ 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;
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
- if (h->plt.refcount > 0)
- h->plt.refcount -= 1;
+ if (h->plt.refcount > 0)
+ h->plt.refcount -= 1;
- 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)
- {
- eh = (struct elf32_arm_link_hash_entry *) h;
+ || 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;
+ 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;
- }
+ 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;
diff --git a/bfd/elfarm-nabi.c b/bfd/elfarm-nabi.c
index aef15d47c5..3eb2cbdf59 100644
--- a/bfd/elfarm-nabi.c
+++ b/bfd/elfarm-nabi.c
@@ -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,52 +730,67 @@ 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 void
-elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
- bfd * abfd ATTRIBUTE_UNUSED;
- arelent * bfd_reloc;
- Elf_Internal_Rela * elf_reloc;
+static reloc_howto_type *
+elf32_arm_howto_from_type (unsigned int r_type)
{
- unsigned int r_type;
-
- r_type = ELF32_R_TYPE (elf_reloc->r_info);
-
+ 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:
- bfd_reloc->howto = & elf32_arm_vtinherit_howto;
- break;
+ return &elf32_arm_vtinherit_howto;
case R_ARM_GNU_VTENTRY:
- bfd_reloc->howto = & elf32_arm_vtentry_howto;
- break;
+ return &elf32_arm_vtentry_howto;
case R_ARM_THM_PC11:
- bfd_reloc->howto = & elf32_arm_thm_pc11_howto;
- break;
+ return &elf32_arm_thm_pc11_howto;
case R_ARM_THM_PC9:
- bfd_reloc->howto = & elf32_arm_thm_pc9_howto;
- break;
+ return &elf32_arm_thm_pc9_howto;
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;
+ return NULL;
}
}
+static void
+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);
+ bfd_reloc->howto = elf32_arm_howto_from_type (r_type);
+}
+
struct elf32_arm_reloc_map
{
bfd_reloc_code_real_type bfd_reloc_val;
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 *
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 4e9a4c2729..abe6a2aca0 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -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",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 1c95d7ec44..8356b6092f 100644
--- a/bfd/reloc.c
+++ b/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
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 2ccb27cf83..2a4f37f9a5 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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".
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index faa628bd28..b0dbff7c95 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -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
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index c2e4663cfb..2d5d2345ed 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -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.
diff --git a/gas/testsuite/gas/arm/pic.d b/gas/testsuite/gas/arm/pic.d
index ff536ad061..2697136570 100644
--- a/gas/testsuite/gas/arm/pic.d
+++ b/gas/testsuite/gas/arm/pic.d
@@ -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
diff --git a/gas/testsuite/gas/arm/pic.s b/gas/testsuite/gas/arm/pic.s
index 7a26750c5b..3c3c3293b6 100644
--- a/gas/testsuite/gas/arm/pic.s
+++ b/gas/testsuite/gas/arm/pic.s
@@ -11,3 +11,4 @@
.word _GLOBAL_OFFSET_TABLE_ - 1b
.word foo2(TARGET1)
.word foo3(SBREL)
+ .word foo4(TARGET2)
diff --git a/include/ChangeLog b/include/ChangeLog
index a1d374e150..b6c11568fb 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -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
diff --git a/include/elf/arm.h b/include/elf/arm.h
index 34bde17e92..05ba3464f0 100644
--- a/include/elf/arm.h
+++ b/include/elf/arm.h
@@ -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. */
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 6caf17bd9c..a267b23e96 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,20 @@
+2004-09-17 Paul Brook <paul@codesourcery.com>
+
+ * 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.
+
2004-09-17 Alan Modra <amodra@bigpond.net.au>
* ldexp.c (fold_name): Update u.undef.next refs.
diff --git a/ld/emulparams/armelf_fbsd.sh b/ld/emulparams/armelf_fbsd.sh
index 52da34557d..ee9520dc4a 100644
--- a/ld/emulparams/armelf_fbsd.sh
+++ b/ld/emulparams/armelf_fbsd.sh
@@ -1,2 +1,3 @@
. ${srcdir}/emulparams/armelf.sh
. ${srcdir}/emulparams/elf_fbsd.sh
+TARGET2_TYPE=got-rel
diff --git a/ld/emulparams/armelf_linux.sh b/ld/emulparams/armelf_linux.sh
index 88a2d19151..60df08120d 100644
--- a/ld/emulparams/armelf_linux.sh
+++ b/ld/emulparams/armelf_linux.sh
@@ -16,6 +16,7 @@ OTHER_BSS_END_SYMBOLS='_bss_end__ = . ; __bss_end__ = . ; __end__ = . ;'
OTHER_SECTIONS='.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }'
TEXT_START_ADDR=0x00008000
+TARGET2_TYPE=got-rel
# ARM does not support .s* sections.
NO_SMALL_DATA=yes
diff --git a/ld/emulparams/armelf_nbsd.sh b/ld/emulparams/armelf_nbsd.sh
index 571483c69b..3d94839153 100644
--- a/ld/emulparams/armelf_nbsd.sh
+++ b/ld/emulparams/armelf_nbsd.sh
@@ -1,6 +1,7 @@
. ${srcdir}/emulparams/armelf.sh
MAXPAGESIZE=0x8000
TEXT_START_ADDR=0x00008000
+TARGET2_TYPE=got-rel
unset STACK_ADDR
unset EMBEDDED
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index 6a690f8bc1..54af832456 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -22,6 +22,7 @@
# This file is sourced from elf32.em, and defines extra arm-elf
# specific routines.
#
+test -z $TARGET2_TYPE && TARGET2_TYPE="rel"
cat >>e${EMULATION_NAME}.c <<EOF
static int no_pipeline_knowledge = 0;
@@ -29,6 +30,7 @@ static char *thumb_entry_symbol = NULL;
static bfd *bfd_for_interwork;
static int byteswap_code = 0;
static int target1_is_rel = 0${TARGET1_IS_REL};
+static char *target2_type = "${TARGET2_TYPE}";
static void
gld${EMULATION_NAME}_before_parse (void)
@@ -121,8 +123,7 @@ arm_elf_before_allocation (void)
{
if (!bfd_elf32_arm_process_before_allocation (is->the_bfd, & link_info,
no_pipeline_knowledge,
- byteswap_code,
- target1_is_rel))
+ byteswap_code))
{
/* xgettext:c-format */
einfo (_("Errors encountered processing file %s"), is->filename);
@@ -182,6 +183,14 @@ arm_elf_finish (void)
thumb_entry_symbol);
}
+/* This is a convenitent point to tell BFD about target specific flags.
+ After the output has been created, but before inputs are read. */
+static void
+arm_elf_create_output_section_statements (void)
+{
+ bfd_elf32_arm_set_target_relocs (&link_info, target1_is_rel, target2_type);
+}
+
EOF
# Define some shell vars to insert bits of code into the standard elf
@@ -192,6 +201,7 @@ PARSE_AND_LIST_PROLOGUE='
#define OPTION_BE8 302
#define OPTION_TARGET1_REL 303
#define OPTION_TARGET1_ABS 304
+#define OPTION_TARGET2 305
'
PARSE_AND_LIST_SHORTOPTS=p
@@ -202,14 +212,16 @@ PARSE_AND_LIST_LONGOPTS='
{ "be8", no_argument, NULL, OPTION_BE8},
{ "target1-rel", no_argument, NULL, OPTION_TARGET1_REL},
{ "target1-abs", no_argument, NULL, OPTION_TARGET1_ABS},
+ { "target2", required_argument, NULL, OPTION_TARGET2},
'
PARSE_AND_LIST_OPTIONS='
fprintf (file, _(" -p --no-pipeline-knowledge Stop the linker knowing about the pipeline length\n"));
fprintf (file, _(" --thumb-entry=<sym> Set the entry point to be Thumb symbol <sym>\n"));
fprintf (file, _(" --be8 Oputput BE8 format image\n"));
- fprintf (file, _(" --target1-rel Interpret R_ARM_TARGET1 as R_ARM_REL32\n"));
- fprintf (file, _(" --target1-abs Interpret R_ARM_TARGET1 as R_ARM_ABS32\n"));
+ fprintf (file, _(" --target1=rel Interpret R_ARM_TARGET1 as R_ARM_REL32\n"));
+ fprintf (file, _(" --target1=abs Interpret R_ARM_TARGET1 as R_ARM_ABS32\n"));
+ fprintf (file, _(" --target2=<type> Specify definition of R_ARM_TARGET2\n"));
'
PARSE_AND_LIST_ARGS_CASES='
@@ -232,12 +244,17 @@ PARSE_AND_LIST_ARGS_CASES='
case OPTION_TARGET1_ABS:
target1_is_rel = 0;
break;
+
+ case OPTION_TARGET2:
+ target2_type = optarg;
+ break;
'
# We have our own after_open and before_allocation functions, but they call
# the standard routines, so give them a different name.
LDEMUL_AFTER_OPEN=arm_elf_after_open
LDEMUL_BEFORE_ALLOCATION=arm_elf_before_allocation
+LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=arm_elf_create_output_section_statements
# Replace the elf before_parse function with our own.
LDEMUL_BEFORE_PARSE=gld"${EMULATION_NAME}"_before_parse
diff --git a/ld/emultempl/armelf_oabi.em b/ld/emultempl/armelf_oabi.em
index 64f908ac16..a9b053bac4 100644
--- a/ld/emultempl/armelf_oabi.em
+++ b/ld/emultempl/armelf_oabi.em
@@ -69,7 +69,7 @@ gld${EMULATION_NAME}_before_allocation (void)
LANG_FOR_EACH_INPUT_STATEMENT (is)
{
if (!bfd_elf32_arm_process_before_allocation (is->the_bfd, &link_info,
- 0, 0, 0))
+ 0, 0))
{
/* xgettext:c-format */
einfo (_("Errors encountered processing file %s"), is->filename);
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 3a64bc2fe2..8acc3c49ad 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -4877,7 +4877,7 @@ point to the function trampoline.
@end ifset
@node ARM
-@section @command{ld}'s Support for Interworking Between ARM and Thumb Code
+@section @command{ld} and the ARM family
@cindex ARM interworking support
@kindex --support-old-code
@@ -4907,6 +4907,26 @@ The @samp{--be8} switch instructs @command{ld} to generate BE8 format
executables. This option is only valid when linking big-endian objects.
The resulting image will contain big-endian data and little-endian code.
+@cindex TARGET1
+@kindex --target1-rel
+@kindex --target1-abs
+The @samp{R_ARM_TARGET1} relocation is typically used for entries in the
+@samp{.init_array} section. It is interpreted as either @samp{R_ARM_REL32}
+or @samp{R_ARM_ABS32}, depending on the target. The @samp{--target1-rel}
+and @samp{--target1-abs} switches override the default.
+
+@cindex TARGET2
+@kindex --target2=@var{type}
+The @samp{--target2=type} switch overrides the default definition of the
+@samp{R_ARM_TARGET2} relocation. Valid values for @samp{type}, their
+meanings, and target defaults are as follows:
+@table @samp
+@item rel
+@samp{R_ARM_REL32} (arm*-*-symbianelf, arm*-*-elf, arm*-*-eabi)
+@item got-rel
+@samp{R_ARM_GOT_PREL} (arm*-*-linux, arm*-*-*bsd)
+@end table
+
@ifclear GENERIC
@lowersections
@end ifclear
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 4772ab5cb4..bc25d1c0a9 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+2004-09-17 Paul Brook <paul@codesourcery.com>
+
+ * 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.
+
2004-09-07 Hans-Peter Nilsson <hp@axis.com>
* ld-cris/hiddef1.d, ld-cris/hiddef1.s, ld-cris/hidrefgotplt1.s:
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index 2f32a11de3..17fb08914c 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -47,6 +47,21 @@ set armelftests {
{"Non-pcrel function reference" "tmpdir/arm-lib.so" "" {arm-app-abs32.s}
{{objdump -fdw arm-app-abs32.d} {objdump -Rw arm-app-abs32.r}}
"arm-app-abs32"}
+ {"target1-abs" "-static --target1-abs -T arm.ld" "" {arm-target1.s}
+ {{objdump -s arm-target1-abs.d}}
+ "arm-target1-abs"}
+ {"target1-rel" "-static --target1-rel -T arm.ld" "" {arm-target1.s}
+ {{objdump -s arm-target1-rel.d}}
+ "arm-target1-rel"}
+ {"target2-rel" "-static --target2=rel -T arm.ld" "" {arm-target2.s}
+ {{objdump -s arm-target2-rel.d}}
+ "arm-target2-rel"}
+ {"target2-got-rel" "-static --target2=got-rel -T arm.ld" "" {arm-target2.s}
+ {{objdump -s arm-target2-got-rel.d}}
+ "arm-target2-got-rel"}
+ {"arm-rel31" "-static -T arm.ld" "" {arm-rel31.s}
+ {{objdump -s arm-rel31.d}}
+ "arm-rel31"}
}
run_ld_link_tests $armelftests
diff --git a/ld/testsuite/ld-arm/arm-rel31.d b/ld/testsuite/ld-arm/arm-rel31.d
new file mode 100644
index 0000000000..1ab683958e
--- /dev/null
+++ b/ld/testsuite/ld-arm/arm-rel31.d
@@ -0,0 +1,5 @@
+
+.*: file format.*
+
+Contents of section .text:
+ 8000 (10000000 fcffff7f 08000080 f4ffffff|00000010 7ffffffc 80000008 fffffff4) .*
diff --git a/ld/testsuite/ld-arm/arm-rel31.s b/ld/testsuite/ld-arm/arm-rel31.s
new file mode 100644
index 0000000000..37eee66c0d
--- /dev/null
+++ b/ld/testsuite/ld-arm/arm-rel31.s
@@ -0,0 +1,11 @@
+# Test the R_ARM_REL31 relocation
+ .section .before
+ .global _start
+_start:
+ .text
+ .rel31 0, foo
+ .rel31 0, _start
+ .rel31 1, foo
+ .rel31 1, _start
+ .section .after
+foo:
diff --git a/ld/testsuite/ld-arm/arm-target1-abs.d b/ld/testsuite/ld-arm/arm-target1-abs.d
new file mode 100644
index 0000000000..81cc9ccdf4
--- /dev/null
+++ b/ld/testsuite/ld-arm/arm-target1-abs.d
@@ -0,0 +1,5 @@
+
+.*: file format.*
+
+Contents of section .text:
+ 8000 (04800000|00008004) .*
diff --git a/ld/testsuite/ld-arm/arm-target1-rel.d b/ld/testsuite/ld-arm/arm-target1-rel.d
new file mode 100644
index 0000000000..2d10deef95
--- /dev/null
+++ b/ld/testsuite/ld-arm/arm-target1-rel.d
@@ -0,0 +1,5 @@
+
+.*: file format .*
+
+Contents of section .text:
+ 8000 (04000000|00000004) .*
diff --git a/ld/testsuite/ld-arm/arm-target1.s b/ld/testsuite/ld-arm/arm-target1.s
new file mode 100644
index 0000000000..5a7ba91459
--- /dev/null
+++ b/ld/testsuite/ld-arm/arm-target1.s
@@ -0,0 +1,6 @@
+# Test the R_ARM_TARGET1 relocation
+ .text
+ .global _start
+_start:
+ .word foo(target1)
+foo:
diff --git a/ld/testsuite/ld-arm/arm-target2-got-rel.d b/ld/testsuite/ld-arm/arm-target2-got-rel.d
new file mode 100644
index 0000000000..089c061aca
--- /dev/null
+++ b/ld/testsuite/ld-arm/arm-target2-got-rel.d
@@ -0,0 +1,7 @@
+
+.*: file format.*
+
+Contents of section .text:
+ 8000 (00100000|00001000) .*
+Contents of section .got:
+ 9000 (04800000|00008004) .*
diff --git a/ld/testsuite/ld-arm/arm-target2-rel.d b/ld/testsuite/ld-arm/arm-target2-rel.d
new file mode 100644
index 0000000000..4913e07240
--- /dev/null
+++ b/ld/testsuite/ld-arm/arm-target2-rel.d
@@ -0,0 +1,5 @@
+
+.*: file format.*
+
+Contents of section .text:
+ 8000 (04000000|00000004) .*
diff --git a/ld/testsuite/ld-arm/arm-target2.s b/ld/testsuite/ld-arm/arm-target2.s
new file mode 100644
index 0000000000..0c343ef6e8
--- /dev/null
+++ b/ld/testsuite/ld-arm/arm-target2.s
@@ -0,0 +1,6 @@
+# Test the R_ARM_TARGET2 relocation
+ .text
+ .global _start
+_start:
+ .word foo(target2)
+foo:
diff --git a/ld/testsuite/ld-arm/arm.ld b/ld/testsuite/ld-arm/arm.ld
new file mode 100644
index 0000000000..23d914b14f
--- /dev/null
+++ b/ld/testsuite/ld-arm/arm.ld
@@ -0,0 +1,16 @@
+/* Script for ld testsuite */
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ PROVIDE (__executable_start = 0x8000); . = 0x8000;
+ .text :
+ {
+ *(.before)
+ *(.text)
+ *(.after)
+ } =0
+ . = 0x9000;
+ .got : { *(.got) *(.got.plt)}
+}