X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felf64-alpha.c;h=8f73212dae660c599e2293ceb48dfd3cf22beb39;hb=6fd1d259e98354236fafd14ec05f3d6a377ede9f;hp=dc23732f7ebd762e89dc69924ce552f9fd532895;hpb=07d6d2b8345ef3dc82eab49635acac9ee67dbb18;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index dc23732f7e..8f73212dae 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -1,5 +1,5 @@ /* Alpha specific support for 64-bit ELF - Copyright (C) 1996-2017 Free Software Foundation, Inc. + Copyright (C) 1996-2020 Free Software Foundation, Inc. Contributed by Richard Henderson . This file is part of BFD, the Binary File Descriptor library. @@ -27,6 +27,7 @@ #include "bfd.h" #include "libbfd.h" #include "elf-bfd.h" +#include "ecoff-bfd.h" #include "elf/alpha.h" @@ -143,14 +144,14 @@ struct alpha_elf_reloc_entry /* Which .reloc section? */ asection *srel; - /* What kind of relocation? */ - unsigned int rtype; - - /* Is this against read-only section? */ - unsigned int reltext : 1; + /* Which section this relocation is against? */ + asection *sec; /* How many did we find? */ unsigned long count; + + /* What kind of relocation? */ + unsigned int rtype; }; struct alpha_elf_link_hash_entry @@ -279,7 +280,7 @@ static struct bfd_link_hash_table * elf64_alpha_bfd_link_hash_table_create (bfd *abfd) { struct alpha_elf_link_hash_table *ret; - bfd_size_type amt = sizeof (struct alpha_elf_link_hash_table); + size_t amt = sizeof (struct alpha_elf_link_hash_table); ret = (struct alpha_elf_link_hash_table *) bfd_zmalloc (amt); if (ret == (struct alpha_elf_link_hash_table *) NULL) @@ -1100,8 +1101,8 @@ elf64_alpha_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, /* Given an Alpha ELF reloc type, fill in an arelent structure. */ -static void -elf64_alpha_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, +static bfd_boolean +elf64_alpha_info_to_howto (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst) { unsigned r_type = ELF64_R_TYPE(dst->r_info); @@ -1109,12 +1110,13 @@ elf64_alpha_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, if (r_type >= R_ALPHA_max) { /* xgettext:c-format */ - _bfd_error_handler (_("%B: unrecognised Alpha reloc number: %d"), + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, r_type); bfd_set_error (bfd_error_bad_value); - r_type = R_ALPHA_NONE; + return FALSE; } cache_ptr->howto = &elf64_alpha_howto_table[r_type]; + return TRUE; } /* These two relocations create a two-word entry in the got. */ @@ -1134,9 +1136,7 @@ elf64_alpha_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, /* Handle an Alpha specific section when reading an object file. This is called when bfd_section_from_shdr finds a section with an unknown - type. - FIXME: We need to handle the SHF_ALPHA_GPREL flag, but I'm not sure - how to. */ + type. */ static bfd_boolean elf64_alpha_section_from_shdr (bfd *abfd, @@ -1167,9 +1167,8 @@ elf64_alpha_section_from_shdr (bfd *abfd, if (hdr->sh_type == SHT_ALPHA_DEBUG) { - if (! bfd_set_section_flags (abfd, newsect, - (bfd_get_section_flags (abfd, newsect) - | SEC_DEBUGGING))) + if (!bfd_set_section_flags (newsect, + bfd_section_flags (newsect) | SEC_DEBUGGING)) return FALSE; } @@ -1179,10 +1178,10 @@ elf64_alpha_section_from_shdr (bfd *abfd, /* Convert Alpha specific section flags to bfd internal section flags. */ static bfd_boolean -elf64_alpha_section_flags (flagword *flags, const Elf_Internal_Shdr *hdr) +elf64_alpha_section_flags (const Elf_Internal_Shdr *hdr) { if (hdr->sh_flags & SHF_ALPHA_GPREL) - *flags |= SEC_SMALL_DATA; + hdr->bfd_section->flags |= SEC_SMALL_DATA; return TRUE; } @@ -1195,7 +1194,7 @@ elf64_alpha_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec) { register const char *name; - name = bfd_get_section_name (abfd, sec); + name = bfd_section_name (sec); if (strcmp (name, ".mdebug") == 0) { @@ -1269,7 +1268,7 @@ elf64_alpha_create_got_section (bfd *abfd, | SEC_LINKER_CREATED); s = bfd_make_section_anyway_with_flags (abfd, ".got", flags); if (s == NULL - || !bfd_set_section_alignment (abfd, s, 3)) + || !bfd_set_section_alignment (s, 3)) return FALSE; alpha_elf_tdata (abfd)->got = s; @@ -1301,7 +1300,7 @@ elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) | (elf64_alpha_use_secureplt ? SEC_READONLY : 0)); s = bfd_make_section_anyway_with_flags (abfd, ".plt", flags); elf_hash_table (info)->splt = s; - if (s == NULL || ! bfd_set_section_alignment (abfd, s, 4)) + if (s == NULL || ! bfd_set_section_alignment (s, 4)) return FALSE; /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the @@ -1316,7 +1315,7 @@ elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) | SEC_LINKER_CREATED | SEC_READONLY); s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt", flags); elf_hash_table (info)->srelplt = s; - if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3)) + if (s == NULL || ! bfd_set_section_alignment (s, 3)) return FALSE; if (elf64_alpha_use_secureplt) @@ -1324,7 +1323,7 @@ elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) flags = SEC_ALLOC | SEC_LINKER_CREATED; s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags); elf_hash_table (info)->sgotplt = s; - if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3)) + if (s == NULL || ! bfd_set_section_alignment (s, 3)) return FALSE; } @@ -1342,7 +1341,7 @@ elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) s = bfd_make_section_anyway_with_flags (abfd, ".rela.got", flags); elf_hash_table (info)->srelgot = s; if (s == NULL - || !bfd_set_section_alignment (abfd, s, 3)) + || !bfd_set_section_alignment (s, 3)) return FALSE; /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the @@ -1386,18 +1385,23 @@ elf64_alpha_read_ecoff_info (bfd *abfd, asection *section, /* The symbolic header contains absolute file offsets and sizes to read. */ #define READ(ptr, offset, count, size, type) \ - if (symhdr->count == 0) \ - debug->ptr = NULL; \ - else \ + do \ { \ - bfd_size_type amt = (bfd_size_type) size * symhdr->count; \ - debug->ptr = (type) bfd_malloc (amt); \ - if (debug->ptr == NULL) \ + size_t amt; \ + debug->ptr = NULL; \ + if (symhdr->count == 0) \ + break; \ + if (_bfd_mul_overflow (size, symhdr->count, &amt)) \ + { \ + bfd_set_error (bfd_error_file_too_big); \ + goto error_return; \ + } \ + if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0) \ goto error_return; \ - if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \ - || bfd_bread (debug->ptr, amt, abfd) != amt) \ + debug->ptr = (type) _bfd_malloc_and_read (abfd, amt, amt); \ + if (debug->ptr == NULL) \ goto error_return; \ - } + } while (0) READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *); READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *); @@ -1466,8 +1470,9 @@ elf64_alpha_find_nearest_line (bfd *abfd, asymbol **symbols, if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset, filename_ptr, functionname_ptr, line_ptr, discriminator_ptr, - dwarf_debug_sections, 0, - &elf_tdata (abfd)->dwarf2_find_line_info)) + dwarf_debug_sections, + &elf_tdata (abfd)->dwarf2_find_line_info) + == 1) return TRUE; msec = bfd_get_section_by_name (abfd, ".mdebug"); @@ -1615,7 +1620,7 @@ elf64_alpha_output_extsym (struct alpha_elf_link_hash_entry *h, void * data) h->esym.asym.sc = scUndefined; else { - name = bfd_section_name (output_section->owner, output_section); + name = bfd_section_name (output_section); if (strcmp (name, ".text") == 0) h->esym.asym.sc = scText; @@ -1722,7 +1727,7 @@ get_got_entry (bfd *abfd, struct alpha_elf_link_hash_entry *h, if (!gotent) { int entry_size; - bfd_size_type amt; + size_t amt; amt = sizeof (struct alpha_elf_got_entry); gotent = (struct alpha_elf_got_entry *) bfd_alloc (abfd, amt); @@ -1785,7 +1790,6 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info, Elf_Internal_Shdr *symtab_hdr; struct alpha_elf_link_hash_entry **sym_hashes; const Elf_Internal_Rela *rel, *relend; - bfd_size_type amt; if (bfd_link_relocatable (info)) return TRUE; @@ -1988,15 +1992,15 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info, if (!rent) { - amt = sizeof (struct alpha_elf_reloc_entry); + size_t amt = sizeof (struct alpha_elf_reloc_entry); rent = (struct alpha_elf_reloc_entry *) bfd_alloc (abfd, amt); if (!rent) return FALSE; rent->srel = sreloc; + rent->sec = sec; rent->rtype = r_type; rent->count = 1; - rent->reltext = (sec->flags & SEC_READONLY) != 0; rent->next = h->reloc_entries; h->reloc_entries = rent; @@ -2010,7 +2014,13 @@ elf64_alpha_check_relocs (bfd *abfd, struct bfd_link_info *info, loaded into memory, we need a RELATIVE reloc. */ sreloc->size += sizeof (Elf64_External_Rela); if (sec->flags & SEC_READONLY) - info->flags |= DF_TEXTREL; + { + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%pB: dynamic relocation against `%pT' in " + "read-only section `%pA'\n"), + sec->owner, h->root.root.root.string, sec); + } } } } @@ -2459,7 +2469,7 @@ elf64_alpha_size_got_sections (struct bfd_link_info *info, /* Yikes! A single object file has too many entries. */ _bfd_error_handler /* xgettext:c-format */ - (_("%B: .got subsegment exceeds 64K (size %d)"), + (_("%pB: .got subsegment exceeds 64K (size %d)"), i, alpha_elf_tdata (this_got)->total_got_size); return FALSE; } @@ -2695,10 +2705,17 @@ elf64_alpha_calc_dynrel_sizes (struct alpha_elf_link_hash_entry *h, bfd_link_pie (info)); if (entries) { + asection *sec = relent->sec; relent->srel->size += entries * sizeof (Elf64_External_Rela) * relent->count; - if (relent->reltext) - info->flags |= DT_TEXTREL; + if ((sec->flags & SEC_READONLY) != 0) + { + info->flags |= DT_TEXTREL; + info->callbacks->minfo + (_("%pB: dynamic relocation against `%pT' in " + "read-only section `%pA'\n"), + sec->owner, h->root.root.root.string, sec); + } } } @@ -2859,7 +2876,7 @@ elf64_alpha_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* It's OK to base decisions on the section name, because none of the dynobj section names depend upon the input files. */ - name = bfd_get_section_name (dynobj, s); + name = bfd_section_name (s); if (CONST_STRNEQ (name, ".rela")) { @@ -3014,8 +3031,9 @@ elf64_alpha_relax_got_load (struct alpha_relax_info *info, bfd_vma symval, reloc_howto_type *howto = elf64_alpha_howto_table + r_type; _bfd_error_handler /* xgettext:c-format */ - (_("%B: %A+%#Lx: warning: %s relocation against unexpected insn"), - info->abfd, info->sec, irel->r_offset, howto->name); + (_("%pB: %pA+%#" PRIx64 ": warning: " + "%s relocation against unexpected insn"), + info->abfd, info->sec, (uint64_t) irel->r_offset, howto->name); return TRUE; } @@ -3209,8 +3227,9 @@ elf64_alpha_relax_with_lituse (struct alpha_relax_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: %A+%#Lx: warning: LITERAL relocation against unexpected insn"), - abfd, info->sec, irel->r_offset); + (_("%pB: %pA+%#" PRIx64 ": warning: " + "%s relocation against unexpected insn"), + abfd, info->sec, (uint64_t) irel->r_offset, "LITERAL"); return TRUE; } @@ -4095,7 +4114,7 @@ elf64_alpha_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: unknown relocation type %d"), + (_("%pB: unsupported relocation type %#x"), input_bfd, (int) r_type); bfd_set_error (bfd_error_bad_value); ret_val = FALSE; @@ -4243,7 +4262,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: unknown relocation type %d"), + (_("%pB: unsupported relocation type %#x"), input_bfd, (int) r_type); bfd_set_error (bfd_error_bad_value); ret_val = FALSE; @@ -4409,7 +4428,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: gp-relative relocation against dynamic symbol %s"), + (_("%pB: gp-relative relocation against dynamic symbol %s"), input_bfd, h->root.root.root.string); ret_val = FALSE; } @@ -4422,7 +4441,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: gp-relative relocation against dynamic symbol %s"), + (_("%pB: gp-relative relocation against dynamic symbol %s"), input_bfd, h->root.root.root.string); ret_val = FALSE; } @@ -4449,7 +4468,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: pc-relative relocation against dynamic symbol %s"), + (_("%pB: pc-relative relocation against dynamic symbol %s"), input_bfd, h->root.root.root.string); ret_val = FALSE; } @@ -4478,7 +4497,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: change in gp: BRSGP %s"), + (_("%pB: change in gp: BRSGP %s"), input_bfd, h->root.root.root.string); ret_val = FALSE; } @@ -4505,11 +4524,11 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (name == NULL) name = _(""); else if (name[0] == 0) - name = bfd_section_name (input_bfd, sec); + name = bfd_section_name (sec); } _bfd_error_handler /* xgettext:c-format */ - (_("%B: !samegp reloc against symbol without .prologue: %s"), + (_("%pB: !samegp reloc against symbol without .prologue: %s"), input_bfd, name); ret_val = FALSE; break; @@ -4567,7 +4586,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: unhandled dynamic relocation against %s"), + (_("%pB: unhandled dynamic relocation against %s"), input_bfd, h->root.root.root.string); ret_val = FALSE; @@ -4593,7 +4612,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: pc-relative relocation against dynamic symbol %s"), + (_("%pB: pc-relative relocation against dynamic symbol %s"), input_bfd, h->root.root.root.string); ret_val = FALSE; } @@ -4602,7 +4621,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: pc-relative relocation against undefined weak symbol %s"), + (_("%pB: pc-relative relocation against undefined weak symbol %s"), input_bfd, h->root.root.root.string); ret_val = FALSE; } @@ -4668,7 +4687,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: dtp-relative relocation against dynamic symbol %s"), + (_("%pB: dtp-relative relocation against dynamic symbol %s"), input_bfd, h->root.root.root.string); ret_val = FALSE; } @@ -4685,7 +4704,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: TLS local exec code cannot be linked into shared objects"), + (_("%pB: TLS local exec code cannot be linked into shared objects"), input_bfd); ret_val = FALSE; } @@ -4693,7 +4712,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: tp-relative relocation against dynamic symbol %s"), + (_("%pB: tp-relative relocation against dynamic symbol %s"), input_bfd, h->root.root.root.string); ret_val = FALSE; } @@ -4721,7 +4740,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL); if (r_type == R_ALPHA_GOTDTPREL) value -= dtp_base; - else if (!bfd_link_pic (info)) + else if (bfd_link_executable (info)) value -= tp_base; else { @@ -4776,7 +4795,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (name == NULL) return FALSE; if (*name == '\0') - name = bfd_section_name (input_bfd, sec); + name = bfd_section_name (sec); } (*info->callbacks->reloc_overflow) (info, (h ? &h->root.root : NULL), name, howto->name, @@ -5495,7 +5514,7 @@ static const struct elf_size_info alpha_elf_size_info = #define elf_backend_size_dynamic_sections \ elf64_alpha_size_dynamic_sections #define elf_backend_omit_section_dynsym \ - ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true) + _bfd_elf_omit_section_dynsym_all #define elf_backend_relocate_section \ elf64_alpha_relocate_section #define elf_backend_finish_dynamic_symbol \ @@ -5519,6 +5538,9 @@ static const struct elf_size_info alpha_elf_size_info = #define elf_backend_special_sections \ elf64_alpha_special_sections +#define elf_backend_strip_zero_sized_dynamic_sections \ + _bfd_elf_strip_zero_sized_dynamic_sections + /* A few constants that determine how the .plt section is set up. */ #define elf_backend_want_got_plt 0 #define elf_backend_plt_readonly 0 @@ -5541,12 +5563,14 @@ static const struct elf_size_info alpha_elf_size_info = "FreeBSD" label in the ELF header. So we put this label on all executables and (for simplicity) also all other object files. */ -static void -elf64_alpha_fbsd_post_process_headers (bfd * abfd, - struct bfd_link_info * link_info ATTRIBUTE_UNUSED) +static bfd_boolean +elf64_alpha_fbsd_init_file_header (bfd *abfd, struct bfd_link_info *info) { Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */ + if (!_bfd_elf_init_file_header (abfd, info)) + return FALSE; + i_ehdrp = elf_elfheader (abfd); /* Put an ABI label supported by FreeBSD >= 4.1. */ @@ -5555,11 +5579,12 @@ elf64_alpha_fbsd_post_process_headers (bfd * abfd, /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */ memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8); #endif + return TRUE; } -#undef elf_backend_post_process_headers -#define elf_backend_post_process_headers \ - elf64_alpha_fbsd_post_process_headers +#undef elf_backend_init_file_header +#define elf_backend_init_file_header \ + elf64_alpha_fbsd_init_file_header #undef elf64_bed #define elf64_bed elf64_alpha_fbsd_bed