aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2007-05-11 03:10:11 +0000
committerAlan Modra <amodra@gmail.com>2007-05-11 03:10:11 +0000
commitece5ef60797fafabe50aae16758ecb33b033871d (patch)
tree89aad076c5b14d568aec538ccf07e4d080b94443 /bfd
parent88b131f3cecc522396bf5c83c09ff76476ad56b9 (diff)
downloadgdb-ece5ef60797fafabe50aae16758ecb33b033871d.zip
gdb-ece5ef60797fafabe50aae16758ecb33b033871d.tar.gz
gdb-ece5ef60797fafabe50aae16758ecb33b033871d.tar.bz2
include/elf/
* spu.h (R_SPU_PPU32, R_SPU_PPU64): Define. bfd/ * reloc.c (BFD_RELOC_SPU_PPU32, BFD_RELOC_SPU_PPU64): Define. * elf-bfd.h (struct elf_backend_data): Change return type of elf_backend_relocate_section to int. * elf32-spu.c (elf_howto_table): Add howtos for R_SPU_PPU32 and R_SPU_PPU64. (spu_elf_bfd_to_reloc_type): Convert new relocs. (spu_elf_count_relocs): New function. (elf_backend_count_relocs): Define. (spu_elf_relocate_section): Arrange to emit R_SPU_PPU32 and R_SPU_PPU64 relocs. * elflink.c (elf_link_input_bfd): Emit relocs if relocate_section returns 2. * bfd-in2.h: Regenerate. * libbfd.h: Regenerate. gas/ * config/tc-spu.c (md_pseudo_table): Add int, long, quad. Call spu_cons for word. (md_assemble): Tidy use of insn.flag. (get_imm): Likewise. Handle uppercase input too. (spu_cons): New function. * config/tc-spu.h (tc_fix_adjustable): Don't adjust SPU_PPU relocs. (TC_FORCE_RELOCATION): Don't resolve them either. binutils/ * embedspu.sh (find_prog): Prefer prog in same dir as embedspu over one found on the users path. (main): Generate .reloc for each R_SPU_PPU* reloc.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog17
-rw-r--r--bfd/bfd-in2.h2
-rw-r--r--bfd/elf-bfd.h7
-rw-r--r--bfd/elf32-spu.c64
-rw-r--r--bfd/elflink.c16
-rw-r--r--bfd/libbfd.h2
-rw-r--r--bfd/reloc.c4
7 files changed, 101 insertions, 11 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b7f09eb..71e7ef7 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,20 @@
+2007-05-11 Alan Modra <amodra@bigpond.net.au>
+
+ * reloc.c (BFD_RELOC_SPU_PPU32, BFD_RELOC_SPU_PPU64): Define.
+ * elf-bfd.h (struct elf_backend_data): Change return type of
+ elf_backend_relocate_section to int.
+ * elf32-spu.c (elf_howto_table): Add howtos for R_SPU_PPU32 and
+ R_SPU_PPU64.
+ (spu_elf_bfd_to_reloc_type): Convert new relocs.
+ (spu_elf_count_relocs): New function.
+ (elf_backend_count_relocs): Define.
+ (spu_elf_relocate_section): Arrange to emit R_SPU_PPU32 and
+ R_SPU_PPU64 relocs.
+ * elflink.c (elf_link_input_bfd): Emit relocs if relocate_section
+ returns 2.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
2007-05-10 Richard Sandiford <richard@codesourcery.com>
* elf32-arm.c (elf32_arm_check_relocs): Don't create PLT entries
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 8154435..e08dddf 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2513,6 +2513,8 @@ relocation types already defined. */
BFD_RELOC_SPU_PCREL16,
BFD_RELOC_SPU_LO16,
BFD_RELOC_SPU_HI16,
+ BFD_RELOC_SPU_PPU32,
+ BFD_RELOC_SPU_PPU64,
/* Alpha ECOFF and ELF relocations. Some of these treat the symbol or
"addend" in some special way.
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index e9ee29b..33ef613 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -792,8 +792,11 @@ struct elf_backend_data
STB_LOCAL/STT_SECTION symbols specially. The output symbol is
going to be the section symbol corresponding to the output
section, which means that the addend must be adjusted
- accordingly. */
- bfd_boolean (*elf_backend_relocate_section)
+ accordingly.
+
+ Returns FALSE on error, TRUE on success, 2 if successful and
+ relocations should be written for this section. */
+ int (*elf_backend_relocate_section)
(bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
asection *input_section, bfd_byte *contents, Elf_Internal_Rela *relocs,
Elf_Internal_Sym *local_syms, asection **local_sections);
diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c
index b6e5fbc..865e1c0 100644
--- a/bfd/elf32-spu.c
+++ b/bfd/elf32-spu.c
@@ -78,6 +78,12 @@ static reloc_howto_type elf_howto_table[] = {
HOWTO (R_SPU_REL32, 0, 2, 32, TRUE, 0, complain_overflow_dont,
bfd_elf_generic_reloc, "SPU_REL32",
FALSE, 0, 0xffffffff, TRUE),
+ HOWTO (R_SPU_PPU32, 0, 2, 32, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "SPU_PPU32",
+ FALSE, 0, 0xffffffff, FALSE),
+ HOWTO (R_SPU_PPU64, 0, 4, 64, FALSE, 0, complain_overflow_dont,
+ bfd_elf_generic_reloc, "SPU_PPU64",
+ FALSE, 0, -1, FALSE),
};
static struct bfd_elf_special_section const spu_elf_special_sections[] = {
@@ -120,6 +126,10 @@ spu_elf_bfd_to_reloc_type (bfd_reloc_code_real_type code)
return R_SPU_ADDR32;
case BFD_RELOC_32_PCREL:
return R_SPU_REL32;
+ case BFD_RELOC_SPU_PPU32:
+ return R_SPU_PPU32;
+ case BFD_RELOC_SPU_PPU64:
+ return R_SPU_PPU64;
}
}
@@ -2627,6 +2637,26 @@ spu_elf_final_link (bfd *output_bfd, struct bfd_link_info *info)
return bfd_elf_final_link (output_bfd, info);
}
+/* Called when not normally emitting relocs, ie. !info->relocatable
+ and !info->emitrelocations. Returns a count of special relocs
+ that need to be emitted. */
+
+static unsigned int
+spu_elf_count_relocs (asection *sec, Elf_Internal_Rela *relocs)
+{
+ unsigned int count = 0;
+ Elf_Internal_Rela *relend = relocs + sec->reloc_count;
+
+ for (; relocs < relend; relocs++)
+ {
+ int r_type = ELF32_R_TYPE (relocs->r_info);
+ if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
+ ++count;
+ }
+
+ return count;
+}
+
/* Apply RELOCS to CONTENTS of INPUT_SECTION from INPUT_BFD. */
static bfd_boolean
@@ -2644,6 +2674,7 @@ spu_elf_relocate_section (bfd *output_bfd,
Elf_Internal_Rela *rel, *relend;
struct spu_link_hash_table *htab;
bfd_boolean ret = TRUE;
+ bfd_boolean emit_these_relocs = FALSE;
htab = spu_hash_table (info);
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
@@ -2669,10 +2700,15 @@ spu_elf_relocate_section (bfd *output_bfd,
r_symndx = ELF32_R_SYM (rel->r_info);
r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
+ {
+ emit_these_relocs = TRUE;
+ continue;
+ }
+
howto = elf_howto_table + r_type;
unresolved_reloc = FALSE;
warned = FALSE;
-
h = NULL;
sym = NULL;
sec = NULL;
@@ -2796,6 +2832,31 @@ spu_elf_relocate_section (bfd *output_bfd,
}
}
+ if (ret
+ && emit_these_relocs
+ && !info->relocatable
+ && !info->emitrelocations)
+ {
+ Elf_Internal_Rela *wrel;
+ Elf_Internal_Shdr *rel_hdr;
+
+ wrel = rel = relocs;
+ relend = relocs + input_section->reloc_count;
+ for (; rel < relend; rel++)
+ {
+ int r_type;
+
+ r_type = ELF32_R_TYPE (rel->r_info);
+ if (r_type == R_SPU_PPU32 || r_type == R_SPU_PPU64)
+ *wrel++ = *rel;
+ }
+ input_section->reloc_count = wrel - relocs;
+ /* Backflips for _bfd_elf_link_output_relocs. */
+ rel_hdr = &elf_section_data (input_section)->rel_hdr;
+ rel_hdr->sh_size = input_section->reloc_count * rel_hdr->sh_entsize;
+ ret = 2;
+ }
+
return ret;
}
@@ -3059,6 +3120,7 @@ spu_elf_modify_program_headers (bfd *abfd, struct bfd_link_info *info)
#define bfd_elf32_bfd_reloc_type_lookup spu_elf_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup spu_elf_reloc_name_lookup
#define elf_info_to_howto spu_elf_info_to_howto
+#define elf_backend_count_relocs spu_elf_count_relocs
#define elf_backend_relocate_section spu_elf_relocate_section
#define elf_backend_symbol_processing spu_elf_backend_symbol_processing
#define elf_backend_link_output_symbol_hook spu_elf_output_symbol_hook
diff --git a/bfd/elflink.c b/bfd/elflink.c
index e64819e..41b518d 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -8198,7 +8198,7 @@ _bfd_elf_check_kept_section (asection *sec, struct bfd_link_info *info)
static bfd_boolean
elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
{
- bfd_boolean (*relocate_section)
+ int (*relocate_section)
(bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
bfd *output_bfd;
@@ -8212,7 +8212,6 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
asection **ppsection;
asection *o;
const struct elf_backend_data *bed;
- bfd_boolean emit_relocs;
struct elf_link_hash_entry **sym_hashes;
output_bfd = finfo->output_bfd;
@@ -8225,9 +8224,6 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
if ((input_bfd->flags & DYNAMIC) != 0)
return TRUE;
- emit_relocs = (finfo->info->relocatable
- || finfo->info->emitrelocations);
-
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
if (elf_bad_symtab (input_bfd))
{
@@ -8443,6 +8439,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
Elf_Internal_Rela *internal_relocs;
bfd_vma r_type_mask;
int r_sym_shift;
+ int ret;
/* Get the swapped relocs. */
internal_relocs
@@ -8580,14 +8577,17 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
corresponding to the output section, which will require
the addend to be adjusted. */
- if (! (*relocate_section) (output_bfd, finfo->info,
+ ret = (*relocate_section) (output_bfd, finfo->info,
input_bfd, o, contents,
internal_relocs,
isymbuf,
- finfo->sections))
+ finfo->sections);
+ if (!ret)
return FALSE;
- if (emit_relocs)
+ if (ret == 2
+ || finfo->info->relocatable
+ || finfo->info->emitrelocations)
{
Elf_Internal_Rela *irela;
Elf_Internal_Rela *irelaend;
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 92bf14a..c9e3df2 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -919,6 +919,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_SPU_PCREL16",
"BFD_RELOC_SPU_LO16",
"BFD_RELOC_SPU_HI16",
+ "BFD_RELOC_SPU_PPU32",
+ "BFD_RELOC_SPU_PPU64",
"BFD_RELOC_ALPHA_GPDISP_HI16",
"BFD_RELOC_ALPHA_GPDISP_LO16",
"BFD_RELOC_ALPHA_GPDISP",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 2a16962..fa9c59d 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -1972,6 +1972,10 @@ ENUMX
BFD_RELOC_SPU_LO16
ENUMX
BFD_RELOC_SPU_HI16
+ENUMX
+ BFD_RELOC_SPU_PPU32
+ENUMX
+ BFD_RELOC_SPU_PPU64
ENUMDOC
SPU Relocations.