diff options
author | Michael Meissner <gnu@the-meissners.org> | 1996-01-13 14:40:50 +0000 |
---|---|---|
committer | Michael Meissner <gnu@the-meissners.org> | 1996-01-13 14:40:50 +0000 |
commit | 1c3a295b135875e0c6f9f1e0d4a356d30a326d03 (patch) | |
tree | 045a3df9e8efc108d97ef5a43016e9e49b514653 /bfd/elf32-ppc.c | |
parent | 1aac3d3c1f2e2dc35f5a133273e6e4129b3ab9d4 (diff) | |
download | gdb-1c3a295b135875e0c6f9f1e0d4a356d30a326d03.zip gdb-1c3a295b135875e0c6f9f1e0d4a356d30a326d03.tar.gz gdb-1c3a295b135875e0c6f9f1e0d4a356d30a326d03.tar.bz2 |
Warn about relocations we do not yet support
Diffstat (limited to 'bfd/elf32-ppc.c')
-rw-r--r-- | bfd/elf32-ppc.c | 149 |
1 files changed, 138 insertions, 11 deletions
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 5b3b8ab..9673e1b 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -117,6 +117,9 @@ static boolean ppc_elf_section_from_shdr PARAMS ((bfd *, Elf32_Internal_Shdr *, char *)); +static bfd *ppc_elf_create_dynamic_sections PARAMS ((bfd *abfd, + struct bfd_link_info *info)); + static boolean ppc_elf_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -1176,6 +1179,36 @@ ppc_elf_fake_sections (abfd, shdr, asect) } +/* Create the PowerPC dynamic sections */ + +static bfd * +ppc_elf_create_dynamic_sections (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + struct elf_link_hash_entry *h; + struct elf_backend_data *bed = get_elf_backend_data (abfd); + + /* Create the .got section. */ + if (! _bfd_elf_create_got_section (abfd, info)) + return (bfd *)0; + + /* Also create the .got.neg section where we put negative offsets */ + if (bfd_get_section_by_name (abfd, ".got.neg") == NULL) + { + asection *s = bfd_make_section (abfd, ".got.neg"); + if (s == NULL + || !bfd_set_section_flags (abfd, s, + SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY) + || !bfd_set_section_alignment (abfd, s, 2)) + return (bfd *)0; + } + + elf_hash_table (info)->dynobj = abfd; + return abfd; +} + + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -1261,6 +1294,11 @@ ppc_elf_size_dynamic_sections (output_bfd, info) s = bfd_get_section_by_name (dynobj, ".rela.got"); if (s != NULL) s->_raw_size = 0; + + /* Ditto for .rela.got.neg */ + s = bfd_get_section_by_name (dynobj, ".rela.got.neg"); + if (s != NULL) + s->_raw_size = 0; } /* The check_relocs and adjust_dynamic_symbol entry points have @@ -1317,7 +1355,8 @@ ppc_elf_size_dynamic_sections (output_bfd, info) } } else if (strcmp (name, ".plt") != 0 - && strcmp (name, ".got") != 0) + && strcmp (name, ".got") != 0 + && strcmp (name, ".got.neg") != 0) { /* It's not one of our sections, so don't allocate space. */ continue; @@ -1425,7 +1464,9 @@ ppc_elf_check_relocs (abfd, info, sec, relocs) const Elf_Internal_Rela *rel; const Elf_Internal_Rela *rel_end; asection *sgot; + asection *sgot_neg; asection *srelgot; + asection *srelgot_neg; asection *sreloc; if (info->relocateable) @@ -1469,16 +1510,16 @@ ppc_elf_check_relocs (abfd, info, sec, relocs) if (dynobj == NULL) { - /* Create the .got section. */ - elf_hash_table (info)->dynobj = dynobj = abfd; - if (! _bfd_elf_create_got_section (dynobj, info)) + dynobj = ppc_elf_create_dynamic_sections (abfd, info); + if (!dynobj) return false; } if (sgot == NULL) { sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); + sgot_neg = bfd_get_section_by_name (dynobj, ".got.neg"); + BFD_ASSERT (sgot != NULL && sgot_neg != NULL); } if (srelgot == NULL @@ -1498,6 +1539,21 @@ ppc_elf_check_relocs (abfd, info, sec, relocs) || ! bfd_set_section_alignment (dynobj, srelgot, 2)) return false; } + + srelgot_neg = bfd_get_section_by_name (dynobj, ".rela.got.neg"); + if (srelgot_neg == NULL) + { + srelgot_neg = bfd_make_section (dynobj, ".rela.got.neg"); + if (srelgot == NULL + || ! bfd_set_section_flags (dynobj, srelgot_neg, + (SEC_ALLOC + | SEC_LOAD + | SEC_HAS_CONTENTS + | SEC_IN_MEMORY + | SEC_READONLY)) + || ! bfd_set_section_alignment (dynobj, srelgot, 2)) + return false; + } } if (h != NULL) @@ -2019,10 +2075,9 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, /* Unknown relocation handling */ if ((unsigned)r_type >= (unsigned)R_PPC_max || !ppc_elf_howto_table[(int)r_type]) { - (*_bfd_error_handler) - ("%s: unknown relocation type %d", - bfd_get_filename (input_bfd), - (int)r_type); + (*_bfd_error_handler) ("%s: unknown relocation type %d", + bfd_get_filename (input_bfd), + (int)r_type); bfd_set_error (bfd_error_bad_value); ret = false; @@ -2113,6 +2168,26 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, switch ((int)r_type) { default: + (*_bfd_error_handler) ("%s: unknown relocation type %d", + bfd_get_filename (input_bfd), + (int)r_type); + + bfd_set_error (bfd_error_bad_value); + ret = false; + continue; + + case R_PPC_NONE: /* relocations that need no special processing */ + case R_PPC_ADDR32: + case R_PPC_ADDR24: + case R_PPC_ADDR16: + case R_PPC_ADDR16_LO: + case R_PPC_ADDR16_HI: + case R_PPC_ADDR14: + case R_PPC_REL24: + case R_PPC_REL14: + case R_PPC_UADDR32: + case R_PPC_UADDR16: + case R_PPC_REL32: break; case (int)R_PPC_ADDR14_BRTAKEN: /* branch taken prediction relocations */ @@ -2138,8 +2213,20 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, case (int)R_PPC_GOT16: /* GOT16 relocations */ case (int)R_PPC_GOT16_LO: case (int)R_PPC_GOT16_HI: - case (int)R_PPC_SDAREL16: + case (int)R_PPC_GOT16_HA: +#ifdef DEBUG fprintf (stderr, "GOT relocations in section %s from section %s\n", input_section->name, sec->name); +#endif + if (dynobj == NULL) + { + dynobj = ppc_elf_create_dynamic_sections (output_bfd, info); + if (!dynobj) + { + ret = false; + continue; + } + } + BFD_ASSERT (sec != (asection *)0); if (!sgot) { @@ -2205,7 +2292,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, asection *srelgot; Elf_Internal_Rela outrel; - /* We need to generate a R_SPARC_RELATIVE reloc + /* We need to generate a R_PPC_RELATIVE reloc for the dynamic linker. */ srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); BFD_ASSERT (srelgot != NULL); @@ -2249,6 +2336,46 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, BFD_ASSERT (sec != (asection *)0); addend += ((relocation + addend) & 0x8000) << 1; break; + + case R_PPC_PLTREL24: + case R_PPC_COPY: + case R_PPC_GLOB_DAT: + case R_PPC_JMP_SLOT: + case R_PPC_RELATIVE: + case R_PPC_LOCAL24PC: + case R_PPC_PLT32: + case R_PPC_PLTREL32: + case R_PPC_PLT16_LO: + case R_PPC_PLT16_HI: + case R_PPC_PLT16_HA: + case R_PPC_SDAREL16: + case R_PPC_SECTOFF: + case R_PPC_SECTOFF_LO: + case R_PPC_SECTOFF_HI: + case R_PPC_SECTOFF_HA: + case R_PPC_EMB_NADDR32: + case R_PPC_EMB_NADDR16: + case R_PPC_EMB_NADDR16_LO: + case R_PPC_EMB_NADDR16_HI: + case R_PPC_EMB_NADDR16_HA: + case R_PPC_EMB_SDAI16: + case R_PPC_EMB_SDA2I16: + case R_PPC_EMB_SDA2REL: + case R_PPC_EMB_SDA21: + case R_PPC_EMB_MRKREF: + case R_PPC_EMB_RELSEC16: + case R_PPC_EMB_RELST_LO: + case R_PPC_EMB_RELST_HI: + case R_PPC_EMB_RELST_HA: + case R_PPC_EMB_BIT_FLD: + case R_PPC_EMB_RELSDA: + (*_bfd_error_handler) ("%s: Relocation %s is not yet supported.", + bfd_get_filename (input_bfd), + ppc_elf_howto_table[ (int)r_type ]->name); + + bfd_set_error (bfd_error_bad_value); + ret = false; + continue; } |