X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Felf32-hppa.c;h=6d5382dc26de4a0d9300f80dbebc295e410dd5ca;hb=c36876fe5b5bac1c404ab2ca82bfbfb2ed9a2717;hp=3f71159531db9c4eda3d77f3c311138925bd49bb;hpb=4a7e52349807017f9bc09ea25f07924f2ec971b3;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index 3f71159531..6d5382dc26 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -1,5 +1,5 @@ /* BFD back-end for HP PA-RISC ELF files. - Copyright (C) 1990-2017 Free Software Foundation, Inc. + Copyright (C) 1990-2020 Free Software Foundation, Inc. Original code by Center for Software Science @@ -71,34 +71,38 @@ Import stub to call shared library routine from normal object file (single sub-space version) - : addil LR'lt_ptr+ltoff,%dp ; get procedure entry point - : ldw RR'lt_ptr+ltoff(%r1),%r21 + : addil LR'lt_ptr+ltoff,%dp ; get PLT address + : ldo RR'lt_ptr+ltoff(%r1),%r22 ; + : ldw 0(%r22),%r21 ; get procedure entry point : bv %r0(%r21) - : ldw RR'lt_ptr+ltoff+4(%r1),%r19 ; get new dlt value. + : ldw 4(%r22),%r19 ; get new dlt value. Import stub to call shared library routine from shared library (single sub-space version) - : addil LR'ltoff,%r19 ; get procedure entry point - : ldw RR'ltoff(%r1),%r21 + : addil LR'ltoff,%r19 ; get PLT address + : ldo RR'ltoff(%r1),%r22 + : ldw 0(%r22),%r21 ; get procedure entry point : bv %r0(%r21) - : ldw RR'ltoff+4(%r1),%r19 ; get new dlt value. + : ldw 4(%r22),%r19 ; get new dlt value. Import stub to call shared library routine from normal object file (multiple sub-space support) - : addil LR'lt_ptr+ltoff,%dp ; get procedure entry point - : ldw RR'lt_ptr+ltoff(%r1),%r21 - : ldw RR'lt_ptr+ltoff+4(%r1),%r19 ; get new dlt value. - : ldsid (%r21),%r1 + : addil LR'lt_ptr+ltoff,%dp ; get PLT address + : ldo RR'lt_ptr+ltoff(%r1),%r22 ; + : ldw 0(%r22),%r21 ; get procedure entry point + : ldsid (%r21),%r1 ; get target sid + : ldw 4(%r22),%r19 ; get new dlt value. : mtsp %r1,%sr0 : be 0(%sr0,%r21) ; branch to target : stw %rp,-24(%sp) ; save rp Import stub to call shared library routine from shared library (multiple sub-space support) - : addil LR'ltoff,%r19 ; get procedure entry point - : ldw RR'ltoff(%r1),%r21 - : ldw RR'ltoff+4(%r1),%r19 ; get new dlt value. - : ldsid (%r21),%r1 + : addil LR'ltoff,%r19 ; get PLT address + : ldo RR'ltoff(%r1),%r22 + : ldw 0(%r22),%r21 ; get procedure entry point + : ldsid (%r21),%r1 ; get target sid + : ldw 4(%r22),%r19 ; get new dlt value. : mtsp %r1,%sr0 : be 0(%sr0,%r21) ; branch to target : stw %rp,-24(%sp) ; save rp @@ -119,7 +123,7 @@ /* Variable names follow a coding style. Please follow this (Apps Hungarian) style: - Structure/Variable Prefix + Structure/Variable Prefix elf_link_hash_table "etab" elf_link_hash_entry "eh" @@ -132,18 +136,21 @@ bfd_hash_table containing stubs "bstab" elf32_hppa_stub_hash_entry "hsh" - elf32_hppa_dyn_reloc_entry "hdh" - Always remember to use GNU Coding Style. */ #define PLT_ENTRY_SIZE 8 #define GOT_ENTRY_SIZE 4 +#define LONG_BRANCH_STUB_SIZE 8 +#define LONG_BRANCH_SHARED_STUB_SIZE 12 +#define IMPORT_STUB_SIZE 20 +#define IMPORT_SHARED_STUB_SIZE 32 +#define EXPORT_STUB_SIZE 24 #define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1" static const bfd_byte plt_stub[] = { - 0x0e, 0x80, 0x10, 0x96, /* 1: ldw 0(%r20),%r22 */ - 0xea, 0xc0, 0xc0, 0x00, /* bv %r0(%r22) */ + 0x0e, 0x80, 0x10, 0x95, /* 1: ldw 0(%r20),%r21 */ + 0xea, 0xa0, 0xc0, 0x00, /* bv %r0(%r21) */ 0x0e, 0x88, 0x10, 0x95, /* ldw 4(%r20),%r21 */ #define PLT_STUB_ENTRY (3*4) 0xea, 0x9f, 0x1f, 0xdd, /* b,l 1b,%r20 */ @@ -226,22 +233,7 @@ struct elf32_hppa_link_hash_entry /* Used to count relocations for delayed sizing of relocation sections. */ - struct elf32_hppa_dyn_reloc_entry - { - /* Next relocation in the chain. */ - struct elf32_hppa_dyn_reloc_entry *hdh_next; - - /* The input section of the reloc. */ - asection *sec; - - /* Number of relocs copied in this section. */ - bfd_size_type count; - -#if RELATIVE_DYNRELOCS - /* Number of relative relocs copied for the input section. */ - bfd_size_type relative_count; -#endif - } *dyn_relocs; + struct elf_dyn_relocs *dyn_relocs; ENUM_BITFIELD (_tls_type) tls_type : 8; @@ -426,7 +418,7 @@ static struct bfd_link_hash_table * elf32_hppa_link_hash_table_create (bfd *abfd) { struct elf32_hppa_link_hash_table *htab; - bfd_size_type amt = sizeof (*htab); + size_t amt = sizeof (*htab); htab = bfd_zmalloc (amt); if (htab == NULL) @@ -520,6 +512,8 @@ hppa_get_stub_entry (const asection *input_section, more than one stub used to reach say, printf, and we need to distinguish between them. */ id_sec = htab->stub_group[input_section->id].link_sec; + if (id_sec == NULL) + return NULL; if (hh != NULL && hh->hsh_cache != NULL && hh->hsh_cache->hh == hh @@ -591,7 +585,7 @@ hppa_add_stub (const char *stub_name, if (hsh == NULL) { /* xgettext:c-format */ - _bfd_error_handler (_("%B: cannot create stub entry %s"), + _bfd_error_handler (_("%pB: cannot create stub entry %s"), section->owner, stub_name); return NULL; } @@ -629,6 +623,9 @@ hppa_type_of_stub (asection *input_sec, return hppa_stub_import; } + if (destination == (bfd_vma) -1) + return hppa_stub_none; + /* Determine where the call point is. */ location = (input_sec->output_offset + input_sec->output_section->vma @@ -674,6 +671,10 @@ hppa_type_of_stub (asection *input_sec, #define ADDIL_R19 0x2a600000 /* addil LR'XXX,%r19,%r1 */ #define LDW_R1_DP 0x483b0000 /* ldw RR'XXX(%sr0,%r1),%dp */ +#define LDO_R1_R22 0x34360000 /* ldo RR'XXX(%r1),%r22 */ +#define LDW_R22_R21 0x0ec01095 /* ldw 0(%r22),%r21 */ +#define LDW_R22_R19 0x0ec81093 /* ldw 4(%r22),%r19 */ + #define LDSID_R21_R1 0x02a010a1 /* ldsid (%sr0,%r21),%r1 */ #define MTSP_R1 0x00011820 /* mtsp %r1,%sr0 */ #define BE_SR0_R21 0xe2a00000 /* be 0(%sr0,%r21) */ @@ -730,6 +731,15 @@ hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg) switch (hsh->stub_type) { case hppa_stub_long_branch: + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (hsh->target_section->output_section == NULL + && info->non_contiguous_regions) + info->callbacks->einfo (_("%F%P: Could not assign '%pA' to an output " + "section. Retry without " + "--enable-non-contiguous-regions.\n"), + hsh->target_section); + /* Create the long branch. A long branch is formed with "ldil" loading the upper bits of the target address into a register, then branching with "be" which adds in the lower bits. @@ -746,10 +756,19 @@ hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg) insn = hppa_rebuild_insn ((int) BE_SR4_R1, val, 17); bfd_put_32 (stub_bfd, insn, loc + 4); - size = 8; + size = LONG_BRANCH_STUB_SIZE; break; case hppa_stub_long_branch_shared: + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (hsh->target_section->output_section == NULL + && info->non_contiguous_regions) + info->callbacks->einfo (_("%F%P: Could not assign %pA to an output " + "section. Retry without " + "--enable-non-contiguous-regions.\n"), + hsh->target_section); + /* Branches are relative. This is where we are going to. */ sym_value = (hsh->target_value + hsh->target_section->output_offset @@ -768,7 +787,7 @@ hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg) val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_rrsel) >> 2; insn = hppa_rebuild_insn ((int) BE_SR4_R1, val, 17); bfd_put_32 (stub_bfd, insn, loc + 8); - size = 12; + size = LONG_BRANCH_SHARED_STUB_SIZE; break; case hppa_stub_import: @@ -788,45 +807,49 @@ hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg) if (hsh->stub_type == hppa_stub_import_shared) insn = ADDIL_R19; #endif + + /* Load function descriptor address into register %r22. It is + sometimes needed for lazy binding. */ val = hppa_field_adjust (sym_value, 0, e_lrsel), insn = hppa_rebuild_insn ((int) insn, val, 21); bfd_put_32 (stub_bfd, insn, loc); - /* It is critical to use lrsel/rrsel here because we are using - two different offsets (+0 and +4) from sym_value. If we use - lsel/rsel then with unfortunate sym_values we will round - sym_value+4 up to the next 2k block leading to a mis-match - between the lsel and rsel value. */ val = hppa_field_adjust (sym_value, 0, e_rrsel); - insn = hppa_rebuild_insn ((int) LDW_R1_R21, val, 14); + insn = hppa_rebuild_insn ((int) LDO_R1_R22, val, 14); bfd_put_32 (stub_bfd, insn, loc + 4); + bfd_put_32 (stub_bfd, (bfd_vma) LDW_R22_R21, loc + 8); + if (htab->multi_subspace) { - val = hppa_field_adjust (sym_value, (bfd_signed_vma) 4, e_rrsel); - insn = hppa_rebuild_insn ((int) LDW_R1_DLT, val, 14); - bfd_put_32 (stub_bfd, insn, loc + 8); - bfd_put_32 (stub_bfd, (bfd_vma) LDSID_R21_R1, loc + 12); - bfd_put_32 (stub_bfd, (bfd_vma) MTSP_R1, loc + 16); - bfd_put_32 (stub_bfd, (bfd_vma) BE_SR0_R21, loc + 20); - bfd_put_32 (stub_bfd, (bfd_vma) STW_RP, loc + 24); + bfd_put_32 (stub_bfd, (bfd_vma) LDW_R22_R19, loc + 16); + bfd_put_32 (stub_bfd, (bfd_vma) MTSP_R1, loc + 20); + bfd_put_32 (stub_bfd, (bfd_vma) BE_SR0_R21, loc + 24); + bfd_put_32 (stub_bfd, (bfd_vma) STW_RP, loc + 28); - size = 28; + size = IMPORT_SHARED_STUB_SIZE; } else { - bfd_put_32 (stub_bfd, (bfd_vma) BV_R0_R21, loc + 8); - val = hppa_field_adjust (sym_value, (bfd_signed_vma) 4, e_rrsel); - insn = hppa_rebuild_insn ((int) LDW_R1_DLT, val, 14); - bfd_put_32 (stub_bfd, insn, loc + 12); + bfd_put_32 (stub_bfd, (bfd_vma) BV_R0_R21, loc + 12); + bfd_put_32 (stub_bfd, (bfd_vma) LDW_R22_R19, loc + 16); - size = 16; + size = IMPORT_STUB_SIZE; } break; case hppa_stub_export: + /* Fail if the target section could not be assigned to an output + section. The user should fix his linker script. */ + if (hsh->target_section->output_section == NULL + && info->non_contiguous_regions) + info->callbacks->einfo (_("%F%P: Could not assign %pA to an output " + "section. Retry without " + "--enable-non-contiguous-regions.\n"), + hsh->target_section); + /* Branches are relative. This is where we are going to. */ sym_value = (hsh->target_value + hsh->target_section->output_offset @@ -843,10 +866,11 @@ hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg) { _bfd_error_handler /* xgettext:c-format */ - (_("%B(%A+%#Lx): cannot reach %s, recompile with -ffunction-sections"), + (_("%pB(%pA+%#" PRIx64 "): " + "cannot reach %s, recompile with -ffunction-sections"), hsh->target_section->owner, stub_sec, - hsh->stub_offset, + (uint64_t) hsh->stub_offset, hsh->bh_root.string); bfd_set_error (bfd_error_bad_value); return FALSE; @@ -859,7 +883,7 @@ hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg) insn = hppa_rebuild_insn ((int) BL22_RP, val, 22); bfd_put_32 (stub_bfd, insn, loc); - bfd_put_32 (stub_bfd, (bfd_vma) NOP, loc + 4); + bfd_put_32 (stub_bfd, (bfd_vma) NOP, loc + 4); bfd_put_32 (stub_bfd, (bfd_vma) LDW_RP, loc + 8); bfd_put_32 (stub_bfd, (bfd_vma) LDSID_RP_R1, loc + 12); bfd_put_32 (stub_bfd, (bfd_vma) MTSP_R1, loc + 16); @@ -869,7 +893,7 @@ hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg) hsh->hh->eh.root.u.def.section = stub_sec; hsh->hh->eh.root.u.def.value = stub_sec->size; - size = 24; + size = EXPORT_STUB_SIZE; break; default: @@ -917,17 +941,17 @@ hppa_size_one_stub (struct bfd_hash_entry *bh, void *in_arg) htab = in_arg; if (hsh->stub_type == hppa_stub_long_branch) - size = 8; + size = LONG_BRANCH_STUB_SIZE; else if (hsh->stub_type == hppa_stub_long_branch_shared) - size = 12; + size = LONG_BRANCH_SHARED_STUB_SIZE; else if (hsh->stub_type == hppa_stub_export) - size = 24; + size = EXPORT_STUB_SIZE; else /* hppa_stub_import or hppa_stub_import_shared. */ { if (htab->multi_subspace) - size = 28; + size = IMPORT_SHARED_STUB_SIZE; else - size = 16; + size = IMPORT_STUB_SIZE; } hsh->stub_sec->size += size; @@ -1026,29 +1050,29 @@ elf32_hppa_copy_indirect_symbol (struct bfd_link_info *info, { if (hh_dir->dyn_relocs != NULL) { - struct elf32_hppa_dyn_reloc_entry **hdh_pp; - struct elf32_hppa_dyn_reloc_entry *hdh_p; + struct elf_dyn_relocs **hdh_pp; + struct elf_dyn_relocs *hdh_p; /* Add reloc counts against the indirect sym to the direct sym list. Merge any entries against the same section. */ for (hdh_pp = &hh_ind->dyn_relocs; (hdh_p = *hdh_pp) != NULL; ) { - struct elf32_hppa_dyn_reloc_entry *hdh_q; + struct elf_dyn_relocs *hdh_q; for (hdh_q = hh_dir->dyn_relocs; hdh_q != NULL; - hdh_q = hdh_q->hdh_next) + hdh_q = hdh_q->next) if (hdh_q->sec == hdh_p->sec) { #if RELATIVE_DYNRELOCS - hdh_q->relative_count += hdh_p->relative_count; + hdh_q->pc_count += hdh_p->pc_count; #endif hdh_q->count += hdh_p->count; - *hdh_pp = hdh_p->hdh_next; + *hdh_pp = hdh_p->next; break; } if (hdh_q == NULL) - hdh_pp = &hdh_p->hdh_next; + hdh_pp = &hdh_p->next; } *hdh_pp = hh_dir->dyn_relocs; } @@ -1256,7 +1280,7 @@ elf32_hppa_check_relocs (bfd *abfd, { _bfd_error_handler /* xgettext:c-format */ - (_("%B: relocation %s can not be used when making a shared object; recompile with -fPIC"), + (_("%pB: relocation %s can not be used when making a shared object; recompile with -fPIC"), abfd, elf_hppa_howto_table[r_type].name); bfd_set_error (bfd_error_bad_value); @@ -1284,9 +1308,7 @@ elf32_hppa_check_relocs (bfd *abfd, /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_PARISC_GNU_VTENTRY: - BFD_ASSERT (hh != NULL); - if (hh != NULL - && !bfd_elf_gc_record_vtentry (abfd, sec, &hh->eh, rela->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, &hh->eh, rela->r_addend)) return FALSE; continue; @@ -1300,7 +1322,7 @@ elf32_hppa_check_relocs (bfd *abfd, case R_PARISC_TLS_IE21L: case R_PARISC_TLS_IE14R: if (bfd_link_dll (info)) - info->flags |= DF_STATIC_TLS; + info->flags |= DF_STATIC_TLS; need_entry = NEED_GOT; break; @@ -1451,8 +1473,8 @@ elf32_hppa_check_relocs (bfd *abfd, && (hh->eh.root.type == bfd_link_hash_defweak || !hh->eh.def_regular))) { - struct elf32_hppa_dyn_reloc_entry *hdh_p; - struct elf32_hppa_dyn_reloc_entry **hdh_head; + struct elf_dyn_relocs *hdh_p; + struct elf_dyn_relocs **hdh_head; /* Create a reloc section in dynobj and make room for this reloc. */ @@ -1493,7 +1515,7 @@ elf32_hppa_check_relocs (bfd *abfd, sr = sec; vpp = &elf_section_data (sr)->local_dynrel; - hdh_head = (struct elf32_hppa_dyn_reloc_entry **) vpp; + hdh_head = (struct elf_dyn_relocs **) vpp; } hdh_p = *hdh_head; @@ -1502,19 +1524,19 @@ elf32_hppa_check_relocs (bfd *abfd, hdh_p = bfd_alloc (htab->etab.dynobj, sizeof *hdh_p); if (hdh_p == NULL) return FALSE; - hdh_p->hdh_next = *hdh_head; + hdh_p->next = *hdh_head; *hdh_head = hdh_p; hdh_p->sec = sec; hdh_p->count = 0; #if RELATIVE_DYNRELOCS - hdh_p->relative_count = 0; + hdh_p->pc_count = 0; #endif } hdh_p->count += 1; #if RELATIVE_DYNRELOCS if (!IS_ABSOLUTE_RELOC (rtype)) - hdh_p->relative_count += 1; + hdh_p->pc_count += 1; #endif } } @@ -1643,10 +1665,10 @@ static asection * readonly_dynrelocs (struct elf_link_hash_entry *eh) { struct elf32_hppa_link_hash_entry *hh; - struct elf32_hppa_dyn_reloc_entry *hdh_p; + struct elf_dyn_relocs *hdh_p; hh = hppa_elf_hash_entry (eh); - for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next) + for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->next) { asection *sec = hdh_p->sec->output_section; @@ -1770,13 +1792,11 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info, if (info->nocopyreloc) return TRUE; + /* If we don't find any dynamic relocs in read-only sections, then + we'll be keeping the dynamic relocs and avoiding the copy reloc. */ if (ELIMINATE_COPY_RELOCS && !alias_readonly_dynrelocs (eh)) - { - /* If we didn't find any dynamic relocs in read-only sections, then - we'll be keeping the dynamic relocs and avoiding the copy reloc. */ - return TRUE; - } + return TRUE; /* We must allocate the symbol in our .dynbss section, which will become part of the .bss section of the executable. There will be @@ -1909,18 +1929,19 @@ got_entries_needed (int tls_type) } /* Calculate size of relocs needed for symbol given its TLS_TYPE and - NEEDed GOT entries. KNOWN says a TPREL offset can be calculated - at link time. */ + NEEDed GOT entries. TPREL_KNOWN says a TPREL offset can be + calculated at link time. DTPREL_KNOWN says the same for a DTPREL + offset. */ static inline unsigned int -got_relocs_needed (int tls_type, unsigned int need, bfd_boolean known) +got_relocs_needed (int tls_type, unsigned int need, + bfd_boolean dtprel_known, bfd_boolean tprel_known) { /* All the entries we allocated need relocs. - Except IE in executable with a local symbol. We could also omit - the DTPOFF reloc on the second word of a GD entry under the same - condition as that for IE, but ld.so might want to differentiate - LD and GD entries at some stage. */ - if ((tls_type & GOT_TLS_IE) != 0 && known) + Except for GD and IE with local symbols. */ + if ((tls_type & GOT_TLS_GD) != 0 && dtprel_known) + need -= GOT_ENTRY_SIZE; + if ((tls_type & GOT_TLS_IE) != 0 && tprel_known) need -= GOT_ENTRY_SIZE; return need * sizeof (Elf32_External_Rela) / GOT_ENTRY_SIZE; } @@ -1935,7 +1956,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) struct elf32_hppa_link_hash_table *htab; asection *sec; struct elf32_hppa_link_hash_entry *hh; - struct elf32_hppa_dyn_reloc_entry *hdh_p; + struct elf_dyn_relocs *hdh_p; if (eh->root.type == bfd_link_hash_indirect) return TRUE; @@ -1974,15 +1995,16 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) need = got_entries_needed (hh->tls_type); sec->size += need; if (htab->etab.dynamic_sections_created - && (bfd_link_pic (info) + && (bfd_link_dll (info) + || (bfd_link_pic (info) && (hh->tls_type & GOT_NORMAL) != 0) || (eh->dynindx != -1 && !SYMBOL_REFERENCES_LOCAL (info, eh))) && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, eh)) { - bfd_boolean tprel_known = (bfd_link_executable (info) - && SYMBOL_REFERENCES_LOCAL (info, eh)); + bfd_boolean local = SYMBOL_REFERENCES_LOCAL (info, eh); htab->etab.srelgot->size - += got_relocs_needed (hh->tls_type, need, tprel_known); + += got_relocs_needed (hh->tls_type, need, local, + local && bfd_link_executable (info)); } } else @@ -2011,16 +2033,16 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) #if RELATIVE_DYNRELOCS if (SYMBOL_CALLS_LOCAL (info, eh)) { - struct elf32_hppa_dyn_reloc_entry **hdh_pp; + struct elf_dyn_relocs **hdh_pp; for (hdh_pp = &hh->dyn_relocs; (hdh_p = *hdh_pp) != NULL; ) { - hdh_p->count -= hdh_p->relative_count; - hdh_p->relative_count = 0; + hdh_p->count -= hdh_p->pc_count; + hdh_p->pc_count = 0; if (hdh_p->count == 0) - *hdh_pp = hdh_p->hdh_next; + *hdh_pp = hdh_p->next; else - hdh_pp = &hdh_p->hdh_next; + hdh_pp = &hdh_p->next; } } #endif @@ -2052,7 +2074,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) } /* Finally, allocate space. */ - for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next) + for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->next) { asection *sreloc = elf_section_data (hdh_p->sec)->sreloc; sreloc->size += hdh_p->count * sizeof (Elf32_External_Rela); @@ -2098,8 +2120,8 @@ maybe_set_textrel (struct elf_link_hash_entry *eh, void *inf) info->flags |= DF_TEXTREL; info->callbacks->minfo - (_("%B: dynamic relocation in read-only section `%A'\n"), - sec->owner, sec); + (_("%pB: dynamic relocation against `%pT' in read-only section `%pA'\n"), + sec->owner, eh->root.root.string, sec); /* Not an error, just cut short the traversal. */ return FALSE; @@ -2163,12 +2185,12 @@ elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, for (sec = ibfd->sections; sec != NULL; sec = sec->next) { - struct elf32_hppa_dyn_reloc_entry *hdh_p; + struct elf_dyn_relocs *hdh_p; - for (hdh_p = ((struct elf32_hppa_dyn_reloc_entry *) + for (hdh_p = ((struct elf_dyn_relocs *) elf_section_data (sec)->local_dynrel); hdh_p != NULL; - hdh_p = hdh_p->hdh_next) + hdh_p = hdh_p->next) { if (!bfd_is_abs_section (hdh_p->sec) && bfd_is_abs_section (hdh_p->sec->output_section)) @@ -2207,12 +2229,12 @@ elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, *local_got = sec->size; need = got_entries_needed (*local_tls_type); sec->size += need; - if (bfd_link_pic (info)) - { - bfd_boolean tprel_known = bfd_link_executable (info); - htab->etab.srelgot->size - += got_relocs_needed (*local_tls_type, need, tprel_known); - } + if (bfd_link_dll (info) + || (bfd_link_pic (info) + && (*local_tls_type & GOT_NORMAL) != 0)) + htab->etab.srelgot->size + += got_relocs_needed (*local_tls_type, need, TRUE, + bfd_link_executable (info)); } else *local_got = (bfd_vma) -1; @@ -2250,7 +2272,7 @@ elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, if (htab->tls_ldm_got.refcount > 0) { /* Allocate 2 got entries and 1 dynamic reloc for - R_PARISC_TLS_DTPMOD32 relocs. */ + R_PARISC_TLS_DTPMOD32 relocs. */ htab->tls_ldm_got.offset = htab->etab.sgot->size; htab->etab.sgot->size += (GOT_ENTRY_SIZE * 2); htab->etab.srelgot->size += sizeof (Elf32_External_Rela); @@ -2283,12 +2305,13 @@ elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* Make space for the plt stub at the end of the .plt section. We want this stub right at the end, up against the .got section. */ - int gotalign = bfd_section_alignment (dynobj, htab->etab.sgot); - int pltalign = bfd_section_alignment (dynobj, sec); + int gotalign = bfd_section_alignment (htab->etab.sgot); + int pltalign = bfd_section_alignment (sec); + int align = gotalign > 3 ? gotalign : 3; bfd_size_type mask; - if (gotalign > pltalign) - (void) bfd_set_section_alignment (dynobj, sec, gotalign); + if (align > pltalign) + bfd_set_section_alignment (sec, align); mask = ((bfd_size_type) 1 << gotalign) - 1; sec->size = (sec->size + sizeof (plt_stub) + mask) & ~mask; } @@ -2297,7 +2320,7 @@ elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, || sec == htab->etab.sdynbss || sec == htab->etab.sdynrelro) ; - else if (CONST_STRNEQ (bfd_get_section_name (dynobj, sec), ".rela")) + else if (CONST_STRNEQ (bfd_section_name (sec), ".rela")) { if (sec->size != 0) { @@ -2411,7 +2434,7 @@ elf32_hppa_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info) unsigned int top_id, top_index; asection *section; asection **input_list, **list; - bfd_size_type amt; + size_t amt; struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info); if (htab == NULL) @@ -2600,7 +2623,7 @@ get_local_syms (bfd *output_bfd, bfd *input_bfd, struct bfd_link_info *info) /* We want to read in symbol extension records only once. To do this we need to read in the local symbols in parallel and save them for later use; so hold pointers to the local symbols in an array. */ - bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count; + size_t amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count; all_local_syms = bfd_zmalloc (amt); htab->all_local_syms = all_local_syms; if (all_local_syms == NULL) @@ -2696,7 +2719,7 @@ get_local_syms (bfd *output_bfd, bfd *input_bfd, struct bfd_link_info *info) else { /* xgettext:c-format */ - _bfd_error_handler (_("%B: duplicate export stub %s"), + _bfd_error_handler (_("%pB: duplicate export stub %s"), input_bfd, stub_name); } } @@ -2808,6 +2831,9 @@ elf32_hppa_size_stubs /* If there aren't any relocs, then there's nothing more to do. */ if ((section->flags & SEC_RELOC) == 0 + || (section->flags & SEC_ALLOC) == 0 + || (section->flags & SEC_LOAD) == 0 + || (section->flags & SEC_CODE) == 0 || section->reloc_count == 0) continue; @@ -2861,7 +2887,7 @@ elf32_hppa_size_stubs section. */ sym_sec = NULL; sym_value = 0; - destination = 0; + destination = -1; hh = NULL; if (r_indx < symtab_hdr->sh_info) { @@ -3051,9 +3077,9 @@ elf32_hppa_set_gp (bfd *abfd, struct bfd_link_info *info) { if (strcmp (bfd_get_target (abfd), "elf32-hppa-netbsd") != 0) { - /* We know we don't have a .plt. If .got is large, + /* We know we don't have a .plt. If .got is large, offset our LTP. */ - if (sec->size > 0x2000) + if (sec->size > 0x2000) gp_val = 0x2000; } } @@ -3222,7 +3248,7 @@ final_link_relocate (asection *input_section, struct elf32_hppa_link_hash_entry *hh, struct bfd_link_info *info) { - int insn; + unsigned int insn; unsigned int r_type = ELF32_R_TYPE (rela->r_info); unsigned int orig_r_type = r_type; reloc_howto_type *howto = elf_hppa_howto_table + r_type; @@ -3291,7 +3317,7 @@ final_link_relocate (asection *input_section, || hh->eh.root.type == bfd_link_hash_defweak))) { hsh = hppa_get_stub_entry (input_section, sym_sec, - hh, rela, htab); + hh, rela, htab); if (hsh != NULL) { value = (hsh->stub_offset @@ -3341,7 +3367,7 @@ final_link_relocate (asection *input_section, /* GCC sometimes uses a register other than r19 for the operation, so we must convert any addil instruction that uses this relocation. */ - if ((insn & 0xfc000000) == ((int) OP_ADDIL << 26)) + if ((insn & 0xfc000000) == OP_ADDIL << 26) insn = ADDIL_DP; else /* We must have a ldil instruction. It's too hard to find @@ -3349,10 +3375,11 @@ final_link_relocate (asection *input_section, error. */ _bfd_error_handler /* xgettext:c-format */ - (_("%B(%A+%#Lx): %s fixup for insn %#x is not supported in a non-shared link"), + (_("%pB(%pA+%#" PRIx64 "): %s fixup for insn %#x " + "is not supported in a non-shared link"), input_bfd, input_section, - offset, + (uint64_t) offset, howto->name, insn); } @@ -3374,8 +3401,8 @@ final_link_relocate (asection *input_section, instance: "extern int foo" with foo defined as "const int foo". */ if (sym_sec == NULL || (sym_sec->flags & SEC_CODE) != 0) { - if ((insn & ((0x3f << 26) | (0x1f << 21))) - == (((int) OP_ADDIL << 26) | (27 << 21))) + if ((insn & ((0x3fu << 26) | (0x1f << 21))) + == ((OP_ADDIL << 26) | (27 << 21))) { insn &= ~ (0x1f << 21); } @@ -3490,7 +3517,7 @@ final_link_relocate (asection *input_section, if (value + addend + max_branch_offset >= 2*max_branch_offset) { hsh = hppa_get_stub_entry (input_section, sym_sec, - hh, rela, htab); + hh, rela, htab); if (hsh == NULL) return bfd_reloc_undefined; @@ -3515,10 +3542,11 @@ final_link_relocate (asection *input_section, { _bfd_error_handler /* xgettext:c-format */ - (_("%B(%A+%#Lx): cannot reach %s, recompile with -ffunction-sections"), + (_("%pB(%pA+%#" PRIx64 "): cannot reach %s, " + "recompile with -ffunction-sections"), input_bfd, input_section, - offset, + (uint64_t) offset, hsh->bh_root.string); bfd_set_error (bfd_error_bad_value); return bfd_reloc_notsupported; @@ -4049,12 +4077,12 @@ elf32_hppa_relocate_section (bfd *output_bfd, bfd_byte *loc = NULL; int cur_off = off; - /* The GOT entries have not been initialized yet. Do it - now, and emit any relocations. If both an IE GOT and a - GD GOT are necessary, we emit the GD first. */ + /* The GOT entries have not been initialized yet. Do it + now, and emit any relocations. If both an IE GOT and a + GD GOT are necessary, we emit the GD first. */ if (indx != 0 - || (bfd_link_pic (info) + || (bfd_link_dll (info) && (hh == NULL || !UNDEFWEAK_NO_DYNAMIC_RELOC (info, &hh->eh)))) { @@ -4078,29 +4106,32 @@ elf32_hppa_relocate_section (bfd *output_bfd, bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); htab->etab.srelgot->reloc_count++; loc += sizeof (Elf32_External_Rela); + bfd_put_32 (output_bfd, 0, + htab->etab.sgot->contents + cur_off); + } + else + /* If we are not emitting relocations for a + general dynamic reference, then we must be in a + static link or an executable link with the + symbol binding locally. Mark it as belonging + to module 1, the executable. */ + bfd_put_32 (output_bfd, 1, + htab->etab.sgot->contents + cur_off); + + if (indx != 0) + { outrel.r_info = ELF32_R_INFO (indx, R_PARISC_TLS_DTPOFF32); outrel.r_offset += 4; bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); htab->etab.srelgot->reloc_count++; loc += sizeof (Elf32_External_Rela); - bfd_put_32 (output_bfd, 0, - htab->etab.sgot->contents + cur_off); bfd_put_32 (output_bfd, 0, htab->etab.sgot->contents + cur_off + 4); } else - { - /* If we are not emitting relocations for a - general dynamic reference, then we must be in a - static link or an executable link with the - symbol binding locally. Mark it as belonging - to module 1, the executable. */ - bfd_put_32 (output_bfd, 1, - htab->etab.sgot->contents + cur_off); - bfd_put_32 (output_bfd, relocation - dtpoff_base (info), - htab->etab.sgot->contents + cur_off + 4); - } + bfd_put_32 (output_bfd, relocation - dtpoff_base (info), + htab->etab.sgot->contents + cur_off + 4); cur_off += 8; } @@ -4156,9 +4187,9 @@ elf32_hppa_relocate_section (bfd *output_bfd, if (sym_name == NULL) return FALSE; if (*sym_name == '\0') - sym_name = bfd_section_name (input_bfd, sym_sec); + sym_name = bfd_section_name (sym_sec); _bfd_error_handler - (_("%B:%s has both normal and TLS relocs"), + (_("%pB:%s has both normal and TLS relocs"), input_bfd, sym_name); } bfd_set_error (bfd_error_bad_value); @@ -4166,8 +4197,8 @@ elf32_hppa_relocate_section (bfd *output_bfd, } if ((tls_type & GOT_TLS_GD) - && r_type != R_PARISC_TLS_GD21L - && r_type != R_PARISC_TLS_GD14R) + && r_type != R_PARISC_TLS_GD21L + && r_type != R_PARISC_TLS_GD14R) off += 2 * GOT_ENTRY_SIZE; /* Add the base of the GOT to the relocation value. */ @@ -4206,7 +4237,7 @@ elf32_hppa_relocate_section (bfd *output_bfd, if (sym_name == NULL) return FALSE; if (*sym_name == '\0') - sym_name = bfd_section_name (input_bfd, sym_sec); + sym_name = bfd_section_name (sym_sec); } howto = elf_hppa_howto_table + r_type; @@ -4217,10 +4248,10 @@ elf32_hppa_relocate_section (bfd *output_bfd, { _bfd_error_handler /* xgettext:c-format */ - (_("%B(%A+%#Lx): cannot handle %s for %s"), + (_("%pB(%pA+%#" PRIx64 "): cannot handle %s for %s"), input_bfd, input_section, - rela->r_offset, + (uint64_t) rela->r_offset, howto->name, sym_name); bfd_set_error (bfd_error_bad_value); @@ -4401,7 +4432,7 @@ elf32_hppa_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, case R_PARISC_TLS_DTPMOD32: case R_PARISC_TLS_DTPOFF32: case R_PARISC_TLS_TPREL32: - return reloc_class_normal; + return reloc_class_normal; } if (ELF32_R_SYM (rela->r_info) == STN_UNDEF)