# DP: updates from the binutils-2.22 branch # git diff 10968a312d8c536be9993ed06bc88fbe0860d95d 20328dadc04ae46c8ca4b334c8d1d4c9aec9c5b7 # exclude bfd/{configure{,.ac},Makefile.{am,in}} diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 65db027..a568f1b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,206 @@ +2012-05-11 Ralf Corsépius + + Backport from mainline: + + 2012-04-24 Alan Modra + PR ld/13991 + * bfd/elf-bfd.h (_bfd_elf_link_just_syms): Define as + _bfd_generic_link_just_syms. + * bfd/elflink.c (_bfd_elf_link_just_syms): Delete. + * bfd/linker.c (_bfd_generic_link_just_syms): Set sec_info_type. + + * bfd/bfd-in.h (discarded_section): Renamed from elf_discarded_section. + * bfd/section.c (SEC_INFO_TYPE_NONE, SEC_INFO_TYPE_STABS, + SEC_INFO_TYPE_MERGE, SEC_INFO_TYPE_EH_FRAME, + SEC_INFO_TYPE_JUST_SYMS): Renamed from corresponding ELF_INFO_TYPE. + * bfd/elf-eh-frame.c, * bfd/elf-m10200.c, * bfd/elf-m10300.c, + * bfd/elf.c, * bfd/elf32-arm.c, * bfd/elf32-avr.c, * bfd/elf32-bfin.c, + * bfd/elf32-cr16.c, * bfd/elf32-cr16c.c, * bfd/elf32-cris.c, + * bfd/elf32-crx.c, * bfd/elf32-d10v.c, * bfd/elf32-epiphany.c, + * bfd/elf32-fr30.c, * bfd/elf32-frv.c, * bfd/elf32-h8300.c, + * bfd/elf32-hppa.c, * bfd/elf32-i370.c, * bfd/elf32-i386.c, + * bfd/elf32-i860.c, * bfd/elf32-ip2k.c, * bfd/elf32-iq2000.c, + * bfd/elf32-lm32.c, * bfd/elf32-m32c.c, * bfd/elf32-m32r.c, + * bfd/elf32-m68hc1x.c, * bfd/elf32-m68k.c, * bfd/elf32-mcore.c, + * bfd/elf32-mep.c, * bfd/elf32-moxie.c, * bfd/elf32-msp430.c, + * bfd/elf32-mt.c, * bfd/elf32-openrisc.c, * bfd/elf32-ppc.c, + * bfd/elf32-rl78.c, * bfd/elf32-rx.c, * bfd/elf32-s390.c, + * bfd/elf32-score.c, * bfd/elf32-score7.c, * bfd/elf32-sh.c, + * bfd/elf32-spu.c, * bfd/elf32-tic6x.c, * bfd/elf32-tilepro.c, + * bfd/elf32-v850.c, * bfd/elf32-vax.c, * bfd/elf32-xc16x.c, + * bfd/elf32-xstormy16.c, * bfd/elf32-xtensa.c, * bfd/elf64-alpha.c, + * bfd/elf64-hppa.c, * bfd/elf64-ia64-vms.c, * bfd/elf64-mmix.c, + * bfd/elf64-ppc.c, * bfd/elf64-s390.c, * bfd/elf64-sh64.c, + * bfd/elf64-x86-64.c, * bfd/elflink.c, * bfd/elfnn-ia64.c, + * bfd/elfxx-mips.c, * bfd/elfxx-sparc.c, * bfd/elfxx-tilegx.c, + * bfd/reloc.c: Update all references. + * bfd/bfd-in2.h: Regenerate. + +2012-04-20 Nick Clifton + + Import this patch from the mainline: + 2012-03-21 Eliot Dresselhaus + + * elf32-tic6x.c (elf32_tic6x_merge_private_bfd_data): Return TRUE + for non-C6X objects. + +2012-02-01 Nick Clifton + + Import this patch from the mainline: + 2012-01-05 Nick Clifton + + PR ld/12161 + * elf32-avr.c (elf32_avr_relax_delete_bytes): Read in relocs if + necessary. + +2012-01-27 John David Anglin + + Backport from mainline: + 2011-12-11 John Davis Anglin + + PR binutils/13476 + * elf32-hppa.c (final_link_relocate): Convert R_PARISC_TLS_GD21L, + R_PARISC_TLS_LDM21L and R_PARISC_TLS_IE21L relocations to + R_PARISC_DPREL21L when not doing a shared link. Likewise convert + R_PARISC_TLS_GD14R, R_PARISC_TLS_LDM14R and R_PARISC_TLS_IE14R to + R_PARISC_DPREL14R. Handle R_PARISC_TLS_GD21L, R_PARISC_TLS_LDM21L + and R_PARISC_TLS_IE21L with R_PARISC_DLTIND21L. + + Backport from mainline: + 2011-11-06 John David Anglin + + PR ld/13387 + * elf32-hppa.c (elf32_hppa_hide_symbol): Make STT_GNU_IFUNC symbol + go through PLT. Reset plt field with init_plt_offset. + (elf32_hppa_adjust_dynamic_symbol): Ensure that a PLT slot is + allocated for symbols referenced by a plabel. + +2012-01-10 H.J. Lu + + Backport from mainline: + PR ld/13581 + * elf64-x86-64.c (elf_x86_64_relocate_section): Remove ABI_64_P + check on R_X86_64_PCXX. + +2011-12-19 Chung-Lin Tang + + Backport from mainline: + + 2011-12-19 Chung-Lin Tang + + * reloc.c (BFD_RELOC_MIPS16_TLS_GD,BFD_RELOC_MIPS16_TLS_LDM, + BFD_RELOC_MIPS16_TLS_DTPREL_HI16,BFD_RELOC_MIPS16_TLS_DTPREL_LO16, + BFD_RELOC_MIPS16_TLS_GOTTPREL,BFD_RELOC_MIPS16_TLS_TPREL_HI16, + BFD_RELOC_MIPS16_TLS_TPREL_LO16): New relocations for MIPS16 TLS. + * bfd-in2.h (bfd_reloc_code_real): Regenerate. + * libbfd.h (bfd_reloc_code_real_names): Regenerate. + * elf32-mips.c (elf_mips16_howto_table_rel): Add R_MIPS16_TLS_* + entries. + (mips16_reloc_map): Add BFD_RELOC_MIPS16_TLS_* to R_MIPS16_TLS_* + mappings. + * elfn32-mips.c (elf_mips16_howto_table_rel, + elf_mips16_howto_table_rela): Add R_MIPS16_TLS_* entries. + (mips16_reloc_map): Add BFD_RELOC_MIPS16_TLS_* to R_MIPS16_TLS_* + mappings. + * elf64-mips.c (mips16_elf64_howto_table_rel, + mips16_elf64_howto_table_rela): Add R_MIPS16_TLS_* entries. + (mips16_reloc_map): Add BFD_RELOC_MIPS16_TLS_* to R_MIPS16_TLS_* + mappings. + * elfxx-mips.c (TLS_RELOC_P,mips16_reloc_p, + _bfd_mips_elf_check_relocs): Add cases for R_MIPS16_TLS_* relocations. + (tls_gd_reloc_p): Add R_MIPS16_TLS_GD case. + (tls_ldm_reloc_p): Add R_MIPS16_TLS_LDM case. + (tls_gottprel_reloc_p): Add R_MIPS16_TLS_GOTTPREL case. + (mips_elf_calculate_relocation): Add cases for R_MIPS16_TLS_*, + R_MIPS_TLS_DTPREL32/64, and R_MIPS_TLS_TPREL32/64 relocations. + +2011-12-19 Chung-Lin Tang + + Backport from mainline: + + 2011-12-19 Chung-Lin Tang + Catherine Moore + Sandra Loosemore + Richard Sandiford + + * elfxx-mips.c (mips_elf_local_pic_function_p): Return true when + H is a MIPS16 function with a kept 32-bit stub. Update comments. + (mips_elf_get_la25_target): New function. + (mips_elf_add_la25_intro): Change to use mips_elf_get_la25_target(). + (mips_elf_add_la25_stub): Move compute of use_trampoline_p down, + change to use mips_elf_get_la25_target(). + (mips_elf_relocation_needs_la25_stub): Add target_is_16_bit_code_p + parameter, add switch case for R_MIPS16_26. + (mips_elf_calculate_relocation): Redirect relocation to point to the + LA25 stub if it exists, instead of the MIPS16 stub. Update arguments + of call to mips_elf_relocation_needs_la25_stub(), don't use la25 stub + for mips16->mips16 calls. + (_bfd_mips_elf_check_relocs): Update arguments of call to + mips_elf_relocation_needs_la25_stub(). + (mips_elf_create_la25_stub): Change to use mips_elf_get_la25_target(). + +2011-12-19 Chung-Lin Tang + + Backport from mainline: + + 2011-12-13 Chung-Lin Tang + + * elfxx-mips.c (mips_elf_calculate_relocation): Correct + R_MIPS16_HI16/R_MIPS16_LO16 handling of two cleared lower bits, + update comments. + +2011-12-10 David Daney + + Backport from mainline: + + 2011-12-10 David Daney + + * elfxx-mips.c (mips_elf_link_hash_table.rld_value): Remove. + (mips_elf_link_hash_table.rld_symbol): New field; + (MIPS_ELF_RLD_MAP_SIZE): New macro. + (_bfd_mips_elf_add_symbol_hook): Remember __rld_obj_head symbol + in rld_symbol. + (_bfd_mips_elf_create_dynamic_sections): Remember __rld_map symbol + in rld_symbol. + (_bfd_mips_elf_size_dynamic_sections): Set correct size for .rld_map. + (_bfd_mips_elf_finish_dynamic_symbol): Remove .rld_map handling. + (_bfd_mips_elf_finish_dynamic_sections): Use rld_symbol to + calculate DT_MIPS_RLD_MAP value. + (_bfd_mips_elf_link_hash_table_create): Initialize rld_symbol, + quit initializing rld_value. + +2011-12-03 Alan Modra + + PR ld/13468 + * elflink.c (bfd_elf_final_link): Don't segfault when checking + for DT_TEXTREL and .dynamic does not exist. + +2011-12-03 Alan Modra + + PR ld/13470 + * elf32-ppc.c (ppc_elf_copy_indirect_symbol): Revert substantive + change in 2011-07-01 commit. Comment. + * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise. + +2011-12-01 Mikael Pettersson + + Apply mainline patches + * elf32-m68k.c (elf_m68k_check_relocs) : For + non-SEC_ALLOC sections break before GOT and PLT accounting. + +2011-12-01 Hans-Peter Nilsson + + Apply mainline patches + * elf32-cris.c (cris_elf_check_relocs) : Move early break for + non-SEC_ALLOC sections before GOT and PLT accounting. + +2011-11-21 Tristan Gingold + + * configure.in: Bump version to 2.22.0 + * Makefile.am (RELEASE): Unset. + * configure, Makefile.in: Regenerate. + 2011-11-21 Tristan Gingold * configure.in: Bump version to 2.22 diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index a477b49..7c5298a 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -295,11 +295,11 @@ typedef struct bfd_section *sec_ptr; ? (sec)->rawsize : (sec)->size) / bfd_octets_per_byte (bfd)) /* Return TRUE if input section SEC has been discarded. */ -#define elf_discarded_section(sec) \ +#define discarded_section(sec) \ (!bfd_is_abs_section (sec) \ && bfd_is_abs_section ((sec)->output_section) \ - && (sec)->sec_info_type != ELF_INFO_TYPE_MERGE \ - && (sec)->sec_info_type != ELF_INFO_TYPE_JUST_SYMS) + && (sec)->sec_info_type != SEC_INFO_TYPE_MERGE \ + && (sec)->sec_info_type != SEC_INFO_TYPE_JUST_SYMS) /* Forward define. */ struct stat; diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 22fcdf6..34f9628 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -302,11 +302,11 @@ typedef struct bfd_section *sec_ptr; ? (sec)->rawsize : (sec)->size) / bfd_octets_per_byte (bfd)) /* Return TRUE if input section SEC has been discarded. */ -#define elf_discarded_section(sec) \ +#define discarded_section(sec) \ (!bfd_is_abs_section (sec) \ && bfd_is_abs_section ((sec)->output_section) \ - && (sec)->sec_info_type != ELF_INFO_TYPE_MERGE \ - && (sec)->sec_info_type != ELF_INFO_TYPE_JUST_SYMS) + && (sec)->sec_info_type != SEC_INFO_TYPE_MERGE \ + && (sec)->sec_info_type != SEC_INFO_TYPE_JUST_SYMS) /* Forward define. */ struct stat; @@ -1384,11 +1384,11 @@ typedef struct bfd_section /* Type of sec_info information. */ unsigned int sec_info_type:3; -#define ELF_INFO_TYPE_NONE 0 -#define ELF_INFO_TYPE_STABS 1 -#define ELF_INFO_TYPE_MERGE 2 -#define ELF_INFO_TYPE_EH_FRAME 3 -#define ELF_INFO_TYPE_JUST_SYMS 4 +#define SEC_INFO_TYPE_NONE 0 +#define SEC_INFO_TYPE_STABS 1 +#define SEC_INFO_TYPE_MERGE 2 +#define SEC_INFO_TYPE_EH_FRAME 3 +#define SEC_INFO_TYPE_JUST_SYMS 4 /* Nonzero if this section uses RELA relocations, rather than REL. */ unsigned int use_rela_p:1; @@ -2780,6 +2780,15 @@ to compensate for the borrow when the low bits are added. */ /* MIPS16 low 16 bits. */ BFD_RELOC_MIPS16_LO16, +/* MIPS16 TLS relocations */ + BFD_RELOC_MIPS16_TLS_GD, + BFD_RELOC_MIPS16_TLS_LDM, + BFD_RELOC_MIPS16_TLS_DTPREL_HI16, + BFD_RELOC_MIPS16_TLS_DTPREL_LO16, + BFD_RELOC_MIPS16_TLS_GOTTPREL, + BFD_RELOC_MIPS16_TLS_TPREL_HI16, + BFD_RELOC_MIPS16_TLS_TPREL_LO16, + /* Relocation against a MIPS literal section. */ BFD_RELOC_MIPS_LITERAL, BFD_RELOC_MICROMIPS_LITERAL, diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index d6e2ab2..2cfe2ba 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1807,8 +1807,7 @@ extern void bfd_elf_set_group_contents (bfd *, asection *, void *); extern asection *_bfd_elf_check_kept_section (asection *, struct bfd_link_info *); -extern void _bfd_elf_link_just_syms - (asection *, struct bfd_link_info *); +#define _bfd_elf_link_just_syms _bfd_generic_link_just_syms extern void _bfd_elf_copy_link_hash_symbol_type (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *); extern bfd_boolean _bfd_elf_size_group_sections diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c index 54142b2..7b5cf7a 100644 --- a/bfd/elf-eh-frame.c +++ b/bfd/elf-eh-frame.c @@ -491,7 +491,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, return; if (sec->size == 0 - || sec->sec_info_type != ELF_INFO_TYPE_NONE) + || sec->sec_info_type != SEC_INFO_TYPE_NONE) { /* This file does not contain .eh_frame information. */ return; @@ -904,7 +904,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info, BFD_ASSERT (cie_count == num_cies); elf_section_data (sec)->sec_info = sec_info; - sec->sec_info_type = ELF_INFO_TYPE_EH_FRAME; + sec->sec_info_type = SEC_INFO_TYPE_EH_FRAME; if (hdr_info->merge_cies) { sec_info->cies = local_cies; @@ -1137,7 +1137,7 @@ _bfd_elf_discard_section_eh_frame struct eh_frame_hdr_info *hdr_info; unsigned int ptr_size, offset; - if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME) + if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME) return FALSE; sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info; @@ -1307,7 +1307,7 @@ _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, struct eh_frame_sec_info *sec_info; unsigned int lo, hi, mid; - if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME) + if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME) return offset; sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info; @@ -1395,7 +1395,7 @@ _bfd_elf_write_section_eh_frame (bfd *abfd, unsigned int ptr_size; struct eh_cie_fde *ent; - if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME) + if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME) /* FIXME: octets_per_byte. */ return bfd_set_section_contents (abfd, sec->output_section, contents, sec->output_offset, sec->size); diff --git a/bfd/elf-m10200.c b/bfd/elf-m10200.c index a38f4db..d58c75c 100644 --- a/bfd/elf-m10200.c +++ b/bfd/elf-m10200.c @@ -401,7 +401,7 @@ mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c index 8276a2f..876ff4a 100644 --- a/bfd/elf-m10300.c +++ b/bfd/elf-m10300.c @@ -1509,7 +1509,7 @@ mn10300_elf_relocate_section (bfd *output_bfd, h->root.root.root.string); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); @@ -2763,7 +2763,7 @@ mn10300_elf_relax_section (bfd *abfd, isym->st_name); if ((sym_sec->flags & SEC_MERGE) - && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE) + && sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE) { symval = isym->st_value; diff --git a/bfd/elf.c b/bfd/elf.c index aa40c33..9e23bee 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -3071,7 +3071,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info) if (link_info != NULL) { /* Check discarded linkonce section. */ - if (elf_discarded_section (s)) + if (discarded_section (s)) { asection *kept; (*_bfd_error_handler) @@ -9390,7 +9390,7 @@ _bfd_elf_rela_local_sym (bfd *abfd, + sym->st_value); if ((sec->flags & SEC_MERGE) && ELF_ST_TYPE (sym->st_info) == STT_SECTION - && sec->sec_info_type == ELF_INFO_TYPE_MERGE) + && sec->sec_info_type == SEC_INFO_TYPE_MERGE) { rel->r_addend = _bfd_merged_section_offset (abfd, psec, @@ -9421,7 +9421,7 @@ _bfd_elf_rel_local_sym (bfd *abfd, { asection *sec = *psec; - if (sec->sec_info_type != ELF_INFO_TYPE_MERGE) + if (sec->sec_info_type != SEC_INFO_TYPE_MERGE) return sym->st_value + addend; return _bfd_merged_section_offset (abfd, psec, @@ -9437,10 +9437,10 @@ _bfd_elf_section_offset (bfd *abfd, { switch (sec->sec_info_type) { - case ELF_INFO_TYPE_STABS: + case SEC_INFO_TYPE_STABS: return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info, offset); - case ELF_INFO_TYPE_EH_FRAME: + case SEC_INFO_TYPE_EH_FRAME: return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset); default: if ((sec->flags & SEC_ELF_REVERSE_COPY) != 0) diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 1f6c1a0..9355f66 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -4485,7 +4485,7 @@ cortex_a8_erratum_scan (bfd *input_bfd, if (elf_section_type (section) != SHT_PROGBITS || (elf_section_flags (section) & SHF_EXECINSTR) == 0 || (section->flags & SEC_EXCLUDE) != 0 - || (section->sec_info_type == ELF_INFO_TYPE_JUST_SYMS) + || (section->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) || (section->output_section == bfd_abs_section_ptr)) continue; @@ -6556,7 +6556,7 @@ bfd_elf32_arm_vfp11_erratum_scan (bfd *abfd, struct bfd_link_info *link_info) if (elf_section_type (sec) != SHT_PROGBITS || (elf_section_flags (sec) & SHF_EXECINSTR) == 0 || (sec->flags & SEC_EXCLUDE) != 0 - || sec->sec_info_type == ELF_INFO_TYPE_JUST_SYMS + || sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS || sec->output_section == bfd_abs_section_ptr || strcmp (sec->name, VFP11_ERRATUM_VENEER_SECTION_NAME) == 0) continue; @@ -10305,7 +10305,7 @@ elf32_arm_relocate_section (bfd * output_bfd, sym_type = h->type; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index 6d20aef..97dc268 100644 --- a/bfd/elf32-avr.c +++ b/bfd/elf32-avr.c @@ -1189,7 +1189,7 @@ elf32_avr_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, name = h->root.root.string; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); @@ -1503,11 +1503,18 @@ elf32_avr_relax_delete_bytes (bfd *abfd, bfd_vma symval; bfd_vma shrinked_insn_address; + if (isec->reloc_count == 0) + continue; + shrinked_insn_address = (sec->output_section->vma + sec->output_offset + addr - count); - irelend = elf_section_data (isec)->relocs + isec->reloc_count; - for (irel = elf_section_data (isec)->relocs; + irel = elf_section_data (isec)->relocs; + /* PR 12161: Read in the relocs for this section if necessary. */ + if (irel == NULL) + irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, FALSE); + + for (irelend = irel + isec->reloc_count; irel < irelend; irel++) { @@ -1564,6 +1571,9 @@ elf32_avr_relax_delete_bytes (bfd *abfd, /* else...Reference symbol is extern. No need for adjusting the addend. */ } + + if (elf_section_data (isec)->relocs == NULL) + free (irelend - isec->reloc_count); } } diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c index b112dfc..4941f40 100644 --- a/bfd/elf32-bfin.c +++ b/bfd/elf32-bfin.c @@ -1444,7 +1444,7 @@ bfin_relocate_section (bfd * output_bfd, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); @@ -2663,7 +2663,7 @@ bfinfdpic_relocate_section (bfd * output_bfd, osec = sec; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); @@ -4429,7 +4429,7 @@ bfinfdpic_elf_discard_info (bfd *ibfd, /* Account for relaxation of .eh_frame section. */ for (s = ibfd->sections; s; s = s->next) - if (s->sec_info_type == ELF_INFO_TYPE_EH_FRAME) + if (s->sec_info_type == SEC_INFO_TYPE_EH_FRAME) { if (!_bfinfdpic_check_discarded_relocs (ibfd, s, info, &changed)) return FALSE; diff --git a/bfd/elf32-cr16.c b/bfd/elf32-cr16.c index 0118131..38af05f 100644 --- a/bfd/elf32-cr16.c +++ b/bfd/elf32-cr16.c @@ -1431,7 +1431,7 @@ elf32_cr16_relocate_section (bfd *output_bfd, struct bfd_link_info *info, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-cr16c.c b/bfd/elf32-cr16c.c index ca2d7cb..109936b 100644 --- a/bfd/elf32-cr16c.c +++ b/bfd/elf32-cr16c.c @@ -723,7 +723,7 @@ elf32_cr16c_relocate_section (bfd *output_bfd, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c index 243a8ec..ec23f03 100644 --- a/bfd/elf32-cris.c +++ b/bfd/elf32-cris.c @@ -1180,7 +1180,7 @@ cris_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, } } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); @@ -3579,6 +3579,12 @@ cris_elf_check_relocs (bfd *abfd, sec, cris_elf_howto_table[r_type].name); } + + /* We don't need to handle relocs into sections not going into + the "real" output. */ + if ((sec->flags & SEC_ALLOC) == 0) + break; + if (h != NULL) { h->non_got_ref = 1; @@ -3608,11 +3614,6 @@ cris_elf_check_relocs (bfd *abfd, if (! info->shared) break; - /* We don't need to handle relocs into sections not going into - the "real" output. */ - if ((sec->flags & SEC_ALLOC) == 0) - break; - /* We may need to create a reloc section in the dynobj and made room for this reloc. */ if (sreloc == NULL) diff --git a/bfd/elf32-crx.c b/bfd/elf32-crx.c index d48932d..fd13447 100644 --- a/bfd/elf32-crx.c +++ b/bfd/elf32-crx.c @@ -873,7 +873,7 @@ elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-d10v.c b/bfd/elf32-d10v.c index 7d65395..e39a9b5 100644 --- a/bfd/elf32-d10v.c +++ b/bfd/elf32-d10v.c @@ -463,7 +463,7 @@ elf32_d10v_relocate_section (bfd *output_bfd, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-fr30.c b/bfd/elf32-fr30.c index 97b0d29..57be6ae 100644 --- a/bfd/elf32-fr30.c +++ b/bfd/elf32-fr30.c @@ -577,7 +577,7 @@ fr30_elf_relocate_section (output_bfd, info, input_bfd, input_section, name = h->root.root.string; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-frv.c b/bfd/elf32-frv.c index 7f3c4dd..513f811 100644 --- a/bfd/elf32-frv.c +++ b/bfd/elf32-frv.c @@ -2812,7 +2812,7 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section, name = h->root.root.string; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); @@ -5678,7 +5678,7 @@ frvfdpic_elf_discard_info (bfd *ibfd, /* Account for relaxation of .eh_frame section. */ for (s = ibfd->sections; s; s = s->next) - if (s->sec_info_type == ELF_INFO_TYPE_EH_FRAME) + if (s->sec_info_type == SEC_INFO_TYPE_EH_FRAME) { if (!_frvfdpic_check_discarded_relocs (ibfd, s, info, &changed)) return FALSE; diff --git a/bfd/elf32-h8300.c b/bfd/elf32-h8300.c index 95d3983..ff1ee70 100644 --- a/bfd/elf32-h8300.c +++ b/bfd/elf32-h8300.c @@ -460,7 +460,7 @@ elf32_h8_relocate_section (bfd *output_bfd, struct bfd_link_info *info, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index 7f0f2cb..044b6fa 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -1789,10 +1789,12 @@ elf32_hppa_hide_symbol (struct bfd_link_info *info, } } - if (! hppa_elf_hash_entry (eh)->plabel) + /* STT_GNU_IFUNC symbol must go through PLT. */ + if (! hppa_elf_hash_entry (eh)->plabel + && eh->type != STT_GNU_IFUNC) { eh->needs_plt = 0; - eh->plt = elf_hash_table (info)->init_plt_refcount; + eh->plt = elf_hash_table (info)->init_plt_offset; } } @@ -1814,6 +1816,13 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info, if (eh->type == STT_FUNC || eh->needs_plt) { + /* If the symbol is used by a plabel, we must allocate a PLT slot. + The refcounts are not reliable when it has been hidden since + hide_symbol can be called before the plabel flag is set. */ + if (hppa_elf_hash_entry (eh)->plabel + && eh->plt.refcount <= 0) + eh->plt.refcount = 1; + if (eh->plt.refcount <= 0 || (eh->def_regular && eh->root.type != bfd_link_hash_defweak @@ -3340,10 +3349,16 @@ final_link_relocate (asection *input_section, switch (r_type) { case R_PARISC_DLTIND21L: + case R_PARISC_TLS_GD21L: + case R_PARISC_TLS_LDM21L: + case R_PARISC_TLS_IE21L: r_type = R_PARISC_DPREL21L; break; case R_PARISC_DLTIND14R: + case R_PARISC_TLS_GD14R: + case R_PARISC_TLS_LDM14R: + case R_PARISC_TLS_IE14R: r_type = R_PARISC_DPREL14R; break; @@ -3409,53 +3424,48 @@ final_link_relocate (asection *input_section, case R_PARISC_DPREL21L: case R_PARISC_DPREL14R: case R_PARISC_DPREL14F: - case R_PARISC_TLS_GD21L: - case R_PARISC_TLS_LDM21L: - case R_PARISC_TLS_IE21L: /* Convert instructions that use the linkage table pointer (r19) to instructions that use the global data pointer (dp). This is the most efficient way of using PIC code in an incomplete executable, but the user must follow the standard runtime conventions for accessing data for this to work. */ - if (orig_r_type == R_PARISC_DLTIND21L - || (!info->shared - && (r_type == R_PARISC_TLS_GD21L - || r_type == R_PARISC_TLS_LDM21L - || r_type == R_PARISC_TLS_IE21L))) + if (orig_r_type != r_type) { - /* Convert addil instructions if the original reloc was a - DLTIND21L. 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)) - insn = ADDIL_DP; - else - /* We must have a ldil instruction. It's too hard to find - and convert the associated add instruction, so issue an - error. */ - (*_bfd_error_handler) - (_("%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"), - input_bfd, - input_section, - (long) offset, - howto->name, - insn); - } - else if (orig_r_type == R_PARISC_DLTIND14F) - { - /* This must be a format 1 load/store. Change the base - register to dp. */ - insn = (insn & 0xfc1ffff) | (27 << 21); + if (r_type == R_PARISC_DPREL21L) + { + /* 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)) + insn = ADDIL_DP; + else + /* We must have a ldil instruction. It's too hard to find + and convert the associated add instruction, so issue an + error. */ + (*_bfd_error_handler) + (_("%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"), + input_bfd, + input_section, + (long) offset, + howto->name, + insn); + } + else if (r_type == R_PARISC_DPREL14F) + { + /* This must be a format 1 load/store. Change the base + register to dp. */ + insn = (insn & 0xfc1ffff) | (27 << 21); + } } - /* For all the DP relative relocations, we need to examine the symbol's - section. If it has no section or if it's a code section, then - "data pointer relative" makes no sense. In that case we don't - adjust the "value", and for 21 bit addil instructions, we change the - source addend register from %dp to %r0. This situation commonly - arises for undefined weak symbols and when a variable's "constness" - is declared differently from the way the variable is defined. For - instance: "extern int foo" with foo defined as "const int foo". */ + /* For all the DP relative relocations, we need to examine the symbol's + section. If it has no section or if it's a code section, then + "data pointer relative" makes no sense. In that case we don't + adjust the "value", and for 21 bit addil instructions, we change the + source addend register from %dp to %r0. This situation commonly + arises for undefined weak symbols and when a variable's "constness" + is declared differently from the way the variable is defined. For + 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))) @@ -3472,6 +3482,9 @@ final_link_relocate (asection *input_section, case R_PARISC_DLTIND21L: case R_PARISC_DLTIND14R: case R_PARISC_DLTIND14F: + case R_PARISC_TLS_GD21L: + case R_PARISC_TLS_LDM21L: + case R_PARISC_TLS_IE21L: case R_PARISC_TLS_GD14R: case R_PARISC_TLS_LDM14R: case R_PARISC_TLS_IE14R: @@ -3728,7 +3741,7 @@ elf32_hppa_relocate_section (bfd *output_bfd, hh = hppa_elf_hash_entry (eh); } - if (sym_sec != NULL && elf_discarded_section (sym_sec)) + if (sym_sec != NULL && discarded_section (sym_sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rela, relend, elf_hppa_howto_table + r_type, diff --git a/bfd/elf32-i370.c b/bfd/elf32-i370.c index 8082927..516511f 100644 --- a/bfd/elf32-i370.c +++ b/bfd/elf32-i370.c @@ -1138,7 +1138,7 @@ i370_elf_relocate_section (bfd *output_bfd, } } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index d518d01..b925ca6 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -3178,7 +3178,7 @@ elf_i386_relocate_section (bfd *output_bfd, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); @@ -4846,7 +4846,7 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd, + PLT_FDE_START_OFFSET); } if (htab->plt_eh_frame->sec_info_type - == ELF_INFO_TYPE_EH_FRAME) + == SEC_INFO_TYPE_EH_FRAME) { if (! _bfd_elf_write_section_eh_frame (output_bfd, info, htab->plt_eh_frame, diff --git a/bfd/elf32-i860.c b/bfd/elf32-i860.c index 00c8ca7..88f4265 100644 --- a/bfd/elf32-i860.c +++ b/bfd/elf32-i860.c @@ -1128,7 +1128,7 @@ elf32_i860_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-ip2k.c b/bfd/elf32-ip2k.c index 0a251b8..43c7b1c 100644 --- a/bfd/elf32-ip2k.c +++ b/bfd/elf32-ip2k.c @@ -1436,7 +1436,7 @@ ip2k_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, name = h->root.root.string; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-iq2000.c b/bfd/elf32-iq2000.c index 63ef3dc..3954616 100644 --- a/bfd/elf32-iq2000.c +++ b/bfd/elf32-iq2000.c @@ -633,7 +633,7 @@ iq2000_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, name = h->root.root.string; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-lm32.c b/bfd/elf32-lm32.c index 07add20..a2b1003 100644 --- a/bfd/elf32-lm32.c +++ b/bfd/elf32-lm32.c @@ -893,7 +893,7 @@ lm32_elf_relocate_section (bfd *output_bfd, name = h->root.root.string; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); @@ -2372,7 +2372,7 @@ lm32_elf_size_dynamic_sections (bfd *output_bfd, /* Don't generate entries for weak symbols. */ if (!h || (h && h->root.type != bfd_link_hash_undefweak)) { - if (!elf_discarded_section (s) && !((bfd_get_section_flags (ibfd, s) & SEC_ALLOC) == 0)) + if (!discarded_section (s) && !((bfd_get_section_flags (ibfd, s) & SEC_ALLOC) == 0)) { switch (ELF32_R_TYPE (internal_relocs->r_info)) { @@ -2394,7 +2394,7 @@ lm32_elf_size_dynamic_sections (bfd *output_bfd, if (!strcmp (current->name, h->root.root.string)) break; } - if (!current && !elf_discarded_section (s) && (bfd_get_section_flags (ibfd, s) & SEC_ALLOC)) + if (!current && !discarded_section (s) && (bfd_get_section_flags (ibfd, s) & SEC_ALLOC)) { /* Will this have an entry in the GOT. */ if (ELF32_R_TYPE (internal_relocs->r_info) == R_LM32_16_GOT) diff --git a/bfd/elf32-m32c.c b/bfd/elf32-m32c.c index cf7ad99..bcdb55d 100644 --- a/bfd/elf32-m32c.c +++ b/bfd/elf32-m32c.c @@ -434,7 +434,7 @@ m32c_elf_relocate_section } } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c index 51ef61e..b151a8a 100644 --- a/bfd/elf32-m32r.c +++ b/bfd/elf32-m32r.c @@ -2616,7 +2616,7 @@ m32r_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, } } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c index 961dce4..4b9a1c0 100644 --- a/bfd/elf32-m68hc1x.c +++ b/bfd/elf32-m68hc1x.c @@ -970,7 +970,7 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, is_far = (h && (h->other & STO_M68HC12_FAR)); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index 612525c..518a41a 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -2816,6 +2816,11 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) case R_68K_8: case R_68K_16: case R_68K_32: + /* We don't need to handle relocs into sections not going into + the "real" output. */ + if ((sec->flags & SEC_ALLOC) == 0) + break; + if (h != NULL) { /* Make sure a plt entry is created for this symbol if it @@ -2829,8 +2834,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) /* If we are creating a shared library, we need to copy the reloc into the shared library. */ - if (info->shared - && (sec->flags & SEC_ALLOC) != 0) + if (info->shared) { /* When creating a shared object, we must copy these reloc types into the output file. We create a reloc @@ -3713,7 +3717,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-mcore.c b/bfd/elf32-mcore.c index 31cc095..02aef53 100644 --- a/bfd/elf32-mcore.c +++ b/bfd/elf32-mcore.c @@ -466,7 +466,7 @@ mcore_elf_relocate_section (bfd * output_bfd, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-mep.c b/bfd/elf32-mep.c index 6fecb25..e5104b3 100644 --- a/bfd/elf32-mep.c +++ b/bfd/elf32-mep.c @@ -500,7 +500,7 @@ mep_elf_relocate_section name = h->root.root.string; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index fd3d4ba..61e8b45 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -830,6 +830,111 @@ static reloc_howto_type elf_mips16_howto_table_rel[] = 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* MIPS16 TLS general dynamic variable reference. */ + HOWTO (R_MIPS16_TLS_GD, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_GD", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic variable reference. */ + HOWTO (R_MIPS16_TLS_LDM, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_LDM", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic offset. */ + HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_DTPREL_HI16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic offset. */ + HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_DTPREL_LO16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_GOTTPREL", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_TPREL_HI16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_TPREL_LO16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ }; static reloc_howto_type elf_micromips_howto_table_rel[] = @@ -1796,6 +1901,15 @@ static const struct elf_reloc_map mips16_reloc_map[] = { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min }, { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min }, { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_DTPREL_HI16, + R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_DTPREL_LO16, + R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min } }; static const struct elf_reloc_map micromips_reloc_map[] = diff --git a/bfd/elf32-moxie.c b/bfd/elf32-moxie.c index 8463599..c340826 100644 --- a/bfd/elf32-moxie.c +++ b/bfd/elf32-moxie.c @@ -250,7 +250,7 @@ moxie_elf_relocate_section (bfd *output_bfd, name = h->root.root.string; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-msp430.c b/bfd/elf32-msp430.c index 9a5fb2a..2fa70d9 100644 --- a/bfd/elf32-msp430.c +++ b/bfd/elf32-msp430.c @@ -454,7 +454,7 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-mt.c b/bfd/elf32-mt.c index 1be5d00..b87995e 100644 --- a/bfd/elf32-mt.c +++ b/bfd/elf32-mt.c @@ -354,7 +354,7 @@ mt_elf_relocate_section name = h->root.root.string; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-openrisc.c b/bfd/elf32-openrisc.c index ada738e..e441f4d 100644 --- a/bfd/elf32-openrisc.c +++ b/bfd/elf32-openrisc.c @@ -373,7 +373,7 @@ openrisc_elf_relocate_section (bfd *output_bfd, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 0c25c3e..d3925af 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -2987,10 +2987,6 @@ ppc_elf_copy_indirect_symbol (struct bfd_link_info *info, edir->elf.needs_plt |= eind->elf.needs_plt; edir->elf.pointer_equality_needed |= eind->elf.pointer_equality_needed; - /* If we were called to copy over info for a weak sym, that's all. */ - if (eind->elf.root.type != bfd_link_hash_indirect) - return; - if (eind->dyn_relocs != NULL) { if (edir->dyn_relocs != NULL) @@ -3022,6 +3018,16 @@ ppc_elf_copy_indirect_symbol (struct bfd_link_info *info, eind->dyn_relocs = NULL; } + /* If we were called to copy over info for a weak sym, that's all. + You might think dyn_relocs need not be copied over; After all, + both syms will be dynamic or both non-dynamic so we're just + moving reloc accounting around. However, ELIMINATE_COPY_RELOCS + code in ppc_elf_adjust_dynamic_symbol needs to check for + dyn_relocs in read-only sections, and it does so on what is the + DIR sym here. */ + if (eind->elf.root.type != bfd_link_hash_indirect) + return; + /* Copy over the GOT refcount entries that we may have already seen to the symbol which just became indirect. */ edir->elf.got.refcount += eind->elf.got.refcount; @@ -6225,7 +6231,7 @@ ppc_elf_relax_section (bfd *abfd, attribute for a code section, and we are only looking at branches. However, implement it correctly here as a reference for other target relax_section functions. */ - if (0 && tsec->sec_info_type == ELF_INFO_TYPE_MERGE) + if (0 && tsec->sec_info_type == SEC_INFO_TYPE_MERGE) { /* At this stage in linking, no SEC_MERGE symbol has been adjusted, so all references to such symbols need to be @@ -6880,7 +6886,7 @@ ppc_elf_relocate_section (bfd *output_bfd, sym_name = h->root.root.string; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) { /* For relocs against symbols from removed linkonce sections, or sections discarded by a linker script, we just want the @@ -9048,7 +9054,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd, BFD_ASSERT ((bfd_vma) ((p + 3 - htab->glink_eh_frame->contents) & -4) == htab->glink_eh_frame->size); - if (htab->glink_eh_frame->sec_info_type == ELF_INFO_TYPE_EH_FRAME + if (htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME && !_bfd_elf_write_section_eh_frame (output_bfd, info, htab->glink_eh_frame, htab->glink_eh_frame->contents)) diff --git a/bfd/elf32-rx.c b/bfd/elf32-rx.c index f049f6e..32820b4 100644 --- a/bfd/elf32-rx.c +++ b/bfd/elf32-rx.c @@ -510,7 +510,7 @@ rx_elf_relocate_section name = h->root.root.string; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); @@ -1588,7 +1588,7 @@ rx_offset_for_reloc (bfd * abfd, if (ssec) { if ((ssec->flags & SEC_MERGE) - && ssec->sec_info_type == ELF_INFO_TYPE_MERGE) + && ssec->sec_info_type == SEC_INFO_TYPE_MERGE) symval = _bfd_merged_section_offset (abfd, & ssec, elf_section_data (ssec)->sec_info, symval); diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index 98437d0..11fb072 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -2282,7 +2282,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-score.c b/bfd/elf32-score.c index b437624..ef849aa 100644 --- a/bfd/elf32-score.c +++ b/bfd/elf32-score.c @@ -2672,7 +2672,7 @@ s3_bfd_score_elf_relocate_section (bfd *output_bfd, } } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-score7.c b/bfd/elf32-score7.c index 3e98bfc..3d228f3 100644 --- a/bfd/elf32-score7.c +++ b/bfd/elf32-score7.c @@ -2443,7 +2443,7 @@ s7_bfd_score_elf_relocate_section (bfd *output_bfd, } } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index ca2c4af..e56c3b5 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -4048,7 +4048,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, _("Unexpected STO_SH5_ISA32 on local symbol is not handled"), input_bfd, input_section, rel->r_offset)); - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) /* Handled below. */ ; else if (info->relocatable) @@ -4236,7 +4236,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, } } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c index ae3ed10..40a9da2 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -4895,7 +4895,7 @@ spu_elf_relocate_section (bfd *output_bfd, sym_name = h->root.root.string; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-tic6x.c b/bfd/elf32-tic6x.c index 19287fe..a879d3c 100644 --- a/bfd/elf32-tic6x.c +++ b/bfd/elf32-tic6x.c @@ -2334,7 +2334,7 @@ elf32_tic6x_relocate_section (bfd *output_bfd, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); @@ -4018,6 +4018,9 @@ elf32_tic6x_merge_private_bfd_data (bfd *ibfd, bfd *obfd) if (!_bfd_generic_verify_endian_match (ibfd, obfd)) return FALSE; + if (! is_tic6x_elf (ibfd) || ! is_tic6x_elf (obfd)) + return TRUE; + if (!elf32_tic6x_merge_attributes (ibfd, obfd)) return FALSE; diff --git a/bfd/elf32-tilepro.c b/bfd/elf32-tilepro.c index f2aed9c..a4e565d 100644 --- a/bfd/elf32-tilepro.c +++ b/bfd/elf32-tilepro.c @@ -2594,7 +2594,7 @@ tilepro_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, } } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c index 9e6f77d..0fbe080 100644 --- a/bfd/elf32-v850.c +++ b/bfd/elf32-v850.c @@ -2093,7 +2093,7 @@ v850_elf_relocate_section (bfd *output_bfd, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c index 643381c..fc3cb7c 100644 --- a/bfd/elf32-vax.c +++ b/bfd/elf32-vax.c @@ -1450,7 +1450,7 @@ elf_vax_relocate_section (bfd *output_bfd, relocation = 0; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-xc16x.c b/bfd/elf32-xc16x.c index 11d9840..00c7841 100644 --- a/bfd/elf32-xc16x.c +++ b/bfd/elf32-xc16x.c @@ -381,7 +381,7 @@ elf32_xc16x_relocate_section (bfd *output_bfd, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) { /* For relocs against symbols from removed linkonce sections, or sections discarded by a linker script, we just want the diff --git a/bfd/elf32-xstormy16.c b/bfd/elf32-xstormy16.c index 6141783..86e1d5b 100644 --- a/bfd/elf32-xstormy16.c +++ b/bfd/elf32-xstormy16.c @@ -825,7 +825,7 @@ xstormy16_elf_relocate_section (bfd * output_bfd ATTRIBUTE_UNU unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index c6e4fb4..5a51eae 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -1712,7 +1712,7 @@ elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, continue; for (s = abfd->sections; s != NULL; s = s->next) { - if (! elf_discarded_section (s) + if (! discarded_section (s) && xtensa_is_littable_section (s) && s != spltlittbl) sgotloc->size += s->size; @@ -2656,7 +2656,7 @@ elf_xtensa_relocate_section (bfd *output_bfd, sym_type = h->type; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); @@ -8960,9 +8960,9 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) that here and adjust things accordingly. */ if (! elf_xtensa_ignore_discarded_relocs (sec) && elf_xtensa_action_discarded (sec) == PRETEND - && sec->sec_info_type != ELF_INFO_TYPE_STABS + && sec->sec_info_type != SEC_INFO_TYPE_STABS && target_sec != NULL - && elf_discarded_section (target_sec)) + && discarded_section (target_sec)) { /* It would be natural to call _bfd_elf_check_kept_section here, but it's not exported from elflink.c. It's also a diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 6076709..ddb1cd7 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -4106,7 +4106,7 @@ elf64_alpha_relocate_section_r (bfd *output_bfd ATTRIBUTE_UNUSED, sec = h->root.u.def.section; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, elf64_alpha_howto_table + r_type, @@ -4263,7 +4263,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, unless it has been done already. */ if ((sec->flags & SEC_MERGE) && ELF_ST_TYPE (sym->st_info) == STT_SECTION - && sec->sec_info_type == ELF_INFO_TYPE_MERGE + && sec->sec_info_type == SEC_INFO_TYPE_MERGE && gotent && !gotent->reloc_xlated) { @@ -4315,7 +4315,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, gotent = h->got_entries; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); @@ -4717,7 +4717,7 @@ elf64_alpha_relocate_section (bfd *output_bfd, struct bfd_link_info *info, if (r_symndx < symtab_hdr->sh_info && sec != NULL && howto->pc_relative - && elf_discarded_section (sec)) + && discarded_section (sec)) break; if (h != NULL) diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c index 057a92d..9d2dfcf 100644 --- a/bfd/elf64-hppa.c +++ b/bfd/elf64-hppa.c @@ -3919,7 +3919,7 @@ elf64_hppa_relocate_section (bfd *output_bfd, } } - if (sym_sec != NULL && elf_discarded_section (sym_sec)) + if (sym_sec != NULL && discarded_section (sym_sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c index 3feb1bb..bdd0c19 100644 --- a/bfd/elf64-mips.c +++ b/bfd/elf64-mips.c @@ -1590,6 +1590,111 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] = 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* MIPS16 TLS general dynamic variable reference. */ + HOWTO (R_MIPS16_TLS_GD, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_GD", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic variable reference. */ + HOWTO (R_MIPS16_TLS_LDM, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_LDM", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic offset. */ + HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_DTPREL_HI16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic offset. */ + HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_DTPREL_LO16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_GOTTPREL", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_TPREL_HI16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_TPREL_LO16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ }; static reloc_howto_type mips16_elf64_howto_table_rela[] = @@ -1686,6 +1791,111 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] = 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* MIPS16 TLS general dynamic variable reference. */ + HOWTO (R_MIPS16_TLS_GD, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_GD", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic variable reference. */ + HOWTO (R_MIPS16_TLS_LDM, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_LDM", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic offset. */ + HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_DTPREL_HI16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic offset. */ + HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_DTPREL_LO16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_GOTTPREL", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_TPREL_HI16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_TPREL_LO16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ }; static reloc_howto_type micromips_elf64_howto_table_rel[] = @@ -2908,6 +3118,15 @@ static const struct elf_reloc_map mips16_reloc_map[] = { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min }, { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min }, { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_DTPREL_HI16, + R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_DTPREL_LO16, + R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min } }; static const struct elf_reloc_map micromips_reloc_map[] = diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c index ecc9ad0..9cc407f 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -1475,7 +1475,7 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section, name = h->root.root.string; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 93d1314..52e9ce9 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -4435,10 +4435,6 @@ ppc64_elf_copy_indirect_symbol (struct bfd_link_info *info, edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak; edir->elf.needs_plt |= eind->elf.needs_plt; - /* If we were called to copy over info for a weak sym, that's all. */ - if (eind->elf.root.type != bfd_link_hash_indirect) - return; - /* Copy over any dynamic relocs we may have on the indirect sym. */ if (eind->dyn_relocs != NULL) { @@ -4471,6 +4467,16 @@ ppc64_elf_copy_indirect_symbol (struct bfd_link_info *info, eind->dyn_relocs = NULL; } + /* If we were called to copy over info for a weak sym, that's all. + You might think dyn_relocs need not be copied over; After all, + both syms will be dynamic or both non-dynamic so we're just + moving reloc accounting around. However, ELIMINATE_COPY_RELOCS + code in ppc64_elf_adjust_dynamic_symbol needs to check for + dyn_relocs in read-only sections, and it does so on what is the + DIR sym here. */ + if (eind->elf.root.type != bfd_link_hash_indirect) + return; + /* Copy over got entries that we may have already seen to the symbol which just became indirect. */ if (eind->elf.got.glist != NULL) @@ -6846,7 +6852,7 @@ adjust_opd_syms (struct elf_link_hash_entry *h, void *inf ATTRIBUTE_UNUSED) if (dsec == NULL) { for (dsec = sym_sec->owner->sections; dsec; dsec = dsec->next) - if (elf_discarded_section (dsec)) + if (discarded_section (dsec)) { ppc64_elf_tdata (sym_sec->owner)->deleted_section = dsec; break; @@ -7027,7 +7033,7 @@ ppc64_elf_edit_opd (struct bfd_link_info *info, bfd_boolean non_overlapping) if (sec == NULL || sec->size == 0) continue; - if (sec->sec_info_type == ELF_INFO_TYPE_JUST_SYMS) + if (sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) continue; if (sec->output_section == bfd_abs_section_ptr) @@ -8071,8 +8077,8 @@ ppc64_elf_edit_toc (struct bfd_link_info *info) toc = bfd_get_section_by_name (ibfd, ".toc"); if (toc == NULL || toc->size == 0 - || toc->sec_info_type == ELF_INFO_TYPE_JUST_SYMS - || elf_discarded_section (toc)) + || toc->sec_info_type == SEC_INFO_TYPE_JUST_SYMS + || discarded_section (toc)) continue; toc_relocs = NULL; @@ -8085,7 +8091,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info) for (sec = ibfd->sections; sec != NULL; sec = sec->next) { if (sec->reloc_count == 0 - || !elf_discarded_section (sec) + || !discarded_section (sec) || get_opd_info (sec) || (sec->flags & SEC_ALLOC) == 0 || (sec->flags & SEC_DEBUGGING) != 0) @@ -8195,7 +8201,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info) goto error_ret; if (sym_sec == NULL - || elf_discarded_section (sym_sec)) + || discarded_section (sym_sec)) continue; if (!SYMBOL_CALLS_LOCAL (info, h)) @@ -8275,7 +8281,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info) int repeat; if (sec->reloc_count == 0 - || elf_discarded_section (sec) + || discarded_section (sec) || get_opd_info (sec) || (sec->flags & SEC_ALLOC) == 0 || (sec->flags & SEC_DEBUGGING) != 0) @@ -8497,7 +8503,7 @@ ppc64_elf_edit_toc (struct bfd_link_info *info) for (sec = ibfd->sections; sec != NULL; sec = sec->next) { if (sec->reloc_count == 0 - || elf_discarded_section (sec)) + || discarded_section (sec)) continue; relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL, @@ -12030,7 +12036,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, } h = (struct ppc_link_hash_entry *) h_elf; - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, ppc64_elf_howto_table[r_type], @@ -13859,7 +13865,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd, if (htab->glink_eh_frame != NULL - && htab->glink_eh_frame->sec_info_type == ELF_INFO_TYPE_EH_FRAME + && htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME && !_bfd_elf_write_section_eh_frame (output_bfd, info, htab->glink_eh_frame, htab->glink_eh_frame->contents)) diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 9884da0..e9138a6 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -2270,7 +2270,7 @@ elf_s390_relocate_section (bfd *output_bfd, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c index bbef2a2..d8f2120 100644 --- a/bfd/elf64-sh64.c +++ b/bfd/elf64-sh64.c @@ -1514,7 +1514,7 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, _("Unexpected STO_SH5_ISA32 on local symbol is not handled"), input_bfd, input_section, rel->r_offset)); - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) /* Handled below. */ ; else if (info->relocatable) @@ -1657,7 +1657,7 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, } } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 3a2444b..9d826e7 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -3062,7 +3062,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, unresolved_reloc, warned); } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); @@ -3460,7 +3460,6 @@ elf_x86_64_relocate_section (bfd *output_bfd, case R_X86_64_PC16: case R_X86_64_PC32: if (info->shared - && ABI_64_P (output_bfd) && (input_section->flags & SEC_ALLOC) != 0 && (input_section->flags & SEC_READONLY) != 0 && h != NULL) @@ -4626,7 +4625,7 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd, + PLT_FDE_START_OFFSET); } if (htab->plt_eh_frame->sec_info_type - == ELF_INFO_TYPE_EH_FRAME) + == SEC_INFO_TYPE_EH_FRAME) { if (! _bfd_elf_write_section_eh_frame (output_bfd, info, htab->plt_eh_frame, diff --git a/bfd/elflink.c b/bfd/elflink.c index fc4266b..da6be48 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -1,6 +1,6 @@ /* ELF linking support for BFD. Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009, 2010, 2011 + 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -937,7 +937,7 @@ _bfd_elf_merge_symbol (bfd *abfd, /* Silently discard TLS symbols from --just-syms. There's no way to combine a static TLS block with a new TLS block for this executable. */ if (ELF_ST_TYPE (sym->st_info) == STT_TLS - && sec->sec_info_type == ELF_INFO_TYPE_JUST_SYMS) + && sec->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) { *skip = TRUE; return TRUE; @@ -2708,7 +2708,7 @@ _bfd_elf_link_sec_merge_syms (struct elf_link_hash_entry *h, void *data) if ((h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) && ((sec = h->root.u.def.section)->flags & SEC_MERGE) - && sec->sec_info_type == ELF_INFO_TYPE_MERGE) + && sec->sec_info_type == SEC_INFO_TYPE_MERGE) { bfd *output_bfd = (bfd *) data; @@ -3499,7 +3499,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) /* ld --just-symbols and dynamic objects don't mix very well. ld shouldn't allow it. */ if ((s = abfd->sections) != NULL - && s->sec_info_type == ELF_INFO_TYPE_JUST_SYMS) + && s->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) abort (); /* If this dynamic lib was specified on the command line with @@ -3896,7 +3896,7 @@ error_free_dyn: sec = bfd_section_from_elf_index (abfd, isym->st_shndx); if (sec == NULL) sec = bfd_abs_section_ptr; - else if (elf_discarded_section (sec)) + else if (discarded_section (sec)) { /* Symbols from discarded section are undefined. We keep its visibility. */ @@ -4861,7 +4861,7 @@ error_free_dyn: &string_offset)) goto error_return; if (secdata->sec_info) - stab->sec_info_type = ELF_INFO_TYPE_STABS; + stab->sec_info_type = SEC_INFO_TYPE_STABS; } } } @@ -6644,25 +6644,14 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) return TRUE; } -/* Indicate that we are only retrieving symbol values from this - section. */ - -void -_bfd_elf_link_just_syms (asection *sec, struct bfd_link_info *info) -{ - if (is_elf_hash_table (info->hash)) - sec->sec_info_type = ELF_INFO_TYPE_JUST_SYMS; - _bfd_generic_link_just_syms (sec, info); -} - /* Make sure sec_info_type is cleared if sec_info is cleared too. */ static void merge_sections_remove_hook (bfd *abfd ATTRIBUTE_UNUSED, asection *sec) { - BFD_ASSERT (sec->sec_info_type == ELF_INFO_TYPE_MERGE); - sec->sec_info_type = ELF_INFO_TYPE_NONE; + BFD_ASSERT (sec->sec_info_type == SEC_INFO_TYPE_MERGE); + sec->sec_info_type = SEC_INFO_TYPE_NONE; } /* Finish SHF_MERGE section merging. */ @@ -6690,7 +6679,7 @@ _bfd_elf_merge_sections (bfd *abfd, struct bfd_link_info *info) sec, &secdata->sec_info)) return FALSE; else if (secdata->sec_info) - sec->sec_info_type = ELF_INFO_TYPE_MERGE; + sec->sec_info_type = SEC_INFO_TYPE_MERGE; } if (elf_hash_table (info)->merge_info != NULL) @@ -8708,7 +8697,7 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) else if ((h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) && ((finfo->info->strip_discarded - && elf_discarded_section (h->root.u.def.section)) + && discarded_section (h->root.u.def.section)) || (h->root.u.def.section->owner != NULL && (h->root.u.def.section->owner->flags & BFD_PLUGIN) != 0))) strip = TRUE; @@ -9007,8 +8996,8 @@ elf_section_ignore_discarded_relocs (asection *sec) switch (sec->sec_info_type) { - case ELF_INFO_TYPE_STABS: - case ELF_INFO_TYPE_EH_FRAME: + case SEC_INFO_TYPE_STABS: + case SEC_INFO_TYPE_EH_FRAME: return TRUE; default: break; @@ -9193,7 +9182,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) *ppsection = NULL; continue; } - else if (isec->sec_info_type == ELF_INFO_TYPE_MERGE + else if (isec->sec_info_type == SEC_INFO_TYPE_MERGE && ELF_ST_TYPE (isym->st_info) != STT_SECTION) isym->st_value = _bfd_merged_section_offset (output_bfd, &isec, @@ -9537,7 +9526,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) { /* Complain if the definition comes from a discarded section. */ - if ((sec = *ps) != NULL && elf_discarded_section (sec)) + if ((sec = *ps) != NULL && discarded_section (sec)) { BFD_ASSERT (r_symndx != STN_UNDEF); if (action_discarded & COMPLAIN) @@ -9874,19 +9863,19 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) } else switch (o->sec_info_type) { - case ELF_INFO_TYPE_STABS: + case SEC_INFO_TYPE_STABS: if (! (_bfd_write_section_stabs (output_bfd, &elf_hash_table (finfo->info)->stab_info, o, &elf_section_data (o)->sec_info, contents))) return FALSE; break; - case ELF_INFO_TYPE_MERGE: + case SEC_INFO_TYPE_MERGE: if (! _bfd_write_merged_section (output_bfd, o, elf_section_data (o)->sec_info)) return FALSE; break; - case ELF_INFO_TYPE_EH_FRAME: + case SEC_INFO_TYPE_EH_FRAME: { if (! _bfd_elf_write_section_eh_frame (output_bfd, finfo->info, o, contents)) @@ -11188,15 +11177,12 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) goto error_return; /* Check for DT_TEXTREL (late, in case the backend removes it). */ - if ((info->warn_shared_textrel && info->shared) - || info->error_textrel) + if (((info->warn_shared_textrel && info->shared) + || info->error_textrel) + && (o = bfd_get_section_by_name (dynobj, ".dynamic")) != NULL) { bfd_byte *dyncon, *dynconend; - /* Fix up .dynamic entries. */ - o = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (o != NULL); - dyncon = o->contents; dynconend = o->contents + o->size; for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn) @@ -12418,7 +12404,7 @@ bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie) if ((h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) - && elf_discarded_section (h->root.u.def.section)) + && discarded_section (h->root.u.def.section)) return TRUE; else return FALSE; @@ -12434,7 +12420,7 @@ bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie) /* Need to: get the symbol; get the section. */ isym = &rcookie->locsyms[r_symndx]; isec = bfd_section_from_elf_index (rcookie->abfd, isym->st_shndx); - if (isec != NULL && elf_discarded_section (isec)) + if (isec != NULL && discarded_section (isec)) return TRUE; } return FALSE; @@ -12485,7 +12471,7 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) if (stab != NULL && (stab->size == 0 || bfd_is_abs_section (stab->output_section) - || stab->sec_info_type != ELF_INFO_TYPE_STABS)) + || stab->sec_info_type != SEC_INFO_TYPE_STABS)) stab = NULL; if (stab == NULL diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c index 00ec8b0..2189566 100644 --- a/bfd/elfn32-mips.c +++ b/bfd/elfn32-mips.c @@ -1555,6 +1555,111 @@ static reloc_howto_type elf_mips16_howto_table_rel[] = 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* MIPS16 TLS general dynamic variable reference. */ + HOWTO (R_MIPS16_TLS_GD, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_GD", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic variable reference. */ + HOWTO (R_MIPS16_TLS_LDM, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_LDM", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic offset. */ + HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_DTPREL_HI16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic offset. */ + HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_DTPREL_LO16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_GOTTPREL", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_TPREL_HI16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_TPREL_LO16", /* name */ + TRUE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ }; static reloc_howto_type elf_mips16_howto_table_rela[] = @@ -1651,6 +1756,111 @@ static reloc_howto_type elf_mips16_howto_table_rela[] = 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* MIPS16 TLS general dynamic variable reference. */ + HOWTO (R_MIPS16_TLS_GD, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_GD", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic variable reference. */ + HOWTO (R_MIPS16_TLS_LDM, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_LDM", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic offset. */ + HOWTO (R_MIPS16_TLS_DTPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_DTPREL_HI16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS local dynamic offset. */ + HOWTO (R_MIPS16_TLS_DTPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_DTPREL_LO16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_GOTTPREL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_GOTTPREL", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_TPREL_HI16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_TPREL_HI16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + + /* MIPS16 TLS thread pointer offset. */ + HOWTO (R_MIPS16_TLS_TPREL_LO16, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS16_TLS_TPREL_LO16", /* name */ + FALSE, /* partial_inplace */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ + FALSE), /* pcrel_offset */ }; static reloc_howto_type elf_micromips_howto_table_rel[] = @@ -2724,6 +2934,15 @@ static const struct elf_reloc_map mips16_reloc_map[] = { BFD_RELOC_MIPS16_CALL16, R_MIPS16_CALL16 - R_MIPS16_min }, { BFD_RELOC_MIPS16_HI16_S, R_MIPS16_HI16 - R_MIPS16_min }, { BFD_RELOC_MIPS16_LO16, R_MIPS16_LO16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_GD, R_MIPS16_TLS_GD - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_LDM, R_MIPS16_TLS_LDM - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_DTPREL_HI16, + R_MIPS16_TLS_DTPREL_HI16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_DTPREL_LO16, + R_MIPS16_TLS_DTPREL_LO16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_GOTTPREL, R_MIPS16_TLS_GOTTPREL - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_TPREL_HI16, R_MIPS16_TLS_TPREL_HI16 - R_MIPS16_min }, + { BFD_RELOC_MIPS16_TLS_TPREL_LO16, R_MIPS16_TLS_TPREL_LO16 - R_MIPS16_min } }; static const struct elf_reloc_map micromips_reloc_map[] = diff --git a/bfd/elfnn-ia64.c b/bfd/elfnn-ia64.c index 3e2ee0b..0f6b720 100644 --- a/bfd/elfnn-ia64.c +++ b/bfd/elfnn-ia64.c @@ -530,7 +530,7 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec, symtype = h->type; } - if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE) + if (tsec->sec_info_type == SEC_INFO_TYPE_MERGE) { /* At this stage in linking, no SEC_MERGE symbol has been adjusted, so all references to such symbols need to be @@ -3861,7 +3861,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd, if (!info->relocatable && (sym_sec->flags & SEC_MERGE) != 0 && ELF_ST_TYPE (sym->st_info) == STT_SECTION - && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE) + && sym_sec->sec_info_type == SEC_INFO_TYPE_MERGE) { struct elfNN_ia64_local_hash_entry *loc_h; @@ -3919,7 +3919,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd, continue; } - if (sym_sec != NULL && elf_discarded_section (sym_sec)) + if (sym_sec != NULL && discarded_section (sym_sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 33a454d..7911050 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -436,8 +436,8 @@ struct mips_elf_link_hash_table entry is set to the address of __rld_obj_head as in IRIX5. */ bfd_boolean use_rld_obj_head; - /* This is the value of the __rld_map or __rld_obj_head symbol. */ - bfd_vma rld_value; + /* The __rld_map or __rld_obj_head symbol. */ + struct elf_link_hash_entry *rld_symbol; /* This is set if we see any mips16 stub sections. */ bfd_boolean mips16_stubs_seen; @@ -529,6 +529,13 @@ struct mips_htab_traverse_info || r_type == R_MIPS_TLS_TPREL64 \ || r_type == R_MIPS_TLS_TPREL_HI16 \ || r_type == R_MIPS_TLS_TPREL_LO16 \ + || r_type == R_MIPS16_TLS_GD \ + || r_type == R_MIPS16_TLS_LDM \ + || r_type == R_MIPS16_TLS_DTPREL_HI16 \ + || r_type == R_MIPS16_TLS_DTPREL_LO16 \ + || r_type == R_MIPS16_TLS_GOTTPREL \ + || r_type == R_MIPS16_TLS_TPREL_HI16 \ + || r_type == R_MIPS16_TLS_TPREL_LO16 \ || r_type == R_MICROMIPS_TLS_GD \ || r_type == R_MICROMIPS_TLS_LDM \ || r_type == R_MICROMIPS_TLS_DTPREL_HI16 \ @@ -768,6 +775,10 @@ static bfd *reldyn_sorting_bfd; #define MIPS_ELF_GOT_SIZE(abfd) \ (get_elf_backend_data (abfd)->s->arch_size / 8) +/* The size of the .rld_map section. */ +#define MIPS_ELF_RLD_MAP_SIZE(abfd) \ + (get_elf_backend_data (abfd)->s->arch_size / 8) + /* The size of a symbol-table entry. */ #define MIPS_ELF_SYM_SIZE(abfd) \ (get_elf_backend_data (abfd)->s->sizeof_sym) @@ -1571,9 +1582,10 @@ _bfd_mips_elf_init_stubs (struct bfd_link_info *info, } /* Return true if H is a locally-defined PIC function, in the sense - that it might need $25 to be valid on entry. Note that MIPS16 - functions never need $25 to be valid on entry; they set up $gp - using PC-relative instructions instead. */ + that it or its fn_stub might need $25 to be valid on entry. + Note that MIPS16 functions set up $gp using PC-relative instructions, + so they themselves never need $25 to be valid. Only non-MIPS16 + entry points are of interest here. */ static bfd_boolean mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h) @@ -1582,11 +1594,32 @@ mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h) || h->root.root.type == bfd_link_hash_defweak) && h->root.def_regular && !bfd_is_abs_section (h->root.root.u.def.section) - && !ELF_ST_IS_MIPS16 (h->root.other) + && (!ELF_ST_IS_MIPS16 (h->root.other) + || (h->fn_stub && h->need_fn_stub)) && (PIC_OBJECT_P (h->root.root.u.def.section->owner) || ELF_ST_IS_MIPS_PIC (h->root.other))); } +/* Set *SEC to the input section that contains the target of STUB. + Return the offset of the target from the start of that section. */ + +static bfd_vma +mips_elf_get_la25_target (struct mips_elf_la25_stub *stub, + asection **sec) +{ + if (ELF_ST_IS_MIPS16 (stub->h->root.other)) + { + BFD_ASSERT (stub->h->need_fn_stub); + *sec = stub->h->fn_stub; + return 0; + } + else + { + *sec = stub->h->root.root.u.def.section; + return stub->h->root.root.u.def.value; + } +} + /* STUB describes an la25 stub that we have decided to implement by inserting an LUI/ADDIU pair before the target function. Create the section and redirect the function symbol to it. */ @@ -1611,7 +1644,7 @@ mips_elf_add_la25_intro (struct mips_elf_la25_stub *stub, sprintf (name, ".text.stub.%d", (int) htab_elements (htab->la25_stubs)); /* Create the section. */ - input_section = stub->h->root.root.u.def.section; + mips_elf_get_la25_target (stub, &input_section); s = htab->add_stub_section (name, input_section, input_section->output_section); if (s == NULL) @@ -1685,12 +1718,6 @@ mips_elf_add_la25_stub (struct bfd_link_info *info, bfd_vma value; void **slot; - /* Prefer to use LUI/ADDIU stubs if the function is at the beginning - of the section and if we would need no more than 2 nops. */ - s = h->root.root.u.def.section; - value = h->root.root.u.def.value; - use_trampoline_p = (value != 0 || s->alignment_power > 4); - /* Describe the stub we want. */ search.stub_section = NULL; search.offset = 0; @@ -1720,6 +1747,11 @@ mips_elf_add_la25_stub (struct bfd_link_info *info, *stub = search; *slot = stub; + /* Prefer to use LUI/ADDIU stubs if the function is at the beginning + of the section and if we would need no more than 2 nops. */ + value = mips_elf_get_la25_target (stub, &s); + use_trampoline_p = (value != 0 || s->alignment_power > 4); + h->la25_stub = stub; return (use_trampoline_p ? mips_elf_add_la25_trampoline (stub, info) @@ -1860,6 +1892,13 @@ mips16_reloc_p (int r_type) case R_MIPS16_CALL16: case R_MIPS16_HI16: case R_MIPS16_LO16: + case R_MIPS16_TLS_GD: + case R_MIPS16_TLS_LDM: + case R_MIPS16_TLS_DTPREL_HI16: + case R_MIPS16_TLS_DTPREL_LO16: + case R_MIPS16_TLS_GOTTPREL: + case R_MIPS16_TLS_TPREL_HI16: + case R_MIPS16_TLS_TPREL_LO16: return TRUE; default: @@ -1987,19 +2026,25 @@ micromips_branch_reloc_p (int r_type) static inline bfd_boolean tls_gd_reloc_p (unsigned int r_type) { - return r_type == R_MIPS_TLS_GD || r_type == R_MICROMIPS_TLS_GD; + return (r_type == R_MIPS_TLS_GD + || r_type == R_MIPS16_TLS_GD + || r_type == R_MICROMIPS_TLS_GD); } static inline bfd_boolean tls_ldm_reloc_p (unsigned int r_type) { - return r_type == R_MIPS_TLS_LDM || r_type == R_MICROMIPS_TLS_LDM; + return (r_type == R_MIPS_TLS_LDM + || r_type == R_MIPS16_TLS_LDM + || r_type == R_MICROMIPS_TLS_LDM); } static inline bfd_boolean tls_gottprel_reloc_p (unsigned int r_type) { - return r_type == R_MIPS_TLS_GOTTPREL || r_type == R_MICROMIPS_TLS_GOTTPREL; + return (r_type == R_MIPS_TLS_GOTTPREL + || r_type == R_MIPS16_TLS_GOTTPREL + || r_type == R_MICROMIPS_TLS_GOTTPREL); } void @@ -4907,7 +4952,8 @@ is_gott_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *h) stub. */ static bfd_boolean -mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type) +mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type, + bfd_boolean target_is_16_bit_code_p) { /* We specifically ignore branches and jumps from EF_PIC objects, where the onus is on the compiler or programmer to perform any @@ -4921,7 +4967,6 @@ mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type) { case R_MIPS_26: case R_MIPS_PC16: - case R_MIPS16_26: case R_MICROMIPS_26_S1: case R_MICROMIPS_PC7_S1: case R_MICROMIPS_PC10_S1: @@ -4929,6 +4974,9 @@ mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type) case R_MICROMIPS_PC23_S2: return TRUE; + case R_MIPS16_26: + return !target_is_16_bit_code_p; + default: return FALSE; } @@ -5189,14 +5237,28 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, have already noticed that we were going to need the stub. */ if (local_p) - sec = elf_tdata (input_bfd)->local_stubs[r_symndx]; + { + sec = elf_tdata (input_bfd)->local_stubs[r_symndx]; + value = 0; + } else { BFD_ASSERT (h->need_fn_stub); - sec = h->fn_stub; + if (h->la25_stub) + { + /* If a LA25 header for the stub itself exists, point to the + prepended LUI/ADDIU sequence. */ + sec = h->la25_stub->stub_section; + value = h->la25_stub->offset; + } + else + { + sec = h->fn_stub; + value = 0; + } } - symbol = sec->output_section->vma + sec->output_offset; + symbol = sec->output_section->vma + sec->output_offset + value; /* The target is 16-bit, but the stub isn't. */ target_is_16_bit_code_p = FALSE; } @@ -5246,7 +5308,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, /* If this is a direct call to a PIC function, redirect to the non-PIC stub. */ else if (h != NULL && h->la25_stub - && mips_elf_relocation_needs_la25_stub (input_bfd, r_type)) + && mips_elf_relocation_needs_la25_stub (input_bfd, r_type, + target_is_16_bit_code_p)) symbol = (h->la25_stub->stub_section->output_section->vma + h->la25_stub->stub_section->output_offset + h->la25_stub->offset); @@ -5318,6 +5381,9 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, case R_MIPS_TLS_GD: case R_MIPS_TLS_GOTTPREL: case R_MIPS_TLS_LDM: + case R_MIPS16_TLS_GD: + case R_MIPS16_TLS_GOTTPREL: + case R_MIPS16_TLS_LDM: case R_MICROMIPS_TLS_GD: case R_MICROMIPS_TLS_GOTTPREL: case R_MICROMIPS_TLS_LDM: @@ -5487,6 +5553,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, break; case R_MIPS_TLS_DTPREL_HI16: + case R_MIPS16_TLS_DTPREL_HI16: case R_MICROMIPS_TLS_DTPREL_HI16: value = (mips_elf_high (addend + symbol - dtprel_base (info)) & howto->dst_mask); @@ -5495,17 +5562,22 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, case R_MIPS_TLS_DTPREL_LO16: case R_MIPS_TLS_DTPREL32: case R_MIPS_TLS_DTPREL64: + case R_MIPS16_TLS_DTPREL_LO16: case R_MICROMIPS_TLS_DTPREL_LO16: value = (symbol + addend - dtprel_base (info)) & howto->dst_mask; break; case R_MIPS_TLS_TPREL_HI16: + case R_MIPS16_TLS_TPREL_HI16: case R_MICROMIPS_TLS_TPREL_HI16: value = (mips_elf_high (addend + symbol - tprel_base (info)) & howto->dst_mask); break; case R_MIPS_TLS_TPREL_LO16: + case R_MIPS_TLS_TPREL32: + case R_MIPS_TLS_TPREL64: + case R_MIPS16_TLS_TPREL_LO16: case R_MICROMIPS_TLS_TPREL_LO16: value = (symbol + addend - tprel_base (info)) & howto->dst_mask; break; @@ -5527,10 +5599,11 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, 12: addu $v0,$v1 14: move $gp,$v0 So the offsets of hi and lo relocs are the same, but the - $pc is four higher than $t9 would be, so reduce - both reloc addends by 4. */ + base $pc is that used by the ADDIUPC instruction at $t9 + 4. + ADDIUPC clears the low two bits of the instruction address, + so the base is ($t9 + 4) & ~3. */ if (r_type == R_MIPS16_HI16) - value = mips_elf_high (addend + gp - p - 4); + value = mips_elf_high (addend + gp - ((p + 4) & ~(bfd_vma) 0x3)); /* The microMIPS .cpload sequence uses the same assembly instructions as the traditional psABI version, but the incoming $t9 has the low bit set. */ @@ -5553,7 +5626,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, /* See the comment for R_MIPS16_HI16 above for the reason for this conditional. */ if (r_type == R_MIPS16_LO16) - value = addend + gp - p; + value = addend + gp - (p & ~(bfd_vma) 0x3); else if (r_type == R_MICROMIPS_LO16 || r_type == R_MICROMIPS_HI0_LO16) value = addend + gp - p + 3; @@ -5637,6 +5710,9 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, case R_MIPS_TLS_GOTTPREL: case R_MIPS_TLS_LDM: case R_MIPS_GOT_DISP: + case R_MIPS16_TLS_GD: + case R_MIPS16_TLS_GOTTPREL: + case R_MIPS16_TLS_LDM: case R_MICROMIPS_TLS_GD: case R_MICROMIPS_TLS_GOTTPREL: case R_MICROMIPS_TLS_LDM: @@ -7081,6 +7157,7 @@ _bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, return FALSE; mips_elf_hash_table (info)->use_rld_obj_head = TRUE; + mips_elf_hash_table (info)->rld_symbol = h; } /* If this is a mips16 text symbol, add 1 to the value to make it @@ -7266,6 +7343,7 @@ _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; + mips_elf_hash_table (info)->rld_symbol = h; } } @@ -7767,8 +7845,6 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, can_make_dynamic_p = FALSE; switch (r_type) { - case R_MIPS16_GOT16: - case R_MIPS16_CALL16: case R_MIPS_GOT16: case R_MIPS_CALL16: case R_MIPS_CALL_HI16: @@ -7781,6 +7857,11 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_MIPS_TLS_GOTTPREL: case R_MIPS_TLS_GD: case R_MIPS_TLS_LDM: + case R_MIPS16_GOT16: + case R_MIPS16_CALL16: + case R_MIPS16_TLS_GOTTPREL: + case R_MIPS16_TLS_GD: + case R_MIPS16_TLS_LDM: case R_MICROMIPS_GOT16: case R_MICROMIPS_CALL16: case R_MICROMIPS_CALL_HI16: @@ -7918,7 +7999,9 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, return FALSE; } - if (h != NULL && mips_elf_relocation_needs_la25_stub (abfd, r_type)) + if (h != NULL + && mips_elf_relocation_needs_la25_stub (abfd, r_type, + ELF_ST_IS_MIPS16 (h->other))) ((struct mips_elf_link_hash_entry *) h)->has_nonpic_branches = TRUE; switch (r_type) @@ -8015,12 +8098,14 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, break; case R_MIPS_TLS_GOTTPREL: + case R_MIPS16_TLS_GOTTPREL: case R_MICROMIPS_TLS_GOTTPREL: if (info->shared) info->flags |= DF_STATIC_TLS; /* Fall through */ case R_MIPS_TLS_LDM: + case R_MIPS16_TLS_LDM: case R_MICROMIPS_TLS_LDM: if (tls_ldm_reloc_p (r_type)) { @@ -8030,6 +8115,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, /* Fall through */ case R_MIPS_TLS_GD: + case R_MIPS16_TLS_GD: case R_MICROMIPS_TLS_GD: /* This symbol requires a global offset table entry, or two for TLS GD relocations. */ @@ -9027,7 +9113,7 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd, { /* We add a room for __rld_map. It will be filled in by the rtld to contain a pointer to the _r_debug structure. */ - s->size += 4; + s->size += MIPS_ELF_RLD_MAP_SIZE (output_bfd); } else if (SGI_COMPAT (output_bfd) && CONST_STRNEQ (name, ".compact_rel")) @@ -9299,7 +9385,7 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, sec = h->root.u.def.section; } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); @@ -9615,9 +9701,9 @@ mips_elf_create_la25_stub (void **slot, void *data) offset = stub->offset; /* Work out the target address. */ - target = (stub->h->root.root.u.def.section->output_section->vma - + stub->h->root.root.u.def.section->output_offset - + stub->h->root.root.u.def.value); + target = mips_elf_get_la25_target (stub, &s); + target += s->output_section->vma + s->output_offset; + target_high = ((target + 0x8000) >> 16) & 0xffff; target_low = (target & 0xffff); @@ -10030,31 +10116,6 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd, if (IRIX_COMPAT (output_bfd) == ict_irix6) mips_elf_irix6_finish_dynamic_symbol (output_bfd, name, sym); - if (! info->shared) - { - if (! mips_elf_hash_table (info)->use_rld_obj_head - && (strcmp (name, "__rld_map") == 0 - || strcmp (name, "__RLD_MAP") == 0)) - { - asection *s = bfd_get_section_by_name (dynobj, ".rld_map"); - BFD_ASSERT (s != NULL); - sym->st_value = s->output_section->vma + s->output_offset; - bfd_put_32 (output_bfd, 0, s->contents); - if (mips_elf_hash_table (info)->rld_value == 0) - mips_elf_hash_table (info)->rld_value = sym->st_value; - } - else if (mips_elf_hash_table (info)->use_rld_obj_head - && strcmp (name, "__rld_obj_head") == 0) - { - /* IRIX6 does not use a .rld_map section. */ - if (IRIX_COMPAT (output_bfd) == ict_irix5 - || IRIX_COMPAT (output_bfd) == ict_none) - BFD_ASSERT (bfd_get_section_by_name (dynobj, ".rld_map") - != NULL); - mips_elf_hash_table (info)->rld_value = sym->st_value; - } - } - /* Keep dynamic MIPS16 symbols odd. This allows the dynamic linker to treat MIPS16 symbols like any other. */ if (ELF_ST_IS_MIPS16 (sym->st_other)) @@ -10517,7 +10578,19 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd, break; case DT_MIPS_RLD_MAP: - dyn.d_un.d_ptr = mips_elf_hash_table (info)->rld_value; + { + struct elf_link_hash_entry *h; + h = mips_elf_hash_table (info)->rld_symbol; + if (!h) + { + dyn_to_skip = MIPS_ELF_DYN_SIZE (dynobj); + swap_out_p = FALSE; + break; + } + s = h->root.u.def.section; + dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset + + h->root.u.def.value); + } break; case DT_MIPS_OPTIONS: @@ -12794,7 +12867,7 @@ _bfd_mips_elf_link_hash_table_create (bfd *abfd) ret->procedure_count = 0; ret->compact_rel_size = 0; ret->use_rld_obj_head = FALSE; - ret->rld_value = 0; + ret->rld_symbol = NULL; ret->mips16_stubs_seen = FALSE; ret->use_plts_and_copy_relocs = FALSE; ret->is_vxworks = FALSE; diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 9a15124..f3c631e 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -2970,7 +2970,7 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, } } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/elfxx-tilegx.c b/bfd/elfxx-tilegx.c index c484562..e1c8946 100644 --- a/bfd/elfxx-tilegx.c +++ b/bfd/elfxx-tilegx.c @@ -2908,7 +2908,7 @@ tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, } } - if (sec != NULL && elf_discarded_section (sec)) + if (sec != NULL && discarded_section (sec)) RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, rel, relend, howto, contents); diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 200a6fa..0395ec2 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1086,6 +1086,13 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_MIPS16_HI16", "BFD_RELOC_MIPS16_HI16_S", "BFD_RELOC_MIPS16_LO16", + "BFD_RELOC_MIPS16_TLS_GD", + "BFD_RELOC_MIPS16_TLS_LDM", + "BFD_RELOC_MIPS16_TLS_DTPREL_HI16", + "BFD_RELOC_MIPS16_TLS_DTPREL_LO16", + "BFD_RELOC_MIPS16_TLS_GOTTPREL", + "BFD_RELOC_MIPS16_TLS_TPREL_HI16", + "BFD_RELOC_MIPS16_TLS_TPREL_LO16", "BFD_RELOC_MIPS_LITERAL", "BFD_RELOC_MICROMIPS_LITERAL", "BFD_RELOC_MICROMIPS_7_PCREL_S1", diff --git a/bfd/linker.c b/bfd/linker.c index 7a01e11..e5d20b2 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -1,6 +1,6 @@ /* linker.c -- BFD linker routines Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support @@ -810,6 +810,7 @@ void _bfd_generic_link_just_syms (asection *sec, struct bfd_link_info *info ATTRIBUTE_UNUSED) { + sec->sec_info_type = SEC_INFO_TYPE_JUST_SYMS; sec->output_section = bfd_abs_section_ptr; sec->output_offset = sec->vma; } diff --git a/bfd/reloc.c b/bfd/reloc.c index 6ac7148..e3f0343 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2247,6 +2247,23 @@ ENUMDOC MIPS16 low 16 bits. ENUM + BFD_RELOC_MIPS16_TLS_GD +ENUMX + BFD_RELOC_MIPS16_TLS_LDM +ENUMX + BFD_RELOC_MIPS16_TLS_DTPREL_HI16 +ENUMX + BFD_RELOC_MIPS16_TLS_DTPREL_LO16 +ENUMX + BFD_RELOC_MIPS16_TLS_GOTTPREL +ENUMX + BFD_RELOC_MIPS16_TLS_TPREL_HI16 +ENUMX + BFD_RELOC_MIPS16_TLS_TPREL_LO16 +ENUMDOC + MIPS16 TLS relocations + +ENUM BFD_RELOC_MIPS_LITERAL ENUMX BFD_RELOC_MICROMIPS_LITERAL @@ -6218,7 +6235,7 @@ bfd_generic_get_relocated_section_contents (bfd *abfd, bfd_reloc_status_type r; symbol = *(*parent)->sym_ptr_ptr; - if (symbol->section && elf_discarded_section (symbol->section)) + if (symbol->section && discarded_section (symbol->section)) { bfd_byte *p; static reloc_howto_type none_howto diff --git a/bfd/section.c b/bfd/section.c index 7c1f750..e60f247 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -382,11 +382,11 @@ CODE_FRAGMENT . . {* Type of sec_info information. *} . unsigned int sec_info_type:3; -.#define ELF_INFO_TYPE_NONE 0 -.#define ELF_INFO_TYPE_STABS 1 -.#define ELF_INFO_TYPE_MERGE 2 -.#define ELF_INFO_TYPE_EH_FRAME 3 -.#define ELF_INFO_TYPE_JUST_SYMS 4 +.#define SEC_INFO_TYPE_NONE 0 +.#define SEC_INFO_TYPE_STABS 1 +.#define SEC_INFO_TYPE_MERGE 2 +.#define SEC_INFO_TYPE_EH_FRAME 3 +.#define SEC_INFO_TYPE_JUST_SYMS 4 . . {* Nonzero if this section uses RELA relocations, rather than REL. *} . unsigned int use_rela_p:1; diff --git a/bfd/version.h b/bfd/version.h index c6800ec..8784380 100644 --- a/bfd/version.h +++ b/bfd/version.h @@ -1,4 +1,4 @@ -#define BFD_VERSION_DATE 20111121 +#define BFD_VERSION_DATE 20120704 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ #define REPORT_BUGS_TO @report_bugs_to@ diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 2f5af61..30101e5 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,10 @@ +2012-01-26 Nick Clifton + + PR binutils/13622 + * readelf.c (process_section_groups): If there are no section + headers do not scan for section groups. + (process_note_sections): Likewise for note sections. + 2011-10-25 Alan Modra Apply mainline patches diff --git a/binutils/readelf.c b/binutils/readelf.c index 9e13190..bf053d9 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -4937,7 +4937,8 @@ process_section_groups (FILE * file) if (section_headers == NULL) { error (_("Section headers are not available!\n")); - abort (); + /* PR 13622: This can happen with a corrupt ELF header. */ + return 0; } section_headers_groups = (struct group **) calloc (elf_header.e_shnum, @@ -12942,7 +12943,7 @@ process_note_sections (FILE * file) int res = 1; for (i = 0, section = section_headers; - i < elf_header.e_shnum; + i < elf_header.e_shnum && section != NULL; i++, section++) if (section->sh_type == SHT_NOTE) res &= process_corefile_note_segment (file, diff --git a/gas/ChangeLog b/gas/ChangeLog index b29f95f..df24933 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,23 @@ +2012-01-08 Richard Sandiford + + * config/tc-mips.c (s_tls_rel_directive): Call mips_clear_insn_labels. + +2011-12-19 Chung-Lin Tang + + Backport from mainline: + + 2011-12-19 Chung-Lin Tang + + * config/tc-mips.c (mips_pseudo_table): Add tprelword/tpreldword + entries. + (mips16_percent_op): Add MIPS16 TLS relocation ops. + (md_apply_fix): Add BFD_RELOC_MIPS16_TLS_* switch cases. + (s_tls_rel_directive): Rename from s_dtprel_internal(). Abstract out + directive string and reloc type as function parameters. Update + comments. + (s_dtprelword,s_dtpreldword): Change to use s_tls_rel_directive(). + (s_tprelword,s_tpreldword): New functions. + 2011-11-15 Maciej W. Rozycki Apply mainline patches diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 0e4c66e..5324450 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -1352,6 +1352,8 @@ static void s_cprestore (int); static void s_cpreturn (int); static void s_dtprelword (int); static void s_dtpreldword (int); +static void s_tprelword (int); +static void s_tpreldword (int); static void s_gpvalue (int); static void s_gpword (int); static void s_gpdword (int); @@ -1431,6 +1433,8 @@ static const pseudo_typeS mips_pseudo_table[] = {"cpreturn", s_cpreturn, 0}, {"dtprelword", s_dtprelword, 0}, {"dtpreldword", s_dtpreldword, 0}, + {"tprelword", s_tprelword, 0}, + {"tpreldword", s_tpreldword, 0}, {"gpvalue", s_gpvalue, 0}, {"gpword", s_gpword, 0}, {"gpdword", s_gpdword, 0}, @@ -14040,7 +14044,14 @@ static const struct percent_op_match mips16_percent_op[] = {"%gprel", BFD_RELOC_MIPS16_GPREL}, {"%got", BFD_RELOC_MIPS16_GOT16}, {"%call16", BFD_RELOC_MIPS16_CALL16}, - {"%hi", BFD_RELOC_MIPS16_HI16_S} + {"%hi", BFD_RELOC_MIPS16_HI16_S}, + {"%tlsgd", BFD_RELOC_MIPS16_TLS_GD}, + {"%tlsldm", BFD_RELOC_MIPS16_TLS_LDM}, + {"%dtprel_hi", BFD_RELOC_MIPS16_TLS_DTPREL_HI16}, + {"%dtprel_lo", BFD_RELOC_MIPS16_TLS_DTPREL_LO16}, + {"%tprel_hi", BFD_RELOC_MIPS16_TLS_TPREL_HI16}, + {"%tprel_lo", BFD_RELOC_MIPS16_TLS_TPREL_LO16}, + {"%gottprel", BFD_RELOC_MIPS16_TLS_GOTTPREL} }; @@ -15369,6 +15380,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) case BFD_RELOC_MIPS_TLS_DTPREL_HI16: case BFD_RELOC_MIPS_TLS_DTPREL_LO16: case BFD_RELOC_MIPS_TLS_GOTTPREL: + case BFD_RELOC_MIPS_TLS_TPREL32: + case BFD_RELOC_MIPS_TLS_TPREL64: case BFD_RELOC_MIPS_TLS_TPREL_HI16: case BFD_RELOC_MIPS_TLS_TPREL_LO16: case BFD_RELOC_MICROMIPS_TLS_GD: @@ -15378,6 +15391,13 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) case BFD_RELOC_MICROMIPS_TLS_GOTTPREL: case BFD_RELOC_MICROMIPS_TLS_TPREL_HI16: case BFD_RELOC_MICROMIPS_TLS_TPREL_LO16: + case BFD_RELOC_MIPS16_TLS_GD: + case BFD_RELOC_MIPS16_TLS_LDM: + case BFD_RELOC_MIPS16_TLS_DTPREL_HI16: + case BFD_RELOC_MIPS16_TLS_DTPREL_LO16: + case BFD_RELOC_MIPS16_TLS_GOTTPREL: + case BFD_RELOC_MIPS16_TLS_TPREL_HI16: + case BFD_RELOC_MIPS16_TLS_TPREL_LO16: S_SET_THREAD_LOCAL (fixP->fx_addsy); /* fall through */ @@ -16547,12 +16567,14 @@ s_cpreturn (int ignore ATTRIBUTE_UNUSED) demand_empty_rest_of_line (); } -/* Handle the .dtprelword and .dtpreldword pseudo-ops. They generate - a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for - use in DWARF debug information. */ +/* Handle a .dtprelword, .dtpreldword, .tprelword, or .tpreldword + pseudo-op; DIRSTR says which. The pseudo-op generates a BYTES-size + DTP- or TP-relative relocation of type RTYPE, for use in either DWARF + debug information or MIPS16 TLS. */ static void -s_dtprel_internal (size_t bytes) +s_tls_rel_directive (const size_t bytes, const char *dirstr, + bfd_reloc_code_real_type rtype) { expressionS ex; char *p; @@ -16561,20 +16583,15 @@ s_dtprel_internal (size_t bytes) if (ex.X_op != O_symbol) { - as_bad (_("Unsupported use of %s"), (bytes == 8 - ? ".dtpreldword" - : ".dtprelword")); + as_bad (_("Unsupported use of %s"), dirstr); ignore_rest_of_line (); } p = frag_more (bytes); md_number_to_chars (p, 0, bytes); - fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE, - (bytes == 8 - ? BFD_RELOC_MIPS_TLS_DTPREL64 - : BFD_RELOC_MIPS_TLS_DTPREL32)); - + fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE, rtype); demand_empty_rest_of_line (); + mips_clear_insn_labels (); } /* Handle .dtprelword. */ @@ -16582,7 +16599,7 @@ s_dtprel_internal (size_t bytes) static void s_dtprelword (int ignore ATTRIBUTE_UNUSED) { - s_dtprel_internal (4); + s_tls_rel_directive (4, ".dtprelword", BFD_RELOC_MIPS_TLS_DTPREL32); } /* Handle .dtpreldword. */ @@ -16590,7 +16607,23 @@ s_dtprelword (int ignore ATTRIBUTE_UNUSED) static void s_dtpreldword (int ignore ATTRIBUTE_UNUSED) { - s_dtprel_internal (8); + s_tls_rel_directive (8, ".dtpreldword", BFD_RELOC_MIPS_TLS_DTPREL64); +} + +/* Handle .tprelword. */ + +static void +s_tprelword (int ignore ATTRIBUTE_UNUSED) +{ + s_tls_rel_directive (4, ".tprelword", BFD_RELOC_MIPS_TLS_TPREL32); +} + +/* Handle .tpreldword. */ + +static void +s_tpreldword (int ignore ATTRIBUTE_UNUSED) +{ + s_tls_rel_directive (8, ".tpreldword", BFD_RELOC_MIPS_TLS_TPREL64); } /* Handle the .gpvalue pseudo-op. This is used when generating NewABI PIC diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 0631572..cbb2309 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-01-08 Richard Sandiford + + * gas/mips/tls-relw.s, gas/mips/tls-relw.d: New test. + * gas/mips/mips.exp: Run it. + 2011-11-14 Maciej W. Rozycki Apply mainline patches diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp index cbaaa70..2f49a2a 100644 --- a/gas/testsuite/gas/mips/mips.exp +++ b/gas/testsuite/gas/mips/mips.exp @@ -878,6 +878,7 @@ if { [istarget mips*-*-vxworks*] } { run_list_test "tls-ill" "-32" run_dump_test "tls-o32" + run_dump_test "tls-relw" run_dump_test "jalr2" run_dump_test_arches "aent" [mips_arch_list_matching mips1] diff --git a/gas/testsuite/gas/mips/tls-relw.d b/gas/testsuite/gas/mips/tls-relw.d new file mode 100644 index 0000000..bc13b43 --- /dev/null +++ b/gas/testsuite/gas/mips/tls-relw.d @@ -0,0 +1,8 @@ +# as: -EB +# objdump: -sj.data + +.* + +Contents of section \.data: + 0000 00000001 00000000 00000002 00000004 ................ + 0010 00000000 00000003 00000010 00000000 ................ diff --git a/gas/testsuite/gas/mips/tls-relw.s b/gas/testsuite/gas/mips/tls-relw.s new file mode 100644 index 0000000..6890685 --- /dev/null +++ b/gas/testsuite/gas/mips/tls-relw.s @@ -0,0 +1,12 @@ + .data +start: + .word 1 +a: + .tprelword t1 + .word 2 + .word a-start +b: + .dtprelword t2 + .word 3 + .word b-start + .word 0 diff --git a/gold/ChangeLog b/gold/ChangeLog index 7f91606..437cf97 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,185 @@ +2012-04-27 Doug Kwan + + Backport from mainline: + + 2012-03-16 Doug Kwan + + * testsuite/Makefile.am: Disable test initpri3b. + * testsuite/Makefile.in: Regenerate. + + 2012-03-14 Doug Kwan + + * gold/arm.cc (Target_arm::Scan::global): Generate + R_ARM_GLOB_DAT dynamic relocations for protected symbols in + shared objects. + +2012-04-06 Ian Lance Taylor + + * timer.cc: #include . + +2011-12-19 Ian Lance Taylor + + Copy from mainline to binutils 2.22 branch: + + 2011-12-17 Cary Coutant + + * dwarf_reader.cc (Sized_dwarf_line_info::read_lines): Add casts. + * resolve.cc (Symbol_table::resolve): Likewise. + * i386.cc (Target_i386::do_code_fill): Use char constants for nop + arrays. + * x86_64.cc (Target_x86_64::do_code_fill): Likewise. + + 2011-10-31 Cary Coutant + + PR gold/13023 + * expression.cc (Expression::eval_with_dot): Add + is_section_dot_assignment parameter. + (Expression::eval_maybe_dot): Likewise. Adjust value when rhs is + absolute and assigning to dot within a section. + * script-sections.cc + (Output_section_element_assignment::set_section_addresses): Pass + dot_section to set_if_absolute. + (Output_section_element_dot_assignment::finalize_symbols): Pass TRUE + as is_section_dot_assignment flag to eval_with_dot. + (Output_section_element_dot_assignment::set_section_addresses): + Likewise. + * script.cc (Symbol_assignment::set_if_absolute): Add dot_section + parameter. Also set value if relative to dot_section; set the + symbol's output_section. + * script.h (Expression::eval_with_dot): Add is_section_dot_assignment + parameter. Adjust all callers. + (Expression::eval_maybe_dot): Likewise. + (Symbol_assignment::set_if_absolute): Add dot_section parameter. + Adjust all callers. + * testsuite/script_test_2.t: Test assignment of an absolute value + to dot within an output section element. + + 2011-10-31 Cary Coutant + + * options.h (class General_options): Add --[no-]gnu-unique options. + * symtab.cc (Symbol_table::sized_write_globals): Convert + STB_GNU_UNIQUE to STB_GLOBAL if --no-gnu-unique. + + 2011-10-31 Cary Coutant + + PR gold/13359 + * i386.cc (Target_i386::Relocate::relocate_tls): Remove + unnecessary assertion. + * x86_64.cc (Target_x86_64::Relocate::relocate_tls): Likewise. + + 2011-10-31 Sriraman Tallam + + * symtab.h (Symbol_table::gc_mark_symbol_for_shlib): Rename to + gc_mark_symbol. + * symtab.cc (Symbol_table::gc_mark_symbol_for_shlib): Rename to + gc_mark_symbol. + Change to just keep the section associated with symbol. + (Symbol_table::add_from_relobj): Mark symbols as not garbage when + they are externally visible and --export-dynamic is turned on. + (Symbol_table::gc_mark_dyn_syms): Call gc_mark_symbol. + + 2011-10-19 Ian Lance Taylor + + PR gold/13163 + * script-sections.cc + (Output_section_element_dot_assignment::needs_output_section): New + function. + + 2011-10-19 Ian Lance Taylor + + PR gold/13204 + * layout.cc (Layout::segment_precedes): Don't assert failure if a + --section-start option was seen. + * options.h (General_options::any_section_start): New function. + + 2011-10-18 Cary Coutant + + * output.cc (posix_fallocate): Return 0 on success, errno on failure. + (Output_file::map_no_anonymous): Check for non-zero + return code from posix_fallocate. + + 2011-10-17 Cary Coutant + + PR gold/13245 + * plugin.cc (is_visible_from_outside): Check for symbols + referenced from dynamic objects. + * resolve.cc (Symbol_table::resolve): Don't count references + from dynamic objects as references from real ELF files. + * testsuite/plugin_test_2.sh: Adjust expected result. + + 2011-10-17 Cary Coutant + + * readsyms.cc (Read_symbols::run): Don't queue an unblocker + task for members of lib groups. + + 2011-10-17 Cary Coutant + + PR gold/13288 + * fileread.cc (File_read::find_view): Add assert. + (File_read::make_view): Move bounds check (replace with assert)... + (File_read::find_or_make_view): ... to here. + + 2011-10-12 Cary Coutant + + * output.cc (Output_file::open_base_file): Handle case where + ::read returns less than requested size. + + 2011-10-10 Cary Coutant + + * incremental.cc (Sized_relobj_incr::Sized_relobj_incr): + Initialize defined_count_. + (Sized_relobj_incr::do_add_symbols): Count defined symbols. + (Sized_relobj_incr::do_get_global_symbol_counts): Rewrite. + (Sized_incr_dynobj::Sized_incr_dynobj): Initialize defined_count_. + (Sized_incr_dynobj::do_add_symbols): Count defined symbols. + (Sized_incr_dynobj::do_get_global_symbol_counts): Rewrite. + * incremental.h (Sized_relobj_incr::defined_count_): New data + member. + (Sized_incr_dynobj::defined_count_): New data member. + * plugin.cc (Sized_pluginobj::do_get_global_symbol_counts): + Return zeroes instead of internal error. + + 2011-10-10 Cary Coutant + + PR gold/13249 + * output.cc (Output_reloc::Output_reloc): Add use_plt_offset flag. + (Output_reloc::symbol_value): Return PLT offset if flag is set. + * output.h (class Output_reloc): Add use_plt_offset flag. + (Output_reloc::type_): Adjust size of bit field. + (Output_reloc::use_plt_offset_): New bit field. + (class Output_data_reloc): Adjust all calls to Output_reloc_type. + (Output_data_reloc::add_local_relative): (RELA only) Add use_plt_offset + flag. Adjust all callers. + * x86_64.cc (Target_x86_64::Scan::local): Check for IFUNC when + creating RELATIVE relocations. + + 2011-10-03 Diego Novillo + + * options.cc (parse_uint): Fix dereference of RETVAL. + + 2011-09-29 Cary Coutant + + * incremental.cc (Sized_incremental_binary::do_process_got_plt): + Check for NULL. + * symtab.cc (Symbol_table::add_from_relobj): Ignore version + symbols during incremental update. + (Symbol_table::add_from_dynobj): Likewise. + + 2011-09-26 Cary Coutant + + * gold.cc (queue_initial_tasks): Move option checks ... + * options.cc (General_options::finalize): ... to here. Disable + some options; make others fatal. + + 2011-09-23 Simon Baldwin + + * configure.ac: Add new --with-gold-ldadd and --with-gold-ldflags + configuration options. + * configure: Regenerate. + * Makefile.am: Handle GOLD_LDADD and GOLD_LDFLAGS. + * Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + 2011-11-11 Doug Kwan * arm.cc (Target_arm::do_make_elf_object): Allow executable also diff --git a/gold/arm.cc b/gold/arm.cc index 72c3670..a1e8e4c 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -8374,7 +8374,9 @@ Target_arm::Scan::global(Symbol_table* symtab, Reloc_section* rel_dyn = target->rel_dyn_section(layout); if (gsym->is_from_dynobj() || gsym->is_undefined() - || gsym->is_preemptible()) + || gsym->is_preemptible() + || (gsym->visibility() == elfcpp::STV_PROTECTED + && parameters->options().shared())) got->add_global_with_rel(gsym, GOT_TYPE_STANDARD, rel_dyn, elfcpp::R_ARM_GLOB_DAT); else diff --git a/gold/dwarf_reader.cc b/gold/dwarf_reader.cc index 3dc33e4..2b47a28 100644 --- a/gold/dwarf_reader.cc +++ b/gold/dwarf_reader.cc @@ -1,6 +1,6 @@ // dwarf_reader.cc -- parse dwarf2/3 debug information -// Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +// Copyright 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -491,8 +491,10 @@ Sized_dwarf_line_info::read_lines(unsigned const char* lineptr && (shndx == -1U || lsm.shndx == -1U || shndx == lsm.shndx)) { Offset_to_lineno_entry entry - = { lsm.address, this->current_header_index_, - lsm.file_num, true, lsm.line_num }; + = { static_cast(lsm.address), + this->current_header_index_, + static_cast(lsm.file_num), + true, lsm.line_num }; std::vector& map(this->line_number_map_[lsm.shndx]); // If we see two consecutive entries with the same diff --git a/gold/expression.cc b/gold/expression.cc index e527b5e..e31c151 100644 --- a/gold/expression.cc +++ b/gold/expression.cc @@ -1,6 +1,6 @@ // expression.cc -- expressions in linker scripts for gold -// Copyright 2006, 2007, 2008 Free Software Foundation, Inc. +// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -77,7 +77,7 @@ Expression::eval(const Symbol_table* symtab, const Layout* layout, bool check_assertions) { return this->eval_maybe_dot(symtab, layout, check_assertions, - false, 0, NULL, NULL, NULL); + false, 0, NULL, NULL, NULL, false); } // Evaluate an expression which may refer to the dot symbol. @@ -87,11 +87,13 @@ Expression::eval_with_dot(const Symbol_table* symtab, const Layout* layout, bool check_assertions, uint64_t dot_value, Output_section* dot_section, Output_section** result_section_pointer, - uint64_t* result_alignment_pointer) + uint64_t* result_alignment_pointer, + bool is_section_dot_assignment) { return this->eval_maybe_dot(symtab, layout, check_assertions, true, dot_value, dot_section, result_section_pointer, - result_alignment_pointer); + result_alignment_pointer, + is_section_dot_assignment); } // Evaluate an expression which may or may not refer to the dot @@ -102,7 +104,8 @@ Expression::eval_maybe_dot(const Symbol_table* symtab, const Layout* layout, bool check_assertions, bool is_dot_available, uint64_t dot_value, Output_section* dot_section, Output_section** result_section_pointer, - uint64_t* result_alignment_pointer) + uint64_t* result_alignment_pointer, + bool is_section_dot_assignment) { Expression_eval_info eei; eei.symtab = symtab; @@ -113,14 +116,24 @@ Expression::eval_maybe_dot(const Symbol_table* symtab, const Layout* layout, eei.dot_section = dot_section; // We assume the value is absolute, and only set this to a section - // if we find a section relative reference. + // if we find a section-relative reference. if (result_section_pointer != NULL) *result_section_pointer = NULL; eei.result_section_pointer = result_section_pointer; eei.result_alignment_pointer = result_alignment_pointer; - return this->value(&eei); + uint64_t val = this->value(&eei); + + // If this is an assignment to dot within a section, and the value + // is absolute, treat it as a section-relative offset. + if (is_section_dot_assignment && *result_section_pointer == NULL) + { + gold_assert(dot_section != NULL); + val += dot_section->address(); + *result_section_pointer = dot_section; + } + return val; } // A number. @@ -257,7 +270,8 @@ class Unary_expression : public Expression eei->dot_value, eei->dot_section, arg_section_pointer, - eei->result_alignment_pointer); + eei->result_alignment_pointer, + false); } void @@ -336,7 +350,8 @@ class Binary_expression : public Expression eei->dot_value, eei->dot_section, section_pointer, - alignment_pointer); + alignment_pointer, + false); } uint64_t @@ -350,7 +365,8 @@ class Binary_expression : public Expression eei->dot_value, eei->dot_section, section_pointer, - alignment_pointer); + alignment_pointer, + false); } void @@ -500,7 +516,8 @@ class Trinary_expression : public Expression eei->dot_value, eei->dot_section, section_pointer, - NULL); + NULL, + false); } uint64_t @@ -514,7 +531,8 @@ class Trinary_expression : public Expression eei->dot_value, eei->dot_section, section_pointer, - alignment_pointer); + alignment_pointer, + false); } uint64_t @@ -528,7 +546,8 @@ class Trinary_expression : public Expression eei->dot_value, eei->dot_section, section_pointer, - alignment_pointer); + alignment_pointer, + false); } void diff --git a/gold/fileread.cc b/gold/fileread.cc index 80ddfbc..c5dc320 100644 --- a/gold/fileread.cc +++ b/gold/fileread.cc @@ -329,6 +329,10 @@ inline File_read::View* File_read::find_view(off_t start, section_size_type size, unsigned int byteshift, File_read::View** vshifted) const { + gold_assert(start <= this->size_ + && (static_cast(size) + <= static_cast(this->size_ - start))); + if (vshifted != NULL) *vshifted = NULL; @@ -456,16 +460,9 @@ File_read::make_view(off_t start, section_size_type size, unsigned int byteshift, bool cache) { gold_assert(size > 0); - - // Check that start and end of the view are within the file. - if (start > this->size_ - || (static_cast(size) - > static_cast(this->size_ - start))) - gold_fatal(_("%s: attempt to map %lld bytes at offset %lld exceeds " - "size of file; the file may be corrupt"), - this->filename().c_str(), - static_cast(size), - static_cast(start)); + gold_assert(start <= this->size_ + && (static_cast(size) + <= static_cast(this->size_ - start))); off_t poff = File_read::page_offset(start); @@ -523,6 +520,16 @@ File_read::View* File_read::find_or_make_view(off_t offset, off_t start, section_size_type size, bool aligned, bool cache) { + // Check that start and end of the view are within the file. + if (start > this->size_ + || (static_cast(size) + > static_cast(this->size_ - start))) + gold_fatal(_("%s: attempt to map %lld bytes at offset %lld exceeds " + "size of file; the file may be corrupt"), + this->filename().c_str(), + static_cast(size), + static_cast(start)); + unsigned int byteshift; if (offset == 0) byteshift = 0; diff --git a/gold/gold.cc b/gold/gold.cc index 12f25b7..693ff79 100644 --- a/gold/gold.cc +++ b/gold/gold.cc @@ -197,46 +197,29 @@ queue_initial_tasks(const General_options& options, // For incremental links, the base output file. Incremental_binary* ibase = NULL; - if (parameters->incremental()) - { - if (options.relocatable()) - gold_error(_("incremental linking is incompatible with -r")); - if (options.emit_relocs()) - gold_error(_("incremental linking is incompatible with --emit-relocs")); - if (options.gc_sections()) - gold_error(_("incremental linking is incompatible with --gc-sections")); - if (options.icf_enabled()) - gold_error(_("incremental linking is incompatible with --icf")); - if (options.has_plugins()) - gold_error(_("incremental linking is incompatible with --plugin")); - if (strcmp(options.compress_debug_sections(), "none") != 0) - gold_error(_("incremental linking is incompatible with " - "--compress-debug-sections")); - - if (parameters->incremental_update()) + if (parameters->incremental_update()) + { + Output_file* of = new Output_file(options.output_file_name()); + if (of->open_base_file(options.incremental_base(), true)) { - Output_file* of = new Output_file(options.output_file_name()); - if (of->open_base_file(options.incremental_base(), true)) - { - ibase = open_incremental_binary(of); - if (ibase != NULL - && ibase->check_inputs(cmdline, layout->incremental_inputs())) - ibase->init_layout(layout); - else - { - delete ibase; - ibase = NULL; - of->close(); - } - } - if (ibase == NULL) + ibase = open_incremental_binary(of); + if (ibase != NULL + && ibase->check_inputs(cmdline, layout->incremental_inputs())) + ibase->init_layout(layout); + else { - if (set_parameters_incremental_full()) - gold_info(_("linking with --incremental-full")); - else - gold_fallback(_("restart link with --incremental-full")); + delete ibase; + ibase = NULL; + of->close(); } } + if (ibase == NULL) + { + if (set_parameters_incremental_full()) + gold_info(_("linking with --incremental-full")); + else + gold_fallback(_("restart link with --incremental-full")); + } } // Read the input files. We have to add the symbols to the symbol diff --git a/gold/i386.cc b/gold/i386.cc index 445bc68..efb6248 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -2709,12 +2709,6 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo, } if (optimized_type == tls::TLSOPT_TO_IE) { - if (tls_segment == NULL) - { - gold_assert(parameters->errors()->error_count() > 0 - || issue_undefined_symbol_error(gsym)); - return; - } this->tls_gd_to_ie(relinfo, relnum, tls_segment, rel, r_type, got_offset, view, view_size); break; @@ -3480,42 +3474,51 @@ Target_i386::do_code_fill(section_size_type length) const } // Nop sequences of various lengths. - const char nop1[1] = { 0x90 }; // nop - const char nop2[2] = { 0x66, 0x90 }; // xchg %ax %ax - const char nop3[3] = { 0x8d, 0x76, 0x00 }; // leal 0(%esi),%esi - const char nop4[4] = { 0x8d, 0x74, 0x26, 0x00}; // leal 0(%esi,1),%esi - const char nop5[5] = { 0x90, 0x8d, 0x74, 0x26, // nop - 0x00 }; // leal 0(%esi,1),%esi - const char nop6[6] = { 0x8d, 0xb6, 0x00, 0x00, // leal 0L(%esi),%esi - 0x00, 0x00 }; - const char nop7[7] = { 0x8d, 0xb4, 0x26, 0x00, // leal 0L(%esi,1),%esi - 0x00, 0x00, 0x00 }; - const char nop8[8] = { 0x90, 0x8d, 0xb4, 0x26, // nop - 0x00, 0x00, 0x00, 0x00 }; // leal 0L(%esi,1),%esi - const char nop9[9] = { 0x89, 0xf6, 0x8d, 0xbc, // movl %esi,%esi - 0x27, 0x00, 0x00, 0x00, // leal 0L(%edi,1),%edi - 0x00 }; - const char nop10[10] = { 0x8d, 0x76, 0x00, 0x8d, // leal 0(%esi),%esi - 0xbc, 0x27, 0x00, 0x00, // leal 0L(%edi,1),%edi - 0x00, 0x00 }; - const char nop11[11] = { 0x8d, 0x74, 0x26, 0x00, // leal 0(%esi,1),%esi - 0x8d, 0xbc, 0x27, 0x00, // leal 0L(%edi,1),%edi - 0x00, 0x00, 0x00 }; - const char nop12[12] = { 0x8d, 0xb6, 0x00, 0x00, // leal 0L(%esi),%esi - 0x00, 0x00, 0x8d, 0xbf, // leal 0L(%edi),%edi - 0x00, 0x00, 0x00, 0x00 }; - const char nop13[13] = { 0x8d, 0xb6, 0x00, 0x00, // leal 0L(%esi),%esi - 0x00, 0x00, 0x8d, 0xbc, // leal 0L(%edi,1),%edi - 0x27, 0x00, 0x00, 0x00, - 0x00 }; - const char nop14[14] = { 0x8d, 0xb4, 0x26, 0x00, // leal 0L(%esi,1),%esi - 0x00, 0x00, 0x00, 0x8d, // leal 0L(%edi,1),%edi - 0xbc, 0x27, 0x00, 0x00, - 0x00, 0x00 }; - const char nop15[15] = { 0xeb, 0x0d, 0x90, 0x90, // jmp .+15 - 0x90, 0x90, 0x90, 0x90, // nop,nop,nop,... - 0x90, 0x90, 0x90, 0x90, - 0x90, 0x90, 0x90 }; + const char nop1[1] = { '\x90' }; // nop + const char nop2[2] = { '\x66', '\x90' }; // xchg %ax %ax + const char nop3[3] = { '\x8d', '\x76', '\x00' }; // leal 0(%esi),%esi + const char nop4[4] = { '\x8d', '\x74', '\x26', // leal 0(%esi,1),%esi + '\x00'}; + const char nop5[5] = { '\x90', '\x8d', '\x74', // nop + '\x26', '\x00' }; // leal 0(%esi,1),%esi + const char nop6[6] = { '\x8d', '\xb6', '\x00', // leal 0L(%esi),%esi + '\x00', '\x00', '\x00' }; + const char nop7[7] = { '\x8d', '\xb4', '\x26', // leal 0L(%esi,1),%esi + '\x00', '\x00', '\x00', + '\x00' }; + const char nop8[8] = { '\x90', '\x8d', '\xb4', // nop + '\x26', '\x00', '\x00', // leal 0L(%esi,1),%esi + '\x00', '\x00' }; + const char nop9[9] = { '\x89', '\xf6', '\x8d', // movl %esi,%esi + '\xbc', '\x27', '\x00', // leal 0L(%edi,1),%edi + '\x00', '\x00', '\x00' }; + const char nop10[10] = { '\x8d', '\x76', '\x00', // leal 0(%esi),%esi + '\x8d', '\xbc', '\x27', // leal 0L(%edi,1),%edi + '\x00', '\x00', '\x00', + '\x00' }; + const char nop11[11] = { '\x8d', '\x74', '\x26', // leal 0(%esi,1),%esi + '\x00', '\x8d', '\xbc', // leal 0L(%edi,1),%edi + '\x27', '\x00', '\x00', + '\x00', '\x00' }; + const char nop12[12] = { '\x8d', '\xb6', '\x00', // leal 0L(%esi),%esi + '\x00', '\x00', '\x00', // leal 0L(%edi),%edi + '\x8d', '\xbf', '\x00', + '\x00', '\x00', '\x00' }; + const char nop13[13] = { '\x8d', '\xb6', '\x00', // leal 0L(%esi),%esi + '\x00', '\x00', '\x00', // leal 0L(%edi,1),%edi + '\x8d', '\xbc', '\x27', + '\x00', '\x00', '\x00', + '\x00' }; + const char nop14[14] = { '\x8d', '\xb4', '\x26', // leal 0L(%esi,1),%esi + '\x00', '\x00', '\x00', // leal 0L(%edi,1),%edi + '\x00', '\x8d', '\xbc', + '\x27', '\x00', '\x00', + '\x00', '\x00' }; + const char nop15[15] = { '\xeb', '\x0d', '\x90', // jmp .+15 + '\x90', '\x90', '\x90', // nop,nop,nop,... + '\x90', '\x90', '\x90', + '\x90', '\x90', '\x90', + '\x90', '\x90', '\x90' }; const char* nops[16] = { NULL, diff --git a/gold/incremental.cc b/gold/incremental.cc index b422827..75e44c5 100644 --- a/gold/incremental.cc +++ b/gold/incremental.cc @@ -685,7 +685,7 @@ Sized_incremental_binary::do_process_got_plt( gold_assert(plt_desc >= first_global && plt_desc < symtab_count); Symbol* sym = this->global_symbol(plt_desc - first_global); // Add the PLT entry only if the symbol is still referenced. - if (sym->in_reg()) + if (sym != NULL && sym->in_reg()) { gold_debug(DEBUG_INCREMENTAL, "PLT entry %d: %s", @@ -1966,8 +1966,9 @@ Sized_relobj_incr::Sized_relobj_incr( input_reader_(ibase->inputs_reader().input_file(input_file_index)), local_symbol_count_(0), output_local_dynsym_count_(0), local_symbol_index_(0), local_symbol_offset_(0), local_dynsym_offset_(0), - symbols_(), incr_reloc_offset_(-1U), incr_reloc_count_(0), - incr_reloc_output_index_(0), incr_relocs_(NULL), local_symbols_() + symbols_(), defined_count_(0), incr_reloc_offset_(-1U), + incr_reloc_count_(0), incr_reloc_output_index_(0), incr_relocs_(NULL), + local_symbols_() { if (this->input_reader_.is_in_system_directory()) this->set_is_in_system_directory(); @@ -2120,6 +2121,9 @@ Sized_relobj_incr::do_add_symbols( Symbol* res = symtab->add_from_incrobj(this, name, NULL, &sym); + if (shndx != elfcpp::SHN_UNDEF) + ++this->defined_count_; + // If this is a linker-defined symbol that hasn't yet been defined, // define it now. if (input_shndx == -1U && !res->is_defined()) @@ -2283,9 +2287,21 @@ Sized_relobj_incr::do_initialize_xindex() template void Sized_relobj_incr::do_get_global_symbol_counts( - const Symbol_table*, size_t*, size_t*) const -{ - gold_unreachable(); + const Symbol_table*, + size_t* defined, + size_t* used) const +{ + *defined = this->defined_count_; + size_t count = 0; + for (typename Symbols::const_iterator p = this->symbols_.begin(); + p != this->symbols_.end(); + ++p) + if (*p != NULL + && (*p)->source() == Symbol::FROM_OBJECT + && (*p)->object() == this + && (*p)->is_defined()) + ++count; + *used = count; } // Read the relocs. @@ -2579,7 +2595,7 @@ Sized_incr_dynobj::Sized_incr_dynobj( : Dynobj(name, NULL), ibase_(ibase), input_file_index_(input_file_index), input_reader_(ibase->inputs_reader().input_file(input_file_index)), - symbols_() + symbols_(), defined_count_(0) { if (this->input_reader_.is_in_system_directory()) this->set_is_in_system_directory(); @@ -2677,6 +2693,7 @@ Sized_incr_dynobj::do_add_symbols( // is meaningless, as long as it's not SHN_UNDEF. shndx = 1; v = gsym.get_st_value(); + ++this->defined_count_; } osym.put_st_name(0); @@ -2845,9 +2862,22 @@ Sized_incr_dynobj::do_initialize_xindex() template void Sized_incr_dynobj::do_get_global_symbol_counts( - const Symbol_table*, size_t*, size_t*) const -{ - gold_unreachable(); + const Symbol_table*, + size_t* defined, + size_t* used) const +{ + *defined = this->defined_count_; + size_t count = 0; + for (typename Symbols::const_iterator p = this->symbols_.begin(); + p != this->symbols_.end(); + ++p) + if (*p != NULL + && (*p)->source() == Symbol::FROM_OBJECT + && (*p)->object() == this + && (*p)->is_defined() + && (*p)->dynsym_index() != -1U) + ++count; + *used = count; } // Allocate an incremental object of the appropriate size and endianness. diff --git a/gold/incremental.h b/gold/incremental.h index e6732df..56fc52b 100644 --- a/gold/incremental.h +++ b/gold/incremental.h @@ -1996,6 +1996,8 @@ class Sized_relobj_incr : public Sized_relobj unsigned int local_dynsym_offset_; // The entries in the symbol table for the external symbols. Symbols symbols_; + // Number of symbols defined in object file itself. + size_t defined_count_; // The offset of the first incremental relocation for this object. unsigned int incr_reloc_offset_; // The number of incremental relocations for this object. @@ -2127,6 +2129,8 @@ class Sized_incr_dynobj : public Dynobj Input_entry_reader input_reader_; // The entries in the symbol table for the external symbols. Symbols symbols_; + // Number of symbols defined in object file itself. + size_t defined_count_; }; // Allocate an incremental object of the appropriate size and endianness. diff --git a/gold/layout.cc b/gold/layout.cc index 1c32bcf..9d8a43a 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -2975,8 +2975,9 @@ Layout::segment_precedes(const Output_segment* seg1, // We shouldn't get here--we shouldn't create segments which we // can't distinguish. Unless of course we are using a weird linker - // script. - gold_assert(this->script_options_->saw_phdrs_clause()); + // script or overlapping --section-start options. + gold_assert(this->script_options_->saw_phdrs_clause() + || parameters->options().any_section_start()); return false; } diff --git a/gold/options.cc b/gold/options.cc index be32645..dcf6ba7 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -198,7 +198,7 @@ parse_uint(const char* option_name, const char* arg, int* retval) { char* endptr; *retval = strtol(arg, &endptr, 0); - if (*endptr != '\0' || retval < 0) + if (*endptr != '\0' || *retval < 0) gold_fatal(_("%s: invalid option value (expected an integer): %s"), option_name, arg); } @@ -1224,6 +1224,37 @@ General_options::finalize() gold_fatal(_("Options --incremental-changed, --incremental-unchanged, " "--incremental-unknown require the use of --incremental")); + // Check for options that are not compatible with incremental linking. + // Where an option can be disabled without seriously changing the semantics + // of the link, we turn the option off; otherwise, we issue a fatal error. + + if (this->incremental_mode_ != INCREMENTAL_OFF) + { + if (this->relocatable()) + gold_fatal(_("incremental linking is not compatible with -r")); + if (this->emit_relocs()) + gold_fatal(_("incremental linking is not compatible with " + "--emit-relocs")); + if (this->has_plugins()) + gold_fatal(_("incremental linking is not compatible with --plugin")); + if (this->gc_sections()) + { + gold_warning(_("ignoring --gc-sections for an incremental link")); + this->set_gc_sections(false); + } + if (this->icf_enabled()) + { + gold_warning(_("ignoring --icf for an incremental link")); + this->set_icf_status(ICF_NONE); + } + if (strcmp(this->compress_debug_sections(), "none") != 0) + { + gold_warning(_("ignoring --compress-debug-sections for an " + "incremental link")); + this->set_compress_debug_sections("none"); + } + } + // FIXME: we can/should be doing a lot more sanity checking here. } diff --git a/gold/options.h b/gold/options.h index 768df9c..8876a1e 100644 --- a/gold/options.h +++ b/gold/options.h @@ -791,6 +791,10 @@ class General_options DEFINE_bool(g, options::EXACTLY_ONE_DASH, '\0', false, N_("Ignored"), NULL); + DEFINE_bool(gnu_unique, options::TWO_DASHES, '\0', true, + N_("Enable STB_GNU_UNIQUE symbol binding (default)"), + N_("Disable STB_GNU_UNIQUE symbol binding")); + DEFINE_string(soname, options::ONE_DASH, 'h', NULL, N_("Set shared library name"), N_("FILENAME")); @@ -1385,6 +1389,11 @@ class General_options bool section_start(const char* secname, uint64_t* paddr) const; + // Return whether any --section-start option was used. + bool + any_section_start() const + { return !this->section_starts_.empty(); } + enum Fix_v4bx { // Leave original instruction. diff --git a/gold/output.cc b/gold/output.cc index 29d8e3d..a7e1e9a 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -119,7 +119,9 @@ extern "C" void *gold_mremap(void *, size_t, size_t, int); static int posix_fallocate(int o, off_t offset, off_t len) { - return ftruncate(o, offset + len); + if (ftruncate(o, offset + len) < 0) + return errno; + return 0; } #endif // !defined(HAVE_POSIX_FALLOCATE) @@ -706,7 +708,7 @@ Output_reloc::Output_reloc( bool is_symbolless) : address_(address), local_sym_index_(GSYM_CODE), type_(type), is_relative_(is_relative), is_symbolless_(is_symbolless), - is_section_symbol_(false), shndx_(INVALID_CODE) + is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE) { // this->type_ is a bitfield; make sure TYPE fits. gold_assert(this->type_ == type); @@ -727,7 +729,7 @@ Output_reloc::Output_reloc( bool is_symbolless) : address_(address), local_sym_index_(GSYM_CODE), type_(type), is_relative_(is_relative), is_symbolless_(is_symbolless), - is_section_symbol_(false), shndx_(shndx) + is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx) { gold_assert(shndx != INVALID_CODE); // this->type_ is a bitfield; make sure TYPE fits. @@ -749,10 +751,12 @@ Output_reloc::Output_reloc( Address address, bool is_relative, bool is_symbolless, - bool is_section_symbol) + bool is_section_symbol, + bool use_plt_offset) : address_(address), local_sym_index_(local_sym_index), type_(type), is_relative_(is_relative), is_symbolless_(is_symbolless), - is_section_symbol_(is_section_symbol), shndx_(INVALID_CODE) + is_section_symbol_(is_section_symbol), use_plt_offset_(use_plt_offset), + shndx_(INVALID_CODE) { gold_assert(local_sym_index != GSYM_CODE && local_sym_index != INVALID_CODE); @@ -773,10 +777,12 @@ Output_reloc::Output_reloc( Address address, bool is_relative, bool is_symbolless, - bool is_section_symbol) + bool is_section_symbol, + bool use_plt_offset) : address_(address), local_sym_index_(local_sym_index), type_(type), is_relative_(is_relative), is_symbolless_(is_symbolless), - is_section_symbol_(is_section_symbol), shndx_(shndx) + is_section_symbol_(is_section_symbol), use_plt_offset_(use_plt_offset), + shndx_(shndx) { gold_assert(local_sym_index != GSYM_CODE && local_sym_index != INVALID_CODE); @@ -799,7 +805,7 @@ Output_reloc::Output_reloc( Address address) : address_(address), local_sym_index_(SECTION_CODE), type_(type), is_relative_(false), is_symbolless_(false), - is_section_symbol_(true), shndx_(INVALID_CODE) + is_section_symbol_(true), use_plt_offset_(false), shndx_(INVALID_CODE) { // this->type_ is a bitfield; make sure TYPE fits. gold_assert(this->type_ == type); @@ -820,7 +826,7 @@ Output_reloc::Output_reloc( Address address) : address_(address), local_sym_index_(SECTION_CODE), type_(type), is_relative_(false), is_symbolless_(false), - is_section_symbol_(true), shndx_(shndx) + is_section_symbol_(true), use_plt_offset_(false), shndx_(shndx) { gold_assert(shndx != INVALID_CODE); // this->type_ is a bitfield; make sure TYPE fits. @@ -842,7 +848,7 @@ Output_reloc::Output_reloc( Address address) : address_(address), local_sym_index_(0), type_(type), is_relative_(false), is_symbolless_(false), - is_section_symbol_(false), shndx_(INVALID_CODE) + is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE) { // this->type_ is a bitfield; make sure TYPE fits. gold_assert(this->type_ == type); @@ -858,7 +864,7 @@ Output_reloc::Output_reloc( Address address) : address_(address), local_sym_index_(0), type_(type), is_relative_(false), is_symbolless_(false), - is_section_symbol_(false), shndx_(shndx) + is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx) { gold_assert(shndx != INVALID_CODE); // this->type_ is a bitfield; make sure TYPE fits. @@ -877,7 +883,7 @@ Output_reloc::Output_reloc( Address address) : address_(address), local_sym_index_(TARGET_CODE), type_(type), is_relative_(false), is_symbolless_(false), - is_section_symbol_(false), shndx_(INVALID_CODE) + is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE) { // this->type_ is a bitfield; make sure TYPE fits. gold_assert(this->type_ == type); @@ -894,7 +900,7 @@ Output_reloc::Output_reloc( Address address) : address_(address), local_sym_index_(TARGET_CODE), type_(type), is_relative_(false), is_symbolless_(false), - is_section_symbol_(false), shndx_(shndx) + is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx) { gold_assert(shndx != INVALID_CODE); // this->type_ is a bitfield; make sure TYPE fits. @@ -1121,6 +1127,12 @@ Output_reloc::symbol_value( Sized_relobj_file* relobj = this->u1_.relobj->sized_relobj(); gold_assert(relobj != NULL); + if (this->use_plt_offset_) + { + uint64_t plt_address = + parameters->target().plt_address_for_local(relobj, lsi); + return plt_address + relobj->local_plt_offset(lsi); + } const Symbol_value* symval = relobj->local_symbol(lsi); return symval->value(relobj, addend); } @@ -4880,17 +4892,27 @@ Output_file::open_base_file(const char* base_name, bool writable) if (use_base_file) { this->open(s.st_size); - ssize_t len = ::read(o, this->base_, s.st_size); - if (len < 0) - { - gold_info(_("%s: read failed: %s"), base_name, strerror(errno)); - return false; - } - if (len < s.st_size) - { - gold_info(_("%s: file too short"), base_name); - return false; - } + ssize_t bytes_to_read = s.st_size; + unsigned char* p = this->base_; + while (bytes_to_read > 0) + { + ssize_t len = ::read(o, p, bytes_to_read); + if (len < 0) + { + gold_info(_("%s: read failed: %s"), base_name, strerror(errno)); + return false; + } + if (len == 0) + { + gold_info(_("%s: file too short: read only %lld of %lld bytes"), + base_name, + static_cast(s.st_size - bytes_to_read), + static_cast(s.st_size)); + return false; + } + p += len; + bytes_to_read -= len; + } ::close(o); return true; } @@ -5052,8 +5074,12 @@ Output_file::map_no_anonymous(bool writable) // output file will wind up incomplete, but we will have already // exited. The alternative to fallocate would be to use fdatasync, // but that would be a more significant performance hit. - if (writable && ::posix_fallocate(o, 0, this->file_size_) < 0) - gold_fatal(_("%s: %s"), this->name_, strerror(errno)); + if (writable) + { + int err = ::posix_fallocate(o, 0, this->file_size_); + if (err != 0) + gold_fatal(_("%s: %s"), this->name_, strerror(err)); + } // Map the file into memory. int prot = PROT_READ; diff --git a/gold/output.h b/gold/output.h index 1bec2c0..e2d35e2 100644 --- a/gold/output.h +++ b/gold/output.h @@ -1033,12 +1033,14 @@ class Output_reloc Output_reloc(Sized_relobj* relobj, unsigned int local_sym_index, unsigned int type, Output_data* od, Address address, bool is_relative, - bool is_symbolless, bool is_section_symbol); + bool is_symbolless, bool is_section_symbol, + bool use_plt_offset); Output_reloc(Sized_relobj* relobj, unsigned int local_sym_index, unsigned int type, unsigned int shndx, Address address, bool is_relative, - bool is_symbolless, bool is_section_symbol); + bool is_symbolless, bool is_section_symbol, + bool use_plt_offset); // A reloc against the STT_SECTION symbol of an output section. @@ -1216,7 +1218,7 @@ class Output_reloc // input file. unsigned int local_sym_index_; // The reloc type--a processor specific code. - unsigned int type_ : 29; + unsigned int type_ : 28; // True if the relocation is a RELATIVE relocation. bool is_relative_ : 1; // True if the relocation is one which should not use @@ -1224,6 +1226,10 @@ class Output_reloc bool is_symbolless_ : 1; // True if the relocation is against a section symbol. bool is_section_symbol_ : 1; + // True if the addend should be the PLT offset. This is used only + // for RELATIVE relocations to local symbols. + // (Used only for RELA, but stored here for space.) + bool use_plt_offset_ : 1; // If the reloc address is an input section in an object, the // section index. This is INVALID_CODE if the reloc address is // specified in some other way. @@ -1268,9 +1274,10 @@ class Output_reloc unsigned int local_sym_index, unsigned int type, Output_data* od, Address address, Addend addend, bool is_relative, - bool is_symbolless, bool is_section_symbol) + bool is_symbolless, bool is_section_symbol, + bool use_plt_offset) : rel_(relobj, local_sym_index, type, od, address, is_relative, - is_symbolless, is_section_symbol), + is_symbolless, is_section_symbol, use_plt_offset), addend_(addend) { } @@ -1278,9 +1285,10 @@ class Output_reloc unsigned int local_sym_index, unsigned int type, unsigned int shndx, Address address, Addend addend, bool is_relative, - bool is_symbolless, bool is_section_symbol) + bool is_symbolless, bool is_section_symbol, + bool use_plt_offset) : rel_(relobj, local_sym_index, type, shndx, address, is_relative, - is_symbolless, is_section_symbol), + is_symbolless, is_section_symbol, use_plt_offset), addend_(addend) { } @@ -1571,7 +1579,7 @@ class Output_data_reloc Output_data* od, Address address) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, - address, false, false, false)); + address, false, false, false, false)); } void @@ -1580,7 +1588,7 @@ class Output_data_reloc Output_data* od, unsigned int shndx, Address address) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, - address, false, false, false)); + address, false, false, false, false)); } // Add a RELATIVE reloc against a local symbol. @@ -1591,7 +1599,7 @@ class Output_data_reloc Output_data* od, Address address) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, - address, true, true, false)); + address, true, true, false, false)); } void @@ -1600,7 +1608,7 @@ class Output_data_reloc Output_data* od, unsigned int shndx, Address address) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, - address, true, true, false)); + address, true, true, false, false)); } // Add a local relocation which does not use a symbol for the relocation, @@ -1612,7 +1620,7 @@ class Output_data_reloc Output_data* od, Address address) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, - address, false, true, false)); + address, false, true, false, false)); } void @@ -1622,7 +1630,7 @@ class Output_data_reloc Address address) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, - address, false, true, false)); + address, false, true, false, false)); } // Add a reloc against a local section symbol. This will be @@ -1635,7 +1643,7 @@ class Output_data_reloc Output_data* od, Address address) { this->add(od, Output_reloc_type(relobj, input_shndx, type, od, - address, false, false, true)); + address, false, false, true, false)); } void @@ -1644,7 +1652,7 @@ class Output_data_reloc Output_data* od, unsigned int shndx, Address address) { this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx, - address, false, false, true)); + address, false, false, true, false)); } // A reloc against the STT_SECTION symbol of an output section. @@ -1767,7 +1775,7 @@ class Output_data_reloc Output_data* od, Address address, Addend addend) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address, - addend, false, false, false)); + addend, false, false, false, false)); } void @@ -1777,7 +1785,8 @@ class Output_data_reloc Addend addend) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, - address, addend, false, false, false)); + address, addend, false, false, false, + false)); } // Add a RELATIVE reloc against a local symbol. @@ -1785,20 +1794,23 @@ class Output_data_reloc void add_local_relative(Sized_relobj* relobj, unsigned int local_sym_index, unsigned int type, - Output_data* od, Address address, Addend addend) + Output_data* od, Address address, Addend addend, + bool use_plt_offset) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address, - addend, true, true, false)); + addend, true, true, false, + use_plt_offset)); } void add_local_relative(Sized_relobj* relobj, unsigned int local_sym_index, unsigned int type, Output_data* od, unsigned int shndx, Address address, - Addend addend) + Addend addend, bool use_plt_offset) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, - address, addend, true, true, false)); + address, addend, true, true, false, + use_plt_offset)); } // Add a local relocation which does not use a symbol for the relocation, @@ -1810,7 +1822,7 @@ class Output_data_reloc Output_data* od, Address address, Addend addend) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address, - addend, false, true, false)); + addend, false, true, false, false)); } void @@ -1820,7 +1832,8 @@ class Output_data_reloc Address address, Addend addend) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, - address, addend, false, true, false)); + address, addend, false, true, false, + false)); } // Add a reloc against a local section symbol. This will be @@ -1833,7 +1846,7 @@ class Output_data_reloc Output_data* od, Address address, Addend addend) { this->add(od, Output_reloc_type(relobj, input_shndx, type, od, address, - addend, false, false, true)); + addend, false, false, true, false)); } void @@ -1843,7 +1856,8 @@ class Output_data_reloc Addend addend) { this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx, - address, addend, false, false, true)); + address, addend, false, false, true, + false)); } // A reloc against the STT_SECTION symbol of an output section. diff --git a/gold/plugin.cc b/gold/plugin.cc index 3ccd8d0..b4e68f8 100644 --- a/gold/plugin.cc +++ b/gold/plugin.cc @@ -818,7 +818,9 @@ Pluginobj::Pluginobj(const std::string& name, Input_file* input_file, } // Return TRUE if a defined symbol is referenced from outside the -// universe of claimed objects. +// universe of claimed objects. Only references from relocatable, +// non-IR (unclaimed) objects count as a reference. References from +// dynamic objects count only as "visible". static inline bool is_referenced_from_outside(Symbol* lsym) @@ -838,6 +840,8 @@ is_referenced_from_outside(Symbol* lsym) static inline bool is_visible_from_outside(Symbol* lsym) { + if (lsym->in_dyn()) + return true; if (parameters->options().export_dynamic() || parameters->options().shared()) return lsym->is_externally_visible(); return false; @@ -1244,14 +1248,18 @@ Sized_pluginobj::do_initialize_xindex() return NULL; } -// Get symbol counts. Not used for plugin objects. +// Get symbol counts. Don't count plugin objects; the replacement +// files will provide the counts. template void -Sized_pluginobj::do_get_global_symbol_counts(const Symbol_table*, - size_t*, size_t*) const +Sized_pluginobj::do_get_global_symbol_counts( + const Symbol_table*, + size_t* defined, + size_t* used) const { - gold_unreachable(); + *defined = 0; + *used = 0; } // Get symbols. Not used for plugin objects. diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 45783c3..62a17ca 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -1329,7 +1329,7 @@ Target_powerpc::Scan::local( rela_dyn->add_local_relative(object, r_sym, r_type, output_section, data_shndx, reloc.get_r_offset(), - reloc.get_r_addend()); + reloc.get_r_addend(), false); } } break; @@ -1372,7 +1372,7 @@ Target_powerpc::Scan::local( object->set_local_got_offset(r_sym, GOT_TYPE_STANDARD, off); rela_dyn->add_local_relative(object, r_sym, elfcpp::R_POWERPC_RELATIVE, - got, off, 0); + got, off, 0, false); } } else diff --git a/gold/readsyms.cc b/gold/readsyms.cc index 1e50942..9974722 100644 --- a/gold/readsyms.cc +++ b/gold/readsyms.cc @@ -161,8 +161,10 @@ void Read_symbols::run(Workqueue* workqueue) { // If we didn't queue a new task, then we need to explicitly unblock - // the token. - if (!this->do_read_symbols(workqueue)) + // the token. If the object is a member of a lib group, however, + // the token was already added to the list of locks for the task, + // and it will be unblocked automatically at the end of the task. + if (!this->do_read_symbols(workqueue) && this->member_ == NULL) workqueue->queue_soon(new Unblock_token(this->this_blocker_, this->next_blocker_)); } diff --git a/gold/resolve.cc b/gold/resolve.cc index 03288ec..780038a 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -296,7 +296,7 @@ Symbol_table::resolve(Sized_symbol* to, // Record if we've seen this symbol in a real ELF object (i.e., the // symbol is referenced from outside the world known to the plugin). - if (object->pluginobj() == NULL) + if (object->pluginobj() == NULL && !object->is_dynamic()) to->set_in_real_elf(); // If we're processing replacement files, allow new symbols to override @@ -336,9 +336,9 @@ Symbol_table::resolve(Sized_symbol* to, && to->name()[0] == '_' && to->name()[1] == 'Z') { Symbol_location fromloc - = { object, orig_st_shndx, sym.get_st_value() }; + = { object, orig_st_shndx, static_cast(sym.get_st_value()) }; Symbol_location toloc = { to->object(), to->shndx(&to_is_ordinary), - to->value() }; + static_cast(to->value()) }; this->candidate_odr_violations_[to->name()].insert(fromloc); this->candidate_odr_violations_[to->name()].insert(toloc); } diff --git a/gold/script-sections.cc b/gold/script-sections.cc index 1fad88d..f90c0b3 100644 --- a/gold/script-sections.cc +++ b/gold/script-sections.cc @@ -680,7 +680,7 @@ class Sections_element_assignment : public Sections_element set_section_addresses(Symbol_table* symtab, Layout* layout, uint64_t* dot_value, uint64_t*, uint64_t*) { - this->assignment_.set_if_absolute(symtab, layout, true, *dot_value); + this->assignment_.set_if_absolute(symtab, layout, true, *dot_value, NULL); } // Print for debugging. @@ -714,7 +714,7 @@ class Sections_element_dot_assignment : public Sections_element // output section definition the dot symbol is always considered // to be absolute. *dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value, - NULL, NULL, NULL); + NULL, NULL, NULL, false); } // Update the dot symbol while setting section addresses. @@ -724,7 +724,7 @@ class Sections_element_dot_assignment : public Sections_element uint64_t* load_address) { *dot_value = this->val_->eval_with_dot(symtab, layout, false, *dot_value, - NULL, NULL, dot_alignment); + NULL, NULL, dot_alignment, false); *load_address = *dot_value; } @@ -866,9 +866,11 @@ class Output_section_element_assignment : public Output_section_element void set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*, uint64_t, uint64_t* dot_value, uint64_t*, - Output_section**, std::string*, Input_section_list*) + Output_section** dot_section, std::string*, + Input_section_list*) { - this->assignment_.set_if_absolute(symtab, layout, true, *dot_value); + this->assignment_.set_if_absolute(symtab, layout, true, *dot_value, + *dot_section); } // Print for debugging. @@ -892,20 +894,28 @@ class Output_section_element_dot_assignment : public Output_section_element : val_(val) { } + // An assignment to dot within an output section is enough to force + // the output section to exist. + bool + needs_output_section() const + { return true; } + // Finalize the symbol. void finalize_symbols(Symbol_table* symtab, const Layout* layout, uint64_t* dot_value, Output_section** dot_section) { *dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value, - *dot_section, dot_section, NULL); + *dot_section, dot_section, NULL, + true); } // Update the dot symbol while setting section addresses. void set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*, uint64_t, uint64_t* dot_value, uint64_t*, - Output_section**, std::string*, Input_section_list*); + Output_section** dot_section, std::string*, + Input_section_list*); // Print for debugging. void @@ -936,7 +946,8 @@ Output_section_element_dot_assignment::set_section_addresses( { uint64_t next_dot = this->val_->eval_with_dot(symtab, layout, false, *dot_value, *dot_section, - dot_section, dot_alignment); + dot_section, dot_alignment, + true); if (next_dot < *dot_value) gold_error(_("dot may not move backward")); if (next_dot > *dot_value && output_section != NULL) @@ -1037,7 +1048,8 @@ Output_data_expression::do_write_to_buffer(unsigned char* buf) { uint64_t val = this->val_->eval_with_dot(this->symtab_, this->layout_, true, this->dot_value_, - this->dot_section_, NULL, NULL); + this->dot_section_, NULL, NULL, + false); if (parameters->target().is_big_endian()) this->endian_write_to_buffer(val, buf); @@ -1187,7 +1199,7 @@ class Output_section_element_fill : public Output_section_element Output_section* fill_section; uint64_t fill_val = this->val_->eval_with_dot(symtab, layout, false, *dot_value, *dot_section, - &fill_section, NULL); + &fill_section, NULL, false); if (fill_section != NULL) gold_warning(_("fill value is not absolute")); // FIXME: The GNU linker supports fill values of arbitrary length. @@ -2108,13 +2120,13 @@ Output_section_definition::finalize_symbols(Symbol_table* symtab, { address = this->address_->eval_with_dot(symtab, layout, true, *dot_value, NULL, - NULL, NULL); + NULL, NULL, false); } if (this->align_ != NULL) { uint64_t align = this->align_->eval_with_dot(symtab, layout, true, *dot_value, NULL, - NULL, NULL); + NULL, NULL, false); address = align_address(address, align); } *dot_value = address; @@ -2303,7 +2315,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, else address = this->address_->eval_with_dot(symtab, layout, true, *dot_value, NULL, NULL, - dot_alignment); + dot_alignment, false); uint64_t align; if (this->align_ == NULL) { @@ -2316,7 +2328,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, { Output_section* align_section; align = this->align_->eval_with_dot(symtab, layout, true, *dot_value, - NULL, &align_section, NULL); + NULL, &align_section, NULL, false); if (align_section != NULL) gold_warning(_("alignment of section %s is not absolute"), this->name_.c_str()); @@ -2401,7 +2413,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, laddr = this->load_address_->eval_with_dot(symtab, layout, true, *dot_value, this->output_section_, - NULL, NULL); + NULL, NULL, false); if (this->output_section_ != NULL) this->output_section_->set_load_address(laddr); } @@ -2416,7 +2428,8 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, Output_section* subalign_section; subalign = this->subalign_->eval_with_dot(symtab, layout, true, *dot_value, NULL, - &subalign_section, NULL); + &subalign_section, NULL, + false); if (subalign_section != NULL) gold_warning(_("subalign of section %s is not absolute"), this->name_.c_str()); @@ -2431,7 +2444,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, uint64_t fill_val = this->fill_->eval_with_dot(symtab, layout, true, *dot_value, NULL, &fill_section, - NULL); + NULL, false); if (fill_section != NULL) gold_warning(_("fill of section %s is not absolute"), this->name_.c_str()); diff --git a/gold/script.cc b/gold/script.cc index 7df0c9e..b471cf9 100644 --- a/gold/script.cc +++ b/gold/script.cc @@ -983,18 +983,20 @@ Symbol_assignment::sized_finalize(Symbol_table* symtab, const Layout* layout, uint64_t final_val = this->val_->eval_maybe_dot(symtab, layout, true, is_dot_available, dot_value, dot_section, - §ion, NULL); + §ion, NULL, false); Sized_symbol* ssym = symtab->get_sized_symbol(this->sym_); ssym->set_value(final_val); if (section != NULL) ssym->set_output_section(section); } -// Set the symbol value if the expression yields an absolute value. +// Set the symbol value if the expression yields an absolute value or +// a value relative to DOT_SECTION. void Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout, - bool is_dot_available, uint64_t dot_value) + bool is_dot_available, uint64_t dot_value, + Output_section* dot_section) { if (this->sym_ == NULL) return; @@ -1002,8 +1004,9 @@ Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout, Output_section* val_section; uint64_t val = this->val_->eval_maybe_dot(symtab, layout, false, is_dot_available, dot_value, - NULL, &val_section, NULL); - if (val_section != NULL) + dot_section, &val_section, NULL, + false); + if (val_section != NULL && val_section != dot_section) return; if (parameters->target().get_size() == 32) @@ -1026,6 +1029,8 @@ Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout, } else gold_unreachable(); + if (val_section != NULL) + this->sym_->set_output_section(val_section); } // Print for debugging. @@ -1215,7 +1220,7 @@ Script_options::set_section_addresses(Symbol_table* symtab, Layout* layout) for (Symbol_assignments::iterator p = this->symbol_assignments_.begin(); p != this->symbol_assignments_.end(); ++p) - (*p)->set_if_absolute(symtab, layout, false, 0); + (*p)->set_if_absolute(symtab, layout, false, 0, NULL); return this->script_sections_.set_section_addresses(symtab, layout); } diff --git a/gold/script.h b/gold/script.h index 73079a4..f41f438 100644 --- a/gold/script.h +++ b/gold/script.h @@ -90,20 +90,28 @@ class Expression // the section address. If RESULT_ALIGNMENT is not NULL, this sets // *RESULT_ALIGNMENT to the alignment of the value of that alignment // is larger than *RESULT_ALIGNMENT; this will only be non-zero if - // this is an ALIGN expression. + // this is an ALIGN expression. If IS_SECTION_DOT_ASSIGMENT is true, + // we are evaluating an assignment to dot within an output section, + // and an absolute value should be interpreted as an offset within + // the section. uint64_t eval_with_dot(const Symbol_table*, const Layout*, bool check_assertions, uint64_t dot_value, Output_section* dot_section, - Output_section** result_section, uint64_t* result_alignment); + Output_section** result_section, uint64_t* result_alignment, + bool is_section_dot_assignment); // Return the value of an expression which may or may not be // permitted to refer to the dot symbol, depending on - // is_dot_available. + // is_dot_available. If IS_SECTION_DOT_ASSIGMENT is true, + // we are evaluating an assignment to dot within an output section, + // and an absolute value should be interpreted as an offset within + // the section. uint64_t eval_maybe_dot(const Symbol_table*, const Layout*, bool check_assertions, bool is_dot_available, uint64_t dot_value, Output_section* dot_section, - Output_section** result_section, uint64_t* result_alignment); + Output_section** result_section, uint64_t* result_alignment, + bool is_section_dot_assignment); // Print the expression to the FILE. This is for debugging. virtual void @@ -339,12 +347,12 @@ class Symbol_assignment finalize_with_dot(Symbol_table*, const Layout*, uint64_t dot_value, Output_section* dot_section); - // Set the symbol value, but only if the value is absolute. This is - // used while processing a SECTIONS clause. We assume that dot is - // an absolute value here. We do not check assertions. + // Set the symbol value, but only if the value is absolute or relative to + // DOT_SECTION. This is used while processing a SECTIONS clause. + // We assume that dot is an absolute value here. We do not check assertions. void set_if_absolute(Symbol_table*, const Layout*, bool is_dot_available, - uint64_t dot_value); + uint64_t dot_value, Output_section* dot_section); const std::string& name() const diff --git a/gold/sparc.cc b/gold/sparc.cc index 5f67a4e..12e1dee 100644 --- a/gold/sparc.cc +++ b/gold/sparc.cc @@ -1855,7 +1855,7 @@ Target_sparc::Scan::local( rela_dyn->add_local_relative(object, r_sym, elfcpp::R_SPARC_RELATIVE, output_section, data_shndx, reloc.get_r_offset(), - reloc.get_r_addend()); + reloc.get_r_addend(), false); } break; @@ -1946,7 +1946,7 @@ Target_sparc::Scan::local( object->set_local_got_offset(r_sym, GOT_TYPE_STANDARD, off); rela_dyn->add_local_relative(object, r_sym, elfcpp::R_SPARC_RELATIVE, - got, off, 0); + got, off, 0, false); } } else diff --git a/gold/symtab.cc b/gold/symtab.cc index ff1b5ca..f0ba1d5 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -602,20 +602,16 @@ Symbol_table::gc_mark_undef_symbols(Layout* layout) } void -Symbol_table::gc_mark_symbol_for_shlib(Symbol* sym) +Symbol_table::gc_mark_symbol(Symbol* sym) { - if (!sym->is_from_dynobj() - && sym->is_externally_visible()) + // Add the object and section to the work list. + Relobj* obj = static_cast(sym->object()); + bool is_ordinary; + unsigned int shndx = sym->shndx(&is_ordinary); + if (is_ordinary && shndx != elfcpp::SHN_UNDEF) { - //Add the object and section to the work list. - Relobj* obj = static_cast(sym->object()); - bool is_ordinary; - unsigned int shndx = sym->shndx(&is_ordinary); - if (is_ordinary && shndx != elfcpp::SHN_UNDEF) - { - gold_assert(this->gc_!= NULL); - this->gc_->worklist().push(Section_id(obj, shndx)); - } + gold_assert(this->gc_!= NULL); + this->gc_->worklist().push(Section_id(obj, shndx)); } } @@ -626,16 +622,7 @@ Symbol_table::gc_mark_dyn_syms(Symbol* sym) { if (sym->in_dyn() && sym->source() == Symbol::FROM_OBJECT && !sym->object()->is_dynamic()) - { - Relobj* obj = static_cast(sym->object()); - bool is_ordinary; - unsigned int shndx = sym->shndx(&is_ordinary); - if (is_ordinary && shndx != elfcpp::SHN_UNDEF) - { - gold_assert(this->gc_ != NULL); - this->gc_->worklist().push(Section_id(obj, shndx)); - } - } + this->gc_mark_symbol(sym); } // Make TO a symbol which forwards to FROM. @@ -1143,6 +1130,14 @@ Symbol_table::add_from_relobj( bool is_default_version = false; bool is_forced_local = false; + // FIXME: For incremental links, we don't store version information, + // so we need to ignore version symbols for now. + if (parameters->incremental_update() && ver != NULL) + { + namelen = ver - name; + ver = NULL; + } + if (ver != NULL) { // The symbol name is of the form foo@VERSION or foo@@VERSION @@ -1243,11 +1238,16 @@ Symbol_table::add_from_relobj( if (is_forced_local) this->force_local(res); - // If building a shared library using garbage collection, do not - // treat externally visible symbols as garbage. - if (parameters->options().gc_sections() - && parameters->options().shared()) - this->gc_mark_symbol_for_shlib(res); + // Do not treat this symbol as garbage if this symbol will be + // exported to the dynamic symbol table. This is true when + // building a shared library or using --export-dynamic and + // the symbol is externally visible. + if (parameters->options().gc_sections() + && res->is_externally_visible() + && !res->is_from_dynobj() + && (parameters->options().shared() + || parameters->options().export_dynamic())) + this->gc_mark_symbol(res); if (is_defined_in_discarded_section) res->set_is_defined_in_discarded_section(); @@ -1346,6 +1346,11 @@ Symbol_table::add_from_dynobj( return; } + // FIXME: For incremental links, we don't store version information, + // so we need to ignore version symbols for now. + if (parameters->incremental_update()) + versym = NULL; + if (versym != NULL && versym_size / 2 < count) { dynobj->error(_("too few symbol versions")); @@ -2809,6 +2814,12 @@ Symbol_table::sized_write_globals(const Stringpool* sympool, typename elfcpp::Elf_types::Elf_Addr sym_value = sym->value(); typename elfcpp::Elf_types::Elf_Addr dynsym_value = sym_value; elfcpp::STB binding = sym->binding(); + + // If --no-gnu-unique is set, change STB_GNU_UNIQUE to STB_GLOBAL. + if (binding == elfcpp::STB_GNU_UNIQUE + && !parameters->options().gnu_unique()) + binding = elfcpp::STB_GLOBAL; + switch (sym->source()) { case Symbol::FROM_OBJECT: diff --git a/gold/symtab.h b/gold/symtab.h index b9b9e00..427f72f 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -1308,10 +1308,9 @@ class Symbol_table void gc_mark_undef_symbols(Layout*); - // During garbage collection, this ensures externally visible symbols - // are not treated as garbage while building shared objects. + // This tells garbage collection that this symbol is referenced. void - gc_mark_symbol_for_shlib(Symbol* sym); + gc_mark_symbol(Symbol* sym); // During garbage collection, this keeps sections that correspond to // symbols seen in dynamic objects. diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 9b8605b..97d6457 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -870,11 +870,16 @@ initpri3a_DEPENDENCIES = gcctestdir/ld initpri3a_LDFLAGS = -Bgcctestdir/ initpri3a_LDADD = -check_PROGRAMS += initpri3b -initpri3b_SOURCES = initpri3.c -initpri3b_DEPENDENCIES = gcctestdir/ld -initpri3b_LDFLAGS = -Bgcctestdir/ -Wl,--no-ctors-in-init-array -initpri3b_LDADD = +# This test fails on targets not using .ctors and .dtors sections (e.g. ARM +# EABI). Given that gcc is moving towards using .init_array in all cases, +# this test is commented out. A better fix would be checking whether gcc +# uses .ctors or .init_array sections in configure. + +# check_PROGRAMS += initpri3b +# initpri3b_SOURCES = initpri3.c +# initpri3b_DEPENDENCIES = gcctestdir/ld +# initpri3b_LDFLAGS = -Bgcctestdir/ -Wl,--no-ctors-in-init-array +# initpri3b_LDADD = # Test --detect-odr-violations check_SCRIPTS += debug_msg.sh diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index 67149fb..518d32b 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -56,6 +56,17 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @NATIVE_OR_CROSS_LINKER_TRUE@am__append_1 = object_unittest \ @NATIVE_OR_CROSS_LINKER_TRUE@ binary_unittest +# This test fails on targets not using .ctors and .dtors sections (e.g. ARM +# EABI). Given that gcc is moving towards using .init_array in all cases, +# this test is commented out. A better fix would be checking whether gcc +# uses .ctors or .init_array sections in configure. + +# check_PROGRAMS += initpri3b +# initpri3b_SOURCES = initpri3.c +# initpri3b_DEPENDENCIES = gcctestdir/ld +# initpri3b_LDFLAGS = -Bgcctestdir/ -Wl,--no-ctors-in-init-array +# initpri3b_LDADD = + # Test --detect-odr-violations # Similar to --detect-odr-violations: check for undefined symbols in .so's @@ -189,7 +200,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ # Test -o when emitting to a special file (such as something in /dev). @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_24 = many_sections_test \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ many_sections_r_test initpri1 \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ initpri2 initpri3a initpri3b \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ initpri2 initpri3a \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_o_specialfile @GCC_FALSE@many_sections_test_DEPENDENCIES = @NATIVE_LINKER_FALSE@many_sections_test_DEPENDENCIES = @@ -204,8 +215,6 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @NATIVE_LINKER_FALSE@initpri2_DEPENDENCIES = @GCC_FALSE@initpri3a_DEPENDENCIES = @NATIVE_LINKER_FALSE@initpri3a_DEPENDENCIES = -@GCC_FALSE@initpri3b_DEPENDENCIES = -@NATIVE_LINKER_FALSE@initpri3b_DEPENDENCIES = # Check that --detect-odr-violations works with compressed debug sections. @GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@am__append_27 = debug_msg_cdebug.err @@ -712,7 +721,6 @@ libgoldtest_a_OBJECTS = $(am_libgoldtest_a_OBJECTS) @GCC_TRUE@@NATIVE_LINKER_TRUE@ initpri1$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ initpri2$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ initpri3a$(EXEEXT) \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ initpri3b$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_o_specialfile$(EXEEXT) @GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_21 = flagstest_compress_debug_sections$(EXEEXT) \ @GCC_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_LINKER_TRUE@ flagstest_o_specialfile_and_compress_debug_sections$(EXEEXT) @@ -1200,11 +1208,6 @@ initpri2_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(initpri2_LDFLAGS) \ initpri3a_OBJECTS = $(am_initpri3a_OBJECTS) initpri3a_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(initpri3a_LDFLAGS) \ $(LDFLAGS) -o $@ -@GCC_TRUE@@NATIVE_LINKER_TRUE@am_initpri3b_OBJECTS = \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ initpri3.$(OBJEXT) -initpri3b_OBJECTS = $(am_initpri3b_OBJECTS) -initpri3b_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(initpri3b_LDFLAGS) \ - $(LDFLAGS) -o $@ @GCC_TRUE@@NATIVE_LINKER_TRUE@am_justsyms_OBJECTS = \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ justsyms_1.$(OBJEXT) justsyms_OBJECTS = $(am_justsyms_OBJECTS) @@ -1698,7 +1701,7 @@ SOURCES = $(libgoldtest_a_SOURCES) basic_pic_test.c basic_pie_test.c \ incremental_copy_test.c incremental_test_2.c \ incremental_test_3.c incremental_test_4.c incremental_test_5.c \ incremental_test_6.c $(initpri1_SOURCES) $(initpri2_SOURCES) \ - $(initpri3a_SOURCES) $(initpri3b_SOURCES) $(justsyms_SOURCES) \ + $(initpri3a_SOURCES) $(justsyms_SOURCES) \ $(justsyms_exec_SOURCES) $(large_SOURCES) local_labels_test.c \ many_sections_r_test.c $(many_sections_test_SOURCES) \ $(object_unittest_SOURCES) permission_test.c plugin_test_1.c \ @@ -1844,6 +1847,8 @@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ GENCAT = @GENCAT@ GMSGFMT = @GMSGFMT@ +GOLD_LDADD = @GOLD_LDADD@ +GOLD_LDFLAGS = @GOLD_LDFLAGS@ GREP = @GREP@ INCINTL = @INCINTL@ INSTALL = @INSTALL@ @@ -2279,10 +2284,6 @@ LDADD = libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@initpri3a_DEPENDENCIES = gcctestdir/ld @GCC_TRUE@@NATIVE_LINKER_TRUE@initpri3a_LDFLAGS = -Bgcctestdir/ @GCC_TRUE@@NATIVE_LINKER_TRUE@initpri3a_LDADD = -@GCC_TRUE@@NATIVE_LINKER_TRUE@initpri3b_SOURCES = initpri3.c -@GCC_TRUE@@NATIVE_LINKER_TRUE@initpri3b_DEPENDENCIES = gcctestdir/ld -@GCC_TRUE@@NATIVE_LINKER_TRUE@initpri3b_LDFLAGS = -Bgcctestdir/ -Wl,--no-ctors-in-init-array -@GCC_TRUE@@NATIVE_LINKER_TRUE@initpri3b_LDADD = @GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_SOURCES = ver_test_main.cc @GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_DEPENDENCIES = gcctestdir/ld ver_test_1.so ver_test_2.so ver_test_4.so @GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,. @@ -2926,9 +2927,6 @@ initpri2$(EXEEXT): $(initpri2_OBJECTS) $(initpri2_DEPENDENCIES) initpri3a$(EXEEXT): $(initpri3a_OBJECTS) $(initpri3a_DEPENDENCIES) @rm -f initpri3a$(EXEEXT) $(initpri3a_LINK) $(initpri3a_OBJECTS) $(initpri3a_LDADD) $(LIBS) -initpri3b$(EXEEXT): $(initpri3b_OBJECTS) $(initpri3b_DEPENDENCIES) - @rm -f initpri3b$(EXEEXT) - $(initpri3b_LINK) $(initpri3b_OBJECTS) $(initpri3b_LDADD) $(LIBS) justsyms$(EXEEXT): $(justsyms_OBJECTS) $(justsyms_DEPENDENCIES) @rm -f justsyms$(EXEEXT) $(justsyms_LINK) $(justsyms_OBJECTS) $(justsyms_LDADD) $(LIBS) @@ -3867,8 +3865,6 @@ initpri2.log: initpri2$(EXEEXT) @p='initpri2$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) initpri3a.log: initpri3a$(EXEEXT) @p='initpri3a$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) -initpri3b.log: initpri3b$(EXEEXT) - @p='initpri3b$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) flagstest_o_specialfile.log: flagstest_o_specialfile$(EXEEXT) @p='flagstest_o_specialfile$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) flagstest_compress_debug_sections.log: flagstest_compress_debug_sections$(EXEEXT) diff --git a/gold/testsuite/plugin_test_2.sh b/gold/testsuite/plugin_test_2.sh index a47d22a..293b1f0 100755 --- a/gold/testsuite/plugin_test_2.sh +++ b/gold/testsuite/plugin_test_2.sh @@ -45,7 +45,7 @@ check plugin_test_2.err "two_file_test_main.o: claim file hook called" check plugin_test_2.err "two_file_test_1.syms: claim file hook called" check plugin_test_2.err "two_file_test_1b.syms: claim file hook called" check plugin_test_2.err "two_file_shared_2.so: claim file hook called" -check plugin_test_2.err "two_file_test_1.syms: _Z4f13iv: PREVAILING_DEF_REG" +check plugin_test_2.err "two_file_test_1.syms: _Z4f13iv: PREVAILING_DEF_IRONLY_EXP" check plugin_test_2.err "two_file_test_1.syms: _Z2t2v: PREVAILING_DEF_REG" check plugin_test_2.err "two_file_test_1.syms: v2: RESOLVED_DYN" check plugin_test_2.err "two_file_test_1.syms: t17data: RESOLVED_DYN" diff --git a/gold/testsuite/script_test_2.t b/gold/testsuite/script_test_2.t index 73d39df..6a0188f 100644 --- a/gold/testsuite/script_test_2.t +++ b/gold/testsuite/script_test_2.t @@ -49,7 +49,7 @@ SECTIONS /* This should match the remaining sections. */ *(.gold_test) - . = . + 4; + . = 60; start_data = .; BYTE(1) SHORT(2) diff --git a/gold/timer.cc b/gold/timer.cc index d9b8874..44e19f5 100644 --- a/gold/timer.cc +++ b/gold/timer.cc @@ -22,6 +22,8 @@ #include "gold.h" +#include + #ifdef HAVE_TIMES #include #endif diff --git a/gold/x86_64.cc b/gold/x86_64.cc index e6b0021..e7c981b 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -1549,7 +1549,7 @@ Target_x86_64::reserve_local_got_entry( case GOT_TYPE_STANDARD: if (parameters->options().output_is_position_independent()) rela_dyn->add_local_relative(obj, r_sym, elfcpp::R_X86_64_RELATIVE, - this->got_, got_offset, 0); + this->got_, got_offset, 0, false); break; case GOT_TYPE_TLS_OFFSET: rela_dyn->add_local(obj, r_sym, elfcpp::R_X86_64_TPOFF64, @@ -1953,8 +1953,8 @@ Target_x86_64::Scan::local(Symbol_table* symtab, const elfcpp::Sym<64, false>& lsym) { // A local STT_GNU_IFUNC symbol may require a PLT entry. - if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC - && this->reloc_needs_plt_for_ifunc(object, r_type)) + bool is_ifunc = lsym.get_st_type() == elfcpp::STT_GNU_IFUNC; + if (is_ifunc && this->reloc_needs_plt_for_ifunc(object, r_type)) { unsigned int r_sym = elfcpp::elf_r_sym<64>(reloc.get_r_info()); target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym); @@ -1982,7 +1982,7 @@ Target_x86_64::Scan::local(Symbol_table* symtab, elfcpp::R_X86_64_RELATIVE, output_section, data_shndx, reloc.get_r_offset(), - reloc.get_r_addend()); + reloc.get_r_addend(), is_ifunc); } break; @@ -2058,7 +2058,7 @@ Target_x86_64::Scan::local(Symbol_table* symtab, // lets function pointers compare correctly with shared // libraries. Otherwise we would need an IRELATIVE reloc. bool is_new; - if (lsym.get_st_type() == elfcpp::STT_GNU_IFUNC) + if (is_ifunc) is_new = got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD); else is_new = got->add_local(object, r_sym, GOT_TYPE_STANDARD); @@ -2076,7 +2076,7 @@ Target_x86_64::Scan::local(Symbol_table* symtab, object->local_got_offset(r_sym, GOT_TYPE_STANDARD); rela_dyn->add_local_relative(object, r_sym, elfcpp::R_X86_64_RELATIVE, - got, got_offset, 0); + got, got_offset, 0, is_ifunc); } else { @@ -3181,12 +3181,6 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, } if (optimized_type == tls::TLSOPT_TO_IE) { - if (tls_segment == NULL) - { - gold_assert(parameters->errors()->error_count() > 0 - || issue_undefined_symbol_error(gsym)); - return; - } value = target->got_plt_section()->address() + got_offset; this->tls_gd_to_ie(relinfo, relnum, tls_segment, rela, r_type, value, view, address, view_size); @@ -3867,42 +3861,51 @@ Target_x86_64::do_code_fill(section_size_type length) const } // Nop sequences of various lengths. - const char nop1[1] = { 0x90 }; // nop - const char nop2[2] = { 0x66, 0x90 }; // xchg %ax %ax - const char nop3[3] = { 0x0f, 0x1f, 0x00 }; // nop (%rax) - const char nop4[4] = { 0x0f, 0x1f, 0x40, 0x00}; // nop 0(%rax) - const char nop5[5] = { 0x0f, 0x1f, 0x44, 0x00, // nop 0(%rax,%rax,1) - 0x00 }; - const char nop6[6] = { 0x66, 0x0f, 0x1f, 0x44, // nopw 0(%rax,%rax,1) - 0x00, 0x00 }; - const char nop7[7] = { 0x0f, 0x1f, 0x80, 0x00, // nopl 0L(%rax) - 0x00, 0x00, 0x00 }; - const char nop8[8] = { 0x0f, 0x1f, 0x84, 0x00, // nopl 0L(%rax,%rax,1) - 0x00, 0x00, 0x00, 0x00 }; - const char nop9[9] = { 0x66, 0x0f, 0x1f, 0x84, // nopw 0L(%rax,%rax,1) - 0x00, 0x00, 0x00, 0x00, - 0x00 }; - const char nop10[10] = { 0x66, 0x2e, 0x0f, 0x1f, // nopw %cs:0L(%rax,%rax,1) - 0x84, 0x00, 0x00, 0x00, - 0x00, 0x00 }; - const char nop11[11] = { 0x66, 0x66, 0x2e, 0x0f, // data16 - 0x1f, 0x84, 0x00, 0x00, // nopw %cs:0L(%rax,%rax,1) - 0x00, 0x00, 0x00 }; - const char nop12[12] = { 0x66, 0x66, 0x66, 0x2e, // data16; data16 - 0x0f, 0x1f, 0x84, 0x00, // nopw %cs:0L(%rax,%rax,1) - 0x00, 0x00, 0x00, 0x00 }; - const char nop13[13] = { 0x66, 0x66, 0x66, 0x66, // data16; data16; data16 - 0x2e, 0x0f, 0x1f, 0x84, // nopw %cs:0L(%rax,%rax,1) - 0x00, 0x00, 0x00, 0x00, - 0x00 }; - const char nop14[14] = { 0x66, 0x66, 0x66, 0x66, // data16; data16; data16 - 0x66, 0x2e, 0x0f, 0x1f, // data16 - 0x84, 0x00, 0x00, 0x00, // nopw %cs:0L(%rax,%rax,1) - 0x00, 0x00 }; - const char nop15[15] = { 0x66, 0x66, 0x66, 0x66, // data16; data16; data16 - 0x66, 0x66, 0x2e, 0x0f, // data16; data16 - 0x1f, 0x84, 0x00, 0x00, // nopw %cs:0L(%rax,%rax,1) - 0x00, 0x00, 0x00 }; + const char nop1[1] = { '\x90' }; // nop + const char nop2[2] = { '\x66', '\x90' }; // xchg %ax %ax + const char nop3[3] = { '\x0f', '\x1f', '\x00' }; // nop (%rax) + const char nop4[4] = { '\x0f', '\x1f', '\x40', // nop 0(%rax) + '\x00'}; + const char nop5[5] = { '\x0f', '\x1f', '\x44', // nop 0(%rax,%rax,1) + '\x00', '\x00' }; + const char nop6[6] = { '\x66', '\x0f', '\x1f', // nopw 0(%rax,%rax,1) + '\x44', '\x00', '\x00' }; + const char nop7[7] = { '\x0f', '\x1f', '\x80', // nopl 0L(%rax) + '\x00', '\x00', '\x00', + '\x00' }; + const char nop8[8] = { '\x0f', '\x1f', '\x84', // nopl 0L(%rax,%rax,1) + '\x00', '\x00', '\x00', + '\x00', '\x00' }; + const char nop9[9] = { '\x66', '\x0f', '\x1f', // nopw 0L(%rax,%rax,1) + '\x84', '\x00', '\x00', + '\x00', '\x00', '\x00' }; + const char nop10[10] = { '\x66', '\x2e', '\x0f', // nopw %cs:0L(%rax,%rax,1) + '\x1f', '\x84', '\x00', + '\x00', '\x00', '\x00', + '\x00' }; + const char nop11[11] = { '\x66', '\x66', '\x2e', // data16 + '\x0f', '\x1f', '\x84', // nopw %cs:0L(%rax,%rax,1) + '\x00', '\x00', '\x00', + '\x00', '\x00' }; + const char nop12[12] = { '\x66', '\x66', '\x66', // data16; data16 + '\x2e', '\x0f', '\x1f', // nopw %cs:0L(%rax,%rax,1) + '\x84', '\x00', '\x00', + '\x00', '\x00', '\x00' }; + const char nop13[13] = { '\x66', '\x66', '\x66', // data16; data16; data16 + '\x66', '\x2e', '\x0f', // nopw %cs:0L(%rax,%rax,1) + '\x1f', '\x84', '\x00', + '\x00', '\x00', '\x00', + '\x00' }; + const char nop14[14] = { '\x66', '\x66', '\x66', // data16; data16; data16 + '\x66', '\x66', '\x2e', // data16 + '\x0f', '\x1f', '\x84', // nopw %cs:0L(%rax,%rax,1) + '\x00', '\x00', '\x00', + '\x00', '\x00' }; + const char nop15[15] = { '\x66', '\x66', '\x66', // data16; data16; data16 + '\x66', '\x66', '\x66', // data16; data16 + '\x2e', '\x0f', '\x1f', // nopw %cs:0L(%rax,%rax,1) + '\x84', '\x00', '\x00', + '\x00', '\x00', '\x00' }; const char* nops[16] = { NULL, diff --git a/include/ChangeLog b/include/ChangeLog index af96977..e32f0f9 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,11 @@ +2011-12-19 Chung-Lin Tang + + Backport from mainline: + + 2011-12-19 Chung-Lin Tang + + * elf/mips.h (elf_mips_reloc_type): Add R_MIPS16_TLS_* entries. + 2011-10-25 Alan Modra Apply mainline patches. diff --git a/include/elf/mips.h b/include/elf/mips.h index db5fa54..c2c5922 100644 --- a/include/elf/mips.h +++ b/include/elf/mips.h @@ -98,7 +98,14 @@ START_RELOC_NUMBERS (elf_mips_reloc_type) RELOC_NUMBER (R_MIPS16_CALL16, 103) RELOC_NUMBER (R_MIPS16_HI16, 104) RELOC_NUMBER (R_MIPS16_LO16, 105) - FAKE_RELOC (R_MIPS16_max, 106) + RELOC_NUMBER (R_MIPS16_TLS_GD, 106) + RELOC_NUMBER (R_MIPS16_TLS_LDM, 107) + RELOC_NUMBER (R_MIPS16_TLS_DTPREL_HI16, 108) + RELOC_NUMBER (R_MIPS16_TLS_DTPREL_LO16, 109) + RELOC_NUMBER (R_MIPS16_TLS_GOTTPREL, 110) + RELOC_NUMBER (R_MIPS16_TLS_TPREL_HI16, 111) + RELOC_NUMBER (R_MIPS16_TLS_TPREL_LO16, 112) + FAKE_RELOC (R_MIPS16_max, 113) /* These relocations are specific to VxWorks. */ RELOC_NUMBER (R_MIPS_COPY, 126) RELOC_NUMBER (R_MIPS_JUMP_SLOT, 127) diff --git a/ld/ChangeLog b/ld/ChangeLog index f5fa6ff..98fd778 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,23 @@ +2012-05-11 Ralf Corsépius + + PR ld/13991 + Backport from mainline: + 2012-04-24 Alan Modra + + * ld/ldlang.c (size_input_section): Use sec_info_type rather than + usrdata->flags.just_syms. + * ld/ldwrite.c (build_link_order): Likewise. + * ld/emultempl/hppaelf.em (build_section_lists): Likewise. + * ld/emultempl/ppc64elf.em (build_toc_list): Likewise. + * ld/emultempl/armelf.em (build_section_lists): Likewise. + (after_allocation): Update for renamed sec_info_type value. + * ld/emultempl/tic6xdsbt.em: Likewise. + +2011-12-20 Joseph Myers + + * emulparams/elf32bmip.sh (OTHER_SECTIONS): Put .mdebug.* and + .gcc_compiled_long* sections at address 0. + 2011-11-02 Rainer Orth Backport from mainline: diff --git a/ld/emulparams/elf32bmip.sh b/ld/emulparams/elf32bmip.sh index 44a0b8a..f0fcd2c 100644 --- a/ld/emulparams/elf32bmip.sh +++ b/ld/emulparams/elf32bmip.sh @@ -64,14 +64,14 @@ OTHER_BSS_SYMBOLS='_fbss = .;' OTHER_SECTIONS=' .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } - .mdebug.abi32 : { KEEP(*(.mdebug.abi32)) } - .mdebug.abiN32 : { KEEP(*(.mdebug.abiN32)) } - .mdebug.abi64 : { KEEP(*(.mdebug.abi64)) } - .mdebug.abiO64 : { KEEP(*(.mdebug.abiO64)) } - .mdebug.eabi32 : { KEEP(*(.mdebug.eabi32)) } - .mdebug.eabi64 : { KEEP(*(.mdebug.eabi64)) } - .gcc_compiled_long32 : { KEEP(*(.gcc_compiled_long32)) } - .gcc_compiled_long64 : { KEEP(*(.gcc_compiled_long64)) } + .mdebug.abi32 0 : { KEEP(*(.mdebug.abi32)) } + .mdebug.abiN32 0 : { KEEP(*(.mdebug.abiN32)) } + .mdebug.abi64 0 : { KEEP(*(.mdebug.abi64)) } + .mdebug.abiO64 0 : { KEEP(*(.mdebug.abiO64)) } + .mdebug.eabi32 0 : { KEEP(*(.mdebug.eabi32)) } + .mdebug.eabi64 0 : { KEEP(*(.mdebug.eabi64)) } + .gcc_compiled_long32 0 : { KEEP(*(.gcc_compiled_long32)) } + .gcc_compiled_long64 0 : { KEEP(*(.gcc_compiled_long64)) } ' ARCH=mips MACHINE= diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index d29da59..7631474 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -240,7 +240,7 @@ build_section_lists (lang_statement_union_type *statement) { asection *i = statement->input_section.section; - if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag + if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS && (i->flags & SEC_EXCLUDE) == 0 && i->output_section != NULL && i->output_section->owner == link_info.output_bfd) @@ -299,7 +299,7 @@ gld${EMULATION_NAME}_after_allocation (void) && elf_section_type (sec) == SHT_PROGBITS && (elf_section_flags (sec) & SHF_EXECINSTR) != 0 && (sec->flags & SEC_EXCLUDE) == 0 - && sec->sec_info_type != ELF_INFO_TYPE_JUST_SYMS + && sec->sec_info_type != SEC_INFO_TYPE_JUST_SYMS && out_sec != bfd_abs_section_ptr) { if (sec_count == list_size) diff --git a/ld/emultempl/hppaelf.em b/ld/emultempl/hppaelf.em index 1137ba2..6258bf4 100644 --- a/ld/emultempl/hppaelf.em +++ b/ld/emultempl/hppaelf.em @@ -229,7 +229,7 @@ build_section_lists (lang_statement_union_type *statement) { asection *i = statement->input_section.section; - if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag + if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS && (i->flags & SEC_EXCLUDE) == 0 && i->output_section != NULL && i->output_section->owner == link_info.output_bfd) diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em index 92a468f..52b9f05 100644 --- a/ld/emultempl/ppc64elf.em +++ b/ld/emultempl/ppc64elf.em @@ -428,7 +428,7 @@ build_toc_list (lang_statement_union_type *statement) { asection *i = statement->input_section.section; - if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag + if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS && (i->flags & SEC_EXCLUDE) == 0 && i->output_section == toc_section) { @@ -446,7 +446,7 @@ build_section_lists (lang_statement_union_type *statement) { asection *i = statement->input_section.section; - if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag + if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS && (i->flags & SEC_EXCLUDE) == 0 && i->output_section != NULL && i->output_section->owner == link_info.output_bfd) diff --git a/ld/emultempl/tic6xdsbt.em b/ld/emultempl/tic6xdsbt.em index e287005..fd7a12b 100644 --- a/ld/emultempl/tic6xdsbt.em +++ b/ld/emultempl/tic6xdsbt.em @@ -122,7 +122,7 @@ gld${EMULATION_NAME}_after_allocation (void) && elf_section_type (sec) == SHT_PROGBITS && (elf_section_flags (sec) & SHF_EXECINSTR) != 0 && (sec->flags & SEC_EXCLUDE) == 0 - && sec->sec_info_type != ELF_INFO_TYPE_JUST_SYMS + && sec->sec_info_type != SEC_INFO_TYPE_JUST_SYMS && out_sec != bfd_abs_section_ptr) { if (sec_count == list_size) diff --git a/ld/ldlang.c b/ld/ldlang.c index 2c56b56..7ecbae2 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -4648,7 +4648,7 @@ size_input_section lang_input_section_type *is = &((*this_ptr)->input_section); asection *i = is->section; - if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag + if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS && (i->flags & SEC_EXCLUDE) == 0) { unsigned int alignment_needed; diff --git a/ld/ldwrite.c b/ld/ldwrite.c index b7a1469..2503d1f 100644 --- a/ld/ldwrite.c +++ b/ld/ldwrite.c @@ -1,6 +1,6 @@ /* ldwrite.c -- write out the linked file Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002, - 2003, 2004, 2005, 2006, 2007, 2008, 2010 + 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2012 Free Software Foundation, Inc. Written by Steve Chamberlain sac@cygnus.com @@ -240,7 +240,7 @@ build_link_order (lang_statement_union_type *statement) attached */ asection *i = statement->input_section.section; - if (!((lang_input_statement_type *) i->owner->usrdata)->just_syms_flag + if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS && (i->flags & SEC_EXCLUDE) == 0) { asection *output_section = i->output_section; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 233d962..6318c4f 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,22 @@ +2012-01-10 H.J. Lu + + Backport from mainline: + PR ld/13581 + * ld-x86-64/ilp32-4.s: New. + * ld-x86-64/ilp32-10.d: Likewise. + * ld-x86-64/ilp32-10.s: Likewise. + + * ld-x86-64/ilp32-4.d: Adjusted. + * ld-x86-64/ilp32-5.d: Likewise. + * ld-x86-64/ilp32-5.s: Likewise. + + * ld-x86-64/x86-64.exp: Run ilp32-10. + +2011-12-01 Hans-Peter Nilsson + + * ld-cris/pic-gc-72.d: Revert last change to adjust for reverted + cause for last change. + 2011-11-10 Matthew Gretton-Dann Apply mainline patches. diff --git a/ld/testsuite/ld-cris/pic-gc-72.d b/ld/testsuite/ld-cris/pic-gc-72.d index 7e72752..7c30980 100644 --- a/ld/testsuite/ld-cris/pic-gc-72.d +++ b/ld/testsuite/ld-cris/pic-gc-72.d @@ -19,11 +19,10 @@ Contents of section .dynsym: Contents of section .dynstr: #... Contents of section .text: - 016e 0f050f05 .* + 0188 0f050f05 .* Contents of section .dynamic: - 2174 .* #... Contents of section .got: - 21cc 74210000 00000000 00000000 .* + 21e4 8c210000 00000000 00000000 .* Contents of section .data: - 21d8 00000000 .* + 21f0 00000000 .* diff --git a/ld/testsuite/ld-x86-64/ilp32-10.d b/ld/testsuite/ld-x86-64/ilp32-10.d new file mode 100644 index 0000000..43d9fbd --- /dev/null +++ b/ld/testsuite/ld-x86-64/ilp32-10.d @@ -0,0 +1,3 @@ +#as: --x32 +#ld: -shared -melf32_x86_64 +#error: .*relocation R_X86_64_PC32 against undefined symbol `bar' can not be used when making a shared object; recompile with -fPIC diff --git a/ld/testsuite/ld-x86-64/ilp32-10.s b/ld/testsuite/ld-x86-64/ilp32-10.s new file mode 100644 index 0000000..70e4a90 --- /dev/null +++ b/ld/testsuite/ld-x86-64/ilp32-10.s @@ -0,0 +1,3 @@ + .globl foo +foo: + mov bar(%rip), %rax diff --git a/ld/testsuite/ld-x86-64/ilp32-4.d b/ld/testsuite/ld-x86-64/ilp32-4.d index 84dc7b2..92d8a67 100644 --- a/ld/testsuite/ld-x86-64/ilp32-4.d +++ b/ld/testsuite/ld-x86-64/ilp32-4.d @@ -1,36 +1,30 @@ -#source: start.s #as: --x32 #ld: -m elf32_x86_64 -shared --no-ld-generated-unwind-info #readelf: -d -S --wide -There are 10 section headers, starting at offset 0x22c: +There are 9 section headers, starting at offset 0x1d8: Section Headers: \[Nr\] Name Type Addr Off Size ES Flg Lk Inf Al \[ 0\] NULL 00000000 000000 000000 00 0 0 0 - \[ 1\] .hash HASH 00000094 000094 000030 04 A 2 0 4 - \[ 2\] .dynsym DYNSYM 000000c4 0000c4 000070 10 A 3 2 4 - \[ 3\] .dynstr STRTAB 00000134 000134 00001d 00 A 0 0 1 - \[ 4\] .rela.dyn RELA 00000154 000154 00000c 0c A 2 0 4 - \[ 5\] .text PROGBITS 00000160 000160 000005 00 AX 0 0 4 - \[ 6\] .dynamic DYNAMIC 00200168 000168 000078 08 WA 3 0 4 - \[ 7\] .shstrtab STRTAB 00000000 0001e0 00004a 00 0 0 1 - \[ 8\] .symtab SYMTAB 00000000 0003bc 0000e0 10 9 9 4 - \[ 9\] .strtab STRTAB 00000000 00049c 000043 00 0 0 1 + \[ 1\] .hash HASH 00000094 000094 00002c 04 A 2 0 4 + \[ 2\] .dynsym DYNSYM 000000c0 0000c0 000060 10 A 3 2 4 + \[ 3\] .dynstr STRTAB 00000120 000120 000019 00 A 0 0 1 + \[ 4\] .text PROGBITS 0000013c 00013c 000001 00 AX 0 0 4 + \[ 5\] .dynamic DYNAMIC 00200140 000140 000058 08 WA 3 0 4 + \[ 6\] .shstrtab STRTAB 00000000 000198 000040 00 0 0 1 + \[ 7\] .symtab SYMTAB 00000000 000340 0000c0 10 8 8 4 + \[ 8\] .strtab STRTAB 00000000 000400 00003f 00 0 0 1 Key to Flags: W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\), l \(large\) I \(info\), L \(link order\), G \(group\), T \(TLS\), E \(exclude\), x \(unknown\) O \(extra OS processing required\) o \(OS specific\), p \(processor specific\) -Dynamic section at offset 0x168 contains 10 entries: +Dynamic section at offset 0x140 contains 6 entries: Tag Type Name/Value 0x00000004 \(HASH\) 0x94 - 0x00000005 \(STRTAB\) 0x134 - 0x00000006 \(SYMTAB\) 0xc4 - 0x0000000a \(STRSZ\) 29 \(bytes\) + 0x00000005 \(STRTAB\) 0x120 + 0x00000006 \(SYMTAB\) 0xc0 + 0x0000000a \(STRSZ\) 25 \(bytes\) 0x0000000b \(SYMENT\) 16 \(bytes\) - 0x00000007 \(RELA\) 0x154 - 0x00000008 \(RELASZ\) 12 \(bytes\) - 0x00000009 \(RELAENT\) 12 \(bytes\) - 0x00000016 \(TEXTREL\) 0x0 0x00000000 \(NULL\) 0x0 diff --git a/ld/testsuite/ld-x86-64/ilp32-4.s b/ld/testsuite/ld-x86-64/ilp32-4.s new file mode 100644 index 0000000..5f270c7 --- /dev/null +++ b/ld/testsuite/ld-x86-64/ilp32-4.s @@ -0,0 +1,3 @@ + .globl _start +_start: + ret diff --git a/ld/testsuite/ld-x86-64/ilp32-5.d b/ld/testsuite/ld-x86-64/ilp32-5.d index e4673e5..4870c2b 100644 --- a/ld/testsuite/ld-x86-64/ilp32-5.d +++ b/ld/testsuite/ld-x86-64/ilp32-5.d @@ -4,5 +4,5 @@ #... [0-9a-f]+ +[0-9a-f]+ +R_X86_64_RELATIVE +[0-9a-f]+ -[0-9a-f]+ +[0-9a-f]+ +R_X86_64_PC32 +[0-9a-f]+ +foo - 4 +[0-9a-f]+ +[0-9a-f]+ +R_X86_64_GLOB_DAT +[0-9a-f]+ +foo \+ 0 [0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +[0-9a-f]+ +foo \+ 0 diff --git a/ld/testsuite/ld-x86-64/ilp32-5.s b/ld/testsuite/ld-x86-64/ilp32-5.s index 0d97807..ef0c60e 100644 --- a/ld/testsuite/ld-x86-64/ilp32-5.s +++ b/ld/testsuite/ld-x86-64/ilp32-5.s @@ -1,6 +1,6 @@ .globl bar bar: - mov foo(%rip), %rax + mov foo@GOTPCREL(%rip), %rax .data xxx: diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 77b081b..44d3e07 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -207,6 +207,7 @@ run_dump_test "ilp32-6" run_dump_test "ilp32-7" run_dump_test "ilp32-8" run_dump_test "ilp32-9" +run_dump_test "ilp32-10" run_dump_test "ia32-1" run_dump_test "ia32-2" run_dump_test "ia32-3" diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index a445030..26f759e 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,8 @@ +2011-11-25 Pierre Muller + + * mips-dis.c (print_insn_micromips): Rename local variable iprintf + to infprintf to avoid shadow warning. + 2011-10-27 Peter Bergner * ppc-opc.c (powerpc_opcodes) fprintf_func; + const fprintf_ftype infprintf = info->fprintf_func; const struct mips_opcode *op, *opend; unsigned int lsb, msbd, msb; void *is = info->stream; @@ -2307,7 +2307,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info); if (status != 0) { - iprintf (is, "micromips 0x%x", higher); + infprintf (is, "micromips 0x%x", higher); (*info->memory_error_func) (status, memaddr + 2, info); return -1; } @@ -2320,7 +2320,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info); if (status != 0) { - iprintf (is, "micromips 0x%x", higher); + infprintf (is, "micromips 0x%x", higher); (*info->memory_error_func) (status, memaddr + 4, info); return -1; } @@ -2328,7 +2328,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) insn = bfd_getb16 (buffer); else insn = bfd_getl16 (buffer); - iprintf (is, "0x%x%04x (48-bit insn)", higher, insn); + infprintf (is, "0x%x%04x (48-bit insn)", higher, insn); info->insn_type = dis_noninsn; return 6; @@ -2341,7 +2341,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info); if (status != 0) { - iprintf (is, "micromips 0x%x", higher); + infprintf (is, "micromips 0x%x", higher); (*info->memory_error_func) (status, memaddr + 2, info); return -1; } @@ -2371,9 +2371,9 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) { const char *s; - iprintf (is, "%s", op->name); + infprintf (is, "%s", op->name); if (op->args[0] != '\0') - iprintf (is, "\t"); + infprintf (is, "\t"); for (s = op->args; *s != '\0'; s++) { @@ -2382,37 +2382,37 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) case ',': case '(': case ')': - iprintf (is, "%c", *s); + infprintf (is, "%c", *s); break; case '.': delta = GET_OP (insn, OFFSET10); if (delta & 0x200) delta |= ~0x3ff; - iprintf (is, "%d", delta); + infprintf (is, "%d", delta); break; case '1': - iprintf (is, "0x%lx", GET_OP (insn, STYPE)); + infprintf (is, "0x%lx", GET_OP (insn, STYPE)); break; case '<': - iprintf (is, "0x%lx", GET_OP (insn, SHAMT)); + infprintf (is, "0x%lx", GET_OP (insn, SHAMT)); break; case '\\': - iprintf (is, "0x%lx", GET_OP (insn, 3BITPOS)); + infprintf (is, "0x%lx", GET_OP (insn, 3BITPOS)); break; case '|': - iprintf (is, "0x%lx", GET_OP (insn, TRAP)); + infprintf (is, "0x%lx", GET_OP (insn, TRAP)); break; case '~': delta = GET_OP (insn, OFFSET12); if (delta & 0x800) delta |= ~0x7ff; - iprintf (is, "%d", delta); + infprintf (is, "%d", delta); break; case 'a': @@ -2433,34 +2433,34 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) case 'r': case 's': case 'v': - iprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS)]); + infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS)]); break; case 'c': - iprintf (is, "0x%lx", GET_OP (insn, CODE)); + infprintf (is, "0x%lx", GET_OP (insn, CODE)); break; case 'd': - iprintf (is, "%s", mips_gpr_names[GET_OP (insn, RD)]); + infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RD)]); break; case 'h': - iprintf (is, "0x%lx", GET_OP (insn, PREFX)); + infprintf (is, "0x%lx", GET_OP (insn, PREFX)); break; case 'i': case 'u': - iprintf (is, "0x%lx", GET_OP (insn, IMMEDIATE)); + infprintf (is, "0x%lx", GET_OP (insn, IMMEDIATE)); break; case 'j': /* Same as i, but sign-extended. */ case 'o': delta = (GET_OP (insn, DELTA) ^ 0x8000) - 0x8000; - iprintf (is, "%d", delta); + infprintf (is, "%d", delta); break; case 'k': - iprintf (is, "0x%x", GET_OP (insn, CACHE)); + infprintf (is, "0x%x", GET_OP (insn, CACHE)); break; case 'n': @@ -2472,26 +2472,26 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) if (s_reg_encode != 0) { if (s_reg_encode == 1) - iprintf (is, "%s", mips_gpr_names[16]); + infprintf (is, "%s", mips_gpr_names[16]); else if (s_reg_encode < 9) - iprintf (is, "%s-%s", + infprintf (is, "%s-%s", mips_gpr_names[16], mips_gpr_names[15 + s_reg_encode]); else if (s_reg_encode == 9) - iprintf (is, "%s-%s,%s", + infprintf (is, "%s-%s,%s", mips_gpr_names[16], mips_gpr_names[23], mips_gpr_names[30]); else - iprintf (is, "UNKNOWN"); + infprintf (is, "UNKNOWN"); } if (immed & 0x10) /* For ra. */ { if (s_reg_encode == 0) - iprintf (is, "%s", mips_gpr_names[31]); + infprintf (is, "%s", mips_gpr_names[31]); else - iprintf (is, ",%s", mips_gpr_names[31]); + infprintf (is, ",%s", mips_gpr_names[31]); } break; } @@ -2504,32 +2504,32 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) break; case 'q': - iprintf (is, "0x%lx", GET_OP (insn, CODE2)); + infprintf (is, "0x%lx", GET_OP (insn, CODE2)); break; case 't': case 'w': - iprintf (is, "%s", mips_gpr_names[GET_OP (insn, RT)]); + infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RT)]); break; case 'y': - iprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS3)]); + infprintf (is, "%s", mips_gpr_names[GET_OP (insn, RS3)]); break; case 'z': - iprintf (is, "%s", mips_gpr_names[0]); + infprintf (is, "%s", mips_gpr_names[0]); break; case 'B': - iprintf (is, "0x%lx", GET_OP (insn, CODE10)); + infprintf (is, "0x%lx", GET_OP (insn, CODE10)); break; case 'C': - iprintf (is, "0x%lx", GET_OP (insn, COPZ)); + infprintf (is, "0x%lx", GET_OP (insn, COPZ)); break; case 'D': - iprintf (is, "%s", mips_fpr_names[GET_OP (insn, FD)]); + infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FD)]); break; case 'E': @@ -2540,7 +2540,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) 'T' format. Therefore, until we gain understanding of cp2 register names, we can simply print the register numbers. */ - iprintf (is, "$%ld", GET_OP (insn, RT)); + infprintf (is, "$%ld", GET_OP (insn, RT)); break; case 'G': @@ -2559,44 +2559,44 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) case 0x000002fc: /* mtc0 */ case 0x580000fc: /* dmfc0 */ case 0x580002fc: /* dmtc0 */ - iprintf (is, "%s", mips_cp0_names[GET_OP (insn, RS)]); + infprintf (is, "%s", mips_cp0_names[GET_OP (insn, RS)]); break; default: - iprintf (is, "$%ld", GET_OP (insn, RS)); + infprintf (is, "$%ld", GET_OP (insn, RS)); break; } break; case 'H': - iprintf (is, "%ld", GET_OP (insn, SEL)); + infprintf (is, "%ld", GET_OP (insn, SEL)); break; case 'K': - iprintf (is, "%s", mips_hwr_names[GET_OP (insn, RS)]); + infprintf (is, "%s", mips_hwr_names[GET_OP (insn, RS)]); break; case 'M': - iprintf (is, "$fcc%ld", GET_OP (insn, CCC)); + infprintf (is, "$fcc%ld", GET_OP (insn, CCC)); break; case 'N': - iprintf (is, + infprintf (is, (op->pinfo & (FP_D | FP_S)) != 0 ? "$fcc%ld" : "$cc%ld", GET_OP (insn, BCC)); break; case 'R': - iprintf (is, "%s", mips_fpr_names[GET_OP (insn, FR)]); + infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FR)]); break; case 'S': case 'V': - iprintf (is, "%s", mips_fpr_names[GET_OP (insn, FS)]); + infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FS)]); break; case 'T': - iprintf (is, "%s", mips_fpr_names[GET_OP (insn, FT)]); + infprintf (is, "%s", mips_fpr_names[GET_OP (insn, FT)]); break; case '+': @@ -2606,18 +2606,18 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) { case 'A': lsb = GET_OP (insn, EXTLSB); - iprintf (is, "0x%x", lsb); + infprintf (is, "0x%x", lsb); break; case 'B': msb = GET_OP (insn, INSMSB); - iprintf (is, "0x%x", msb - lsb + 1); + infprintf (is, "0x%x", msb - lsb + 1); break; case 'C': case 'H': msbd = GET_OP (insn, EXTMSBD); - iprintf (is, "0x%x", msbd + 1); + infprintf (is, "0x%x", msbd + 1); break; case 'D': @@ -2637,30 +2637,30 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) mips_cp0sel_names_len, cp0reg, sel); if (n != NULL) - iprintf (is, "%s", n->name); + infprintf (is, "%s", n->name); else - iprintf (is, "$%d,%d", cp0reg, sel); + infprintf (is, "$%d,%d", cp0reg, sel); break; } case 'E': lsb = GET_OP (insn, EXTLSB) + 32; - iprintf (is, "0x%x", lsb); + infprintf (is, "0x%x", lsb); break; case 'F': msb = GET_OP (insn, INSMSB) + 32; - iprintf (is, "0x%x", msb - lsb + 1); + infprintf (is, "0x%x", msb - lsb + 1); break; case 'G': msbd = GET_OP (insn, EXTMSBD) + 32; - iprintf (is, "0x%x", msbd + 1); + infprintf (is, "0x%x", msbd + 1); break; default: /* xgettext:c-format */ - iprintf (is, + infprintf (is, _("# internal disassembler error, " "unrecognized modifier (+%c)"), *s); @@ -2674,111 +2674,111 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) switch (*s) { case 'a': /* global pointer. */ - iprintf (is, "%s", mips_gpr_names[28]); + infprintf (is, "%s", mips_gpr_names[28]); break; case 'b': regno = micromips_to_32_reg_b_map[GET_OP (insn, MB)]; - iprintf (is, "%s", mips_gpr_names[regno]); + infprintf (is, "%s", mips_gpr_names[regno]); break; case 'c': regno = micromips_to_32_reg_c_map[GET_OP (insn, MC)]; - iprintf (is, "%s", mips_gpr_names[regno]); + infprintf (is, "%s", mips_gpr_names[regno]); break; case 'd': regno = micromips_to_32_reg_d_map[GET_OP (insn, MD)]; - iprintf (is, "%s", mips_gpr_names[regno]); + infprintf (is, "%s", mips_gpr_names[regno]); break; case 'e': regno = micromips_to_32_reg_e_map[GET_OP (insn, ME)]; - iprintf (is, "%s", mips_gpr_names[regno]); + infprintf (is, "%s", mips_gpr_names[regno]); break; case 'f': /* Save lastregno for "mt" to print out later. */ lastregno = micromips_to_32_reg_f_map[GET_OP (insn, MF)]; - iprintf (is, "%s", mips_gpr_names[lastregno]); + infprintf (is, "%s", mips_gpr_names[lastregno]); break; case 'g': regno = micromips_to_32_reg_g_map[GET_OP (insn, MG)]; - iprintf (is, "%s", mips_gpr_names[regno]); + infprintf (is, "%s", mips_gpr_names[regno]); break; case 'h': regno = micromips_to_32_reg_h_map[GET_OP (insn, MH)]; - iprintf (is, "%s", mips_gpr_names[regno]); + infprintf (is, "%s", mips_gpr_names[regno]); break; case 'i': regno = micromips_to_32_reg_i_map[GET_OP (insn, MI)]; - iprintf (is, "%s", mips_gpr_names[regno]); + infprintf (is, "%s", mips_gpr_names[regno]); break; case 'j': - iprintf (is, "%s", mips_gpr_names[GET_OP (insn, MJ)]); + infprintf (is, "%s", mips_gpr_names[GET_OP (insn, MJ)]); break; case 'l': regno = micromips_to_32_reg_l_map[GET_OP (insn, ML)]; - iprintf (is, "%s", mips_gpr_names[regno]); + infprintf (is, "%s", mips_gpr_names[regno]); break; case 'm': regno = micromips_to_32_reg_m_map[GET_OP (insn, MM)]; - iprintf (is, "%s", mips_gpr_names[regno]); + infprintf (is, "%s", mips_gpr_names[regno]); break; case 'n': regno = micromips_to_32_reg_n_map[GET_OP (insn, MN)]; - iprintf (is, "%s", mips_gpr_names[regno]); + infprintf (is, "%s", mips_gpr_names[regno]); break; case 'p': /* Save lastregno for "mt" to print out later. */ lastregno = GET_OP (insn, MP); - iprintf (is, "%s", mips_gpr_names[lastregno]); + infprintf (is, "%s", mips_gpr_names[lastregno]); break; case 'q': regno = micromips_to_32_reg_q_map[GET_OP (insn, MQ)]; - iprintf (is, "%s", mips_gpr_names[regno]); + infprintf (is, "%s", mips_gpr_names[regno]); break; case 'r': /* program counter. */ - iprintf (is, "$pc"); + infprintf (is, "$pc"); break; case 's': /* stack pointer. */ lastregno = 29; - iprintf (is, "%s", mips_gpr_names[29]); + infprintf (is, "%s", mips_gpr_names[29]); break; case 't': - iprintf (is, "%s", mips_gpr_names[lastregno]); + infprintf (is, "%s", mips_gpr_names[lastregno]); break; case 'z': /* $0. */ - iprintf (is, "%s", mips_gpr_names[0]); + infprintf (is, "%s", mips_gpr_names[0]); break; case 'A': /* Sign-extend the immediate. */ immed = ((GET_OP (insn, IMMA) ^ 0x40) - 0x40) << 2; - iprintf (is, "%d", immed); + infprintf (is, "%d", immed); break; case 'B': immed = micromips_imm_b_map[GET_OP (insn, IMMB)]; - iprintf (is, "%d", immed); + infprintf (is, "%d", immed); break; case 'C': immed = micromips_imm_c_map[GET_OP (insn, IMMC)]; - iprintf (is, "0x%lx", immed); + infprintf (is, "0x%lx", immed); break; case 'D': @@ -2797,50 +2797,50 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) case 'F': immed = GET_OP (insn, IMMF); - iprintf (is, "0x%x", immed); + infprintf (is, "0x%x", immed); break; case 'G': immed = (insn >> MICROMIPSOP_SH_IMMG) + 1; immed = (immed & MICROMIPSOP_MASK_IMMG) - 1; - iprintf (is, "%d", immed); + infprintf (is, "%d", immed); break; case 'H': immed = GET_OP (insn, IMMH) << 1; - iprintf (is, "%d", immed); + infprintf (is, "%d", immed); break; case 'I': immed = (insn >> MICROMIPSOP_SH_IMMI) + 1; immed = (immed & MICROMIPSOP_MASK_IMMI) - 1; - iprintf (is, "%d", immed); + infprintf (is, "%d", immed); break; case 'J': immed = GET_OP (insn, IMMJ) << 2; - iprintf (is, "%d", immed); + infprintf (is, "%d", immed); break; case 'L': immed = GET_OP (insn, IMML); - iprintf (is, "%d", immed); + infprintf (is, "%d", immed); break; case 'M': immed = (insn >> MICROMIPSOP_SH_IMMM) - 1; immed = (immed & MICROMIPSOP_MASK_IMMM) + 1; - iprintf (is, "%d", immed); + infprintf (is, "%d", immed); break; case 'N': immed = GET_OP (insn, IMMN); if (immed == 0) - iprintf (is, "%s,%s", + infprintf (is, "%s,%s", mips_gpr_names[16], mips_gpr_names[31]); else - iprintf (is, "%s-%s,%s", + infprintf (is, "%s-%s,%s", mips_gpr_names[16], mips_gpr_names[16 + immed], mips_gpr_names[31]); @@ -2848,35 +2848,35 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) case 'O': immed = GET_OP (insn, IMMO); - iprintf (is, "0x%x", immed); + infprintf (is, "0x%x", immed); break; case 'P': immed = GET_OP (insn, IMMP) << 2; - iprintf (is, "%d", immed); + infprintf (is, "%d", immed); break; case 'Q': /* Sign-extend the immediate. */ immed = (GET_OP (insn, IMMQ) ^ 0x400000) - 0x400000; immed <<= 2; - iprintf (is, "%d", immed); + infprintf (is, "%d", immed); break; case 'U': immed = GET_OP (insn, IMMU) << 2; - iprintf (is, "%d", immed); + infprintf (is, "%d", immed); break; case 'W': immed = GET_OP (insn, IMMW) << 2; - iprintf (is, "%d", immed); + infprintf (is, "%d", immed); break; case 'X': /* Sign-extend the immediate. */ immed = (GET_OP (insn, IMMX) ^ 0x8) - 0x8; - iprintf (is, "%d", immed); + infprintf (is, "%d", immed); break; case 'Y': @@ -2885,12 +2885,12 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) if (immed >= -2 && immed <= 1) immed ^= 0x100; immed = immed << 2; - iprintf (is, "%d", immed); + infprintf (is, "%d", immed); break; default: /* xgettext:c-format */ - iprintf (is, + infprintf (is, _("# internal disassembler error, " "unrecognized modifier (m%c)"), *s); @@ -2900,7 +2900,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) default: /* xgettext:c-format */ - iprintf (is, + infprintf (is, _("# internal disassembler error, " "unrecognized modifier (%c)"), *s); @@ -2937,7 +2937,7 @@ print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info) } #undef GET_OP - iprintf (is, "0x%x", insn); + infprintf (is, "0x%x", insn); info->insn_type = dis_noninsn; return length;