diff options
author | Alan Modra <amodra@gmail.com> | 2007-05-11 03:10:11 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2007-05-11 03:10:11 +0000 |
commit | ece5ef60797fafabe50aae16758ecb33b033871d (patch) | |
tree | 89aad076c5b14d568aec538ccf07e4d080b94443 /bfd | |
parent | 88b131f3cecc522396bf5c83c09ff76476ad56b9 (diff) | |
download | gdb-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/ChangeLog | 17 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 2 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 7 | ||||
-rw-r--r-- | bfd/elf32-spu.c | 64 | ||||
-rw-r--r-- | bfd/elflink.c | 16 | ||||
-rw-r--r-- | bfd/libbfd.h | 2 | ||||
-rw-r--r-- | bfd/reloc.c | 4 |
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. |