diff options
author | obrien <obrien@FreeBSD.org> | 2002-07-05 20:16:34 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2002-07-05 20:16:34 +0000 |
commit | f3c54bd2c1850601b80aa0558b8843517125f50f (patch) | |
tree | 30918b465d458ef1aca113937ad46b1e912ce044 | |
parent | 18ff9f4f1bddd11c341a37177885ac89fcccedd9 (diff) | |
download | FreeBSD-src-f3c54bd2c1850601b80aa0558b8843517125f50f.zip FreeBSD-src-f3c54bd2c1850601b80aa0558b8843517125f50f.tar.gz |
Import of Binutils from the FSF 2.12 branch (just post-.1 release).
These bits are taken from the FSF anoncvs repo on 22-June-2002 23:28:00 EDT.
105 files changed, 13301 insertions, 3072 deletions
diff --git a/contrib/binutils/bfd/ChangeLog b/contrib/binutils/bfd/ChangeLog index f58ffce..987bd68 100644 --- a/contrib/binutils/bfd/ChangeLog +++ b/contrib/binutils/bfd/ChangeLog @@ -1,3 +1,311 @@ +2002-05-14 Daniel Jacobowitz <drow@mvista.com> + + * configure.in: Set is_release=y for 2.12.1 release. + * configure: Likewise. + +2002-05-13 David Edelsohn <edelsohn@gnu.org> + + * configure.in: Auto-configure HAVE_ST_C_IMPL. + * configure: Regenerate. + * config.in: Regenerate. + * rs6000-core.c (CNEW_IMPL): Guard use of c_impl with HAVE_ST_C_IMPL + or AIX_5_CORE. + +2002-05-11 Daniel Jacobowitz <drow@mvista.com> + + Merge from mainline (to elf32-mips.c): + 2002-05-03 H.J. Lu (hjl@gnu.org) + + * elfxx-mips.c (mips_elf_link_hash_entry): Add forced_local. + (mips_elf_link_hash_newfunc): Initialize forced_local to false. + (mips_elf_record_global_got_symbol): Call _bfd_mips_elf_hide_symbol + to hide a global symbol. + (_bfd_mips_elf_hide_symbol): Return if forced_local is true. Set + forced_local to true. + +2002-05-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de> + Daniel Jacobowitz <drow@mvista.com> + + * coff-sh.c (sh_reloc_map): Map to R_SH_IMM32 for non-PE. Don't + map BFD_RELOC_RVA. + +2002-05-09 Alan Modra <amodra@bigpond.net.au> + + * elf64-ppc.c (RA_REGISTER_MASK, RA_REGISTER_SHIFT): Delete. + + Merge from mainline + 2002-05-08 Alan Modra <amodra@bigpond.net.au> + * elf32-ppc.c (ppc_elf_create_got): New function. + (ppc_elf_create_dynamic_sections): Call ppc_elf_create_got before + _bfd_elf_create_dynamic_sections. Correct .plt flags. + (ppc_elf_check_relocs): Use ppc_elf_create_got in place of + _bfd_elf_create_got_section. + + 2002-05-07 Alan Modra <amodra@bigpond.net.au> + * elf-bfd.h (struct elf_backend_data): Add rela_normal. + * elfxx-target.h (elf_backend_rela_normal): Define. + (elfNN_bed): Init rela_normal. + * elflink.h (elf_link_input_bfd <emit_relocs>): Handle adjustment + for section symbols here if rela_normal. Simplify abs section test. + * elf-m10200.c (mn10200_elf_relocate_section): If relocatable, + return immediately. Remove code handling relocatable linking. + * elf-m10300.c (mn10300_elf_relocate_section): Likewise. + * elf32-fr30.c (fr30_elf_relocate_section): Likewise. + * elf32-i370.c (i370_elf_relocate_section): Likewise. + * elf32-i860.c (elf32_i860_relocate_section): Likewise. + * elf32-m68k.c (elf_m68k_relocate_section): Likewise. + * elf32-mcore.c (mcore_elf_relocate_section): Likewise. + * elf32-openrisc.c (openrisc_elf_relocate_section): Likewise. + * elf32-ppc.c (ppc_elf_relocate_section): Likewise. + * elf32-s390.c (elf_s390_relocate_section): Likewise. + * elf32-xstormy16.c (xstormy16_elf_relocate_section): Likewise. + * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. + * elf64-s390.c (elf_s390_relocate_section): Likewise. + * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise. + * elfxx-ia64.c (elfNN_ia64_relocate_section): Likewise. + * elf32-arm.h (elf32_arm_relocate_section): Likewise #ifndef USE_REL. + * elf32-m32r.c (m32r_elf_relocate_section): Likewise. + * elf-m10200.c (elf_backend_rela_normal): Define. + * elf-m10300.c (elf_backend_rela_normal): Define. + * elf32-fr30.c (elf_backend_rela_normal): Define. + * elf32-i370.c (elf_backend_rela_normal): Define. + * elf32-i860.c (elf_backend_rela_normal): Define. + * elf32-m68k.c (elf_backend_rela_normal): Define. + * elf32-mcore.c (elf_backend_rela_normal): Define. + * elf32-openrisc.c (elf_backend_rela_normal): Define. + * elf32-ppc.c (elf_backend_rela_normal): Define. + * elf32-s390.c (elf_backend_rela_normal): Define. + * elf32-xstormy16.c (elf_backend_rela_normal): Define. + * elf64-ppc.c (elf_backend_rela_normal): Define. + * elf64-s390.c (elf_backend_rela_normal): Define. + * elf64-x86-64.c (elf_backend_rela_normal): Define. + * elfxx-ia64.c (elf_backend_rela_normal): Define. + * elf32-arm.h (elf_backend_rela_normal): Define #ifndef USE_REL. + * elf32-m32r.c (elf_backend_rela_normal): Likewise. + + 2002-05-06 Alan Modra <amodra@bigpond.net.au> + * elflink.h (elf_link_input_bfd <emit_relocs>): Adjust r_offset + when not relocatable. Fix reloc_emitter call for K&R. + + 2002-05-04 Alan Modra <amodra@bigpond.net.au> + * dwarf2.c (struct line_head): Make prologue_length a bfd_vma. + (read_abbrevs): Change "offset" param to bfd_vma. + (parse_comp_unit): Change "version" and addr_size to unsigned ints. + Change "abbrev_offset" to bfd_vma. + (read_indirect_string): Use correct conversion chars in error + message format string, cast bfd_vma's to unsigned long. + (read_abbrevs): Likewise. + (read_attribute_value): Likewise. + (decode_line_info): Likewise. + (scan_unit_for_functions): Likewise. + (parse_comp_unit): Likewise. + + 2002-05-04 Bob Byrnes <byrnes@curl.com> + * opncls.c (_bfd_new_bfd_contained_in): Check return value of + _bfd_new_bfd. + + 2002-05-02 Alan Modra <amodra@bigpond.net.au> + * elf64-ppc.c (ppc64_elf_howto_raw <R_PPC64_SECTOFF>): Change to a + 16 bit reloc. + <R_PPC64_SECTOFF_DS>: Likewise. + (ppc64_elf_reloc_type_lookup): Map from BFD_RELOC_16_BASEREL to + SECTOFF reloc. + * elf32-ppc.c (ppc_elf_howto_raw <R_PPC_SECTOFF>): Correct. + (ppc_elf_reloc_type_lookup): Map from BFD_RELOC_16_BASEREL to + SECTOFF reloc. + * elf64-ppc.c (ppc64_elf_addr16_ha_reloc): Delete. + (ppc64_elf_ha_reloc): New function. + (ppc64_elf_brtaken_reloc): New function. + (ppc64_elf_sectoff_reloc): New function. + (ppc64_elf_sectoff_ha_reloc): New function. + (ppc64_elf_toc_reloc): New function. + (ppc64_elf_toc_ha_reloc): New function. + (ppc64_elf_toc64_reloc): New function. + (ppc64_elf_unhandled_reloc): New function. + (ppc64_elf_howto_raw): Use the above. + <R_PPC64_RELATIVE>: Mark pc_relative, pcrel_offset. + <R_PPC64_SECTOFF>: Not pc_relative or pcrel_offset. Fix dst_mask. + <R_PPC64_SECTOFF_DS>: Likewise. + (IS_ABSOLUTE_RELOC): Update. + (struct ppc_link_hash_table): Add have_undefweak. + (ppc64_elf_link_hash_table_create): Init. + (func_desc_adjust): Set have_undefweak. + (ppc64_elf_func_desc_adjust): Call func_desc_adjust earlier. Only + add the .sfpr blr when have_undefweak. + (ppc64_elf_set_toc): Rename to ppc64_elf_toc, remove info param + and relocatable test. Return TOCstart and don't set elf_gp. + (ppc64_elf_relocate_section): Correct BRTAKEN/BRNTAKEN branch + offset calculation. Add assert on weak sym branch tweaks. + * elf64-ppc.h (ppc64_elf_set_toc): Delete. + (ppc64_elf_toc): Declare. + + 2002-05-01 Alan Modra <amodra@bigpond.net.au> + * syms.c (_bfd_stab_section_find_nearest_line): Don't bomb on NULL + file_name. + + 2002-05-01 Alan Modra <amodra@bigpond.net.au> + * elf64-ppc.c (CROR_151515, CROR_313131): Define. + (ppc64_elf_relocate_section): Use them. Don't look for plt calls + on R_PPC64_ADDR24 relocs. Require a nop or no link reg on plt + call branches. Correct undefined weak destination. + (ppc64_elf_func_desc_adjust): Always create at least one blr in + .sfpr, and correct case where either only savef* or restf* is + needed. + + 2002-04-09 DJ Delorie <dj@redhat.com> + * elfarm-nabi.c (elf32_arm_howto_table): Fix ABS16 masks. + +2002-05-06 Nick Clifton <nickc@cambridge.redhat.com> + + * elf32-arm.h (elf32_arm_final_link_relocate): Convert + 'reloc_signed_max' and 'reloc_signed_min' into half-word offsets. + +2002-05-02 Richard Henderson <rth@redhat.com> + + * elf64-alpha.c (elf64_alpha_relocate_section): Force relative relocs + vs SHN_UNDEF to zero. + +2002-04-27 Alan Modra <amodra@bigpond.net.au> + + Merge from mainline + 2002-04-12 Alan Modra <amodra@bigpond.net.au> + * elf.c (prep_headers): Don't zero EI_OSABI, EI_ABIVERSION or + header pad. + + 2002-02-21 Andreas Jaeger <aj@suse.de> + * elf64-x86-64.c: Major rework that introduces all recent changes + to the x86-64 backend. Get a closer match to elf32-i386. + (struct elf64_x86_64_dyn_relocs): Rename from + elf64_x86_64_pcrel_relocs_copied, add additional fields. Change + all users. + (struct elf64_x86_64_link_hash_table): Add short cuts to some + sections. + (link_hash_newfunc): Rename from elf64_x86_64_link_hash_newfunc, + remove casts, initialize new hash members. + (create_got_section): New. + (elf64_x86_64_create_dynamic_sections): New. + (elf64_x86_64_copy_indirect_symbol): New. + (elf64_x86_64_check_relocs): Don't allocate space for dynamic + relocs, .got or .relgot here but do it in allocate_dynrelocs. + Reference count possible .plt and .got entries. Don't test input + section SEC_READONLY here to try to avoid copy relocs, and keep + dyn_relocs regardless of ELF_LINK_NON_GOT_REF. Don't set + DF_TEXTREL here. Delay setting of variables until needed. Cache + pointer to "sreloc" section in elf_section_data. Tweak condition + under which .got created. Report files with bad relocation + section names. + (elf64_x86_64_gc_sweep_hook): Sweep dyn_relocs and local_dynrel. + Reference count possible .plt entries. Don't deallocate .got and + .relgot space here. + (elf64_x86_64_adjust_dynamic_symbol): Handle nocopyreloc. Don't + do copy reloc processing for weakdefs. Remove redundant casts and + aborts. Delay setting of vars until needed. Move creation of + dynamic symbols and allocation of .plt and .rela.plt to + allocate_dynrelocs. Replace BFD_ASSERT with abort. + (WILL_CALL_FINISH_DYNAMIC_SYMBOL): New. + (allocate_dynrelocs): New. + (readonly_dynrelocs): New. + (elf64_x86_64_size_dynamic_sections): Call readonly_dynrelocs. + Allocate space for dyn relocs. Replace BFD_ASSERT with abort. + Zero out the dynamic allocated content space. + (elf64_x86_64_discard_copies): Removed. + (elf64_x86_64_relocate_section): Make use of dynamic section + short-cuts. Localise vars, and delay setting. Better error + reporting, replace BFD_ASSERT with abort. Check + ELF_LINK_HASH_DEF_DYNAMIC to see if a symbol is not defined in the + regular object file and tread the weak definition as the normal + one. Don't discard relocs for undefweak or undefined symbols and + check !DEF_REGULAR as well as DEF_DYNAMIC in test for avoided copy + relocs. + (elf64_x86_64_finish_dynamic_symbol): Don't copy relocs for + symbols that have been forced local. Use same test to decide if + we can use a relative reloc for got as relocate_section. Expand + SHN_UNDEF comment. Move expressions out of function calls. + Replace BFD_ASSERT with abort. + (bfd_elf64_bfd_final_link): Removed. + (elf_backend_copy_indirect_symbol): Define. + + * reloc.c: Move sh relocs to where they belong. + * libbfd.h, bfd-in2.h: Regenerate. + + Merge from mainline + 2002-04-26 Alan Modra <amodra@bigpond.net.au> + * opncls.c (bfd_make_readable): Call bfd_section_list_clear. + * xcofflink.c (xcoff_link_add_dynamic_symbols): Likewise. + * elflink.h (elf_bfd_final_link): Ensure input bfd class is the + same as the output before calling elf_link_input_bfd. + * coffcode.h (coff_compute_section_file_positions): Set + section_tail after shuffling section list. + + 2002-04-23 Alan Modra <amodra@bigpond.net.au> + * elf32-hppa.c (hppa_type_of_stub): Correct and simplify condition + under which a plt call stub is used. + (final_link_relocate): Similarly. + (allocate_plt_static): Clear h-plabel except when plt entry is + exclusively used for a plabel. + (allocate_dynrelocs): Use the above to simplify plt sizing. + (struct elf32_hppa_link_hash_table): Add has_22bit_branch. + (elf32_hppa_link_hash_table_create): Init. + (BL22_RP): Define. + (hppa_build_one_stub): Use BL22_RP if has_22bit_branch. + (elf32_hppa_check_relocs): Set has_22bit_branch. + * elf32-hppa.c (elf32_hppa_check_relocs): Remove debug message. + (final_link_relocate): Likewise. + + 2002-04-20 Alan Modra <amodra@bigpond.net.au> + * archures.c (bfd_arch_info): Add comment on list order. + (bfd_default_set_arch_mach): Use bfd_lookup_arch. + * cpu-powerpc.c (bfd_powerpc_archs): Re-order so that the default + is always at head of list. + * bfd-in2.h: Regenerate. + + 2002-04-16 Alan Modra <amodra@bigpond.net.au> + * elf32-m32r.c (m32r_elf_add_symbol_hook): Check the hash table + type rather than just assuming entries are ELF. + * elf32-sh64.c (sh64_elf_add_symbol_hook): Likewise. + * elf64-sh64.c (sh64_elf64_add_symbol_hook): Likewise. + * elf64-sparc.c (sparc64_elf_add_symbol_hook): Likewise. + * elf64-mmix.c (mmix_elf_add_symbol_hook): Use bfd_link_hash_entry + rather than elf_link_hash_entry. + + 2002-04-15 Alan Modra <amodra@bigpond.net.au> + * elf32-ppc.c (ppc_elf_add_symbol_hook): Check the hash table type. + + 2002-04-08 Randolph Chung <tausq@debian.org> + * elf32-hppa.c (hppa_unwind_entry_compare): Move to elf-hppa.h. + (elf32_hppa_final_link): Split out sorting logic to.. + * elf-hppa.h (elf_hppa_sort_unwind): ..here. + (elf_hppa_final_link): Call elf_hppa_sort_unwind. + +2002-04-26 Richard Smith <richard@ex-parrot.com> + Jakub Jelinek <jakub@redhat.com> + + * elf-eh-frame.c (struct eh_cie_fde): Add per_encoding_relative. + (_bfd_elf_discard_section_eh_frame): Set it for CIEs with pcrel + encoded personality. + (_bfd_elf_write_section_eh_frame): Adjust pcrel encoded personality + for CIE/FDE removal. + +2002-04-26 Jakub Jelinek <jakub@redhat.com> + + * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't build + search table if some FDE is DW_EH_PE_aligned encoded either. + (_bfd_elf_write_section_eh_frame): Handle terminating FDE specially. + +2002-04-18 Nick Clifton <nickc@cambridge.redhat.com> + + * coff-arm.c (coff_thumb_pcrel_12, coff_thumb_pcrel_9, + insert_thumb_branch, record_thumb_to_arm_glue): Suppress + definition of these functions for ARM_WINCE builds as they are + not used. + (SWAP_IN_RELOC_OFFSET, SWAP_OUT_RELOC_OFFSET): Do not define + for ARM_WINCE builds. + +2002-04-16 Nick Clifton <nickc@cambridge.redhat.com> + + * ihex.c (ihex_write_object_contents): Fix check for records + crossing 64K boundaries. + 2002-04-06 Hans-Peter Nilsson <hp@axis.com> * elf32-cris.c (cris_elf_howto_table) <R_CRIS_16_PCREL, diff --git a/contrib/binutils/bfd/ChangeLog-9495 b/contrib/binutils/bfd/ChangeLog-9495 index 4657d66..a208f42 100644 --- a/contrib/binutils/bfd/ChangeLog-9495 +++ b/contrib/binutils/bfd/ChangeLog-9495 @@ -6887,7 +6887,7 @@ Tue May 24 16:17:18 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) * libelf.h (struct elf_obj_tdata): Add new field bad_symtab. (elf_bad_symtab): Define new accessor macro. (_bfd_elf_link_hash_newfunc): Declare. - (_bew_elf_link_hash_table_init): Declare. + (_bfd_elf_link_hash_table_init): Declare. * elfcode.h (elf_object_p): Call backend object_p hook after swapping in all the section headers. (map_program_segments): Correct typo: Internal for External. diff --git a/contrib/binutils/bfd/archures.c b/contrib/binutils/bfd/archures.c index 9a91424..40102e8 100644 --- a/contrib/binutils/bfd/archures.c +++ b/contrib/binutils/bfd/archures.c @@ -288,7 +288,9 @@ DESCRIPTION . const char *arch_name; . const char *printable_name; . unsigned int section_align_power; -. {* True if this is the default machine for the architecture. *} +. {* True if this is the default machine for the architecture. +. The default arch should be the first entry for an arch so that +. all the entries for that arch can be accessed via <<next>>. *} . boolean the_default; . const struct bfd_arch_info * (*compatible) . PARAMS ((const struct bfd_arch_info *a, @@ -604,21 +606,9 @@ bfd_default_set_arch_mach (abfd, arch, mach) enum bfd_architecture arch; unsigned long mach; { - const bfd_arch_info_type * const *app, *ap; - - for (app = bfd_archures_list; *app != NULL; app++) - { - for (ap = *app; ap != NULL; ap = ap->next) - { - if (ap->arch == arch - && (ap->mach == mach - || (mach == 0 && ap->the_default))) - { - abfd->arch_info = ap; - return true; - } - } - } + abfd->arch_info = bfd_lookup_arch (arch, mach); + if (abfd->arch_info != NULL) + return true; abfd->arch_info = &bfd_default_arch_struct; bfd_set_error (bfd_error_bad_value); diff --git a/contrib/binutils/bfd/bfd-in2.h b/contrib/binutils/bfd/bfd-in2.h index 93696ae..a69b375 100644 --- a/contrib/binutils/bfd/bfd-in2.h +++ b/contrib/binutils/bfd/bfd-in2.h @@ -1657,7 +1657,9 @@ typedef struct bfd_arch_info const char *arch_name; const char *printable_name; unsigned int section_align_power; - /* True if this is the default machine for the architecture. */ + /* True if this is the default machine for the architecture. + The default arch should be the first entry for an arch so that + all the entries for that arch can be accessed via <<next>>. */ boolean the_default; const struct bfd_arch_info * (*compatible) PARAMS ((const struct bfd_arch_info *a, @@ -2194,55 +2196,6 @@ to compensate for the borrow when the low bits are added. */ BFD_RELOC_MIPS_REL16, BFD_RELOC_MIPS_RELGOT, BFD_RELOC_MIPS_JALR, - BFD_RELOC_SH_GOT_LOW16, - BFD_RELOC_SH_GOT_MEDLOW16, - BFD_RELOC_SH_GOT_MEDHI16, - BFD_RELOC_SH_GOT_HI16, - BFD_RELOC_SH_GOTPLT_LOW16, - BFD_RELOC_SH_GOTPLT_MEDLOW16, - BFD_RELOC_SH_GOTPLT_MEDHI16, - BFD_RELOC_SH_GOTPLT_HI16, - BFD_RELOC_SH_PLT_LOW16, - BFD_RELOC_SH_PLT_MEDLOW16, - BFD_RELOC_SH_PLT_MEDHI16, - BFD_RELOC_SH_PLT_HI16, - BFD_RELOC_SH_GOTOFF_LOW16, - BFD_RELOC_SH_GOTOFF_MEDLOW16, - BFD_RELOC_SH_GOTOFF_MEDHI16, - BFD_RELOC_SH_GOTOFF_HI16, - BFD_RELOC_SH_GOTPC_LOW16, - BFD_RELOC_SH_GOTPC_MEDLOW16, - BFD_RELOC_SH_GOTPC_MEDHI16, - BFD_RELOC_SH_GOTPC_HI16, - BFD_RELOC_SH_COPY64, - BFD_RELOC_SH_GLOB_DAT64, - BFD_RELOC_SH_JMP_SLOT64, - BFD_RELOC_SH_RELATIVE64, - BFD_RELOC_SH_GOT10BY4, - BFD_RELOC_SH_GOT10BY8, - BFD_RELOC_SH_GOTPLT10BY4, - BFD_RELOC_SH_GOTPLT10BY8, - BFD_RELOC_SH_GOTPLT32, - BFD_RELOC_SH_SHMEDIA_CODE, - BFD_RELOC_SH_IMMU5, - BFD_RELOC_SH_IMMS6, - BFD_RELOC_SH_IMMS6BY32, - BFD_RELOC_SH_IMMU6, - BFD_RELOC_SH_IMMS10, - BFD_RELOC_SH_IMMS10BY2, - BFD_RELOC_SH_IMMS10BY4, - BFD_RELOC_SH_IMMS10BY8, - BFD_RELOC_SH_IMMS16, - BFD_RELOC_SH_IMMU16, - BFD_RELOC_SH_IMM_LOW16, - BFD_RELOC_SH_IMM_LOW16_PCREL, - BFD_RELOC_SH_IMM_MEDLOW16, - BFD_RELOC_SH_IMM_MEDLOW16_PCREL, - BFD_RELOC_SH_IMM_MEDHI16, - BFD_RELOC_SH_IMM_MEDHI16_PCREL, - BFD_RELOC_SH_IMM_HI16, - BFD_RELOC_SH_IMM_HI16_PCREL, - BFD_RELOC_SH_PT_16, /* i386/elf relocations */ @@ -2423,6 +2376,55 @@ field in the instruction. */ BFD_RELOC_SH_JMP_SLOT, BFD_RELOC_SH_RELATIVE, BFD_RELOC_SH_GOTPC, + BFD_RELOC_SH_GOT_LOW16, + BFD_RELOC_SH_GOT_MEDLOW16, + BFD_RELOC_SH_GOT_MEDHI16, + BFD_RELOC_SH_GOT_HI16, + BFD_RELOC_SH_GOTPLT_LOW16, + BFD_RELOC_SH_GOTPLT_MEDLOW16, + BFD_RELOC_SH_GOTPLT_MEDHI16, + BFD_RELOC_SH_GOTPLT_HI16, + BFD_RELOC_SH_PLT_LOW16, + BFD_RELOC_SH_PLT_MEDLOW16, + BFD_RELOC_SH_PLT_MEDHI16, + BFD_RELOC_SH_PLT_HI16, + BFD_RELOC_SH_GOTOFF_LOW16, + BFD_RELOC_SH_GOTOFF_MEDLOW16, + BFD_RELOC_SH_GOTOFF_MEDHI16, + BFD_RELOC_SH_GOTOFF_HI16, + BFD_RELOC_SH_GOTPC_LOW16, + BFD_RELOC_SH_GOTPC_MEDLOW16, + BFD_RELOC_SH_GOTPC_MEDHI16, + BFD_RELOC_SH_GOTPC_HI16, + BFD_RELOC_SH_COPY64, + BFD_RELOC_SH_GLOB_DAT64, + BFD_RELOC_SH_JMP_SLOT64, + BFD_RELOC_SH_RELATIVE64, + BFD_RELOC_SH_GOT10BY4, + BFD_RELOC_SH_GOT10BY8, + BFD_RELOC_SH_GOTPLT10BY4, + BFD_RELOC_SH_GOTPLT10BY8, + BFD_RELOC_SH_GOTPLT32, + BFD_RELOC_SH_SHMEDIA_CODE, + BFD_RELOC_SH_IMMU5, + BFD_RELOC_SH_IMMS6, + BFD_RELOC_SH_IMMS6BY32, + BFD_RELOC_SH_IMMU6, + BFD_RELOC_SH_IMMS10, + BFD_RELOC_SH_IMMS10BY2, + BFD_RELOC_SH_IMMS10BY4, + BFD_RELOC_SH_IMMS10BY8, + BFD_RELOC_SH_IMMS16, + BFD_RELOC_SH_IMMU16, + BFD_RELOC_SH_IMM_LOW16, + BFD_RELOC_SH_IMM_LOW16_PCREL, + BFD_RELOC_SH_IMM_MEDLOW16, + BFD_RELOC_SH_IMM_MEDLOW16_PCREL, + BFD_RELOC_SH_IMM_MEDHI16, + BFD_RELOC_SH_IMM_MEDHI16_PCREL, + BFD_RELOC_SH_IMM_HI16, + BFD_RELOC_SH_IMM_HI16_PCREL, + BFD_RELOC_SH_PT_16, /* Thumb 23-, 12- and 9-bit pc-relative branches. The lowest bit must be zero and is not stored in the instruction. */ diff --git a/contrib/binutils/bfd/coff-arm.c b/contrib/binutils/bfd/coff-arm.c index 798cd49..c92cbe6 100644 --- a/contrib/binutils/bfd/coff-arm.c +++ b/contrib/binutils/bfd/coff-arm.c @@ -87,12 +87,16 @@ static bfd_reloc_status_type aoutarm_fix_pcrel_26_done PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); static bfd_reloc_status_type aoutarm_fix_pcrel_26 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +#ifndef ARM_WINCE static bfd_reloc_status_type coff_thumb_pcrel_23 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static bfd_reloc_status_type coff_thumb_pcrel_12 - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); static bfd_reloc_status_type coff_thumb_pcrel_9 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static insn32 insert_thumb_branch + PARAMS ((insn32, int)); +#endif +static bfd_reloc_status_type coff_thumb_pcrel_12 + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); static bfd_reloc_status_type coff_arm_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); static boolean coff_arm_adjust_symndx @@ -109,8 +113,6 @@ static const struct reloc_howto_struct * coff_arm_reloc_type_lookup PARAMS ((bfd *, bfd_reloc_code_real_type)); static struct bfd_link_hash_table * coff_arm_link_hash_table_create PARAMS ((bfd *)); -static insn32 insert_thumb_branch - PARAMS ((insn32, int)); static struct coff_link_hash_entry * find_thumb_glue PARAMS ((struct bfd_link_info *, const char *, bfd *)); static struct coff_link_hash_entry * find_arm_glue @@ -118,9 +120,11 @@ static struct coff_link_hash_entry * find_arm_glue #ifndef COFF_IMAGE_WITH_PE static void record_arm_to_thumb_glue PARAMS ((struct bfd_link_info *, struct coff_link_hash_entry *)); +#ifndef ARM_WINCE static void record_thumb_to_arm_glue PARAMS ((struct bfd_link_info *, struct coff_link_hash_entry *)); #endif +#endif static boolean coff_arm_merge_private_bfd_data PARAMS ((bfd *, bfd *)); static boolean coff_arm_print_private_bfd_data @@ -801,6 +805,7 @@ coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, input_section, return flag; } +#ifndef ARM_WINCE static bfd_reloc_status_type coff_thumb_pcrel_23 (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) @@ -818,7 +823,7 @@ coff_thumb_pcrel_23 (abfd, reloc_entry, symbol, data, input_section, } static bfd_reloc_status_type -coff_thumb_pcrel_12 (abfd, reloc_entry, symbol, data, input_section, +coff_thumb_pcrel_9 (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) bfd *abfd; arelent *reloc_entry; @@ -830,11 +835,12 @@ coff_thumb_pcrel_12 (abfd, reloc_entry, symbol, data, input_section, { return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message, - b12); + b9); } +#endif /* not ARM_WINCE */ static bfd_reloc_status_type -coff_thumb_pcrel_9 (abfd, reloc_entry, symbol, data, input_section, +coff_thumb_pcrel_12 (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message) bfd *abfd; arelent *reloc_entry; @@ -846,7 +852,7 @@ coff_thumb_pcrel_9 (abfd, reloc_entry, symbol, data, input_section, { return coff_thumb_pcrel_common (abfd, reloc_entry, symbol, data, input_section, output_bfd, error_message, - b9); + b12); } static const struct reloc_howto_struct * @@ -900,10 +906,12 @@ coff_arm_reloc_type_lookup (abfd, code) #define BADMAG(x) ARMBADMAG(x) #define ARM 1 /* Customize coffcode.h */ +#ifndef ARM_WINCE /* Make sure that the 'r_offset' field is copied properly so that identical binaries will compare the same. */ #define SWAP_IN_RELOC_OFFSET H_GET_32 #define SWAP_OUT_RELOC_OFFSET H_PUT_32 +#endif /* Extend the coff_link_hash_table structure with a few ARM specific fields. This allows us to store global data here without actually creating any @@ -975,6 +983,7 @@ arm_emit_base_file_entry (info, output_bfd, input_section, reloc_offset) } +#ifndef ARM_WINCE /* The thumb form of a long branch is a bit finicky, because the offset encoding is split over two fields, each in it's own instruction. They can occur in any order. So given a thumb form of long branch, and an @@ -1031,6 +1040,7 @@ insert_thumb_branch (br_insn, rel_off) return br_insn; } + static struct coff_link_hash_entry * find_thumb_glue (info, name, input_bfd) @@ -1060,6 +1070,7 @@ find_thumb_glue (info, name, input_bfd) return myh; } +#endif /* not ARM_WINCE */ static struct coff_link_hash_entry * find_arm_glue (info, name, input_bfd) @@ -1914,6 +1925,7 @@ record_arm_to_thumb_glue (info, h) return; } +#ifndef ARM_WINCE static void record_thumb_to_arm_glue (info, h) struct bfd_link_info * info; @@ -1987,6 +1999,7 @@ record_thumb_to_arm_glue (info, h) return; } +#endif /* not ARM_WINCE */ /* Select a BFD to be used to hold the sections used by the glue code. This function is called from the linker scripts in ld/emultempl/ diff --git a/contrib/binutils/bfd/coffcode.h b/contrib/binutils/bfd/coffcode.h index 72690d5..5c6704f 100644 --- a/contrib/binutils/bfd/coffcode.h +++ b/contrib/binutils/bfd/coffcode.h @@ -3014,6 +3014,7 @@ coff_compute_section_file_positions (abfd) else current->target_index = target_index++; } + abfd->section_tail = ¤t->next; free (section_list); } diff --git a/contrib/binutils/bfd/config.in b/contrib/binutils/bfd/config.in index e0b0c20..222096e 100644 --- a/contrib/binutils/bfd/config.in +++ b/contrib/binutils/bfd/config.in @@ -214,6 +214,9 @@ /* Define if getenv is not declared in system header files. */ #undef NEED_DECLARATION_GETENV +/* Define if struct core_dumpx has member c_impl */ +#undef HAVE_ST_C_IMPL + /* Define if <sys/procfs.h> has prstatus_t. */ #undef HAVE_PRSTATUS_T diff --git a/contrib/binutils/bfd/configure b/contrib/binutils/bfd/configure index 9bbf34d..94c88ab 100755 --- a/contrib/binutils/bfd/configure +++ b/contrib/binutils/bfd/configure @@ -1199,7 +1199,7 @@ fi # Uncomment the next line to remove the date from the reported bfd version -#is_release=y +is_release=y bfd_version=`echo "${VERSION}" | sed -e 's/\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\).*/\1.00\2.00\3.00\4.00\5/' -e 's/\([^\.]*\)\..*\(..\)\..*\(..\)\..*\(..\)\..*\(..\)$/\1\2\3\4\5/'` @@ -5173,6 +5173,32 @@ if test "${target}" = "${host}"; then rs6000-*-aix4.[3-9]* | powerpc-*-aix4.[3-9]*) COREFILE=rs6000-core.lo COREFLAG="$COREFLAG -DAIX_CORE_DUMPX_CORE" + # Not all versions of AIX with -DAIX_CORE_DUMPX_CORE + # have c_impl as a member of struct core_dumpx + echo $ac_n "checking for c_impl in struct core_dumpx""... $ac_c" 1>&6 +echo "configure:5180: checking for c_impl in struct core_dumpx" >&5 + cat > conftest.$ac_ext <<EOF +#line 5182 "configure" +#include "confdefs.h" +#include <core.h> +int main() { +struct core_dumpx c; c.c_impl = 0; +; return 0; } +EOF +if { (eval echo configure:5189: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + cat >> confdefs.h <<\EOF +#define HAVE_ST_C_IMPL 1 +EOF + + echo "$ac_t""yes" 1>&6 +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "$ac_t""no" 1>&6 +fi +rm -f conftest* ;; rs6000-*-aix4*) COREFILE=rs6000-core.lo ;; rs6000-*-*) COREFILE=rs6000-core.lo ;; @@ -5226,17 +5252,17 @@ if test "${target}" = "${host}"; then do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5230: checking for $ac_hdr" >&5 +echo "configure:5256: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5235 "configure" +#line 5261 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5240: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5266: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5264,12 +5290,12 @@ done if test "$ac_cv_header_sys_procfs_h" = yes; then echo $ac_n "checking for prstatus_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5268: checking for prstatus_t in sys/procfs.h" >&5 +echo "configure:5294: checking for prstatus_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prstatus_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5273 "configure" +#line 5299 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5278,7 +5304,7 @@ int main() { prstatus_t avar ; return 0; } EOF -if { (eval echo configure:5282: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5308: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_prstatus_t=yes else @@ -5300,12 +5326,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_prstatus_t" 1>&6 echo $ac_n "checking for prstatus32_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5304: checking for prstatus32_t in sys/procfs.h" >&5 +echo "configure:5330: checking for prstatus32_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prstatus32_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5309 "configure" +#line 5335 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5314,7 +5340,7 @@ int main() { prstatus32_t avar ; return 0; } EOF -if { (eval echo configure:5318: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5344: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_prstatus32_t=yes else @@ -5336,12 +5362,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_prstatus32_t" 1>&6 echo $ac_n "checking for prstatus_t.pr_who in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5340: checking for prstatus_t.pr_who in sys/procfs.h" >&5 +echo "configure:5366: checking for prstatus_t.pr_who in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5345 "configure" +#line 5371 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5350,7 +5376,7 @@ int main() { prstatus_t avar; void* aref = (void*) &avar.pr_who ; return 0; } EOF -if { (eval echo configure:5354: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5380: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who=yes else @@ -5372,12 +5398,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who" 1>&6 echo $ac_n "checking for prstatus32_t.pr_who in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5376: checking for prstatus32_t.pr_who in sys/procfs.h" >&5 +echo "configure:5402: checking for prstatus32_t.pr_who in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_member_prstatus32_t_pr_who'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5381 "configure" +#line 5407 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5386,7 +5412,7 @@ int main() { prstatus32_t avar; void* aref = (void*) &avar.pr_who ; return 0; } EOF -if { (eval echo configure:5390: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5416: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_member_prstatus32_t_pr_who=yes else @@ -5408,12 +5434,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_member_prstatus32_t_pr_who" 1>&6 echo $ac_n "checking for pstatus_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5412: checking for pstatus_t in sys/procfs.h" >&5 +echo "configure:5438: checking for pstatus_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_pstatus_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5417 "configure" +#line 5443 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5422,7 +5448,7 @@ int main() { pstatus_t avar ; return 0; } EOF -if { (eval echo configure:5426: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5452: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_pstatus_t=yes else @@ -5444,12 +5470,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_pstatus_t" 1>&6 echo $ac_n "checking for pxstatus_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5448: checking for pxstatus_t in sys/procfs.h" >&5 +echo "configure:5474: checking for pxstatus_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_pxstatus_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5453 "configure" +#line 5479 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5458,7 +5484,7 @@ int main() { pxstatus_t avar ; return 0; } EOF -if { (eval echo configure:5462: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5488: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_pxstatus_t=yes else @@ -5480,12 +5506,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_pxstatus_t" 1>&6 echo $ac_n "checking for pstatus32_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5484: checking for pstatus32_t in sys/procfs.h" >&5 +echo "configure:5510: checking for pstatus32_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_pstatus32_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5489 "configure" +#line 5515 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5494,7 +5520,7 @@ int main() { pstatus32_t avar ; return 0; } EOF -if { (eval echo configure:5498: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5524: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_pstatus32_t=yes else @@ -5516,12 +5542,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_pstatus32_t" 1>&6 echo $ac_n "checking for prpsinfo_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5520: checking for prpsinfo_t in sys/procfs.h" >&5 +echo "configure:5546: checking for prpsinfo_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prpsinfo_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5525 "configure" +#line 5551 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5530,7 +5556,7 @@ int main() { prpsinfo_t avar ; return 0; } EOF -if { (eval echo configure:5534: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5560: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_prpsinfo_t=yes else @@ -5552,12 +5578,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_prpsinfo_t" 1>&6 echo $ac_n "checking for prpsinfo32_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5556: checking for prpsinfo32_t in sys/procfs.h" >&5 +echo "configure:5582: checking for prpsinfo32_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prpsinfo32_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5561 "configure" +#line 5587 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5566,7 +5592,7 @@ int main() { prpsinfo32_t avar ; return 0; } EOF -if { (eval echo configure:5570: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5596: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_prpsinfo32_t=yes else @@ -5588,12 +5614,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_prpsinfo32_t" 1>&6 echo $ac_n "checking for psinfo_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5592: checking for psinfo_t in sys/procfs.h" >&5 +echo "configure:5618: checking for psinfo_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_psinfo_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5597 "configure" +#line 5623 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5602,7 +5628,7 @@ int main() { psinfo_t avar ; return 0; } EOF -if { (eval echo configure:5606: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5632: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_psinfo_t=yes else @@ -5624,12 +5650,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_psinfo_t" 1>&6 echo $ac_n "checking for psinfo32_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5628: checking for psinfo32_t in sys/procfs.h" >&5 +echo "configure:5654: checking for psinfo32_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_psinfo32_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5633 "configure" +#line 5659 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5638,7 +5664,7 @@ int main() { psinfo32_t avar ; return 0; } EOF -if { (eval echo configure:5642: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5668: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_psinfo32_t=yes else @@ -5660,12 +5686,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_psinfo32_t" 1>&6 echo $ac_n "checking for lwpstatus_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5664: checking for lwpstatus_t in sys/procfs.h" >&5 +echo "configure:5690: checking for lwpstatus_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_lwpstatus_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5669 "configure" +#line 5695 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5674,7 +5700,7 @@ int main() { lwpstatus_t avar ; return 0; } EOF -if { (eval echo configure:5678: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5704: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_lwpstatus_t=yes else @@ -5696,12 +5722,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_lwpstatus_t" 1>&6 echo $ac_n "checking for lwpxstatus_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5700: checking for lwpxstatus_t in sys/procfs.h" >&5 +echo "configure:5726: checking for lwpxstatus_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_lwpxstatus_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5705 "configure" +#line 5731 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5710,7 +5736,7 @@ int main() { lwpxstatus_t avar ; return 0; } EOF -if { (eval echo configure:5714: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5740: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_lwpxstatus_t=yes else @@ -5732,12 +5758,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_lwpxstatus_t" 1>&6 echo $ac_n "checking for lwpstatus_t.pr_context in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5736: checking for lwpstatus_t.pr_context in sys/procfs.h" >&5 +echo "configure:5762: checking for lwpstatus_t.pr_context in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5741 "configure" +#line 5767 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5746,7 +5772,7 @@ int main() { lwpstatus_t avar; void* aref = (void*) &avar.pr_context ; return 0; } EOF -if { (eval echo configure:5750: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5776: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context=yes else @@ -5768,12 +5794,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context" 1>&6 echo $ac_n "checking for lwpstatus_t.pr_reg in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5772: checking for lwpstatus_t.pr_reg in sys/procfs.h" >&5 +echo "configure:5798: checking for lwpstatus_t.pr_reg in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5777 "configure" +#line 5803 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5782,7 +5808,7 @@ int main() { lwpstatus_t avar; void* aref = (void*) &avar.pr_reg ; return 0; } EOF -if { (eval echo configure:5786: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5812: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg=yes else @@ -5804,12 +5830,12 @@ EOF echo "$ac_t""$bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg" 1>&6 echo $ac_n "checking for win32_pstatus_t in sys/procfs.h""... $ac_c" 1>&6 -echo "configure:5808: checking for win32_pstatus_t in sys/procfs.h" >&5 +echo "configure:5834: checking for win32_pstatus_t in sys/procfs.h" >&5 if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_win32_pstatus_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 5813 "configure" +#line 5839 "configure" #include "confdefs.h" #define _SYSCALL32 @@ -5818,7 +5844,7 @@ int main() { win32_pstatus_t avar ; return 0; } EOF -if { (eval echo configure:5822: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5848: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* bfd_cv_have_sys_procfs_type_win32_pstatus_t=yes else @@ -6235,10 +6261,10 @@ case ${host64}-${target64}-${want64} in if test -n "$GCC" ; then bad_64bit_gcc=no; echo $ac_n "checking for gcc version with buggy 64-bit support""... $ac_c" 1>&6 -echo "configure:6239: checking for gcc version with buggy 64-bit support" >&5 +echo "configure:6265: checking for gcc version with buggy 64-bit support" >&5 # Add more tests for gcc versions with non-working 64-bit support here. cat > conftest.$ac_ext <<EOF -#line 6242 "configure" +#line 6268 "configure" #include "confdefs.h" :__GNUC__:__GNUC_MINOR__:__i386__: EOF @@ -6283,17 +6309,17 @@ for ac_hdr in stdlib.h unistd.h sys/stat.h sys/types.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:6287: checking for $ac_hdr" >&5 +echo "configure:6313: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6292 "configure" +#line 6318 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6297: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6323: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -6322,12 +6348,12 @@ done for ac_func in getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6326: checking for $ac_func" >&5 +echo "configure:6352: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6331 "configure" +#line 6357 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6350,7 +6376,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6354: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6380: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6375,7 +6401,7 @@ fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -echo "configure:6379: checking for working mmap" >&5 +echo "configure:6405: checking for working mmap" >&5 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6383,7 +6409,7 @@ else ac_cv_func_mmap_fixed_mapped=no else cat > conftest.$ac_ext <<EOF -#line 6387 "configure" +#line 6413 "configure" #include "confdefs.h" /* Thanks to Mike Haertel and Jim Avera for this test. @@ -6536,7 +6562,7 @@ main() } EOF -if { (eval echo configure:6540: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:6566: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_mmap_fixed_mapped=yes else @@ -6561,12 +6587,12 @@ fi for ac_func in madvise mprotect do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6565: checking for $ac_func" >&5 +echo "configure:6591: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6570 "configure" +#line 6596 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6589,7 +6615,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6593: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6619: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else diff --git a/contrib/binutils/bfd/configure.in b/contrib/binutils/bfd/configure.in index 999847a..defa540 100644 --- a/contrib/binutils/bfd/configure.in +++ b/contrib/binutils/bfd/configure.in @@ -9,7 +9,7 @@ AC_ISC_POSIX AM_INIT_AUTOMAKE(bfd, 2.12.1) # Uncomment the next line to remove the date from the reported bfd version -#is_release=y +is_release=y changequote(,)dnl bfd_version=`echo "${VERSION}" | sed -e 's/\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\)\.*\([^\.]*\).*/\1.00\2.00\3.00\4.00\5/' -e 's/\([^\.]*\)\..*\(..\)\..*\(..\)\..*\(..\)\..*\(..\)$/\1\2\3\4\5/'` @@ -327,6 +327,14 @@ changequote(,)dnl changequote([,])dnl COREFILE=rs6000-core.lo COREFLAG="$COREFLAG -DAIX_CORE_DUMPX_CORE" + # Not all versions of AIX with -DAIX_CORE_DUMPX_CORE + # have c_impl as a member of struct core_dumpx + AC_MSG_CHECKING([for c_impl in struct core_dumpx]) + AC_TRY_COMPILE([#include <core.h>], + [struct core_dumpx c; c.c_impl = 0;], + [AC_DEFINE(HAVE_ST_C_IMPL, 1, + [Define if struct core_dumpx has member c_impl]) + AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)]) ;; rs6000-*-aix4*) COREFILE=rs6000-core.lo ;; rs6000-*-*) COREFILE=rs6000-core.lo ;; diff --git a/contrib/binutils/bfd/cpu-powerpc.c b/contrib/binutils/bfd/cpu-powerpc.c index d812618..d77b426 100644 --- a/contrib/binutils/bfd/cpu-powerpc.c +++ b/contrib/binutils/bfd/cpu-powerpc.c @@ -50,6 +50,65 @@ powerpc_compatible (a,b) const bfd_arch_info_type bfd_powerpc_archs[] = { +#if BFD_DEFAULT_TARGET_SIZE == 64 /* default arch must come first. */ + { + 64, /* 64 bits in a word */ + 64, /* 64 bits in an address */ + 8, /* 8 bits in a byte */ + bfd_arch_powerpc, + bfd_mach_ppc64, + "powerpc", + "powerpc:common64", + 3, + true, /* default for 64 bit target */ + powerpc_compatible, + bfd_default_scan, + &bfd_powerpc_archs[1] + }, + { + 32, /* 32 bits in a word */ + 32, /* 32 bits in an address */ + 8, /* 8 bits in a byte */ + bfd_arch_powerpc, + bfd_mach_ppc, /* for the POWER/PowerPC common architecture */ + "powerpc", + "powerpc:common", + 3, + false, + powerpc_compatible, + bfd_default_scan, + &bfd_powerpc_archs[2], + }, +#else + { + 32, /* 32 bits in a word */ + 32, /* 32 bits in an address */ + 8, /* 8 bits in a byte */ + bfd_arch_powerpc, + bfd_mach_ppc, /* for the POWER/PowerPC common architecture */ + "powerpc", + "powerpc:common", + 3, + true, /* default for 32 bit target */ + powerpc_compatible, + bfd_default_scan, + &bfd_powerpc_archs[1], + }, + { + 64, /* 64 bits in a word */ + 64, /* 64 bits in an address */ + 8, /* 8 bits in a byte */ + bfd_arch_powerpc, + bfd_mach_ppc64, + "powerpc", + "powerpc:common64", + 3, + false, + powerpc_compatible, + bfd_default_scan, + &bfd_powerpc_archs[2] + }, +#endif { 32, /* 32 bits in a word */ 32, /* 32 bits in an address */ @@ -62,7 +121,7 @@ const bfd_arch_info_type bfd_powerpc_archs[] = false, /* not the default */ powerpc_compatible, bfd_default_scan, - &bfd_powerpc_archs[1] + &bfd_powerpc_archs[3] }, { 32, /* 32 bits in a word */ @@ -76,7 +135,7 @@ const bfd_arch_info_type bfd_powerpc_archs[] = false, /* not the default */ powerpc_compatible, bfd_default_scan, - &bfd_powerpc_archs[2] + &bfd_powerpc_archs[4] }, { 32, /* 32 bits in a word */ @@ -90,7 +149,7 @@ const bfd_arch_info_type bfd_powerpc_archs[] = false, /* not the default */ powerpc_compatible, bfd_default_scan, - &bfd_powerpc_archs[3] + &bfd_powerpc_archs[5] }, { 32, /* 32 bits in a word */ @@ -104,7 +163,7 @@ const bfd_arch_info_type bfd_powerpc_archs[] = false, /* not the default */ powerpc_compatible, bfd_default_scan, - &bfd_powerpc_archs[4] + &bfd_powerpc_archs[6] }, { 32, /* 32 bits in a word */ @@ -118,7 +177,7 @@ const bfd_arch_info_type bfd_powerpc_archs[] = false, /* not the default */ powerpc_compatible, bfd_default_scan, - &bfd_powerpc_archs[5] + &bfd_powerpc_archs[7] }, { 64, /* 64 bits in a word */ @@ -132,7 +191,7 @@ const bfd_arch_info_type bfd_powerpc_archs[] = false, /* not the default */ powerpc_compatible, bfd_default_scan, - &bfd_powerpc_archs[6] + &bfd_powerpc_archs[8] }, { 64, /* 64 bits in a word */ @@ -146,7 +205,7 @@ const bfd_arch_info_type bfd_powerpc_archs[] = false, /* not the default */ powerpc_compatible, bfd_default_scan, - &bfd_powerpc_archs[7] + &bfd_powerpc_archs[9] }, { 64, /* 64 bits in a word */ @@ -160,7 +219,7 @@ const bfd_arch_info_type bfd_powerpc_archs[] = false, /* not the default */ powerpc_compatible, bfd_default_scan, - &bfd_powerpc_archs[8] + &bfd_powerpc_archs[10] }, { 64, /* 64 bits in a word */ @@ -174,7 +233,7 @@ const bfd_arch_info_type bfd_powerpc_archs[] = false, /* not the default */ powerpc_compatible, bfd_default_scan, - &bfd_powerpc_archs[9] + &bfd_powerpc_archs[11] }, { 64, /* 64 bits in a word */ @@ -188,7 +247,7 @@ const bfd_arch_info_type bfd_powerpc_archs[] = false, /* not the default */ powerpc_compatible, bfd_default_scan, - &bfd_powerpc_archs[10] + &bfd_powerpc_archs[12] }, { 32, /* 32 bits in a word */ @@ -202,7 +261,7 @@ const bfd_arch_info_type bfd_powerpc_archs[] = false, /* not the default */ powerpc_compatible, bfd_default_scan, - &bfd_powerpc_archs[11] + &bfd_powerpc_archs[13] }, { 32, /* 32 bits in a word */ @@ -216,34 +275,6 @@ const bfd_arch_info_type bfd_powerpc_archs[] = false, /* not the default */ powerpc_compatible, bfd_default_scan, - &bfd_powerpc_archs[12] - }, - { - 64, /* 64 bits in a word */ - 64, /* 64 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_powerpc, - bfd_mach_ppc64, - "powerpc", - "powerpc:common64", - 3, - BFD_DEFAULT_TARGET_SIZE == 64, /* default for 64 bit target */ - powerpc_compatible, - bfd_default_scan, - &bfd_powerpc_archs[13] - }, - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_powerpc, - bfd_mach_ppc, /* for the POWER/PowerPC common architecture */ - "powerpc", - "powerpc:common", - 3, - BFD_DEFAULT_TARGET_SIZE != 64, /* default for 32 bit target */ - powerpc_compatible, - bfd_default_scan, 0 } }; diff --git a/contrib/binutils/bfd/cpu-s390.c b/contrib/binutils/bfd/cpu-s390.c new file mode 100644 index 0000000..ac0d45e --- /dev/null +++ b/contrib/binutils/bfd/cpu-s390.c @@ -0,0 +1,56 @@ +/* BFD support for the s390 processor. + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Carl B. Pedersen and Martin Schwidefsky. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "libbfd.h" + +const bfd_arch_info_type bfd_s390_64_arch = +{ + 64, /* bits in a word */ + 64, /* bits in an address */ + 8, /* bits in a byte */ + bfd_arch_s390, + bfd_mach_s390_64, + "s390", + "s390:64-bit", + 3, /* section alignment power */ + true, /* the default */ + bfd_default_compatible, + bfd_default_scan, + NULL +}; + +const bfd_arch_info_type bfd_s390_arch = +{ + 32, /* bits in a word */ + 32, /* bits in an address */ + 8, /* bits in a byte */ + bfd_arch_s390, + bfd_mach_s390_31, + "s390", + "s390:31-bit", + 3, /* section alignment power */ + true, /* the default */ + bfd_default_compatible, + bfd_default_scan, + &bfd_s390_64_arch +}; diff --git a/contrib/binutils/bfd/doc/archures.texi b/contrib/binutils/bfd/doc/archures.texi index dcdaff9..eb4d180 100644 --- a/contrib/binutils/bfd/doc/archures.texi +++ b/contrib/binutils/bfd/doc/archures.texi @@ -225,8 +225,8 @@ enum bfd_architecture #define bfd_mach_avr5 5 bfd_arch_cris, /* Axis CRIS */ bfd_arch_s390, /* IBM s390 */ -#define bfd_mach_s390_esa 0 -#define bfd_mach_s390_esame 1 +#define bfd_mach_s390_31 0 +#define bfd_mach_s390_64 1 bfd_arch_openrisc, /* OpenRISC */ bfd_arch_mmix, /* Donald Knuth's educational processor. */ bfd_arch_xstormy16, @@ -253,7 +253,9 @@ typedef struct bfd_arch_info const char *arch_name; const char *printable_name; unsigned int section_align_power; - /* True if this is the default machine for the architecture. */ + /* True if this is the default machine for the architecture. + The default arch should be the first entry for an arch so that + all the entries for that arch can be accessed via @code{next}. */ boolean the_default; const struct bfd_arch_info * (*compatible) PARAMS ((const struct bfd_arch_info *a, diff --git a/contrib/binutils/bfd/doc/libbfd.texi b/contrib/binutils/bfd/doc/libbfd.texi index 0c20a07..b28650f 100644 --- a/contrib/binutils/bfd/doc/libbfd.texi +++ b/contrib/binutils/bfd/doc/libbfd.texi @@ -10,7 +10,7 @@ completeness. @subsubsection @code{bfd_write_bigendian_4byte_int} @strong{Synopsis} @example -void bfd_write_bigendian_4byte_int (bfd *, unsigned int); +boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int); @end example @strong{Description}@* Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big diff --git a/contrib/binutils/bfd/doc/reloc.texi b/contrib/binutils/bfd/doc/reloc.texi index 2b449d3..2f462fd 100644 --- a/contrib/binutils/bfd/doc/reloc.texi +++ b/contrib/binutils/bfd/doc/reloc.texi @@ -768,55 +768,6 @@ Relocation against a MIPS literal section. @deffnx {} BFD_RELOC_MIPS_REL16 @deffnx {} BFD_RELOC_MIPS_RELGOT @deffnx {} BFD_RELOC_MIPS_JALR -@deffnx {} BFD_RELOC_SH_GOT_LOW16 -@deffnx {} BFD_RELOC_SH_GOT_MEDLOW16 -@deffnx {} BFD_RELOC_SH_GOT_MEDHI16 -@deffnx {} BFD_RELOC_SH_GOT_HI16 -@deffnx {} BFD_RELOC_SH_GOTPLT_LOW16 -@deffnx {} BFD_RELOC_SH_GOTPLT_MEDLOW16 -@deffnx {} BFD_RELOC_SH_GOTPLT_MEDHI16 -@deffnx {} BFD_RELOC_SH_GOTPLT_HI16 -@deffnx {} BFD_RELOC_SH_PLT_LOW16 -@deffnx {} BFD_RELOC_SH_PLT_MEDLOW16 -@deffnx {} BFD_RELOC_SH_PLT_MEDHI16 -@deffnx {} BFD_RELOC_SH_PLT_HI16 -@deffnx {} BFD_RELOC_SH_GOTOFF_LOW16 -@deffnx {} BFD_RELOC_SH_GOTOFF_MEDLOW16 -@deffnx {} BFD_RELOC_SH_GOTOFF_MEDHI16 -@deffnx {} BFD_RELOC_SH_GOTOFF_HI16 -@deffnx {} BFD_RELOC_SH_GOTPC_LOW16 -@deffnx {} BFD_RELOC_SH_GOTPC_MEDLOW16 -@deffnx {} BFD_RELOC_SH_GOTPC_MEDHI16 -@deffnx {} BFD_RELOC_SH_GOTPC_HI16 -@deffnx {} BFD_RELOC_SH_COPY64 -@deffnx {} BFD_RELOC_SH_GLOB_DAT64 -@deffnx {} BFD_RELOC_SH_JMP_SLOT64 -@deffnx {} BFD_RELOC_SH_RELATIVE64 -@deffnx {} BFD_RELOC_SH_GOT10BY4 -@deffnx {} BFD_RELOC_SH_GOT10BY8 -@deffnx {} BFD_RELOC_SH_GOTPLT10BY4 -@deffnx {} BFD_RELOC_SH_GOTPLT10BY8 -@deffnx {} BFD_RELOC_SH_GOTPLT32 -@deffnx {} BFD_RELOC_SH_SHMEDIA_CODE -@deffnx {} BFD_RELOC_SH_IMMU5 -@deffnx {} BFD_RELOC_SH_IMMS6 -@deffnx {} BFD_RELOC_SH_IMMS6BY32 -@deffnx {} BFD_RELOC_SH_IMMU6 -@deffnx {} BFD_RELOC_SH_IMMS10 -@deffnx {} BFD_RELOC_SH_IMMS10BY2 -@deffnx {} BFD_RELOC_SH_IMMS10BY4 -@deffnx {} BFD_RELOC_SH_IMMS10BY8 -@deffnx {} BFD_RELOC_SH_IMMS16 -@deffnx {} BFD_RELOC_SH_IMMU16 -@deffnx {} BFD_RELOC_SH_IMM_LOW16 -@deffnx {} BFD_RELOC_SH_IMM_LOW16_PCREL -@deffnx {} BFD_RELOC_SH_IMM_MEDLOW16 -@deffnx {} BFD_RELOC_SH_IMM_MEDLOW16_PCREL -@deffnx {} BFD_RELOC_SH_IMM_MEDHI16 -@deffnx {} BFD_RELOC_SH_IMM_MEDHI16_PCREL -@deffnx {} BFD_RELOC_SH_IMM_HI16 -@deffnx {} BFD_RELOC_SH_IMM_HI16_PCREL -@deffnx {} BFD_RELOC_SH_PT_16 MIPS ELF relocations. @end deffn @deffn {} BFD_RELOC_386_GOT32 @@ -996,6 +947,55 @@ These relocs are only used within the ARM assembler. They are not @deffnx {} BFD_RELOC_SH_JMP_SLOT @deffnx {} BFD_RELOC_SH_RELATIVE @deffnx {} BFD_RELOC_SH_GOTPC +@deffnx {} BFD_RELOC_SH_GOT_LOW16 +@deffnx {} BFD_RELOC_SH_GOT_MEDLOW16 +@deffnx {} BFD_RELOC_SH_GOT_MEDHI16 +@deffnx {} BFD_RELOC_SH_GOT_HI16 +@deffnx {} BFD_RELOC_SH_GOTPLT_LOW16 +@deffnx {} BFD_RELOC_SH_GOTPLT_MEDLOW16 +@deffnx {} BFD_RELOC_SH_GOTPLT_MEDHI16 +@deffnx {} BFD_RELOC_SH_GOTPLT_HI16 +@deffnx {} BFD_RELOC_SH_PLT_LOW16 +@deffnx {} BFD_RELOC_SH_PLT_MEDLOW16 +@deffnx {} BFD_RELOC_SH_PLT_MEDHI16 +@deffnx {} BFD_RELOC_SH_PLT_HI16 +@deffnx {} BFD_RELOC_SH_GOTOFF_LOW16 +@deffnx {} BFD_RELOC_SH_GOTOFF_MEDLOW16 +@deffnx {} BFD_RELOC_SH_GOTOFF_MEDHI16 +@deffnx {} BFD_RELOC_SH_GOTOFF_HI16 +@deffnx {} BFD_RELOC_SH_GOTPC_LOW16 +@deffnx {} BFD_RELOC_SH_GOTPC_MEDLOW16 +@deffnx {} BFD_RELOC_SH_GOTPC_MEDHI16 +@deffnx {} BFD_RELOC_SH_GOTPC_HI16 +@deffnx {} BFD_RELOC_SH_COPY64 +@deffnx {} BFD_RELOC_SH_GLOB_DAT64 +@deffnx {} BFD_RELOC_SH_JMP_SLOT64 +@deffnx {} BFD_RELOC_SH_RELATIVE64 +@deffnx {} BFD_RELOC_SH_GOT10BY4 +@deffnx {} BFD_RELOC_SH_GOT10BY8 +@deffnx {} BFD_RELOC_SH_GOTPLT10BY4 +@deffnx {} BFD_RELOC_SH_GOTPLT10BY8 +@deffnx {} BFD_RELOC_SH_GOTPLT32 +@deffnx {} BFD_RELOC_SH_SHMEDIA_CODE +@deffnx {} BFD_RELOC_SH_IMMU5 +@deffnx {} BFD_RELOC_SH_IMMS6 +@deffnx {} BFD_RELOC_SH_IMMS6BY32 +@deffnx {} BFD_RELOC_SH_IMMU6 +@deffnx {} BFD_RELOC_SH_IMMS10 +@deffnx {} BFD_RELOC_SH_IMMS10BY2 +@deffnx {} BFD_RELOC_SH_IMMS10BY4 +@deffnx {} BFD_RELOC_SH_IMMS10BY8 +@deffnx {} BFD_RELOC_SH_IMMS16 +@deffnx {} BFD_RELOC_SH_IMMU16 +@deffnx {} BFD_RELOC_SH_IMM_LOW16 +@deffnx {} BFD_RELOC_SH_IMM_LOW16_PCREL +@deffnx {} BFD_RELOC_SH_IMM_MEDLOW16 +@deffnx {} BFD_RELOC_SH_IMM_MEDLOW16_PCREL +@deffnx {} BFD_RELOC_SH_IMM_MEDHI16 +@deffnx {} BFD_RELOC_SH_IMM_MEDHI16_PCREL +@deffnx {} BFD_RELOC_SH_IMM_HI16 +@deffnx {} BFD_RELOC_SH_IMM_HI16_PCREL +@deffnx {} BFD_RELOC_SH_PT_16 Hitachi SH relocs. Not all of these appear in object files. @end deffn @deffn {} BFD_RELOC_THUMB_PCREL_BRANCH9 diff --git a/contrib/binutils/bfd/dwarf2.c b/contrib/binutils/bfd/dwarf2.c index f129e0b..e3b8e27 100644 --- a/contrib/binutils/bfd/dwarf2.c +++ b/contrib/binutils/bfd/dwarf2.c @@ -42,7 +42,7 @@ struct line_head { bfd_vma total_length; unsigned short version; - unsigned int prologue_length; + bfd_vma prologue_length; unsigned char minimum_instruction_length; unsigned char default_is_stmt; int line_base; @@ -225,7 +225,7 @@ static bfd_vma read_address PARAMS ((struct comp_unit *, char *)); static struct abbrev_info *lookup_abbrev PARAMS ((unsigned int, struct abbrev_info **)); static struct abbrev_info **read_abbrevs - PARAMS ((bfd *, unsigned int, struct dwarf2_debug *)); + PARAMS ((bfd *, bfd_vma, struct dwarf2_debug *)); static char *read_attribute PARAMS ((struct attribute *, struct attr_abbrev *, struct comp_unit *, char *)); @@ -396,8 +396,8 @@ read_indirect_string (unit, buf, bytes_read_ptr) if (offset >= stash->dwarf_str_size) { - (*_bfd_error_handler) (_("Dwarf Error: DW_FORM_strp offset (%u) greater than or equal to .debug_str size (%u)."), - offset, stash->dwarf_str_size); + (*_bfd_error_handler) (_("Dwarf Error: DW_FORM_strp offset (%lu) greater than or equal to .debug_str size (%lu)."), + (unsigned long) offset, stash->dwarf_str_size); bfd_set_error (bfd_error_bad_value); return NULL; } @@ -523,7 +523,7 @@ lookup_abbrev (number,abbrevs) static struct abbrev_info** read_abbrevs (abfd, offset, stash) bfd * abfd; - unsigned int offset; + bfd_vma offset; struct dwarf2_debug *stash; { struct abbrev_info **abbrevs; @@ -557,8 +557,8 @@ read_abbrevs (abfd, offset, stash) if (offset >= stash->dwarf_abbrev_size) { - (*_bfd_error_handler) (_("Dwarf Error: Abbrev offset (%u) greater than or equal to .debug_abbrev size (%u)."), - offset, stash->dwarf_abbrev_size); + (*_bfd_error_handler) (_("Dwarf Error: Abbrev offset (%lu) greater than or equal to .debug_abbrev size (%lu)."), + (unsigned long) offset, stash->dwarf_abbrev_size); bfd_set_error (bfd_error_bad_value); return 0; } @@ -754,7 +754,7 @@ read_attribute_value (attr, form, unit, info_ptr) info_ptr = read_attribute_value (attr, form, unit, info_ptr); break; default: - (*_bfd_error_handler) (_("Dwarf Error: Invalid or unhandled FORM value: %d."), + (*_bfd_error_handler) (_("Dwarf Error: Invalid or unhandled FORM value: %u."), form); bfd_set_error (bfd_error_bad_value); } @@ -958,7 +958,7 @@ decode_line_info (unit, stash) below. */ if (unit->line_offset >= stash->dwarf_line_size) { - (*_bfd_error_handler) (_("Dwarf Error: Line offset (%u) greater than or equal to .debug_line size (%u)."), + (*_bfd_error_handler) (_("Dwarf Error: Line offset (%lu) greater than or equal to .debug_line size (%lu)."), unit->line_offset, stash->dwarf_line_size); bfd_set_error (bfd_error_bad_value); return 0; @@ -1345,7 +1345,7 @@ scan_unit_for_functions (unit) abbrev = lookup_abbrev (abbrev_number,unit->abbrevs); if (! abbrev) { - (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %d."), + (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."), abbrev_number); bfd_set_error (bfd_error_bad_value); return false; @@ -1486,9 +1486,9 @@ parse_comp_unit (abfd, stash, unit_length, offset_size) unsigned int offset_size; { struct comp_unit* unit; - unsigned short version; - unsigned int abbrev_offset = 0; - unsigned char addr_size; + unsigned int version; + bfd_vma abbrev_offset = 0; + unsigned int addr_size; struct abbrev_info** abbrevs; unsigned int abbrev_number, bytes_read, i; struct abbrev_info *abbrev; @@ -1517,7 +1517,7 @@ parse_comp_unit (abfd, stash, unit_length, offset_size) if (version != 2) { - (*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%hu', this reader only handles version 2 information."), version); + (*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%u', this reader only handles version 2 information."), version); bfd_set_error (bfd_error_bad_value); return 0; } @@ -1526,7 +1526,7 @@ parse_comp_unit (abfd, stash, unit_length, offset_size) { (*_bfd_error_handler) (_("Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."), addr_size, - sizeof (bfd_vma)); + (unsigned int) sizeof (bfd_vma)); bfd_set_error (bfd_error_bad_value); return 0; } @@ -1547,7 +1547,7 @@ parse_comp_unit (abfd, stash, unit_length, offset_size) info_ptr += bytes_read; if (! abbrev_number) { - (*_bfd_error_handler) (_("Dwarf Error: Bad abbrev number: %d."), + (*_bfd_error_handler) (_("Dwarf Error: Bad abbrev number: %u."), abbrev_number); bfd_set_error (bfd_error_bad_value); return 0; @@ -1556,7 +1556,7 @@ parse_comp_unit (abfd, stash, unit_length, offset_size) abbrev = lookup_abbrev (abbrev_number, abbrevs); if (! abbrev) { - (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %d."), + (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."), abbrev_number); bfd_set_error (bfd_error_bad_value); return 0; diff --git a/contrib/binutils/bfd/elf-bfd.h b/contrib/binutils/bfd/elf-bfd.h index 4439daa..d10fda9 100644 --- a/contrib/binutils/bfd/elf-bfd.h +++ b/contrib/binutils/bfd/elf-bfd.h @@ -788,6 +788,11 @@ struct elf_backend_data section. */ unsigned default_use_rela_p : 1; + /* Set if RELA relocations for a relocatable link can be handled by + generic code. Backends that set this flag need do nothing in the + backend relocate_section routine for relocatable linking. */ + unsigned rela_normal : 1; + /* True if addresses "naturally" sign extend. This is used when swapping in from Elf32 when BFD64. */ unsigned sign_extend_vma : 1; diff --git a/contrib/binutils/bfd/elf-eh-frame.c b/contrib/binutils/bfd/elf-eh-frame.c index 20cbfb2..6a23edb 100644 --- a/contrib/binutils/bfd/elf-eh-frame.c +++ b/contrib/binutils/bfd/elf-eh-frame.c @@ -64,6 +64,7 @@ struct eh_cie_fde unsigned char removed : 1; unsigned char make_relative : 1; unsigned char make_lsda_relative : 1; + unsigned char per_encoding_relative : 1; }; struct eh_frame_sec_info @@ -469,6 +470,8 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec, = cie.make_relative; sec_info->entry[last_cie_ndx].make_lsda_relative = cie.make_lsda_relative; + sec_info->entry[last_cie_ndx].per_encoding_relative + = (cie.per_encoding & 0x70) == DW_EH_PE_pcrel; } } @@ -633,8 +636,9 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec, else { if (info->shared - && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr - && cie.make_relative == 0) + && (((cie.fde_encoding & 0xf0) == DW_EH_PE_absptr + && cie.make_relative == 0) + || (cie.fde_encoding & 0xf0) == DW_EH_PE_aligned)) { /* If shared library uses absolute pointers which we cannot turn into PC relative, @@ -689,6 +693,7 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec, { sec_info->entry[i].make_relative = make_relative; sec_info->entry[i].make_lsda_relative = make_lsda_relative; + sec_info->entry[i].per_encoding_relative = 0; } } else if (sec_info->entry[i].cie && sec_info->entry[i].sec == sec) @@ -947,7 +952,8 @@ _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents) /* CIE */ cie_offset = sec_info->entry[i].new_offset; if (sec_info->entry[i].make_relative - || sec_info->entry[i].make_lsda_relative) + || sec_info->entry[i].make_lsda_relative + || sec_info->entry[i].per_encoding_relative) { unsigned char *aug; unsigned int action; @@ -956,7 +962,8 @@ _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents) /* Need to find 'R' or 'L' augmentation's argument and modify DW_EH_PE_* value. */ action = (sec_info->entry[i].make_relative ? 1 : 0) - | (sec_info->entry[i].make_lsda_relative ? 2 : 0); + | (sec_info->entry[i].make_lsda_relative ? 2 : 0) + | (sec_info->entry[i].per_encoding_relative ? 4 : 0); buf = contents + sec_info->entry[i].offset; /* Skip length, id and version. */ buf += 9; @@ -988,10 +995,22 @@ _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents) per_width = get_DW_EH_PE_width (per_encoding, ptr_size); BFD_ASSERT (per_width != 0); + BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel) + == sec_info->entry[i].per_encoding_relative); if ((per_encoding & 0xf0) == DW_EH_PE_aligned) buf = (contents + ((buf - contents + per_width - 1) & ~((bfd_size_type) per_width - 1))); + if (action & 4) + { + bfd_vma value; + + value = read_value (abfd, buf, per_width); + value += (sec_info->entry[i].offset + - sec_info->entry[i].new_offset); + write_value (abfd, buf, value, per_width); + action &= ~4; + } buf += per_width; break; case 'R': @@ -1008,7 +1027,7 @@ _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents) } } } - else + else if (sec_info->entry[i].size > 4) { /* FDE */ bfd_vma value = 0, address; @@ -1081,6 +1100,9 @@ _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents) } } } + else + /* Terminating FDE must be at the end of .eh_frame section only. */ + BFD_ASSERT (i == sec_info->count - 1); BFD_ASSERT (p == contents + sec_info->entry[i].new_offset); memmove (p, contents + sec_info->entry[i].offset, diff --git a/contrib/binutils/bfd/elf.c b/contrib/binutils/bfd/elf.c index 67d9add..b78eb5f 100644 --- a/contrib/binutils/bfd/elf.c +++ b/contrib/binutils/bfd/elf.c @@ -3881,7 +3881,6 @@ prep_headers (abfd) Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ Elf_Internal_Phdr *i_phdrp = 0; /* Program header table, internal form */ Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */ - int count; struct elf_strtab_hash *shstrtab; struct elf_backend_data *bed = get_elf_backend_data (abfd); @@ -3904,12 +3903,6 @@ prep_headers (abfd) bfd_big_endian (abfd) ? ELFDATA2MSB : ELFDATA2LSB; i_ehdrp->e_ident[EI_VERSION] = bed->s->ev_current; - i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_NONE; - i_ehdrp->e_ident[EI_ABIVERSION] = 0; - - for (count = EI_PAD; count < EI_NIDENT; count++) - i_ehdrp->e_ident[count] = 0; - if ((abfd->flags & DYNAMIC) != 0) i_ehdrp->e_type = ET_DYN; else if ((abfd->flags & EXEC_P) != 0) diff --git a/contrib/binutils/bfd/elf32-arm.h b/contrib/binutils/bfd/elf32-arm.h index d420e5b..7d02127 100644 --- a/contrib/binutils/bfd/elf32-arm.h +++ b/contrib/binutils/bfd/elf32-arm.h @@ -1390,7 +1390,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, boolean overflow = false; bfd_vma upper_insn = bfd_get_16 (input_bfd, hit_data); bfd_vma lower_insn = bfd_get_16 (input_bfd, hit_data + 2); - bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1; + bfd_signed_vma reloc_signed_max = ((1 << (howto->bitsize - 1)) - 1) >> howto->rightshift; bfd_signed_vma reloc_signed_min = ~ reloc_signed_max; bfd_vma check; bfd_signed_vma signed_check; @@ -1830,6 +1830,11 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section, Elf_Internal_Rela * relend; const char * name; +#ifndef USE_REL + if (info->relocateable) + return true; +#endif + symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; sym_hashes = elf_sym_hashes (input_bfd); @@ -1862,6 +1867,7 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section, #endif howto = bfd_reloc.howto; +#ifdef USE_REL if (info->relocateable) { /* This is a relocateable link. We don't have to change @@ -1874,19 +1880,16 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section, if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) { sec = local_sections[r_symndx]; -#ifdef USE_REL arm_add_to_rel (input_bfd, contents + rel->r_offset, howto, (bfd_signed_vma) (sec->output_offset + sym->st_value)); -#else - rel->r_addend += (sec->output_offset + sym->st_value); -#endif } } continue; } +#endif /* This is a final link. */ h = NULL; @@ -3637,6 +3640,9 @@ elf32_arm_reloc_type_class (rela) #define elf_backend_plt_readonly 1 #define elf_backend_want_got_plt 1 #define elf_backend_want_plt_sym 0 +#ifndef USE_REL +#define elf_backend_rela_normal 1 +#endif #define elf_backend_got_header_size 12 #define elf_backend_plt_header_size PLT_ENTRY_SIZE diff --git a/contrib/binutils/bfd/elf32-mips.c b/contrib/binutils/bfd/elf32-mips.c index e7b4701..ddfe4a0 100644 --- a/contrib/binutils/bfd/elf32-mips.c +++ b/contrib/binutils/bfd/elf32-mips.c @@ -105,6 +105,9 @@ struct mips_elf_link_hash_entry /* This is like the call_stub field, but it is used if the function being called returns a floating point value. */ asection *call_fp_stub; + + /* Are we forced local? .*/ + boolean forced_local; }; static bfd_reloc_status_type mips32_64bit_reloc @@ -4528,6 +4531,7 @@ mips_elf_link_hash_newfunc (entry, table, string) ret->need_fn_stub = false; ret->call_stub = NULL; ret->call_fp_stub = NULL; + ret->forced_local = false; } return (struct bfd_hash_entry *) ret; @@ -4543,7 +4547,12 @@ _bfd_mips_elf_hide_symbol (info, entry, force_local) asection *got; struct mips_got_info *g; struct mips_elf_link_hash_entry *h; + h = (struct mips_elf_link_hash_entry *) entry; + if (h->forced_local) + return; + h->forced_local = true; + dynobj = elf_hash_table (info)->dynobj; got = bfd_get_section_by_name (dynobj, ".got"); g = (struct mips_got_info *) elf_section_data (got)->tdata; @@ -6047,9 +6056,18 @@ mips_elf_record_global_got_symbol (h, info, g) { /* A global symbol in the GOT must also be in the dynamic symbol table. */ - if (h->dynindx == -1 - && !bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; + if (h->dynindx == -1) + { + switch (ELF_ST_VISIBILITY (h->other)) + { + case STV_INTERNAL: + case STV_HIDDEN: + _bfd_mips_elf_hide_symbol (info, h, true); + break; + } + if (!bfd_elf32_link_record_dynamic_symbol (info, h)) + return false; + } /* If we've already marked this entry as needing GOT space, we don't need to do it again. */ diff --git a/contrib/binutils/bfd/elf32-ppc.c b/contrib/binutils/bfd/elf32-ppc.c index be6cfab..31d9e0c 100644 --- a/contrib/binutils/bfd/elf32-ppc.c +++ b/contrib/binutils/bfd/elf32-ppc.c @@ -1,5 +1,5 @@ /* PowerPC-specific support for 32-bit ELF - Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. @@ -49,6 +49,8 @@ static boolean ppc_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *)); static int ppc_elf_additional_program_headers PARAMS ((bfd *)); static boolean ppc_elf_modify_segment_map PARAMS ((bfd *)); +static asection *ppc_elf_create_got + PARAMS ((bfd *, struct bfd_link_info *)); static boolean ppc_elf_create_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); @@ -679,20 +681,20 @@ static reloc_howto_type ppc_elf_howto_raw[] = { 0xffff, /* dst_mask */ false), /* pcrel_offset */ - /* 32-bit section relative relocation. */ + /* 16-bit section relative relocation. */ HOWTO (R_PPC_SECTOFF, /* type */ 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_PPC_SECTOFF", /* name */ false, /* partial_inplace */ 0, /* src_mask */ - 0, /* dst_mask */ - true), /* pcrel_offset */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ /* 16-bit lower half section relative relocation. */ HOWTO (R_PPC_SECTOFF_LO, /* type */ @@ -1295,7 +1297,7 @@ ppc_elf_reloc_type_lookup (abfd, code) case BFD_RELOC_HI16_PLTOFF: ppc_reloc = R_PPC_PLT16_HI; break; case BFD_RELOC_HI16_S_PLTOFF: ppc_reloc = R_PPC_PLT16_HA; break; case BFD_RELOC_GPREL16: ppc_reloc = R_PPC_SDAREL16; break; - case BFD_RELOC_32_BASEREL: ppc_reloc = R_PPC_SECTOFF; break; + case BFD_RELOC_16_BASEREL: ppc_reloc = R_PPC_SECTOFF; break; case BFD_RELOC_LO16_BASEREL: ppc_reloc = R_PPC_SECTOFF_LO; break; case BFD_RELOC_HI16_BASEREL: ppc_reloc = R_PPC_SECTOFF_HI; break; case BFD_RELOC_HI16_S_BASEREL: ppc_reloc = R_PPC_SECTOFF_HA; break; @@ -1632,6 +1634,30 @@ ppc_elf_modify_segment_map (abfd) return true; } +/* The powerpc .got has a blrl instruction in it. Mark it executable. */ + +static asection * +ppc_elf_create_got (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + register asection *s; + flagword flags; + + if (!_bfd_elf_create_got_section (abfd, info)) + return NULL; + + s = bfd_get_section_by_name (abfd, ".got"); + if (s == NULL) + abort (); + + flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_IN_MEMORY + | SEC_LINKER_CREATED); + if (!bfd_set_section_flags (abfd, s, flags)) + return NULL; + return s; +} + /* We have to create .dynsbss and .rela.sbss here so that they get mapped to output sections (just like _bfd_elf_create_dynamic_sections has to create .dynbss and .rela.bss). */ @@ -1644,6 +1670,9 @@ ppc_elf_create_dynamic_sections (abfd, info) register asection *s; flagword flags; + if (!ppc_elf_create_got (abfd, info)) + return false; + if (!_bfd_elf_create_dynamic_sections (abfd, info)) return false; @@ -1663,7 +1692,13 @@ ppc_elf_create_dynamic_sections (abfd, info) || ! bfd_set_section_alignment (abfd, s, 2)) return false; } - return true; + + s = bfd_get_section_by_name (abfd, ".plt"); + if (s == NULL) + abort (); + + flags = SEC_ALLOC | SEC_CODE | SEC_IN_MEMORY | SEC_LINKER_CREATED; + return bfd_set_section_flags (abfd, s, flags); } /* Adjust a symbol defined by a dynamic object and referenced by a @@ -2119,10 +2154,9 @@ ppc_elf_check_relocs (abfd, info, sec, relocs) { if (dynobj == NULL) elf_hash_table (info)->dynobj = dynobj = abfd; - if (! _bfd_elf_create_got_section (dynobj, info)) + sgot = ppc_elf_create_got (dynobj, info); + if (sgot == NULL) return false; - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); } } @@ -2139,10 +2173,9 @@ ppc_elf_check_relocs (abfd, info, sec, relocs) { if (dynobj == NULL) elf_hash_table (info)->dynobj = dynobj = abfd; - if (! _bfd_elf_create_got_section (dynobj, info)) + sgot = ppc_elf_create_got (dynobj, info); + if (sgot == NULL) return false; - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); } if (srelgot == NULL @@ -2542,7 +2575,8 @@ ppc_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) { if (sym->st_shndx == SHN_COMMON && !info->relocateable - && sym->st_size <= elf_gp_size (abfd)) + && sym->st_size <= elf_gp_size (abfd) + && info->hash->creator->flavour == bfd_target_elf_flavour) { /* Common symbols less than or equal to -G nn bytes are automatically put into .sdata. */ @@ -2895,6 +2929,9 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, (info->relocateable) ? " (relocatable)" : ""); #endif + if (info->relocateable) + return true; + if (!ppc_elf_howto_table[R_PPC_ADDR32]) /* Initialize howto table if needed. */ ppc_elf_howto_init (); @@ -2939,34 +2976,6 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section, howto = ppc_elf_howto_table[(int) r_type]; r_symndx = ELF32_R_SYM (rel->r_info); - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if ((unsigned) ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections[r_symndx]; - addend = rel->r_addend += sec->output_offset + sym->st_value; - } - } - -#ifdef DEBUG - fprintf (stderr, "\ttype = %s (%d), symbol index = %ld, offset = %ld, addend = %ld\n", - howto->name, - (int) r_type, - r_symndx, - (long) offset, - (long) addend); -#endif - continue; - } - - /* This is a final link. */ if (r_symndx < symtab_hdr->sh_info) { sym = local_syms + r_symndx; @@ -3780,6 +3789,7 @@ ppc_elf_grok_psinfo (abfd, note) #define elf_backend_can_refcount 1 #define elf_backend_got_header_size 12 #define elf_backend_plt_header_size PLT_INITIAL_ENTRY_SIZE +#define elf_backend_rela_normal 1 #define bfd_elf32_bfd_merge_private_bfd_data ppc_elf_merge_private_bfd_data #define bfd_elf32_bfd_relax_section ppc_elf_relax_section diff --git a/contrib/binutils/bfd/elf32-s390.c b/contrib/binutils/bfd/elf32-s390.c new file mode 100644 index 0000000..ed5f3f0 --- /dev/null +++ b/contrib/binutils/bfd/elf32-s390.c @@ -0,0 +1,2476 @@ +/* IBM S/390-specific support for 32-bit ELF + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Carl B. Pedersen and Martin Schwidefsky. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "libbfd.h" +#include "elf-bfd.h" + +static reloc_howto_type *elf_s390_reloc_type_lookup + PARAMS ((bfd *, bfd_reloc_code_real_type)); +static void elf_s390_info_to_howto + PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); +static boolean elf_s390_is_local_label_name + PARAMS ((bfd *, const char *)); +static struct bfd_hash_entry *link_hash_newfunc + PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); +static struct bfd_link_hash_table *elf_s390_link_hash_table_create + PARAMS ((bfd *)); +static boolean create_got_section + PARAMS((bfd *, struct bfd_link_info *)); +static boolean elf_s390_create_dynamic_sections + PARAMS((bfd *, struct bfd_link_info *)); +static void elf_s390_copy_indirect_symbol + PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *)); +static boolean elf_s390_check_relocs + PARAMS ((bfd *, struct bfd_link_info *, asection *, + const Elf_Internal_Rela *)); +static asection *elf_s390_gc_mark_hook + PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + struct elf_link_hash_entry *, Elf_Internal_Sym *)); +static boolean elf_s390_gc_sweep_hook + PARAMS ((bfd *, struct bfd_link_info *, asection *, + const Elf_Internal_Rela *)); +static boolean elf_s390_adjust_dynamic_symbol + PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); +static boolean allocate_dynrelocs + PARAMS ((struct elf_link_hash_entry *, PTR)); +static boolean readonly_dynrelocs + PARAMS ((struct elf_link_hash_entry *, PTR)); +static boolean elf_s390_size_dynamic_sections + PARAMS ((bfd *, struct bfd_link_info *)); +static boolean elf_s390_relocate_section + PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, + Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); +static boolean elf_s390_finish_dynamic_symbol + PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, + Elf_Internal_Sym *)); +static enum elf_reloc_type_class elf_s390_reloc_type_class + PARAMS ((const Elf_Internal_Rela *)); +static boolean elf_s390_finish_dynamic_sections + PARAMS ((bfd *, struct bfd_link_info *)); +static boolean elf_s390_object_p PARAMS ((bfd *)); +static boolean elf_s390_grok_prstatus PARAMS ((bfd *, Elf_Internal_Note *)); + +#define USE_RELA 1 /* We want RELA relocations, not REL. */ + +#include "elf/s390.h" + +/* The relocation "howto" table. */ + +static reloc_howto_type elf_howto_table[] = +{ + HOWTO (R_390_NONE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_390_NONE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO(R_390_8, 0, 0, 8, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_8", false, 0,0x000000ff, false), + HOWTO(R_390_12, 0, 1, 12, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_390_12", false, 0,0x00000fff, false), + HOWTO(R_390_16, 0, 1, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_16", false, 0,0x0000ffff, false), + HOWTO(R_390_32, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_32", false, 0,0xffffffff, false), + HOWTO(R_390_PC32, 0, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC32", false, 0,0xffffffff, true), + HOWTO(R_390_GOT12, 0, 1, 12, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_390_GOT12", false, 0,0x00000fff, false), + HOWTO(R_390_GOT32, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT32", false, 0,0xffffffff, false), + HOWTO(R_390_PLT32, 0, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT32", false, 0,0xffffffff, true), + HOWTO(R_390_COPY, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_COPY", false, 0,0xffffffff, false), + HOWTO(R_390_GLOB_DAT, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GLOB_DAT",false, 0,0xffffffff, false), + HOWTO(R_390_JMP_SLOT, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_JMP_SLOT",false, 0,0xffffffff, false), + HOWTO(R_390_RELATIVE, 0, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_RELATIVE",false, 0,0xffffffff, false), + HOWTO(R_390_GOTOFF, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTOFF", false, 0,0xffffffff, false), + HOWTO(R_390_GOTPC, 0, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTPC", false, 0,0xffffffff, true), + HOWTO(R_390_GOT16, 0, 1, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT16", false, 0,0x0000ffff, false), + HOWTO(R_390_PC16, 0, 1, 16, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC16", false, 0,0x0000ffff, true), + HOWTO(R_390_PC16DBL, 1, 1, 16, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC16DBL", false, 0,0x0000ffff, true), + HOWTO(R_390_PLT16DBL, 1, 1, 16, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT16DBL", false, 0,0x0000ffff, true), + HOWTO(R_390_PC32DBL, 1, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC32DBL", false, 0,0xffffffff, true), + HOWTO(R_390_PLT32DBL, 1, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT32DBL", false, 0,0xffffffff, true), + HOWTO(R_390_GOTPCDBL, 1, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTPCDBL", false, 0,0xffffffff, true), + HOWTO(R_390_GOTENT, 1, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTENT", false, 0,0xffffffff, true), +}; + +/* GNU extension to record C++ vtable hierarchy. */ +static reloc_howto_type elf32_s390_vtinherit_howto = + HOWTO (R_390_GNU_VTINHERIT, 0,2,0,false,0,complain_overflow_dont, NULL, "R_390_GNU_VTINHERIT", false,0, 0, false); +static reloc_howto_type elf32_s390_vtentry_howto = + HOWTO (R_390_GNU_VTENTRY, 0,2,0,false,0,complain_overflow_dont, _bfd_elf_rel_vtable_reloc_fn,"R_390_GNU_VTENTRY", false,0,0, false); + +static reloc_howto_type * +elf_s390_reloc_type_lookup (abfd, code) + bfd *abfd ATTRIBUTE_UNUSED; + bfd_reloc_code_real_type code; +{ + switch (code) + { + case BFD_RELOC_NONE: + return &elf_howto_table[(int) R_390_NONE]; + case BFD_RELOC_8: + return &elf_howto_table[(int) R_390_8]; + case BFD_RELOC_390_12: + return &elf_howto_table[(int) R_390_12]; + case BFD_RELOC_16: + return &elf_howto_table[(int) R_390_16]; + case BFD_RELOC_32: + return &elf_howto_table[(int) R_390_32]; + case BFD_RELOC_CTOR: + return &elf_howto_table[(int) R_390_32]; + case BFD_RELOC_32_PCREL: + return &elf_howto_table[(int) R_390_PC32]; + case BFD_RELOC_390_GOT12: + return &elf_howto_table[(int) R_390_GOT12]; + case BFD_RELOC_32_GOT_PCREL: + return &elf_howto_table[(int) R_390_GOT32]; + case BFD_RELOC_390_PLT32: + return &elf_howto_table[(int) R_390_PLT32]; + case BFD_RELOC_390_COPY: + return &elf_howto_table[(int) R_390_COPY]; + case BFD_RELOC_390_GLOB_DAT: + return &elf_howto_table[(int) R_390_GLOB_DAT]; + case BFD_RELOC_390_JMP_SLOT: + return &elf_howto_table[(int) R_390_JMP_SLOT]; + case BFD_RELOC_390_RELATIVE: + return &elf_howto_table[(int) R_390_RELATIVE]; + case BFD_RELOC_32_GOTOFF: + return &elf_howto_table[(int) R_390_GOTOFF]; + case BFD_RELOC_390_GOTPC: + return &elf_howto_table[(int) R_390_GOTPC]; + case BFD_RELOC_390_GOT16: + return &elf_howto_table[(int) R_390_GOT16]; + case BFD_RELOC_16_PCREL: + return &elf_howto_table[(int) R_390_PC16]; + case BFD_RELOC_390_PC16DBL: + return &elf_howto_table[(int) R_390_PC16DBL]; + case BFD_RELOC_390_PLT16DBL: + return &elf_howto_table[(int) R_390_PLT16DBL]; + case BFD_RELOC_390_PC32DBL: + return &elf_howto_table[(int) R_390_PC32DBL]; + case BFD_RELOC_390_PLT32DBL: + return &elf_howto_table[(int) R_390_PLT32DBL]; + case BFD_RELOC_390_GOTPCDBL: + return &elf_howto_table[(int) R_390_GOTPCDBL]; + case BFD_RELOC_390_GOTENT: + return &elf_howto_table[(int) R_390_GOTENT]; + case BFD_RELOC_VTABLE_INHERIT: + return &elf32_s390_vtinherit_howto; + case BFD_RELOC_VTABLE_ENTRY: + return &elf32_s390_vtentry_howto; + default: + break; + } + return 0; +} + +/* We need to use ELF32_R_TYPE so we have our own copy of this function, + and elf32-s390.c has its own copy. */ + +static void +elf_s390_info_to_howto (abfd, cache_ptr, dst) + bfd *abfd ATTRIBUTE_UNUSED; + arelent *cache_ptr; + Elf_Internal_Rela *dst; +{ + switch (ELF32_R_TYPE(dst->r_info)) + { + case R_390_GNU_VTINHERIT: + cache_ptr->howto = &elf32_s390_vtinherit_howto; + break; + + case R_390_GNU_VTENTRY: + cache_ptr->howto = &elf32_s390_vtentry_howto; + break; + + default: + BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_390_max); + cache_ptr->howto = &elf_howto_table[ELF32_R_TYPE(dst->r_info)]; + } +} + +static boolean +elf_s390_is_local_label_name (abfd, name) + bfd *abfd; + const char *name; +{ + if (name[0] == '.' && (name[1] == 'X' || name[1] == 'L')) + return true; + + return _bfd_elf_is_local_label_name (abfd, name); +} + +/* Functions for the 390 ELF linker. */ + +/* The name of the dynamic interpreter. This is put in the .interp + section. */ + +#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" + +/* The size in bytes of the first entry in the procedure linkage table. */ +#define PLT_FIRST_ENTRY_SIZE 32 +/* The size in bytes of an entry in the procedure linkage table. */ +#define PLT_ENTRY_SIZE 32 + +#define GOT_ENTRY_SIZE 4 + +/* The first three entries in a procedure linkage table are reserved, + and the initial contents are unimportant (we zero them out). + Subsequent entries look like this. See the SVR4 ABI 386 + supplement to see how this works. */ + +/* For the s390, simple addr offset can only be 0 - 4096. + To use the full 2 GB address space, several instructions + are needed to load an address in a register and execute + a branch( or just saving the address) + + Furthermore, only r 0 and 1 are free to use!!! */ + +/* The first 3 words in the GOT are then reserved. + Word 0 is the address of the dynamic table. + Word 1 is a pointer to a structure describing the object + Word 2 is used to point to the loader entry address. + + The code for position independand PLT entries looks like this: + + r12 holds addr of the current GOT at entry to the PLT + + The GOT holds the address in the PLT to be executed. + The loader then gets: + 24(15) = Pointer to the structure describing the object. + 28(15) = Offset in symbol table + + The loader must then find the module where the function is + and insert the address in the GOT. + + Note: 390 can only address +- 64 K relative. + We check if offset > 65536, then make a relative branch -64xxx + back to a previous defined branch + +PLT1: BASR 1,0 # 2 bytes + L 1,22(1) # 4 bytes Load offset in GOT in r 1 + L 1,(1,12) # 4 bytes Load address from GOT in r1 + BCR 15,1 # 2 bytes Jump to address +RET1: BASR 1,0 # 2 bytes Return from GOT 1st time + L 1,14(1) # 4 bytes Load offset in symol table in r1 + BRC 15,-x # 4 bytes Jump to start of PLT + .word 0 # 2 bytes filler + .long ? # 4 bytes offset in GOT + .long ? # 4 bytes offset into symbol table + + This was the general case. There are two additional, optimizes PLT + definitions. One for GOT offsets < 4096 and one for GOT offsets < 32768. + First the one for GOT offsets < 4096: + +PLT1: L 1,<offset>(12) # 4 bytes Load address from GOT in R1 + BCR 15,1 # 2 bytes Jump to address + .word 0,0,0 # 6 bytes filler +RET1: BASR 1,0 # 2 bytes Return from GOT 1st time + L 1,14(1) # 4 bytes Load offset in symbol table in r1 + BRC 15,-x # 4 bytes Jump to start of PLT + .word 0,0,0 # 6 bytes filler + .long ? # 4 bytes offset into symbol table + + Second the one for GOT offsets < 32768: + +PLT1: LHI 1,<offset> # 4 bytes Load offset in GOT to r1 + L 1,(1,12) # 4 bytes Load address from GOT to r1 + BCR 15,1 # 2 bytes Jump to address + .word 0 # 2 bytes filler +RET1: BASR 1,0 # 2 bytes Return from GOT 1st time + L 1,14(1) # 4 bytes Load offset in symbol table in r1 + BRC 15,-x # 4 bytes Jump to start of PLT + .word 0,0,0 # 6 bytes filler + .long ? # 4 bytes offset into symbol table + +Total = 32 bytes per PLT entry + + The code for static build PLT entries looks like this: + +PLT1: BASR 1,0 # 2 bytes + L 1,22(1) # 4 bytes Load address of GOT entry + L 1,0(0,1) # 4 bytes Load address from GOT in r1 + BCR 15,1 # 2 bytes Jump to address +RET1: BASR 1,0 # 2 bytes Return from GOT 1st time + L 1,14(1) # 4 bytes Load offset in symbol table in r1 + BRC 15,-x # 4 bytes Jump to start of PLT + .word 0 # 2 bytes filler + .long ? # 4 bytes address of GOT entry + .long ? # 4 bytes offset into symbol table */ + +#define PLT_PIC_ENTRY_WORD0 0x0d105810 +#define PLT_PIC_ENTRY_WORD1 0x10165811 +#define PLT_PIC_ENTRY_WORD2 0xc00007f1 +#define PLT_PIC_ENTRY_WORD3 0x0d105810 +#define PLT_PIC_ENTRY_WORD4 0x100ea7f4 + +#define PLT_PIC12_ENTRY_WORD0 0x5810c000 +#define PLT_PIC12_ENTRY_WORD1 0x07f10000 +#define PLT_PIC12_ENTRY_WORD2 0x00000000 +#define PLT_PIC12_ENTRY_WORD3 0x0d105810 +#define PLT_PIC12_ENTRY_WORD4 0x100ea7f4 + +#define PLT_PIC16_ENTRY_WORD0 0xa7180000 +#define PLT_PIC16_ENTRY_WORD1 0x5811c000 +#define PLT_PIC16_ENTRY_WORD2 0x07f10000 +#define PLT_PIC16_ENTRY_WORD3 0x0d105810 +#define PLT_PIC16_ENTRY_WORD4 0x100ea7f4 + +#define PLT_ENTRY_WORD0 0x0d105810 +#define PLT_ENTRY_WORD1 0x10165810 +#define PLT_ENTRY_WORD2 0x100007f1 +#define PLT_ENTRY_WORD3 0x0d105810 +#define PLT_ENTRY_WORD4 0x100ea7f4 + +/* The first PLT entry pushes the offset into the symbol table + from R1 onto the stack at 8(15) and the loader object info + at 12(15), loads the loader address in R1 and jumps to it. */ + +/* The first entry in the PLT for PIC code: + +PLT0: + ST 1,28(15) # R1 has offset into symbol table + L 1,4(12) # Get loader ino(object struct address) + ST 1,24(15) # Store address + L 1,8(12) # Entry address of loader in R1 + BR 1 # Jump to loader + + The first entry in the PLT for static code: + +PLT0: + ST 1,28(15) # R1 has offset into symbol table + BASR 1,0 + L 1,18(0,1) # Get address of GOT + MVC 24(4,15),4(1) # Move loader ino to stack + L 1,8(1) # Get address of loader + BR 1 # Jump to loader + .word 0 # filler + .long got # address of GOT */ + +#define PLT_PIC_FIRST_ENTRY_WORD0 0x5010f01c +#define PLT_PIC_FIRST_ENTRY_WORD1 0x5810c004 +#define PLT_PIC_FIRST_ENTRY_WORD2 0x5010f018 +#define PLT_PIC_FIRST_ENTRY_WORD3 0x5810c008 +#define PLT_PIC_FIRST_ENTRY_WORD4 0x07f10000 + +#define PLT_FIRST_ENTRY_WORD0 0x5010f01c +#define PLT_FIRST_ENTRY_WORD1 0x0d105810 +#define PLT_FIRST_ENTRY_WORD2 0x1012D203 +#define PLT_FIRST_ENTRY_WORD3 0xf0181004 +#define PLT_FIRST_ENTRY_WORD4 0x58101008 +#define PLT_FIRST_ENTRY_WORD5 0x07f10000 + +/* The s390 linker needs to keep track of the number of relocs that it + decides to copy as dynamic relocs in check_relocs for each symbol. + This is so that it can later discard them if they are found to be + unnecessary. We store the information in a field extending the + regular ELF linker hash table. */ + +struct elf_s390_dyn_relocs +{ + struct elf_s390_dyn_relocs *next; + + /* The input section of the reloc. */ + asection *sec; + + /* Total number of relocs copied for the input section. */ + bfd_size_type count; + + /* Number of pc-relative relocs copied for the input section. */ + bfd_size_type pc_count; +}; + +/* s390 ELF linker hash entry. */ + +struct elf_s390_link_hash_entry +{ + struct elf_link_hash_entry elf; + + /* Track dynamic relocs copied for this symbol. */ + struct elf_s390_dyn_relocs *dyn_relocs; +}; + +/* s390 ELF linker hash table. */ + +struct elf_s390_link_hash_table +{ + struct elf_link_hash_table elf; + + /* Short-cuts to get to dynamic linker sections. */ + asection *sgot; + asection *sgotplt; + asection *srelgot; + asection *splt; + asection *srelplt; + asection *sdynbss; + asection *srelbss; + + /* Small local sym to section mapping cache. */ + struct sym_sec_cache sym_sec; +}; + +/* Get the s390 ELF linker hash table from a link_info structure. */ + +#define elf_s390_hash_table(p) \ + ((struct elf_s390_link_hash_table *) ((p)->hash)) + +/* Create an entry in an s390 ELF linker hash table. */ + +static struct bfd_hash_entry * +link_hash_newfunc (entry, table, string) + struct bfd_hash_entry *entry; + struct bfd_hash_table *table; + const char *string; +{ + /* Allocate the structure if it has not already been allocated by a + subclass. */ + if (entry == NULL) + { + entry = bfd_hash_allocate (table, + sizeof (struct elf_s390_link_hash_entry)); + if (entry == NULL) + return entry; + } + + /* Call the allocation method of the superclass. */ + entry = _bfd_elf_link_hash_newfunc (entry, table, string); + if (entry != NULL) + { + struct elf_s390_link_hash_entry *eh; + + eh = (struct elf_s390_link_hash_entry *) entry; + eh->dyn_relocs = NULL; + } + + return entry; +} + +/* Create an s390 ELF linker hash table. */ + +static struct bfd_link_hash_table * +elf_s390_link_hash_table_create (abfd) + bfd *abfd; +{ + struct elf_s390_link_hash_table *ret; + bfd_size_type amt = sizeof (struct elf_s390_link_hash_table); + + ret = (struct elf_s390_link_hash_table *) bfd_alloc (abfd, amt); + if (ret == NULL) + return NULL; + + if (! _bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc)) + { + bfd_release (abfd, ret); + return NULL; + } + + ret->sgot = NULL; + ret->sgotplt = NULL; + ret->srelgot = NULL; + ret->splt = NULL; + ret->srelplt = NULL; + ret->sdynbss = NULL; + ret->srelbss = NULL; + ret->sym_sec.abfd = NULL; + + return &ret->elf.root; +} + +/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up + shortcuts to them in our hash table. */ + +static boolean +create_got_section (dynobj, info) + bfd *dynobj; + struct bfd_link_info *info; +{ + struct elf_s390_link_hash_table *htab; + + if (! _bfd_elf_create_got_section (dynobj, info)) + return false; + + htab = elf_s390_hash_table (info); + htab->sgot = bfd_get_section_by_name (dynobj, ".got"); + htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt"); + if (!htab->sgot || !htab->sgotplt) + abort (); + + htab->srelgot = bfd_make_section (dynobj, ".rela.got"); + if (htab->srelgot == NULL + || ! bfd_set_section_flags (dynobj, htab->srelgot, + (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS + | SEC_IN_MEMORY | SEC_LINKER_CREATED + | SEC_READONLY)) + || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2)) + return false; + return true; +} + +/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and + .rela.bss sections in DYNOBJ, and set up shortcuts to them in our + hash table. */ + +static boolean +elf_s390_create_dynamic_sections (dynobj, info) + bfd *dynobj; + struct bfd_link_info *info; +{ + struct elf_s390_link_hash_table *htab; + + htab = elf_s390_hash_table (info); + if (!htab->sgot && !create_got_section (dynobj, info)) + return false; + + if (!_bfd_elf_create_dynamic_sections (dynobj, info)) + return false; + + htab->splt = bfd_get_section_by_name (dynobj, ".plt"); + htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt"); + htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss"); + if (!info->shared) + htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss"); + + if (!htab->splt || !htab->srelplt || !htab->sdynbss + || (!info->shared && !htab->srelbss)) + abort (); + + return true; +} + +/* Copy the extra info we tack onto an elf_link_hash_entry. */ + +static void +elf_s390_copy_indirect_symbol (dir, ind) + struct elf_link_hash_entry *dir, *ind; +{ + struct elf_s390_link_hash_entry *edir, *eind; + + edir = (struct elf_s390_link_hash_entry *) dir; + eind = (struct elf_s390_link_hash_entry *) ind; + + if (eind->dyn_relocs != NULL) + { + if (edir->dyn_relocs != NULL) + { + struct elf_s390_dyn_relocs **pp; + struct elf_s390_dyn_relocs *p; + + if (ind->root.type == bfd_link_hash_indirect) + abort (); + + /* Add reloc counts against the weak sym to the strong sym + list. Merge any entries against the same section. */ + for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) + { + struct elf_s390_dyn_relocs *q; + + for (q = edir->dyn_relocs; q != NULL; q = q->next) + if (q->sec == p->sec) + { + q->pc_count += p->pc_count; + q->count += p->count; + *pp = p->next; + break; + } + if (q == NULL) + pp = &p->next; + } + *pp = edir->dyn_relocs; + } + + edir->dyn_relocs = eind->dyn_relocs; + eind->dyn_relocs = NULL; + } + + _bfd_elf_link_hash_copy_indirect (dir, ind); +} + +/* Look through the relocs for a section during the first phase, and + allocate space in the global offset table or procedure linkage + table. */ + +static boolean +elf_s390_check_relocs (abfd, info, sec, relocs) + bfd *abfd; + struct bfd_link_info *info; + asection *sec; + const Elf_Internal_Rela *relocs; +{ + struct elf_s390_link_hash_table *htab; + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + const Elf_Internal_Rela *rel; + const Elf_Internal_Rela *rel_end; + asection *sreloc; + + if (info->relocateable) + return true; + + htab = elf_s390_hash_table (info); + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (abfd); + + sreloc = NULL; + + rel_end = relocs + sec->reloc_count; + for (rel = relocs; rel < rel_end; rel++) + { + unsigned long r_symndx; + struct elf_link_hash_entry *h; + + r_symndx = ELF32_R_SYM (rel->r_info); + + if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) + { + (*_bfd_error_handler) (_("%s: bad symbol index: %d"), + bfd_archive_filename (abfd), + r_symndx); + return false; + } + + if (r_symndx < symtab_hdr->sh_info) + h = NULL; + else + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + + switch (ELF32_R_TYPE (rel->r_info)) + { + case R_390_GOT12: + case R_390_GOT16: + case R_390_GOT32: + case R_390_GOTENT: + /* This symbol requires a global offset table entry. */ + if (h != NULL) + { + h->got.refcount += 1; + } + else + { + bfd_signed_vma *local_got_refcounts; + + /* This is a global offset table entry for a local symbol. */ + local_got_refcounts = elf_local_got_refcounts (abfd); + if (local_got_refcounts == NULL) + { + bfd_size_type size; + + size = symtab_hdr->sh_info; + size *= sizeof (bfd_signed_vma); + local_got_refcounts = ((bfd_signed_vma *) + bfd_zalloc (abfd, size)); + if (local_got_refcounts == NULL) + return false; + elf_local_got_refcounts (abfd) = local_got_refcounts; + } + local_got_refcounts[r_symndx] += 1; + } + /* Fall through */ + + case R_390_GOTOFF: + case R_390_GOTPC: + case R_390_GOTPCDBL: + if (htab->sgot == NULL) + { + if (htab->elf.dynobj == NULL) + htab->elf.dynobj = abfd; + if (!create_got_section (htab->elf.dynobj, info)) + return false; + } + break; + + case R_390_PLT16DBL: + case R_390_PLT32DBL: + case R_390_PLT32: + /* This symbol requires a procedure linkage table entry. We + actually build the entry in adjust_dynamic_symbol, + because this might be a case of linking PIC code which is + never referenced by a dynamic object, in which case we + don't need to generate a procedure linkage table entry + after all. */ + + /* If this is a local symbol, we resolve it directly without + creating a procedure linkage table entry. */ + if (h == NULL) + continue; + + h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; + h->plt.refcount += 1; + break; + + case R_390_8: + case R_390_16: + case R_390_32: + case R_390_PC16: + case R_390_PC16DBL: + case R_390_PC32DBL: + case R_390_PC32: + if (h != NULL && !info->shared) + { + /* If this reloc is in a read-only section, we might + need a copy reloc. We can't check reliably at this + stage whether the section is read-only, as input + sections have not yet been mapped to output sections. + Tentatively set the flag for now, and correct in + adjust_dynamic_symbol. */ + h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF; + + /* We may need a .plt entry if the function this reloc + refers to is in a shared lib. */ + h->plt.refcount += 1; + } + + /* If we are creating a shared library, and this is a reloc + against a global symbol, or a non PC relative reloc + against a local symbol, then we need to copy the reloc + into the shared library. However, if we are linking with + -Bsymbolic, we do not need to copy a reloc against a + global symbol which is defined in an object we are + including in the link (i.e., DEF_REGULAR is set). At + this point we have not seen all the input files, so it is + possible that DEF_REGULAR is not set now but will be set + later (it is never cleared). In case of a weak definition, + DEF_REGULAR may be cleared later by a strong definition in + a shared library. We account for that possibility below by + storing information in the relocs_copied field of the hash + table entry. A similar situation occurs when creating + shared libraries and symbol visibility changes render the + symbol local. + + If on the other hand, we are creating an executable, we + may need to keep relocations for symbols satisfied by a + dynamic library if we manage to avoid copy relocs for the + symbol. */ + if ((info->shared + && (sec->flags & SEC_ALLOC) != 0 + && ((ELF32_R_TYPE (rel->r_info) != R_390_PC16 + && ELF32_R_TYPE (rel->r_info) != R_390_PC16DBL + && ELF32_R_TYPE (rel->r_info) != R_390_PC32DBL + && ELF32_R_TYPE (rel->r_info) != R_390_PC32) + || (h != NULL + && (! info->symbolic + || h->root.type == bfd_link_hash_defweak + || (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0)))) + || (!info->shared + && (sec->flags & SEC_ALLOC) != 0 + && h != NULL + && (h->root.type == bfd_link_hash_defweak + || (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0))) + { + struct elf_s390_dyn_relocs *p; + struct elf_s390_dyn_relocs **head; + + /* We must copy these reloc types into the output file. + Create a reloc section in dynobj and make room for + this reloc. */ + if (sreloc == NULL) + { + const char *name; + bfd *dynobj; + + name = (bfd_elf_string_from_elf_section + (abfd, + elf_elfheader (abfd)->e_shstrndx, + elf_section_data (sec)->rel_hdr.sh_name)); + if (name == NULL) + return false; + + if (strncmp (name, ".rela", 5) != 0 + || strcmp (bfd_get_section_name (abfd, sec), + name + 5) != 0) + { + (*_bfd_error_handler) + (_("%s: bad relocation section name `%s\'"), + bfd_archive_filename (abfd), name); + } + + if (htab->elf.dynobj == NULL) + htab->elf.dynobj = abfd; + + dynobj = htab->elf.dynobj; + sreloc = bfd_get_section_by_name (dynobj, name); + if (sreloc == NULL) + { + flagword flags; + + sreloc = bfd_make_section (dynobj, name); + flags = (SEC_HAS_CONTENTS | SEC_READONLY + | SEC_IN_MEMORY | SEC_LINKER_CREATED); + if ((sec->flags & SEC_ALLOC) != 0) + flags |= SEC_ALLOC | SEC_LOAD; + if (sreloc == NULL + || ! bfd_set_section_flags (dynobj, sreloc, flags) + || ! bfd_set_section_alignment (dynobj, sreloc, 2)) + return false; + } + elf_section_data (sec)->sreloc = sreloc; + } + + /* If this is a global symbol, we count the number of + relocations we need for this symbol. */ + if (h != NULL) + { + head = &((struct elf_s390_link_hash_entry *) h)->dyn_relocs; + } + else + { + /* Track dynamic relocs needed for local syms too. + We really need local syms available to do this + easily. Oh well. */ + + asection *s; + s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, + sec, r_symndx); + if (s == NULL) + return false; + + head = ((struct elf_s390_dyn_relocs **) + &elf_section_data (s)->local_dynrel); + } + + p = *head; + if (p == NULL || p->sec != sec) + { + bfd_size_type amt = sizeof *p; + p = ((struct elf_s390_dyn_relocs *) + bfd_alloc (htab->elf.dynobj, amt)); + if (p == NULL) + return false; + p->next = *head; + *head = p; + p->sec = sec; + p->count = 0; + p->pc_count = 0; + } + + p->count += 1; + if (ELF32_R_TYPE (rel->r_info) == R_390_PC16 + || ELF32_R_TYPE (rel->r_info) == R_390_PC16DBL + || ELF32_R_TYPE (rel->r_info) == R_390_PC32DBL + || ELF32_R_TYPE (rel->r_info) == R_390_PC32) + p->pc_count += 1; + } + break; + + /* This relocation describes the C++ object vtable hierarchy. + Reconstruct it for later use during GC. */ + case R_390_GNU_VTINHERIT: + if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + return false; + break; + + /* This relocation describes which C++ vtable entries are actually + used. Record for later use during GC. */ + case R_390_GNU_VTENTRY: + if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + return false; + break; + + default: + break; + } + } + + return true; +} + +/* Return the section that should be marked against GC for a given + relocation. */ + +static asection * +elf_s390_gc_mark_hook (abfd, info, rel, h, sym) + bfd *abfd; + struct bfd_link_info *info ATTRIBUTE_UNUSED; + Elf_Internal_Rela *rel; + struct elf_link_hash_entry *h; + Elf_Internal_Sym *sym; +{ + if (h != NULL) + { + switch (ELF32_R_TYPE (rel->r_info)) + { + case R_390_GNU_VTINHERIT: + case R_390_GNU_VTENTRY: + break; + + default: + switch (h->root.type) + { + case bfd_link_hash_defined: + case bfd_link_hash_defweak: + return h->root.u.def.section; + + case bfd_link_hash_common: + return h->root.u.c.p->section; + + default: + break; + } + } + } + else + { + return bfd_section_from_elf_index (abfd, sym->st_shndx); + } + + return NULL; +} + +/* Update the got entry reference counts for the section being removed. */ + +static boolean +elf_s390_gc_sweep_hook (abfd, info, sec, relocs) + bfd *abfd; + struct bfd_link_info *info; + asection *sec; + const Elf_Internal_Rela *relocs; +{ + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + bfd_signed_vma *local_got_refcounts; + const Elf_Internal_Rela *rel, *relend; + unsigned long r_symndx; + struct elf_link_hash_entry *h; + + elf_section_data (sec)->local_dynrel = NULL; + + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (abfd); + local_got_refcounts = elf_local_got_refcounts (abfd); + + relend = relocs + sec->reloc_count; + for (rel = relocs; rel < relend; rel++) + switch (ELF32_R_TYPE (rel->r_info)) + { + case R_390_GOT12: + case R_390_GOT16: + case R_390_GOT32: + case R_390_GOTOFF: + case R_390_GOTPC: + case R_390_GOTPCDBL: + case R_390_GOTENT: + r_symndx = ELF32_R_SYM (rel->r_info); + if (r_symndx >= symtab_hdr->sh_info) + { + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + if (h->got.refcount > 0) + h->got.refcount -= 1; + } + else if (local_got_refcounts != NULL) + { + if (local_got_refcounts[r_symndx] > 0) + local_got_refcounts[r_symndx] -= 1; + } + break; + + case R_390_8: + case R_390_12: + case R_390_16: + case R_390_32: + case R_390_PC16: + case R_390_PC16DBL: + case R_390_PC32DBL: + case R_390_PC32: + r_symndx = ELF32_R_SYM (rel->r_info); + if (r_symndx >= symtab_hdr->sh_info) + { + struct elf_s390_link_hash_entry *eh; + struct elf_s390_dyn_relocs **pp; + struct elf_s390_dyn_relocs *p; + + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + + if (!info->shared && h->plt.refcount > 0) + h->plt.refcount -= 1; + + eh = (struct elf_s390_link_hash_entry *) h; + + for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) + if (p->sec == sec) + { + if (ELF32_R_TYPE (rel->r_info) == R_390_PC16 + || ELF32_R_TYPE (rel->r_info) == R_390_PC16DBL + || ELF32_R_TYPE (rel->r_info) == R_390_PC32DBL + || ELF32_R_TYPE (rel->r_info) == R_390_PC32) + p->pc_count -= 1; + p->count -= 1; + if (p->count == 0) + *pp = p->next; + break; + } + } + break; + + case R_390_PLT16DBL: + case R_390_PLT32DBL: + case R_390_PLT32: + r_symndx = ELF32_R_SYM (rel->r_info); + if (r_symndx >= symtab_hdr->sh_info) + { + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + if (h->plt.refcount > 0) + h->plt.refcount -= 1; + } + break; + + default: + break; + } + + return true; +} + +/* Adjust a symbol defined by a dynamic object and referenced by a + regular object. The current definition is in some section of the + dynamic object, but we're not including those sections. We have to + change the definition to something the rest of the link can + understand. */ + +static boolean +elf_s390_adjust_dynamic_symbol (info, h) + struct bfd_link_info *info; + struct elf_link_hash_entry *h; +{ + struct elf_s390_link_hash_table *htab; + struct elf_s390_link_hash_entry * eh; + struct elf_s390_dyn_relocs *p; + asection *s; + unsigned int power_of_two; + + /* If this is a function, put it in the procedure linkage table. We + will fill in the contents of the procedure linkage table later + (although we could actually do it here). */ + if (h->type == STT_FUNC + || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) + { + if (h->plt.refcount <= 0 + || (! info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0 + && h->root.type != bfd_link_hash_undefweak + && h->root.type != bfd_link_hash_undefined)) + { + /* This case can occur if we saw a PLT32 reloc in an input + file, but the symbol was never referred to by a dynamic + object, or if all references were garbage collected. In + such a case, we don't actually need to build a procedure + linkage table, and we can just do a PC32 reloc instead. */ + h->plt.offset = (bfd_vma) -1; + h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; + } + + return true; + } + else + /* It's possible that we incorrectly decided a .plt reloc was + needed for an R_390_PC32 reloc to a non-function sym in + check_relocs. We can't decide accurately between function and + non-function syms in check-relocs; Objects loaded later in + the link may change h->type. So fix it now. */ + h->plt.offset = (bfd_vma) -1; + + /* If this is a weak symbol, and there is a real definition, the + processor independent code will have arranged for us to see the + real definition first, and we can just use the same value. */ + if (h->weakdef != NULL) + { + BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined + || h->weakdef->root.type == bfd_link_hash_defweak); + h->root.u.def.section = h->weakdef->root.u.def.section; + h->root.u.def.value = h->weakdef->root.u.def.value; + return true; + } + + /* This is a reference to a symbol defined by a dynamic object which + is not a function. */ + + /* If we are creating a shared library, we must presume that the + only references to the symbol are via the global offset table. + For such cases we need not do anything here; the relocations will + be handled correctly by relocate_section. */ + if (info->shared) + return true; + + /* If there are no references to this symbol that do not use the + GOT, we don't need to generate a copy reloc. */ + if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0) + return true; + + /* If -z nocopyreloc was given, we won't generate them either. */ + if (info->nocopyreloc) + { + h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF; + return true; + } + + eh = (struct elf_s390_link_hash_entry *) h; + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + s = p->sec->output_section; + if (s != NULL && (s->flags & SEC_READONLY) != 0) + break; + } + + /* If we didn't find any dynamic relocs in read-only sections, then + we'll be keeping the dynamic relocs and avoiding the copy reloc. */ + if (p == NULL) + { + h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF; + return true; + } + + /* We must allocate the symbol in our .dynbss section, which will + become part of the .bss section of the executable. There will be + an entry for this symbol in the .dynsym section. The dynamic + object will contain position independent code, so all references + from the dynamic object to this symbol will go through the global + offset table. The dynamic linker will use the .dynsym entry to + determine the address it must put in the global offset table, so + both the dynamic object and the regular object will refer to the + same memory location for the variable. */ + + htab = elf_s390_hash_table (info); + + /* We must generate a R_390_COPY reloc to tell the dynamic linker to + copy the initial value out of the dynamic object and into the + runtime process image. */ + if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) + { + htab->srelbss->_raw_size += sizeof (Elf32_External_Rela); + h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY; + } + + /* We need to figure out the alignment required for this symbol. I + have no idea how ELF linkers handle this. */ + power_of_two = bfd_log2 (h->size); + if (power_of_two > 3) + power_of_two = 3; + + /* Apply the required alignment. */ + s = htab->sdynbss; + s->_raw_size = BFD_ALIGN (s->_raw_size, (bfd_size_type) (1 << power_of_two)); + if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s)) + { + if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two)) + return false; + } + + /* Define the symbol as being at this point in the section. */ + h->root.u.def.section = s; + h->root.u.def.value = s->_raw_size; + + /* Increment the section size to make room for the symbol. */ + s->_raw_size += h->size; + + return true; +} + +/* This is the condition under which elf_s390_finish_dynamic_symbol + will be called from elflink.h. If elflink.h doesn't call our + finish_dynamic_symbol routine, we'll need to do something about + initializing any .plt and .got entries in elf_s390_relocate_section. */ +#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \ + ((DYN) \ + && ((INFO)->shared \ + || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ + && ((H)->dynindx != -1 \ + || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) + +/* Allocate space in .plt, .got and associated reloc sections for + dynamic relocs. */ + +static boolean +allocate_dynrelocs (h, inf) + struct elf_link_hash_entry *h; + PTR inf; +{ + struct bfd_link_info *info; + struct elf_s390_link_hash_table *htab; + struct elf_s390_link_hash_entry *eh; + struct elf_s390_dyn_relocs *p; + + if (h->root.type == bfd_link_hash_indirect) + return true; + + if (h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + info = (struct bfd_link_info *) inf; + htab = elf_s390_hash_table (info); + + if (htab->elf.dynamic_sections_created + && h->plt.refcount > 0) + { + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) + { + if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + return false; + } + + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h)) + { + asection *s = htab->splt; + + /* If this is the first .plt entry, make room for the special + first entry. */ + if (s->_raw_size == 0) + s->_raw_size += PLT_FIRST_ENTRY_SIZE; + + h->plt.offset = s->_raw_size; + + /* If this symbol is not defined in a regular file, and we are + not generating a shared library, then set the symbol to this + location in the .plt. This is required to make function + pointers compare as equal between the normal executable and + the shared library. */ + if (! info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) + { + h->root.u.def.section = s; + h->root.u.def.value = h->plt.offset; + } + + /* Make room for this entry. */ + s->_raw_size += PLT_ENTRY_SIZE; + + /* We also need to make an entry in the .got.plt section, which + will be placed in the .got section by the linker script. */ + htab->sgotplt->_raw_size += GOT_ENTRY_SIZE; + + /* We also need to make an entry in the .rela.plt section. */ + htab->srelplt->_raw_size += sizeof (Elf32_External_Rela); + } + else + { + h->plt.offset = (bfd_vma) -1; + h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; + } + } + else + { + h->plt.offset = (bfd_vma) -1; + h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; + } + + if (h->got.refcount > 0) + { + asection *s; + boolean dyn; + + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) + { + if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + return false; + } + + s = htab->sgot; + h->got.offset = s->_raw_size; + s->_raw_size += GOT_ENTRY_SIZE; + dyn = htab->elf.dynamic_sections_created; + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)) + htab->srelgot->_raw_size += sizeof (Elf32_External_Rela); + } + else + h->got.offset = (bfd_vma) -1; + + eh = (struct elf_s390_link_hash_entry *) h; + if (eh->dyn_relocs == NULL) + return true; + + /* In the shared -Bsymbolic case, discard space allocated for + dynamic pc-relative relocs against symbols which turn out to be + defined in regular objects. For the normal shared case, discard + space for pc-relative relocs that have become local due to symbol + visibility changes. */ + + if (info->shared) + { + if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 + && ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0 + || info->symbolic)) + { + struct elf_s390_dyn_relocs **pp; + + for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + { + p->count -= p->pc_count; + p->pc_count = 0; + if (p->count == 0) + *pp = p->next; + else + pp = &p->next; + } + } + } + else + { + /* For the non-shared case, discard space for relocs against + symbols which turn out to need copy relocs or are not + dynamic. */ + + if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0 + && (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) + || (htab->elf.dynamic_sections_created + && (h->root.type == bfd_link_hash_undefweak + || h->root.type == bfd_link_hash_undefined)))) + { + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) + { + if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + return false; + } + + /* If that succeeded, we know we'll be keeping all the + relocs. */ + if (h->dynindx != -1) + goto keep; + } + + eh->dyn_relocs = NULL; + + keep: ; + } + + /* Finally, allocate space. */ + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + asection *sreloc = elf_section_data (p->sec)->sreloc; + sreloc->_raw_size += p->count * sizeof (Elf32_External_Rela); + } + + return true; +} + +/* Find any dynamic relocs that apply to read-only sections. */ + +static boolean +readonly_dynrelocs (h, inf) + struct elf_link_hash_entry *h; + PTR inf; +{ + struct elf_s390_link_hash_entry *eh; + struct elf_s390_dyn_relocs *p; + + if (h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + eh = (struct elf_s390_link_hash_entry *) h; + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + { + struct bfd_link_info *info = (struct bfd_link_info *) inf; + + info->flags |= DF_TEXTREL; + + /* Not an error, just cut short the traversal. */ + return false; + } + } + return true; +} + +/* Set the sizes of the dynamic sections. */ + +static boolean +elf_s390_size_dynamic_sections (output_bfd, info) + bfd *output_bfd ATTRIBUTE_UNUSED; + struct bfd_link_info *info; +{ + struct elf_s390_link_hash_table *htab; + bfd *dynobj; + asection *s; + boolean relocs; + bfd *ibfd; + + htab = elf_s390_hash_table (info); + dynobj = htab->elf.dynobj; + if (dynobj == NULL) + abort (); + + if (htab->elf.dynamic_sections_created) + { + /* Set the contents of the .interp section to the interpreter. */ + if (! info->shared) + { + s = bfd_get_section_by_name (dynobj, ".interp"); + if (s == NULL) + abort (); + s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; + s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; + } + } + + /* Set up .got offsets for local syms, and space for local dynamic + relocs. */ + for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) + { + bfd_signed_vma *local_got; + bfd_signed_vma *end_local_got; + bfd_size_type locsymcount; + Elf_Internal_Shdr *symtab_hdr; + asection *srela; + + if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) + continue; + + for (s = ibfd->sections; s != NULL; s = s->next) + { + struct elf_s390_dyn_relocs *p; + + for (p = *((struct elf_s390_dyn_relocs **) + &elf_section_data (s)->local_dynrel); + p != NULL; + p = p->next) + { + if (!bfd_is_abs_section (p->sec) + && bfd_is_abs_section (p->sec->output_section)) + { + /* Input section has been discarded, either because + it is a copy of a linkonce section or due to + linker script /DISCARD/, so we'll be discarding + the relocs too. */ + } + else if (p->count != 0) + { + srela = elf_section_data (p->sec)->sreloc; + srela->_raw_size += p->count * sizeof (Elf32_External_Rela); + if ((p->sec->output_section->flags & SEC_READONLY) != 0) + info->flags |= DF_TEXTREL; + } + } + } + + local_got = elf_local_got_refcounts (ibfd); + if (!local_got) + continue; + + symtab_hdr = &elf_tdata (ibfd)->symtab_hdr; + locsymcount = symtab_hdr->sh_info; + end_local_got = local_got + locsymcount; + s = htab->sgot; + srela = htab->srelgot; + for (; local_got < end_local_got; ++local_got) + { + if (*local_got > 0) + { + *local_got = s->_raw_size; + s->_raw_size += GOT_ENTRY_SIZE; + if (info->shared) + srela->_raw_size += sizeof (Elf32_External_Rela); + } + else + *local_got = (bfd_vma) -1; + } + } + + /* Allocate global sym .plt and .got entries, and space for global + sym dynamic relocs. */ + elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info); + + /* We now have determined the sizes of the various dynamic sections. + Allocate memory for them. */ + relocs = false; + for (s = dynobj->sections; s != NULL; s = s->next) + { + if ((s->flags & SEC_LINKER_CREATED) == 0) + continue; + + if (s == htab->splt + || s == htab->sgot + || s == htab->sgotplt) + { + /* Strip this section if we don't need it; see the + comment below. */ + } + else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0) + { + if (s->_raw_size != 0 && s != htab->srelplt) + relocs = true; + + /* We use the reloc_count field as a counter if we need + to copy relocs into the output file. */ + s->reloc_count = 0; + } + else + { + /* It's not one of our sections, so don't allocate space. */ + continue; + } + + if (s->_raw_size == 0) + { + /* If we don't need this section, strip it from the + output file. This is to handle .rela.bss and + .rela.plt. We must create it in + create_dynamic_sections, because it must be created + before the linker maps input sections to output + sections. The linker does that before + adjust_dynamic_symbol is called, and it is that + function which decides whether anything needs to go + into these sections. */ + + _bfd_strip_section_from_output (info, s); + continue; + } + + /* Allocate memory for the section contents. We use bfd_zalloc + here in case unused entries are not reclaimed before the + section's contents are written out. This should not happen, + but this way if it does, we get a R_390_NONE reloc instead + of garbage. */ + s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size); + if (s->contents == NULL) + return false; + } + + if (htab->elf.dynamic_sections_created) + { + /* Add some entries to the .dynamic section. We fill in the + values later, in elf_s390_finish_dynamic_sections, but we + must add the entries now so that we get the correct size for + the .dynamic section. The DT_DEBUG entry is filled in by the + dynamic linker and used by the debugger. */ +#define add_dynamic_entry(TAG, VAL) \ + bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL)) + + if (! info->shared) + { + if (!add_dynamic_entry (DT_DEBUG, 0)) + return false; + } + + if (htab->splt->_raw_size != 0) + { + if (!add_dynamic_entry (DT_PLTGOT, 0) + || !add_dynamic_entry (DT_PLTRELSZ, 0) + || !add_dynamic_entry (DT_PLTREL, DT_RELA) + || !add_dynamic_entry (DT_JMPREL, 0)) + return false; + } + + if (relocs) + { + if (!add_dynamic_entry (DT_RELA, 0) + || !add_dynamic_entry (DT_RELASZ, 0) + || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) + return false; + + /* If any dynamic relocs apply to a read-only section, + then we need a DT_TEXTREL entry. */ + if ((info->flags & DF_TEXTREL) == 0) + elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, + (PTR) info); + + if ((info->flags & DF_TEXTREL) != 0) + { + if (!add_dynamic_entry (DT_TEXTREL, 0)) + return false; + } + } + } +#undef add_dynamic_entry + + return true; +} + +/* Relocate a 390 ELF section. */ + +static boolean +elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, + contents, relocs, local_syms, local_sections) + bfd *output_bfd; + struct bfd_link_info *info; + bfd *input_bfd; + asection *input_section; + bfd_byte *contents; + Elf_Internal_Rela *relocs; + Elf_Internal_Sym *local_syms; + asection **local_sections; +{ + struct elf_s390_link_hash_table *htab; + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + bfd_vma *local_got_offsets; + Elf_Internal_Rela *rel; + Elf_Internal_Rela *relend; + + if (info->relocateable) + return true; + + htab = elf_s390_hash_table (info); + symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (input_bfd); + local_got_offsets = elf_local_got_offsets (input_bfd); + + rel = relocs; + relend = relocs + input_section->reloc_count; + for (; rel < relend; rel++) + { + int r_type; + reloc_howto_type *howto; + unsigned long r_symndx; + struct elf_link_hash_entry *h; + Elf_Internal_Sym *sym; + asection *sec; + bfd_vma off; + bfd_vma relocation; + boolean unresolved_reloc; + bfd_reloc_status_type r; + + r_type = ELF32_R_TYPE (rel->r_info); + if (r_type == (int) R_390_GNU_VTINHERIT + || r_type == (int) R_390_GNU_VTENTRY) + continue; + if (r_type < 0 || r_type >= (int) R_390_max) + { + bfd_set_error (bfd_error_bad_value); + return false; + } + + howto = elf_howto_table + r_type; + r_symndx = ELF32_R_SYM (rel->r_info); + h = NULL; + sym = NULL; + sec = NULL; + unresolved_reloc = false; + if (r_symndx < symtab_hdr->sh_info) + { + sym = local_syms + r_symndx; + sec = local_sections[r_symndx]; + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); + } + else + { + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + if (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + { + sec = h->root.u.def.section; + if (sec->output_section == NULL) + { + /* Set a flag that will be cleared later if we find a + relocation value for this symbol. output_section + is typically NULL for symbols satisfied by a shared + library. */ + unresolved_reloc = true; + relocation = 0; + } + else + relocation = (h->root.u.def.value + + sec->output_section->vma + + sec->output_offset); + } + else if (h->root.type == bfd_link_hash_undefweak) + relocation = 0; + else if (info->shared + && (!info->symbolic || info->allow_shlib_undefined) + && !info->no_undefined + && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) + relocation = 0; + else + { + if (! ((*info->callbacks->undefined_symbol) + (info, h->root.root.string, input_bfd, + input_section, rel->r_offset, + (!info->shared || info->no_undefined + || ELF_ST_VISIBILITY (h->other))))) + return false; + relocation = 0; + } + } + + switch (r_type) + { + case R_390_GOT12: + case R_390_GOT16: + case R_390_GOT32: + case R_390_GOTENT: + /* Relocation is to the entry for this symbol in the global + offset table. */ + if (htab->sgot == NULL) + abort (); + + if (h != NULL) + { + boolean dyn; + + off = h->got.offset; + dyn = htab->elf.dynamic_sections_created; + if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h) + || (info->shared + && (info->symbolic + || h->dynindx == -1 + || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)) + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) + { + /* This is actually a static link, or it is a + -Bsymbolic link and the symbol is defined + locally, or the symbol was forced to be local + because of a version file. We must initialize + this entry in the global offset table. Since the + offset must always be a multiple of 2, we use the + least significant bit to record whether we have + initialized it already. + + When doing a dynamic link, we create a .rel.got + relocation entry to initialize the value. This + is done in the finish_dynamic_symbol routine. */ + if ((off & 1) != 0) + off &= ~1; + else + { + bfd_put_32 (output_bfd, relocation, + htab->sgot->contents + off); + h->got.offset |= 1; + } + } + else + unresolved_reloc = false; + } + else + { + if (local_got_offsets == NULL) + abort (); + + off = local_got_offsets[r_symndx]; + + /* The offset must always be a multiple of 4. We use + the least significant bit to record whether we have + already generated the necessary reloc. */ + if ((off & 1) != 0) + off &= ~1; + else + { + bfd_put_32 (output_bfd, relocation, + htab->sgot->contents + off); + + if (info->shared) + { + asection *srelgot; + Elf_Internal_Rela outrel; + Elf32_External_Rela *loc; + + srelgot = htab->srelgot; + if (srelgot == NULL) + abort (); + + outrel.r_offset = (htab->sgot->output_section->vma + + htab->sgot->output_offset + + off); + outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE); + outrel.r_addend = relocation; + loc = (Elf32_External_Rela *) srelgot->contents; + loc += srelgot->reloc_count++; + bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); + } + + local_got_offsets[r_symndx] |= 1; + } + } + + if (off >= (bfd_vma) -2) + abort (); + + relocation = htab->sgot->output_offset + off; + + /* + * For @GOTENT the relocation is against the offset between + * the instruction and the symbols entry in the GOT and not + * between the start of the GOT and the symbols entry. We + * add the vma of the GOT to get the correct value. + */ + if (r_type == R_390_GOTENT) + relocation += htab->sgot->output_section->vma; + + break; + + case R_390_GOTOFF: + /* Relocation is relative to the start of the global offset + table. */ + + /* Note that sgot->output_offset is not involved in this + calculation. We always want the start of .got. If we + defined _GLOBAL_OFFSET_TABLE in a different way, as is + permitted by the ABI, we might have to change this + calculation. */ + relocation -= htab->sgot->output_section->vma; + break; + + case R_390_GOTPC: + case R_390_GOTPCDBL: + /* Use global offset table as symbol value. */ + relocation = htab->sgot->output_section->vma; + unresolved_reloc = false; + break; + + case R_390_PLT16DBL: + case R_390_PLT32DBL: + case R_390_PLT32: + /* Relocation is to the entry for this symbol in the + procedure linkage table. */ + + /* Resolve a PLT32 reloc against a local symbol directly, + without using the procedure linkage table. */ + if (h == NULL) + break; + + if (h->plt.offset == (bfd_vma) -1 + || htab->splt == NULL) + { + /* We didn't make a PLT entry for this symbol. This + happens when statically linking PIC code, or when + using -Bsymbolic. */ + break; + } + + relocation = (htab->splt->output_section->vma + + htab->splt->output_offset + + h->plt.offset); + unresolved_reloc = false; + break; + + case R_390_8: + case R_390_16: + case R_390_32: + case R_390_PC16: + case R_390_PC16DBL: + case R_390_PC32DBL: + case R_390_PC32: + /* r_symndx will be zero only for relocs against symbols + from removed linkonce sections, or sections discarded by + a linker script. */ + if (r_symndx == 0 + || (input_section->flags & SEC_ALLOC) == 0) + break; + + if ((info->shared + && ((r_type != R_390_PC16 + && r_type != R_390_PC16DBL + && r_type != R_390_PC32DBL + && r_type != R_390_PC32) + || (h != NULL + && h->dynindx != -1 + && (! info->symbolic + || (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0)))) + || (!info->shared + && h != NULL + && h->dynindx != -1 + && (h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0 + && (((h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_DYNAMIC) != 0 + && (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0) + || h->root.type == bfd_link_hash_undefweak + || h->root.type == bfd_link_hash_undefined))) + { + Elf_Internal_Rela outrel; + boolean skip, relocate; + asection *sreloc; + Elf32_External_Rela *loc; + + /* When generating a shared object, these relocations + are copied into the output file to be resolved at run + time. */ + + skip = false; + relocate = false; + + outrel.r_offset = + _bfd_elf_section_offset (output_bfd, info, input_section, + rel->r_offset); + if (outrel.r_offset == (bfd_vma) -1) + skip = true; + else if (outrel.r_offset == (bfd_vma) -2) + skip = true, relocate = true; + outrel.r_offset += (input_section->output_section->vma + + input_section->output_offset); + + if (skip) + memset (&outrel, 0, sizeof outrel); + else if (h != NULL + && h->dynindx != -1 + && (r_type == R_390_PC16 + || r_type == R_390_PC16DBL + || r_type == R_390_PC32DBL + || r_type == R_390_PC32 + || !info->shared + || !info->symbolic + || (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0)) + { + outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); + outrel.r_addend = rel->r_addend; + } + else + { + /* This symbol is local, or marked to become local. */ + relocate = true; + outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE); + outrel.r_addend = relocation + rel->r_addend; + } + + sreloc = elf_section_data (input_section)->sreloc; + if (sreloc == NULL) + abort (); + + loc = (Elf32_External_Rela *) sreloc->contents; + loc += sreloc->reloc_count++; + bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); + + /* If this reloc is against an external symbol, we do + not want to fiddle with the addend. Otherwise, we + need to include the symbol value so that it becomes + an addend for the dynamic reloc. */ + if (! relocate) + continue; + } + break; + + default: + break; + } + + if (unresolved_reloc + && !(info->shared + && (input_section->flags & SEC_DEBUGGING) != 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)) + (*_bfd_error_handler) + (_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"), + bfd_archive_filename (input_bfd), + bfd_get_section_name (input_bfd, input_section), + (long) rel->r_offset, + h->root.root.string); + + r = _bfd_final_link_relocate (howto, input_bfd, input_section, + contents, rel->r_offset, + relocation, rel->r_addend); + + if (r != bfd_reloc_ok) + { + const char *name; + + if (h != NULL) + name = h->root.root.string; + else + { + name = bfd_elf_string_from_elf_section (input_bfd, + symtab_hdr->sh_link, + sym->st_name); + if (name == NULL) + return false; + if (*name == '\0') + name = bfd_section_name (input_bfd, sec); + } + + if (r == bfd_reloc_overflow) + { + + if (! ((*info->callbacks->reloc_overflow) + (info, name, howto->name, (bfd_vma) 0, + input_bfd, input_section, rel->r_offset))) + return false; + } + else + { + (*_bfd_error_handler) + (_("%s(%s+0x%lx): reloc against `%s': error %d"), + bfd_archive_filename (input_bfd), + bfd_get_section_name (input_bfd, input_section), + (long) rel->r_offset, name, (int) r); + return false; + } + } + } + + return true; +} + +/* Finish up dynamic symbol handling. We set the contents of various + dynamic sections here. */ + +static boolean +elf_s390_finish_dynamic_symbol (output_bfd, info, h, sym) + bfd *output_bfd; + struct bfd_link_info *info; + struct elf_link_hash_entry *h; + Elf_Internal_Sym *sym; +{ + struct elf_s390_link_hash_table *htab; + + htab = elf_s390_hash_table (info); + + if (h->plt.offset != (bfd_vma) -1) + { + bfd_vma plt_index; + bfd_vma got_offset; + Elf_Internal_Rela rela; + Elf32_External_Rela *loc; + bfd_vma relative_offset; + + /* This symbol has an entry in the procedure linkage table. Set + it up. */ + + if (h->dynindx == -1 + || htab->splt == NULL + || htab->sgotplt == NULL + || htab->srelplt == NULL) + abort (); + + /* Calc. index no. + Current offset - size first entry / entry size. */ + plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE; + + /* Offset in GOT is PLT index plus GOT headers(3) times 4, + addr & GOT addr. */ + got_offset = (plt_index + 3) * GOT_ENTRY_SIZE; + + /* S390 uses halfwords for relative branch calc! */ + relative_offset = - ((PLT_FIRST_ENTRY_SIZE + + (PLT_ENTRY_SIZE * plt_index) + 18) / 2); + /* If offset is > 32768, branch to a previous branch + 390 can only handle +-64 K jumps. */ + if ( -32768 > (int) relative_offset ) + relative_offset = + -(unsigned) (((65536 / PLT_ENTRY_SIZE - 1) * PLT_ENTRY_SIZE) / 2); + + /* Fill in the entry in the procedure linkage table. */ + if (!info->shared) + { + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD0, + htab->splt->contents + h->plt.offset); + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD1, + htab->splt->contents + h->plt.offset + 4); + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD2, + htab->splt->contents + h->plt.offset + 8); + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD3, + htab->splt->contents + h->plt.offset + 12); + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD4, + htab->splt->contents + h->plt.offset + 16); + bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16), + htab->splt->contents + h->plt.offset + 20); + bfd_put_32 (output_bfd, + (htab->sgotplt->output_section->vma + + htab->sgotplt->output_offset + + got_offset), + htab->splt->contents + h->plt.offset + 24); + } + else if (got_offset < 4096) + { + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC12_ENTRY_WORD0 + got_offset, + htab->splt->contents + h->plt.offset); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC12_ENTRY_WORD1, + htab->splt->contents + h->plt.offset + 4); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC12_ENTRY_WORD2, + htab->splt->contents + h->plt.offset + 8); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC12_ENTRY_WORD3, + htab->splt->contents + h->plt.offset + 12); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC12_ENTRY_WORD4, + htab->splt->contents + h->plt.offset + 16); + bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16), + htab->splt->contents + h->plt.offset + 20); + bfd_put_32 (output_bfd, (bfd_vma) 0, + htab->splt->contents + h->plt.offset + 24); + } + else if (got_offset < 32768) + { + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC16_ENTRY_WORD0 + got_offset, + htab->splt->contents + h->plt.offset); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC16_ENTRY_WORD1, + htab->splt->contents + h->plt.offset + 4); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC16_ENTRY_WORD2, + htab->splt->contents + h->plt.offset + 8); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC16_ENTRY_WORD3, + htab->splt->contents + h->plt.offset + 12); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC16_ENTRY_WORD4, + htab->splt->contents + h->plt.offset + 16); + bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16), + htab->splt->contents + h->plt.offset + 20); + bfd_put_32 (output_bfd, (bfd_vma) 0, + htab->splt->contents + h->plt.offset + 24); + } + else + { + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD0, + htab->splt->contents + h->plt.offset); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD1, + htab->splt->contents + h->plt.offset + 4); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD2, + htab->splt->contents + h->plt.offset + 8); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD3, + htab->splt->contents + h->plt.offset + 12); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_ENTRY_WORD4, + htab->splt->contents + h->plt.offset + 16); + bfd_put_32 (output_bfd, (bfd_vma) 0+(relative_offset << 16), + htab->splt->contents + h->plt.offset + 20); + bfd_put_32 (output_bfd, got_offset, + htab->splt->contents + h->plt.offset + 24); + } + /* Insert offset into reloc. table here. */ + bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela), + htab->splt->contents + h->plt.offset + 28); + + /* Fill in the entry in the global offset table. + Points to instruction after GOT offset. */ + bfd_put_32 (output_bfd, + (htab->splt->output_section->vma + + htab->splt->output_offset + + h->plt.offset + + 12), + htab->sgotplt->contents + got_offset); + + /* Fill in the entry in the .rela.plt section. */ + rela.r_offset = (htab->sgotplt->output_section->vma + + htab->sgotplt->output_offset + + got_offset); + rela.r_info = ELF32_R_INFO (h->dynindx, R_390_JMP_SLOT); + rela.r_addend = 0; + loc = (Elf32_External_Rela *) htab->srelplt->contents + plt_index; + bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); + + if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) + { + /* Mark the symbol as undefined, rather than as defined in + the .plt section. Leave the value alone. This is a clue + for the dynamic linker, to make function pointer + comparisons work between an application and shared + library. */ + sym->st_shndx = SHN_UNDEF; + } + } + + if (h->got.offset != (bfd_vma) -1) + { + Elf_Internal_Rela rela; + Elf32_External_Rela *loc; + + /* This symbol has an entry in the global offset table. Set it + up. */ + + if (htab->sgot == NULL || htab->srelgot == NULL) + abort (); + + rela.r_offset = (htab->sgot->output_section->vma + + htab->sgot->output_offset + + (h->got.offset &~ (bfd_vma) 1)); + + /* If this is a static link, or it is a -Bsymbolic link and the + symbol is defined locally or was forced to be local because + of a version file, we just want to emit a RELATIVE reloc. + The entry in the global offset table will already have been + initialized in the relocate_section function. */ + if (info->shared + && (info->symbolic + || h->dynindx == -1 + || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)) + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) + { + BFD_ASSERT((h->got.offset & 1) != 0); + rela.r_info = ELF32_R_INFO (0, R_390_RELATIVE); + rela.r_addend = (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset); + } + else + { + BFD_ASSERT((h->got.offset & 1) == 0); + bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgot->contents + h->got.offset); + rela.r_info = ELF32_R_INFO (h->dynindx, R_390_GLOB_DAT); + rela.r_addend = 0; + } + + loc = (Elf32_External_Rela *) htab->srelgot->contents; + loc += htab->srelgot->reloc_count++; + bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); + } + + if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) + { + Elf_Internal_Rela rela; + Elf32_External_Rela *loc; + + /* This symbols needs a copy reloc. Set it up. */ + + if (h->dynindx == -1 + || (h->root.type != bfd_link_hash_defined + && h->root.type != bfd_link_hash_defweak) + || htab->srelbss == NULL) + abort (); + + rela.r_offset = (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset); + rela.r_info = ELF32_R_INFO (h->dynindx, R_390_COPY); + rela.r_addend = 0; + loc = (Elf32_External_Rela *) htab->srelbss->contents; + loc += htab->srelbss->reloc_count++; + bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); + } + + /* Mark some specially defined symbols as absolute. */ + if (strcmp (h->root.root.string, "_DYNAMIC") == 0 + || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0 + || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0) + sym->st_shndx = SHN_ABS; + + return true; +} + +/* Used to decide how to sort relocs in an optimal manner for the + dynamic linker, before writing them out. */ + +static enum elf_reloc_type_class +elf_s390_reloc_type_class (rela) + const Elf_Internal_Rela *rela; +{ + switch ((int) ELF32_R_TYPE (rela->r_info)) + { + case R_390_RELATIVE: + return reloc_class_relative; + case R_390_JMP_SLOT: + return reloc_class_plt; + case R_390_COPY: + return reloc_class_copy; + default: + return reloc_class_normal; + } +} + +/* Finish up the dynamic sections. */ + +static boolean +elf_s390_finish_dynamic_sections (output_bfd, info) + bfd *output_bfd; + struct bfd_link_info *info; +{ + struct elf_s390_link_hash_table *htab; + bfd *dynobj; + asection *sdyn; + + htab = elf_s390_hash_table (info); + dynobj = htab->elf.dynobj; + sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); + + if (htab->elf.dynamic_sections_created) + { + Elf32_External_Dyn *dyncon, *dynconend; + + if (sdyn == NULL || htab->sgot == NULL) + abort (); + + dyncon = (Elf32_External_Dyn *) sdyn->contents; + dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_size); + for (; dyncon < dynconend; dyncon++) + { + Elf_Internal_Dyn dyn; + asection *s; + + bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); + + switch (dyn.d_tag) + { + default: + continue; + + case DT_PLTGOT: + dyn.d_un.d_ptr = htab->sgot->output_section->vma; + break; + + case DT_JMPREL: + dyn.d_un.d_ptr = htab->srelplt->output_section->vma; + break; + + case DT_PLTRELSZ: + s = htab->srelplt->output_section; + if (s->_cooked_size != 0) + dyn.d_un.d_val = s->_cooked_size; + else + dyn.d_un.d_val = s->_raw_size; + break; + } + + bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); + } + + /* Fill in the special first entry in the procedure linkage table. */ + if (htab->splt && htab->splt->_raw_size > 0) + { + memset (htab->splt->contents, 0, PLT_FIRST_ENTRY_SIZE); + if (info->shared) + { + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD0, + htab->splt->contents ); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD1, + htab->splt->contents +4 ); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD2, + htab->splt->contents +8 ); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD3, + htab->splt->contents +12 ); + bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD4, + htab->splt->contents +16 ); + } + else + { + bfd_put_32 (output_bfd, (bfd_vma)PLT_FIRST_ENTRY_WORD0, + htab->splt->contents ); + bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD1, + htab->splt->contents +4 ); + bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD2, + htab->splt->contents +8 ); + bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD3, + htab->splt->contents +12 ); + bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD4, + htab->splt->contents +16 ); + bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD5, + htab->splt->contents +20 ); + bfd_put_32 (output_bfd, + htab->sgotplt->output_section->vma + + htab->sgotplt->output_offset, + htab->splt->contents + 24); + } + elf_section_data (htab->splt->output_section) + ->this_hdr.sh_entsize = 4; + } + + } + + if (htab->sgotplt) + { + /* Fill in the first three entries in the global offset table. */ + if (htab->sgotplt->_raw_size > 0) + { + bfd_put_32 (output_bfd, + (sdyn == NULL ? (bfd_vma) 0 + : sdyn->output_section->vma + sdyn->output_offset), + htab->sgotplt->contents); + /* One entry for shared object struct ptr. */ + bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 4); + /* One entry for _dl_runtime_resolve. */ + bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 8); + } + + elf_section_data (htab->sgotplt->output_section) + ->this_hdr.sh_entsize = 4; + } + return true; +} + +static boolean +elf_s390_object_p (abfd) + bfd *abfd; +{ + return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_31); +} + +static boolean +elf_s390_grok_prstatus (abfd, note) + bfd * abfd; + Elf_Internal_Note * note; +{ + int offset; + unsigned int raw_size; + + switch (note->descsz) + { + default: + return false; + + case 224: /* S/390 Linux. */ + /* pr_cursig */ + elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12); + + /* pr_pid */ + elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24); + + /* pr_reg */ + offset = 72; + raw_size = 144; + break; + } + + /* Make a ".reg/999" section. */ + return _bfd_elfcore_make_pseudosection (abfd, ".reg", + raw_size, note->descpos + offset); +} + +#define TARGET_BIG_SYM bfd_elf32_s390_vec +#define TARGET_BIG_NAME "elf32-s390" +#define ELF_ARCH bfd_arch_s390 +#define ELF_MACHINE_CODE EM_S390 +#define ELF_MACHINE_ALT1 EM_S390_OLD +#define ELF_MAXPAGESIZE 0x1000 + +#define elf_backend_can_gc_sections 1 +#define elf_backend_can_refcount 1 +#define elf_backend_want_got_plt 1 +#define elf_backend_plt_readonly 1 +#define elf_backend_want_plt_sym 0 +#define elf_backend_got_header_size 12 +#define elf_backend_plt_header_size PLT_ENTRY_SIZE +#define elf_backend_rela_normal 1 + +#define elf_info_to_howto elf_s390_info_to_howto + +#define bfd_elf32_bfd_is_local_label_name elf_s390_is_local_label_name +#define bfd_elf32_bfd_link_hash_table_create elf_s390_link_hash_table_create +#define bfd_elf32_bfd_reloc_type_lookup elf_s390_reloc_type_lookup + +#define elf_backend_adjust_dynamic_symbol elf_s390_adjust_dynamic_symbol +#define elf_backend_check_relocs elf_s390_check_relocs +#define elf_backend_copy_indirect_symbol elf_s390_copy_indirect_symbol +#define elf_backend_create_dynamic_sections elf_s390_create_dynamic_sections +#define elf_backend_finish_dynamic_sections elf_s390_finish_dynamic_sections +#define elf_backend_finish_dynamic_symbol elf_s390_finish_dynamic_symbol +#define elf_backend_gc_mark_hook elf_s390_gc_mark_hook +#define elf_backend_gc_sweep_hook elf_s390_gc_sweep_hook +#define elf_backend_reloc_type_class elf_s390_reloc_type_class +#define elf_backend_relocate_section elf_s390_relocate_section +#define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections +#define elf_backend_reloc_type_class elf_s390_reloc_type_class +#define elf_backend_grok_prstatus elf_s390_grok_prstatus + +#define elf_backend_object_p elf_s390_object_p + +#include "elf32-target.h" diff --git a/contrib/binutils/bfd/elf64-alpha.c b/contrib/binutils/bfd/elf64-alpha.c index 550de53..faf9944 100644 --- a/contrib/binutils/bfd/elf64-alpha.c +++ b/contrib/binutils/bfd/elf64-alpha.c @@ -3695,6 +3695,16 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section, } goto default_reloc; + case R_ALPHA_SREL32: + case R_ALPHA_SREL64: + /* ??? .eh_frame references to discarded sections will be smashed + to relocations against SHN_UNDEF. The .eh_frame format allows + NULL to be encoded as 0 in any format, so this works here. */ + if (r_symndx == 0) + howto = (elf64_alpha_howto_table + + (r_type - R_ALPHA_SREL32 + R_ALPHA_REFLONG)); + goto default_reloc; + default: default_reloc: r = _bfd_final_link_relocate (howto, input_bfd, input_section, diff --git a/contrib/binutils/bfd/elf64-ppc.c b/contrib/binutils/bfd/elf64-ppc.c index 6adc202..d25c25f 100644 --- a/contrib/binutils/bfd/elf64-ppc.c +++ b/contrib/binutils/bfd/elf64-ppc.c @@ -39,7 +39,21 @@ static reloc_howto_type *ppc64_elf_reloc_type_lookup PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); static void ppc64_elf_info_to_howto PARAMS ((bfd *abfd, arelent *cache_ptr, Elf64_Internal_Rela *dst)); -static bfd_reloc_status_type ppc64_elf_addr16_ha_reloc +static bfd_reloc_status_type ppc64_elf_ha_reloc + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static bfd_reloc_status_type ppc64_elf_brtaken_reloc + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static bfd_reloc_status_type ppc64_elf_sectoff_reloc + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static bfd_reloc_status_type ppc64_elf_sectoff_ha_reloc + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static bfd_reloc_status_type ppc64_elf_toc_reloc + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static bfd_reloc_status_type ppc64_elf_toc_ha_reloc + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static bfd_reloc_status_type ppc64_elf_toc64_reloc + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static bfd_reloc_status_type ppc64_elf_unhandled_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); static boolean ppc64_elf_set_private_flags PARAMS ((bfd *, flagword)); @@ -101,12 +115,6 @@ static boolean ppc64_elf_finish_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); -/* Mask to set RA in memory instructions. */ -#define RA_REGISTER_MASK 0x001f0000 - -/* Value to shift register by to insert RA. */ -#define RA_REGISTER_SHIFT 16 - /* The name of the dynamic interpreter. This is put in the .interp section. */ #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" @@ -146,6 +154,10 @@ static boolean ppc64_elf_finish_dynamic_sections /* Pad with this. */ #define NOP 0x60000000 +/* Some other nops. */ +#define CROR_151515 0x4def7b82 +#define CROR_313131 0x4ffffb82 + /* .glink entries for the first 32k functions are two instructions. */ #define LI_R0_0 0x38000000 /* li %r0,0 */ #define B_DOT 0x48000000 /* b . */ @@ -273,7 +285,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - ppc64_elf_addr16_ha_reloc, /* special_function */ + ppc64_elf_ha_reloc, /* special_function */ "R_PPC64_ADDR16_HA", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -306,7 +318,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_brtaken_reloc, /* special_function */ "R_PPC64_ADDR14_BRTAKEN",/* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -323,7 +335,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_brtaken_reloc, /* special_function */ "R_PPC64_ADDR14_BRNTAKEN",/* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -370,7 +382,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { true, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_brtaken_reloc, /* special_function */ "R_PPC64_REL14_BRTAKEN", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -387,7 +399,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { true, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_brtaken_reloc, /* special_function */ "R_PPC64_REL14_BRNTAKEN",/* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -403,7 +415,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_GOT16", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -419,7 +431,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_GOT16_LO", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -435,7 +447,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_GOT16_HI", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -451,7 +463,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ - ppc64_elf_addr16_ha_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_GOT16_HA", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -470,7 +482,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_COPY", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -486,7 +498,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_GLOB_DAT", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -502,7 +514,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_JMP_SLOT", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -580,7 +592,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_PLT32", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -612,7 +624,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_PLT16_LO", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -628,7 +640,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_PLT16_HI", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -644,31 +656,29 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - ppc64_elf_addr16_ha_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_PLT16_HA", /* name */ false, /* partial_inplace */ 0, /* src_mask */ 0xffff, /* dst_mask */ false), /* pcrel_offset */ - /* 32-bit section relative relocation. */ - /* FIXME: Verify R_PPC64_SECTOFF. Seems strange with size=2 and - dst_mask=0. */ + /* 16-bit section relative relocation. */ HOWTO (R_PPC64_SECTOFF, /* type */ 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_sectoff_reloc, /* special_function */ "R_PPC64_SECTOFF", /* name */ false, /* partial_inplace */ 0, /* src_mask */ - 0, /* dst_mask */ - true), /* pcrel_offset */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ - /* 16-bit lower half section relative relocation. */ + /* Like R_PPC64_SECTOFF, but no overflow warning. */ HOWTO (R_PPC64_SECTOFF_LO, /* type */ 0, /* rightshift */ 1, /* size (0 = byte, 1 = short, 2 = long) */ @@ -676,7 +686,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_sectoff_reloc, /* special_function */ "R_PPC64_SECTOFF_LO", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -691,7 +701,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_sectoff_reloc, /* special_function */ "R_PPC64_SECTOFF_HI", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -706,7 +716,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - ppc64_elf_addr16_ha_reloc, /* special_function */ + ppc64_elf_sectoff_ha_reloc, /* special_function */ "R_PPC64_SECTOFF_HA", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -714,8 +724,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false), /* pcrel_offset */ /* Like R_PPC64_REL24 without touching the two least significant - bits. */ - /* FIXME: Verify R_PPC64_ADDR30. */ + bits. Should have been named R_PPC64_REL30! */ HOWTO (R_PPC64_ADDR30, /* type */ 2, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -771,7 +780,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - ppc64_elf_addr16_ha_reloc, /* special_function */ + ppc64_elf_ha_reloc, /* special_function */ "R_PPC64_ADDR16_HIGHERA", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -802,7 +811,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - ppc64_elf_addr16_ha_reloc, /* special_function */ + ppc64_elf_ha_reloc, /* special_function */ "R_PPC64_ADDR16_HIGHESTA", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -847,7 +856,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_PLT64", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -864,7 +873,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { true, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_PLTREL64", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -881,7 +890,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_toc_reloc, /* special_function */ "R_PPC64_TOC16", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -898,7 +907,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_toc_reloc, /* special_function */ "R_PPC64_TOC16_LO", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -915,7 +924,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_toc_reloc, /* special_function */ "R_PPC64_TOC16_HI", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -934,7 +943,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - ppc64_elf_addr16_ha_reloc, /* special_function */ + ppc64_elf_toc_ha_reloc, /* special_function */ "R_PPC64_TOC16_HA", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -951,7 +960,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_toc64_reloc, /* special_function */ "R_PPC64_TOC", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -974,7 +983,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_PLTGOT16", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -990,7 +999,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_PLTGOT16_LO", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -1006,7 +1015,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_PLTGOT16_HI", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -1024,7 +1033,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont,/* complain_on_overflow */ - ppc64_elf_addr16_ha_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_PLTGOT16_HA", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -1069,7 +1078,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_GOT16_DS", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -1084,7 +1093,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_GOT16_LO_DS", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -1099,7 +1108,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_PLT16_LO_DS", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -1107,21 +1116,19 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false), /* pcrel_offset */ /* Like R_PPC64_SECTOFF, but for instructions with a DS field. */ - /* FIXME: Verify R_PPC64_SECTOFF. Seems strange with size=2 and - dst_mask=0. */ HOWTO (R_PPC64_SECTOFF_DS, /* type */ 0, /* rightshift */ - 2, /* size (0 = byte, 1 = short, 2 = long) */ - 32, /* bitsize */ - true, /* pc_relative */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ 0, /* bitpos */ complain_overflow_bitfield, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_sectoff_reloc, /* special_function */ "R_PPC64_SECTOFF_DS", /* name */ false, /* partial_inplace */ 0, /* src_mask */ - 0, /* dst_mask */ - true), /* pcrel_offset */ + 0xfffc, /* dst_mask */ + false), /* pcrel_offset */ /* Like R_PPC64_SECTOFF_LO, but for instructions with a DS field. */ HOWTO (R_PPC64_SECTOFF_LO_DS, /* type */ @@ -1131,7 +1138,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_sectoff_reloc, /* special_function */ "R_PPC64_SECTOFF_LO_DS",/* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -1146,7 +1153,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_toc_reloc, /* special_function */ "R_PPC64_TOC16_DS", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -1161,7 +1168,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_toc_reloc, /* special_function */ "R_PPC64_TOC16_LO_DS", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -1177,7 +1184,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_signed, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_PLTGOT16_DS", /* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -1193,7 +1200,7 @@ static reloc_howto_type ppc64_elf_howto_raw[] = { false, /* pc_relative */ 0, /* bitpos */ complain_overflow_dont, /* complain_on_overflow */ - bfd_elf_generic_reloc, /* special_function */ + ppc64_elf_unhandled_reloc, /* special_function */ "R_PPC64_PLTGOT16_LO_DS",/* name */ false, /* partial_inplace */ 0, /* src_mask */ @@ -1319,7 +1326,7 @@ ppc64_elf_reloc_type_lookup (abfd, code) break; case BFD_RELOC_HI16_S_PLTOFF: ppc_reloc = R_PPC64_PLT16_HA; break; - case BFD_RELOC_32_BASEREL: ppc_reloc = R_PPC64_SECTOFF; + case BFD_RELOC_16_BASEREL: ppc_reloc = R_PPC64_SECTOFF; break; case BFD_RELOC_LO16_BASEREL: ppc_reloc = R_PPC64_SECTOFF_LO; break; @@ -1417,41 +1424,265 @@ ppc64_elf_info_to_howto (abfd, cache_ptr, dst) /* Handle the R_PPC_ADDR16_HA and similar relocs. */ static bfd_reloc_status_type -ppc64_elf_addr16_ha_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd ATTRIBUTE_UNUSED; +ppc64_elf_ha_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message) + bfd *abfd; + arelent *reloc_entry; + asymbol *symbol; + PTR data; + asection *input_section; + bfd *output_bfd; + char **error_message; +{ + /* If this is a relocatable link (output_bfd test tells us), just + call the generic function. Any adjustment will be done at final + link time. */ + if (output_bfd != NULL) + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); + + /* Adjust the addend for sign extension of the low 16 bits. + We won't actually be using the low 16 bits, so trashing them + doesn't matter. */ + reloc_entry->addend += 0x8000; + return bfd_reloc_continue; +} + +static bfd_reloc_status_type +ppc64_elf_brtaken_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message) + bfd *abfd; arelent *reloc_entry; asymbol *symbol; - PTR data ATTRIBUTE_UNUSED; + PTR data; asection *input_section; bfd *output_bfd; - char **error_message ATTRIBUTE_UNUSED; + char **error_message; { - bfd_vma relocation; + long insn; + enum elf_ppc_reloc_type r_type; + bfd_size_type octets; + /* Disabled until we sort out how ld should choose 'y' vs 'at'. */ + boolean is_power4 = false; + /* If this is a relocatable link (output_bfd test tells us), just + call the generic function. Any adjustment will be done at final + link time. */ if (output_bfd != NULL) + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); + + octets = reloc_entry->address * bfd_octets_per_byte (abfd); + insn = bfd_get_32 (abfd, (bfd_byte *) data + octets); + insn &= ~(0x01 << 21); + r_type = (enum elf_ppc_reloc_type) reloc_entry->howto->type; + if (r_type == R_PPC64_ADDR14_BRTAKEN + || r_type == R_PPC64_REL14_BRTAKEN) + insn |= 0x01 << 21; /* 'y' or 't' bit, lowest bit of BO field. */ + + if (is_power4) + { + /* Set 'a' bit. This is 0b00010 in BO field for branch + on CR(BI) insns (BO == 001at or 011at), and 0b01000 + for branch on CTR insns (BO == 1a00t or 1a01t). */ + if ((insn & (0x14 << 21)) == (0x04 << 21)) + insn |= 0x02 << 21; + else if ((insn & (0x14 << 21)) == (0x10 << 21)) + insn |= 0x08 << 21; + else + return bfd_reloc_continue; + } + else { - reloc_entry->address += input_section->output_offset; - return bfd_reloc_ok; + bfd_vma target = 0; + bfd_vma from; + + if (!bfd_is_com_section (symbol->section)) + target = symbol->value; + target += symbol->section->output_section->vma; + target += symbol->section->output_offset; + target += reloc_entry->addend; + + from = (reloc_entry->address + + input_section->output_offset + + input_section->output_section->vma); + + /* Invert 'y' bit if not the default. */ + if ((bfd_signed_vma) (target - from) < 0) + insn ^= 0x01 << 21; } + bfd_put_32 (abfd, (bfd_vma) insn, (bfd_byte *) data + octets); + return bfd_reloc_continue; +} + +static bfd_reloc_status_type +ppc64_elf_sectoff_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message) + bfd *abfd; + arelent *reloc_entry; + asymbol *symbol; + PTR data; + asection *input_section; + bfd *output_bfd; + char **error_message; +{ + /* If this is a relocatable link (output_bfd test tells us), just + call the generic function. Any adjustment will be done at final + link time. */ + if (output_bfd != NULL) + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); - if (reloc_entry->address > input_section->_cooked_size) - return bfd_reloc_outofrange; + /* Subtract the symbol section base address. */ + reloc_entry->addend -= symbol->section->output_section->vma; + return bfd_reloc_continue; +} - if (bfd_is_com_section (symbol->section)) - relocation = 0; - else - relocation = symbol->value; +static bfd_reloc_status_type +ppc64_elf_sectoff_ha_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message) + bfd *abfd; + arelent *reloc_entry; + asymbol *symbol; + PTR data; + asection *input_section; + bfd *output_bfd; + char **error_message; +{ + /* If this is a relocatable link (output_bfd test tells us), just + call the generic function. Any adjustment will be done at final + link time. */ + if (output_bfd != NULL) + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); + + /* Subtract the symbol section base address. */ + reloc_entry->addend -= symbol->section->output_section->vma; + + /* Adjust the addend for sign extension of the low 16 bits. */ + reloc_entry->addend += 0x8000; + return bfd_reloc_continue; +} + +static bfd_reloc_status_type +ppc64_elf_toc_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message) + bfd *abfd; + arelent *reloc_entry; + asymbol *symbol; + PTR data; + asection *input_section; + bfd *output_bfd; + char **error_message; +{ + bfd_vma TOCstart; + + /* If this is a relocatable link (output_bfd test tells us), just + call the generic function. Any adjustment will be done at final + link time. */ + if (output_bfd != NULL) + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); + + TOCstart = _bfd_get_gp_value (input_section->output_section->owner); + if (TOCstart == 0) + TOCstart = ppc64_elf_toc (input_section->output_section->owner); - relocation += symbol->section->output_section->vma; - relocation += symbol->section->output_offset; - relocation += reloc_entry->addend; + /* Subtract the TOC base address. */ + reloc_entry->addend -= TOCstart + TOC_BASE_OFF; + return bfd_reloc_continue; +} + +static bfd_reloc_status_type +ppc64_elf_toc_ha_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message) + bfd *abfd; + arelent *reloc_entry; + asymbol *symbol; + PTR data; + asection *input_section; + bfd *output_bfd; + char **error_message; +{ + bfd_vma TOCstart; + + /* If this is a relocatable link (output_bfd test tells us), just + call the generic function. Any adjustment will be done at final + link time. */ + if (output_bfd != NULL) + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); + + TOCstart = _bfd_get_gp_value (input_section->output_section->owner); + if (TOCstart == 0) + TOCstart = ppc64_elf_toc (input_section->output_section->owner); - reloc_entry->addend += (relocation & 0x8000) << 1; + /* Subtract the TOC base address. */ + reloc_entry->addend -= TOCstart + TOC_BASE_OFF; + /* Adjust the addend for sign extension of the low 16 bits. */ + reloc_entry->addend += 0x8000; return bfd_reloc_continue; } +static bfd_reloc_status_type +ppc64_elf_toc64_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message) + bfd *abfd; + arelent *reloc_entry; + asymbol *symbol; + PTR data; + asection *input_section; + bfd *output_bfd; + char **error_message; +{ + bfd_vma TOCstart; + bfd_size_type octets; + + /* If this is a relocatable link (output_bfd test tells us), just + call the generic function. Any adjustment will be done at final + link time. */ + if (output_bfd != NULL) + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); + + TOCstart = _bfd_get_gp_value (input_section->output_section->owner); + if (TOCstart == 0) + TOCstart = ppc64_elf_toc (input_section->output_section->owner); + + octets = reloc_entry->address * bfd_octets_per_byte (abfd); + bfd_put_64 (abfd, TOCstart + TOC_BASE_OFF, (bfd_byte *) data + octets); + return bfd_reloc_ok; +} + +static bfd_reloc_status_type +ppc64_elf_unhandled_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message) + bfd *abfd; + arelent *reloc_entry; + asymbol *symbol; + PTR data; + asection *input_section; + bfd *output_bfd; + char **error_message; +{ + /* If this is a relocatable link (output_bfd test tells us), just + call the generic function. Any adjustment will be done at final + link time. */ + if (output_bfd != NULL) + return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data, + input_section, output_bfd, error_message); + + if (error_message != NULL) + { + static char buf[60]; + sprintf (buf, "generic linker can't handle %s", + reloc_entry->howto->name); + *error_message = buf; + } + return bfd_reloc_dangerous; +} + /* Function to set whether a module needs the -mrelocatable bit set. */ static boolean @@ -1731,6 +1962,9 @@ struct ppc_link_hash_table /* Set on error. */ int plt_overflow; + /* Set if we detect a reference undefined weak symbol. */ + unsigned int have_undefweak; + /* Small local sym to section mapping cache. */ struct sym_sec_cache sym_sec; }; @@ -1800,6 +2034,7 @@ ppc64_elf_link_hash_table_create (abfd) htab->sglink = NULL; htab->sfpr = NULL; htab->plt_overflow = 0; + htab->have_undefweak = 0; htab->sym_sec.abfd = NULL; return &htab->elf.root; @@ -2515,6 +2750,10 @@ func_desc_adjust (h, inf) if (!((struct ppc_link_hash_entry *) h)->is_func) return true; + if (h->root.type == bfd_link_hash_undefweak + && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR)) + htab->have_undefweak = true; + if (h->plt.refcount > 0 && h->root.root.string[0] == '.' && h->root.root.string[1] != '\0') @@ -2610,6 +2849,7 @@ ppc64_elf_func_desc_adjust (obfd, info) unsigned int lowest_restf = MAX_SAVE_FPR + 2; unsigned int i; struct elf_link_hash_entry *h; + bfd_byte *p; char sym[10]; htab = ppc_hash_table (info); @@ -2660,41 +2900,52 @@ ppc64_elf_func_desc_adjust (obfd, info) } } + elf_link_hash_traverse (&htab->elf, func_desc_adjust, (PTR) info); + htab->sfpr->_raw_size = ((MAX_SAVE_FPR + 2 - lowest_savef) * 4 + (MAX_SAVE_FPR + 2 - lowest_restf) * 4); if (htab->sfpr->_raw_size == 0) { - _bfd_strip_section_from_output (info, htab->sfpr); - } - else - { - bfd_byte *p = (bfd_byte *) bfd_alloc (htab->elf.dynobj, - htab->sfpr->_raw_size); - if (p == NULL) - return false; - htab->sfpr->contents = p; - - for (i = lowest_savef; i <= MAX_SAVE_FPR; i++) + if (!htab->have_undefweak) { - unsigned int fpr = i << 21; - unsigned int stackoff = (1 << 16) - (MAX_SAVE_FPR + 1 - i) * 8; - bfd_put_32 (htab->elf.dynobj, STFD_FR0_0R1 + fpr + stackoff, p); - p += 4; + _bfd_strip_section_from_output (info, htab->sfpr); + return true; } + + htab->sfpr->_raw_size = 4; + } + + p = (bfd_byte *) bfd_alloc (htab->elf.dynobj, htab->sfpr->_raw_size); + if (p == NULL) + return false; + htab->sfpr->contents = p; + + for (i = lowest_savef; i <= MAX_SAVE_FPR; i++) + { + unsigned int fpr = i << 21; + unsigned int stackoff = (1 << 16) - (MAX_SAVE_FPR + 1 - i) * 8; + bfd_put_32 (htab->elf.dynobj, STFD_FR0_0R1 + fpr + stackoff, p); + p += 4; + } + if (lowest_savef <= MAX_SAVE_FPR) + { bfd_put_32 (htab->elf.dynobj, BLR, p); p += 4; + } - for (i = lowest_restf; i <= MAX_SAVE_FPR; i++) - { - unsigned int fpr = i << 21; - unsigned int stackoff = (1 << 16) - (MAX_SAVE_FPR + 1 - i) * 8; - bfd_put_32 (htab->elf.dynobj, LFD_FR0_0R1 + fpr + stackoff, p); - p += 4; - } - bfd_put_32 (htab->elf.dynobj, BLR, p); + for (i = lowest_restf; i <= MAX_SAVE_FPR; i++) + { + unsigned int fpr = i << 21; + unsigned int stackoff = (1 << 16) - (MAX_SAVE_FPR + 1 - i) * 8; + bfd_put_32 (htab->elf.dynobj, LFD_FR0_0R1 + fpr + stackoff, p); p += 4; } + if (lowest_restf <= MAX_SAVE_FPR + || htab->sfpr->_raw_size == 4) + { + bfd_put_32 (htab->elf.dynobj, BLR, p); + } elf_link_hash_traverse (&htab->elf, func_desc_adjust, (PTR) info); return true; @@ -3285,69 +3536,61 @@ ppc64_elf_size_dynamic_sections (output_bfd, info) return true; } -/* Called after we have seen all the input files/sections, but before - final symbol resolution and section placement has been determined. +/* Called after we have determined section placement. If sections + move, we'll be called again. Provide a value for TOCstart. */ - We use this hook to provide a value for TOCstart, which we store in - the output bfd elf_gp. */ - -boolean -ppc64_elf_set_toc (obfd, info) +bfd_vma +ppc64_elf_toc (obfd) bfd *obfd; - struct bfd_link_info *info; { - if (!info->relocateable) - { - asection *s; - bfd_vma TOCstart; + asection *s; + bfd_vma TOCstart; - /* The TOC consists of sections .got, .toc, .tocbss, .plt in that - order. The TOC starts where the first of these sections starts. */ - s = bfd_get_section_by_name (obfd, ".got"); - if (s == NULL) - s = bfd_get_section_by_name (obfd, ".toc"); + /* The TOC consists of sections .got, .toc, .tocbss, .plt in that + order. The TOC starts where the first of these sections starts. */ + s = bfd_get_section_by_name (obfd, ".got"); + if (s == NULL) + s = bfd_get_section_by_name (obfd, ".toc"); + if (s == NULL) + s = bfd_get_section_by_name (obfd, ".tocbss"); + if (s == NULL) + s = bfd_get_section_by_name (obfd, ".plt"); + if (s == NULL) + { + /* This may happen for + o references to TOC base (SYM@toc / TOC[tc0]) without a + .toc directive + o bad linker script + o --gc-sections and empty TOC sections + + FIXME: Warn user? */ + + /* Look for a likely section. We probably won't even be + using TOCstart. */ + for (s = obfd->sections; s != NULL; s = s->next) + if ((s->flags & (SEC_ALLOC | SEC_SMALL_DATA | SEC_READONLY)) + == (SEC_ALLOC | SEC_SMALL_DATA)) + break; if (s == NULL) - s = bfd_get_section_by_name (obfd, ".tocbss"); + for (s = obfd->sections; s != NULL; s = s->next) + if ((s->flags & (SEC_ALLOC | SEC_SMALL_DATA)) + == (SEC_ALLOC | SEC_SMALL_DATA)) + break; if (s == NULL) - s = bfd_get_section_by_name (obfd, ".plt"); + for (s = obfd->sections; s != NULL; s = s->next) + if ((s->flags & (SEC_ALLOC | SEC_READONLY)) == SEC_ALLOC) + break; if (s == NULL) - { - /* This may happen for - o references to TOC base (SYM@toc / TOC[tc0]) without a - .toc directive - o bad linker script - o --gc-sections and empty TOC sections - - FIXME: Warn user? */ - - /* Look for a likely section. We probably won't even be - using TOCstart. */ - for (s = obfd->sections; s != NULL; s = s->next) - if ((s->flags & (SEC_ALLOC | SEC_SMALL_DATA | SEC_READONLY)) - == (SEC_ALLOC | SEC_SMALL_DATA)) - break; - if (s == NULL) - for (s = obfd->sections; s != NULL; s = s->next) - if ((s->flags & (SEC_ALLOC | SEC_SMALL_DATA)) - == (SEC_ALLOC | SEC_SMALL_DATA)) - break; - if (s == NULL) - for (s = obfd->sections; s != NULL; s = s->next) - if ((s->flags & (SEC_ALLOC | SEC_READONLY)) == SEC_ALLOC) - break; - if (s == NULL) - for (s = obfd->sections; s != NULL; s = s->next) - if ((s->flags & SEC_ALLOC) == SEC_ALLOC) - break; - } + for (s = obfd->sections; s != NULL; s = s->next) + if ((s->flags & SEC_ALLOC) == SEC_ALLOC) + break; + } - TOCstart = 0; - if (s != NULL) - TOCstart = s->output_section->vma + s->output_offset; + TOCstart = 0; + if (s != NULL) + TOCstart = s->output_section->vma + s->output_offset; - elf_gp (obfd) = TOCstart; - } - return true; + return TOCstart; } /* PowerPC64 .plt entries are 24 bytes long, which doesn't divide @@ -3642,6 +3885,9 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, /* Disabled until we sort out how ld should choose 'y' vs 'at'. */ boolean is_power4 = false; + if (info->relocateable) + return true; + /* Initialize howto table if needed. */ if (!ppc64_elf_howto_table[R_PPC64_ADDR32]) ppc_howto_init (); @@ -3668,32 +3914,11 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, unsigned long r_symndx; bfd_vma relocation; boolean unresolved_reloc; - boolean has_nop; long insn; + bfd_vma from; r_type = (enum elf_ppc_reloc_type) ELF64_R_TYPE (rel->r_info); r_symndx = ELF64_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocatable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if ((unsigned) ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections[r_symndx]; - rel->r_addend += sec->output_offset + sym->st_value; - } - } - continue; - } - - /* This is a final link. */ - offset = rel->r_offset; addend = rel->r_addend; r = bfd_reloc_other; @@ -3716,6 +3941,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, sym_name = "<local symbol>"; relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); + /* rel may have changed, update our copy of addend. */ addend = rel->r_addend; } else @@ -3791,8 +4017,12 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, } else { + from = (offset + + input_section->output_offset + + input_section->output_section->vma); + /* Invert 'y' bit if not the default. */ - if ((bfd_signed_vma) (relocation - offset) < 0) + if ((bfd_signed_vma) (relocation + addend - from) < 0) insn ^= 0x01 << 21; } @@ -3800,57 +4030,71 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, break; case R_PPC64_REL24: - case R_PPC64_ADDR24: - /* An ADDR24 or REL24 branching to a linkage function may be - followed by a nop that we have to replace with a ld in - order to restore the TOC base pointer. Only calls to - shared objects need to alter the TOC base. These are - recognized by their need for a PLT entry. */ - has_nop = 0; + /* A REL24 branching to a linkage function is followed by a + nop. We replace the nop with a ld in order to restore + the TOC base pointer. Only calls to shared objects need + to alter the TOC base. These are recognized by their + need for a PLT entry. */ if (h != NULL && h->plt.offset != (bfd_vma) -1 && htab->sstub != NULL) { - /* plt.offset here is the offset into the stub section. */ - relocation = (htab->sstub->output_section->vma - + htab->sstub->output_offset - + h->plt.offset); - unresolved_reloc = false; - - /* Make sure that there really is an instruction after - the branch that we can decode. */ + boolean can_plt_call = 0; + if (offset + 8 <= input_section->_cooked_size) { - bfd_byte *pnext; - - pnext = contents + offset + 4; - insn = bfd_get_32 (input_bfd, pnext); - - if (insn == 0x60000000 /* nop (ori r0,r0,0) */ - || insn == 0x4def7b82 /* cror 15,15,15 */ - || insn == 0x4ffffb82) /* cror 31,31,31 */ + insn = bfd_get_32 (input_bfd, contents + offset + 4); + if (insn == NOP + || insn == CROR_151515 || insn == CROR_313131) { - bfd_put_32 (input_bfd, - (bfd_vma) 0xe8410028, /* ld r2,40(r1) */ - pnext); - has_nop = 1; + bfd_put_32 (input_bfd, (bfd_vma) LD_R2_40R1, + contents + offset + 4); + can_plt_call = 1; } } + + if (!can_plt_call) + { + /* If this is a plain branch rather than a branch + and link, don't require a nop. */ + insn = bfd_get_32 (input_bfd, contents + offset); + if ((insn & 1) == 0) + can_plt_call = 1; + } + + if (can_plt_call) + { + /* plt.offset here is the offset into the stub section. */ + relocation = (htab->sstub->output_section->vma + + htab->sstub->output_offset + + h->plt.offset); + addend = 0; + unresolved_reloc = false; + } } if (h != NULL && h->root.type == bfd_link_hash_undefweak - && r_type == R_PPC64_REL24 - && addend == 0 - && relocation == 0) + && relocation == 0 + && addend == 0) { - /* Tweak calls to undefined weak functions to behave as - if the "called" function immediately returns. We can - thus call to a weak function without first checking - whether the function is defined. */ - relocation = 4; - if (has_nop) - relocation = 8; + /* Tweak calls to undefined weak functions to point at a + blr. We can thus call a weak function without first + checking whether the function is defined. We have a + blr at the end of .sfpr. */ + BFD_ASSERT (htab->sfpr->_raw_size != 0); + relocation = (htab->sfpr->_raw_size - 4 + + htab->sfpr->output_offset + + htab->sfpr->output_section->vma); + from = (offset + + input_section->output_offset + + input_section->output_section->vma); + + /* But let's not be silly about it. If the blr isn't in + reach, just go to the next instruction. */ + if (relocation - from + (1 << 25) >= (1 << 26) + || htab->sfpr->_raw_size == 0) + relocation = from + 4; } break; } @@ -4593,6 +4837,7 @@ ppc64_elf_finish_dynamic_sections (output_bfd, info) #define elf_backend_plt_header_size PLT_INITIAL_ENTRY_SIZE #define elf_backend_can_gc_sections 1 #define elf_backend_can_refcount 1 +#define elf_backend_rela_normal 1 #define bfd_elf64_bfd_reloc_type_lookup ppc64_elf_reloc_type_lookup #define bfd_elf64_bfd_set_private_flags ppc64_elf_set_private_flags diff --git a/contrib/binutils/bfd/elf64-ppc.h b/contrib/binutils/bfd/elf64-ppc.h index b261a58..beb637b 100644 --- a/contrib/binutils/bfd/elf64-ppc.h +++ b/contrib/binutils/bfd/elf64-ppc.h @@ -17,6 +17,6 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -boolean ppc64_elf_set_toc PARAMS ((bfd *, struct bfd_link_info *)); +bfd_vma ppc64_elf_toc PARAMS ((bfd *)); boolean ppc64_elf_size_stubs PARAMS ((bfd *, struct bfd_link_info *, int *)); boolean ppc64_elf_build_stubs PARAMS ((bfd *, struct bfd_link_info *)); diff --git a/contrib/binutils/bfd/elf64-s390.c b/contrib/binutils/bfd/elf64-s390.c new file mode 100644 index 0000000..40f4908 --- /dev/null +++ b/contrib/binutils/bfd/elf64-s390.c @@ -0,0 +1,2392 @@ +/* IBM S/390-specific support for 64-bit ELF + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed Martin Schwidefsky (schwidefsky@de.ibm.com). + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "libbfd.h" +#include "elf-bfd.h" + +static reloc_howto_type *elf_s390_reloc_type_lookup + PARAMS ((bfd *, bfd_reloc_code_real_type)); +static void elf_s390_info_to_howto + PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); +static boolean elf_s390_is_local_label_name + PARAMS ((bfd *, const char *)); +static struct bfd_hash_entry *link_hash_newfunc + PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); +static struct bfd_link_hash_table *elf_s390_link_hash_table_create + PARAMS ((bfd *)); +static boolean create_got_section + PARAMS((bfd *, struct bfd_link_info *)); +static boolean elf_s390_create_dynamic_sections + PARAMS((bfd *, struct bfd_link_info *)); +static void elf_s390_copy_indirect_symbol + PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *)); +static boolean elf_s390_check_relocs + PARAMS ((bfd *, struct bfd_link_info *, asection *, + const Elf_Internal_Rela *)); +static asection *elf_s390_gc_mark_hook + PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + struct elf_link_hash_entry *, Elf_Internal_Sym *)); +static boolean elf_s390_gc_sweep_hook + PARAMS ((bfd *, struct bfd_link_info *, asection *, + const Elf_Internal_Rela *)); +static boolean elf_s390_adjust_dynamic_symbol + PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); +static boolean allocate_dynrelocs + PARAMS ((struct elf_link_hash_entry *, PTR)); +static boolean readonly_dynrelocs + PARAMS ((struct elf_link_hash_entry *, PTR)); +static boolean elf_s390_size_dynamic_sections + PARAMS ((bfd *, struct bfd_link_info *)); +static boolean elf_s390_relocate_section + PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, + Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); +static boolean elf_s390_finish_dynamic_symbol + PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, + Elf_Internal_Sym *)); +static enum elf_reloc_type_class elf_s390_reloc_type_class + PARAMS ((const Elf_Internal_Rela *)); +static boolean elf_s390_finish_dynamic_sections + PARAMS ((bfd *, struct bfd_link_info *)); +static boolean elf_s390_object_p PARAMS ((bfd *)); + +#define USE_RELA 1 /* We want RELA relocations, not REL. */ + +#include "elf/s390.h" + +/* In case we're on a 32-bit machine, construct a 64-bit "-1" value + from smaller values. Start with zero, widen, *then* decrement. */ +#define MINUS_ONE (((bfd_vma)0) - 1) + +/* The relocation "howto" table. */ +static reloc_howto_type elf_howto_table[] = +{ + HOWTO (R_390_NONE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_390_NONE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + HOWTO(R_390_8, 0, 0, 8, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_8", false, 0,0x000000ff, false), + HOWTO(R_390_12, 0, 1, 12, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_390_12", false, 0,0x00000fff, false), + HOWTO(R_390_16, 0, 1, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_16", false, 0,0x0000ffff, false), + HOWTO(R_390_32, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_32", false, 0,0xffffffff, false), + HOWTO(R_390_PC32, 0, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC32", false, 0,0xffffffff, true), + HOWTO(R_390_GOT12, 0, 1, 12, false, 0, complain_overflow_dont, bfd_elf_generic_reloc, "R_390_GOT12", false, 0,0x00000fff, false), + HOWTO(R_390_GOT32, 0, 2, 32, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT32", false, 0,0xffffffff, false), + HOWTO(R_390_PLT32, 0, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT32", false, 0,0xffffffff, true), + HOWTO(R_390_COPY, 0, 4, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_COPY", false, 0,MINUS_ONE, false), + HOWTO(R_390_GLOB_DAT, 0, 4, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GLOB_DAT",false, 0,MINUS_ONE, false), + HOWTO(R_390_JMP_SLOT, 0, 4, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_JMP_SLOT",false, 0,MINUS_ONE, false), + HOWTO(R_390_RELATIVE, 0, 4, 64, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_RELATIVE",false, 0,MINUS_ONE, false), + HOWTO(R_390_GOTOFF, 0, 4, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTOFF", false, 0,MINUS_ONE, false), + HOWTO(R_390_GOTPC, 0, 4, 64, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTPC", false, 0,MINUS_ONE, true), + HOWTO(R_390_GOT16, 0, 1, 16, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT16", false, 0,0x0000ffff, false), + HOWTO(R_390_PC16, 0, 1, 16, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC16", false, 0,0x0000ffff, true), + HOWTO(R_390_PC16DBL, 1, 1, 16, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC16DBL", false, 0,0x0000ffff, true), + HOWTO(R_390_PLT16DBL, 1, 1, 16, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT16DBL", false, 0,0x0000ffff, true), + HOWTO(R_390_PC32DBL, 1, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC32DBL", false, 0,0xffffffff, true), + HOWTO(R_390_PLT32DBL, 1, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT32DBL", false, 0,0xffffffff, true), + HOWTO(R_390_GOTPCDBL, 1, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTPCDBL", false, 0,MINUS_ONE, true), + HOWTO(R_390_64, 0, 4, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_64", false, 0,MINUS_ONE, false), + HOWTO(R_390_PC64, 0, 4, 64, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PC64", false, 0,MINUS_ONE, true), + HOWTO(R_390_GOT64, 0, 4, 64, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOT64", false, 0,MINUS_ONE, false), + HOWTO(R_390_PLT64, 0, 4, 64, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_PLT64", false, 0,MINUS_ONE, true), + HOWTO(R_390_GOTENT, 1, 2, 32, true, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_390_GOTENT", false, 0,MINUS_ONE, true), +}; + +/* GNU extension to record C++ vtable hierarchy. */ +static reloc_howto_type elf64_s390_vtinherit_howto = + HOWTO (R_390_GNU_VTINHERIT, 0,4,0,false,0,complain_overflow_dont, NULL, "R_390_GNU_VTINHERIT", false,0, 0, false); +static reloc_howto_type elf64_s390_vtentry_howto = + HOWTO (R_390_GNU_VTENTRY, 0,4,0,false,0,complain_overflow_dont, _bfd_elf_rel_vtable_reloc_fn,"R_390_GNU_VTENTRY", false,0,0, false); + +static reloc_howto_type * +elf_s390_reloc_type_lookup (abfd, code) + bfd *abfd ATTRIBUTE_UNUSED; + bfd_reloc_code_real_type code; +{ + switch (code) + { + case BFD_RELOC_NONE: + return &elf_howto_table[(int) R_390_NONE]; + case BFD_RELOC_8: + return &elf_howto_table[(int) R_390_8]; + case BFD_RELOC_390_12: + return &elf_howto_table[(int) R_390_12]; + case BFD_RELOC_16: + return &elf_howto_table[(int) R_390_16]; + case BFD_RELOC_32: + return &elf_howto_table[(int) R_390_32]; + case BFD_RELOC_CTOR: + return &elf_howto_table[(int) R_390_32]; + case BFD_RELOC_32_PCREL: + return &elf_howto_table[(int) R_390_PC32]; + case BFD_RELOC_390_GOT12: + return &elf_howto_table[(int) R_390_GOT12]; + case BFD_RELOC_32_GOT_PCREL: + return &elf_howto_table[(int) R_390_GOT32]; + case BFD_RELOC_390_PLT32: + return &elf_howto_table[(int) R_390_PLT32]; + case BFD_RELOC_390_COPY: + return &elf_howto_table[(int) R_390_COPY]; + case BFD_RELOC_390_GLOB_DAT: + return &elf_howto_table[(int) R_390_GLOB_DAT]; + case BFD_RELOC_390_JMP_SLOT: + return &elf_howto_table[(int) R_390_JMP_SLOT]; + case BFD_RELOC_390_RELATIVE: + return &elf_howto_table[(int) R_390_RELATIVE]; + case BFD_RELOC_32_GOTOFF: + return &elf_howto_table[(int) R_390_GOTOFF]; + case BFD_RELOC_390_GOTPC: + return &elf_howto_table[(int) R_390_GOTPC]; + case BFD_RELOC_390_GOT16: + return &elf_howto_table[(int) R_390_GOT16]; + case BFD_RELOC_16_PCREL: + return &elf_howto_table[(int) R_390_PC16]; + case BFD_RELOC_390_PC16DBL: + return &elf_howto_table[(int) R_390_PC16DBL]; + case BFD_RELOC_390_PLT16DBL: + return &elf_howto_table[(int) R_390_PLT16DBL]; + case BFD_RELOC_VTABLE_INHERIT: + return &elf64_s390_vtinherit_howto; + case BFD_RELOC_VTABLE_ENTRY: + return &elf64_s390_vtentry_howto; + case BFD_RELOC_390_PC32DBL: + return &elf_howto_table[(int) R_390_PC32DBL]; + case BFD_RELOC_390_PLT32DBL: + return &elf_howto_table[(int) R_390_PLT32DBL]; + case BFD_RELOC_390_GOTPCDBL: + return &elf_howto_table[(int) R_390_GOTPCDBL]; + case BFD_RELOC_64: + return &elf_howto_table[(int) R_390_64]; + case BFD_RELOC_64_PCREL: + return &elf_howto_table[(int) R_390_PC64]; + case BFD_RELOC_390_GOT64: + return &elf_howto_table[(int) R_390_GOT64]; + case BFD_RELOC_390_PLT64: + return &elf_howto_table[(int) R_390_PLT64]; + case BFD_RELOC_390_GOTENT: + return &elf_howto_table[(int) R_390_GOTENT]; + default: + break; + } + return 0; +} + +/* We need to use ELF64_R_TYPE so we have our own copy of this function, + and elf64-s390.c has its own copy. */ + +static void +elf_s390_info_to_howto (abfd, cache_ptr, dst) + bfd *abfd ATTRIBUTE_UNUSED; + arelent *cache_ptr; + Elf_Internal_Rela *dst; +{ + switch (ELF64_R_TYPE(dst->r_info)) + { + case R_390_GNU_VTINHERIT: + cache_ptr->howto = &elf64_s390_vtinherit_howto; + break; + + case R_390_GNU_VTENTRY: + cache_ptr->howto = &elf64_s390_vtentry_howto; + break; + + default: + BFD_ASSERT (ELF64_R_TYPE(dst->r_info) < (unsigned int) R_390_max); + cache_ptr->howto = &elf_howto_table[ELF64_R_TYPE(dst->r_info)]; + } +} + +static boolean +elf_s390_is_local_label_name (abfd, name) + bfd *abfd; + const char *name; +{ + if (name[0] == '.' && (name[1] == 'X' || name[1] == 'L')) + return true; + + return _bfd_elf_is_local_label_name (abfd, name); +} + +/* Functions for the 390 ELF linker. */ + +/* The name of the dynamic interpreter. This is put in the .interp + section. */ + +#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" + +/* The size in bytes of the first entry in the procedure linkage table. */ +#define PLT_FIRST_ENTRY_SIZE 32 +/* The size in bytes of an entry in the procedure linkage table. */ +#define PLT_ENTRY_SIZE 32 + +#define GOT_ENTRY_SIZE 8 + +/* The first three entries in a procedure linkage table are reserved, + and the initial contents are unimportant (we zero them out). + Subsequent entries look like this. See the SVR4 ABI 386 + supplement to see how this works. */ + +/* For the s390, simple addr offset can only be 0 - 4096. + To use the full 16777216 TB address space, several instructions + are needed to load an address in a register and execute + a branch( or just saving the address) + + Furthermore, only r 0 and 1 are free to use!!! */ + +/* The first 3 words in the GOT are then reserved. + Word 0 is the address of the dynamic table. + Word 1 is a pointer to a structure describing the object + Word 2 is used to point to the loader entry address. + + The code for PLT entries looks like this: + + The GOT holds the address in the PLT to be executed. + The loader then gets: + 24(15) = Pointer to the structure describing the object. + 28(15) = Offset in symbol table + The loader must then find the module where the function is + and insert the address in the GOT. + + PLT1: LARL 1,<fn>@GOTENT # 6 bytes Load address of GOT entry in r1 + LG 1,0(1) # 6 bytes Load address from GOT in r1 + BCR 15,1 # 2 bytes Jump to address + RET1: BASR 1,0 # 2 bytes Return from GOT 1st time + LGF 1,12(1) # 6 bytes Load offset in symbl table in r1 + BRCL 15,-x # 6 bytes Jump to start of PLT + .long ? # 4 bytes offset into symbol table + + Total = 32 bytes per PLT entry + Fixup at offset 2: relative address to GOT entry + Fixup at offset 22: relative branch to PLT0 + Fixup at offset 28: 32 bit offset into symbol table + + A 32 bit offset into the symbol table is enough. It allows for symbol + tables up to a size of 2 gigabyte. A single dynamic object (the main + program, any shared library) is limited to 4GB in size and I want to see + the program that manages to have a symbol table of more than 2 GB with a + total size of at max 4 GB. */ + +#define PLT_ENTRY_WORD0 (bfd_vma) 0xc0100000 +#define PLT_ENTRY_WORD1 (bfd_vma) 0x0000e310 +#define PLT_ENTRY_WORD2 (bfd_vma) 0x10000004 +#define PLT_ENTRY_WORD3 (bfd_vma) 0x07f10d10 +#define PLT_ENTRY_WORD4 (bfd_vma) 0xe310100c +#define PLT_ENTRY_WORD5 (bfd_vma) 0x0014c0f4 +#define PLT_ENTRY_WORD6 (bfd_vma) 0x00000000 +#define PLT_ENTRY_WORD7 (bfd_vma) 0x00000000 + +/* The first PLT entry pushes the offset into the symbol table + from R1 onto the stack at 8(15) and the loader object info + at 12(15), loads the loader address in R1 and jumps to it. */ + +/* The first entry in the PLT: + + PLT0: + STG 1,56(15) # r1 contains the offset into the symbol table + LARL 1,_GLOBAL_OFFSET_TABLE # load address of global offset table + MVC 48(8,15),8(1) # move loader ino (object struct address) to stack + LG 1,16(1) # get entry address of loader + BCR 15,1 # jump to loader + + Fixup at offset 8: relative address to start of GOT. */ + +#define PLT_FIRST_ENTRY_WORD0 (bfd_vma) 0xe310f038 +#define PLT_FIRST_ENTRY_WORD1 (bfd_vma) 0x0024c010 +#define PLT_FIRST_ENTRY_WORD2 (bfd_vma) 0x00000000 +#define PLT_FIRST_ENTRY_WORD3 (bfd_vma) 0xd207f030 +#define PLT_FIRST_ENTRY_WORD4 (bfd_vma) 0x1008e310 +#define PLT_FIRST_ENTRY_WORD5 (bfd_vma) 0x10100004 +#define PLT_FIRST_ENTRY_WORD6 (bfd_vma) 0x07f10700 +#define PLT_FIRST_ENTRY_WORD7 (bfd_vma) 0x07000700 + +/* The s390 linker needs to keep track of the number of relocs that it + decides to copy as dynamic relocs in check_relocs for each symbol. + This is so that it can later discard them if they are found to be + unnecessary. We store the information in a field extending the + regular ELF linker hash table. */ + +struct elf_s390_dyn_relocs +{ + struct elf_s390_dyn_relocs *next; + + /* The input section of the reloc. */ + asection *sec; + + /* Total number of relocs copied for the input section. */ + bfd_size_type count; + + /* Number of pc-relative relocs copied for the input section. */ + bfd_size_type pc_count; +}; + +/* s390 ELF linker hash entry. */ + +struct elf_s390_link_hash_entry +{ + struct elf_link_hash_entry elf; + + /* Track dynamic relocs copied for this symbol. */ + struct elf_s390_dyn_relocs *dyn_relocs; +}; + +/* s390 ELF linker hash table. */ + +struct elf_s390_link_hash_table +{ + struct elf_link_hash_table elf; + + /* Short-cuts to get to dynamic linker sections. */ + asection *sgot; + asection *sgotplt; + asection *srelgot; + asection *splt; + asection *srelplt; + asection *sdynbss; + asection *srelbss; + + /* Small local sym to section mapping cache. */ + struct sym_sec_cache sym_sec; +}; + +/* Get the s390 ELF linker hash table from a link_info structure. */ + +#define elf_s390_hash_table(p) \ + ((struct elf_s390_link_hash_table *) ((p)->hash)) + +/* Create an entry in an s390 ELF linker hash table. */ + +static struct bfd_hash_entry * +link_hash_newfunc (entry, table, string) + struct bfd_hash_entry *entry; + struct bfd_hash_table *table; + const char *string; +{ + /* Allocate the structure if it has not already been allocated by a + subclass. */ + if (entry == NULL) + { + entry = bfd_hash_allocate (table, + sizeof (struct elf_s390_link_hash_entry)); + if (entry == NULL) + return entry; + } + + /* Call the allocation method of the superclass. */ + entry = _bfd_elf_link_hash_newfunc (entry, table, string); + if (entry != NULL) + { + struct elf_s390_link_hash_entry *eh; + + eh = (struct elf_s390_link_hash_entry *) entry; + eh->dyn_relocs = NULL; + } + + return entry; +} + +/* Create an s390 ELF linker hash table. */ + +static struct bfd_link_hash_table * +elf_s390_link_hash_table_create (abfd) + bfd *abfd; +{ + struct elf_s390_link_hash_table *ret; + bfd_size_type amt = sizeof (struct elf_s390_link_hash_table); + + ret = (struct elf_s390_link_hash_table *) bfd_alloc (abfd, amt); + if (ret == NULL) + return NULL; + + if (! _bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc)) + { + bfd_release (abfd, ret); + return NULL; + } + + ret->sgot = NULL; + ret->sgotplt = NULL; + ret->srelgot = NULL; + ret->splt = NULL; + ret->srelplt = NULL; + ret->sdynbss = NULL; + ret->srelbss = NULL; + ret->sym_sec.abfd = NULL; + + return &ret->elf.root; +} + +/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up + shortcuts to them in our hash table. */ + +static boolean +create_got_section (dynobj, info) + bfd *dynobj; + struct bfd_link_info *info; +{ + struct elf_s390_link_hash_table *htab; + + if (! _bfd_elf_create_got_section (dynobj, info)) + return false; + + htab = elf_s390_hash_table (info); + htab->sgot = bfd_get_section_by_name (dynobj, ".got"); + htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt"); + if (!htab->sgot || !htab->sgotplt) + abort (); + + htab->srelgot = bfd_make_section (dynobj, ".rela.got"); + if (htab->srelgot == NULL + || ! bfd_set_section_flags (dynobj, htab->srelgot, + (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS + | SEC_IN_MEMORY | SEC_LINKER_CREATED + | SEC_READONLY)) + || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2)) + return false; + return true; +} + +/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and + .rela.bss sections in DYNOBJ, and set up shortcuts to them in our + hash table. */ + +static boolean +elf_s390_create_dynamic_sections (dynobj, info) + bfd *dynobj; + struct bfd_link_info *info; +{ + struct elf_s390_link_hash_table *htab; + + htab = elf_s390_hash_table (info); + if (!htab->sgot && !create_got_section (dynobj, info)) + return false; + + if (!_bfd_elf_create_dynamic_sections (dynobj, info)) + return false; + + htab->splt = bfd_get_section_by_name (dynobj, ".plt"); + htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt"); + htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss"); + if (!info->shared) + htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss"); + + if (!htab->splt || !htab->srelplt || !htab->sdynbss + || (!info->shared && !htab->srelbss)) + abort (); + + return true; +} + +/* Copy the extra info we tack onto an elf_link_hash_entry. */ + +static void +elf_s390_copy_indirect_symbol (dir, ind) + struct elf_link_hash_entry *dir, *ind; +{ + struct elf_s390_link_hash_entry *edir, *eind; + + edir = (struct elf_s390_link_hash_entry *) dir; + eind = (struct elf_s390_link_hash_entry *) ind; + + if (eind->dyn_relocs != NULL) + { + if (edir->dyn_relocs != NULL) + { + struct elf_s390_dyn_relocs **pp; + struct elf_s390_dyn_relocs *p; + + if (ind->root.type == bfd_link_hash_indirect) + abort (); + + /* Add reloc counts against the weak sym to the strong sym + list. Merge any entries against the same section. */ + for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) + { + struct elf_s390_dyn_relocs *q; + + for (q = edir->dyn_relocs; q != NULL; q = q->next) + if (q->sec == p->sec) + { + q->pc_count += p->pc_count; + q->count += p->count; + *pp = p->next; + break; + } + if (q == NULL) + pp = &p->next; + } + *pp = edir->dyn_relocs; + } + + edir->dyn_relocs = eind->dyn_relocs; + eind->dyn_relocs = NULL; + } + + _bfd_elf_link_hash_copy_indirect (dir, ind); +} + +/* Look through the relocs for a section during the first phase, and + allocate space in the global offset table or procedure linkage + table. */ + +static boolean +elf_s390_check_relocs (abfd, info, sec, relocs) + bfd *abfd; + struct bfd_link_info *info; + asection *sec; + const Elf_Internal_Rela *relocs; +{ + struct elf_s390_link_hash_table *htab; + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + const Elf_Internal_Rela *rel; + const Elf_Internal_Rela *rel_end; + asection *sreloc; + + if (info->relocateable) + return true; + + htab = elf_s390_hash_table (info); + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (abfd); + + sreloc = NULL; + + rel_end = relocs + sec->reloc_count; + for (rel = relocs; rel < rel_end; rel++) + { + unsigned long r_symndx; + struct elf_link_hash_entry *h; + + r_symndx = ELF64_R_SYM (rel->r_info); + + if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) + { + (*_bfd_error_handler) (_("%s: bad symbol index: %d"), + bfd_archive_filename (abfd), + r_symndx); + return false; + } + + if (r_symndx < symtab_hdr->sh_info) + h = NULL; + else + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + + switch (ELF64_R_TYPE (rel->r_info)) + { + case R_390_GOT12: + case R_390_GOT16: + case R_390_GOT32: + case R_390_GOT64: + case R_390_GOTENT: + /* This symbol requires a global offset table entry. */ + if (h != NULL) + { + h->got.refcount += 1; + } + else + { + bfd_signed_vma *local_got_refcounts; + + /* This is a global offset table entry for a local symbol. */ + local_got_refcounts = elf_local_got_refcounts (abfd); + if (local_got_refcounts == NULL) + { + bfd_size_type size; + + size = symtab_hdr->sh_info; + size *= sizeof (bfd_signed_vma); + local_got_refcounts = ((bfd_signed_vma *) + bfd_zalloc (abfd, size)); + if (local_got_refcounts == NULL) + return false; + elf_local_got_refcounts (abfd) = local_got_refcounts; + } + local_got_refcounts[r_symndx] += 1; + } + /* Fall through */ + + case R_390_GOTOFF: + case R_390_GOTPC: + case R_390_GOTPCDBL: + if (htab->sgot == NULL) + { + if (htab->elf.dynobj == NULL) + htab->elf.dynobj = abfd; + if (!create_got_section (htab->elf.dynobj, info)) + return false; + } + break; + + case R_390_PLT16DBL: + case R_390_PLT32: + case R_390_PLT32DBL: + case R_390_PLT64: + /* This symbol requires a procedure linkage table entry. We + actually build the entry in adjust_dynamic_symbol, + because this might be a case of linking PIC code which is + never referenced by a dynamic object, in which case we + don't need to generate a procedure linkage table entry + after all. */ + + /* If this is a local symbol, we resolve it directly without + creating a procedure linkage table entry. */ + if (h == NULL) + continue; + + h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; + h->plt.refcount += 1; + break; + + case R_390_8: + case R_390_16: + case R_390_32: + case R_390_64: + case R_390_PC16: + case R_390_PC16DBL: + case R_390_PC32: + case R_390_PC32DBL: + case R_390_PC64: + if (h != NULL && !info->shared) + { + /* If this reloc is in a read-only section, we might + need a copy reloc. We can't check reliably at this + stage whether the section is read-only, as input + sections have not yet been mapped to output sections. + Tentatively set the flag for now, and correct in + adjust_dynamic_symbol. */ + h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF; + + /* We may need a .plt entry if the function this reloc + refers to is in a shared lib. */ + h->plt.refcount += 1; + } + + /* If we are creating a shared library, and this is a reloc + against a global symbol, or a non PC relative reloc + against a local symbol, then we need to copy the reloc + into the shared library. However, if we are linking with + -Bsymbolic, we do not need to copy a reloc against a + global symbol which is defined in an object we are + including in the link (i.e., DEF_REGULAR is set). At + this point we have not seen all the input files, so it is + possible that DEF_REGULAR is not set now but will be set + later (it is never cleared). In case of a weak definition, + DEF_REGULAR may be cleared later by a strong definition in + a shared library. We account for that possibility below by + storing information in the relocs_copied field of the hash + table entry. A similar situation occurs when creating + shared libraries and symbol visibility changes render the + symbol local. + + If on the other hand, we are creating an executable, we + may need to keep relocations for symbols satisfied by a + dynamic library if we manage to avoid copy relocs for the + symbol. */ + if ((info->shared + && (sec->flags & SEC_ALLOC) != 0 + && ((ELF64_R_TYPE (rel->r_info) != R_390_PC16 + && ELF64_R_TYPE (rel->r_info) != R_390_PC16DBL + && ELF64_R_TYPE (rel->r_info) != R_390_PC32 + && ELF64_R_TYPE (rel->r_info) != R_390_PC32DBL + && ELF64_R_TYPE (rel->r_info) != R_390_PC64) + || (h != NULL + && (! info->symbolic + || h->root.type == bfd_link_hash_defweak + || (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0)))) + || (!info->shared + && (sec->flags & SEC_ALLOC) != 0 + && h != NULL + && (h->root.type == bfd_link_hash_defweak + || (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0))) + { + struct elf_s390_dyn_relocs *p; + struct elf_s390_dyn_relocs **head; + + /* We must copy these reloc types into the output file. + Create a reloc section in dynobj and make room for + this reloc. */ + if (sreloc == NULL) + { + const char *name; + bfd *dynobj; + + name = (bfd_elf_string_from_elf_section + (abfd, + elf_elfheader (abfd)->e_shstrndx, + elf_section_data (sec)->rel_hdr.sh_name)); + if (name == NULL) + return false; + + if (strncmp (name, ".rela", 5) != 0 + || strcmp (bfd_get_section_name (abfd, sec), + name + 5) != 0) + { + (*_bfd_error_handler) + (_("%s: bad relocation section name `%s\'"), + bfd_archive_filename (abfd), name); + } + + if (htab->elf.dynobj == NULL) + htab->elf.dynobj = abfd; + + dynobj = htab->elf.dynobj; + sreloc = bfd_get_section_by_name (dynobj, name); + if (sreloc == NULL) + { + flagword flags; + + sreloc = bfd_make_section (dynobj, name); + flags = (SEC_HAS_CONTENTS | SEC_READONLY + | SEC_IN_MEMORY | SEC_LINKER_CREATED); + if ((sec->flags & SEC_ALLOC) != 0) + flags |= SEC_ALLOC | SEC_LOAD; + if (sreloc == NULL + || ! bfd_set_section_flags (dynobj, sreloc, flags) + || ! bfd_set_section_alignment (dynobj, sreloc, 2)) + return false; + } + elf_section_data (sec)->sreloc = sreloc; + } + + /* If this is a global symbol, we count the number of + relocations we need for this symbol. */ + if (h != NULL) + { + head = &((struct elf_s390_link_hash_entry *) h)->dyn_relocs; + } + else + { + /* Track dynamic relocs needed for local syms too. + We really need local syms available to do this + easily. Oh well. */ + + asection *s; + s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, + sec, r_symndx); + if (s == NULL) + return false; + + head = ((struct elf_s390_dyn_relocs **) + &elf_section_data (s)->local_dynrel); + } + + p = *head; + if (p == NULL || p->sec != sec) + { + bfd_size_type amt = sizeof *p; + p = ((struct elf_s390_dyn_relocs *) + bfd_alloc (htab->elf.dynobj, amt)); + if (p == NULL) + return false; + p->next = *head; + *head = p; + p->sec = sec; + p->count = 0; + p->pc_count = 0; + } + + p->count += 1; + if (ELF64_R_TYPE (rel->r_info) == R_390_PC16 + || ELF64_R_TYPE (rel->r_info) == R_390_PC16DBL + || ELF64_R_TYPE (rel->r_info) == R_390_PC32 + || ELF64_R_TYPE (rel->r_info) == R_390_PC32DBL + || ELF64_R_TYPE (rel->r_info) == R_390_PC64) + p->pc_count += 1; + } + break; + + /* This relocation describes the C++ object vtable hierarchy. + Reconstruct it for later use during GC. */ + case R_390_GNU_VTINHERIT: + if (!_bfd_elf64_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + return false; + break; + + /* This relocation describes which C++ vtable entries are actually + used. Record for later use during GC. */ + case R_390_GNU_VTENTRY: + if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + return false; + break; + + default: + break; + } + } + + return true; +} + +/* Return the section that should be marked against GC for a given + relocation. */ + +static asection * +elf_s390_gc_mark_hook (abfd, info, rel, h, sym) + bfd *abfd; + struct bfd_link_info *info ATTRIBUTE_UNUSED; + Elf_Internal_Rela *rel; + struct elf_link_hash_entry *h; + Elf_Internal_Sym *sym; +{ + if (h != NULL) + { + switch (ELF64_R_TYPE (rel->r_info)) + { + case R_390_GNU_VTINHERIT: + case R_390_GNU_VTENTRY: + break; + + default: + switch (h->root.type) + { + case bfd_link_hash_defined: + case bfd_link_hash_defweak: + return h->root.u.def.section; + + case bfd_link_hash_common: + return h->root.u.c.p->section; + + default: + break; + } + } + } + else + { + return bfd_section_from_elf_index (abfd, sym->st_shndx); + } + + return NULL; +} + +/* Update the got entry reference counts for the section being removed. */ + +static boolean +elf_s390_gc_sweep_hook (abfd, info, sec, relocs) + bfd *abfd; + struct bfd_link_info *info; + asection *sec; + const Elf_Internal_Rela *relocs; +{ + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + bfd_signed_vma *local_got_refcounts; + const Elf_Internal_Rela *rel, *relend; + unsigned long r_symndx; + struct elf_link_hash_entry *h; + + elf_section_data (sec)->local_dynrel = NULL; + + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (abfd); + local_got_refcounts = elf_local_got_refcounts (abfd); + + relend = relocs + sec->reloc_count; + for (rel = relocs; rel < relend; rel++) + switch (ELF64_R_TYPE (rel->r_info)) + { + case R_390_GOT12: + case R_390_GOT16: + case R_390_GOT32: + case R_390_GOT64: + case R_390_GOTOFF: + case R_390_GOTPC: + case R_390_GOTPCDBL: + case R_390_GOTENT: + r_symndx = ELF64_R_SYM (rel->r_info); + if (r_symndx >= symtab_hdr->sh_info) + { + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + if (h->got.refcount > 0) + h->got.refcount -= 1; + } + else if (local_got_refcounts != NULL) + { + if (local_got_refcounts[r_symndx] > 0) + local_got_refcounts[r_symndx] -= 1; + } + break; + + case R_390_8: + case R_390_12: + case R_390_16: + case R_390_32: + case R_390_64: + case R_390_PC16: + case R_390_PC16DBL: + case R_390_PC32: + case R_390_PC32DBL: + case R_390_PC64: + r_symndx = ELF64_R_SYM (rel->r_info); + if (r_symndx >= symtab_hdr->sh_info) + { + struct elf_s390_link_hash_entry *eh; + struct elf_s390_dyn_relocs **pp; + struct elf_s390_dyn_relocs *p; + + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + + if (!info->shared && h->plt.refcount > 0) + h->plt.refcount -= 1; + + eh = (struct elf_s390_link_hash_entry *) h; + + for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) + if (p->sec == sec) + { + if (ELF64_R_TYPE (rel->r_info) == R_390_PC16 + || ELF64_R_TYPE (rel->r_info) == R_390_PC16DBL + || ELF64_R_TYPE (rel->r_info) == R_390_PC32) + p->pc_count -= 1; + p->count -= 1; + if (p->count == 0) + *pp = p->next; + break; + } + } + break; + + case R_390_PLT16DBL: + case R_390_PLT32: + case R_390_PLT32DBL: + case R_390_PLT64: + r_symndx = ELF64_R_SYM (rel->r_info); + if (r_symndx >= symtab_hdr->sh_info) + { + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + if (h->plt.refcount > 0) + h->plt.refcount -= 1; + } + break; + + default: + break; + } + + return true; +} + +/* Adjust a symbol defined by a dynamic object and referenced by a + regular object. The current definition is in some section of the + dynamic object, but we're not including those sections. We have to + change the definition to something the rest of the link can + understand. */ + +static boolean +elf_s390_adjust_dynamic_symbol (info, h) + struct bfd_link_info *info; + struct elf_link_hash_entry *h; +{ + struct elf_s390_link_hash_table *htab; + struct elf_s390_link_hash_entry * eh; + struct elf_s390_dyn_relocs *p; + asection *s; + unsigned int power_of_two; + + /* If this is a function, put it in the procedure linkage table. We + will fill in the contents of the procedure linkage table later + (although we could actually do it here). */ + if (h->type == STT_FUNC + || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) + { + if (h->plt.refcount <= 0 + || (! info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0 + && h->root.type != bfd_link_hash_undefweak + && h->root.type != bfd_link_hash_undefined)) + { + /* This case can occur if we saw a PLT32 reloc in an input + file, but the symbol was never referred to by a dynamic + object, or if all references were garbage collected. In + such a case, we don't actually need to build a procedure + linkage table, and we can just do a PC32 reloc instead. */ + h->plt.offset = (bfd_vma) -1; + h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; + } + + return true; + } + else + /* It's possible that we incorrectly decided a .plt reloc was + needed for an R_390_PC32 reloc to a non-function sym in + check_relocs. We can't decide accurately between function and + non-function syms in check-relocs; Objects loaded later in + the link may change h->type. So fix it now. */ + h->plt.offset = (bfd_vma) -1; + + /* If this is a weak symbol, and there is a real definition, the + processor independent code will have arranged for us to see the + real definition first, and we can just use the same value. */ + if (h->weakdef != NULL) + { + BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined + || h->weakdef->root.type == bfd_link_hash_defweak); + h->root.u.def.section = h->weakdef->root.u.def.section; + h->root.u.def.value = h->weakdef->root.u.def.value; + return true; + } + + /* This is a reference to a symbol defined by a dynamic object which + is not a function. */ + + /* If we are creating a shared library, we must presume that the + only references to the symbol are via the global offset table. + For such cases we need not do anything here; the relocations will + be handled correctly by relocate_section. */ + if (info->shared) + return true; + + /* If there are no references to this symbol that do not use the + GOT, we don't need to generate a copy reloc. */ + if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0) + return true; + + /* If -z nocopyreloc was given, we won't generate them either. */ + if (info->nocopyreloc) + { + h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF; + return true; + } + + eh = (struct elf_s390_link_hash_entry *) h; + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + s = p->sec->output_section; + if (s != NULL && (s->flags & SEC_READONLY) != 0) + break; + } + + /* If we didn't find any dynamic relocs in read-only sections, then + we'll be keeping the dynamic relocs and avoiding the copy reloc. */ + if (p == NULL) + { + h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF; + return true; + } + + /* We must allocate the symbol in our .dynbss section, which will + become part of the .bss section of the executable. There will be + an entry for this symbol in the .dynsym section. The dynamic + object will contain position independent code, so all references + from the dynamic object to this symbol will go through the global + offset table. The dynamic linker will use the .dynsym entry to + determine the address it must put in the global offset table, so + both the dynamic object and the regular object will refer to the + same memory location for the variable. */ + + htab = elf_s390_hash_table (info); + + /* We must generate a R_390_COPY reloc to tell the dynamic linker to + copy the initial value out of the dynamic object and into the + runtime process image. */ + if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) + { + htab->srelbss->_raw_size += sizeof (Elf64_External_Rela); + h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY; + } + + /* We need to figure out the alignment required for this symbol. I + have no idea how ELF linkers handle this. */ + power_of_two = bfd_log2 (h->size); + if (power_of_two > 3) + power_of_two = 3; + + /* Apply the required alignment. */ + s = htab->sdynbss; + s->_raw_size = BFD_ALIGN (s->_raw_size, (bfd_size_type) (1 << power_of_two)); + if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s)) + { + if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two)) + return false; + } + + /* Define the symbol as being at this point in the section. */ + h->root.u.def.section = s; + h->root.u.def.value = s->_raw_size; + + /* Increment the section size to make room for the symbol. */ + s->_raw_size += h->size; + + return true; +} + +/* This is the condition under which elf_s390_finish_dynamic_symbol + will be called from elflink.h. If elflink.h doesn't call our + finish_dynamic_symbol routine, we'll need to do something about + initializing any .plt and .got entries in elf_s390_relocate_section. */ +#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \ + ((DYN) \ + && ((INFO)->shared \ + || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ + && ((H)->dynindx != -1 \ + || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) + +/* Allocate space in .plt, .got and associated reloc sections for + dynamic relocs. */ + +static boolean +allocate_dynrelocs (h, inf) + struct elf_link_hash_entry *h; + PTR inf; +{ + struct bfd_link_info *info; + struct elf_s390_link_hash_table *htab; + struct elf_s390_link_hash_entry *eh; + struct elf_s390_dyn_relocs *p; + + if (h->root.type == bfd_link_hash_indirect) + return true; + + if (h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + info = (struct bfd_link_info *) inf; + htab = elf_s390_hash_table (info); + + if (htab->elf.dynamic_sections_created + && h->plt.refcount > 0) + { + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) + { + if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + return false; + } + + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h)) + { + asection *s = htab->splt; + + /* If this is the first .plt entry, make room for the special + first entry. */ + if (s->_raw_size == 0) + s->_raw_size += PLT_FIRST_ENTRY_SIZE; + + h->plt.offset = s->_raw_size; + + /* If this symbol is not defined in a regular file, and we are + not generating a shared library, then set the symbol to this + location in the .plt. This is required to make function + pointers compare as equal between the normal executable and + the shared library. */ + if (! info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) + { + h->root.u.def.section = s; + h->root.u.def.value = h->plt.offset; + } + + /* Make room for this entry. */ + s->_raw_size += PLT_ENTRY_SIZE; + + /* We also need to make an entry in the .got.plt section, which + will be placed in the .got section by the linker script. */ + htab->sgotplt->_raw_size += GOT_ENTRY_SIZE; + + /* We also need to make an entry in the .rela.plt section. */ + htab->srelplt->_raw_size += sizeof (Elf64_External_Rela); + } + else + { + h->plt.offset = (bfd_vma) -1; + h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; + } + } + else + { + h->plt.offset = (bfd_vma) -1; + h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; + } + + if (h->got.refcount > 0) + { + asection *s; + boolean dyn; + + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) + { + if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + return false; + } + + s = htab->sgot; + h->got.offset = s->_raw_size; + s->_raw_size += GOT_ENTRY_SIZE; + dyn = htab->elf.dynamic_sections_created; + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)) + htab->srelgot->_raw_size += sizeof (Elf64_External_Rela); + } + else + h->got.offset = (bfd_vma) -1; + + eh = (struct elf_s390_link_hash_entry *) h; + if (eh->dyn_relocs == NULL) + return true; + + /* In the shared -Bsymbolic case, discard space allocated for + dynamic pc-relative relocs against symbols which turn out to be + defined in regular objects. For the normal shared case, discard + space for pc-relative relocs that have become local due to symbol + visibility changes. */ + + if (info->shared) + { + if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 + && ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0 + || info->symbolic)) + { + struct elf_s390_dyn_relocs **pp; + + for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + { + p->count -= p->pc_count; + p->pc_count = 0; + if (p->count == 0) + *pp = p->next; + else + pp = &p->next; + } + } + } + else + { + /* For the non-shared case, discard space for relocs against + symbols which turn out to need copy relocs or are not + dynamic. */ + + if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0 + && (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) + || (htab->elf.dynamic_sections_created + && (h->root.type == bfd_link_hash_undefweak + || h->root.type == bfd_link_hash_undefined)))) + { + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) + { + if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + return false; + } + + /* If that succeeded, we know we'll be keeping all the + relocs. */ + if (h->dynindx != -1) + goto keep; + } + + eh->dyn_relocs = NULL; + + keep: ; + } + + /* Finally, allocate space. */ + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + asection *sreloc = elf_section_data (p->sec)->sreloc; + sreloc->_raw_size += p->count * sizeof (Elf64_External_Rela); + } + + return true; +} + +/* Find any dynamic relocs that apply to read-only sections. */ + +static boolean +readonly_dynrelocs (h, inf) + struct elf_link_hash_entry *h; + PTR inf; +{ + struct elf_s390_link_hash_entry *eh; + struct elf_s390_dyn_relocs *p; + + if (h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + eh = (struct elf_s390_link_hash_entry *) h; + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + { + struct bfd_link_info *info = (struct bfd_link_info *) inf; + + info->flags |= DF_TEXTREL; + + /* Not an error, just cut short the traversal. */ + return false; + } + } + return true; +} + +/* Set the sizes of the dynamic sections. */ + +static boolean +elf_s390_size_dynamic_sections (output_bfd, info) + bfd *output_bfd ATTRIBUTE_UNUSED; + struct bfd_link_info *info; +{ + struct elf_s390_link_hash_table *htab; + bfd *dynobj; + asection *s; + boolean relocs; + bfd *ibfd; + + htab = elf_s390_hash_table (info); + dynobj = htab->elf.dynobj; + if (dynobj == NULL) + abort (); + + if (htab->elf.dynamic_sections_created) + { + /* Set the contents of the .interp section to the interpreter. */ + if (! info->shared) + { + s = bfd_get_section_by_name (dynobj, ".interp"); + if (s == NULL) + abort (); + s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; + s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; + } + } + + /* Set up .got offsets for local syms, and space for local dynamic + relocs. */ + for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) + { + bfd_signed_vma *local_got; + bfd_signed_vma *end_local_got; + bfd_size_type locsymcount; + Elf_Internal_Shdr *symtab_hdr; + asection *srela; + + if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) + continue; + + for (s = ibfd->sections; s != NULL; s = s->next) + { + struct elf_s390_dyn_relocs *p; + + for (p = *((struct elf_s390_dyn_relocs **) + &elf_section_data (s)->local_dynrel); + p != NULL; + p = p->next) + { + if (!bfd_is_abs_section (p->sec) + && bfd_is_abs_section (p->sec->output_section)) + { + /* Input section has been discarded, either because + it is a copy of a linkonce section or due to + linker script /DISCARD/, so we'll be discarding + the relocs too. */ + } + else if (p->count != 0) + { + srela = elf_section_data (p->sec)->sreloc; + srela->_raw_size += p->count * sizeof (Elf64_External_Rela); + if ((p->sec->output_section->flags & SEC_READONLY) != 0) + info->flags |= DF_TEXTREL; + } + } + } + + local_got = elf_local_got_refcounts (ibfd); + if (!local_got) + continue; + + symtab_hdr = &elf_tdata (ibfd)->symtab_hdr; + locsymcount = symtab_hdr->sh_info; + end_local_got = local_got + locsymcount; + s = htab->sgot; + srela = htab->srelgot; + for (; local_got < end_local_got; ++local_got) + { + if (*local_got > 0) + { + *local_got = s->_raw_size; + s->_raw_size += GOT_ENTRY_SIZE; + if (info->shared) + srela->_raw_size += sizeof (Elf64_External_Rela); + } + else + *local_got = (bfd_vma) -1; + } + } + + /* Allocate global sym .plt and .got entries, and space for global + sym dynamic relocs. */ + elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info); + + /* We now have determined the sizes of the various dynamic sections. + Allocate memory for them. */ + relocs = false; + for (s = dynobj->sections; s != NULL; s = s->next) + { + if ((s->flags & SEC_LINKER_CREATED) == 0) + continue; + + if (s == htab->splt + || s == htab->sgot + || s == htab->sgotplt) + { + /* Strip this section if we don't need it; see the + comment below. */ + } + else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0) + { + if (s->_raw_size != 0 && s != htab->srelplt) + relocs = true; + + /* We use the reloc_count field as a counter if we need + to copy relocs into the output file. */ + s->reloc_count = 0; + } + else + { + /* It's not one of our sections, so don't allocate space. */ + continue; + } + + if (s->_raw_size == 0) + { + /* If we don't need this section, strip it from the + output file. This is to handle .rela.bss and + .rela.plt. We must create it in + create_dynamic_sections, because it must be created + before the linker maps input sections to output + sections. The linker does that before + adjust_dynamic_symbol is called, and it is that + function which decides whether anything needs to go + into these sections. */ + + _bfd_strip_section_from_output (info, s); + continue; + } + + /* Allocate memory for the section contents. We use bfd_zalloc + here in case unused entries are not reclaimed before the + section's contents are written out. This should not happen, + but this way if it does, we get a R_390_NONE reloc instead + of garbage. */ + s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size); + if (s->contents == NULL) + return false; + } + + if (htab->elf.dynamic_sections_created) + { + /* Add some entries to the .dynamic section. We fill in the + values later, in elf_s390_finish_dynamic_sections, but we + must add the entries now so that we get the correct size for + the .dynamic section. The DT_DEBUG entry is filled in by the + dynamic linker and used by the debugger. */ +#define add_dynamic_entry(TAG, VAL) \ + bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL)) + + if (! info->shared) + { + if (!add_dynamic_entry (DT_DEBUG, 0)) + return false; + } + + if (htab->splt->_raw_size != 0) + { + if (!add_dynamic_entry (DT_PLTGOT, 0) + || !add_dynamic_entry (DT_PLTRELSZ, 0) + || !add_dynamic_entry (DT_PLTREL, DT_RELA) + || !add_dynamic_entry (DT_JMPREL, 0)) + return false; + } + + if (relocs) + { + if (!add_dynamic_entry (DT_RELA, 0) + || !add_dynamic_entry (DT_RELASZ, 0) + || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela))) + return false; + + /* If any dynamic relocs apply to a read-only section, + then we need a DT_TEXTREL entry. */ + if ((info->flags & DF_TEXTREL) == 0) + elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, + (PTR) info); + + if ((info->flags & DF_TEXTREL) != 0) + { + if (!add_dynamic_entry (DT_TEXTREL, 0)) + return false; + } + } + } +#undef add_dynamic_entry + + return true; +} + +/* Relocate a 390 ELF section. */ + +static boolean +elf_s390_relocate_section (output_bfd, info, input_bfd, input_section, + contents, relocs, local_syms, local_sections) + bfd *output_bfd; + struct bfd_link_info *info; + bfd *input_bfd; + asection *input_section; + bfd_byte *contents; + Elf_Internal_Rela *relocs; + Elf_Internal_Sym *local_syms; + asection **local_sections; +{ + struct elf_s390_link_hash_table *htab; + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + bfd_vma *local_got_offsets; + Elf_Internal_Rela *rel; + Elf_Internal_Rela *relend; + + if (info->relocateable) + return true; + + htab = elf_s390_hash_table (info); + symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (input_bfd); + local_got_offsets = elf_local_got_offsets (input_bfd); + + rel = relocs; + relend = relocs + input_section->reloc_count; + for (; rel < relend; rel++) + { + int r_type; + reloc_howto_type *howto; + unsigned long r_symndx; + struct elf_link_hash_entry *h; + Elf_Internal_Sym *sym; + asection *sec; + bfd_vma off; + bfd_vma relocation; + boolean unresolved_reloc; + bfd_reloc_status_type r; + + r_type = ELF64_R_TYPE (rel->r_info); + if (r_type == (int) R_390_GNU_VTINHERIT + || r_type == (int) R_390_GNU_VTENTRY) + continue; + if (r_type < 0 || r_type >= (int) R_390_max) + { + bfd_set_error (bfd_error_bad_value); + return false; + } + + howto = elf_howto_table + r_type; + r_symndx = ELF64_R_SYM (rel->r_info); + h = NULL; + sym = NULL; + sec = NULL; + unresolved_reloc = false; + if (r_symndx < symtab_hdr->sh_info) + { + sym = local_syms + r_symndx; + sec = local_sections[r_symndx]; + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); + } + else + { + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + if (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + { + sec = h->root.u.def.section; + if (sec->output_section == NULL) + { + /* Set a flag that will be cleared later if we find a + relocation value for this symbol. output_section + is typically NULL for symbols satisfied by a shared + library. */ + unresolved_reloc = true; + relocation = 0; + } + else + relocation = (h->root.u.def.value + + sec->output_section->vma + + sec->output_offset); + } + else if (h->root.type == bfd_link_hash_undefweak) + relocation = 0; + else if (info->shared + && (!info->symbolic || info->allow_shlib_undefined) + && !info->no_undefined + && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) + relocation = 0; + else + { + if (! ((*info->callbacks->undefined_symbol) + (info, h->root.root.string, input_bfd, + input_section, rel->r_offset, + (!info->shared || info->no_undefined + || ELF_ST_VISIBILITY (h->other))))) + return false; + relocation = 0; + } + } + + switch (r_type) + { + case R_390_GOT12: + case R_390_GOT16: + case R_390_GOT32: + case R_390_GOT64: + case R_390_GOTENT: + /* Relocation is to the entry for this symbol in the global + offset table. */ + if (htab->sgot == NULL) + abort (); + + if (h != NULL) + { + boolean dyn; + + off = h->got.offset; + dyn = htab->elf.dynamic_sections_created; + if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h) + || (info->shared + && (info->symbolic + || h->dynindx == -1 + || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)) + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) + { + /* This is actually a static link, or it is a + -Bsymbolic link and the symbol is defined + locally, or the symbol was forced to be local + because of a version file. We must initialize + this entry in the global offset table. Since the + offset must always be a multiple of 2, we use the + least significant bit to record whether we have + initialized it already. + + When doing a dynamic link, we create a .rel.got + relocation entry to initialize the value. This + is done in the finish_dynamic_symbol routine. */ + if ((off & 1) != 0) + off &= ~1; + else + { + bfd_put_64 (output_bfd, relocation, + htab->sgot->contents + off); + h->got.offset |= 1; + } + } + else + unresolved_reloc = false; + } + else + { + if (local_got_offsets == NULL) + abort (); + + off = local_got_offsets[r_symndx]; + + /* The offset must always be a multiple of 8. We use + the least significant bit to record whether we have + already generated the necessary reloc. */ + if ((off & 1) != 0) + off &= ~1; + else + { + bfd_put_64 (output_bfd, relocation, + htab->sgot->contents + off); + + if (info->shared) + { + asection *srelgot; + Elf_Internal_Rela outrel; + Elf64_External_Rela *loc; + + srelgot = htab->srelgot; + if (srelgot == NULL) + abort (); + + outrel.r_offset = (htab->sgot->output_section->vma + + htab->sgot->output_offset + + off); + outrel.r_info = ELF64_R_INFO (0, R_390_RELATIVE); + outrel.r_addend = relocation; + loc = (Elf64_External_Rela *) srelgot->contents; + loc += srelgot->reloc_count++; + bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); + } + + local_got_offsets[r_symndx] |= 1; + } + } + + if (off >= (bfd_vma) -2) + abort (); + + relocation = htab->sgot->output_offset + off; + + /* + * For @GOTENT the relocation is against the offset between + * the instruction and the symbols entry in the GOT and not + * between the start of the GOT and the symbols entry. We + * add the vma of the GOT to get the correct value. + */ + if (r_type == R_390_GOTENT) + relocation += htab->sgot->output_section->vma; + + break; + + case R_390_GOTOFF: + /* Relocation is relative to the start of the global offset + table. */ + + /* Note that sgot->output_offset is not involved in this + calculation. We always want the start of .got. If we + defined _GLOBAL_OFFSET_TABLE in a different way, as is + permitted by the ABI, we might have to change this + calculation. */ + relocation -= htab->sgot->output_section->vma; + + break; + + case R_390_GOTPC: + case R_390_GOTPCDBL: + /* Use global offset table as symbol value. */ + relocation = htab->sgot->output_section->vma; + unresolved_reloc = false; + break; + + case R_390_PLT16DBL: + case R_390_PLT32: + case R_390_PLT32DBL: + case R_390_PLT64: + /* Relocation is to the entry for this symbol in the + procedure linkage table. */ + + /* Resolve a PLT32 reloc against a local symbol directly, + without using the procedure linkage table. */ + if (h == NULL) + break; + + if (h->plt.offset == (bfd_vma) -1 + || htab->splt == NULL) + { + /* We didn't make a PLT entry for this symbol. This + happens when statically linking PIC code, or when + using -Bsymbolic. */ + break; + } + + relocation = (htab->splt->output_section->vma + + htab->splt->output_offset + + h->plt.offset); + unresolved_reloc = false; + break; + + case R_390_8: + case R_390_16: + case R_390_32: + case R_390_64: + case R_390_PC16: + case R_390_PC16DBL: + case R_390_PC32: + case R_390_PC32DBL: + case R_390_PC64: + /* r_symndx will be zero only for relocs against symbols + from removed linkonce sections, or sections discarded by + a linker script. */ + if (r_symndx == 0 + || (input_section->flags & SEC_ALLOC) == 0) + break; + + if ((info->shared + && ((r_type != R_390_PC16 + && r_type != R_390_PC16DBL + && r_type != R_390_PC32 + && r_type != R_390_PC32DBL + && r_type != R_390_PC64) + || (h != NULL + && h->dynindx != -1 + && (! info->symbolic + || (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0)))) + || (!info->shared + && h != NULL + && h->dynindx != -1 + && (h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0 + && (((h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_DYNAMIC) != 0 + && (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0) + || h->root.type == bfd_link_hash_undefweak + || h->root.type == bfd_link_hash_undefined))) + { + Elf_Internal_Rela outrel; + boolean skip, relocate; + asection *sreloc; + Elf64_External_Rela *loc; + + /* When generating a shared object, these relocations + are copied into the output file to be resolved at run + time. */ + + skip = false; + relocate = false; + + outrel.r_offset = + _bfd_elf_section_offset (output_bfd, info, input_section, + rel->r_offset); + if (outrel.r_offset == (bfd_vma) -1) + skip = true; + else if (outrel.r_offset == (bfd_vma) -2) + skip = true, relocate = true; + + outrel.r_offset += (input_section->output_section->vma + + input_section->output_offset); + + if (skip) + memset (&outrel, 0, sizeof outrel); + else if (h != NULL + && h->dynindx != -1 + && (r_type == R_390_PC16 + || r_type == R_390_PC16DBL + || r_type == R_390_PC32 + || r_type == R_390_PC32DBL + || r_type == R_390_PC64 + || !info->shared + || !info->symbolic + || (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0)) + { + outrel.r_info = ELF64_R_INFO (h->dynindx, r_type); + outrel.r_addend = rel->r_addend; + } + else + { + /* This symbol is local, or marked to become local. */ + relocate = true; + outrel.r_info = ELF64_R_INFO (0, R_390_RELATIVE); + outrel.r_addend = relocation + rel->r_addend; + } + + sreloc = elf_section_data (input_section)->sreloc; + if (sreloc == NULL) + abort (); + + loc = (Elf64_External_Rela *) sreloc->contents; + loc += sreloc->reloc_count++; + bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); + + /* If this reloc is against an external symbol, we do + not want to fiddle with the addend. Otherwise, we + need to include the symbol value so that it becomes + an addend for the dynamic reloc. */ + if (! relocate) + continue; + } + + break; + + default: + break; + } + + if (unresolved_reloc + && !(info->shared + && (input_section->flags & SEC_DEBUGGING) != 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)) + (*_bfd_error_handler) + (_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"), + bfd_archive_filename (input_bfd), + bfd_get_section_name (input_bfd, input_section), + (long) rel->r_offset, + h->root.root.string); + + r = _bfd_final_link_relocate (howto, input_bfd, input_section, + contents, rel->r_offset, + relocation, rel->r_addend); + + if (r != bfd_reloc_ok) + { + const char *name; + + if (h != NULL) + name = h->root.root.string; + else + { + name = bfd_elf_string_from_elf_section (input_bfd, + symtab_hdr->sh_link, + sym->st_name); + if (name == NULL) + return false; + if (*name == '\0') + name = bfd_section_name (input_bfd, sec); + } + + if (r == bfd_reloc_overflow) + { + + if (! ((*info->callbacks->reloc_overflow) + (info, name, howto->name, (bfd_vma) 0, + input_bfd, input_section, rel->r_offset))) + return false; + } + else + { + (*_bfd_error_handler) + (_("%s(%s+0x%lx): reloc against `%s': error %d"), + bfd_archive_filename (input_bfd), + bfd_get_section_name (input_bfd, input_section), + (long) rel->r_offset, name, (int) r); + return false; + } + } + } + + return true; +} + +/* Finish up dynamic symbol handling. We set the contents of various + dynamic sections here. */ + +static boolean +elf_s390_finish_dynamic_symbol (output_bfd, info, h, sym) + bfd *output_bfd; + struct bfd_link_info *info; + struct elf_link_hash_entry *h; + Elf_Internal_Sym *sym; +{ + struct elf_s390_link_hash_table *htab; + + htab = elf_s390_hash_table (info); + + if (h->plt.offset != (bfd_vma) -1) + { + bfd_vma plt_index; + bfd_vma got_offset; + Elf_Internal_Rela rela; + Elf64_External_Rela *loc; + + /* This symbol has an entry in the procedure linkage table. Set + it up. */ + + if (h->dynindx == -1 + || htab->splt == NULL + || htab->sgotplt == NULL + || htab->srelplt == NULL) + abort (); + + /* Calc. index no. + Current offset - size first entry / entry size. */ + plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE; + + /* Offset in GOT is PLT index plus GOT headers(3) times 8, + addr & GOT addr. */ + got_offset = (plt_index + 3) * GOT_ENTRY_SIZE; + + /* Fill in the blueprint of a PLT. */ + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD0, + htab->splt->contents + h->plt.offset); + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD1, + htab->splt->contents + h->plt.offset + 4); + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD2, + htab->splt->contents + h->plt.offset + 8); + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD3, + htab->splt->contents + h->plt.offset + 12); + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD4, + htab->splt->contents + h->plt.offset + 16); + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD5, + htab->splt->contents + h->plt.offset + 20); + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD6, + htab->splt->contents + h->plt.offset + 24); + bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD7, + htab->splt->contents + h->plt.offset + 28); + /* Fixup the relative address to the GOT entry */ + bfd_put_32 (output_bfd, + (htab->sgotplt->output_section->vma + + htab->sgotplt->output_offset + got_offset + - (htab->splt->output_section->vma + h->plt.offset))/2, + htab->splt->contents + h->plt.offset + 2); + /* Fixup the relative branch to PLT 0 */ + bfd_put_32 (output_bfd, - (PLT_FIRST_ENTRY_SIZE + + (PLT_ENTRY_SIZE * plt_index) + 22)/2, + htab->splt->contents + h->plt.offset + 24); + /* Fixup offset into symbol table */ + bfd_put_32 (output_bfd, plt_index * sizeof (Elf64_External_Rela), + htab->splt->contents + h->plt.offset + 28); + + /* Fill in the entry in the global offset table. + Points to instruction after GOT offset. */ + bfd_put_64 (output_bfd, + (htab->splt->output_section->vma + + htab->splt->output_offset + + h->plt.offset + + 14), + htab->sgotplt->contents + got_offset); + + /* Fill in the entry in the .rela.plt section. */ + rela.r_offset = (htab->sgotplt->output_section->vma + + htab->sgotplt->output_offset + + got_offset); + rela.r_info = ELF64_R_INFO (h->dynindx, R_390_JMP_SLOT); + rela.r_addend = 0; + loc = (Elf64_External_Rela *) htab->srelplt->contents + plt_index; + bfd_elf64_swap_reloca_out (output_bfd, &rela, loc); + + if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) + { + /* Mark the symbol as undefined, rather than as defined in + the .plt section. Leave the value alone. This is a clue + for the dynamic linker, to make function pointer + comparisons work between an application and shared + library. */ + sym->st_shndx = SHN_UNDEF; + } + } + + if (h->got.offset != (bfd_vma) -1) + { + Elf_Internal_Rela rela; + Elf64_External_Rela *loc; + + /* This symbol has an entry in the global offset table. Set it + up. */ + + if (htab->sgot == NULL || htab->srelgot == NULL) + abort (); + + rela.r_offset = (htab->sgot->output_section->vma + + htab->sgot->output_offset + + (h->got.offset &~ (bfd_vma) 1)); + + /* If this is a static link, or it is a -Bsymbolic link and the + symbol is defined locally or was forced to be local because + of a version file, we just want to emit a RELATIVE reloc. + The entry in the global offset table will already have been + initialized in the relocate_section function. */ + if (info->shared + && (info->symbolic + || h->dynindx == -1 + || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)) + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) + { + BFD_ASSERT((h->got.offset & 1) != 0); + rela.r_info = ELF64_R_INFO (0, R_390_RELATIVE); + rela.r_addend = (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset); + } + else + { + BFD_ASSERT((h->got.offset & 1) == 0); + bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgot->contents + h->got.offset); + rela.r_info = ELF64_R_INFO (h->dynindx, R_390_GLOB_DAT); + rela.r_addend = 0; + } + + loc = (Elf64_External_Rela *) htab->srelgot->contents; + loc += htab->srelgot->reloc_count++; + bfd_elf64_swap_reloca_out (output_bfd, &rela, loc); + } + + if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) + { + Elf_Internal_Rela rela; + Elf64_External_Rela *loc; + + /* This symbols needs a copy reloc. Set it up. */ + + if (h->dynindx == -1 + || (h->root.type != bfd_link_hash_defined + && h->root.type != bfd_link_hash_defweak) + || htab->srelbss == NULL) + abort (); + + rela.r_offset = (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset); + rela.r_info = ELF64_R_INFO (h->dynindx, R_390_COPY); + rela.r_addend = 0; + loc = (Elf64_External_Rela *) htab->srelbss->contents; + loc += htab->srelbss->reloc_count++; + bfd_elf64_swap_reloca_out (output_bfd, &rela, loc); + } + + /* Mark some specially defined symbols as absolute. */ + if (strcmp (h->root.root.string, "_DYNAMIC") == 0 + || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0 + || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0) + sym->st_shndx = SHN_ABS; + + return true; +} + +/* Used to decide how to sort relocs in an optimal manner for the + dynamic linker, before writing them out. */ + +static enum elf_reloc_type_class +elf_s390_reloc_type_class (rela) + const Elf_Internal_Rela *rela; +{ + switch ((int) ELF64_R_TYPE (rela->r_info)) + { + case R_390_RELATIVE: + return reloc_class_relative; + case R_390_JMP_SLOT: + return reloc_class_plt; + case R_390_COPY: + return reloc_class_copy; + default: + return reloc_class_normal; + } +} + +/* Finish up the dynamic sections. */ + +static boolean +elf_s390_finish_dynamic_sections (output_bfd, info) + bfd *output_bfd; + struct bfd_link_info *info; +{ + struct elf_s390_link_hash_table *htab; + bfd *dynobj; + asection *sdyn; + + htab = elf_s390_hash_table (info); + dynobj = htab->elf.dynobj; + sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); + + if (htab->elf.dynamic_sections_created) + { + Elf64_External_Dyn *dyncon, *dynconend; + + if (sdyn == NULL || htab->sgot == NULL) + abort (); + + dyncon = (Elf64_External_Dyn *) sdyn->contents; + dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size); + for (; dyncon < dynconend; dyncon++) + { + Elf_Internal_Dyn dyn; + asection *s; + + bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn); + + switch (dyn.d_tag) + { + default: + continue; + + case DT_PLTGOT: + dyn.d_un.d_ptr = htab->sgot->output_section->vma; + break; + + case DT_JMPREL: + dyn.d_un.d_ptr = htab->srelplt->output_section->vma; + break; + + case DT_PLTRELSZ: + s = htab->srelplt->output_section; + if (s->_cooked_size != 0) + dyn.d_un.d_val = s->_cooked_size; + else + dyn.d_un.d_val = s->_raw_size; + break; + + case DT_RELASZ: + /* The procedure linkage table relocs (DT_JMPREL) should + not be included in the overall relocs (DT_RELA). + Therefore, we override the DT_RELASZ entry here to + make it not include the JMPREL relocs. Since the + linker script arranges for .rela.plt to follow all + other relocation sections, we don't have to worry + about changing the DT_RELA entry. */ + s = htab->srelplt->output_section; + if (s->_cooked_size != 0) + dyn.d_un.d_val -= s->_cooked_size; + else + dyn.d_un.d_val -= s->_raw_size; + break; + } + + bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); + } + + /* Fill in the special first entry in the procedure linkage table. */ + if (htab->splt && htab->splt->_raw_size > 0) + { + /* fill in blueprint for plt 0 entry */ + bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD0, + htab->splt->contents ); + bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD1, + htab->splt->contents +4 ); + bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD3, + htab->splt->contents +12 ); + bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD4, + htab->splt->contents +16 ); + bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD5, + htab->splt->contents +20 ); + bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD6, + htab->splt->contents + 24); + bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD7, + htab->splt->contents + 28 ); + /* Fixup relative address to start of GOT */ + bfd_put_32 (output_bfd, + (htab->sgotplt->output_section->vma + + htab->sgotplt->output_offset + - htab->splt->output_section->vma - 6)/2, + htab->splt->contents + 8); + } + elf_section_data (htab->splt->output_section) + ->this_hdr.sh_entsize = PLT_ENTRY_SIZE; + } + + if (htab->sgotplt) + { + /* Fill in the first three entries in the global offset table. */ + if (htab->sgotplt->_raw_size > 0) + { + bfd_put_64 (output_bfd, + (sdyn == NULL ? (bfd_vma) 0 + : sdyn->output_section->vma + sdyn->output_offset), + htab->sgotplt->contents); + /* One entry for shared object struct ptr. */ + bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 8); + /* One entry for _dl_runtime_resolve. */ + bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + 12); + } + + elf_section_data (htab->sgot->output_section) + ->this_hdr.sh_entsize = 8; + } + return true; +} + +static boolean +elf_s390_object_p (abfd) + bfd *abfd; +{ + return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_64); +} + +/* + * Why was the hash table entry size definition changed from + * ARCH_SIZE/8 to 4? This breaks the 64 bit dynamic linker and + * this is the only reason for the s390_elf64_size_info structure. + */ + +const struct elf_size_info s390_elf64_size_info = +{ + sizeof (Elf64_External_Ehdr), + sizeof (Elf64_External_Phdr), + sizeof (Elf64_External_Shdr), + sizeof (Elf64_External_Rel), + sizeof (Elf64_External_Rela), + sizeof (Elf64_External_Sym), + sizeof (Elf64_External_Dyn), + sizeof (Elf_External_Note), + 8, /* hash-table entry size */ + 1, /* internal relocations per external relocations */ + 64, /* arch_size */ + 8, /* file_align */ + ELFCLASS64, EV_CURRENT, + bfd_elf64_write_out_phdrs, + bfd_elf64_write_shdrs_and_ehdr, + bfd_elf64_write_relocs, + bfd_elf64_swap_symbol_out, + bfd_elf64_slurp_reloc_table, + bfd_elf64_slurp_symbol_table, + bfd_elf64_swap_dyn_in, + bfd_elf64_swap_dyn_out, + NULL, + NULL, + NULL, + NULL +}; + +#define TARGET_BIG_SYM bfd_elf64_s390_vec +#define TARGET_BIG_NAME "elf64-s390" +#define ELF_ARCH bfd_arch_s390 +#define ELF_MACHINE_CODE EM_S390 +#define ELF_MACHINE_ALT1 EM_S390_OLD +#define ELF_MAXPAGESIZE 0x1000 + +#define elf_backend_size_info s390_elf64_size_info + +#define elf_backend_can_gc_sections 1 +#define elf_backend_can_refcount 1 +#define elf_backend_want_got_plt 1 +#define elf_backend_plt_readonly 1 +#define elf_backend_want_plt_sym 0 +#define elf_backend_got_header_size 24 +#define elf_backend_plt_header_size PLT_ENTRY_SIZE +#define elf_backend_rela_normal 1 + +#define elf_info_to_howto elf_s390_info_to_howto + +#define bfd_elf64_bfd_is_local_label_name elf_s390_is_local_label_name +#define bfd_elf64_bfd_link_hash_table_create elf_s390_link_hash_table_create +#define bfd_elf64_bfd_reloc_type_lookup elf_s390_reloc_type_lookup + +#define elf_backend_adjust_dynamic_symbol elf_s390_adjust_dynamic_symbol +#define elf_backend_check_relocs elf_s390_check_relocs +#define elf_backend_copy_indirect_symbol elf_s390_copy_indirect_symbol +#define elf_backend_create_dynamic_sections elf_s390_create_dynamic_sections +#define elf_backend_finish_dynamic_sections elf_s390_finish_dynamic_sections +#define elf_backend_finish_dynamic_symbol elf_s390_finish_dynamic_symbol +#define elf_backend_gc_mark_hook elf_s390_gc_mark_hook +#define elf_backend_gc_sweep_hook elf_s390_gc_sweep_hook +#define elf_backend_reloc_type_class elf_s390_reloc_type_class +#define elf_backend_relocate_section elf_s390_relocate_section +#define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections +#define elf_backend_reloc_type_class elf_s390_reloc_type_class + +#define elf_backend_object_p elf_s390_object_p + +#include "elf64-target.h" diff --git a/contrib/binutils/bfd/elf64-sparc.c b/contrib/binutils/bfd/elf64-sparc.c index 78d2a56..d04a1d3 100644 --- a/contrib/binutils/bfd/elf64-sparc.c +++ b/contrib/binutils/bfd/elf64-sparc.c @@ -1,5 +1,5 @@ /* SPARC-specific support for 64-bit ELF - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -1385,9 +1385,8 @@ sparc64_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp) *namep = NULL; return true; } - else if (! *namep || ! **namep) - return true; - else + else if (*namep && **namep + && info->hash->creator->flavour == bfd_target_elf_flavour) { int i; struct sparc64_elf_app_reg *p; diff --git a/contrib/binutils/bfd/elf64-x86-64.c b/contrib/binutils/bfd/elf64-x86-64.c index 61d2c6e..b980344 100644 --- a/contrib/binutils/bfd/elf64-x86-64.c +++ b/contrib/binutils/bfd/elf64-x86-64.c @@ -1,5 +1,5 @@ /* X86-64 specific support for 64-bit ELF - Copyright 2000, 2001 Free Software Foundation, Inc. + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Jan Hubicka <jh@suse.cz>. This file is part of BFD, the Binary File Descriptor library. @@ -20,13 +20,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" #include "sysdep.h" +#include "bfdlink.h" #include "libbfd.h" #include "elf-bfd.h" #include "elf/x86-64.h" /* We use only the RELA entries. */ -#define USE_RELA +#define USE_RELA 1 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */ #define MINUS_ONE (~ (bfd_vma) 0) @@ -127,6 +128,12 @@ static void elf64_x86_64_info_to_howto static struct bfd_link_hash_table *elf64_x86_64_link_hash_table_create PARAMS ((bfd *)); static boolean elf64_x86_64_elf_object_p PARAMS ((bfd *abfd)); +static boolean create_got_section + PARAMS((bfd *, struct bfd_link_info *)); +static boolean elf64_x86_64_create_dynamic_sections + PARAMS((bfd *, struct bfd_link_info *)); +static void elf64_x86_64_copy_indirect_symbol + PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *)); static boolean elf64_x86_64_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *sec, const Elf_Internal_Rela *)); @@ -138,11 +145,15 @@ static boolean elf64_x86_64_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); -static struct bfd_hash_entry *elf64_x86_64_link_hash_newfunc +static struct bfd_hash_entry *link_hash_newfunc PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); static boolean elf64_x86_64_adjust_dynamic_symbol PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); +static boolean allocate_dynrelocs + PARAMS ((struct elf_link_hash_entry *, PTR)); +static boolean readonly_dynrelocs + PARAMS ((struct elf_link_hash_entry *, PTR)); static boolean elf64_x86_64_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); static boolean elf64_x86_64_relocate_section @@ -235,53 +246,54 @@ static const bfd_byte elf64_x86_64_plt_entry[PLT_ENTRY_SIZE] = }; /* The x86-64 linker needs to keep track of the number of relocs that - it decides to copy in check_relocs for each symbol. This is so - that it can discard PC relative relocs if it doesn't need them when - linking with -Bsymbolic. We store the information in a field - extending the regular ELF linker hash table. */ + it decides to copy as dynamic relocs in check_relocs for each symbol. + This is so that it can later discard them if they are found to be + unnecessary. We store the information in a field extending the + regular ELF linker hash table. */ -/* This structure keeps track of the number of PC relative relocs we - have copied for a given symbol. */ - -struct elf64_x86_64_pcrel_relocs_copied +struct elf64_x86_64_dyn_relocs { /* Next section. */ - struct elf64_x86_64_pcrel_relocs_copied *next; - /* A section in dynobj. */ - asection *section; - /* Number of relocs copied in this section. */ + struct elf64_x86_64_dyn_relocs *next; + + /* The input section of the reloc. */ + asection *sec; + + /* Total number of relocs copied for the input section. */ bfd_size_type count; + + /* Number of pc-relative relocs copied for the input section. */ + bfd_size_type pc_count; }; /* x86-64 ELF linker hash entry. */ struct elf64_x86_64_link_hash_entry { - struct elf_link_hash_entry root; + struct elf_link_hash_entry elf; - /* Number of PC relative relocs copied for this symbol. */ - struct elf64_x86_64_pcrel_relocs_copied *pcrel_relocs_copied; + /* Track dynamic relocs copied for this symbol. */ + struct elf64_x86_64_dyn_relocs *dyn_relocs; }; -/* x86-64 ELF linker hash table. */ +/* x86-64 ELF linker hash table. */ struct elf64_x86_64_link_hash_table { - struct elf_link_hash_table root; -}; - -/* Declare this now that the above structures are defined. */ + struct elf_link_hash_table elf; -static boolean elf64_x86_64_discard_copies - PARAMS ((struct elf64_x86_64_link_hash_entry *, PTR)); - -/* Traverse an x86-64 ELF linker hash table. */ + /* Short-cuts to get to dynamic linker sections. */ + asection *sgot; + asection *sgotplt; + asection *srelgot; + asection *splt; + asection *srelplt; + asection *sdynbss; + asection *srelbss; -#define elf64_x86_64_link_hash_traverse(table, func, info) \ - (elf_link_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \ - (info))) + /* Small local sym to section mapping cache. */ + struct sym_sec_cache sym_sec; +}; /* Get the x86-64 ELF linker hash table from a link_info structure. */ @@ -291,33 +303,32 @@ static boolean elf64_x86_64_discard_copies /* Create an entry in an x86-64 ELF linker hash table. */ static struct bfd_hash_entry * -elf64_x86_64_link_hash_newfunc (entry, table, string) +link_hash_newfunc (entry, table, string) struct bfd_hash_entry *entry; struct bfd_hash_table *table; const char *string; { - struct elf64_x86_64_link_hash_entry *ret = - (struct elf64_x86_64_link_hash_entry *) entry; - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == (struct elf64_x86_64_link_hash_entry *) NULL) - ret = ((struct elf64_x86_64_link_hash_entry *) - bfd_hash_allocate (table, - sizeof (struct elf64_x86_64_link_hash_entry))); - if (ret == (struct elf64_x86_64_link_hash_entry *) NULL) - return (struct bfd_hash_entry *) ret; + subclass. */ + if (entry == NULL) + { + entry = bfd_hash_allocate (table, + sizeof (struct elf64_x86_64_link_hash_entry)); + if (entry == NULL) + return entry; + } /* Call the allocation method of the superclass. */ - ret = ((struct elf64_x86_64_link_hash_entry *) - _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, - table, string)); - if (ret != (struct elf64_x86_64_link_hash_entry *) NULL) + entry = _bfd_elf_link_hash_newfunc (entry, table, string); + if (entry != NULL) { - ret->pcrel_relocs_copied = NULL; + struct elf64_x86_64_link_hash_entry *eh; + + eh = (struct elf64_x86_64_link_hash_entry *) entry; + eh->dyn_relocs = NULL; } - return (struct bfd_hash_entry *) ret; + return entry; } /* Create an X86-64 ELF linker hash table. */ @@ -329,18 +340,135 @@ elf64_x86_64_link_hash_table_create (abfd) struct elf64_x86_64_link_hash_table *ret; bfd_size_type amt = sizeof (struct elf64_x86_64_link_hash_table); - ret = ((struct elf64_x86_64_link_hash_table *) bfd_alloc (abfd, amt)); - if (ret == (struct elf64_x86_64_link_hash_table *) NULL) + ret = (struct elf64_x86_64_link_hash_table *) bfd_alloc (abfd, amt); + if (ret == NULL) return NULL; - if (! _bfd_elf_link_hash_table_init (&ret->root, abfd, - elf64_x86_64_link_hash_newfunc)) + if (! _bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc)) { bfd_release (abfd, ret); return NULL; } - return &ret->root.root; + ret->sgot = NULL; + ret->sgotplt = NULL; + ret->srelgot = NULL; + ret->splt = NULL; + ret->srelplt = NULL; + ret->sdynbss = NULL; + ret->srelbss = NULL; + ret->sym_sec.abfd = NULL; + + return &ret->elf.root; +} + +/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up + shortcuts to them in our hash table. */ + +static boolean +create_got_section (dynobj, info) + bfd *dynobj; + struct bfd_link_info *info; +{ + struct elf64_x86_64_link_hash_table *htab; + + if (! _bfd_elf_create_got_section (dynobj, info)) + return false; + + htab = elf64_x86_64_hash_table (info); + htab->sgot = bfd_get_section_by_name (dynobj, ".got"); + htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt"); + if (!htab->sgot || !htab->sgotplt) + abort (); + + htab->srelgot = bfd_make_section (dynobj, ".rela.got"); + if (htab->srelgot == NULL + || ! bfd_set_section_flags (dynobj, htab->srelgot, + (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS + | SEC_IN_MEMORY | SEC_LINKER_CREATED + | SEC_READONLY)) + || ! bfd_set_section_alignment (dynobj, htab->srelgot, 3)) + return false; + return true; +} + +/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and + .rela.bss sections in DYNOBJ, and set up shortcuts to them in our + hash table. */ + +static boolean +elf64_x86_64_create_dynamic_sections (dynobj, info) + bfd *dynobj; + struct bfd_link_info *info; +{ + struct elf64_x86_64_link_hash_table *htab; + + htab = elf64_x86_64_hash_table (info); + if (!htab->sgot && !create_got_section (dynobj, info)) + return false; + + if (!_bfd_elf_create_dynamic_sections (dynobj, info)) + return false; + + htab->splt = bfd_get_section_by_name (dynobj, ".plt"); + htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt"); + htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss"); + if (!info->shared) + htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss"); + + if (!htab->splt || !htab->srelplt || !htab->sdynbss + || (!info->shared && !htab->srelbss)) + abort (); + + return true; +} + +/* Copy the extra info we tack onto an elf_link_hash_entry. */ + +static void +elf64_x86_64_copy_indirect_symbol (dir, ind) + struct elf_link_hash_entry *dir, *ind; +{ + struct elf64_x86_64_link_hash_entry *edir, *eind; + + edir = (struct elf64_x86_64_link_hash_entry *) dir; + eind = (struct elf64_x86_64_link_hash_entry *) ind; + + if (eind->dyn_relocs != NULL) + { + if (edir->dyn_relocs != NULL) + { + struct elf64_x86_64_dyn_relocs **pp; + struct elf64_x86_64_dyn_relocs *p; + + if (ind->root.type == bfd_link_hash_indirect) + abort (); + + /* Add reloc counts against the weak sym to the strong sym + list. Merge any entries against the same section. */ + for (pp = &eind->dyn_relocs; (p = *pp) != NULL; ) + { + struct elf64_x86_64_dyn_relocs *q; + + for (q = edir->dyn_relocs; q != NULL; q = q->next) + if (q->sec == p->sec) + { + q->pc_count += p->pc_count; + q->count += p->count; + *pp = p->next; + break; + } + if (q == NULL) + pp = &p->next; + } + *pp = edir->dyn_relocs; + } + + edir->dyn_relocs = eind->dyn_relocs; + eind->dyn_relocs = NULL; + } + + _bfd_elf_link_hash_copy_indirect (dir, ind); } static boolean @@ -353,8 +481,8 @@ elf64_x86_64_elf_object_p (abfd) } /* Look through the relocs for a section during the first phase, and - allocate space in the global offset table or procedure linkage - table. */ + calculate needed space in the global offset table, procedure + linkage table, and dynamic reloc sections. */ static boolean elf64_x86_64_check_relocs (abfd, info, sec, relocs) @@ -363,25 +491,22 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs) asection *sec; const Elf_Internal_Rela *relocs; { - bfd *dynobj; + struct elf64_x86_64_link_hash_table *htab; Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; - bfd_signed_vma *local_got_refcounts; const Elf_Internal_Rela *rel; const Elf_Internal_Rela *rel_end; - asection *sgot; - asection *srelgot; asection *sreloc; if (info->relocateable) return true; - dynobj = elf_hash_table (info)->dynobj; + htab = elf64_x86_64_hash_table (info); symtab_hdr = &elf_tdata (abfd)->symtab_hdr; sym_hashes = elf_sym_hashes (abfd); - local_got_refcounts = elf_local_got_refcounts (abfd); - sgot = srelgot = sreloc = NULL; + sreloc = NULL; + rel_end = relocs + sec->reloc_count; for (rel = relocs; rel < rel_end; rel++) { @@ -389,75 +514,35 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs) struct elf_link_hash_entry *h; r_symndx = ELF64_R_SYM (rel->r_info); + + if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) + { + (*_bfd_error_handler) (_("%s: bad symbol index: %d"), + bfd_archive_filename (abfd), + r_symndx); + return false; + } + if (r_symndx < symtab_hdr->sh_info) h = NULL; else h = sym_hashes[r_symndx - symtab_hdr->sh_info]; - /* Some relocs require a global offset table. */ - if (dynobj == NULL) - { - switch (ELF64_R_TYPE (rel->r_info)) - { - case R_X86_64_GOT32: - case R_X86_64_GOTPCREL: - elf_hash_table (info)->dynobj = dynobj = abfd; - if (! _bfd_elf_create_got_section (dynobj, info)) - return false; - break; - } - } - switch (ELF64_R_TYPE (rel->r_info)) { - case R_X86_64_GOTPCREL: case R_X86_64_GOT32: + case R_X86_64_GOTPCREL: /* This symbol requires a global offset table entry. */ - - if (sgot == NULL) - { - sgot = bfd_get_section_by_name (dynobj, ".got"); - BFD_ASSERT (sgot != NULL); - } - - if (srelgot == NULL && (h != NULL || info->shared)) - { - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - if (srelgot == NULL) - { - srelgot = bfd_make_section (dynobj, ".rela.got"); - if (srelgot == NULL - || ! bfd_set_section_flags (dynobj, srelgot, - (SEC_ALLOC - | SEC_LOAD - | SEC_HAS_CONTENTS - | SEC_IN_MEMORY - | SEC_LINKER_CREATED - | SEC_READONLY)) - || ! bfd_set_section_alignment (dynobj, srelgot, 3)) - return false; - } - } - if (h != NULL) { - if (h->got.refcount == 0) - { - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) - return false; - } - - sgot->_raw_size += GOT_ENTRY_SIZE; - srelgot->_raw_size += sizeof (Elf64_External_Rela); - } h->got.refcount += 1; } else { + bfd_signed_vma *local_got_refcounts; + /* This is a global offset table entry for a local symbol. */ + local_got_refcounts = elf_local_got_refcounts (abfd); if (local_got_refcounts == NULL) { bfd_size_type size; @@ -470,19 +555,18 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs) return false; elf_local_got_refcounts (abfd) = local_got_refcounts; } - if (local_got_refcounts[r_symndx] == 0) - { - sgot->_raw_size += GOT_ENTRY_SIZE; - if (info->shared) - { - /* If we are generating a shared object, we need to - output a R_X86_64_RELATIVE reloc so that the dynamic - linker can adjust this GOT entry. */ - srelgot->_raw_size += sizeof (Elf64_External_Rela); - } - } local_got_refcounts[r_symndx] += 1; } + /* Fall through */ + + //case R_X86_64_GOTPCREL: + if (htab->sgot == NULL) + { + if (htab->elf.dynobj == NULL) + htab->elf.dynobj = abfd; + if (!create_got_section (htab->elf.dynobj, info)) + return false; + } break; case R_X86_64_PLT32: @@ -507,9 +591,23 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs) case R_X86_64_32: case R_X86_64_64: case R_X86_64_32S: + case R_X86_64_PC8: + case R_X86_64_PC16: case R_X86_64_PC32: - if (h != NULL) - h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF; + if (h != NULL && !info->shared) + { + /* If this reloc is in a read-only section, we might + need a copy reloc. We can't check reliably at this + stage whether the section is read-only, as input + sections have not yet been mapped to output sections. + Tentatively set the flag for now, and correct in + adjust_dynamic_symbol. */ + h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF; + + /* We may need a .plt entry if the function this reloc + refers to is in a shared lib. */ + h->plt.refcount += 1; + } /* If we are creating a shared library, and this is a reloc against a global symbol, or a non PC relative reloc @@ -520,27 +618,45 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs) including in the link (i.e., DEF_REGULAR is set). At this point we have not seen all the input files, so it is possible that DEF_REGULAR is not set now but will be set - later (it is never cleared). We account for that - possibility below by storing information in the - pcrel_relocs_copied field of the hash table entry. - A similar situation occurs when creating shared libraries - and symbol visibility changes render the symbol local. */ - if (info->shared - && (sec->flags & SEC_ALLOC) != 0 - && (((ELF64_R_TYPE (rel->r_info) != R_X86_64_PC8) - && (ELF64_R_TYPE (rel->r_info) != R_X86_64_PC16) - && (ELF64_R_TYPE (rel->r_info) != R_X86_64_PC32)) - || (h != NULL - && (! info->symbolic - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)))) + later (it is never cleared). In case of a weak definition, + DEF_REGULAR may be cleared later by a strong definition in + a shared library. We account for that possibility below by + storing information in the relocs_copied field of the hash + table entry. A similar situation occurs when creating + shared libraries and symbol visibility changes render the + symbol local. + + If on the other hand, we are creating an executable, we + may need to keep relocations for symbols satisfied by a + dynamic library if we manage to avoid copy relocs for the + symbol. */ + if ((info->shared + && (sec->flags & SEC_ALLOC) != 0 + && (((ELF64_R_TYPE (rel->r_info) != R_X86_64_PC8) + && (ELF64_R_TYPE (rel->r_info) != R_X86_64_PC16) + && (ELF64_R_TYPE (rel->r_info) != R_X86_64_PC32)) + || (h != NULL + && (! info->symbolic + || h->root.type == bfd_link_hash_defweak + || (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0)))) + || (!info->shared + && (sec->flags & SEC_ALLOC) != 0 + && h != NULL + && (h->root.type == bfd_link_hash_defweak + || (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0))) { - /* When creating a shared object, we must copy these - reloc types into the output file. We create a reloc - section in dynobj and make room for this reloc. */ + struct elf64_x86_64_dyn_relocs *p; + struct elf64_x86_64_dyn_relocs **head; + + /* We must copy these reloc types into the output file. + Create a reloc section in dynobj and make room for + this reloc. */ if (sreloc == NULL) { const char *name; + bfd *dynobj; name = (bfd_elf_string_from_elf_section (abfd, @@ -549,9 +665,19 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs) if (name == NULL) return false; - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (abfd, sec), - name + 5) == 0); + if (strncmp (name, ".rela", 5) != 0 + || strcmp (bfd_get_section_name (abfd, sec), + name + 5) != 0) + { + (*_bfd_error_handler) + (_("%s: bad relocation section name `%s\'"), + bfd_archive_filename (abfd), name); + } + + if (htab->elf.dynobj == NULL) + htab->elf.dynobj = abfd; + + dynobj = htab->elf.dynobj; sreloc = bfd_get_section_by_name (dynobj, name); if (sreloc == NULL) @@ -568,46 +694,51 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs) || ! bfd_set_section_alignment (dynobj, sreloc, 3)) return false; } - if (sec->flags & SEC_READONLY) - info->flags |= DF_TEXTREL; + elf_section_data (sec)->sreloc = sreloc; } - sreloc->_raw_size += sizeof (Elf64_External_Rela); - - /* If this is a global symbol, we count the number of PC - relative relocations we have entered for this symbol, - so that we can discard them later as necessary. Note - that this function is only called if we are using an - elf64_x86_64 linker hash table, which means that h is - really a pointer to an elf64_x86_64_link_hash_entry. */ - if (h != NULL - && ((ELF64_R_TYPE (rel->r_info) == R_X86_64_PC8) - || (ELF64_R_TYPE (rel->r_info) == R_X86_64_PC16) - || (ELF64_R_TYPE (rel->r_info) == R_X86_64_PC32))) + /* If this is a global symbol, we count the number of + relocations we need for this symbol. */ + if (h != NULL) { - struct elf64_x86_64_link_hash_entry *eh; - struct elf64_x86_64_pcrel_relocs_copied *p; - - eh = (struct elf64_x86_64_link_hash_entry *) h; + head = &((struct elf64_x86_64_link_hash_entry *) h)->dyn_relocs; + } + else + { + /* Track dynamic relocs needed for local syms too. + We really need local syms available to do this + easily. Oh well. */ + + asection *s; + s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, + sec, r_symndx); + if (s == NULL) + return false; - for (p = eh->pcrel_relocs_copied; p != NULL; p = p->next) - if (p->section == sreloc) - break; + head = ((struct elf64_x86_64_dyn_relocs **) + &elf_section_data (s)->local_dynrel); + } + p = *head; + if (p == NULL || p->sec != sec) + { + bfd_size_type amt = sizeof *p; + p = ((struct elf64_x86_64_dyn_relocs *) + bfd_alloc (htab->elf.dynobj, amt)); if (p == NULL) - { - p = ((struct elf64_x86_64_pcrel_relocs_copied *) - bfd_alloc (dynobj, (bfd_size_type) sizeof *p)); - if (p == NULL) - return false; - p->next = eh->pcrel_relocs_copied; - eh->pcrel_relocs_copied = p; - p->section = sreloc; - p->count = 0; - } - - ++p->count; + return false; + p->next = *head; + *head = p; + p->sec = sec; + p->count = 0; + p->pc_count = 0; } + + p->count += 1; + if (ELF64_R_TYPE (rel->r_info) == R_X86_64_PC8 + || ELF64_R_TYPE (rel->r_info) == R_X86_64_PC16 + || ELF64_R_TYPE (rel->r_info) == R_X86_64_PC32) + p->pc_count += 1; } break; @@ -624,6 +755,9 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs) if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return false; break; + + default: + break; } } @@ -637,7 +771,7 @@ static asection * elf64_x86_64_gc_mark_hook (abfd, info, rel, h, sym) bfd *abfd; struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Rela *rel ATTRIBUTE_UNUSED; + Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; Elf_Internal_Sym *sym; { @@ -677,7 +811,7 @@ elf64_x86_64_gc_mark_hook (abfd, info, rel, h, sym) static boolean elf64_x86_64_gc_sweep_hook (abfd, info, sec, relocs) bfd *abfd; - struct bfd_link_info *info ATTRIBUTE_UNUSED; + struct bfd_link_info *info; asection *sec; const Elf_Internal_Rela *relocs; { @@ -687,21 +821,13 @@ elf64_x86_64_gc_sweep_hook (abfd, info, sec, relocs) const Elf_Internal_Rela *rel, *relend; unsigned long r_symndx; struct elf_link_hash_entry *h; - bfd *dynobj; - asection *sgot; - asection *srelgot; + + elf_section_data (sec)->local_dynrel = NULL; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; sym_hashes = elf_sym_hashes (abfd); local_got_refcounts = elf_local_got_refcounts (abfd); - dynobj = elf_hash_table (info)->dynobj; - if (dynobj == NULL) - return true; - - sgot = bfd_get_section_by_name (dynobj, ".got"); - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - relend = relocs + sec->reloc_count; for (rel = relocs; rel < relend; rel++) switch (ELF64_R_TYPE (rel->r_info)) @@ -713,30 +839,53 @@ elf64_x86_64_gc_sweep_hook (abfd, info, sec, relocs) { h = sym_hashes[r_symndx - symtab_hdr->sh_info]; if (h->got.refcount > 0) - { - h->got.refcount -= 1; - if (h->got.refcount == 0) - { - sgot->_raw_size -= GOT_ENTRY_SIZE; - srelgot->_raw_size -= sizeof (Elf64_External_Rela); - } - } + h->got.refcount -= 1; } else if (local_got_refcounts != NULL) { if (local_got_refcounts[r_symndx] > 0) - { - local_got_refcounts[r_symndx] -= 1; - if (local_got_refcounts[r_symndx] == 0) - { - sgot->_raw_size -= GOT_ENTRY_SIZE; - if (info->shared) - srelgot->_raw_size -= sizeof (Elf64_External_Rela); - } - } + local_got_refcounts[r_symndx] -= 1; } break; + case R_X86_64_8: + case R_X86_64_16: + case R_X86_64_32: + case R_X86_64_64: + case R_X86_64_32S: + case R_X86_64_PC8: + case R_X86_64_PC16: + case R_X86_64_PC32: + r_symndx = ELF64_R_SYM (rel->r_info); + if (r_symndx >= symtab_hdr->sh_info) + { + struct elf64_x86_64_link_hash_entry *eh; + struct elf64_x86_64_dyn_relocs **pp; + struct elf64_x86_64_dyn_relocs *p; + + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + + if (!info->shared && h->plt.refcount > 0) + h->plt.refcount -= 1; + + eh = (struct elf64_x86_64_link_hash_entry *) h; + + for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) + if (p->sec == sec) + { + if (ELF64_R_TYPE (rel->r_info) == R_X86_64_PC8 + || ELF64_R_TYPE (rel->r_info) == R_X86_64_PC16 + || ELF64_R_TYPE (rel->r_info) == R_X86_64_PC32) + p->pc_count -= 1; + p->count -= 1; + if (p->count == 0) + *pp = p->next; + break; + } + } + break; + + case R_X86_64_PLT32: r_symndx = ELF64_R_SYM (rel->r_info); if (r_symndx >= symtab_hdr->sh_info) @@ -765,33 +914,24 @@ elf64_x86_64_adjust_dynamic_symbol (info, h) struct bfd_link_info *info; struct elf_link_hash_entry *h; { - bfd *dynobj; + struct elf64_x86_64_link_hash_table *htab; + struct elf64_x86_64_link_hash_entry * eh; + struct elf64_x86_64_dyn_relocs *p; asection *s; unsigned int power_of_two; - dynobj = elf_hash_table (info)->dynobj; - - /* Make sure we know what is going on here. */ - BFD_ASSERT (dynobj != NULL - && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) - || h->weakdef != NULL - || ((h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_REF_REGULAR) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0))); - /* If this is a function, put it in the procedure linkage table. We will fill in the contents of the procedure linkage table later, when we know the address of the .got section. */ if (h->type == STT_FUNC || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) { - if ((! info->shared - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0) - || (info->shared && h->plt.refcount <= 0)) + if (h->plt.refcount <= 0 + || (! info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0 + && h->root.type != bfd_link_hash_undefweak + && h->root.type != bfd_link_hash_undefined)) { /* This case can occur if we saw a PLT32 reloc in an input file, but the symbol was never referred to by a dynamic @@ -800,55 +940,16 @@ elf64_x86_64_adjust_dynamic_symbol (info, h) linkage table, and we can just do a PC32 reloc instead. */ h->plt.offset = (bfd_vma) -1; h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; - return true; - } - - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) - return false; - } - - s = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (s != NULL); - - /* If this is the first .plt entry, make room for the special - first entry. */ - if (s->_raw_size == 0) - s->_raw_size = PLT_ENTRY_SIZE; - - /* If this symbol is not defined in a regular file, and we are - not generating a shared library, then set the symbol to this - location in the .plt. This is required to make function - pointers compare as equal between the normal executable and - the shared library. */ - if (! info->shared - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - h->root.u.def.section = s; - h->root.u.def.value = s->_raw_size; } - h->plt.offset = s->_raw_size; - - /* Make room for this entry. */ - s->_raw_size += PLT_ENTRY_SIZE; - - /* We also need to make an entry in the .got.plt section, which - will be placed in the .got section by the linker script. */ - s = bfd_get_section_by_name (dynobj, ".got.plt"); - BFD_ASSERT (s != NULL); - s->_raw_size += GOT_ENTRY_SIZE; - - /* We also need to make an entry in the .rela.plt section. */ - s = bfd_get_section_by_name (dynobj, ".rela.plt"); - BFD_ASSERT (s != NULL); - s->_raw_size += sizeof (Elf64_External_Rela); - return true; } else + /* It's possible that we incorrectly decided a .plt reloc was + needed for an R_X86_64_PC32 reloc to a non-function sym in + check_relocs. We can't decide accurately between function and + non-function syms in check-relocs; Objects loaded later in + the link may change h->type. So fix it now. */ h->plt.offset = (bfd_vma) -1; /* If this is a weak symbol, and there is a real definition, the @@ -878,6 +979,29 @@ elf64_x86_64_adjust_dynamic_symbol (info, h) if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0) return true; + /* If -z nocopyreloc was given, we won't generate them either. */ + if (info->nocopyreloc) + { + h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF; + return true; + } + + eh = (struct elf64_x86_64_link_hash_entry *) h; + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + s = p->sec->output_section; + if (s != NULL && (s->flags & SEC_READONLY) != 0) + break; + } + + /* If we didn't find any dynamic relocs in read-only sections, then + we'll be keeping the dynamic relocs and avoiding the copy reloc. */ + if (p == NULL) + { + h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF; + return true; + } + /* We must allocate the symbol in our .dynbss section, which will become part of the .bss section of the executable. There will be an entry for this symbol in the .dynsym section. The dynamic @@ -888,20 +1012,14 @@ elf64_x86_64_adjust_dynamic_symbol (info, h) both the dynamic object and the regular object will refer to the same memory location for the variable. */ - s = bfd_get_section_by_name (dynobj, ".dynbss"); - BFD_ASSERT (s != NULL); + htab = elf64_x86_64_hash_table (info); /* We must generate a R_X86_64_COPY reloc to tell the dynamic linker to copy the initial value out of the dynamic object and into the - runtime process image. We need to remember the offset into the - .rela.bss section we are going to use. */ + runtime process image. */ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) { - asection *srel; - - srel = bfd_get_section_by_name (dynobj, ".rela.bss"); - BFD_ASSERT (srel != NULL); - srel->_raw_size += sizeof (Elf64_External_Rela); + htab->srelbss->_raw_size += sizeof (Elf64_External_Rela); h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY; } @@ -915,10 +1033,11 @@ elf64_x86_64_adjust_dynamic_symbol (info, h) power_of_two = 4; /* Apply the required alignment. */ + s = htab->sdynbss; s->_raw_size = BFD_ALIGN (s->_raw_size, (bfd_size_type) (1 << power_of_two)); - if (power_of_two > bfd_get_section_alignment (dynobj, s)) + if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s)) { - if (! bfd_set_section_alignment (dynobj, s, power_of_two)) + if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two)) return false; } @@ -932,6 +1051,223 @@ elf64_x86_64_adjust_dynamic_symbol (info, h) return true; } +/* This is the condition under which elf64_x86_64_finish_dynamic_symbol + will be called from elflink.h. If elflink.h doesn't call our + finish_dynamic_symbol routine, we'll need to do something about + initializing any .plt and .got entries in elf64_x86_64_relocate_section. */ +#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \ + ((DYN) \ + && ((INFO)->shared \ + || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ + && ((H)->dynindx != -1 \ + || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) + +/* Allocate space in .plt, .got and associated reloc sections for + dynamic relocs. */ + +static boolean +allocate_dynrelocs (h, inf) + struct elf_link_hash_entry *h; + PTR inf; +{ + struct bfd_link_info *info; + struct elf64_x86_64_link_hash_table *htab; + struct elf64_x86_64_link_hash_entry *eh; + struct elf64_x86_64_dyn_relocs *p; + + if (h->root.type == bfd_link_hash_indirect) + return true; + + if (h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + info = (struct bfd_link_info *) inf; + htab = elf64_x86_64_hash_table (info); + + if (htab->elf.dynamic_sections_created + && h->plt.refcount > 0) + { + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) + { + if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + return false; + } + + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h)) + { + asection *s = htab->splt; + + /* If this is the first .plt entry, make room for the special + first entry. */ + if (s->_raw_size == 0) + s->_raw_size += PLT_ENTRY_SIZE; + + h->plt.offset = s->_raw_size; + + /* If this symbol is not defined in a regular file, and we are + not generating a shared library, then set the symbol to this + location in the .plt. This is required to make function + pointers compare as equal between the normal executable and + the shared library. */ + if (! info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) + { + h->root.u.def.section = s; + h->root.u.def.value = h->plt.offset; + } + + /* Make room for this entry. */ + s->_raw_size += PLT_ENTRY_SIZE; + + /* We also need to make an entry in the .got.plt section, which + will be placed in the .got section by the linker script. */ + htab->sgotplt->_raw_size += GOT_ENTRY_SIZE; + + /* We also need to make an entry in the .rela.plt section. */ + htab->srelplt->_raw_size += sizeof (Elf64_External_Rela); + } + else + { + h->plt.offset = (bfd_vma) -1; + h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; + } + } + else + { + h->plt.offset = (bfd_vma) -1; + h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; + } + + if (h->got.refcount > 0) + { + asection *s; + boolean dyn; + + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) + { + if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + return false; + } + + s = htab->sgot; + h->got.offset = s->_raw_size; + s->_raw_size += GOT_ENTRY_SIZE; + dyn = htab->elf.dynamic_sections_created; + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)) + htab->srelgot->_raw_size += sizeof (Elf64_External_Rela); + } + else + h->got.offset = (bfd_vma) -1; + + eh = (struct elf64_x86_64_link_hash_entry *) h; + if (eh->dyn_relocs == NULL) + return true; + + /* In the shared -Bsymbolic case, discard space allocated for + dynamic pc-relative relocs against symbols which turn out to be + defined in regular objects. For the normal shared case, discard + space for pc-relative relocs that have become local due to symbol + visibility changes. */ + + if (info->shared) + { + if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 + && ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0 + || info->symbolic)) + { + struct elf64_x86_64_dyn_relocs **pp; + + for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) + { + p->count -= p->pc_count; + p->pc_count = 0; + if (p->count == 0) + *pp = p->next; + else + pp = &p->next; + } + } + } + else + { + /* For the non-shared case, discard space for relocs against + symbols which turn out to need copy relocs or are not + dynamic. */ + + if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0 + && (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) + || (htab->elf.dynamic_sections_created + && (h->root.type == bfd_link_hash_undefweak + || h->root.type == bfd_link_hash_undefined)))) + { + /* Make sure this symbol is output as a dynamic symbol. + Undefined weak syms won't yet be marked as dynamic. */ + if (h->dynindx == -1 + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) + { + if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + return false; + } + + /* If that succeeded, we know we'll be keeping all the + relocs. */ + if (h->dynindx != -1) + goto keep; + } + + eh->dyn_relocs = NULL; + + keep: ; + } + + /* Finally, allocate space. */ + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + asection *sreloc = elf_section_data (p->sec)->sreloc; + sreloc->_raw_size += p->count * sizeof (Elf64_External_Rela); + } + + return true; +} + +/* Find any dynamic relocs that apply to read-only sections. */ + +static boolean +readonly_dynrelocs (h, inf) + struct elf_link_hash_entry *h; + PTR inf; +{ + struct elf64_x86_64_link_hash_entry *eh; + struct elf64_x86_64_dyn_relocs *p; + + if (h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + eh = (struct elf64_x86_64_link_hash_entry *) h; + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + { + struct bfd_link_info *info = (struct bfd_link_info *) inf; + + info->flags |= DF_TEXTREL; + + /* Not an error, just cut short the traversal. */ + return false; + } + } + return true; +} + /* Set the sizes of the dynamic sections. */ static boolean @@ -939,110 +1275,140 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info) bfd *output_bfd ATTRIBUTE_UNUSED; struct bfd_link_info *info; { + struct elf64_x86_64_link_hash_table *htab; bfd *dynobj; asection *s; - boolean plt; boolean relocs; + bfd *ibfd; - dynobj = elf_hash_table (info)->dynobj; - BFD_ASSERT (dynobj != NULL); + htab = elf64_x86_64_hash_table (info); + dynobj = htab->elf.dynobj; + if (dynobj == NULL) + abort (); - if (elf_hash_table (info)->dynamic_sections_created) + if (htab->elf.dynamic_sections_created) { /* Set the contents of the .interp section to the interpreter. */ if (! info->shared) { s = bfd_get_section_by_name (dynobj, ".interp"); - BFD_ASSERT (s != NULL); + if (s == NULL) + abort (); s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER; s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; } } - else - { - /* We may have created entries in the .rela.got section. - However, if we are not creating the dynamic sections, we will - not actually use these entries. Reset the size of .rela.got, - which will cause it to get stripped from the output file - below. */ - s = bfd_get_section_by_name (dynobj, ".rela.got"); - if (s != NULL) - s->_raw_size = 0; - } - /* If this is a -Bsymbolic shared link, then we need to discard all - PC relative relocs against symbols defined in a regular object. - We allocated space for them in the check_relocs routine, but we - will not fill them in in the relocate_section routine. */ - if (info->shared) - elf64_x86_64_link_hash_traverse (elf64_x86_64_hash_table (info), - elf64_x86_64_discard_copies, - (PTR) info); - - /* The check_relocs and adjust_dynamic_symbol entry points have - determined the sizes of the various dynamic sections. Allocate - memory for them. */ - plt = relocs = false; - for (s = dynobj->sections; s != NULL; s = s->next) + /* Set up .got offsets for local syms, and space for local dynamic + relocs. */ + for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) { - const char *name; - boolean strip; + bfd_signed_vma *local_got; + bfd_signed_vma *end_local_got; + bfd_size_type locsymcount; + Elf_Internal_Shdr *symtab_hdr; + asection *srel; - if ((s->flags & SEC_LINKER_CREATED) == 0) + if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) continue; - /* It's OK to base decisions on the section name, because none - of the dynobj section names depend upon the input files. */ - name = bfd_get_section_name (dynobj, s); - - strip = false; - if (strcmp (name, ".plt") == 0) + for (s = ibfd->sections; s != NULL; s = s->next) { - if (s->_raw_size == 0) - { - /* Strip this section if we don't need it; see the - comment below. */ - strip = true; - } - else + struct elf64_x86_64_dyn_relocs *p; + + for (p = *((struct elf64_x86_64_dyn_relocs **) + &elf_section_data (s)->local_dynrel); + p != NULL; + p = p->next) { - /* Remember whether there is a PLT. */ - plt = true; + if (!bfd_is_abs_section (p->sec) + && bfd_is_abs_section (p->sec->output_section)) + { + /* Input section has been discarded, either because + it is a copy of a linkonce section or due to + linker script /DISCARD/, so we'll be discarding + the relocs too. */ + } + else if (p->count != 0) + { + srel = elf_section_data (p->sec)->sreloc; + srel->_raw_size += p->count * sizeof (Elf64_External_Rela); + if ((p->sec->output_section->flags & SEC_READONLY) != 0) + info->flags |= DF_TEXTREL; + + } } } - else if (strncmp (name, ".rela", 5) == 0) + + local_got = elf_local_got_refcounts (ibfd); + if (!local_got) + continue; + + symtab_hdr = &elf_tdata (ibfd)->symtab_hdr; + locsymcount = symtab_hdr->sh_info; + end_local_got = local_got + locsymcount; + s = htab->sgot; + srel = htab->srelgot; + for (; local_got < end_local_got; ++local_got) { - if (s->_raw_size == 0) + if (*local_got > 0) { - /* If we don't need this section, strip it from the - output file. This is mostly to handle .rela.bss and - .rela.plt. We must create both sections in - create_dynamic_sections, because they must be created - before the linker maps input sections to output - sections. The linker does that before - adjust_dynamic_symbol is called, and it is that - function which decides whether anything needs to go - into these sections. */ - strip = true; + *local_got = s->_raw_size; + s->_raw_size += GOT_ENTRY_SIZE; + if (info->shared) + srel->_raw_size += sizeof (Elf64_External_Rela); } else - { - if (strcmp (name, ".rela.plt") != 0) - relocs = true; + *local_got = (bfd_vma) -1; + } + } - /* We use the reloc_count field as a counter if we need - to copy relocs into the output file. */ - s->reloc_count = 0; - } + /* Allocate global sym .plt and .got entries, and space for global + sym dynamic relocs. */ + elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info); + + /* We now have determined the sizes of the various dynamic sections. + Allocate memory for them. */ + relocs = false; + for (s = dynobj->sections; s != NULL; s = s->next) + { + if ((s->flags & SEC_LINKER_CREATED) == 0) + continue; + + if (s == htab->splt + || s == htab->sgot + || s == htab->sgotplt) + { + /* Strip this section if we don't need it; see the + comment below. */ } - else if (strncmp (name, ".got", 4) != 0) + else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0) + { + if (s->_raw_size != 0 && s != htab->srelplt) + relocs = true; + + /* We use the reloc_count field as a counter if we need + to copy relocs into the output file. */ + s->reloc_count = 0; + } + else { /* It's not one of our sections, so don't allocate space. */ continue; } - if (strip) + if (s->_raw_size == 0) { + /* If we don't need this section, strip it from the + output file. This is mostly to handle .rela.bss and + .rela.plt. We must create both sections in + create_dynamic_sections, because they must be created + before the linker maps input sections to output + sections. The linker does that before + adjust_dynamic_symbol is called, and it is that + function which decides whether anything needs to go + into these sections. */ + _bfd_strip_section_from_output (info, s); continue; } @@ -1053,11 +1419,11 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info) but this way if it does, we get a R_X86_64_NONE reloc instead of garbage. */ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size); - if (s->contents == NULL && s->_raw_size != 0) + if (s->contents == NULL) return false; } - if (elf_hash_table (info)->dynamic_sections_created) + if (htab->elf.dynamic_sections_created) { /* Add some entries to the .dynamic section. We fill in the values later, in elf64_x86_64_finish_dynamic_sections, but we @@ -1073,7 +1439,7 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info) return false; } - if (plt) + if (htab->splt->_raw_size != 0) { if (!add_dynamic_entry (DT_PLTGOT, 0) || !add_dynamic_entry (DT_PLTRELSZ, 0) @@ -1088,12 +1454,18 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info) || !add_dynamic_entry (DT_RELASZ, 0) || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela))) return false; - } - if ((info->flags & DF_TEXTREL) != 0) - { - if (!add_dynamic_entry (DT_TEXTREL, 0)) - return false; + /* If any dynamic relocs apply to a read-only section, + then we need a DT_TEXTREL entry. */ + if ((info->flags & DF_TEXTREL) == 0) + elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, + (PTR) info); + + if ((info->flags & DF_TEXTREL) != 0) + { + if (!add_dynamic_entry (DT_TEXTREL, 0)) + return false; + } } } #undef add_dynamic_entry @@ -1101,40 +1473,6 @@ elf64_x86_64_size_dynamic_sections (output_bfd, info) return true; } -/* This function is called via elf64_x86_64_link_hash_traverse if we are - creating a shared object. In the -Bsymbolic case, it discards the - space allocated to copy PC relative relocs against symbols which - are defined in regular objects. For the normal non-symbolic case, - we also discard space for relocs that have become local due to - symbol visibility changes. We allocated space for them in the - check_relocs routine, but we won't fill them in in the - relocate_section routine. */ - -static boolean -elf64_x86_64_discard_copies (h, inf) - struct elf64_x86_64_link_hash_entry *h; - PTR inf; -{ - struct elf64_x86_64_pcrel_relocs_copied *s; - struct bfd_link_info *info = (struct bfd_link_info *) inf; - - if (h->root.root.type == bfd_link_hash_warning) - h = (struct elf64_x86_64_link_hash_entry *) h->root.root.u.i.link; - - /* If a symbol has been forced local or we have found a regular - definition for the symbolic link case, then we won't be needing - any relocs. */ - if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 - && ((h->root.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0 - || info->symbolic)) - { - for (s = h->pcrel_relocs_copied; s != NULL; s = s->next) - s->section->_raw_size -= s->count * sizeof (Elf64_External_Rela); - } - - return true; -} - /* Relocate an x86_64 ELF section. */ static boolean @@ -1149,31 +1487,24 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, Elf_Internal_Sym *local_syms; asection **local_sections; { - bfd *dynobj; + struct elf64_x86_64_link_hash_table *htab; Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; bfd_vma *local_got_offsets; - asection *sgot; - asection *splt; - asection *sreloc; - Elf_Internal_Rela *rela; + Elf_Internal_Rela *rel; Elf_Internal_Rela *relend; - dynobj = elf_hash_table (info)->dynobj; + if (info->relocateable) + return true; + + htab = elf64_x86_64_hash_table (info); symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; sym_hashes = elf_sym_hashes (input_bfd); local_got_offsets = elf_local_got_offsets (input_bfd); - sreloc = splt = sgot = NULL; - if (dynobj != NULL) - { - splt = bfd_get_section_by_name (dynobj, ".plt"); - sgot = bfd_get_section_by_name (dynobj, ".got"); - } - - rela = relocs; + rel = relocs; relend = relocs + input_section->reloc_count; - for (; rela < relend; rela++) + for (; rel < relend; rel++) { int r_type; reloc_howto_type *howto; @@ -1181,52 +1512,34 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, struct elf_link_hash_entry *h; Elf_Internal_Sym *sym; asection *sec; + bfd_vma off; bfd_vma relocation; + boolean unresolved_reloc; bfd_reloc_status_type r; - unsigned int indx; - r_type = ELF64_R_TYPE (rela->r_info); + r_type = ELF64_R_TYPE (rel->r_info); if (r_type == (int) R_X86_64_GNU_VTINHERIT || r_type == (int) R_X86_64_GNU_VTENTRY) continue; - if ((indx = (unsigned) r_type) >= R_X86_64_max) + if (r_type < 0 || r_type >= R_X86_64_max) { bfd_set_error (bfd_error_bad_value); return false; } - howto = x86_64_elf_howto_table + indx; - - r_symndx = ELF64_R_SYM (rela->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sec = local_sections[r_symndx]; - rela->r_addend += sec->output_offset + sym->st_value; - } - } - - continue; - } - /* This is a final link. */ + howto = x86_64_elf_howto_table + r_type; + r_symndx = ELF64_R_SYM (rel->r_info); h = NULL; sym = NULL; sec = NULL; + unresolved_reloc = false; if (r_symndx < symtab_hdr->sh_info) { sym = local_syms + r_symndx; sec = local_sections[r_symndx]; - relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rela); + + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); } else { @@ -1234,50 +1547,18 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, while (h->root.type == bfd_link_hash_indirect || h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; + if (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) { sec = h->root.u.def.section; - if ((r_type == R_X86_64_PLT32 - && splt != NULL - && h->plt.offset != (bfd_vma) -1) - || ((r_type == R_X86_64_GOT32 || r_type == R_X86_64_GOTPCREL) - && elf_hash_table (info)->dynamic_sections_created - && (!info->shared - || (! info->symbolic && h->dynindx != -1) - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0)) - || (info->shared - && ((! info->symbolic && h->dynindx != -1) - || (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_REGULAR) == 0) - && (r_type == R_X86_64_8 - || r_type == R_X86_64_16 - || r_type == R_X86_64_32 - || r_type == R_X86_64_64 - || r_type == R_X86_64_PC8 - || r_type == R_X86_64_PC16 - || r_type == R_X86_64_PC32) - && ((input_section->flags & SEC_ALLOC) != 0 - /* DWARF will emit R_X86_64_32 relocations in its - sections against symbols defined externally - in shared libraries. We can't do anything - with them here. */ - || ((input_section->flags & SEC_DEBUGGING) != 0 - && (h->elf_link_hash_flags - & ELF_LINK_HASH_DEF_DYNAMIC) != 0)))) - { - /* In these cases, we don't need the relocation - value. We check specially because in some - obscure cases sec->output_section will be NULL. */ - relocation = 0; - } - else if (sec->output_section == NULL) + if (sec->output_section == NULL) { - (*_bfd_error_handler) - (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"), - bfd_archive_filename (input_bfd), h->root.root.string, - bfd_get_section_name (input_bfd, input_section)); + /* Set a flag that will be cleared later if we find a + relocation value for this symbol. output_section + is typically NULL for symbols satisfied by a shared + library. */ + unresolved_reloc = true; relocation = 0; } else @@ -1296,14 +1577,13 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, { if (! ((*info->callbacks->undefined_symbol) (info, h->root.root.string, input_bfd, - input_section, rela->r_offset, + input_section, rel->r_offset, (!info->shared || info->no_undefined || ELF_ST_VISIBILITY (h->other))))) return false; relocation = 0; } } - /* When generating a shared object, the relocations handled here are copied into the output file to be resolved at run time. */ switch (r_type) @@ -1313,16 +1593,21 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, offset table. */ case R_X86_64_GOTPCREL: /* Use global offset table as symbol value. */ - BFD_ASSERT (sgot != NULL); + if (htab->sgot == NULL) + abort (); if (h != NULL) { - bfd_vma off = h->got.offset; - BFD_ASSERT (off != (bfd_vma) -1); + boolean dyn; + + off = h->got.offset; + dyn = htab->elf.dynamic_sections_created; - if (! elf_hash_table (info)->dynamic_sections_created + if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h) || (info->shared - && (info->symbolic || h->dynindx == -1) + && (info->symbolic + || h->dynindx == -1 + || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)) && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) { /* This is actually a static link, or it is a -Bsymbolic @@ -1341,21 +1626,17 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, else { bfd_put_64 (output_bfd, relocation, - sgot->contents + off); + htab->sgot->contents + off); h->got.offset |= 1; } } - if (r_type == R_X86_64_GOTPCREL) - relocation = sgot->output_section->vma + sgot->output_offset + off; else - relocation = sgot->output_offset + off; + unresolved_reloc = false; } else { - bfd_vma off; - - BFD_ASSERT (local_got_offsets != NULL - && local_got_offsets[r_symndx] != (bfd_vma) -1); + if (local_got_offsets == NULL) + abort (); off = local_got_offsets[r_symndx]; @@ -1366,39 +1647,42 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, off &= ~1; else { - bfd_put_64 (output_bfd, relocation, sgot->contents + off); + bfd_put_64 (output_bfd, relocation, + htab->sgot->contents + off); if (info->shared) { asection *srelgot; Elf_Internal_Rela outrel; + Elf64_External_Rela *loc; /* We need to generate a R_X86_64_RELATIVE reloc for the dynamic linker. */ - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - BFD_ASSERT (srelgot != NULL); + srelgot = htab->srelgot; + if (srelgot == NULL) + abort (); - outrel.r_offset = (sgot->output_section->vma - + sgot->output_offset + outrel.r_offset = (htab->sgot->output_section->vma + + htab->sgot->output_offset + off); outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE); outrel.r_addend = relocation; - bfd_elf64_swap_reloca_out (output_bfd, &outrel, - (((Elf64_External_Rela *) - srelgot->contents) - + srelgot->reloc_count)); - ++srelgot->reloc_count; + loc = (Elf64_External_Rela *) srelgot->contents; + loc += srelgot->reloc_count++; + bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); } local_got_offsets[r_symndx] |= 1; } - - if (r_type == R_X86_64_GOTPCREL) - relocation = sgot->output_section->vma + sgot->output_offset + off; - else - relocation = sgot->output_offset + off; } + if (off >= (bfd_vma) -2) + abort (); + + relocation = htab->sgot->output_offset + off; + if (r_type == R_X86_64_GOTPCREL) + relocation += htab->sgot->output_section->vma; + break; case R_X86_64_PLT32: @@ -1410,7 +1694,8 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, if (h == NULL) break; - if (h->plt.offset == (bfd_vma) -1 || splt == NULL) + if (h->plt.offset == (bfd_vma) -1 + || htab->splt == NULL) { /* We didn't make a PLT entry for this symbol. This happens when statically linking PIC code, or when @@ -1418,62 +1703,64 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, break; } - relocation = (splt->output_section->vma - + splt->output_offset + relocation = (htab->splt->output_section->vma + + htab->splt->output_offset + h->plt.offset); + unresolved_reloc = false; break; case R_X86_64_PC8: case R_X86_64_PC16: case R_X86_64_PC32: - if (h == NULL || h->dynindx == -1 - || (info->symbolic - && h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) - break; - /* Fall through. */ case R_X86_64_8: case R_X86_64_16: case R_X86_64_32: case R_X86_64_64: /* FIXME: The ABI says the linker should make sure the value is the same when it's zeroextended to 64 bit. */ - if (info->shared - && r_symndx != 0 - && (input_section->flags & SEC_ALLOC) != 0) + + /* r_symndx will be zero only for relocs against symbols + from removed linkonce sections, or sections discarded by + a linker script. */ + if (r_symndx == 0 + || (input_section->flags & SEC_ALLOC) == 0) + break; + + if ((info->shared + && ((r_type != R_X86_64_PC8 + && r_type != R_X86_64_PC16 + && r_type != R_X86_64_PC32) + || (h != NULL + && h->dynindx != -1 + && (! info->symbolic + || (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0)))) + || (!info->shared + && h != NULL + && h->dynindx != -1 + && (h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0 + && (((h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_DYNAMIC) != 0 + && (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0) + || h->root.type == bfd_link_hash_undefweak + || h->root.type == bfd_link_hash_undefined))) { Elf_Internal_Rela outrel; boolean skip, relocate; + asection *sreloc; + Elf64_External_Rela *loc; /* When generating a shared object, these relocations are copied into the output file to be resolved at run time. */ - if (sreloc == NULL) - { - const char *name; - - name = (bfd_elf_string_from_elf_section - (input_bfd, - elf_elfheader (input_bfd)->e_shstrndx, - elf_section_data (input_section)->rel_hdr.sh_name)); - if (name == NULL) - return false; - - BFD_ASSERT (strncmp (name, ".rela", 5) == 0 - && strcmp (bfd_get_section_name (input_bfd, - input_section), - name + 5) == 0); - - sreloc = bfd_get_section_by_name (dynobj, name); - BFD_ASSERT (sreloc != NULL); - } - skip = false; relocate = false; outrel.r_offset = _bfd_elf_section_offset (output_bfd, info, input_section, - rela->r_offset); + rel->r_offset); if (outrel.r_offset == (bfd_vma) -1) skip = true; else if (outrel.r_offset == (bfd_vma) -2) @@ -1484,65 +1771,37 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, if (skip) memset (&outrel, 0, sizeof outrel); + /* h->dynindx may be -1 if this symbol was marked to become local. */ else if (h != NULL - && ((! info->symbolic && h->dynindx != -1) + && h->dynindx != -1 + && (r_type == R_X86_64_PC8 + || r_type == R_X86_64_PC16 + || r_type == R_X86_64_PC32 + || !info->shared + || !info->symbolic || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)) { - BFD_ASSERT (h->dynindx != -1); outrel.r_info = ELF64_R_INFO (h->dynindx, r_type); - outrel.r_addend = relocation + rela->r_addend; + outrel.r_addend = rel->r_addend; } else { - if (r_type == R_X86_64_64) - { - relocate = true; - outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE); - outrel.r_addend = relocation + rela->r_addend; - } - else - { - long sindx; - - if (h == NULL) - sec = local_sections[r_symndx]; - else - { - BFD_ASSERT (h->root.type == bfd_link_hash_defined - || (h->root.type - == bfd_link_hash_defweak)); - sec = h->root.u.def.section; - } - if (sec != NULL && bfd_is_abs_section (sec)) - sindx = 0; - else if (sec == NULL || sec->owner == NULL) - { - bfd_set_error (bfd_error_bad_value); - return false; - } - else - { - asection *osec; - - osec = sec->output_section; - sindx = elf_section_data (osec)->dynindx; - BFD_ASSERT (sindx > 0); - } - - outrel.r_info = ELF64_R_INFO (sindx, r_type); - outrel.r_addend = relocation + rela->r_addend; - } - + /* This symbol is local, or marked to become local. */ + relocate = true; + outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE); + outrel.r_addend = relocation + rel->r_addend; } - bfd_elf64_swap_reloca_out (output_bfd, &outrel, - (((Elf64_External_Rela *) - sreloc->contents) - + sreloc->reloc_count)); - ++sreloc->reloc_count; + sreloc = elf_section_data (input_section)->sreloc; + if (sreloc == NULL) + abort (); + + loc = (Elf64_External_Rela *) sreloc->contents; + loc += sreloc->reloc_count++; + bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc); /* If this reloc is against an external symbol, we do not want to fiddle with the addend. Otherwise, we @@ -1558,39 +1817,59 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, break; } + /* FIXME: Why do we allow debugging sections to escape this error? + More importantly, why do we not emit dynamic relocs for + R_386_32 above in debugging sections (which are ! SEC_ALLOC)? + If we had emitted the dynamic reloc, we could remove the + fudge here. */ + if (unresolved_reloc + && !(info->shared + && (input_section->flags & SEC_DEBUGGING) != 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)) + (*_bfd_error_handler) + (_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"), + bfd_archive_filename (input_bfd), + bfd_get_section_name (input_bfd, input_section), + (long) rel->r_offset, + h->root.root.string); + r = _bfd_final_link_relocate (howto, input_bfd, input_section, - contents, rela->r_offset, - relocation, rela->r_addend); + contents, rel->r_offset, + relocation, rel->r_addend); if (r != bfd_reloc_ok) { - switch (r) + const char *name; + + if (h != NULL) + name = h->root.root.string; + else { - default: - case bfd_reloc_outofrange: - abort (); - case bfd_reloc_overflow: - { - const char *name; - - if (h != NULL) - name = h->root.root.string; - else - { - name = bfd_elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); - if (name == NULL) - return false; - if (*name == '\0') - name = bfd_section_name (input_bfd, sec); - } - if (! ((*info->callbacks->reloc_overflow) - (info, name, howto->name, (bfd_vma) 0, - input_bfd, input_section, rela->r_offset))) - return false; - } - break; + name = bfd_elf_string_from_elf_section (input_bfd, + symtab_hdr->sh_link, + sym->st_name); + if (name == NULL) + return false; + if (*name == '\0') + name = bfd_section_name (input_bfd, sec); + } + + if (r == bfd_reloc_overflow) + { + + if (! ((*info->callbacks->reloc_overflow) + (info, name, howto->name, (bfd_vma) 0, + input_bfd, input_section, rel->r_offset))) + return false; + } + else + { + (*_bfd_error_handler) + (_("%s(%s+0x%lx): reloc against `%s': error %d"), + bfd_archive_filename (input_bfd), + bfd_get_section_name (input_bfd, input_section), + (long) rel->r_offset, name, (int) r); + return false; } } } @@ -1608,28 +1887,25 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym) struct elf_link_hash_entry *h; Elf_Internal_Sym *sym; { - bfd *dynobj; + struct elf64_x86_64_link_hash_table *htab; - dynobj = elf_hash_table (info)->dynobj; + htab = elf64_x86_64_hash_table (info); if (h->plt.offset != (bfd_vma) -1) { - asection *splt; - asection *sgot; - asection *srela; bfd_vma plt_index; bfd_vma got_offset; Elf_Internal_Rela rela; + Elf64_External_Rela *loc; /* This symbol has an entry in the procedure linkage table. Set it up. */ - BFD_ASSERT (h->dynindx != -1); - - splt = bfd_get_section_by_name (dynobj, ".plt"); - sgot = bfd_get_section_by_name (dynobj, ".got.plt"); - srela = bfd_get_section_by_name (dynobj, ".rela.plt"); - BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL); + if (h->dynindx == -1 + || htab->splt == NULL + || htab->sgotplt == NULL + || htab->srelplt == NULL) + abort (); /* Get the index in the procedure linkage table which corresponds to this symbol. This is the index of this symbol @@ -1643,7 +1919,7 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym) got_offset = (plt_index + 3) * GOT_ENTRY_SIZE; /* Fill in the entry in the procedure linkage table. */ - memcpy (splt->contents + h->plt.offset, elf64_x86_64_plt_entry, + memcpy (htab->splt->contents + h->plt.offset, elf64_x86_64_plt_entry, PLT_ENTRY_SIZE); /* Insert the relocation positions of the plt section. The magic @@ -1652,67 +1928,61 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym) /* Put offset for jmp *name@GOTPCREL(%rip), since the instruction uses 6 bytes, subtract this value. */ bfd_put_32 (output_bfd, - (sgot->output_section->vma - + sgot->output_offset + (htab->sgotplt->output_section->vma + + htab->sgotplt->output_offset + got_offset - - splt->output_section->vma - - splt->output_offset + - htab->splt->output_section->vma + - htab->splt->output_offset - h->plt.offset - 6), - splt->contents + h->plt.offset + 2); + htab->splt->contents + h->plt.offset + 2); /* Put relocation index. */ bfd_put_32 (output_bfd, plt_index, - splt->contents + h->plt.offset + 7); + htab->splt->contents + h->plt.offset + 7); /* Put offset for jmp .PLT0. */ bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE), - splt->contents + h->plt.offset + 12); + htab->splt->contents + h->plt.offset + 12); /* Fill in the entry in the global offset table, initially this points to the pushq instruction in the PLT which is at offset 6. */ - bfd_put_64 (output_bfd, (splt->output_section->vma + splt->output_offset + bfd_put_64 (output_bfd, (htab->splt->output_section->vma + + htab->splt->output_offset + h->plt.offset + 6), - sgot->contents + got_offset); + htab->sgotplt->contents + got_offset); /* Fill in the entry in the .rela.plt section. */ - rela.r_offset = (sgot->output_section->vma - + sgot->output_offset + rela.r_offset = (htab->sgotplt->output_section->vma + + htab->sgotplt->output_offset + got_offset); rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_JUMP_SLOT); rela.r_addend = 0; - bfd_elf64_swap_reloca_out (output_bfd, &rela, - ((Elf64_External_Rela *) srela->contents - + plt_index)); + loc = (Elf64_External_Rela *) htab->srelplt->contents + plt_index; + bfd_elf64_swap_reloca_out (output_bfd, &rela, loc); if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) { /* Mark the symbol as undefined, rather than as defined in - the .plt section. Leave the value alone. */ + the .plt section. Leave the value alone. This is a clue + for the dynamic linker, to make function pointer + comparisons work between an application and shared + library. */ sym->st_shndx = SHN_UNDEF; - /* If the symbol is weak, we do need to clear the value. - Otherwise, the PLT entry would provide a definition for - the symbol even if the symbol wasn't defined anywhere, - and so the symbol would never be NULL. */ - if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR_NONWEAK) - == 0) - sym->st_value = 0; } } if (h->got.offset != (bfd_vma) -1) { - asection *sgot; - asection *srela; Elf_Internal_Rela rela; + Elf64_External_Rela *loc; /* This symbol has an entry in the global offset table. Set it up. */ - sgot = bfd_get_section_by_name (dynobj, ".got"); - srela = bfd_get_section_by_name (dynobj, ".rela.got"); - BFD_ASSERT (sgot != NULL && srela != NULL); + if (htab->sgot == NULL || htab->srelgot == NULL) + abort (); - rela.r_offset = (sgot->output_section->vma - + sgot->output_offset + rela.r_offset = (htab->sgot->output_section->vma + + htab->sgot->output_offset + (h->got.offset &~ (bfd_vma) 1)); /* If this is a static link, or it is a -Bsymbolic link and the @@ -1720,10 +1990,11 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym) of a version file, we just want to emit a RELATIVE reloc. The entry in the global offset table will already have been initialized in the relocate_section function. */ - if (! elf_hash_table (info)->dynamic_sections_created - || (info->shared - && (info->symbolic || h->dynindx == -1) - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) + if (info->shared + && (info->symbolic + || h->dynindx == -1 + || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)) + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) { BFD_ASSERT((h->got.offset & 1) != 0); rela.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE); @@ -1734,41 +2005,38 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym) else { BFD_ASSERT((h->got.offset & 1) == 0); - bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset); + bfd_put_64 (output_bfd, (bfd_vma) 0, + htab->sgot->contents + h->got.offset); rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_GLOB_DAT); rela.r_addend = 0; } - bfd_elf64_swap_reloca_out (output_bfd, &rela, - ((Elf64_External_Rela *) srela->contents - + srela->reloc_count)); - ++srela->reloc_count; + loc = (Elf64_External_Rela *) htab->srelgot->contents; + loc += htab->srelgot->reloc_count++; + bfd_elf64_swap_reloca_out (output_bfd, &rela, loc); } if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) { - asection *s; Elf_Internal_Rela rela; + Elf64_External_Rela *loc; /* This symbol needs a copy reloc. Set it up. */ - BFD_ASSERT (h->dynindx != -1 - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)); - - s = bfd_get_section_by_name (h->root.u.def.section->owner, - ".rela.bss"); - BFD_ASSERT (s != NULL); + if (h->dynindx == -1 + || (h->root.type != bfd_link_hash_defined + && h->root.type != bfd_link_hash_defweak) + || htab->srelbss == NULL) + abort (); rela.r_offset = (h->root.u.def.value + h->root.u.def.section->output_section->vma + h->root.u.def.section->output_offset); rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_COPY); rela.r_addend = 0; - bfd_elf64_swap_reloca_out (output_bfd, &rela, - ((Elf64_External_Rela *) s->contents - + s->reloc_count)); - ++s->reloc_count; + loc = (Elf64_External_Rela *) htab->srelbss->contents; + loc += htab->srelbss->reloc_count++; + bfd_elf64_swap_reloca_out (output_bfd, &rela, loc); } /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute. */ @@ -1779,6 +2047,26 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym) return true; } +/* Used to decide how to sort relocs in an optimal manner for the + dynamic linker, before writing them out. */ + +static enum elf_reloc_type_class +elf64_x86_64_reloc_type_class (rela) + const Elf_Internal_Rela *rela; +{ + switch ((int) ELF64_R_TYPE (rela->r_info)) + { + case R_X86_64_RELATIVE: + return reloc_class_relative; + case R_X86_64_JUMP_SLOT: + return reloc_class_plt; + case R_X86_64_COPY: + return reloc_class_copy; + default: + return reloc_class_normal; + } +} + /* Finish up the dynamic sections. */ static boolean @@ -1786,29 +2074,26 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info) bfd *output_bfd; struct bfd_link_info *info; { + struct elf64_x86_64_link_hash_table *htab; bfd *dynobj; asection *sdyn; - asection *sgot; - - dynobj = elf_hash_table (info)->dynobj; - sgot = bfd_get_section_by_name (dynobj, ".got.plt"); - BFD_ASSERT (sgot != NULL); + htab = elf64_x86_64_hash_table (info); + dynobj = htab->elf.dynobj; sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - if (elf_hash_table (info)->dynamic_sections_created) + if (htab->elf.dynamic_sections_created) { - asection *splt; Elf64_External_Dyn *dyncon, *dynconend; - BFD_ASSERT (sdyn != NULL); + if (sdyn == NULL || htab->sgot == NULL) + abort (); dyncon = (Elf64_External_Dyn *) sdyn->contents; dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size); for (; dyncon < dynconend; dyncon++) { Elf_Internal_Dyn dyn; - const char *name; asection *s; bfd_elf64_swap_dyn_in (dynobj, dyncon, &dyn); @@ -1819,115 +2104,100 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info) continue; case DT_PLTGOT: - name = ".got"; - goto get_vma; + dyn.d_un.d_ptr = htab->sgot->output_section->vma; + break; case DT_JMPREL: - name = ".rela.plt"; + dyn.d_un.d_ptr = htab->srelplt->output_section->vma; + break; - get_vma: - s = bfd_get_section_by_name (output_bfd, name); - BFD_ASSERT (s != NULL); - dyn.d_un.d_ptr = s->vma; + case DT_PLTRELSZ: + s = htab->srelplt->output_section; + if (s->_cooked_size != 0) + dyn.d_un.d_val = s->_cooked_size; + else + dyn.d_un.d_val = s->_raw_size; break; case DT_RELASZ: - /* FIXME: This comment and code is from elf64-alpha.c: */ - /* My interpretation of the TIS v1.1 ELF document indicates - that RELASZ should not include JMPREL. This is not what - the rest of the BFD does. It is, however, what the - glibc ld.so wants. Do this fixup here until we found - out who is right. */ - s = bfd_get_section_by_name (output_bfd, ".rela.plt"); - if (s) + /* The procedure linkage table relocs (DT_JMPREL) should + not be included in the overall relocs (DT_RELA). + Therefore, we override the DT_RELASZ entry here to + make it not include the JMPREL relocs. Since the + linker script arranges for .rela.plt to follow all + other relocation sections, we don't have to worry + about changing the DT_RELA entry. */ + if (htab->srelplt != NULL) { - /* Subtract JMPREL size from RELASZ. */ - dyn.d_un.d_val -= - (s->_cooked_size ? s->_cooked_size : s->_raw_size); + s = htab->srelplt->output_section; + if (s->_cooked_size != 0) + dyn.d_un.d_val -= s->_cooked_size; + else + dyn.d_un.d_val -= s->_raw_size; } break; - - case DT_PLTRELSZ: - s = bfd_get_section_by_name (output_bfd, ".rela.plt"); - BFD_ASSERT (s != NULL); - dyn.d_un.d_val = - (s->_cooked_size != 0 ? s->_cooked_size : s->_raw_size); - break; } + bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); } - /* Initialize the contents of the .plt section. */ - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL); - if (splt->_raw_size > 0) + /* Fill in the special first entry in the procedure linkage table. */ + if (htab->splt && htab->splt->_raw_size > 0) { /* Fill in the first entry in the procedure linkage table. */ - memcpy (splt->contents, elf64_x86_64_plt0_entry, PLT_ENTRY_SIZE); + memcpy (htab->splt->contents, elf64_x86_64_plt0_entry, + PLT_ENTRY_SIZE); /* Add offset for pushq GOT+8(%rip), since the instruction uses 6 bytes subtract this value. */ bfd_put_32 (output_bfd, - (sgot->output_section->vma - + sgot->output_offset + (htab->sgotplt->output_section->vma + + htab->sgotplt->output_offset + 8 - - splt->output_section->vma - - splt->output_offset + - htab->splt->output_section->vma + - htab->splt->output_offset - 6), - splt->contents + 2); + htab->splt->contents + 2); /* Add offset for jmp *GOT+16(%rip). The 12 is the offset to the end of the instruction. */ bfd_put_32 (output_bfd, - (sgot->output_section->vma - + sgot->output_offset + (htab->sgotplt->output_section->vma + + htab->sgotplt->output_offset + 16 - - splt->output_section->vma - - splt->output_offset + - htab->splt->output_section->vma + - htab->splt->output_offset - 12), - splt->contents + 8); + htab->splt->contents + 8); + elf_section_data (htab->splt->output_section)->this_hdr.sh_entsize = + PLT_ENTRY_SIZE; } - - elf_section_data (splt->output_section)->this_hdr.sh_entsize = - PLT_ENTRY_SIZE; } - /* Set the first entry in the global offset table to the address of - the dynamic section. */ - if (sgot->_raw_size > 0) + if (htab->sgotplt) { - if (sdyn == NULL) - bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents); - else - bfd_put_64 (output_bfd, - sdyn->output_section->vma + sdyn->output_offset, - sgot->contents); - /* Write GOT[1] and GOT[2], needed for the dynamic linker. */ - bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + GOT_ENTRY_SIZE); - bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + GOT_ENTRY_SIZE*2); - } + /* Fill in the first three entries in the global offset table. */ + if (htab->sgotplt->_raw_size > 0) + { + /* Set the first entry in the global offset table to the address of + the dynamic section. */ + if (sdyn == NULL) + bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents); + else + bfd_put_64 (output_bfd, + sdyn->output_section->vma + sdyn->output_offset, + htab->sgotplt->contents); + /* Write GOT[1] and GOT[2], needed for the dynamic linker. */ + bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + GOT_ENTRY_SIZE); + bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + GOT_ENTRY_SIZE*2); + } - elf_section_data (sgot->output_section)->this_hdr.sh_entsize = - GOT_ENTRY_SIZE; + elf_section_data (htab->sgotplt->output_section)->this_hdr.sh_entsize = + GOT_ENTRY_SIZE; + } return true; } -static enum elf_reloc_type_class -elf64_x86_64_reloc_type_class (rela) - const Elf_Internal_Rela *rela; -{ - switch ((int) ELF64_R_TYPE (rela->r_info)) - { - case R_X86_64_RELATIVE: - return reloc_class_relative; - case R_X86_64_JUMP_SLOT: - return reloc_class_plt; - case R_X86_64_COPY: - return reloc_class_copy; - default: - return reloc_class_normal; - } -} #define TARGET_LITTLE_SYM bfd_elf64_x86_64_vec #define TARGET_LITTLE_NAME "elf64-x86-64" @@ -1942,25 +2212,25 @@ elf64_x86_64_reloc_type_class (rela) #define elf_backend_want_plt_sym 0 #define elf_backend_got_header_size (GOT_ENTRY_SIZE*3) #define elf_backend_plt_header_size PLT_ENTRY_SIZE +#define elf_backend_rela_normal 1 #define elf_info_to_howto elf64_x86_64_info_to_howto -#define bfd_elf64_bfd_final_link _bfd_elf64_gc_common_final_link #define bfd_elf64_bfd_link_hash_table_create \ elf64_x86_64_link_hash_table_create #define bfd_elf64_bfd_reloc_type_lookup elf64_x86_64_reloc_type_lookup #define elf_backend_adjust_dynamic_symbol elf64_x86_64_adjust_dynamic_symbol #define elf_backend_check_relocs elf64_x86_64_check_relocs -#define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections -#define elf_backend_finish_dynamic_sections \ - elf64_x86_64_finish_dynamic_sections +#define elf_backend_copy_indirect_symbol elf64_x86_64_copy_indirect_symbol +#define elf_backend_create_dynamic_sections elf64_x86_64_create_dynamic_sections +#define elf_backend_finish_dynamic_sections elf64_x86_64_finish_dynamic_sections #define elf_backend_finish_dynamic_symbol elf64_x86_64_finish_dynamic_symbol #define elf_backend_gc_mark_hook elf64_x86_64_gc_mark_hook #define elf_backend_gc_sweep_hook elf64_x86_64_gc_sweep_hook +#define elf_backend_reloc_type_class elf64_x86_64_reloc_type_class #define elf_backend_relocate_section elf64_x86_64_relocate_section #define elf_backend_size_dynamic_sections elf64_x86_64_size_dynamic_sections #define elf_backend_object_p elf64_x86_64_elf_object_p -#define elf_backend_reloc_type_class elf64_x86_64_reloc_type_class #include "elf64-target.h" diff --git a/contrib/binutils/bfd/elfarm-nabi.c b/contrib/binutils/bfd/elfarm-nabi.c index 7ced680..2d791de 100644 --- a/contrib/binutils/bfd/elfarm-nabi.c +++ b/contrib/binutils/bfd/elfarm-nabi.c @@ -138,8 +138,8 @@ static reloc_howto_type elf32_arm_howto_table[] = bfd_elf_generic_reloc, /* special_function */ "R_ARM_ABS16", /* name */ false, /* partial_inplace */ - 0, /* src_mask */ - 0, /* dst_mask */ + 0x0000ffff, /* src_mask */ + 0x0000ffff, /* dst_mask */ false), /* pcrel_offset */ /* 12 bit absolute */ diff --git a/contrib/binutils/bfd/elflink.h b/contrib/binutils/bfd/elflink.h index d43d861..bfe6374 100644 --- a/contrib/binutils/bfd/elflink.h +++ b/contrib/binutils/bfd/elflink.h @@ -5347,21 +5347,11 @@ elf_bfd_final_link (abfd, info) { for (p = o->link_order_head; p != NULL; p = p->next) { - Elf_Internal_Shdr *rhdr; - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour (p->u.indirect.section->owner) + && (bfd_get_flavour ((sub = p->u.indirect.section->owner)) == bfd_target_elf_flavour) - && (((rhdr = &elf_section_data (p->u.indirect.section)->rel_hdr) - ->sh_entsize == 0) - || rhdr->sh_entsize == sizeof (Elf_External_Rel) - || rhdr->sh_entsize == sizeof (Elf_External_Rela)) - && (((rhdr = elf_section_data (p->u.indirect.section)->rel_hdr2) - == NULL) - || rhdr->sh_entsize == sizeof (Elf_External_Rel) - || rhdr->sh_entsize == sizeof (Elf_External_Rela))) + && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass) { - sub = p->u.indirect.section->owner; if (! sub->output_has_begun) { if (! elf_link_input_bfd (&finfo, sub)) @@ -6764,6 +6754,12 @@ elf_link_input_bfd (finfo, input_bfd) void (*reloc_emitter) PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *)); + boolean rela_normal; + + input_rel_hdr = &elf_section_data (o)->rel_hdr; + rela_normal = (bed->rela_normal + && (input_rel_hdr->sh_entsize + == sizeof (Elf_External_Rela))); /* Adjust the reloc addresses and symbol indices. */ @@ -6786,7 +6782,7 @@ elf_link_input_bfd (finfo, input_bfd) irela->r_offset += o->output_offset; /* Relocs in an executable have to be virtual addresses. */ - if (finfo->info->emitrelocations) + if (!finfo->info->relocateable) irela->r_offset += o->output_section->vma; r_symndx = ELF_R_SYM (irela->r_info); @@ -6837,10 +6833,9 @@ elf_link_input_bfd (finfo, input_bfd) processor specific section. If we have discarded a section, the output_section will be the absolute section. */ - if (sec != NULL - && (bfd_is_abs_section (sec) - || (sec->output_section != NULL - && bfd_is_abs_section (sec->output_section)))) + if (bfd_is_abs_section (sec) + || (sec != NULL + && bfd_is_abs_section (sec->output_section))) r_symndx = 0; else if (sec == NULL || sec->owner == NULL) { @@ -6852,6 +6847,11 @@ elf_link_input_bfd (finfo, input_bfd) r_symndx = sec->output_section->target_index; BFD_ASSERT (r_symndx != 0); } + + /* Adjust the addend according to where the + section winds up in the output section. */ + if (rela_normal) + irela->r_addend += sec->output_offset; } else { @@ -6910,7 +6910,6 @@ elf_link_input_bfd (finfo, input_bfd) else reloc_emitter = elf_link_output_relocs; - input_rel_hdr = &elf_section_data (o)->rel_hdr; (*reloc_emitter) (output_bfd, o, input_rel_hdr, internal_relocs); input_rel_hdr = elf_section_data (o)->rel_hdr2; @@ -6918,7 +6917,8 @@ elf_link_input_bfd (finfo, input_bfd) { internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr) * bed->s->int_rels_per_ext_rel); - reloc_emitter (output_bfd, o, input_rel_hdr, internal_relocs); + (*reloc_emitter) (output_bfd, o, input_rel_hdr, + internal_relocs); } } diff --git a/contrib/binutils/bfd/elfxx-ia64.c b/contrib/binutils/bfd/elfxx-ia64.c index aadb963..f92ab6a 100644 --- a/contrib/binutils/bfd/elfxx-ia64.c +++ b/contrib/binutils/bfd/elfxx-ia64.c @@ -3502,6 +3502,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, elf_section_data(input_section->output_section) ->this_hdr.sh_flags |= flags; + return true; } gp_val = _bfd_get_gp_value (output_bfd); @@ -3534,29 +3535,9 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section, ret_val = false; continue; } + howto = lookup_howto (r_type); r_symndx = ELFNN_R_SYM (rel->r_info); - - if (info->relocateable) - { - /* This is a relocateable link. We don't have to change - anything, unless the reloc is against a section symbol, - in which case we have to adjust according to where the - section symbol winds up in the output section. */ - if (r_symndx < symtab_hdr->sh_info) - { - sym = local_syms + r_symndx; - if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) - { - sym_sec = local_sections[r_symndx]; - rel->r_addend += sym_sec->output_offset; - } - } - continue; - } - - /* This is a final link. */ - h = NULL; sym = NULL; sym_sec = NULL; @@ -4561,6 +4542,7 @@ elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval) #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class +#define elf_backend_rela_normal 1 #include "elfNN-target.h" diff --git a/contrib/binutils/bfd/elfxx-target.h b/contrib/binutils/bfd/elfxx-target.h index 25ddd0e..e6b63d1 100644 --- a/contrib/binutils/bfd/elfxx-target.h +++ b/contrib/binutils/bfd/elfxx-target.h @@ -390,6 +390,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define elf_backend_default_use_rela_p !USE_REL #endif +#ifndef elf_backend_rela_normal +#define elf_backend_rela_normal 0 +#endif + #ifndef ELF_MACHINE_ALT1 #define ELF_MACHINE_ALT1 0 #endif @@ -470,6 +474,7 @@ static const struct elf_backend_data elfNN_bed = elf_backend_may_use_rel_p, elf_backend_may_use_rela_p, elf_backend_default_use_rela_p, + elf_backend_rela_normal, elf_backend_sign_extend_vma, elf_backend_want_got_plt, elf_backend_plt_readonly, diff --git a/contrib/binutils/bfd/ihex.c b/contrib/binutils/bfd/ihex.c index 613eaf3..2e4494d 100644 --- a/contrib/binutils/bfd/ihex.c +++ b/contrib/binutils/bfd/ihex.c @@ -875,8 +875,8 @@ ihex_write_object_contents (abfd) rec_addr = where - (extbase + segbase); /* Output records shouldn't cross 64K boundaries. */ - if (rec_addr + now > 0xfffff) - now = 0xffff - rec_addr; + if (rec_addr + now > 0xffff) + now = 0x10000 - rec_addr; if (! ihex_write_record (abfd, now, rec_addr, 0, p)) return false; diff --git a/contrib/binutils/bfd/libbfd.h b/contrib/binutils/bfd/libbfd.h index e7ba1c5..55d192c 100644 --- a/contrib/binutils/bfd/libbfd.h +++ b/contrib/binutils/bfd/libbfd.h @@ -752,55 +752,6 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_MIPS_REL16", "BFD_RELOC_MIPS_RELGOT", "BFD_RELOC_MIPS_JALR", - "BFD_RELOC_SH_GOT_LOW16", - "BFD_RELOC_SH_GOT_MEDLOW16", - "BFD_RELOC_SH_GOT_MEDHI16", - "BFD_RELOC_SH_GOT_HI16", - "BFD_RELOC_SH_GOTPLT_LOW16", - "BFD_RELOC_SH_GOTPLT_MEDLOW16", - "BFD_RELOC_SH_GOTPLT_MEDHI16", - "BFD_RELOC_SH_GOTPLT_HI16", - "BFD_RELOC_SH_PLT_LOW16", - "BFD_RELOC_SH_PLT_MEDLOW16", - "BFD_RELOC_SH_PLT_MEDHI16", - "BFD_RELOC_SH_PLT_HI16", - "BFD_RELOC_SH_GOTOFF_LOW16", - "BFD_RELOC_SH_GOTOFF_MEDLOW16", - "BFD_RELOC_SH_GOTOFF_MEDHI16", - "BFD_RELOC_SH_GOTOFF_HI16", - "BFD_RELOC_SH_GOTPC_LOW16", - "BFD_RELOC_SH_GOTPC_MEDLOW16", - "BFD_RELOC_SH_GOTPC_MEDHI16", - "BFD_RELOC_SH_GOTPC_HI16", - "BFD_RELOC_SH_COPY64", - "BFD_RELOC_SH_GLOB_DAT64", - "BFD_RELOC_SH_JMP_SLOT64", - "BFD_RELOC_SH_RELATIVE64", - "BFD_RELOC_SH_GOT10BY4", - "BFD_RELOC_SH_GOT10BY8", - "BFD_RELOC_SH_GOTPLT10BY4", - "BFD_RELOC_SH_GOTPLT10BY8", - "BFD_RELOC_SH_GOTPLT32", - "BFD_RELOC_SH_SHMEDIA_CODE", - "BFD_RELOC_SH_IMMU5", - "BFD_RELOC_SH_IMMS6", - "BFD_RELOC_SH_IMMS6BY32", - "BFD_RELOC_SH_IMMU6", - "BFD_RELOC_SH_IMMS10", - "BFD_RELOC_SH_IMMS10BY2", - "BFD_RELOC_SH_IMMS10BY4", - "BFD_RELOC_SH_IMMS10BY8", - "BFD_RELOC_SH_IMMS16", - "BFD_RELOC_SH_IMMU16", - "BFD_RELOC_SH_IMM_LOW16", - "BFD_RELOC_SH_IMM_LOW16_PCREL", - "BFD_RELOC_SH_IMM_MEDLOW16", - "BFD_RELOC_SH_IMM_MEDLOW16_PCREL", - "BFD_RELOC_SH_IMM_MEDHI16", - "BFD_RELOC_SH_IMM_MEDHI16_PCREL", - "BFD_RELOC_SH_IMM_HI16", - "BFD_RELOC_SH_IMM_HI16_PCREL", - "BFD_RELOC_SH_PT_16", "BFD_RELOC_386_GOT32", "BFD_RELOC_386_PLT32", @@ -947,6 +898,55 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_SH_JMP_SLOT", "BFD_RELOC_SH_RELATIVE", "BFD_RELOC_SH_GOTPC", + "BFD_RELOC_SH_GOT_LOW16", + "BFD_RELOC_SH_GOT_MEDLOW16", + "BFD_RELOC_SH_GOT_MEDHI16", + "BFD_RELOC_SH_GOT_HI16", + "BFD_RELOC_SH_GOTPLT_LOW16", + "BFD_RELOC_SH_GOTPLT_MEDLOW16", + "BFD_RELOC_SH_GOTPLT_MEDHI16", + "BFD_RELOC_SH_GOTPLT_HI16", + "BFD_RELOC_SH_PLT_LOW16", + "BFD_RELOC_SH_PLT_MEDLOW16", + "BFD_RELOC_SH_PLT_MEDHI16", + "BFD_RELOC_SH_PLT_HI16", + "BFD_RELOC_SH_GOTOFF_LOW16", + "BFD_RELOC_SH_GOTOFF_MEDLOW16", + "BFD_RELOC_SH_GOTOFF_MEDHI16", + "BFD_RELOC_SH_GOTOFF_HI16", + "BFD_RELOC_SH_GOTPC_LOW16", + "BFD_RELOC_SH_GOTPC_MEDLOW16", + "BFD_RELOC_SH_GOTPC_MEDHI16", + "BFD_RELOC_SH_GOTPC_HI16", + "BFD_RELOC_SH_COPY64", + "BFD_RELOC_SH_GLOB_DAT64", + "BFD_RELOC_SH_JMP_SLOT64", + "BFD_RELOC_SH_RELATIVE64", + "BFD_RELOC_SH_GOT10BY4", + "BFD_RELOC_SH_GOT10BY8", + "BFD_RELOC_SH_GOTPLT10BY4", + "BFD_RELOC_SH_GOTPLT10BY8", + "BFD_RELOC_SH_GOTPLT32", + "BFD_RELOC_SH_SHMEDIA_CODE", + "BFD_RELOC_SH_IMMU5", + "BFD_RELOC_SH_IMMS6", + "BFD_RELOC_SH_IMMS6BY32", + "BFD_RELOC_SH_IMMU6", + "BFD_RELOC_SH_IMMS10", + "BFD_RELOC_SH_IMMS10BY2", + "BFD_RELOC_SH_IMMS10BY4", + "BFD_RELOC_SH_IMMS10BY8", + "BFD_RELOC_SH_IMMS16", + "BFD_RELOC_SH_IMMU16", + "BFD_RELOC_SH_IMM_LOW16", + "BFD_RELOC_SH_IMM_LOW16_PCREL", + "BFD_RELOC_SH_IMM_MEDLOW16", + "BFD_RELOC_SH_IMM_MEDLOW16_PCREL", + "BFD_RELOC_SH_IMM_MEDHI16", + "BFD_RELOC_SH_IMM_MEDHI16_PCREL", + "BFD_RELOC_SH_IMM_HI16", + "BFD_RELOC_SH_IMM_HI16_PCREL", + "BFD_RELOC_SH_PT_16", "BFD_RELOC_THUMB_PCREL_BRANCH9", "BFD_RELOC_THUMB_PCREL_BRANCH12", "BFD_RELOC_THUMB_PCREL_BRANCH23", diff --git a/contrib/binutils/bfd/opncls.c b/contrib/binutils/bfd/opncls.c index 0b285d4..200f6c7 100644 --- a/contrib/binutils/bfd/opncls.c +++ b/contrib/binutils/bfd/opncls.c @@ -1,6 +1,6 @@ /* opncls.c -- open and close a BFD. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, - 2001 + 2001, 2002 Free Software Foundation, Inc. Written by Cygnus Support. @@ -96,6 +96,8 @@ _bfd_new_bfd_contained_in (obfd) bfd *nbfd; nbfd = _bfd_new_bfd (); + if (nbfd == NULL) + return NULL; nbfd->xvec = obfd->xvec; nbfd->my_archive = obfd; nbfd->direction = read_direction; @@ -618,7 +620,6 @@ bfd_make_readable(abfd) abfd->arch_info = &bfd_default_arch_struct; abfd->where = 0; - abfd->sections = (asection *) NULL; abfd->format = bfd_unknown; abfd->my_archive = (bfd *) NULL; abfd->origin = 0; @@ -637,6 +638,7 @@ bfd_make_readable(abfd) abfd->outsymbols = 0; abfd->tdata.any = 0; + bfd_section_list_clear (abfd); bfd_check_format(abfd, bfd_object); return true; diff --git a/contrib/binutils/bfd/reloc.c b/contrib/binutils/bfd/reloc.c index 559a351..c701fe0 100644 --- a/contrib/binutils/bfd/reloc.c +++ b/contrib/binutils/bfd/reloc.c @@ -2051,106 +2051,6 @@ ENUMX BFD_RELOC_MIPS_JALR COMMENT COMMENT -ENUMX - BFD_RELOC_SH_GOT_LOW16 -ENUMX - BFD_RELOC_SH_GOT_MEDLOW16 -ENUMX - BFD_RELOC_SH_GOT_MEDHI16 -ENUMX - BFD_RELOC_SH_GOT_HI16 -ENUMX - BFD_RELOC_SH_GOTPLT_LOW16 -ENUMX - BFD_RELOC_SH_GOTPLT_MEDLOW16 -ENUMX - BFD_RELOC_SH_GOTPLT_MEDHI16 -ENUMX - BFD_RELOC_SH_GOTPLT_HI16 -ENUMX - BFD_RELOC_SH_PLT_LOW16 -ENUMX - BFD_RELOC_SH_PLT_MEDLOW16 -ENUMX - BFD_RELOC_SH_PLT_MEDHI16 -ENUMX - BFD_RELOC_SH_PLT_HI16 -ENUMX - BFD_RELOC_SH_GOTOFF_LOW16 -ENUMX - BFD_RELOC_SH_GOTOFF_MEDLOW16 -ENUMX - BFD_RELOC_SH_GOTOFF_MEDHI16 -ENUMX - BFD_RELOC_SH_GOTOFF_HI16 -ENUMX - BFD_RELOC_SH_GOTPC_LOW16 -ENUMX - BFD_RELOC_SH_GOTPC_MEDLOW16 -ENUMX - BFD_RELOC_SH_GOTPC_MEDHI16 -ENUMX - BFD_RELOC_SH_GOTPC_HI16 -ENUMX - BFD_RELOC_SH_COPY64 -ENUMX - BFD_RELOC_SH_GLOB_DAT64 -ENUMX - BFD_RELOC_SH_JMP_SLOT64 -ENUMX - BFD_RELOC_SH_RELATIVE64 -ENUMX - BFD_RELOC_SH_GOT10BY4 -ENUMX - BFD_RELOC_SH_GOT10BY8 -ENUMX - BFD_RELOC_SH_GOTPLT10BY4 -ENUMX - BFD_RELOC_SH_GOTPLT10BY8 -ENUMX - BFD_RELOC_SH_GOTPLT32 -COMMENT -ENUMX - BFD_RELOC_SH_SHMEDIA_CODE -ENUMX - BFD_RELOC_SH_IMMU5 -ENUMX - BFD_RELOC_SH_IMMS6 -ENUMX - BFD_RELOC_SH_IMMS6BY32 -ENUMX - BFD_RELOC_SH_IMMU6 -ENUMX - BFD_RELOC_SH_IMMS10 -ENUMX - BFD_RELOC_SH_IMMS10BY2 -ENUMX - BFD_RELOC_SH_IMMS10BY4 -ENUMX - BFD_RELOC_SH_IMMS10BY8 -ENUMX - BFD_RELOC_SH_IMMS16 -ENUMX - BFD_RELOC_SH_IMMU16 -ENUMX - BFD_RELOC_SH_IMM_LOW16 -ENUMX - BFD_RELOC_SH_IMM_LOW16_PCREL -ENUMX - BFD_RELOC_SH_IMM_MEDLOW16 -ENUMX - BFD_RELOC_SH_IMM_MEDLOW16_PCREL -ENUMX - BFD_RELOC_SH_IMM_MEDHI16 -ENUMX - BFD_RELOC_SH_IMM_MEDHI16_PCREL -ENUMX - BFD_RELOC_SH_IMM_HI16 -ENUMX - BFD_RELOC_SH_IMM_HI16_PCREL -ENUMX - BFD_RELOC_SH_PT_16 -COMMENT ENUMDOC MIPS ELF relocations. @@ -2487,6 +2387,104 @@ ENUMX BFD_RELOC_SH_RELATIVE ENUMX BFD_RELOC_SH_GOTPC +ENUMX + BFD_RELOC_SH_GOT_LOW16 +ENUMX + BFD_RELOC_SH_GOT_MEDLOW16 +ENUMX + BFD_RELOC_SH_GOT_MEDHI16 +ENUMX + BFD_RELOC_SH_GOT_HI16 +ENUMX + BFD_RELOC_SH_GOTPLT_LOW16 +ENUMX + BFD_RELOC_SH_GOTPLT_MEDLOW16 +ENUMX + BFD_RELOC_SH_GOTPLT_MEDHI16 +ENUMX + BFD_RELOC_SH_GOTPLT_HI16 +ENUMX + BFD_RELOC_SH_PLT_LOW16 +ENUMX + BFD_RELOC_SH_PLT_MEDLOW16 +ENUMX + BFD_RELOC_SH_PLT_MEDHI16 +ENUMX + BFD_RELOC_SH_PLT_HI16 +ENUMX + BFD_RELOC_SH_GOTOFF_LOW16 +ENUMX + BFD_RELOC_SH_GOTOFF_MEDLOW16 +ENUMX + BFD_RELOC_SH_GOTOFF_MEDHI16 +ENUMX + BFD_RELOC_SH_GOTOFF_HI16 +ENUMX + BFD_RELOC_SH_GOTPC_LOW16 +ENUMX + BFD_RELOC_SH_GOTPC_MEDLOW16 +ENUMX + BFD_RELOC_SH_GOTPC_MEDHI16 +ENUMX + BFD_RELOC_SH_GOTPC_HI16 +ENUMX + BFD_RELOC_SH_COPY64 +ENUMX + BFD_RELOC_SH_GLOB_DAT64 +ENUMX + BFD_RELOC_SH_JMP_SLOT64 +ENUMX + BFD_RELOC_SH_RELATIVE64 +ENUMX + BFD_RELOC_SH_GOT10BY4 +ENUMX + BFD_RELOC_SH_GOT10BY8 +ENUMX + BFD_RELOC_SH_GOTPLT10BY4 +ENUMX + BFD_RELOC_SH_GOTPLT10BY8 +ENUMX + BFD_RELOC_SH_GOTPLT32 +ENUMX + BFD_RELOC_SH_SHMEDIA_CODE +ENUMX + BFD_RELOC_SH_IMMU5 +ENUMX + BFD_RELOC_SH_IMMS6 +ENUMX + BFD_RELOC_SH_IMMS6BY32 +ENUMX + BFD_RELOC_SH_IMMU6 +ENUMX + BFD_RELOC_SH_IMMS10 +ENUMX + BFD_RELOC_SH_IMMS10BY2 +ENUMX + BFD_RELOC_SH_IMMS10BY4 +ENUMX + BFD_RELOC_SH_IMMS10BY8 +ENUMX + BFD_RELOC_SH_IMMS16 +ENUMX + BFD_RELOC_SH_IMMU16 +ENUMX + BFD_RELOC_SH_IMM_LOW16 +ENUMX + BFD_RELOC_SH_IMM_LOW16_PCREL +ENUMX + BFD_RELOC_SH_IMM_MEDLOW16 +ENUMX + BFD_RELOC_SH_IMM_MEDLOW16_PCREL +ENUMX + BFD_RELOC_SH_IMM_MEDHI16 +ENUMX + BFD_RELOC_SH_IMM_MEDHI16_PCREL +ENUMX + BFD_RELOC_SH_IMM_HI16 +ENUMX + BFD_RELOC_SH_IMM_HI16_PCREL +ENUMX + BFD_RELOC_SH_PT_16 ENUMDOC Hitachi SH relocs. Not all of these appear in object files. diff --git a/contrib/binutils/bfd/rs6000-core.c b/contrib/binutils/bfd/rs6000-core.c index 19ff4a4..6330153 100644 --- a/contrib/binutils/bfd/rs6000-core.c +++ b/contrib/binutils/bfd/rs6000-core.c @@ -182,7 +182,7 @@ typedef union { /* Return the c_impl field from struct core_dumpx C. */ -#ifdef AIX_CORE_DUMPX_CORE +#if defined (HAVE_ST_C_IMPL) || defined (AIX_5_CORE) # define CNEW_IMPL(c) (c).c_impl #else # define CNEW_IMPL(c) 0 diff --git a/contrib/binutils/bfd/syms.c b/contrib/binutils/bfd/syms.c index 4309c0d..01f7eee 100644 --- a/contrib/binutils/bfd/syms.c +++ b/contrib/binutils/bfd/syms.c @@ -1297,7 +1297,8 @@ _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, pfound, *pfound = true; - if (IS_ABSOLUTE_PATH(file_name) || directory_name == NULL) + if (file_name == NULL || IS_ABSOLUTE_PATH (file_name) + || directory_name == NULL) *pfilename = file_name; else { diff --git a/contrib/binutils/bfd/version.h b/contrib/binutils/bfd/version.h index 6af6920..600c673 100644 --- a/contrib/binutils/bfd/version.h +++ b/contrib/binutils/bfd/version.h @@ -1 +1 @@ -#define BFD_VERSION_DATE 20020412 +#define BFD_VERSION_DATE 20020622 diff --git a/contrib/binutils/bfd/xcofflink.c b/contrib/binutils/bfd/xcofflink.c index a939b5c..2e5ca5d 100644 --- a/contrib/binutils/bfd/xcofflink.c +++ b/contrib/binutils/bfd/xcofflink.c @@ -2114,7 +2114,7 @@ xcoff_link_add_dynamic_symbols (abfd, info) /* Remove the sections from this object, so that they do not get included in the link. */ - abfd->sections = NULL; + bfd_section_list_clear (abfd); bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr); diff --git a/contrib/binutils/binutils/ChangeLog b/contrib/binutils/binutils/ChangeLog index 8aa1f51..91900a4 100644 --- a/contrib/binutils/binutils/ChangeLog +++ b/contrib/binutils/binutils/ChangeLog @@ -1,3 +1,131 @@ +2002-05-09 Alan Modra <amodra@bigpond.net.au> + + * configure.in: Replace `*pe' with `pe' throughout. + * configure: Regenerate. + + Merge from mainline + 2002-05-06 Alan Modra <amodra@bigpond.net.au> + * dlltool.c (process_def_file): Add missing prototype. + (new_directive, assemble_file, main): Likewise. + (process_def_file, new_directive): Make static. + (inform): Rewrite using VA_FIXEDARG. + * dllwrap.c (mybasename): Add missing prototype. + (strhash, main): Likewise. + (inform): Rewrite using VA_FIXEDARG. + (warn): Likewise. + (cleanup_and_exit): Use old style function definition. + (strhash): Likewise. + * windres.c (define_resource): Use one memset to clear all of + struct res_resource. + * rcparse.y: Remove newcmd rule. Move rcparse_discard_strings + call to rules that need no lookahead. Check for no lookahead. + + 2002-05-06 Borut Razem <borut.razem@siol.net> + * rclex.l (get_string): Correct "strings" list handling. + * resrc.c (read_rc_file): Discard strings. + + 2002-05-04 Bob Byrnes <byrnes@curl.com> + * size.c (display_archive): Add last_arfile and code to close archives. + + 2002-05-01 Alan Modra <amodra@bigpond.net.au> + * nm.c (print_symbol): Check returned filename from + bfd_find_nearest_line is non-NULL. + + 2002-04-17 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de> + * arparse.y: Fix syntax warning. + + 2002-04-16 Nick Clifton <nickc@cambridge.redhat.com> + * rcparse.y: Set MEMFLAG_DISCARDABLE by default. + + 2002-04-15 Nick Clifton <nickc@cambridge.redhat.com> + * resrc.c (write_rc_dialog): If charset is non-default value + display all of the DIALOGEX parameters. + + 2002-04-15 Eric Kohl <ekohl@rz-online.de> + * rcparse.y: Allow two to five parameter in FONT statement of + DIALOGEX resources. + * resbin.c (bin_to_res_dialog): Fixed read/write code for dialogex + resource data. + (res_to_bin_dialog): Likewise. + * windres.h: Added misssing charset variable to dialog_ex + structure. + + 2002-04-10 Nick Clifton <nickc@cambridge.redhat.com> + * rcparse.y: Set MEMFLAG_PURE by default. + + 2002-04-09 Bernd Herd <info@herdsoft.com> + * rcparse.y: CLASS definitions in DIALOG resources + are quoted. + Fix typo in BEDIT warning. + Don't add default dialog style when explicit style specified. + Add WS_CAPTION dialog style if CAPTION is specified. + * rclex.l (handle_quotes): "\xhex" encoding in strings corrected. + (handle_quotes) "\a" escape (used for right justified key + definitions in menus) is encodes as binary 8. + * resrc.c (write_rc_dialog): Print style even if it is 0. + (write_rc_directory): Fix overlooked sublang shift bug. + (bin_to_res_dialog): Don't print empty dialog caption. + * resbin.c (bin_to_res_dialog): Use signature to identify + DIALOGEX. + * windres.c (main): Set default LANGUAGE to english/us. + + 2002-04-09 Gunnar Degnbol <degnbol@danbbs.dk> + * resrc.c: print CLASS names in quotes + +2002-04-27 Alan Modra <amodra@bigpond.net.au> + + Merge from mainline + 2002-04-25 Elena Zannoni <ezannoni@redhat.com> + * readelf.c (get_AT_name): Handle DW_AT_GNU_vector. + + 2002-04-16 Nick Clifton <nickc@cambridge.redhat.com> + * readelf.c (fetch_location_list): Remove unused function. + * readelf.c (process_corefile_note_segment): Catch corrupt notes + and display a warning message, then exit the loop. + + 2002-04-24 Christian Groessler <chris@groessler.org> + * MAINTAINERS: Changed my email address. + + 2002-04-09 J"orn Rennecke <joern.rennecke@superh.com> + * MAINTAINERS: Update my email address. + + 2002-03-27 Peter Targett <peter.targett@arc.com> + * MAINTAINERS: Update my email address. + + 2002-03-20 Daniel Berlin <dan@dberlin.org> + * readelf.c: Add support for displaying dwarf2 location lists. + (do_debug_loc, debug_loc_section, debug_loc_size): New. + (parse_args): Use 'O' as shorthand for displaying location list + section. + (process_section_headers): Handle debug_loc as well. + (load_debug_loc): New. + (free_debug_loc): New. + (fetch_location_list): New. + (display_debug_loc): New. + (display_debug_info): Call load_debug_loc and free_debug_loc. + (debug_displays): We can display .debug_loc now, too. + (usage): Update usage string. + (read_and_display_attr_value): Note location lists, but don't + display them inline. + + 2002-03-01 Dmitry Timoshkov <dmitry@baikal.ru> + * dlltool.c (gen_exp_file): Take into account --kill-at (-k) while + generating .exp file. + + 2002-02-21 Nick Clifton <nickc@cambridge.redhat.com> + * readelf.c (dump_relocations): Fix typo. + + 2002-02-18 Timothy Daly <remote_bob@yahoo.com> + * readelf.c (dump_relocations): Display 2nd and 3rd reloc + types for 64-bit MIPS. Narrow some fields for 80-char + output. + (dump_relocations): Change spelling from 'unrecognised' + to 'unrecognized'. + (decode_ARM_machine_flags): Likewise. + (parse_args): Likewise. + (read_and_display_attr_value): Likewise. + (display_debug_section): Likewise. + 2002-04-04 Alan Modra <amodra@bigpond.net.au> * dep-in.sed: Cope with absolute paths. diff --git a/contrib/binutils/binutils/MAINTAINERS b/contrib/binutils/binutils/MAINTAINERS index e1a3f53..24d015b 100644 --- a/contrib/binutils/binutils/MAINTAINERS +++ b/contrib/binutils/binutils/MAINTAINERS @@ -50,7 +50,7 @@ maintainers for a given domain then responsibility falls to the first maintainer. The first maintainer is free to devolve that responsibility among the other maintainers. - ARC Peter Targett <peter.targett@arccores.com> + ARC Peter Targett <peter.targett@arc.com> ARM Nick Clifton <nickc@redhat.com> ARM Richard Earnshaw <rearnsha@arm.com> AVR Denis Chertykov <denisc@overta.ru> @@ -74,12 +74,13 @@ responsibility among the other maintainers. PPC Geoff Keating <geoffk@redhat.com> PPC XCOFF Tom Rix <trix@redhat.com> s390, s390x Martin Schwidefsky <schwidefsky@de.ibm.com> - SH Jörn Rennecke <amylaar@onetel.net.uk> + SH Jörn Rennecke <joern.rennecke@superh.com> SH Hans-Peter Nilsson <hp@bitrange.com> SH Alexandre Oliva <aoliva@redhat.com> SPARC Jakub Jelinek <jakub@redhat.com> TIC54X Timothy Wall <twall@alum.mit.edu> - z8k Christian Groessler <cpg@aladdin.de> + z8k Christian Groessler <chris@groessler.org> + --------- CGEN Maintainers ------------- diff --git a/contrib/binutils/binutils/arparse.y b/contrib/binutils/binutils/arparse.y index a03c2c4..cf0ece1 100644 --- a/contrib/binutils/binutils/arparse.y +++ b/contrib/binutils/binutils/arparse.y @@ -74,6 +74,7 @@ session: command_line: command NEWLINE { prompt(); } + ; command: open_command diff --git a/contrib/binutils/binutils/config.in b/contrib/binutils/binutils/config.in index 1e0aa93..02ec0a7 100644 --- a/contrib/binutils/binutils/config.in +++ b/contrib/binutils/binutils/config.in @@ -28,6 +28,9 @@ /* Define to `long' if <sys/types.h> doesn't define. */ #undef off_t +/* Define if you need to in order for stat and other things to work. */ +#undef _POSIX_SOURCE + /* Define to `unsigned' if <sys/types.h> doesn't define. */ #undef size_t diff --git a/contrib/binutils/binutils/configure b/contrib/binutils/binutils/configure index c63f2b0..316d09b 100755 --- a/contrib/binutils/binutils/configure +++ b/contrib/binutils/binutils/configure @@ -5495,12 +5495,12 @@ do DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM_EPOC -DDLLTOOL_ARM" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' ;; - arm-*pe* | arm-*-wince) + arm-pe* | arm-*-wince) BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' ;; - thumb-*pe*) + thumb-pe*) BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' @@ -5508,7 +5508,7 @@ do arm*-* | xscale-* | strongarm-* | d10v-*) OBJDUMP_DEFS="-DDISASSEMBLER_NEEDS_RELOCS" ;; - i[3-6]86-*pe* | i[3-6]86-*-cygwin* | i[3-6]86-*-mingw32*) + i[3-6]86-pe* | i[3-6]86-*-cygwin* | i[3-6]86-*-mingw32*) BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_I386" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' @@ -5518,22 +5518,22 @@ do BUILD_DLLTOOL='$(DLLTOOL_PROG)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_I386" ;; - powerpc*-*-*pe* | powerpc*-*-cygwin*) + powerpc*-*-pe* | powerpc*-*-cygwin*) BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_PPC" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' ;; - sh*-*-*pe) + sh*-*-pe) BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_SH" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' ;; - mips*-*-*pe) + mips*-*-pe) BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_MIPS" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' ;; - mcore-*pe) + mcore-pe) BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_MCORE" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' diff --git a/contrib/binutils/binutils/configure.in b/contrib/binutils/binutils/configure.in index bc6ce94..4246185 100644 --- a/contrib/binutils/binutils/configure.in +++ b/contrib/binutils/binutils/configure.in @@ -235,12 +235,12 @@ changequote([,])dnl DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM_EPOC -DDLLTOOL_ARM" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' ;; - arm-*pe* | arm-*-wince) + arm-pe* | arm-*-wince) BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' ;; - thumb-*pe*) + thumb-pe*) BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_ARM" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' @@ -249,7 +249,7 @@ changequote([,])dnl OBJDUMP_DEFS="-DDISASSEMBLER_NEEDS_RELOCS" ;; changequote(,)dnl - i[3-6]86-*pe* | i[3-6]86-*-cygwin* | i[3-6]86-*-mingw32*) + i[3-6]86-pe* | i[3-6]86-*-cygwin* | i[3-6]86-*-mingw32*) changequote([,])dnl BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_I386" @@ -260,22 +260,22 @@ changequote([,])dnl BUILD_DLLTOOL='$(DLLTOOL_PROG)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_I386" ;; - powerpc*-*-*pe* | powerpc*-*-cygwin*) + powerpc*-*-pe* | powerpc*-*-cygwin*) BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_PPC" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' ;; - sh*-*-*pe) + sh*-*-pe) BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_SH" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' ;; - mips*-*-*pe) + mips*-*-pe) BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_MIPS" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' ;; - mcore-*pe) + mcore-pe) BUILD_DLLTOOL='$(DLLTOOL_PROG)$(EXEEXT)' DLLTOOL_DEFS="$DLLTOOL_DEFS -DDLLTOOL_MCORE" BUILD_WINDRES='$(WINDRES_PROG)$(EXEEXT)' diff --git a/contrib/binutils/binutils/dlltool.c b/contrib/binutils/binutils/dlltool.c index a3c52c5..6864d22 100644 --- a/contrib/binutils/binutils/dlltool.c +++ b/contrib/binutils/binutils/dlltool.c @@ -1,5 +1,5 @@ /* dlltool.c -- tool to generate stuff for PE style DLLs - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GNU Binutils. @@ -658,6 +658,8 @@ static struct string_list *excludes; static const char *rvaafter PARAMS ((int)); static const char *rvabefore PARAMS ((int)); static const char *asm_prefix PARAMS ((int)); +static void process_def_file PARAMS ((const char *)); +static void new_directive PARAMS ((char *)); static void append_import PARAMS ((const char *, const char *, int)); static void run PARAMS ((const char *, char *)); static void scan_drectve_symbols PARAMS ((bfd *)); @@ -674,6 +676,7 @@ static int sfunc PARAMS ((const void *, const void *)); static void flush_page PARAMS ((FILE *, long *, int, int)); static void gen_def_file PARAMS ((void)); static void generate_idata_ofile PARAMS ((FILE *)); +static void assemble_file PARAMS ((const char *, const char *)); static void gen_exp_file PARAMS ((void)); static const char *xlate PARAMS ((const char *)); #if 0 @@ -697,28 +700,17 @@ static void inform PARAMS ((const char *, ...)); static void -#ifdef __STDC__ -inform (const char * message, ...) -#else -inform (message, va_alist) - const char * message; - va_dcl -#endif +inform VPARAMS ((const char *message, ...)) { - va_list args; - + VA_OPEN (args, message); + VA_FIXEDARG (args, const char *, message); + if (!verbose) return; -#ifdef __STDC__ - va_start (args, message); -#else - va_start (args); -#endif - report (message, args); - - va_end (args); + + VA_CLOSE (args); } static const char * @@ -820,7 +812,7 @@ asm_prefix (machine) static char **oav; -void +static void process_def_file (name) const char *name; { @@ -943,7 +935,7 @@ def_description (desc) d_list = d; } -void +static void new_directive (dir) char *dir; { @@ -1865,7 +1857,7 @@ gen_exp_file () if (!exp->noname || show_allnames) { fprintf (f, "n%d: %s \"%s\"\n", - exp->ordinal, ASM_TEXT, exp->name); + exp->ordinal, ASM_TEXT, xlate (exp->name)); if (exp->forward != 0) fprintf (f, "f%d: %s \"%s\"\n", exp->forward, ASM_TEXT, exp->internal_name); @@ -3206,6 +3198,8 @@ static const struct option long_options[] = {NULL,0,NULL,0} }; +int main PARAMS ((int, char **)); + int main (ac, av) int ac; diff --git a/contrib/binutils/binutils/dllwrap.c b/contrib/binutils/binutils/dllwrap.c index f8449a8..7c9496c 100644 --- a/contrib/binutils/binutils/dllwrap.c +++ b/contrib/binutils/binutils/dllwrap.c @@ -115,14 +115,16 @@ static int delete_exp_file = 1; static int delete_def_file = 1; static int run PARAMS ((const char *, char *)); +static char *mybasename PARAMS ((const char *)); +static int strhash PARAMS ((const char *)); static void usage PARAMS ((FILE *, int)); static void display PARAMS ((const char *, va_list)); static void inform PARAMS ((const char *, ...)); -static void warn PARAMS ((const char *format, ...)); +static void warn PARAMS ((const char *, ...)); static char *look_for_prog PARAMS ((const char *, const char *, int)); static char *deduce_name PARAMS ((const char *)); static void delete_temp_files PARAMS ((void)); -static void cleanup_and_exit PARAMS ((int status)); +static void cleanup_and_exit PARAMS ((int)); /**********************************************************************/ @@ -147,58 +149,30 @@ display (message, args) } -#ifdef __STDC__ static void -inform (const char * message, ...) +inform VPARAMS ((const char *message, ...)) { - va_list args; + VA_OPEN (args, message); + VA_FIXEDARG (args, const char *, message); if (!verbose) return; - va_start (args, message); display (message, args); - va_end (args); -} - -static void -warn (const char *format, ...) -{ - va_list args; - - va_start (args, format); - display (format, args); - va_end (args); -} -#else - -static void -inform (message, va_alist) - const char * message; - va_dcl -{ - va_list args; - - if (!verbose) - return; - va_start (args); - display (message, args); - va_end (args); + VA_CLOSE (args); } static void -warn (format, va_alist) - const char *format; - va_dcl +warn VPARAMS ((const char *format, ...)) { - va_list args; + VA_OPEN (args, format); + VA_FIXEDARG (args, const char *, format); - va_start (args); display (format, args); - va_end (args); + + VA_CLOSE (args); } -#endif /* Look for the program formed by concatenating PROG_NAME and the string running from PREFIX to END_PREFIX. If the concatenated @@ -375,7 +349,8 @@ delete_temp_files () } static void -cleanup_and_exit (int status) +cleanup_and_exit (status) + int status; { delete_temp_files (); exit (status); @@ -487,7 +462,8 @@ mybasename (name) } static int -strhash (const char *str) +strhash (str) + const char *str; { const unsigned char *s; unsigned long hash; @@ -635,6 +611,8 @@ static const struct option long_options[] = {0, 0, 0, 0} }; +int main PARAMS ((int, char **)); + int main (argc, argv) int argc; diff --git a/contrib/binutils/binutils/doc/Makefile.in b/contrib/binutils/binutils/doc/Makefile.in index 5d96d27..5ac149f 100644 --- a/contrib/binutils/binutils/doc/Makefile.in +++ b/contrib/binutils/binutils/doc/Makefile.in @@ -175,7 +175,7 @@ DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = gtar +TAR = tar GZIP_ENV = --best all: all-redirect .SUFFIXES: diff --git a/contrib/binutils/binutils/doc/addr2line.1 b/contrib/binutils/binutils/doc/addr2line.1 index 61397f2..faa5164 100644 --- a/contrib/binutils/binutils/doc/addr2line.1 +++ b/contrib/binutils/binutils/doc/addr2line.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "ADDR2LINE 1" -.TH ADDR2LINE 1 "2002-03-08" "binutils-2.12" "GNU Development Tools" +.TH ADDR2LINE 1 "2002-05-14" "binutils-2.12.1" "GNU Development Tools" .UC .SH "NAME" addr2line \- convert addresses into file names and line numbers. diff --git a/contrib/binutils/binutils/doc/ar.1 b/contrib/binutils/binutils/doc/ar.1 index 2672211..21eef42 100644 --- a/contrib/binutils/binutils/doc/ar.1 +++ b/contrib/binutils/binutils/doc/ar.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "AR 1" -.TH AR 1 "2002-03-08" "binutils-2.12" "GNU Development Tools" +.TH AR 1 "2002-05-14" "binutils-2.12.1" "GNU Development Tools" .UC .SH "NAME" ar \- create, modify, and extract from archives diff --git a/contrib/binutils/binutils/doc/cxxfilt.man b/contrib/binutils/binutils/doc/cxxfilt.man index c2a4265..903e029 100644 --- a/contrib/binutils/binutils/doc/cxxfilt.man +++ b/contrib/binutils/binutils/doc/cxxfilt.man @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "C++FILT 1" -.TH C++FILT 1 "2002-03-08" "binutils-2.12" "GNU Development Tools" +.TH C++FILT 1 "2002-05-14" "binutils-2.12.1" "GNU Development Tools" .UC .SH "NAME" cxxfilt \- Demangle \*(C+ and Java symbols. diff --git a/contrib/binutils/binutils/doc/dlltool.1 b/contrib/binutils/binutils/doc/dlltool.1 index 7e70f9d..f347e2a 100644 --- a/contrib/binutils/binutils/doc/dlltool.1 +++ b/contrib/binutils/binutils/doc/dlltool.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "DLLTOOL 1" -.TH DLLTOOL 1 "2002-03-08" "binutils-2.12" "GNU Development Tools" +.TH DLLTOOL 1 "2002-05-14" "binutils-2.12.1" "GNU Development Tools" .UC .SH "NAME" dlltool \- Create files needed to build and use DLLs. diff --git a/contrib/binutils/binutils/doc/nm.1 b/contrib/binutils/binutils/doc/nm.1 index 75f9185..92760ec 100644 --- a/contrib/binutils/binutils/doc/nm.1 +++ b/contrib/binutils/binutils/doc/nm.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "NM 1" -.TH NM 1 "2002-03-08" "binutils-2.12" "GNU Development Tools" +.TH NM 1 "2002-05-14" "binutils-2.12.1" "GNU Development Tools" .UC .SH "NAME" nm \- list symbols from object files diff --git a/contrib/binutils/binutils/doc/objcopy.1 b/contrib/binutils/binutils/doc/objcopy.1 index d06eb1d..44e1a44 100644 --- a/contrib/binutils/binutils/doc/objcopy.1 +++ b/contrib/binutils/binutils/doc/objcopy.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "OBJCOPY 1" -.TH OBJCOPY 1 "2002-03-08" "binutils-2.12" "GNU Development Tools" +.TH OBJCOPY 1 "2002-05-14" "binutils-2.12.1" "GNU Development Tools" .UC .SH "NAME" objcopy \- copy and translate object files diff --git a/contrib/binutils/binutils/doc/objdump.1 b/contrib/binutils/binutils/doc/objdump.1 index bfbc8f3..8dbfefa 100644 --- a/contrib/binutils/binutils/doc/objdump.1 +++ b/contrib/binutils/binutils/doc/objdump.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "OBJDUMP 1" -.TH OBJDUMP 1 "2002-03-08" "binutils-2.12" "GNU Development Tools" +.TH OBJDUMP 1 "2002-05-14" "binutils-2.12.1" "GNU Development Tools" .UC .SH "NAME" objdump \- display information from object files. diff --git a/contrib/binutils/binutils/doc/ranlib.1 b/contrib/binutils/binutils/doc/ranlib.1 index cf319dd..0cdb70b 100644 --- a/contrib/binutils/binutils/doc/ranlib.1 +++ b/contrib/binutils/binutils/doc/ranlib.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "RANLIB 1" -.TH RANLIB 1 "2002-03-08" "binutils-2.12" "GNU Development Tools" +.TH RANLIB 1 "2002-05-14" "binutils-2.12.1" "GNU Development Tools" .UC .SH "NAME" ranlib \- generate index to archive. diff --git a/contrib/binutils/binutils/doc/readelf.1 b/contrib/binutils/binutils/doc/readelf.1 index 8843ef1..a0464d3 100644 --- a/contrib/binutils/binutils/doc/readelf.1 +++ b/contrib/binutils/binutils/doc/readelf.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "READELF 1" -.TH READELF 1 "2002-03-08" "binutils-2.12" "GNU Development Tools" +.TH READELF 1 "2002-05-14" "binutils-2.12.1" "GNU Development Tools" .UC .SH "NAME" readelf \- Displays information about \s-1ELF\s0 files. diff --git a/contrib/binutils/binutils/doc/size.1 b/contrib/binutils/binutils/doc/size.1 index 88d797a..4a2b995 100644 --- a/contrib/binutils/binutils/doc/size.1 +++ b/contrib/binutils/binutils/doc/size.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SIZE 1" -.TH SIZE 1 "2002-03-08" "binutils-2.12" "GNU Development Tools" +.TH SIZE 1 "2002-05-14" "binutils-2.12.1" "GNU Development Tools" .UC .SH "NAME" size \- list section sizes and total size. diff --git a/contrib/binutils/binutils/doc/strings.1 b/contrib/binutils/binutils/doc/strings.1 index c87c0be..e61a2eb 100644 --- a/contrib/binutils/binutils/doc/strings.1 +++ b/contrib/binutils/binutils/doc/strings.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "STRINGS 1" -.TH STRINGS 1 "2002-03-08" "binutils-2.12" "GNU Development Tools" +.TH STRINGS 1 "2002-05-14" "binutils-2.12.1" "GNU Development Tools" .UC .SH "NAME" strings \- print the strings of printable characters in files. diff --git a/contrib/binutils/binutils/doc/strip.1 b/contrib/binutils/binutils/doc/strip.1 index da1c3b0..abd02fc 100644 --- a/contrib/binutils/binutils/doc/strip.1 +++ b/contrib/binutils/binutils/doc/strip.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "STRIP 1" -.TH STRIP 1 "2002-03-08" "binutils-2.12" "GNU Development Tools" +.TH STRIP 1 "2002-05-14" "binutils-2.12.1" "GNU Development Tools" .UC .SH "NAME" strip \- Discard symbols from object files. diff --git a/contrib/binutils/binutils/nm.c b/contrib/binutils/binutils/nm.c index 68eae77..eb8a55f 100644 --- a/contrib/binutils/binutils/nm.c +++ b/contrib/binutils/binutils/nm.c @@ -1291,7 +1291,8 @@ print_symbol (abfd, sym, archive_bfd) bfd_asymbol_name (*r->sym_ptr_ptr)) == 0 && bfd_find_nearest_line (abfd, secs[i], syms, r->address, &filename, - &functionname, &lineno)) + &functionname, &lineno) + && filename != NULL) { /* We only print the first one we find. */ printf ("\t%s:%u", filename, lineno); diff --git a/contrib/binutils/binutils/rclex.c b/contrib/binutils/binutils/rclex.c index 0d225cc..2a2bd10 100644 --- a/contrib/binutils/binutils/rclex.c +++ b/contrib/binutils/binutils/rclex.c @@ -1,7 +1,7 @@ /* A lexical scanner generated by flex */ /* Scanner skeleton version: - * $Header: /cvs/src/src/binutils/Attic/rclex.c,v 1.1.6.1 2002/03/08 17:01:00 drow Exp $ + * $Header: /cvs/src/src/binutils/Attic/rclex.c,v 1.1.6.2 2002/05/11 20:00:49 drow Exp $ */ #define FLEX_SCANNER @@ -22,7 +22,7 @@ #ifdef __cplusplus #include <stdlib.h> -#ifndef _Win32 +#ifndef _WIN32 #include <unistd.h> #else #ifndef YY_ALWAYS_INTERACTIVE @@ -643,7 +643,7 @@ char *yytext; #line 1 "rclex.l" #define INITIAL 0 #line 2 "rclex.l" -/* Copyright 1997, 1998, 1999, 2001 Free Software Foundation, Inc. +/* Copyright 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. This file is part of GNU Binutils. @@ -2022,7 +2022,7 @@ YY_BUFFER_STATE b; } -#ifndef _Win32 +#ifndef _WIN32 #include <unistd.h> #else #ifndef YY_ALWAYS_INTERACTIVE @@ -2400,11 +2400,11 @@ cpp_line (s) if (!initial_fn) { initial_fn = xmalloc (strlen (fn) + 1); - strcpy(initial_fn, fn); + strcpy (initial_fn, fn); } /* Allow the initial file, regardless of name. Suppress all other - files if they end in ".h" (this allows included "*.rc") */ + files if they end in ".h" (this allows included "*.rc"). */ if (strcmp (initial_fn, fn) == 0 || strcmp (fn + strlen (fn) - 2, ".h") != 0) suppress_cpp_data = 0; @@ -2447,7 +2447,7 @@ handle_quotes (input, len) break; case 'a': - *s++ = ESCAPE_A; + *s++ = ESCAPE_B; /* Strange, but true... */ ++t; break; @@ -2510,9 +2510,9 @@ handle_quotes (input, len) if (*t >= '0' && *t <= '9') ch = (ch << 4) | (*t - '0'); else if (*t >= 'a' && *t <= 'f') - ch = (ch << 4) | (*t - 'a'); + ch = (ch << 4) | (*t - 'a' + 10); else if (*t >= 'A' && *t <= 'F') - ch = (ch << 4) | (*t - 'A'); + ch = (ch << 4) | (*t - 'A' + 10); else break; ++t; @@ -2568,7 +2568,7 @@ get_string (len) as->s = xmalloc (len); as->next = strings; - strings = as->next; + strings = as; return as->s; } diff --git a/contrib/binutils/binutils/rclex.l b/contrib/binutils/binutils/rclex.l index c9073e2..600e38e 100644 --- a/contrib/binutils/binutils/rclex.l +++ b/contrib/binutils/binutils/rclex.l @@ -1,5 +1,5 @@ %{ /* rclex.l -- lexer for Windows rc files parser */ -/* Copyright 1997, 1998, 1999, 2001 Free Software Foundation, Inc. +/* Copyright 1997, 1998, 1999, 2001, 2002 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. This file is part of GNU Binutils. @@ -284,11 +284,11 @@ cpp_line (s) if (!initial_fn) { initial_fn = xmalloc (strlen (fn) + 1); - strcpy(initial_fn, fn); + strcpy (initial_fn, fn); } /* Allow the initial file, regardless of name. Suppress all other - files if they end in ".h" (this allows included "*.rc") */ + files if they end in ".h" (this allows included "*.rc"). */ if (strcmp (initial_fn, fn) == 0 || strcmp (fn + strlen (fn) - 2, ".h") != 0) suppress_cpp_data = 0; @@ -331,7 +331,7 @@ handle_quotes (input, len) break; case 'a': - *s++ = ESCAPE_A; + *s++ = ESCAPE_B; /* Strange, but true... */ ++t; break; @@ -394,9 +394,9 @@ handle_quotes (input, len) if (*t >= '0' && *t <= '9') ch = (ch << 4) | (*t - '0'); else if (*t >= 'a' && *t <= 'f') - ch = (ch << 4) | (*t - 'a'); + ch = (ch << 4) | (*t - 'a' + 10); else if (*t >= 'A' && *t <= 'F') - ch = (ch << 4) | (*t - 'A'); + ch = (ch << 4) | (*t - 'A' + 10); else break; ++t; @@ -452,7 +452,7 @@ get_string (len) as->s = xmalloc (len); as->next = strings; - strings = as->next; + strings = as; return as->s; } diff --git a/contrib/binutils/binutils/rcparse.c b/contrib/binutils/binutils/rcparse.c index 90af526..9add78f 100644 --- a/contrib/binutils/binutils/rcparse.c +++ b/contrib/binutils/binutils/rcparse.c @@ -1,5 +1,5 @@ /* A Bison parser, made from rcparse.y - by GNU bison 1.33. */ + by GNU bison 1.35. */ #define YYBISON 1 /* Identify Bison output. */ @@ -89,7 +89,7 @@ #line 1 "rcparse.y" /* rcparse.y -- parser for Windows rc files - Copyright 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. This file is part of GNU Binutils. @@ -186,6 +186,7 @@ typedef union } ss; } yystype; # define YYSTYPE yystype +# define YYSTYPE_IS_TRIVIAL 1 #endif #ifndef YYDEBUG # define YYDEBUG 0 @@ -198,7 +199,7 @@ typedef union #define YYNTBASE 99 /* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */ -#define YYTRANSLATE(x) ((unsigned)(x) <= 339 ? yytranslate[x] : 191) +#define YYTRANSLATE(x) ((unsigned)(x) <= 339 ? yytranslate[x] : 189) /* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */ static const char yytranslate[] = @@ -242,126 +243,126 @@ static const char yytranslate[] = #if YYDEBUG static const short yyprhs[] = { - 0, 0, 1, 5, 9, 13, 17, 21, 25, 29, - 33, 37, 41, 45, 49, 53, 57, 61, 62, 69, - 70, 73, 76, 81, 83, 85, 87, 91, 94, 96, - 98, 100, 102, 104, 106, 111, 116, 117, 131, 132, - 146, 147, 162, 163, 167, 168, 172, 176, 177, 182, - 186, 192, 200, 204, 208, 213, 217, 218, 221, 222, - 226, 227, 231, 232, 236, 237, 241, 242, 246, 247, - 251, 263, 276, 289, 303, 304, 308, 309, 313, 314, - 318, 319, 323, 324, 328, 335, 344, 355, 367, 368, - 372, 373, 377, 378, 382, 383, 387, 388, 392, 393, - 397, 398, 402, 403, 407, 408, 412, 413, 430, 438, - 448, 459, 460, 462, 465, 466, 470, 471, 475, 476, - 480, 481, 485, 490, 495, 499, 506, 507, 510, 515, - 518, 525, 526, 530, 533, 535, 537, 539, 541, 543, - 545, 552, 553, 556, 559, 563, 569, 572, 578, 585, - 593, 603, 608, 615, 616, 619, 620, 622, 624, 626, - 630, 634, 635, 642, 643, 647, 652, 659, 664, 671, - 672, 679, 686, 690, 694, 698, 702, 706, 707, 716, - 724, 725, 731, 732, 736, 738, 740, 742, 745, 748, - 751, 753, 754, 757, 761, 766, 770, 771, 774, 775, - 778, 780, 782, 784, 786, 788, 790, 792, 794, 796, - 798, 801, 805, 810, 812, 816, 817, 819, 822, 824, - 826, 830, 833, 836, 840, 844, 848, 852, 856, 860, - 864, 868, 871, 873, 875, 879, 882, 886, 890, 894, - 898, 902, 906, 910 + 0, 0, 1, 4, 7, 10, 13, 16, 19, 22, + 25, 28, 31, 34, 37, 40, 43, 46, 53, 54, + 57, 60, 65, 67, 69, 71, 75, 78, 80, 82, + 84, 86, 88, 90, 95, 100, 101, 115, 116, 130, + 131, 146, 147, 151, 152, 156, 160, 164, 168, 172, + 178, 185, 193, 202, 206, 210, 215, 219, 220, 223, + 224, 228, 229, 233, 234, 238, 239, 243, 244, 248, + 249, 253, 265, 278, 291, 305, 306, 310, 311, 315, + 316, 320, 321, 325, 326, 330, 337, 346, 357, 369, + 370, 374, 375, 379, 380, 384, 385, 389, 390, 394, + 395, 399, 400, 404, 405, 409, 410, 414, 415, 432, + 440, 450, 461, 462, 464, 467, 468, 472, 473, 477, + 478, 482, 483, 487, 492, 497, 501, 508, 509, 512, + 517, 520, 527, 528, 532, 535, 537, 539, 541, 543, + 545, 547, 554, 555, 558, 561, 565, 571, 574, 580, + 587, 595, 605, 610, 617, 618, 621, 622, 624, 626, + 628, 632, 636, 637, 644, 645, 649, 654, 661, 666, + 673, 674, 681, 688, 692, 696, 700, 704, 708, 709, + 718, 726, 727, 733, 734, 738, 740, 742, 744, 747, + 750, 753, 755, 756, 759, 763, 768, 772, 773, 776, + 777, 780, 782, 784, 786, 788, 790, 792, 794, 796, + 798, 800, 803, 807, 812, 814, 818, 819, 821, 824, + 826, 828, 832, 835, 838, 842, 846, 850, 854, 858, + 862, 866, 870, 873, 875, 877, 881, 884, 888, 892, + 896, 900, 904, 908, 912 }; static const short yyrhs[] = { - -1, 99, 100, 101, 0, 99, 100, 107, 0, 99, - 100, 108, 0, 99, 100, 109, 0, 99, 100, 148, - 0, 99, 100, 149, 0, 99, 100, 150, 0, 99, - 100, 151, 0, 99, 100, 156, 0, 99, 100, 159, - 0, 99, 100, 160, 0, 99, 100, 165, 0, 99, - 100, 168, 0, 99, 100, 169, 0, 99, 100, 84, - 0, 0, 174, 5, 177, 3, 102, 4, 0, 0, - 102, 103, 0, 104, 188, 0, 104, 188, 95, 105, - 0, 80, 0, 189, 0, 106, 0, 105, 95, 106, - 0, 105, 106, 0, 6, 0, 7, 0, 8, 0, - 9, 0, 10, 0, 11, 0, 174, 12, 179, 181, - 0, 174, 13, 178, 181, 0, 0, 174, 14, 179, - 113, 189, 185, 185, 185, 110, 114, 3, 116, 4, - 0, 0, 174, 15, 179, 113, 189, 185, 185, 185, - 111, 114, 3, 116, 4, 0, 0, 174, 15, 179, - 113, 189, 185, 185, 185, 185, 112, 114, 3, 116, - 4, 0, 0, 16, 96, 186, 0, 0, 114, 17, - 80, 0, 114, 18, 174, 0, 0, 114, 19, 115, - 182, 0, 114, 16, 186, 0, 114, 41, 186, 95, - 80, 0, 114, 41, 186, 95, 80, 185, 185, 0, - 114, 46, 174, 0, 114, 44, 186, 0, 114, 43, - 186, 185, 0, 114, 45, 186, 0, 0, 116, 117, - 0, 0, 20, 118, 139, 0, 0, 21, 119, 139, - 0, 0, 22, 120, 139, 0, 0, 38, 121, 139, - 0, 0, 23, 122, 139, 0, 0, 24, 123, 139, - 0, 10, 140, 186, 185, 142, 185, 185, 185, 185, - 184, 141, 0, 10, 140, 186, 185, 142, 185, 185, - 185, 185, 185, 185, 141, 0, 10, 140, 186, 95, - 80, 142, 185, 185, 185, 185, 184, 141, 0, 10, - 140, 186, 95, 80, 142, 185, 185, 185, 185, 185, - 185, 141, 0, 0, 25, 124, 139, 0, 0, 26, - 125, 139, 0, 0, 27, 126, 139, 0, 0, 28, - 127, 139, 0, 0, 39, 128, 139, 0, 42, 176, - 186, 185, 185, 141, 0, 42, 176, 186, 185, 185, - 185, 185, 141, 0, 42, 176, 186, 185, 185, 185, - 185, 144, 184, 141, 0, 42, 176, 186, 185, 185, - 185, 185, 144, 185, 185, 141, 0, 0, 40, 129, - 139, 0, 0, 29, 130, 139, 0, 0, 30, 131, - 139, 0, 0, 31, 132, 139, 0, 0, 32, 133, - 139, 0, 0, 33, 134, 139, 0, 0, 34, 135, - 139, 0, 0, 35, 136, 139, 0, 0, 36, 137, - 139, 0, 0, 37, 80, 95, 186, 95, 186, 95, - 186, 95, 186, 95, 186, 95, 138, 182, 184, 0, - 140, 186, 185, 185, 185, 185, 141, 0, 140, 186, - 185, 185, 185, 185, 146, 184, 141, 0, 140, 186, - 185, 185, 185, 185, 146, 185, 185, 141, 0, 0, - 80, 0, 80, 95, 0, 0, 3, 161, 4, 0, - 0, 95, 143, 182, 0, 0, 95, 145, 182, 0, - 0, 95, 147, 182, 0, 174, 41, 178, 181, 0, - 174, 42, 178, 181, 0, 43, 186, 185, 0, 174, - 46, 177, 3, 152, 4, 0, 0, 152, 153, 0, - 48, 80, 185, 154, 0, 48, 49, 0, 50, 80, - 154, 3, 152, 4, 0, 0, 154, 95, 155, 0, - 154, 155, 0, 51, 0, 52, 0, 53, 0, 54, - 0, 55, 0, 56, 0, 174, 47, 177, 3, 157, - 4, 0, 0, 157, 158, 0, 48, 80, 0, 48, - 80, 185, 0, 48, 80, 185, 185, 184, 0, 48, - 49, 0, 50, 80, 3, 157, 4, 0, 50, 80, - 185, 3, 157, 4, 0, 50, 80, 185, 185, 3, - 157, 4, 0, 50, 80, 185, 185, 185, 184, 3, - 157, 4, 0, 174, 57, 179, 181, 0, 174, 58, - 177, 3, 161, 4, 0, 0, 162, 163, 0, 0, - 164, 0, 83, 0, 187, 0, 164, 95, 83, 0, - 164, 95, 187, 0, 0, 59, 177, 3, 166, 167, - 4, 0, 0, 167, 186, 80, 0, 167, 186, 95, - 80, 0, 174, 174, 177, 3, 161, 4, 0, 174, - 174, 177, 181, 0, 174, 60, 170, 3, 171, 4, - 0, 0, 170, 61, 186, 185, 185, 185, 0, 170, - 62, 186, 185, 185, 185, 0, 170, 63, 186, 0, - 170, 64, 186, 0, 170, 65, 186, 0, 170, 66, - 186, 0, 170, 67, 186, 0, 0, 171, 68, 3, - 71, 3, 172, 4, 4, 0, 171, 69, 3, 70, - 80, 173, 4, 0, 0, 172, 70, 80, 95, 80, - 0, 0, 173, 185, 185, 0, 189, 0, 81, 0, - 80, 0, 80, 95, 0, 81, 95, 0, 189, 95, - 0, 175, 0, 0, 177, 180, 0, 177, 44, 186, - 0, 177, 43, 186, 185, 0, 177, 45, 186, 0, - 0, 178, 180, 0, 0, 179, 180, 0, 72, 0, - 73, 0, 74, 0, 75, 0, 76, 0, 77, 0, - 78, 0, 80, 0, 81, 0, 183, 0, 79, 183, - 0, 182, 85, 183, 0, 182, 85, 79, 183, 0, - 82, 0, 97, 186, 98, 0, 0, 185, 0, 95, - 186, 0, 187, 0, 82, 0, 97, 187, 98, 0, - 93, 187, 0, 89, 187, 0, 187, 90, 187, 0, - 187, 91, 187, 0, 187, 92, 187, 0, 187, 88, - 187, 0, 187, 89, 187, 0, 187, 87, 187, 0, - 187, 86, 187, 0, 187, 85, 187, 0, 95, 189, - 0, 190, 0, 82, 0, 97, 187, 98, 0, 93, - 187, 0, 190, 90, 187, 0, 190, 91, 187, 0, - 190, 92, 187, 0, 190, 88, 187, 0, 190, 89, - 187, 0, 190, 87, 187, 0, 190, 86, 187, 0, - 190, 85, 187, 0 + -1, 99, 100, 0, 99, 106, 0, 99, 107, 0, + 99, 108, 0, 99, 146, 0, 99, 147, 0, 99, + 148, 0, 99, 149, 0, 99, 154, 0, 99, 157, + 0, 99, 158, 0, 99, 163, 0, 99, 166, 0, + 99, 167, 0, 99, 84, 0, 172, 5, 175, 3, + 101, 4, 0, 0, 101, 102, 0, 103, 186, 0, + 103, 186, 95, 104, 0, 80, 0, 187, 0, 105, + 0, 104, 95, 105, 0, 104, 105, 0, 6, 0, + 7, 0, 8, 0, 9, 0, 10, 0, 11, 0, + 172, 12, 177, 179, 0, 172, 13, 176, 179, 0, + 0, 172, 14, 177, 112, 187, 183, 183, 183, 109, + 113, 3, 114, 4, 0, 0, 172, 15, 177, 112, + 187, 183, 183, 183, 110, 113, 3, 114, 4, 0, + 0, 172, 15, 177, 112, 187, 183, 183, 183, 183, + 111, 113, 3, 114, 4, 0, 0, 16, 96, 184, + 0, 0, 113, 17, 80, 0, 113, 18, 172, 0, + 113, 19, 180, 0, 113, 16, 184, 0, 113, 18, + 80, 0, 113, 41, 184, 95, 80, 0, 113, 41, + 184, 95, 80, 183, 0, 113, 41, 184, 95, 80, + 183, 183, 0, 113, 41, 184, 95, 80, 183, 183, + 183, 0, 113, 46, 172, 0, 113, 44, 184, 0, + 113, 43, 184, 183, 0, 113, 45, 184, 0, 0, + 114, 115, 0, 0, 20, 116, 137, 0, 0, 21, + 117, 137, 0, 0, 22, 118, 137, 0, 0, 38, + 119, 137, 0, 0, 23, 120, 137, 0, 0, 24, + 121, 137, 0, 10, 138, 184, 183, 140, 183, 183, + 183, 183, 182, 139, 0, 10, 138, 184, 183, 140, + 183, 183, 183, 183, 183, 183, 139, 0, 10, 138, + 184, 95, 80, 140, 183, 183, 183, 183, 182, 139, + 0, 10, 138, 184, 95, 80, 140, 183, 183, 183, + 183, 183, 183, 139, 0, 0, 25, 122, 137, 0, + 0, 26, 123, 137, 0, 0, 27, 124, 137, 0, + 0, 28, 125, 137, 0, 0, 39, 126, 137, 0, + 42, 174, 184, 183, 183, 139, 0, 42, 174, 184, + 183, 183, 183, 183, 139, 0, 42, 174, 184, 183, + 183, 183, 183, 142, 182, 139, 0, 42, 174, 184, + 183, 183, 183, 183, 142, 183, 183, 139, 0, 0, + 40, 127, 137, 0, 0, 29, 128, 137, 0, 0, + 30, 129, 137, 0, 0, 31, 130, 137, 0, 0, + 32, 131, 137, 0, 0, 33, 132, 137, 0, 0, + 34, 133, 137, 0, 0, 35, 134, 137, 0, 0, + 36, 135, 137, 0, 0, 37, 80, 95, 184, 95, + 184, 95, 184, 95, 184, 95, 184, 95, 136, 180, + 182, 0, 138, 184, 183, 183, 183, 183, 139, 0, + 138, 184, 183, 183, 183, 183, 144, 182, 139, 0, + 138, 184, 183, 183, 183, 183, 144, 183, 183, 139, + 0, 0, 80, 0, 80, 95, 0, 0, 3, 159, + 4, 0, 0, 95, 141, 180, 0, 0, 95, 143, + 180, 0, 0, 95, 145, 180, 0, 172, 41, 176, + 179, 0, 172, 42, 176, 179, 0, 43, 184, 183, + 0, 172, 46, 175, 3, 150, 4, 0, 0, 150, + 151, 0, 48, 80, 183, 152, 0, 48, 49, 0, + 50, 80, 152, 3, 150, 4, 0, 0, 152, 95, + 153, 0, 152, 153, 0, 51, 0, 52, 0, 53, + 0, 54, 0, 55, 0, 56, 0, 172, 47, 175, + 3, 155, 4, 0, 0, 155, 156, 0, 48, 80, + 0, 48, 80, 183, 0, 48, 80, 183, 183, 182, + 0, 48, 49, 0, 50, 80, 3, 155, 4, 0, + 50, 80, 183, 3, 155, 4, 0, 50, 80, 183, + 183, 3, 155, 4, 0, 50, 80, 183, 183, 183, + 182, 3, 155, 4, 0, 172, 57, 177, 179, 0, + 172, 58, 175, 3, 159, 4, 0, 0, 160, 161, + 0, 0, 162, 0, 83, 0, 185, 0, 162, 95, + 83, 0, 162, 95, 185, 0, 0, 59, 175, 3, + 164, 165, 4, 0, 0, 165, 184, 80, 0, 165, + 184, 95, 80, 0, 172, 172, 175, 3, 159, 4, + 0, 172, 172, 175, 179, 0, 172, 60, 168, 3, + 169, 4, 0, 0, 168, 61, 184, 183, 183, 183, + 0, 168, 62, 184, 183, 183, 183, 0, 168, 63, + 184, 0, 168, 64, 184, 0, 168, 65, 184, 0, + 168, 66, 184, 0, 168, 67, 184, 0, 0, 169, + 68, 3, 71, 3, 170, 4, 4, 0, 169, 69, + 3, 70, 80, 171, 4, 0, 0, 170, 70, 80, + 95, 80, 0, 0, 171, 183, 183, 0, 187, 0, + 81, 0, 80, 0, 80, 95, 0, 81, 95, 0, + 187, 95, 0, 173, 0, 0, 175, 178, 0, 175, + 44, 184, 0, 175, 43, 184, 183, 0, 175, 45, + 184, 0, 0, 176, 178, 0, 0, 177, 178, 0, + 72, 0, 73, 0, 74, 0, 75, 0, 76, 0, + 77, 0, 78, 0, 80, 0, 81, 0, 181, 0, + 79, 181, 0, 180, 85, 181, 0, 180, 85, 79, + 181, 0, 82, 0, 97, 184, 98, 0, 0, 183, + 0, 95, 184, 0, 185, 0, 82, 0, 97, 185, + 98, 0, 93, 185, 0, 89, 185, 0, 185, 90, + 185, 0, 185, 91, 185, 0, 185, 92, 185, 0, + 185, 88, 185, 0, 185, 89, 185, 0, 185, 87, + 185, 0, 185, 86, 185, 0, 185, 85, 185, 0, + 95, 187, 0, 188, 0, 82, 0, 97, 185, 98, + 0, 93, 185, 0, 188, 90, 185, 0, 188, 91, + 185, 0, 188, 92, 185, 0, 188, 88, 185, 0, + 188, 89, 185, 0, 188, 87, 185, 0, 188, 86, + 185, 0, 188, 85, 185, 0 }; #endif @@ -371,30 +372,30 @@ static const short yyrhs[] = static const short yyrline[] = { 0, 154, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 165, 166, 167, 168, 169, 170, 173, 182, 189, - 194, 214, 220, 231, 253, 262, 267, 272, 278, 283, - 288, 292, 296, 300, 308, 317, 326, 326, 348, 348, - 371, 371, 397, 402, 408, 410, 414, 418, 418, 424, - 428, 434, 447, 451, 455, 459, 465, 467, 477, 477, - 488, 488, 498, 498, 508, 508, 521, 521, 531, 531, - 541, 552, 561, 574, 585, 585, 595, 595, 605, 605, - 615, 615, 625, 625, 638, 643, 649, 655, 661, 661, - 674, 674, 684, 684, 694, 694, 704, 704, 714, 714, - 724, 724, 734, 734, 744, 744, 754, 754, 771, 784, - 795, 806, 811, 815, 821, 826, 834, 834, 840, 840, - 846, 846, 854, 863, 873, 882, 889, 894, 910, 915, - 919, 925, 930, 934, 940, 945, 949, 953, 957, 961, - 969, 976, 981, 997, 1002, 1006, 1010, 1014, 1018, 1022, - 1026, 1035, 1044, 1054, 1054, 1065, 1071, 1077, 1086, 1094, - 1103, 1116, 1116, 1122, 1124, 1128, 1137, 1142, 1150, 1157, - 1164, 1170, 1176, 1181, 1186, 1191, 1196, 1209, 1214, 1218, - 1224, 1229, 1235, 1240, 1248, 1254, 1269, 1274, 1278, 1285, - 1291, 1307, 1315, 1321, 1326, 1331, 1340, 1347, 1357, 1364, - 1375, 1381, 1386, 1391, 1396, 1401, 1406, 1415, 1420, 1436, - 1441, 1445, 1449, 1455, 1460, 1468, 1473, 1481, 1490, 1499, - 1504, 1508, 1513, 1518, 1523, 1528, 1533, 1538, 1543, 1548, - 1553, 1563, 1572, 1583, 1588, 1592, 1597, 1602, 1607, 1612, - 1617, 1622, 1627, 1632 + 164, 165, 166, 167, 168, 169, 170, 175, 185, 190, + 210, 216, 227, 249, 258, 263, 268, 274, 279, 284, + 288, 292, 296, 304, 316, 328, 328, 354, 354, 381, + 381, 411, 416, 422, 424, 430, 434, 439, 443, 447, + 460, 475, 490, 505, 509, 513, 517, 523, 525, 535, + 535, 546, 546, 556, 556, 566, 566, 579, 579, 589, + 589, 599, 610, 619, 632, 643, 643, 653, 653, 663, + 663, 673, 673, 683, 683, 696, 701, 707, 713, 719, + 719, 732, 732, 742, 742, 752, 752, 762, 762, 772, + 772, 782, 782, 792, 792, 802, 802, 812, 812, 829, + 842, 853, 864, 869, 873, 879, 884, 892, 892, 898, + 898, 904, 904, 912, 924, 937, 946, 956, 961, 977, + 982, 986, 992, 997, 1001, 1007, 1012, 1016, 1020, 1024, + 1028, 1036, 1046, 1051, 1067, 1072, 1076, 1080, 1084, 1088, + 1092, 1096, 1105, 1117, 1130, 1130, 1141, 1147, 1153, 1162, + 1170, 1179, 1192, 1192, 1198, 1200, 1207, 1219, 1227, 1238, + 1248, 1255, 1261, 1267, 1272, 1277, 1282, 1287, 1300, 1305, + 1309, 1315, 1320, 1326, 1331, 1339, 1345, 1360, 1365, 1369, + 1376, 1382, 1398, 1406, 1412, 1417, 1422, 1431, 1438, 1448, + 1455, 1466, 1472, 1477, 1482, 1487, 1492, 1497, 1506, 1511, + 1527, 1532, 1536, 1540, 1546, 1551, 1559, 1564, 1572, 1581, + 1590, 1595, 1599, 1604, 1609, 1614, 1619, 1624, 1629, 1634, + 1639, 1644, 1654, 1663, 1674, 1679, 1683, 1688, 1693, 1698, + 1703, 1708, 1713, 1718, 1723 }; #endif @@ -420,22 +421,22 @@ static const char *const yytname[] = "IMPURE", "PRELOAD", "LOADONCALL", "DISCARDABLE", "NOT", "QUOTEDSTRING", "STRING", "NUMBER", "SIZEDSTRING", "IGNORED_TOKEN", "'|'", "'^'", "'&'", "'+'", "'-'", "'*'", "'/'", "'%'", "'~'", "NEG", "','", "'='", "'('", - "')'", "input", "newcmd", "accelerator", "acc_entries", "acc_entry", - "acc_event", "acc_options", "acc_option", "bitmap", "cursor", "dialog", - "@1", "@2", "@3", "exstyle", "styles", "@4", "controls", "control", - "@5", "@6", "@7", "@8", "@9", "@10", "@11", "@12", "@13", "@14", "@15", - "@16", "@17", "@18", "@19", "@20", "@21", "@22", "@23", "@24", "@25", + "')'", "input", "accelerator", "acc_entries", "acc_entry", "acc_event", + "acc_options", "acc_option", "bitmap", "cursor", "dialog", "@1", "@2", + "@3", "exstyle", "styles", "controls", "control", "@4", "@5", "@6", + "@7", "@8", "@9", "@10", "@11", "@12", "@13", "@14", "@15", "@16", + "@17", "@18", "@19", "@20", "@21", "@22", "@23", "@24", "control_params", "optstringc", "opt_control_data", "control_styleexpr", - "@26", "icon_styleexpr", "@27", "control_params_styleexpr", "@28", + "@25", "icon_styleexpr", "@26", "control_params_styleexpr", "@27", "font", "icon", "language", "menu", "menuitems", "menuitem", "menuitem_flags", "menuitem_flag", "menuex", "menuexitems", - "menuexitem", "messagetable", "rcdata", "optrcdata_data", "@29", - "optrcdata_data_int", "rcdata_data", "stringtable", "@30", + "menuexitem", "messagetable", "rcdata", "optrcdata_data", "@28", + "optrcdata_data_int", "rcdata_data", "stringtable", "@29", "string_data", "user", "versioninfo", "fixedverinfo", "verblocks", "vervals", "vertrans", "id", "resname", "resref", "suboptions", "memflags_move_discard", "memflags_move", "memflag", "file_name", "styleexpr", "parennumber", "optcnumexpr", "cnumexpr", "numexpr", - "sizednumexpr", "cposnumexpr", "posnumexpr", "sizedposnumexpr", NULL + "sizednumexpr", "cposnumexpr", "posnumexpr", "sizedposnumexpr", 0 }; #endif @@ -443,60 +444,60 @@ static const char *const yytname[] = static const short yyr1[] = { 0, 99, 99, 99, 99, 99, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 99, 99, 100, 101, 102, - 102, 103, 103, 104, 104, 105, 105, 105, 106, 106, - 106, 106, 106, 106, 107, 108, 110, 109, 111, 109, - 112, 109, 113, 113, 114, 114, 114, 115, 114, 114, - 114, 114, 114, 114, 114, 114, 116, 116, 118, 117, - 119, 117, 120, 117, 121, 117, 122, 117, 123, 117, - 117, 117, 117, 117, 124, 117, 125, 117, 126, 117, - 127, 117, 128, 117, 117, 117, 117, 117, 129, 117, - 130, 117, 131, 117, 132, 117, 133, 117, 134, 117, - 135, 117, 136, 117, 137, 117, 138, 117, 139, 139, - 139, 140, 140, 140, 141, 141, 143, 142, 145, 144, - 147, 146, 148, 149, 150, 151, 152, 152, 153, 153, - 153, 154, 154, 154, 155, 155, 155, 155, 155, 155, - 156, 157, 157, 158, 158, 158, 158, 158, 158, 158, - 158, 159, 160, 162, 161, 163, 163, 164, 164, 164, - 164, 166, 165, 167, 167, 167, 168, 168, 169, 170, - 170, 170, 170, 170, 170, 170, 170, 171, 171, 171, - 172, 172, 173, 173, 174, 174, 175, 175, 175, 176, - 176, 177, 177, 177, 177, 177, 178, 178, 179, 179, - 180, 180, 180, 180, 180, 180, 180, 181, 181, 182, - 182, 182, 182, 183, 183, 184, 184, 185, 186, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 188, 189, 190, 190, 190, 190, 190, 190, 190, - 190, 190, 190, 190 + 99, 99, 99, 99, 99, 99, 99, 100, 101, 101, + 102, 102, 103, 103, 104, 104, 104, 105, 105, 105, + 105, 105, 105, 106, 107, 109, 108, 110, 108, 111, + 108, 112, 112, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 114, 114, 116, + 115, 117, 115, 118, 115, 119, 115, 120, 115, 121, + 115, 115, 115, 115, 115, 122, 115, 123, 115, 124, + 115, 125, 115, 126, 115, 115, 115, 115, 115, 127, + 115, 128, 115, 129, 115, 130, 115, 131, 115, 132, + 115, 133, 115, 134, 115, 135, 115, 136, 115, 137, + 137, 137, 138, 138, 138, 139, 139, 141, 140, 143, + 142, 145, 144, 146, 147, 148, 149, 150, 150, 151, + 151, 151, 152, 152, 152, 153, 153, 153, 153, 153, + 153, 154, 155, 155, 156, 156, 156, 156, 156, 156, + 156, 156, 157, 158, 160, 159, 161, 161, 162, 162, + 162, 162, 164, 163, 165, 165, 165, 166, 166, 167, + 168, 168, 168, 168, 168, 168, 168, 168, 169, 169, + 169, 170, 170, 171, 171, 172, 172, 173, 173, 173, + 174, 174, 175, 175, 175, 175, 175, 176, 176, 177, + 177, 178, 178, 178, 178, 178, 178, 178, 179, 179, + 180, 180, 180, 180, 181, 181, 182, 182, 183, 184, + 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 186, 187, 188, 188, 188, 188, 188, 188, + 188, 188, 188, 188, 188 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const short yyr2[] = { - 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 0, 6, 0, - 2, 2, 4, 1, 1, 1, 3, 2, 1, 1, - 1, 1, 1, 1, 4, 4, 0, 13, 0, 13, - 0, 14, 0, 3, 0, 3, 3, 0, 4, 3, - 5, 7, 3, 3, 4, 3, 0, 2, 0, 3, - 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, - 11, 12, 12, 13, 0, 3, 0, 3, 0, 3, - 0, 3, 0, 3, 6, 8, 10, 11, 0, 3, - 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, - 0, 3, 0, 3, 0, 3, 0, 16, 7, 9, - 10, 0, 1, 2, 0, 3, 0, 3, 0, 3, - 0, 3, 4, 4, 3, 6, 0, 2, 4, 2, - 6, 0, 3, 2, 1, 1, 1, 1, 1, 1, - 6, 0, 2, 2, 3, 5, 2, 5, 6, 7, - 9, 4, 6, 0, 2, 0, 1, 1, 1, 3, - 3, 0, 6, 0, 3, 4, 6, 4, 6, 0, - 6, 6, 3, 3, 3, 3, 3, 0, 8, 7, - 0, 5, 0, 3, 1, 1, 1, 2, 2, 2, - 1, 0, 2, 3, 4, 3, 0, 2, 0, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 3, 4, 1, 3, 0, 1, 2, 1, 1, - 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 2, 1, 1, 3, 2, 3, 3, 3, 3, - 3, 3, 3, 3 + 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 6, 0, 2, + 2, 4, 1, 1, 1, 3, 2, 1, 1, 1, + 1, 1, 1, 4, 4, 0, 13, 0, 13, 0, + 14, 0, 3, 0, 3, 3, 3, 3, 3, 5, + 6, 7, 8, 3, 3, 4, 3, 0, 2, 0, + 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, + 3, 11, 12, 12, 13, 0, 3, 0, 3, 0, + 3, 0, 3, 0, 3, 6, 8, 10, 11, 0, + 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, + 3, 0, 3, 0, 3, 0, 3, 0, 16, 7, + 9, 10, 0, 1, 2, 0, 3, 0, 3, 0, + 3, 0, 3, 4, 4, 3, 6, 0, 2, 4, + 2, 6, 0, 3, 2, 1, 1, 1, 1, 1, + 1, 6, 0, 2, 2, 3, 5, 2, 5, 6, + 7, 9, 4, 6, 0, 2, 0, 1, 1, 1, + 3, 3, 0, 6, 0, 3, 4, 6, 4, 6, + 0, 6, 6, 3, 3, 3, 3, 3, 0, 8, + 7, 0, 5, 0, 3, 1, 1, 1, 2, 2, + 2, 1, 0, 2, 3, 4, 3, 0, 2, 0, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 3, 4, 1, 3, 0, 1, 2, 1, + 1, 3, 2, 2, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 1, 1, 3, 2, 3, 3, 3, + 3, 3, 3, 3, 3 }; /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE @@ -504,290 +505,290 @@ static const short yyr2[] = error. */ static const short yydefact[] = { - 1, 17, 0, 0, 191, 185, 233, 16, 0, 0, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 0, 184, 232, 219, 0, 0, - 0, 0, 218, 0, 235, 0, 191, 198, 196, 198, - 198, 196, 196, 191, 191, 198, 191, 169, 191, 0, - 0, 0, 0, 0, 0, 0, 0, 222, 221, 0, - 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, - 161, 0, 0, 0, 200, 201, 202, 203, 204, 205, - 206, 192, 234, 0, 0, 0, 42, 42, 0, 0, - 0, 0, 0, 0, 0, 0, 243, 242, 241, 239, - 240, 236, 237, 238, 220, 217, 230, 229, 228, 226, - 227, 223, 224, 225, 163, 0, 193, 195, 19, 207, - 208, 199, 34, 197, 35, 0, 0, 0, 122, 123, - 126, 141, 151, 153, 177, 0, 0, 0, 0, 0, - 0, 0, 153, 167, 0, 194, 0, 0, 0, 0, - 0, 0, 0, 155, 0, 0, 0, 172, 173, 174, - 175, 176, 0, 162, 0, 18, 23, 20, 0, 24, - 43, 0, 0, 125, 0, 0, 127, 140, 0, 0, - 142, 152, 157, 154, 156, 158, 168, 0, 0, 0, - 0, 166, 164, 0, 0, 21, 0, 0, 129, 0, - 131, 146, 143, 0, 0, 0, 0, 0, 0, 165, - 231, 0, 36, 38, 131, 0, 144, 141, 0, 159, - 160, 0, 0, 170, 171, 28, 29, 30, 31, 32, - 33, 22, 25, 44, 44, 40, 128, 126, 134, 135, - 136, 137, 138, 139, 0, 133, 215, 0, 141, 0, - 180, 182, 0, 27, 0, 0, 44, 0, 132, 145, - 216, 147, 0, 141, 215, 0, 0, 26, 56, 0, - 0, 0, 47, 0, 0, 0, 0, 0, 56, 0, - 130, 148, 0, 0, 0, 0, 179, 0, 0, 49, - 45, 46, 0, 0, 0, 53, 55, 52, 0, 56, - 149, 141, 178, 0, 183, 37, 111, 58, 60, 62, - 66, 68, 74, 76, 78, 80, 90, 92, 94, 96, - 98, 100, 102, 104, 0, 64, 82, 88, 0, 57, - 0, 213, 0, 48, 209, 0, 54, 39, 0, 0, - 0, 112, 0, 111, 111, 111, 111, 111, 111, 111, - 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, - 0, 111, 111, 111, 186, 0, 190, 0, 0, 210, - 0, 0, 50, 41, 150, 181, 113, 0, 59, 0, - 61, 63, 67, 69, 75, 77, 79, 81, 91, 93, - 95, 97, 99, 101, 103, 105, 0, 65, 83, 89, - 187, 188, 0, 189, 214, 0, 211, 0, 0, 0, - 0, 0, 0, 212, 51, 0, 116, 0, 0, 0, - 114, 0, 0, 0, 0, 0, 153, 84, 0, 0, - 117, 0, 0, 0, 0, 114, 0, 0, 114, 0, - 115, 118, 85, 215, 0, 215, 120, 108, 215, 0, - 0, 114, 216, 215, 114, 216, 0, 114, 216, 0, - 119, 86, 114, 114, 216, 70, 114, 121, 109, 114, - 0, 87, 72, 114, 71, 110, 0, 73, 106, 0, - 215, 107, 0, 0 + 1, 0, 0, 192, 186, 234, 16, 0, 0, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 185, 233, 220, 0, 0, 0, + 0, 219, 0, 236, 0, 192, 199, 197, 199, 199, + 197, 197, 192, 192, 199, 192, 170, 192, 0, 0, + 0, 0, 0, 0, 0, 0, 223, 222, 0, 0, + 125, 0, 0, 0, 0, 0, 0, 0, 0, 162, + 0, 0, 0, 201, 202, 203, 204, 205, 206, 207, + 193, 235, 0, 0, 0, 41, 41, 0, 0, 0, + 0, 0, 0, 0, 0, 244, 243, 242, 240, 241, + 237, 238, 239, 221, 218, 231, 230, 229, 227, 228, + 224, 225, 226, 164, 0, 194, 196, 18, 208, 209, + 200, 33, 198, 34, 0, 0, 0, 123, 124, 127, + 142, 152, 154, 178, 0, 0, 0, 0, 0, 0, + 0, 154, 168, 0, 195, 0, 0, 0, 0, 0, + 0, 0, 156, 0, 0, 0, 173, 174, 175, 176, + 177, 0, 163, 0, 17, 22, 19, 0, 23, 42, + 0, 0, 126, 0, 0, 128, 141, 0, 0, 143, + 153, 158, 155, 157, 159, 169, 0, 0, 0, 0, + 167, 165, 0, 0, 20, 0, 0, 130, 0, 132, + 147, 144, 0, 0, 0, 0, 0, 0, 166, 232, + 0, 35, 37, 132, 0, 145, 142, 0, 160, 161, + 0, 0, 171, 172, 27, 28, 29, 30, 31, 32, + 21, 24, 43, 43, 39, 129, 127, 135, 136, 137, + 138, 139, 140, 0, 134, 216, 0, 142, 0, 181, + 183, 0, 26, 0, 0, 43, 0, 133, 146, 217, + 148, 0, 142, 216, 0, 0, 25, 57, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 57, 0, 131, + 149, 0, 0, 0, 0, 180, 0, 0, 47, 44, + 48, 45, 0, 214, 0, 46, 210, 0, 0, 54, + 56, 53, 0, 57, 150, 142, 179, 0, 184, 36, + 112, 59, 61, 63, 67, 69, 75, 77, 79, 81, + 91, 93, 95, 97, 99, 101, 103, 105, 0, 65, + 83, 89, 0, 58, 211, 0, 0, 0, 55, 38, + 0, 0, 0, 113, 0, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 0, 112, 112, 112, 187, 0, 191, 0, + 0, 215, 0, 212, 49, 40, 151, 182, 114, 0, + 60, 0, 62, 64, 68, 70, 76, 78, 80, 82, + 92, 94, 96, 98, 100, 102, 104, 106, 0, 66, + 84, 90, 188, 189, 0, 190, 213, 50, 0, 0, + 0, 0, 0, 51, 0, 117, 0, 0, 0, 115, + 52, 0, 0, 0, 0, 0, 154, 85, 0, 0, + 118, 0, 0, 0, 0, 115, 0, 0, 115, 0, + 116, 119, 86, 216, 0, 216, 121, 109, 216, 0, + 0, 115, 217, 216, 115, 217, 0, 115, 217, 0, + 120, 87, 115, 115, 217, 71, 115, 122, 110, 115, + 0, 88, 73, 115, 72, 111, 0, 74, 107, 0, + 216, 108, 0, 0 }; static const short yydefgoto[] = { - 1, 2, 10, 146, 167, 168, 231, 232, 11, 12, - 13, 233, 234, 256, 126, 254, 292, 288, 329, 343, - 344, 345, 361, 346, 347, 348, 349, 350, 351, 362, - 363, 352, 353, 354, 355, 356, 357, 358, 359, 479, - 378, 379, 427, 417, 422, 443, 450, 448, 456, 14, - 15, 16, 17, 150, 176, 215, 245, 18, 151, 180, - 19, 20, 152, 153, 183, 184, 21, 114, 144, 22, - 23, 94, 154, 265, 266, 24, 366, 367, 33, 85, - 84, 81, 122, 333, 334, 259, 260, 105, 32, 195, - 25, 26 + 1, 9, 145, 166, 167, 230, 231, 10, 11, 12, + 232, 233, 255, 125, 253, 287, 333, 345, 346, 347, + 363, 348, 349, 350, 351, 352, 353, 364, 365, 354, + 355, 356, 357, 358, 359, 360, 361, 479, 380, 381, + 427, 416, 422, 443, 450, 448, 456, 13, 14, 15, + 16, 149, 175, 214, 244, 17, 150, 179, 18, 19, + 151, 152, 182, 183, 20, 113, 143, 21, 22, 93, + 153, 264, 265, 23, 368, 369, 32, 84, 83, 80, + 121, 295, 296, 258, 259, 104, 31, 194, 24, 25 }; static const short yypact[] = { - -32768, 31, 240, 241,-32768,-32768,-32768,-32768, 241, 241, + -32768, 13, 412,-32768,-32768,-32768,-32768, 412, 412,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - -32768,-32768,-32768,-32768, 68,-32768, 578,-32768, 241, 241, - 241, -73, 586, 169,-32768, 388,-32768,-32768,-32768,-32768, - -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 241, - 241, 241, 241, 241, 241, 241, 241,-32768,-32768, 513, - 241,-32768, 241, 241, 241, 241, 241, 241, 241, 241, - -32768, 241, 241, 241,-32768,-32768,-32768,-32768,-32768,-32768, - -32768,-32768,-32768, 215, 581, 581, 268, 268, 581, 581, - 232, 275, 581, 283, 250, 156, 593, 599, 616, 98, - 98,-32768,-32768,-32768,-32768,-32768, 593, 599, 616, 98, - 98,-32768,-32768,-32768,-32768, -73,-32768,-32768,-32768,-32768, - -32768,-32768,-32768,-32768,-32768, -61, 290, 290,-32768,-32768, - -32768,-32768,-32768,-32768,-32768, 241, 241, 241, 241, 241, - 241, 241,-32768,-32768, 4,-32768, 5, 241, -73, -73, - 9, 92, 32, 309, 10, -73, -73,-32768,-32768,-32768, - -32768,-32768, 54,-32768, -57,-32768,-32768,-32768, -20,-32768, - -32768, -73, -73,-32768, 39, -9,-32768,-32768, 40, 11, - -32768,-32768,-32768,-32768, 36, 586,-32768, 145, 151, -73, - -73,-32768,-32768, 78, 290, 79, -73, -73,-32768, -73, - -32768,-32768, -73, 16, 365, 106, 108, -73, -73,-32768, - -32768, 686,-32768, -73,-32768, 52, -73,-32768, 17,-32768, - 586, 178, 128,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - -32768, 34,-32768,-32768,-32768,-32768, 314,-32768,-32768,-32768, - -32768,-32768,-32768,-32768, 647,-32768, -73, 95,-32768, 18, - -32768,-32768, 686,-32768, 150, 378,-32768, 112,-32768,-32768, - -32768,-32768, 123,-32768, -73, 6, 29,-32768,-32768, 241, - 129, 281,-32768, 241, 241, 241, 241, 281,-32768, 452, - -32768,-32768, 135, 200, 213, 143,-32768, -73, 479,-32768, - -32768,-32768, 182, 91, -73,-32768,-32768,-32768, 516,-32768, - -32768,-32768,-32768, 130,-32768,-32768, 147,-32768,-32768,-32768, - -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - -32768,-32768,-32768,-32768, 158,-32768,-32768,-32768, 170,-32768, - 73,-32768, 241, 154,-32768, 160,-32768,-32768, 553, 172, - 168, 161, 241, 147, 147, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, - 173, 147, 147, 147, 174, 186,-32768, 241, 187,-32768, - 196, 183, -73,-32768,-32768,-32768,-32768, 201,-32768, 241, - -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - -32768,-32768,-32768,-32768,-32768,-32768, 241,-32768,-32768,-32768, - -32768,-32768, -73,-32768,-32768, 73,-32768, -73, 293, 202, - -73, 203, -73,-32768,-32768, 202,-32768, -73, -73, 241, - 22, -73, 182, -73, -73, 205,-32768,-32768, -73, -73, - 154, -73, -73, 241, 297, 26, -73, -73, 27, 208, - -32768,-32768,-32768, -73, -73, -73,-32768,-32768, -73, 241, - 182, 251, -73, -73, 251, -73, 182, 251, -73, 230, - 154,-32768, 251, 251, -73,-32768, 251, 154,-32768, 251, - 241,-32768,-32768, 251,-32768,-32768, 236,-32768,-32768, 182, - -11,-32768, 332,-32768 + -32768,-32768,-32768, 111,-32768, 511,-32768, 412, 412, 412, + -79, 600, 244,-32768, 562,-32768,-32768,-32768,-32768,-32768, + -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 412, 412, + 412, 412, 412, 412, 412, 412,-32768,-32768, 576, 412, + -32768, 412, 412, 412, 412, 412, 412, 412, 412,-32768, + 412, 412, 412,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + -32768,-32768, 256, 603, 603, 297, 297, 603, 603, 280, + 337, 603, 345, 100, 231, 607, 613, 567, 172, 172, + -32768,-32768,-32768,-32768,-32768, 607, 613, 567, 172, 172, + -32768,-32768,-32768,-32768, -79,-32768,-32768,-32768,-32768,-32768, + -32768,-32768,-32768,-32768, -60, 63, 63,-32768,-32768,-32768, + -32768,-32768,-32768,-32768, 412, 412, 412, 412, 412, 412, + 412,-32768,-32768, 7,-32768, 5, 412, -79, -79, 33, + 34, 35, 254, 51, -79, -79,-32768,-32768,-32768,-32768, + -32768, 36,-32768, 60,-32768,-32768,-32768, -38,-32768,-32768, + -79, -79,-32768, -39, 11,-32768,-32768, 59, 25,-32768, + -32768,-32768,-32768, 27, 600,-32768, 127, 144, -79, -79, + -32768,-32768, 74, 63, 87, -79, -79,-32768, -79,-32768, + -32768, -79, 12, 294, 118, 128, -79, -79,-32768,-32768, + 700,-32768, -79,-32768, 22, -79,-32768, 14,-32768, 600, + 194, 121,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + 23,-32768,-32768,-32768,-32768, 309,-32768,-32768,-32768,-32768, + -32768,-32768,-32768, 661,-32768, -79, 38,-32768, 16,-32768, + -32768, 700,-32768, 383, 472,-32768, 42,-32768,-32768,-32768, + -32768, 124,-32768, -79, 10, 4,-32768,-32768, 412, 126, + 187, 99, 412, 412, 412, 412, 200,-32768, 480,-32768, + -32768, 125, 204, 207, 135,-32768, -79, 510,-32768,-32768, + -32768,-32768, 49,-32768, 412, 136,-32768, 133, -79,-32768, + -32768,-32768, 547,-32768,-32768,-32768,-32768, 134,-32768,-32768, + 152,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 153,-32768, + -32768,-32768, 374,-32768,-32768, 140, 112, 157,-32768,-32768, + 584, 138, 160, 148, 412, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 158, 152, 152, 152, 161, 163,-32768, 412, + 165,-32768, 49,-32768, -79,-32768,-32768,-32768,-32768, 170, + -32768, 412,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 412,-32768, + -32768,-32768,-32768,-32768, -79,-32768,-32768, -79, 123, 183, + -79, 184, -79, -79, 183,-32768, -79, -79, 412, 17, + -32768, -79, 99, -79, -79, 190,-32768,-32768, -79, -79, + 136, -79, -79, 412, 248, 18, -79, -79, 19, 195, + -32768,-32768,-32768, -79, -79, -79,-32768,-32768, -79, 412, + 99, 245, -79, -79, 245, -79, 99, 245, -79, 196, + 136,-32768, 245, 245, -79,-32768, 245, 136,-32768, 245, + 412,-32768,-32768, 245,-32768,-32768, 201,-32768,-32768, 99, + 64,-32768, 295,-32768 }; static const short yypgoto[] = { - -32768,-32768,-32768,-32768,-32768,-32768,-32768, -220,-32768,-32768, - -32768,-32768,-32768,-32768, 248, -222,-32768, -262,-32768,-32768, - -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + -32768,-32768,-32768,-32768,-32768,-32768, -206,-32768,-32768,-32768, + -32768,-32768,-32768, 212, -85, -259,-32768,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - 289, 30, 159, -44,-32768,-32768,-32768,-32768,-32768,-32768, - -32768,-32768,-32768, 117,-32768, 163, 140,-32768, -171,-32768, - -32768,-32768, -141,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - -32768,-32768,-32768,-32768,-32768, -22,-32768,-32768, 486, -24, - 55, 480, 316, -304, -315, -261, 8, -3, -2,-32768, - -122,-32768 + -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 281, -8, + -212, -104,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + -32768, 78,-32768, 113, 92,-32768, -204,-32768,-32768,-32768, + -140,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + -32768,-32768,-32768, -21,-32768,-32768, 350, 139, 175, 475, + 416, -329, -257, -258, 29, -2, -1,-32768, -122,-32768 }; -#define YYLAST 708 +#define YYLAST 717 static const short yytable[] = { - 31, 162, 48, 283, 148, 149, 34, 35, 163, 165, - 284, 253, 255, 173, 186, 369, 298, 88, 89, 217, - 248, 263, 60, 192, 169, 426, 57, 58, 59, 426, - 426, 482, 267, 286, 279, 147, 181, 338, 193, 61, - 225, 226, 227, 228, 229, 230, 247, 96, 97, 98, - 99, 100, 101, 102, 103, 237, 406, 174, 191, 175, - 106, 107, 108, 109, 110, 111, 112, 113, 115, 116, - 117, 200, 210, 36, 371, 194, 285, 262, 187, 188, - 37, 38, 39, 40, 60, 166, 27, 6, 198, 201, - 413, 203, 282, 28, 86, 87, 177, 29, 8, 261, - 92, 30, 9, 238, 239, 240, 241, 242, 243, 41, - 42, 60, 60, 60, 43, 44, 280, 60, 430, 199, - 202, 441, 446, 145, 60, 45, 46, 281, 47, 252, - 339, 204, 155, 156, 157, 158, 159, 160, 161, 300, - 178, 164, 179, 178, 170, 179, 460, 244, 205, 5, - 6, 185, 467, 268, 206, 331, 171, 172, 209, 142, - 174, 8, 175, 189, 190, 9, 269, 270, 271, 272, - 332, 178, 70, 179, 211, 480, 374, 221, 222, 196, - 197, 250, 451, 178, 454, 179, 335, 457, 67, 68, - 69, 273, 463, 274, 275, 276, 277, 207, 208, 71, - 72, 73, 220, 301, 212, 213, 368, 214, 251, 290, - 216, 218, 71, 72, 73, 223, 224, 302, 118, 481, - 178, 235, 179, 303, 246, 340, 249, 341, 74, 75, - 76, 77, 78, 79, 80, 130, 119, 120, 360, 371, - 372, 74, 75, 76, 77, 78, 79, 80, 375, 291, - 364, 365, 6, 134, 426, 297, 376, 264, 71, 72, - 73, 330, 405, 8, 331, 331, 289, 9, 396, 400, - 293, 294, 295, 296, 287, 71, 72, 73, 131, 332, - 332, 401, 403, 3, 125, 434, 133, 74, 75, 76, - 77, 78, 79, 80, 404, 304, 408, 416, 419, 4, - 433, 440, 336, 449, 74, 75, 76, 77, 78, 79, - 80, 135, 136, 137, 138, 139, 140, 141, 71, 72, - 73, 5, 6, 27, 7, 470, 71, 72, 73, 370, - 28, 478, 483, 8, 29, 127, 342, 9, 30, 377, - 74, 75, 76, 77, 78, 79, 80, 74, 75, 76, - 77, 78, 79, 80, 257, 74, 75, 76, 77, 78, - 79, 80, 5, 6, 402, 238, 239, 240, 241, 242, - 243, 421, 6, 415, 8, 27, 410, 236, 9, 0, - 407, 278, 28, 8, 258, 409, 29, 9, 0, 0, - 30, 27, 182, 411, 269, 270, 271, 272, 28, 0, - 0, 124, 29, 0, 128, 129, 30, 0, 132, 244, - 412, 143, 0, 0, 0, 414, 425, 0, 418, 273, - 420, 274, 275, 276, 277, 423, 424, 0, 428, 429, - 439, 431, 432, 0, 0, 0, 435, 436, 0, 437, - 438, 0, 0, 0, 444, 445, 459, 27, 219, 0, - 0, 452, 453, 455, 28, 299, 458, 0, 29, 0, - 462, 464, 30, 466, 0, 0, 469, 476, 269, 270, - 271, 272, 473, 62, 63, 64, 65, 66, 67, 68, - 69, 0, 0, 305, 0, 0, 82, 0, 0, 306, - 0, 0, 0, 273, 0, 274, 275, 276, 277, 307, - 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, - 337, 328, 83, 0, 0, 0, 306, 0, 0, 90, - 91, 0, 93, 0, 95, 0, 307, 308, 309, 310, + 30, 161, 47, 147, 148, 282, 33, 34, 285, 164, + 197, 162, 246, 482, 283, 216, 59, 247, 302, 262, + 426, 426, 426, 168, 252, 236, 56, 57, 58, 224, + 225, 226, 227, 228, 229, 334, 146, 172, 176, 180, + 190, 198, 260, 261, 340, 266, 279, 95, 96, 97, + 98, 99, 100, 101, 102, 185, 2, 193, 281, 60, + 105, 106, 107, 108, 109, 110, 111, 112, 114, 115, + 116, 209, 3, 237, 238, 239, 240, 241, 242, 373, + 284, 173, 177, 174, 178, 165, 177, 5, 178, 26, + 173, 199, 174, 430, 4, 5, 27, 6, 7, 59, + 28, 341, 8, 133, 29, 202, 7, 59, 200, 59, + 8, 59, 59, 441, 446, 406, 35, 243, 251, 186, + 187, 460, 203, 36, 37, 38, 39, 467, 280, 304, + 204, 293, 154, 155, 156, 157, 158, 159, 160, 201, + 191, 163, 376, 144, 169, 5, 294, 205, 254, 336, + 480, 184, 40, 41, 208, 192, 7, 42, 43, 59, + 8, 134, 135, 136, 137, 138, 139, 140, 44, 45, + 278, 46, 177, 177, 178, 178, 170, 171, 292, 87, + 88, 293, 210, 188, 189, 451, 177, 454, 178, 220, + 457, 372, 4, 5, 293, 463, 294, 249, 221, 195, + 196, 250, 219, 414, 7, 26, 289, 305, 8, 294, + 370, 306, 27, 85, 86, 307, 28, 206, 207, 91, + 29, 336, 481, 442, 211, 212, 447, 213, 337, 342, + 215, 217, 343, 362, 141, 222, 223, 374, 371, 461, + 377, 234, 465, 378, 245, 468, 248, 69, 426, 291, + 471, 472, 440, 398, 474, 301, 402, 475, 403, 117, + 405, 477, 66, 67, 68, 408, 288, 290, 4, 5, + 297, 298, 299, 300, 70, 71, 72, 263, 415, 418, + 7, 4, 5, 129, 8, 433, 434, 70, 71, 72, + 449, 470, 335, 7, 286, 483, 478, 8, 126, 70, + 71, 72, 344, 73, 74, 75, 76, 77, 78, 79, + 421, 118, 119, 124, 256, 308, 73, 74, 75, 76, + 77, 78, 79, 70, 71, 72, 235, 338, 73, 74, + 75, 76, 77, 78, 79, 257, 26, 181, 0, 0, + 130, 0, 379, 27, 0, 0, 0, 28, 132, 0, + 0, 29, 73, 74, 75, 76, 77, 78, 79, 0, + 237, 238, 239, 240, 241, 242, 0, 404, 0, 73, + 74, 75, 76, 77, 78, 79, 26, 218, 0, 410, + 70, 71, 72, 27, 0, 82, 267, 28, 70, 71, + 72, 29, 89, 90, 0, 92, 411, 94, 0, 268, + 269, 270, 271, 407, 243, 0, 0, 0, 409, 73, + 74, 75, 76, 77, 78, 79, 425, 73, 74, 75, + 76, 77, 78, 79, 272, 0, 273, 274, 275, 276, + 0, 439, 0, 412, 0, 0, 413, 0, 0, 417, + 0, 419, 420, 0, 0, 423, 424, 459, 428, 0, + 429, 0, 431, 432, 366, 367, 5, 435, 436, 0, + 437, 438, 0, 0, 0, 444, 445, 7, 476, 0, + 0, 8, 452, 453, 455, 277, 0, 458, 0, 0, + 0, 462, 464, 303, 466, 0, 0, 469, 268, 269, + 270, 271, 0, 473, 26, 0, 268, 269, 270, 271, + 123, 27, 0, 127, 128, 28, 0, 131, 0, 29, + 142, 0, 0, 272, 309, 273, 274, 275, 276, 0, + 310, 272, 0, 273, 274, 275, 276, 0, 0, 0, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 322, 323, 324, 325, 326, 327, 373, 328, 0, - 0, 0, 0, 306, 121, 123, 121, 121, 123, 123, - 0, 0, 121, 307, 308, 309, 310, 311, 312, 313, + 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, + 331, 339, 332, 0, 0, 0, 0, 310, 120, 122, + 120, 120, 122, 122, 0, 0, 120, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 324, 325, 326, 327, 442, 328, 0, 447, 62, 63, - 64, 65, 66, 67, 68, 69, 0, 0, 0, 0, - 461, 104, 0, 465, 0, 0, 468, 0, 0, 0, - 0, 471, 472, 0, 0, 474, 0, 0, 475, 0, - 0, 0, 477, 380, 381, 382, 383, 384, 385, 386, - 387, 388, 389, 390, 391, 392, 393, 394, 395, 0, - 397, 398, 399, 74, 75, 76, 77, 78, 79, 80, - 0, 119, 120, 49, 50, 51, 52, 53, 54, 55, - 56, 62, 63, 64, 65, 66, 67, 68, 69, 63, - 64, 65, 66, 67, 68, 69, 64, 65, 66, 67, - 68, 69, 225, 226, 227, 228, 229, 230, 238, 239, - 240, 241, 242, 243, 65, 66, 67, 68, 69 + 324, 325, 326, 327, 328, 329, 330, 331, 375, 332, + 0, 0, 0, 0, 310, 0, 48, 49, 50, 51, + 52, 53, 54, 55, 311, 312, 313, 314, 315, 316, + 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, + 327, 328, 329, 330, 331, 0, 332, 382, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 0, 399, 400, 401, 61, 62, 63, + 64, 65, 66, 67, 68, 64, 65, 66, 67, 68, + 81, 61, 62, 63, 64, 65, 66, 67, 68, 0, + 0, 0, 0, 0, 103, 73, 74, 75, 76, 77, + 78, 79, 0, 118, 119, 61, 62, 63, 64, 65, + 66, 67, 68, 62, 63, 64, 65, 66, 67, 68, + 63, 64, 65, 66, 67, 68, 224, 225, 226, 227, + 228, 229, 237, 238, 239, 240, 241, 242 }; static const short yycheck[] = { - 3, 142, 24, 264, 126, 127, 8, 9, 4, 4, - 4, 231, 234, 4, 4, 330, 278, 41, 42, 3, - 3, 3, 95, 80, 146, 3, 28, 29, 30, 3, - 3, 0, 252, 4, 256, 96, 4, 299, 95, 31, - 6, 7, 8, 9, 10, 11, 217, 49, 50, 51, - 52, 53, 54, 55, 56, 3, 371, 48, 4, 50, - 62, 63, 64, 65, 66, 67, 68, 69, 71, 72, - 73, 80, 194, 5, 85, 95, 70, 248, 68, 69, - 12, 13, 14, 15, 95, 80, 82, 82, 49, 49, - 405, 80, 263, 89, 39, 40, 4, 93, 93, 4, - 45, 97, 97, 51, 52, 53, 54, 55, 56, 41, - 42, 95, 95, 95, 46, 47, 4, 95, 422, 80, - 80, 95, 95, 115, 95, 57, 58, 4, 60, 95, - 301, 95, 135, 136, 137, 138, 139, 140, 141, 4, - 48, 144, 50, 48, 147, 50, 450, 95, 3, 81, - 82, 153, 456, 3, 3, 82, 148, 149, 80, 3, - 48, 93, 50, 155, 156, 97, 16, 17, 18, 19, - 97, 48, 3, 50, 95, 479, 4, 71, 70, 171, - 172, 3, 443, 48, 445, 50, 95, 448, 90, 91, - 92, 41, 453, 43, 44, 45, 46, 189, 190, 43, - 44, 45, 204, 3, 196, 197, 328, 199, 80, 80, - 202, 203, 43, 44, 45, 207, 208, 4, 3, 480, - 48, 213, 50, 80, 216, 95, 218, 80, 72, 73, - 74, 75, 76, 77, 78, 3, 80, 81, 80, 85, - 80, 72, 73, 74, 75, 76, 77, 78, 80, 271, - 80, 81, 82, 3, 3, 277, 95, 249, 43, 44, - 45, 79, 79, 93, 82, 82, 269, 97, 95, 95, - 273, 274, 275, 276, 266, 43, 44, 45, 3, 97, - 97, 95, 95, 43, 16, 426, 3, 72, 73, 74, - 75, 76, 77, 78, 98, 287, 95, 95, 95, 59, - 95, 4, 294, 95, 72, 73, 74, 75, 76, 77, - 78, 61, 62, 63, 64, 65, 66, 67, 43, 44, - 45, 81, 82, 82, 84, 95, 43, 44, 45, 332, - 89, 95, 0, 93, 93, 87, 306, 97, 97, 342, - 72, 73, 74, 75, 76, 77, 78, 72, 73, 74, - 75, 76, 77, 78, 237, 72, 73, 74, 75, 76, - 77, 78, 81, 82, 367, 51, 52, 53, 54, 55, - 56, 415, 82, 80, 93, 82, 379, 214, 97, -1, - 372, 3, 89, 93, 244, 377, 93, 97, -1, -1, - 97, 82, 83, 396, 16, 17, 18, 19, 89, -1, - -1, 85, 93, -1, 88, 89, 97, -1, 92, 95, - 402, 95, -1, -1, -1, 407, 419, -1, 410, 41, - 412, 43, 44, 45, 46, 417, 418, -1, 420, 421, - 433, 423, 424, -1, -1, -1, 428, 429, -1, 431, - 432, -1, -1, -1, 436, 437, 449, 82, 83, -1, - -1, 443, 444, 445, 89, 3, 448, -1, 93, -1, - 452, 453, 97, 455, -1, -1, 458, 470, 16, 17, - 18, 19, 464, 85, 86, 87, 88, 89, 90, 91, - 92, -1, -1, 4, -1, -1, 98, -1, -1, 10, - -1, -1, -1, 41, -1, 43, 44, 45, 46, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 4, 42, 36, -1, -1, -1, 10, -1, -1, 43, - 44, -1, 46, -1, 48, -1, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 4, 42, -1, - -1, -1, -1, 10, 84, 85, 86, 87, 88, 89, - -1, -1, 92, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 435, 42, -1, 438, 85, 86, - 87, 88, 89, 90, 91, 92, -1, -1, -1, -1, - 451, 98, -1, 454, -1, -1, 457, -1, -1, -1, - -1, 462, 463, -1, -1, 466, -1, -1, 469, -1, - -1, -1, 473, 344, 345, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 359, -1, - 361, 362, 363, 72, 73, 74, 75, 76, 77, 78, - -1, 80, 81, 85, 86, 87, 88, 89, 90, 91, - 92, 85, 86, 87, 88, 89, 90, 91, 92, 86, - 87, 88, 89, 90, 91, 92, 87, 88, 89, 90, - 91, 92, 6, 7, 8, 9, 10, 11, 51, 52, - 53, 54, 55, 56, 88, 89, 90, 91, 92 + 2, 141, 23, 125, 126, 263, 7, 8, 4, 4, + 49, 4, 216, 0, 4, 3, 95, 3, 277, 3, + 3, 3, 3, 145, 230, 3, 27, 28, 29, 6, + 7, 8, 9, 10, 11, 292, 96, 4, 4, 4, + 4, 80, 4, 247, 303, 251, 4, 48, 49, 50, + 51, 52, 53, 54, 55, 4, 43, 95, 262, 30, + 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, + 72, 193, 59, 51, 52, 53, 54, 55, 56, 336, + 70, 48, 48, 50, 50, 80, 48, 82, 50, 82, + 48, 80, 50, 422, 81, 82, 89, 84, 93, 95, + 93, 305, 97, 3, 97, 80, 93, 95, 49, 95, + 97, 95, 95, 95, 95, 372, 5, 95, 95, 68, + 69, 450, 95, 12, 13, 14, 15, 456, 4, 4, + 3, 82, 134, 135, 136, 137, 138, 139, 140, 80, + 80, 143, 4, 114, 146, 82, 97, 3, 233, 85, + 479, 152, 41, 42, 80, 95, 93, 46, 47, 95, + 97, 61, 62, 63, 64, 65, 66, 67, 57, 58, + 255, 60, 48, 48, 50, 50, 147, 148, 79, 40, + 41, 82, 95, 154, 155, 443, 48, 445, 50, 71, + 448, 79, 81, 82, 82, 453, 97, 3, 70, 170, + 171, 80, 203, 80, 93, 82, 80, 3, 97, 97, + 332, 4, 89, 38, 39, 80, 93, 188, 189, 44, + 97, 85, 480, 435, 195, 196, 438, 198, 95, 95, + 201, 202, 80, 80, 3, 206, 207, 80, 98, 451, + 80, 212, 454, 95, 215, 457, 217, 3, 3, 270, + 462, 463, 4, 95, 466, 276, 95, 469, 95, 3, + 95, 473, 90, 91, 92, 95, 268, 80, 81, 82, + 272, 273, 274, 275, 43, 44, 45, 248, 95, 95, + 93, 81, 82, 3, 97, 95, 426, 43, 44, 45, + 95, 95, 294, 93, 265, 0, 95, 97, 86, 43, + 44, 45, 310, 72, 73, 74, 75, 76, 77, 78, + 414, 80, 81, 16, 236, 286, 72, 73, 74, 75, + 76, 77, 78, 43, 44, 45, 213, 298, 72, 73, + 74, 75, 76, 77, 78, 243, 82, 83, -1, -1, + 3, -1, 344, 89, -1, -1, -1, 93, 3, -1, + -1, 97, 72, 73, 74, 75, 76, 77, 78, -1, + 51, 52, 53, 54, 55, 56, -1, 369, -1, 72, + 73, 74, 75, 76, 77, 78, 82, 83, -1, 381, + 43, 44, 45, 89, -1, 35, 3, 93, 43, 44, + 45, 97, 42, 43, -1, 45, 398, 47, -1, 16, + 17, 18, 19, 374, 95, -1, -1, -1, 379, 72, + 73, 74, 75, 76, 77, 78, 418, 72, 73, 74, + 75, 76, 77, 78, 41, -1, 43, 44, 45, 46, + -1, 433, -1, 404, -1, -1, 407, -1, -1, 410, + -1, 412, 413, -1, -1, 416, 417, 449, 419, -1, + 421, -1, 423, 424, 80, 81, 82, 428, 429, -1, + 431, 432, -1, -1, -1, 436, 437, 93, 470, -1, + -1, 97, 443, 444, 445, 3, -1, 448, -1, -1, + -1, 452, 453, 3, 455, -1, -1, 458, 16, 17, + 18, 19, -1, 464, 82, -1, 16, 17, 18, 19, + 84, 89, -1, 87, 88, 93, -1, 91, -1, 97, + 94, -1, -1, 41, 4, 43, 44, 45, 46, -1, + 10, 41, -1, 43, 44, 45, 46, -1, -1, -1, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 4, 42, -1, -1, -1, -1, 10, 83, 84, + 85, 86, 87, 88, -1, -1, 91, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 4, 42, + -1, -1, -1, -1, 10, -1, 85, 86, 87, 88, + 89, 90, 91, 92, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, -1, 42, 346, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 361, -1, 363, 364, 365, 85, 86, 87, + 88, 89, 90, 91, 92, 88, 89, 90, 91, 92, + 98, 85, 86, 87, 88, 89, 90, 91, 92, -1, + -1, -1, -1, -1, 98, 72, 73, 74, 75, 76, + 77, 78, -1, 80, 81, 85, 86, 87, 88, 89, + 90, 91, 92, 86, 87, 88, 89, 90, 91, 92, + 87, 88, 89, 90, 91, 92, 6, 7, 8, 9, + 10, 11, 51, 52, 53, 54, 55, 56 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/usr/share/bison/bison.simple" @@ -829,12 +830,6 @@ static const short yycheck[] = define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ -#ifdef __cplusplus -# define YYSTD(x) std::x -#else -# define YYSTD(x) x -#endif - #if ! defined (yyoverflow) || defined (YYERROR_VERBOSE) /* The parser invokes alloca or malloc; define the necessary symbols. */ @@ -857,18 +852,19 @@ static const short yycheck[] = /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # else -# ifdef __cplusplus -# include <cstdlib> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T std::size_t -# else -# ifdef __STDC__ -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif +# if defined (__STDC__) || defined (__cplusplus) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t # endif -# define YYSTACK_ALLOC YYSTD (malloc) -# define YYSTACK_FREE YYSTD (free) +# define YYSTACK_ALLOC malloc +# define YYSTACK_FREE free # endif +#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc @@ -895,24 +891,41 @@ union yyalloc + YYSTACK_GAP_MAX) # endif -/* Relocate the TYPE STACK from its old location to the new one. The +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Type, Stack) \ +# define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ - yymemcpy ((char *) yyptr, (char *) (Stack), \ - yysize * (YYSIZE_T) sizeof (Type)); \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (Type) + YYSTACK_GAP_MAX; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (0) -#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */ +#endif #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) @@ -922,14 +935,9 @@ union yyalloc # define YYSIZE_T size_t #endif #if ! defined (YYSIZE_T) -# ifdef __cplusplus -# include <cstddef> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T std::size_t -# else -# ifdef __STDC__ -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif +# if defined (__STDC__) || defined (__cplusplus) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t # endif #endif #if ! defined (YYSIZE_T) @@ -1008,12 +1016,8 @@ while (0) #if YYDEBUG # ifndef YYFPRINTF -# ifdef __cplusplus -# include <cstdio> /* INFRINGES ON USER NAME SPACE */ -# else -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# endif -# define YYFPRINTF YYSTD (fprintf) +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ @@ -1021,10 +1025,8 @@ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) -/* Nonzero means print parse trace. [The following comment makes no - sense to me. Could someone clarify it? --akim] Since this is - uninitialized, it does not stop multiple parsers from coexisting. - */ +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) @@ -1050,33 +1052,6 @@ int yydebug; # define YYMAXDEPTH 10000 #endif -#if ! defined (yyoverflow) && ! defined (yymemcpy) -# if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -# define yymemcpy __builtin_memcpy -# else /* not GNU C or C++ */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -# if defined (__STDC__) || defined (__cplusplus) -yymemcpy (char *yyto, const char *yyfrom, YYSIZE_T yycount) -# else -yymemcpy (yyto, yyfrom, yycount) - char *yyto; - const char *yyfrom; - YYSIZE_T yycount; -# endif -{ - register const char *yyf = yyfrom; - register char *yyt = yyto; - register YYSIZE_T yyi = yycount; - - while (yyi-- != 0) - *yyt++ = *yyf++; -} -# endif -#endif - #ifdef YYERROR_VERBOSE # ifndef yystrlen @@ -1129,7 +1104,7 @@ yystpcpy (yydest, yysrc) # endif #endif -#line 341 "/usr/share/bison/bison.simple" +#line 315 "/usr/share/bison/bison.simple" /* The user can define YYPARSE_PARAM as the name of an argument to be passed @@ -1139,13 +1114,13 @@ yystpcpy (yydest, yysrc) to the proper pointer type. */ #ifdef YYPARSE_PARAM -# ifdef __cplusplus +# if defined (__STDC__) || defined (__cplusplus) # define YYPARSE_PARAM_ARG void *YYPARSE_PARAM # define YYPARSE_PARAM_DECL -# else /* !__cplusplus */ +# else # define YYPARSE_PARAM_ARG YYPARSE_PARAM # define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -# endif /* !__cplusplus */ +# endif #else /* !YYPARSE_PARAM */ # define YYPARSE_PARAM_ARG # define YYPARSE_PARAM_DECL @@ -1319,6 +1294,9 @@ yyparse (YYPARSE_PARAM_ARG) yyvs = yyvs1; } #else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else /* Extend the stack our own way. */ if (yystacksize >= YYMAXDEPTH) goto yyoverflowlab; @@ -1332,15 +1310,16 @@ yyparse (YYPARSE_PARAM_ARG) (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyoverflowlab; - YYSTACK_RELOCATE (short, yyss); - YYSTACK_RELOCATE (YYSTYPE, yyvs); + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); # if YYLSP_NEEDED - YYSTACK_RELOCATE (YYLTYPE, yyls); + YYSTACK_RELOCATE (yyls); # endif # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } +# endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; @@ -1519,26 +1498,23 @@ yyreduce: switch (yyn) { case 17: -#line 175 "rcparse.y" +#line 177 "rcparse.y" { + define_accelerator (yyvsp[-5].id, &yyvsp[-3].res_info, yyvsp[-1].pacc); + if (yychar != YYEMPTY) + YYERROR; rcparse_discard_strings (); } break; case 18: -#line 184 "rcparse.y" +#line 187 "rcparse.y" { - define_accelerator (yyvsp[-5].id, &yyvsp[-3].res_info, yyvsp[-1].pacc); + yyval.pacc = NULL; } break; case 19: #line 191 "rcparse.y" { - yyval.pacc = NULL; - } - break; -case 20: -#line 195 "rcparse.y" -{ struct accelerator *a; a = (struct accelerator *) res_alloc (sizeof *a); @@ -1556,15 +1532,15 @@ case 20: } } break; -case 21: -#line 216 "rcparse.y" +case 20: +#line 212 "rcparse.y" { yyval.acc = yyvsp[-1].acc; yyval.acc.id = yyvsp[0].il; } break; -case 22: -#line 221 "rcparse.y" +case 21: +#line 217 "rcparse.y" { yyval.acc = yyvsp[-3].acc; yyval.acc.id = yyvsp[-2].il; @@ -1574,8 +1550,8 @@ case 22: rcparse_warning (_("inappropriate modifiers for non-VIRTKEY")); } break; -case 23: -#line 233 "rcparse.y" +case 22: +#line 229 "rcparse.y" { const char *s = yyvsp[0].s; char ch; @@ -1597,8 +1573,8 @@ case 23: rcparse_warning (_("accelerator should only be one character")); } break; -case 24: -#line 254 "rcparse.y" +case 23: +#line 250 "rcparse.y" { yyval.acc.next = NULL; yyval.acc.flags = 0; @@ -1606,75 +1582,81 @@ case 24: yyval.acc.key = yyvsp[0].il; } break; +case 24: +#line 260 "rcparse.y" +{ + yyval.is = yyvsp[0].is; + } + break; case 25: #line 264 "rcparse.y" { - yyval.is = yyvsp[0].is; + yyval.is = yyvsp[-2].is | yyvsp[0].is; } break; case 26: -#line 268 "rcparse.y" +#line 269 "rcparse.y" { - yyval.is = yyvsp[-2].is | yyvsp[0].is; + yyval.is = yyvsp[-1].is | yyvsp[0].is; } break; case 27: -#line 273 "rcparse.y" +#line 276 "rcparse.y" { - yyval.is = yyvsp[-1].is | yyvsp[0].is; + yyval.is = ACC_VIRTKEY; } break; case 28: #line 280 "rcparse.y" { - yyval.is = ACC_VIRTKEY; + /* This is just the absence of VIRTKEY. */ + yyval.is = 0; } break; case 29: -#line 284 "rcparse.y" +#line 285 "rcparse.y" { - /* This is just the absence of VIRTKEY. */ - yyval.is = 0; + yyval.is = ACC_NOINVERT; } break; case 30: #line 289 "rcparse.y" { - yyval.is = ACC_NOINVERT; + yyval.is = ACC_SHIFT; } break; case 31: #line 293 "rcparse.y" { - yyval.is = ACC_SHIFT; + yyval.is = ACC_CONTROL; } break; case 32: #line 297 "rcparse.y" { - yyval.is = ACC_CONTROL; - } - break; -case 33: -#line 301 "rcparse.y" -{ yyval.is = ACC_ALT; } break; -case 34: -#line 310 "rcparse.y" +case 33: +#line 306 "rcparse.y" { define_bitmap (yyvsp[-3].id, &yyvsp[-1].res_info, yyvsp[0].s); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 35: -#line 319 "rcparse.y" +case 34: +#line 318 "rcparse.y" { define_cursor (yyvsp[-3].id, &yyvsp[-1].res_info, yyvsp[0].s); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 36: -#line 329 "rcparse.y" +case 35: +#line 331 "rcparse.y" { memset (&dialog, 0, sizeof dialog); dialog.x = yyvsp[-3].il; @@ -1689,16 +1671,20 @@ case 36: dialog.ex = NULL; dialog.controls = NULL; sub_res_info = yyvsp[-5].res_info; + style = 0; } break; -case 37: -#line 345 "rcparse.y" +case 36: +#line 348 "rcparse.y" { define_dialog (yyvsp[-12].id, &sub_res_info, &dialog); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 38: -#line 350 "rcparse.y" +case 37: +#line 356 "rcparse.y" { memset (&dialog, 0, sizeof dialog); dialog.x = yyvsp[-3].il; @@ -1715,16 +1701,20 @@ case 38: memset (dialog.ex, 0, sizeof (struct dialog_ex)); dialog.controls = NULL; sub_res_info = yyvsp[-5].res_info; + style = 0; } break; -case 39: -#line 368 "rcparse.y" +case 38: +#line 375 "rcparse.y" { define_dialog (yyvsp[-12].id, &sub_res_info, &dialog); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 40: -#line 373 "rcparse.y" +case 39: +#line 383 "rcparse.y" { memset (&dialog, 0, sizeof dialog); dialog.x = yyvsp[-4].il; @@ -1742,66 +1732,99 @@ case 40: dialog.ex->help = yyvsp[0].il; dialog.controls = NULL; sub_res_info = yyvsp[-6].res_info; + style = 0; } break; -case 41: -#line 392 "rcparse.y" +case 40: +#line 403 "rcparse.y" { define_dialog (yyvsp[-13].id, &sub_res_info, &dialog); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 42: -#line 399 "rcparse.y" +case 41: +#line 413 "rcparse.y" { yyval.il = 0; } break; -case 43: -#line 403 "rcparse.y" +case 42: +#line 417 "rcparse.y" { yyval.il = yyvsp[0].il; } break; -case 45: -#line 411 "rcparse.y" +case 44: +#line 425 "rcparse.y" { + dialog.style |= WS_CAPTION; + style |= WS_CAPTION; unicode_from_ascii ((int *) NULL, &dialog.caption, yyvsp[0].s); } break; -case 46: -#line 415 "rcparse.y" +case 45: +#line 431 "rcparse.y" { dialog.class = yyvsp[0].id; } break; +case 46: +#line 436 "rcparse.y" +{ + dialog.style = style; + } + break; case 47: -#line 419 "rcparse.y" -{ style = dialog.style; } +#line 440 "rcparse.y" +{ + dialog.exstyle = yyvsp[0].il; + } break; case 48: -#line 421 "rcparse.y" +#line 444 "rcparse.y" { - dialog.style = style; + res_string_to_id (& dialog.class, yyvsp[0].s); } break; case 49: -#line 425 "rcparse.y" +#line 448 "rcparse.y" { - dialog.exstyle = yyvsp[0].il; + dialog.style |= DS_SETFONT; + style |= DS_SETFONT; + dialog.pointsize = yyvsp[-2].il; + unicode_from_ascii ((int *) NULL, &dialog.font, yyvsp[0].s); + if (dialog.ex != NULL) + { + dialog.ex->weight = 0; + dialog.ex->italic = 0; + dialog.ex->charset = 1; + } } break; case 50: -#line 429 "rcparse.y" +#line 461 "rcparse.y" { dialog.style |= DS_SETFONT; - dialog.pointsize = yyvsp[-2].il; - unicode_from_ascii ((int *) NULL, &dialog.font, yyvsp[0].s); + style |= DS_SETFONT; + dialog.pointsize = yyvsp[-3].il; + unicode_from_ascii ((int *) NULL, &dialog.font, yyvsp[-1].s); + if (dialog.ex == NULL) + rcparse_warning (_("extended FONT requires DIALOGEX")); + else + { + dialog.ex->weight = yyvsp[0].il; + dialog.ex->italic = 0; + dialog.ex->charset = 1; + } } break; case 51: -#line 435 "rcparse.y" +#line 476 "rcparse.y" { dialog.style |= DS_SETFONT; + style |= DS_SETFONT; dialog.pointsize = yyvsp[-4].il; unicode_from_ascii ((int *) NULL, &dialog.font, yyvsp[-2].s); if (dialog.ex == NULL) @@ -1810,35 +1833,53 @@ case 51: { dialog.ex->weight = yyvsp[-1].il; dialog.ex->italic = yyvsp[0].il; + dialog.ex->charset = 1; } } break; case 52: -#line 448 "rcparse.y" +#line 491 "rcparse.y" { - dialog.menu = yyvsp[0].id; + dialog.style |= DS_SETFONT; + style |= DS_SETFONT; + dialog.pointsize = yyvsp[-5].il; + unicode_from_ascii ((int *) NULL, &dialog.font, yyvsp[-3].s); + if (dialog.ex == NULL) + rcparse_warning (_("extended FONT requires DIALOGEX")); + else + { + dialog.ex->weight = yyvsp[-2].il; + dialog.ex->italic = yyvsp[-1].il; + dialog.ex->charset = yyvsp[0].il; + } } break; case 53: -#line 452 "rcparse.y" +#line 506 "rcparse.y" { - sub_res_info.characteristics = yyvsp[0].il; + dialog.menu = yyvsp[0].id; } break; case 54: -#line 456 "rcparse.y" +#line 510 "rcparse.y" { - sub_res_info.language = yyvsp[-1].il | (yyvsp[0].il << SUBLANG_SHIFT); + sub_res_info.characteristics = yyvsp[0].il; } break; case 55: -#line 460 "rcparse.y" +#line 514 "rcparse.y" +{ + sub_res_info.language = yyvsp[-1].il | (yyvsp[0].il << SUBLANG_SHIFT); + } + break; +case 56: +#line 518 "rcparse.y" { sub_res_info.version = yyvsp[0].il; } break; -case 57: -#line 468 "rcparse.y" +case 58: +#line 526 "rcparse.y" { struct dialog_control **pp; @@ -1847,95 +1888,95 @@ case 57: *pp = yyvsp[0].dialog_control; } break; -case 58: -#line 479 "rcparse.y" +case 59: +#line 537 "rcparse.y" { default_style = BS_AUTO3STATE | WS_TABSTOP; base_style = BS_AUTO3STATE; class = CTL_BUTTON; } break; -case 59: -#line 485 "rcparse.y" +case 60: +#line 543 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 60: -#line 489 "rcparse.y" +case 61: +#line 547 "rcparse.y" { default_style = BS_AUTOCHECKBOX | WS_TABSTOP; base_style = BS_AUTOCHECKBOX; class = CTL_BUTTON; } break; -case 61: -#line 495 "rcparse.y" +case 62: +#line 553 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 62: -#line 499 "rcparse.y" +case 63: +#line 557 "rcparse.y" { default_style = BS_AUTORADIOBUTTON | WS_TABSTOP; base_style = BS_AUTORADIOBUTTON; class = CTL_BUTTON; } break; -case 63: -#line 505 "rcparse.y" +case 64: +#line 563 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 64: -#line 509 "rcparse.y" +case 65: +#line 567 "rcparse.y" { default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; class = CTL_EDIT; } break; -case 65: -#line 515 "rcparse.y" +case 66: +#line 573 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; if (dialog.ex == NULL) - rcparse_warning (_("IEDIT requires DIALOGEX")); + rcparse_warning (_("BEDIT requires DIALOGEX")); res_string_to_id (&yyval.dialog_control->class, "BEDIT"); } break; -case 66: -#line 522 "rcparse.y" +case 67: +#line 580 "rcparse.y" { default_style = BS_CHECKBOX | WS_TABSTOP; base_style = BS_CHECKBOX | WS_TABSTOP; class = CTL_BUTTON; } break; -case 67: -#line 528 "rcparse.y" +case 68: +#line 586 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 68: -#line 532 "rcparse.y" +case 69: +#line 590 "rcparse.y" { default_style = CBS_SIMPLE | WS_TABSTOP; base_style = 0; class = CTL_COMBOBOX; } break; -case 69: -#line 538 "rcparse.y" +case 70: +#line 596 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 70: -#line 543 "rcparse.y" +case 71: +#line 601 "rcparse.y" { yyval.dialog_control = define_control (yyvsp[-9].s, yyvsp[-8].il, yyvsp[-5].il, yyvsp[-4].il, yyvsp[-3].il, yyvsp[-2].il, yyvsp[-7].il, style, yyvsp[-1].il); if (yyvsp[0].rcdata_item != NULL) @@ -1946,8 +1987,8 @@ case 70: } } break; -case 71: -#line 554 "rcparse.y" +case 72: +#line 612 "rcparse.y" { yyval.dialog_control = define_control (yyvsp[-10].s, yyvsp[-9].il, yyvsp[-6].il, yyvsp[-5].il, yyvsp[-4].il, yyvsp[-3].il, yyvsp[-8].il, style, yyvsp[-2].il); if (dialog.ex == NULL) @@ -1956,8 +1997,8 @@ case 71: yyval.dialog_control->data = yyvsp[0].rcdata_item; } break; -case 72: -#line 563 "rcparse.y" +case 73: +#line 621 "rcparse.y" { yyval.dialog_control = define_control (yyvsp[-10].s, yyvsp[-9].il, yyvsp[-5].il, yyvsp[-4].il, yyvsp[-3].il, yyvsp[-2].il, 0, style, yyvsp[-1].il); if (yyvsp[0].rcdata_item != NULL) @@ -1967,11 +2008,11 @@ case 72: yyval.dialog_control->data = yyvsp[0].rcdata_item; } yyval.dialog_control->class.named = 1; - unicode_from_ascii(&yyval.dialog_control->class.u.n.length, &yyval.dialog_control->class.u.n.name, yyvsp[-7].s); + unicode_from_ascii (&yyval.dialog_control->class.u.n.length, &yyval.dialog_control->class.u.n.name, yyvsp[-7].s); } break; -case 73: -#line 576 "rcparse.y" +case 74: +#line 634 "rcparse.y" { yyval.dialog_control = define_control (yyvsp[-11].s, yyvsp[-10].il, yyvsp[-6].il, yyvsp[-5].il, yyvsp[-4].il, yyvsp[-3].il, 0, style, yyvsp[-2].il); if (dialog.ex == NULL) @@ -1979,75 +2020,75 @@ case 73: yyval.dialog_control->help = yyvsp[-1].il; yyval.dialog_control->data = yyvsp[0].rcdata_item; yyval.dialog_control->class.named = 1; - unicode_from_ascii(&yyval.dialog_control->class.u.n.length, &yyval.dialog_control->class.u.n.name, yyvsp[-8].s); + unicode_from_ascii (&yyval.dialog_control->class.u.n.length, &yyval.dialog_control->class.u.n.name, yyvsp[-8].s); } break; -case 74: -#line 586 "rcparse.y" +case 75: +#line 644 "rcparse.y" { default_style = SS_CENTER | WS_GROUP; base_style = SS_CENTER; class = CTL_STATIC; } break; -case 75: -#line 592 "rcparse.y" +case 76: +#line 650 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 76: -#line 596 "rcparse.y" +case 77: +#line 654 "rcparse.y" { default_style = BS_DEFPUSHBUTTON | WS_TABSTOP; base_style = BS_DEFPUSHBUTTON | WS_TABSTOP; class = CTL_BUTTON; } break; -case 77: -#line 602 "rcparse.y" +case 78: +#line 660 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 78: -#line 606 "rcparse.y" +case 79: +#line 664 "rcparse.y" { default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; class = CTL_EDIT; } break; -case 79: -#line 612 "rcparse.y" +case 80: +#line 670 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 80: -#line 616 "rcparse.y" +case 81: +#line 674 "rcparse.y" { default_style = BS_GROUPBOX; base_style = BS_GROUPBOX; class = CTL_BUTTON; } break; -case 81: -#line 622 "rcparse.y" +case 82: +#line 680 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 82: -#line 626 "rcparse.y" +case 83: +#line 684 "rcparse.y" { default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; class = CTL_EDIT; } break; -case 83: -#line 632 "rcparse.y" +case 84: +#line 690 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; if (dialog.ex == NULL) @@ -2055,44 +2096,44 @@ case 83: res_string_to_id (&yyval.dialog_control->class, "HEDIT"); } break; -case 84: -#line 639 "rcparse.y" +case 85: +#line 697 "rcparse.y" { yyval.dialog_control = define_icon_control (yyvsp[-4].id, yyvsp[-3].il, yyvsp[-2].il, yyvsp[-1].il, 0, 0, 0, yyvsp[0].rcdata_item, dialog.ex); } break; -case 85: -#line 645 "rcparse.y" +case 86: +#line 703 "rcparse.y" { yyval.dialog_control = define_icon_control (yyvsp[-6].id, yyvsp[-5].il, yyvsp[-4].il, yyvsp[-3].il, 0, 0, 0, yyvsp[0].rcdata_item, dialog.ex); } break; -case 86: -#line 651 "rcparse.y" +case 87: +#line 709 "rcparse.y" { yyval.dialog_control = define_icon_control (yyvsp[-8].id, yyvsp[-7].il, yyvsp[-6].il, yyvsp[-5].il, style, yyvsp[-1].il, 0, yyvsp[0].rcdata_item, dialog.ex); } break; -case 87: -#line 657 "rcparse.y" +case 88: +#line 715 "rcparse.y" { yyval.dialog_control = define_icon_control (yyvsp[-9].id, yyvsp[-8].il, yyvsp[-7].il, yyvsp[-6].il, style, yyvsp[-2].il, yyvsp[-1].il, yyvsp[0].rcdata_item, dialog.ex); } break; -case 88: -#line 662 "rcparse.y" +case 89: +#line 720 "rcparse.y" { default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; class = CTL_EDIT; } break; -case 89: -#line 668 "rcparse.y" +case 90: +#line 726 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; if (dialog.ex == NULL) @@ -2100,131 +2141,131 @@ case 89: res_string_to_id (&yyval.dialog_control->class, "IEDIT"); } break; -case 90: -#line 675 "rcparse.y" +case 91: +#line 733 "rcparse.y" { default_style = LBS_NOTIFY | WS_BORDER; base_style = LBS_NOTIFY | WS_BORDER; class = CTL_LISTBOX; } break; -case 91: -#line 681 "rcparse.y" +case 92: +#line 739 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 92: -#line 685 "rcparse.y" +case 93: +#line 743 "rcparse.y" { default_style = SS_LEFT | WS_GROUP; base_style = SS_LEFT; class = CTL_STATIC; } break; -case 93: -#line 691 "rcparse.y" +case 94: +#line 749 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 94: -#line 695 "rcparse.y" +case 95: +#line 753 "rcparse.y" { default_style = BS_PUSHBOX | WS_TABSTOP; base_style = BS_PUSHBOX; class = CTL_BUTTON; } break; -case 95: -#line 701 "rcparse.y" +case 96: +#line 759 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 96: -#line 705 "rcparse.y" +case 97: +#line 763 "rcparse.y" { default_style = BS_PUSHBUTTON | WS_TABSTOP; base_style = BS_PUSHBUTTON | WS_TABSTOP; class = CTL_BUTTON; } break; -case 97: -#line 711 "rcparse.y" +case 98: +#line 769 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 98: -#line 715 "rcparse.y" +case 99: +#line 773 "rcparse.y" { default_style = BS_RADIOBUTTON | WS_TABSTOP; base_style = BS_RADIOBUTTON; class = CTL_BUTTON; } break; -case 99: -#line 721 "rcparse.y" +case 100: +#line 779 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 100: -#line 725 "rcparse.y" +case 101: +#line 783 "rcparse.y" { default_style = SS_RIGHT | WS_GROUP; base_style = SS_RIGHT; class = CTL_STATIC; } break; -case 101: -#line 731 "rcparse.y" +case 102: +#line 789 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 102: -#line 735 "rcparse.y" +case 103: +#line 793 "rcparse.y" { default_style = SBS_HORZ; base_style = 0; class = CTL_SCROLLBAR; } break; -case 103: -#line 741 "rcparse.y" +case 104: +#line 799 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 104: -#line 745 "rcparse.y" +case 105: +#line 803 "rcparse.y" { default_style = BS_3STATE | WS_TABSTOP; base_style = BS_3STATE; class = CTL_BUTTON; } break; -case 105: -#line 751 "rcparse.y" +case 106: +#line 809 "rcparse.y" { yyval.dialog_control = yyvsp[0].dialog_control; } break; -case 106: -#line 756 "rcparse.y" +case 107: +#line 814 "rcparse.y" { style = WS_CHILD | WS_VISIBLE; } break; -case 107: -#line 758 "rcparse.y" +case 108: +#line 816 "rcparse.y" { yyval.dialog_control = define_control (yyvsp[-14].s, yyvsp[-12].il, yyvsp[-10].il, yyvsp[-8].il, yyvsp[-6].il, yyvsp[-4].il, CTL_BUTTON, style, yyvsp[0].il); } break; -case 108: -#line 774 "rcparse.y" +case 109: +#line 832 "rcparse.y" { yyval.dialog_control = define_control (yyvsp[-6].s, yyvsp[-5].il, yyvsp[-4].il, yyvsp[-3].il, yyvsp[-2].il, yyvsp[-1].il, class, default_style | WS_CHILD | WS_VISIBLE, 0); @@ -2236,8 +2277,8 @@ case 108: } } break; -case 109: -#line 786 "rcparse.y" +case 110: +#line 844 "rcparse.y" { yyval.dialog_control = define_control (yyvsp[-8].s, yyvsp[-7].il, yyvsp[-6].il, yyvsp[-5].il, yyvsp[-4].il, yyvsp[-3].il, class, style, yyvsp[-1].il); if (yyvsp[0].rcdata_item != NULL) @@ -2248,8 +2289,8 @@ case 109: } } break; -case 110: -#line 797 "rcparse.y" +case 111: +#line 855 "rcparse.y" { yyval.dialog_control = define_control (yyvsp[-9].s, yyvsp[-8].il, yyvsp[-7].il, yyvsp[-6].il, yyvsp[-5].il, yyvsp[-4].il, class, style, yyvsp[-2].il); if (dialog.ex == NULL) @@ -2258,80 +2299,89 @@ case 110: yyval.dialog_control->data = yyvsp[0].rcdata_item; } break; -case 111: -#line 808 "rcparse.y" +case 112: +#line 866 "rcparse.y" { yyval.s = NULL; } break; -case 112: -#line 812 "rcparse.y" +case 113: +#line 870 "rcparse.y" { yyval.s = yyvsp[0].s; } break; -case 113: -#line 816 "rcparse.y" +case 114: +#line 874 "rcparse.y" { yyval.s = yyvsp[-1].s; } break; -case 114: -#line 823 "rcparse.y" +case 115: +#line 881 "rcparse.y" { yyval.rcdata_item = NULL; } break; -case 115: -#line 827 "rcparse.y" +case 116: +#line 885 "rcparse.y" { yyval.rcdata_item = yyvsp[-1].rcdata.first; } break; -case 116: -#line 836 "rcparse.y" +case 117: +#line 894 "rcparse.y" { style = WS_CHILD | WS_VISIBLE; } break; -case 118: -#line 842 "rcparse.y" +case 119: +#line 900 "rcparse.y" { style = SS_ICON | WS_CHILD | WS_VISIBLE; } break; -case 120: -#line 848 "rcparse.y" +case 121: +#line 906 "rcparse.y" { style = base_style | WS_CHILD | WS_VISIBLE; } break; -case 122: -#line 856 "rcparse.y" +case 123: +#line 914 "rcparse.y" { define_font (yyvsp[-3].id, &yyvsp[-1].res_info, yyvsp[0].s); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 123: -#line 865 "rcparse.y" +case 124: +#line 926 "rcparse.y" { define_icon (yyvsp[-3].id, &yyvsp[-1].res_info, yyvsp[0].s); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 124: -#line 875 "rcparse.y" +case 125: +#line 939 "rcparse.y" { language = yyvsp[-1].il | (yyvsp[0].il << SUBLANG_SHIFT); } break; -case 125: -#line 884 "rcparse.y" +case 126: +#line 948 "rcparse.y" { define_menu (yyvsp[-5].id, &yyvsp[-3].res_info, yyvsp[-1].menuitem); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 126: -#line 891 "rcparse.y" +case 127: +#line 958 "rcparse.y" { yyval.menuitem = NULL; } break; -case 127: -#line 895 "rcparse.y" +case 128: +#line 962 "rcparse.y" { if (yyvsp[-1].menuitem == NULL) yyval.menuitem = yyvsp[0].menuitem; @@ -2346,92 +2396,95 @@ case 127: } } break; -case 128: -#line 912 "rcparse.y" +case 129: +#line 979 "rcparse.y" { yyval.menuitem = define_menuitem (yyvsp[-2].s, yyvsp[-1].il, yyvsp[0].is, 0, 0, NULL); } break; -case 129: -#line 916 "rcparse.y" +case 130: +#line 983 "rcparse.y" { yyval.menuitem = define_menuitem (NULL, 0, 0, 0, 0, NULL); } break; -case 130: -#line 920 "rcparse.y" +case 131: +#line 987 "rcparse.y" { yyval.menuitem = define_menuitem (yyvsp[-4].s, 0, yyvsp[-3].is, 0, 0, yyvsp[-1].menuitem); } break; -case 131: -#line 927 "rcparse.y" +case 132: +#line 994 "rcparse.y" { yyval.is = 0; } break; -case 132: -#line 931 "rcparse.y" +case 133: +#line 998 "rcparse.y" { yyval.is = yyvsp[-2].is | yyvsp[0].is; } break; -case 133: -#line 935 "rcparse.y" +case 134: +#line 1002 "rcparse.y" { yyval.is = yyvsp[-1].is | yyvsp[0].is; } break; -case 134: -#line 942 "rcparse.y" +case 135: +#line 1009 "rcparse.y" { yyval.is = MENUITEM_CHECKED; } break; -case 135: -#line 946 "rcparse.y" +case 136: +#line 1013 "rcparse.y" { yyval.is = MENUITEM_GRAYED; } break; -case 136: -#line 950 "rcparse.y" +case 137: +#line 1017 "rcparse.y" { yyval.is = MENUITEM_HELP; } break; -case 137: -#line 954 "rcparse.y" +case 138: +#line 1021 "rcparse.y" { yyval.is = MENUITEM_INACTIVE; } break; -case 138: -#line 958 "rcparse.y" +case 139: +#line 1025 "rcparse.y" { yyval.is = MENUITEM_MENUBARBREAK; } break; -case 139: -#line 962 "rcparse.y" +case 140: +#line 1029 "rcparse.y" { yyval.is = MENUITEM_MENUBREAK; } break; -case 140: -#line 971 "rcparse.y" +case 141: +#line 1038 "rcparse.y" { define_menu (yyvsp[-5].id, &yyvsp[-3].res_info, yyvsp[-1].menuitem); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 141: -#line 978 "rcparse.y" +case 142: +#line 1048 "rcparse.y" { yyval.menuitem = NULL; } break; -case 142: -#line 982 "rcparse.y" +case 143: +#line 1052 "rcparse.y" { if (yyvsp[-1].menuitem == NULL) yyval.menuitem = yyvsp[0].menuitem; @@ -2446,94 +2499,100 @@ case 142: } } break; -case 143: -#line 999 "rcparse.y" +case 144: +#line 1069 "rcparse.y" { yyval.menuitem = define_menuitem (yyvsp[0].s, 0, 0, 0, 0, NULL); } break; -case 144: -#line 1003 "rcparse.y" +case 145: +#line 1073 "rcparse.y" { yyval.menuitem = define_menuitem (yyvsp[-1].s, yyvsp[0].il, 0, 0, 0, NULL); } break; -case 145: -#line 1007 "rcparse.y" +case 146: +#line 1077 "rcparse.y" { yyval.menuitem = define_menuitem (yyvsp[-3].s, yyvsp[-2].il, yyvsp[-1].il, yyvsp[0].il, 0, NULL); } break; -case 146: -#line 1011 "rcparse.y" +case 147: +#line 1081 "rcparse.y" { yyval.menuitem = define_menuitem (NULL, 0, 0, 0, 0, NULL); } break; -case 147: -#line 1015 "rcparse.y" +case 148: +#line 1085 "rcparse.y" { yyval.menuitem = define_menuitem (yyvsp[-3].s, 0, 0, 0, 0, yyvsp[-1].menuitem); } break; -case 148: -#line 1019 "rcparse.y" +case 149: +#line 1089 "rcparse.y" { yyval.menuitem = define_menuitem (yyvsp[-4].s, yyvsp[-3].il, 0, 0, 0, yyvsp[-1].menuitem); } break; -case 149: -#line 1023 "rcparse.y" +case 150: +#line 1093 "rcparse.y" { yyval.menuitem = define_menuitem (yyvsp[-5].s, yyvsp[-4].il, yyvsp[-3].il, 0, 0, yyvsp[-1].menuitem); } break; -case 150: -#line 1028 "rcparse.y" +case 151: +#line 1098 "rcparse.y" { yyval.menuitem = define_menuitem (yyvsp[-7].s, yyvsp[-6].il, yyvsp[-5].il, yyvsp[-4].il, yyvsp[-3].il, yyvsp[-1].menuitem); } break; -case 151: -#line 1037 "rcparse.y" +case 152: +#line 1107 "rcparse.y" { define_messagetable (yyvsp[-3].id, &yyvsp[-1].res_info, yyvsp[0].s); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 152: -#line 1046 "rcparse.y" +case 153: +#line 1119 "rcparse.y" { define_rcdata (yyvsp[-5].id, &yyvsp[-3].res_info, yyvsp[-1].rcdata.first); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 153: -#line 1055 "rcparse.y" +case 154: +#line 1131 "rcparse.y" { rcparse_rcdata (); } break; -case 154: -#line 1059 "rcparse.y" +case 155: +#line 1135 "rcparse.y" { rcparse_normal (); yyval.rcdata = yyvsp[0].rcdata; } break; -case 155: -#line 1067 "rcparse.y" +case 156: +#line 1143 "rcparse.y" { yyval.rcdata.first = NULL; yyval.rcdata.last = NULL; } break; -case 156: -#line 1072 "rcparse.y" +case 157: +#line 1148 "rcparse.y" { yyval.rcdata = yyvsp[0].rcdata; } break; -case 157: -#line 1079 "rcparse.y" +case 158: +#line 1155 "rcparse.y" { struct rcdata_item *ri; @@ -2542,8 +2601,8 @@ case 157: yyval.rcdata.last = ri; } break; -case 158: -#line 1087 "rcparse.y" +case 159: +#line 1163 "rcparse.y" { struct rcdata_item *ri; @@ -2552,8 +2611,8 @@ case 158: yyval.rcdata.last = ri; } break; -case 159: -#line 1095 "rcparse.y" +case 160: +#line 1171 "rcparse.y" { struct rcdata_item *ri; @@ -2563,8 +2622,8 @@ case 159: yyval.rcdata.last = ri; } break; -case 160: -#line 1104 "rcparse.y" +case 161: +#line 1180 "rcparse.y" { struct rcdata_item *ri; @@ -2574,150 +2633,165 @@ case 160: yyval.rcdata.last = ri; } break; -case 161: -#line 1118 "rcparse.y" +case 162: +#line 1194 "rcparse.y" { sub_res_info = yyvsp[-1].res_info; } break; -case 164: -#line 1125 "rcparse.y" +case 165: +#line 1201 "rcparse.y" { define_stringtable (&sub_res_info, yyvsp[-1].il, yyvsp[0].s); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 165: -#line 1129 "rcparse.y" +case 166: +#line 1208 "rcparse.y" { define_stringtable (&sub_res_info, yyvsp[-2].il, yyvsp[0].s); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 166: -#line 1139 "rcparse.y" +case 167: +#line 1221 "rcparse.y" { define_user_data (yyvsp[-5].id, yyvsp[-4].id, &yyvsp[-3].res_info, yyvsp[-1].rcdata.first); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 167: -#line 1143 "rcparse.y" +case 168: +#line 1228 "rcparse.y" { define_user_file (yyvsp[-3].id, yyvsp[-2].id, &yyvsp[-1].res_info, yyvsp[0].s); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 168: -#line 1152 "rcparse.y" +case 169: +#line 1240 "rcparse.y" { define_versioninfo (yyvsp[-5].id, language, yyvsp[-3].fixver, yyvsp[-1].verinfo); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } break; -case 169: -#line 1159 "rcparse.y" +case 170: +#line 1250 "rcparse.y" { yyval.fixver = ((struct fixed_versioninfo *) res_alloc (sizeof (struct fixed_versioninfo))); memset (yyval.fixver, 0, sizeof (struct fixed_versioninfo)); } break; -case 170: -#line 1165 "rcparse.y" +case 171: +#line 1256 "rcparse.y" { yyvsp[-5].fixver->file_version_ms = (yyvsp[-3].il << 16) | yyvsp[-2].il; yyvsp[-5].fixver->file_version_ls = (yyvsp[-1].il << 16) | yyvsp[0].il; yyval.fixver = yyvsp[-5].fixver; } break; -case 171: -#line 1171 "rcparse.y" +case 172: +#line 1262 "rcparse.y" { yyvsp[-5].fixver->product_version_ms = (yyvsp[-3].il << 16) | yyvsp[-2].il; yyvsp[-5].fixver->product_version_ls = (yyvsp[-1].il << 16) | yyvsp[0].il; yyval.fixver = yyvsp[-5].fixver; } break; -case 172: -#line 1177 "rcparse.y" +case 173: +#line 1268 "rcparse.y" { yyvsp[-2].fixver->file_flags_mask = yyvsp[0].il; yyval.fixver = yyvsp[-2].fixver; } break; -case 173: -#line 1182 "rcparse.y" +case 174: +#line 1273 "rcparse.y" { yyvsp[-2].fixver->file_flags = yyvsp[0].il; yyval.fixver = yyvsp[-2].fixver; } break; -case 174: -#line 1187 "rcparse.y" +case 175: +#line 1278 "rcparse.y" { yyvsp[-2].fixver->file_os = yyvsp[0].il; yyval.fixver = yyvsp[-2].fixver; } break; -case 175: -#line 1192 "rcparse.y" +case 176: +#line 1283 "rcparse.y" { yyvsp[-2].fixver->file_type = yyvsp[0].il; yyval.fixver = yyvsp[-2].fixver; } break; -case 176: -#line 1197 "rcparse.y" +case 177: +#line 1288 "rcparse.y" { yyvsp[-2].fixver->file_subtype = yyvsp[0].il; yyval.fixver = yyvsp[-2].fixver; } break; -case 177: -#line 1211 "rcparse.y" +case 178: +#line 1302 "rcparse.y" { yyval.verinfo = NULL; } break; -case 178: -#line 1215 "rcparse.y" +case 179: +#line 1306 "rcparse.y" { yyval.verinfo = append_ver_stringfileinfo (yyvsp[-7].verinfo, yyvsp[-4].s, yyvsp[-2].verstring); } break; -case 179: -#line 1219 "rcparse.y" +case 180: +#line 1310 "rcparse.y" { yyval.verinfo = append_ver_varfileinfo (yyvsp[-6].verinfo, yyvsp[-2].s, yyvsp[-1].vervar); } break; -case 180: -#line 1226 "rcparse.y" +case 181: +#line 1317 "rcparse.y" { yyval.verstring = NULL; } break; -case 181: -#line 1230 "rcparse.y" +case 182: +#line 1321 "rcparse.y" { yyval.verstring = append_verval (yyvsp[-4].verstring, yyvsp[-2].s, yyvsp[0].s); } break; -case 182: -#line 1237 "rcparse.y" +case 183: +#line 1328 "rcparse.y" { yyval.vervar = NULL; } break; -case 183: -#line 1241 "rcparse.y" +case 184: +#line 1332 "rcparse.y" { yyval.vervar = append_vertrans (yyvsp[-2].vervar, yyvsp[-1].il, yyvsp[0].il); } break; -case 184: -#line 1250 "rcparse.y" +case 185: +#line 1341 "rcparse.y" { yyval.id.named = 0; yyval.id.u.id = yyvsp[0].il; } break; -case 185: -#line 1255 "rcparse.y" +case 186: +#line 1346 "rcparse.y" { char *copy, *s; @@ -2729,33 +2803,33 @@ case 185: free (copy); } break; -case 186: -#line 1271 "rcparse.y" +case 187: +#line 1362 "rcparse.y" { yyval.s = yyvsp[0].s; } break; -case 187: -#line 1275 "rcparse.y" +case 188: +#line 1366 "rcparse.y" { yyval.s = yyvsp[-1].s; } break; -case 188: -#line 1279 "rcparse.y" +case 189: +#line 1370 "rcparse.y" { yyval.s = yyvsp[-1].s; } break; -case 189: -#line 1287 "rcparse.y" +case 190: +#line 1378 "rcparse.y" { yyval.id.named = 0; yyval.id.u.id = yyvsp[-1].il; } break; -case 190: -#line 1292 "rcparse.y" +case 191: +#line 1383 "rcparse.y" { char *copy, *s; @@ -2767,361 +2841,361 @@ case 190: free (copy); } break; -case 191: -#line 1309 "rcparse.y" +case 192: +#line 1400 "rcparse.y" { memset (&yyval.res_info, 0, sizeof (struct res_res_info)); yyval.res_info.language = language; /* FIXME: Is this the right default? */ - yyval.res_info.memflags = MEMFLAG_MOVEABLE; + yyval.res_info.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE; } break; -case 192: -#line 1316 "rcparse.y" +case 193: +#line 1407 "rcparse.y" { yyval.res_info = yyvsp[-1].res_info; yyval.res_info.memflags |= yyvsp[0].memflags.on; yyval.res_info.memflags &=~ yyvsp[0].memflags.off; } break; -case 193: -#line 1322 "rcparse.y" +case 194: +#line 1413 "rcparse.y" { yyval.res_info = yyvsp[-2].res_info; yyval.res_info.characteristics = yyvsp[0].il; } break; -case 194: -#line 1327 "rcparse.y" +case 195: +#line 1418 "rcparse.y" { yyval.res_info = yyvsp[-3].res_info; yyval.res_info.language = yyvsp[-1].il | (yyvsp[0].il << SUBLANG_SHIFT); } break; -case 195: -#line 1332 "rcparse.y" +case 196: +#line 1423 "rcparse.y" { yyval.res_info = yyvsp[-2].res_info; yyval.res_info.version = yyvsp[0].il; } break; -case 196: -#line 1342 "rcparse.y" +case 197: +#line 1433 "rcparse.y" { memset (&yyval.res_info, 0, sizeof (struct res_res_info)); yyval.res_info.language = language; yyval.res_info.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE; } break; -case 197: -#line 1348 "rcparse.y" +case 198: +#line 1439 "rcparse.y" { yyval.res_info = yyvsp[-1].res_info; yyval.res_info.memflags |= yyvsp[0].memflags.on; yyval.res_info.memflags &=~ yyvsp[0].memflags.off; } break; -case 198: -#line 1359 "rcparse.y" +case 199: +#line 1450 "rcparse.y" { memset (&yyval.res_info, 0, sizeof (struct res_res_info)); yyval.res_info.language = language; - yyval.res_info.memflags = MEMFLAG_MOVEABLE; + yyval.res_info.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE; } break; -case 199: -#line 1365 "rcparse.y" +case 200: +#line 1456 "rcparse.y" { yyval.res_info = yyvsp[-1].res_info; yyval.res_info.memflags |= yyvsp[0].memflags.on; yyval.res_info.memflags &=~ yyvsp[0].memflags.off; } break; -case 200: -#line 1377 "rcparse.y" +case 201: +#line 1468 "rcparse.y" { yyval.memflags.on = MEMFLAG_MOVEABLE; yyval.memflags.off = 0; } break; -case 201: -#line 1382 "rcparse.y" +case 202: +#line 1473 "rcparse.y" { yyval.memflags.on = 0; yyval.memflags.off = MEMFLAG_MOVEABLE; } break; -case 202: -#line 1387 "rcparse.y" +case 203: +#line 1478 "rcparse.y" { yyval.memflags.on = MEMFLAG_PURE; yyval.memflags.off = 0; } break; -case 203: -#line 1392 "rcparse.y" +case 204: +#line 1483 "rcparse.y" { yyval.memflags.on = 0; yyval.memflags.off = MEMFLAG_PURE; } break; -case 204: -#line 1397 "rcparse.y" +case 205: +#line 1488 "rcparse.y" { yyval.memflags.on = MEMFLAG_PRELOAD; yyval.memflags.off = 0; } break; -case 205: -#line 1402 "rcparse.y" +case 206: +#line 1493 "rcparse.y" { yyval.memflags.on = 0; yyval.memflags.off = MEMFLAG_PRELOAD; } break; -case 206: -#line 1407 "rcparse.y" +case 207: +#line 1498 "rcparse.y" { yyval.memflags.on = MEMFLAG_DISCARDABLE; yyval.memflags.off = 0; } break; -case 207: -#line 1417 "rcparse.y" +case 208: +#line 1508 "rcparse.y" { yyval.s = yyvsp[0].s; } break; -case 208: -#line 1421 "rcparse.y" +case 209: +#line 1512 "rcparse.y" { yyval.s = yyvsp[0].s; } break; -case 209: -#line 1438 "rcparse.y" +case 210: +#line 1529 "rcparse.y" { style |= yyvsp[0].il; } break; -case 210: -#line 1442 "rcparse.y" +case 211: +#line 1533 "rcparse.y" { style &=~ yyvsp[0].il; } break; -case 211: -#line 1446 "rcparse.y" +case 212: +#line 1537 "rcparse.y" { style |= yyvsp[0].il; } break; -case 212: -#line 1450 "rcparse.y" +case 213: +#line 1541 "rcparse.y" { style &=~ yyvsp[0].il; } break; -case 213: -#line 1457 "rcparse.y" +case 214: +#line 1548 "rcparse.y" { yyval.il = yyvsp[0].i.val; } break; -case 214: -#line 1461 "rcparse.y" +case 215: +#line 1552 "rcparse.y" { yyval.il = yyvsp[-1].il; } break; -case 215: -#line 1470 "rcparse.y" +case 216: +#line 1561 "rcparse.y" { yyval.il = 0; } break; -case 216: -#line 1474 "rcparse.y" +case 217: +#line 1565 "rcparse.y" { yyval.il = yyvsp[0].il; } break; -case 217: -#line 1483 "rcparse.y" +case 218: +#line 1574 "rcparse.y" { yyval.il = yyvsp[0].il; } break; -case 218: -#line 1492 "rcparse.y" +case 219: +#line 1583 "rcparse.y" { yyval.il = yyvsp[0].i.val; } break; -case 219: -#line 1501 "rcparse.y" +case 220: +#line 1592 "rcparse.y" { yyval.i = yyvsp[0].i; } break; -case 220: -#line 1505 "rcparse.y" +case 221: +#line 1596 "rcparse.y" { yyval.i = yyvsp[-1].i; } break; -case 221: -#line 1509 "rcparse.y" +case 222: +#line 1600 "rcparse.y" { yyval.i.val = ~ yyvsp[0].i.val; yyval.i.dword = yyvsp[0].i.dword; } break; -case 222: -#line 1514 "rcparse.y" +case 223: +#line 1605 "rcparse.y" { yyval.i.val = - yyvsp[0].i.val; yyval.i.dword = yyvsp[0].i.dword; } break; -case 223: -#line 1519 "rcparse.y" +case 224: +#line 1610 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val * yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 224: -#line 1524 "rcparse.y" +case 225: +#line 1615 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val / yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 225: -#line 1529 "rcparse.y" +case 226: +#line 1620 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val % yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 226: -#line 1534 "rcparse.y" +case 227: +#line 1625 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val + yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 227: -#line 1539 "rcparse.y" +case 228: +#line 1630 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val - yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 228: -#line 1544 "rcparse.y" +case 229: +#line 1635 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val & yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 229: -#line 1549 "rcparse.y" +case 230: +#line 1640 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val ^ yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 230: -#line 1554 "rcparse.y" +case 231: +#line 1645 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val | yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 231: -#line 1565 "rcparse.y" +case 232: +#line 1656 "rcparse.y" { yyval.il = yyvsp[0].il; } break; -case 232: -#line 1574 "rcparse.y" +case 233: +#line 1665 "rcparse.y" { yyval.il = yyvsp[0].i.val; } break; -case 233: -#line 1585 "rcparse.y" +case 234: +#line 1676 "rcparse.y" { yyval.i = yyvsp[0].i; } break; -case 234: -#line 1589 "rcparse.y" +case 235: +#line 1680 "rcparse.y" { yyval.i = yyvsp[-1].i; } break; -case 235: -#line 1593 "rcparse.y" +case 236: +#line 1684 "rcparse.y" { yyval.i.val = ~ yyvsp[0].i.val; yyval.i.dword = yyvsp[0].i.dword; } break; -case 236: -#line 1598 "rcparse.y" +case 237: +#line 1689 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val * yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 237: -#line 1603 "rcparse.y" +case 238: +#line 1694 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val / yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 238: -#line 1608 "rcparse.y" +case 239: +#line 1699 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val % yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 239: -#line 1613 "rcparse.y" +case 240: +#line 1704 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val + yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 240: -#line 1618 "rcparse.y" +case 241: +#line 1709 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val - yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 241: -#line 1623 "rcparse.y" +case 242: +#line 1714 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val & yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 242: -#line 1628 "rcparse.y" +case 243: +#line 1719 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val ^ yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; } break; -case 243: -#line 1633 "rcparse.y" +case 244: +#line 1724 "rcparse.y" { yyval.i.val = yyvsp[-2].i.val | yyvsp[0].i.val; yyval.i.dword = yyvsp[-2].i.dword || yyvsp[0].i.dword; @@ -3129,7 +3203,7 @@ case 243: break; } -#line 727 "/usr/share/bison/bison.simple" +#line 705 "/usr/share/bison/bison.simple" yyvsp -= yylen; @@ -3360,7 +3434,7 @@ yyreturn: #endif return yyresult; } -#line 1639 "rcparse.y" +#line 1730 "rcparse.y" /* Set the language from the command line. */ diff --git a/contrib/binutils/binutils/rcparse.h b/contrib/binutils/binutils/rcparse.h index 7fc8ad4..3ad5fd3 100644 --- a/contrib/binutils/binutils/rcparse.h +++ b/contrib/binutils/binutils/rcparse.h @@ -42,6 +42,7 @@ typedef union } ss; } yystype; # define YYSTYPE yystype +# define YYSTYPE_IS_TRIVIAL 1 #endif # define BEG 257 # define END 258 diff --git a/contrib/binutils/binutils/rcparse.y b/contrib/binutils/binutils/rcparse.y index 152c8ee..898e99f 100644 --- a/contrib/binutils/binutils/rcparse.y +++ b/contrib/binutils/binutils/rcparse.y @@ -1,5 +1,5 @@ %{ /* rcparse.y -- parser for Windows rc files - Copyright 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. This file is part of GNU Binutils. @@ -153,28 +153,21 @@ static unsigned long class; input: /* empty */ - | input newcmd accelerator - | input newcmd bitmap - | input newcmd cursor - | input newcmd dialog - | input newcmd font - | input newcmd icon - | input newcmd language - | input newcmd menu - | input newcmd menuex - | input newcmd messagetable - | input newcmd rcdata - | input newcmd stringtable - | input newcmd user - | input newcmd versioninfo - | input newcmd IGNORED_TOKEN - ; - -newcmd: - /* empty */ - { - rcparse_discard_strings (); - } + | input accelerator + | input bitmap + | input cursor + | input dialog + | input font + | input icon + | input language + | input menu + | input menuex + | input messagetable + | input rcdata + | input stringtable + | input user + | input versioninfo + | input IGNORED_TOKEN ; /* Accelerator resources. */ @@ -183,6 +176,9 @@ accelerator: id ACCELERATORS suboptions BEG acc_entries END { define_accelerator ($1, &$3, $5); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -309,6 +305,9 @@ bitmap: id BITMAP memflags_move file_name { define_bitmap ($1, &$3, $4); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -318,6 +317,9 @@ cursor: id CURSOR memflags_move_discard file_name { define_cursor ($1, &$3, $4); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -340,10 +342,14 @@ dialog: dialog.ex = NULL; dialog.controls = NULL; sub_res_info = $3; + style = 0; } styles BEG controls END { define_dialog ($1, &sub_res_info, &dialog); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr cnumexpr @@ -363,10 +369,14 @@ dialog: memset (dialog.ex, 0, sizeof (struct dialog_ex)); dialog.controls = NULL; sub_res_info = $3; + style = 0; } styles BEG controls END { define_dialog ($1, &sub_res_info, &dialog); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr cnumexpr cnumexpr @@ -387,10 +397,14 @@ dialog: dialog.ex->help = $9; dialog.controls = NULL; sub_res_info = $3; + style = 0; } styles BEG controls END { define_dialog ($1, &sub_res_info, &dialog); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -409,6 +423,8 @@ styles: /* empty */ | styles CAPTION QUOTEDSTRING { + dialog.style |= WS_CAPTION; + style |= WS_CAPTION; unicode_from_ascii ((int *) NULL, &dialog.caption, $3); } | styles CLASS id @@ -416,7 +432,6 @@ styles: dialog.class = $3; } | styles STYLE - { style = dialog.style; } styleexpr { dialog.style = style; @@ -425,15 +440,57 @@ styles: { dialog.exstyle = $3; } + | styles CLASS QUOTEDSTRING + { + res_string_to_id (& dialog.class, $3); + } | styles FONT numexpr ',' QUOTEDSTRING { dialog.style |= DS_SETFONT; + style |= DS_SETFONT; dialog.pointsize = $3; unicode_from_ascii ((int *) NULL, &dialog.font, $5); + if (dialog.ex != NULL) + { + dialog.ex->weight = 0; + dialog.ex->italic = 0; + dialog.ex->charset = 1; + } + } + | styles FONT numexpr ',' QUOTEDSTRING cnumexpr + { + dialog.style |= DS_SETFONT; + style |= DS_SETFONT; + dialog.pointsize = $3; + unicode_from_ascii ((int *) NULL, &dialog.font, $5); + if (dialog.ex == NULL) + rcparse_warning (_("extended FONT requires DIALOGEX")); + else + { + dialog.ex->weight = $6; + dialog.ex->italic = 0; + dialog.ex->charset = 1; + } } | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr { dialog.style |= DS_SETFONT; + style |= DS_SETFONT; + dialog.pointsize = $3; + unicode_from_ascii ((int *) NULL, &dialog.font, $5); + if (dialog.ex == NULL) + rcparse_warning (_("extended FONT requires DIALOGEX")); + else + { + dialog.ex->weight = $6; + dialog.ex->italic = $7; + dialog.ex->charset = 1; + } + } + | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr cnumexpr + { + dialog.style |= DS_SETFONT; + style |= DS_SETFONT; dialog.pointsize = $3; unicode_from_ascii ((int *) NULL, &dialog.font, $5); if (dialog.ex == NULL) @@ -442,6 +499,7 @@ styles: { dialog.ex->weight = $6; dialog.ex->italic = $7; + dialog.ex->charset = $8; } } | styles MENU id @@ -515,7 +573,7 @@ control: { $$ = $3; if (dialog.ex == NULL) - rcparse_warning (_("IEDIT requires DIALOGEX")); + rcparse_warning (_("BEDIT requires DIALOGEX")); res_string_to_id (&$$->class, "BEDIT"); } | CHECKBOX @@ -569,7 +627,7 @@ control: $$->data = $12; } $$->class.named = 1; - unicode_from_ascii(&$$->class.u.n.length, &$$->class.u.n.name, $5); + unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5); } | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data @@ -580,7 +638,7 @@ control: $$->help = $12; $$->data = $13; $$->class.named = 1; - unicode_from_ascii(&$$->class.u.n.length, &$$->class.u.n.name, $5); + unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5); } | CTEXT { @@ -855,6 +913,9 @@ font: id FONT memflags_move_discard file_name { define_font ($1, &$3, $4); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -864,6 +925,9 @@ icon: id ICON memflags_move_discard file_name { define_icon ($1, &$3, $4); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -883,6 +947,9 @@ menu: id MENU suboptions BEG menuitems END { define_menu ($1, &$3, $5); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -970,6 +1037,9 @@ menuex: id MENUEX suboptions BEG menuexitems END { define_menu ($1, &$3, $5); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -1036,6 +1106,9 @@ messagetable: id MESSAGETABLE memflags_move file_name { define_messagetable ($1, &$3, $4); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -1045,6 +1118,9 @@ rcdata: id RCDATA suboptions BEG optrcdata_data END { define_rcdata ($1, &$3, $5.first); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -1124,10 +1200,16 @@ string_data: | string_data numexpr QUOTEDSTRING { define_stringtable (&sub_res_info, $2, $3); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } | string_data numexpr ',' QUOTEDSTRING { define_stringtable (&sub_res_info, $2, $4); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -1138,10 +1220,16 @@ user: id id suboptions BEG optrcdata_data END { define_user_data ($1, $2, &$3, $5.first); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } | id id suboptions file_name { define_user_file ($1, $2, &$3, $4); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -1151,6 +1239,9 @@ versioninfo: id VERSIONINFO fixedverinfo BEG verblocks END { define_versioninfo ($1, language, $3, $5); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -1310,7 +1401,7 @@ suboptions: memset (&$$, 0, sizeof (struct res_res_info)); $$.language = language; /* FIXME: Is this the right default? */ - $$.memflags = MEMFLAG_MOVEABLE; + $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE; } | suboptions memflag { @@ -1359,7 +1450,7 @@ memflags_move: { memset (&$$, 0, sizeof (struct res_res_info)); $$.language = language; - $$.memflags = MEMFLAG_MOVEABLE; + $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE; } | memflags_move memflag { diff --git a/contrib/binutils/binutils/readelf.c b/contrib/binutils/binutils/readelf.c index 3bd67ba..77694cb 100644 --- a/contrib/binutils/binutils/readelf.c +++ b/contrib/binutils/binutils/readelf.c @@ -127,6 +127,7 @@ int do_debug_frames; int do_debug_frames_interp; int do_debug_macinfo; int do_debug_str; +int do_debug_loc; int do_arch; int do_notes; int is_32bit_elf; @@ -227,10 +228,13 @@ static int display_debug_aranges PARAMS ((Elf32_Internal_Sh static int display_debug_frames PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); static int display_debug_macinfo PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); static int display_debug_str PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); +static int display_debug_loc PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *)); static unsigned char * process_abbrev_section PARAMS ((unsigned char *, unsigned char *)); static void load_debug_str PARAMS ((FILE *)); static void free_debug_str PARAMS ((void)); static const char * fetch_indirect_string PARAMS ((unsigned long)); +static void load_debug_loc PARAMS ((FILE *)); +static void free_debug_loc PARAMS ((void)); static unsigned long read_leb128 PARAMS ((unsigned char *, int *, int)); static int process_extended_line_op PARAMS ((unsigned char *, int, int)); static void reset_state_machine PARAMS ((int)); @@ -845,29 +849,49 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) if (is_32bit_elf) { if (is_rela) - printf - (_(" Offset Info Type Symbol's Value Symbol's Name Addend\n")); + { + if (do_wide) + printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n")); + else + printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n")); + } else - printf - (_(" Offset Info Type Symbol's Value Symbol's Name\n")); + { + if (do_wide) + printf (_(" Offset Info Type Sym. Value Symbol's Name\n")); + else + printf (_(" Offset Info Type Sym.Value Sym. Name\n")); + } } else { if (is_rela) - printf - (_(" Offset Info Type Symbol's Value Symbol's Name Addend\n")); + { + if (do_wide) + printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n")); + else + printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n")); + } else - printf - (_(" Offset Info Type Symbol's Value Symbol's Name\n")); + { + if (do_wide) + printf (_(" Offset Info Type Symbol's Value Symbol's Name\n")); + else + printf (_(" Offset Info Type Sym. Value Sym. Name\n")); + } } for (i = 0; i < rel_size; i++) { const char * rtype; + const char * rtype2 = NULL; + const char * rtype3 = NULL; bfd_vma offset; bfd_vma info; bfd_vma symtab_index; bfd_vma type; + bfd_vma type2 = (bfd_vma) NULL; + bfd_vma type3 = (bfd_vma) NULL; if (is_rela) { @@ -887,10 +911,16 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) } else { - if (elf_header.e_machine == EM_SPARCV9) - type = ELF64_R_TYPE_ID (info); + if (elf_header.e_machine == EM_MIPS) + { + type = ELF64_MIPS_R_TYPE (info); + type2 = ELF64_MIPS_R_TYPE2 (info); + type3 = ELF64_MIPS_R_TYPE3 (info); + } + else if (elf_header.e_machine == EM_SPARCV9) + type = ELF64_R_TYPE_ID (info); else - type = ELF64_R_TYPE (info); + type = ELF64_R_TYPE (info); /* The #ifdef BFD64 below is to prevent a compile time warning. We know that if we do not have a 64 bit data type that we will never execute this code anyway. */ @@ -910,13 +940,18 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) else { #ifdef _bfd_int64_low - printf ("%8.8lx%8.8lx %8.8lx%8.8lx ", + printf (do_wide + ? "%8.8lx%8.8lx %8.8lx%8.8lx " + : "%4.4lx%8.8lx %4.4lx%8.8lx ", _bfd_int64_high (offset), _bfd_int64_low (offset), _bfd_int64_high (info), _bfd_int64_low (info)); #else - printf ("%16.16lx %16.16lx ", offset, info); + printf (do_wide + ? "%16.16lx %16.16lx " + : "%12.12lx %12.12lx ", + offset, info); #endif } @@ -1006,6 +1041,11 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) case EM_MIPS: case EM_MIPS_RS3_LE: rtype = elf_mips_reloc_type (type); + if (!is_32bit_elf) + { + rtype2 = elf_mips_reloc_type (type2); + rtype3 = elf_mips_reloc_type (type3); + } break; case EM_ALPHA: @@ -1067,12 +1107,12 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) if (rtype == NULL) #ifdef _bfd_int64_low - printf (_("unrecognised: %-7lx"), _bfd_int64_low (type)); + printf (_("unrecognized: %-7lx"), _bfd_int64_low (type)); #else - printf (_("unrecognised: %-7lx"), type); + printf (_("unrecognized: %-7lx"), type); #endif else - printf ("%-21.21s", rtype); + printf (do_wide ? "%-21.21s" : "%-17.17s", rtype); if (symtab_index) { @@ -1086,14 +1126,14 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) printf (" "); print_vma (psym->st_value, LONG_HEX); - printf (" "); + printf (is_32bit_elf ? " " : " "); if (psym->st_name == 0) - print_symbol (-25, SECTION_NAME (section_headers + psym->st_shndx)); + print_symbol (22, SECTION_NAME (section_headers + psym->st_shndx)); else if (strtab == NULL) printf (_("<string table index %3ld>"), psym->st_name); else - print_symbol (-25, strtab + psym->st_name); + print_symbol (22, strtab + psym->st_name); if (is_rela) printf (" + %lx", (unsigned long) relas [i].r_addend); @@ -1101,7 +1141,7 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) } else if (is_rela) { - printf ("%*c", is_32bit_elf ? 34 : 26, ' '); + printf ("%*c", is_32bit_elf ? (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' '); print_vma (relas[i].r_addend, LONG_HEX); } @@ -1110,6 +1150,33 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (info)); putchar ('\n'); + + if (! is_32bit_elf && elf_header.e_machine == EM_MIPS) + { + printf (" Type2: "); + + if (rtype2 == NULL) +#ifdef _bfd_int64_low + printf (_("unrecognized: %-7lx"), _bfd_int64_low (type2)); +#else + printf (_("unrecognized: %-7lx"), type2); +#endif + else + printf ("%-17.17s", rtype2); + + printf("\n Type3: "); + + if (rtype3 == NULL) +#ifdef _bfd_int64_low + printf (_("unrecognized: %-7lx"), _bfd_int64_low (type3)); +#else + printf (_("unrecognized: %-7lx"), type3); +#endif + else + printf ("%-17.17s", rtype3); + + putchar ('\n'); + } } if (is_rela) @@ -1504,7 +1571,7 @@ decode_ARM_machine_flags (e_flags, buf) switch (eabi) { default: - strcat (buf, ", <unrecognised EABI>"); + strcat (buf, ", <unrecognized EABI>"); if (e_flags) unknown = 1; break; @@ -2185,7 +2252,7 @@ usage () -A --arch-specific Display architecture specific information (if any).\n\ -D --use-dynamic Use the dynamic section info when displaying symbols\n\ -x --hex-dump=<number> Dump the contents of section <number>\n\ - -w --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str]\n\ + -w --debug-dump[=line,=info,=abbrev,=pubnames,=ranges,=macro,=frames,=str,=loc]\n\ Display the contents of DWARF2 debug sections\n")); #ifdef SUPPORT_DISASSEMBLY fprintf (stdout, _("\ @@ -2372,8 +2439,13 @@ parse_args (argc, argv) do_debug_str = 1; break; + case 'o': + case 'O': + do_debug_loc = 1; + break; + default: - warn (_("Unrecognised debug option '%s'\n"), optarg); + warn (_("Unrecognized debug option '%s'\n"), optarg); break; } } @@ -3238,7 +3310,8 @@ process_section_headers (file) } else if ((do_debugging || do_debug_info || do_debug_abbrevs || do_debug_lines || do_debug_pubnames || do_debug_aranges - || do_debug_frames || do_debug_macinfo || do_debug_str) + || do_debug_frames || do_debug_macinfo || do_debug_str + || do_debug_loc) && strncmp (name, ".debug_", 7) == 0) { name += 7; @@ -3252,6 +3325,7 @@ process_section_headers (file) || (do_debug_frames && (strcmp (name, "frame") == 0)) || (do_debug_macinfo && (strcmp (name, "macinfo") == 0)) || (do_debug_str && (strcmp (name, "str") == 0)) + || (do_debug_loc && (strcmp (name, "loc") == 0)) ) request_dump (i, DEBUG_DUMP); } @@ -6455,6 +6529,7 @@ get_AT_name (attribute) case DW_AT_src_coords: return "DW_AT_src_coords"; case DW_AT_body_begin: return "DW_AT_body_begin"; case DW_AT_body_end: return "DW_AT_body_end"; + case DW_AT_GNU_vector: return "DW_AT_GNU_vector"; default: { static char buffer [100]; @@ -7124,6 +7199,112 @@ decode_location_expression (data, pointer_size, length) } } +static const char * debug_loc_contents; +static bfd_vma debug_loc_size; + +static void +load_debug_loc (file) + FILE * file; +{ + Elf32_Internal_Shdr * sec; + unsigned int i; + + /* If it is already loaded, do nothing. */ + if (debug_loc_contents != NULL) + return; + + /* Locate the .debug_loc section. */ + for (i = 0, sec = section_headers; + i < elf_header.e_shnum; + i ++, sec ++) + if (strcmp (SECTION_NAME (sec), ".debug_loc") == 0) + break; + + if (i == elf_header.e_shnum || sec->sh_size == 0) + return; + + debug_loc_size = sec->sh_size; + + debug_loc_contents = ((char *) + get_data (NULL, file, sec->sh_offset, sec->sh_size, + _("debug_loc section data"))); +} + +static void +free_debug_loc () +{ + if (debug_loc_contents == NULL) + return; + + free ((char *) debug_loc_contents); + debug_loc_contents = NULL; + debug_loc_size = 0; +} + + +static int +display_debug_loc (section, start, file) + Elf32_Internal_Shdr * section; + unsigned char * start; + FILE * file ATTRIBUTE_UNUSED; +{ + unsigned char *section_end; + unsigned long bytes; + unsigned char *section_begin = start; + bfd_vma addr; + + addr = section->sh_addr; + bytes = section->sh_size; + section_end = start + bytes; + if (bytes == 0) + { + printf (_("\nThe .debug_loc section is empty.\n")); + return 0; + } + printf (_("Contents of the .debug_loc section:\n\n")); + printf (_("\n Offset Begin End Expression\n")); + while (start < section_end) + { + unsigned long begin; + unsigned long end; + unsigned short length; + unsigned long offset; + + offset = start - section_begin; + + while (1) + { + /* Normally, the lists in the debug_loc section are related to a + given compilation unit, and thus, we would use the + pointer size of that compilation unit. However, since we are + displaying it seperately here, we either have to store + pointer sizes of all compilation units, or assume they don't + change. We assume, like the debug_line display, that + it doesn't change. */ + begin = byte_get (start, debug_line_pointer_size); + start += debug_line_pointer_size; + end = byte_get (start, debug_line_pointer_size); + start += debug_line_pointer_size; + + if (begin == 0 && end == 0) + break; + + begin += addr; + end += addr; + + length = byte_get (start, 2); + start += 2; + + printf (" %8.8lx %8.8lx %8.8lx (", offset, begin, end); + decode_location_expression (start, debug_line_pointer_size, length); + printf (")\n"); + + start += length; + } + printf ("\n"); + } + return 1; +} static const char * debug_str_contents; static bfd_vma debug_str_size; @@ -7379,7 +7560,7 @@ read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size) break; default: - warn (_("Unrecognised form: %d\n"), form); + warn (_("Unrecognized form: %d\n"), form); break; } @@ -7528,6 +7709,12 @@ read_and_display_attr_value (attribute, form, data, cu_offset, pointer_size) decode_location_expression (block_start, pointer_size, uvalue); printf (")"); } + else if (form == DW_FORM_data4) + { + printf ("("); + printf ("location list"); + printf (")"); + } break; default: @@ -7564,6 +7751,7 @@ display_debug_info (section, start, file) printf (_("The section %s contains:\n\n"), SECTION_NAME (section)); load_debug_str (file); + load_debug_loc (file); while (start < end) { @@ -7748,6 +7936,7 @@ display_debug_info (section, start, file) } free_debug_str (); + free_debug_loc (); printf ("\n"); @@ -8559,7 +8748,7 @@ debug_displays[] = { ".eh_frame", display_debug_frames, NULL }, { ".debug_macinfo", display_debug_macinfo, NULL }, { ".debug_str", display_debug_str, NULL }, - + { ".debug_loc", display_debug_loc, NULL }, { ".debug_pubtypes", display_debug_not_supported, NULL }, { ".debug_ranges", display_debug_not_supported, NULL }, { ".debug_static_func", display_debug_not_supported, NULL }, @@ -8602,7 +8791,7 @@ display_debug_section (section, file) } if (i == -1) - printf (_("Unrecognised debug section: %s\n"), name); + printf (_("Unrecognized debug section: %s\n"), name); free (start); @@ -9240,6 +9429,7 @@ process_corefile_note_segment (file, offset, length) while (external < (Elf_External_Note *)((char *) pnotes + length)) { + Elf_External_Note * next; Elf32_Internal_Note inote; char * temp = NULL; @@ -9250,7 +9440,18 @@ process_corefile_note_segment (file, offset, length) inote.descdata = inote.namedata + align_power (inote.namesz, 2); inote.descpos = offset + (inote.descdata - (char *) pnotes); - external = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2)); + next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2)); + + if (((char *) next) > (((char *) pnotes) + length)) + { + warn (_("corrupt note found at offset %x into core notes\n"), + ((char *) external) - ((char *) pnotes)); + warn (_(" type: %x, namesize: %08lx, descsize: %08lx\n"), + inote.type, inote.namesz, inote.descsz); + break; + } + + external = next; /* Verify that name is null terminated. It appears that at least one version of Linux (RedHat 6.0) generates corefiles that don't diff --git a/contrib/binutils/binutils/resbin.c b/contrib/binutils/binutils/resbin.c index a545343..7ed84f9 100644 --- a/contrib/binutils/binutils/resbin.c +++ b/contrib/binutils/binutils/resbin.c @@ -1,5 +1,5 @@ /* resbin.c -- manipulate the Windows binary resource format. - Copyright 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright 1997, 1998, 1999, 2002 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. This file is part of GNU Binutils. @@ -30,6 +30,7 @@ /* Macros to swap in values. */ +#define get_8(s) (*((unsigned char *)(s))) #define get_16(be, s) ((be) ? bfd_getb16 (s) : bfd_getl16 (s)) #define get_32(be, s) ((be) ? bfd_getb32 (s) : bfd_getl32 (s)) @@ -68,6 +69,9 @@ static struct res_resource *bin_to_res_version PARAMS ((const unsigned char *, unsigned long, int)); static struct res_resource *bin_to_res_userdata PARAMS ((const unsigned char *, unsigned long, int)); +static void get_version_header + PARAMS ((const unsigned char *, unsigned long, int, const char *, + unichar **, int *, int *, int *, int *)); /* Given a resource type ID, a pointer to data, a length, return a res_resource structure which represents that resource. The caller @@ -460,7 +464,7 @@ bin_to_res_dialog (data, length, big_endian) unsigned long length; int big_endian; { - int version; + int signature; struct dialog *d; int c, sublen, i; unsigned int off; @@ -472,8 +476,8 @@ bin_to_res_dialog (data, length, big_endian) d = (struct dialog *) res_alloc (sizeof *d); - version = get_16 (big_endian, data); - if (version != 1) + signature = get_16 (big_endian, data + 2); + if (signature != 0xffff) { d->ex = NULL; d->style = get_32 (big_endian, data); @@ -482,11 +486,11 @@ bin_to_res_dialog (data, length, big_endian) } else { - int signature; + int version; - signature = get_16 (big_endian, data + 2); - if (signature != 0xffff) - fatal (_("unexpected dialog signature %d"), signature); + version = get_16 (big_endian, data); + if (version != 1) + fatal (_("unexpected DIALOGEX version %d"), version); d->ex = (struct dialog_ex *) res_alloc (sizeof (struct dialog_ex)); d->ex->help = get_32 (big_endian, data + 4); @@ -514,6 +518,8 @@ bin_to_res_dialog (data, length, big_endian) d->caption = get_unicode (data + off, length - off, big_endian, &sublen); off += sublen * 2 + 2; + if (sublen == 0) + d->caption = NULL; if ((d->style & DS_SETFONT) == 0) { @@ -523,6 +529,7 @@ bin_to_res_dialog (data, length, big_endian) { d->ex->weight = 0; d->ex->italic = 0; + d->ex->charset = 1; /* Default charset. */ } } else @@ -538,7 +545,8 @@ bin_to_res_dialog (data, length, big_endian) if (length < off + 4) toosmall (_("dialogex font information")); d->ex->weight = get_16 (big_endian, data + off); - d->ex->italic = get_16 (big_endian, data + off + 2); + d->ex->italic = get_8 (data + off + 2); + d->ex->charset = get_8 (data + off + 3); off += 4; } @@ -808,7 +816,7 @@ static struct res_resource * bin_to_res_rcdata (data, length, big_endian) const unsigned char *data; unsigned long length; - int big_endian; + int big_endian ATTRIBUTE_UNUSED; { struct rcdata_item *ri; struct res_resource *r; @@ -1019,7 +1027,7 @@ bin_to_res_version (data, length, big_endian) struct res_resource *r; get_version_header (data, length, big_endian, "VS_VERSION_INFO", - (unichar *) NULL, &verlen, &vallen, &type, &off); + (unichar **) NULL, &verlen, &vallen, &type, &off); if ((unsigned int) verlen != length) fatal (_("version length %d does not match resource length %lu"), @@ -1091,7 +1099,7 @@ bin_to_res_version (data, length, big_endian) vi->type = VERINFO_STRING; get_version_header (data, length, big_endian, "StringFileInfo", - (unichar *) NULL, &verlen, &vallen, &type, + (unichar **) NULL, &verlen, &vallen, &type, &off); if (vallen != 0) @@ -1163,7 +1171,7 @@ bin_to_res_version (data, length, big_endian) vi->type = VERINFO_VAR; get_version_header (data, length, big_endian, "VarFileInfo", - (unichar *) NULL, &verlen, &vallen, &type, + (unichar **) NULL, &verlen, &vallen, &type, &off); if (vallen != 0) @@ -1231,7 +1239,7 @@ static struct res_resource * bin_to_res_userdata (data, length, big_endian) const unsigned char *data; unsigned long length; - int big_endian; + int big_endian ATTRIBUTE_UNUSED; { struct rcdata_item *ri; struct res_resource *r; @@ -1252,6 +1260,7 @@ bin_to_res_userdata (data, length, big_endian) /* Macros to swap out values. */ +#define put_8(v, s) (*((unsigned char *) (s)) = (unsigned char) (v)) #define put_16(be, v, s) ((be) ? bfd_putb16 ((v), (s)) : bfd_putl16 ((v), (s))) #define put_32(be, v, s) ((be) ? bfd_putb32 ((v), (s)) : bfd_putl32 ((v), (s))) @@ -1621,12 +1630,14 @@ res_to_bin_dialog (dialog, big_endian) if (dialog->ex == NULL) { put_16 (big_endian, 0, d->data + 2); - put_16 (big_endian, 0, d->data + 4); + put_8 (0, d->data + 4); + put_8 (1, d->data + 5); } else { put_16 (big_endian, dialog->ex->weight, d->data + 2); - put_16 (big_endian, dialog->ex->italic, d->data + 4); + put_8 (dialog->ex->italic, d->data + 4); + put_8 (dialog->ex->charset, d->data + 5); } } diff --git a/contrib/binutils/binutils/resrc.c b/contrib/binutils/binutils/resrc.c index eb7db96..fb0d36c 100644 --- a/contrib/binutils/binutils/resrc.c +++ b/contrib/binutils/binutils/resrc.c @@ -1,5 +1,5 @@ /* resrc.c -- read and write Windows rc files. - Copyright 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. This file is part of GNU Binutils. @@ -131,7 +131,7 @@ static FILE *cpp_pipe; static char *cpp_temp_file; -/* Input stream is either a file or a pipe. */ +/* Input stream is either a file or a pipe. */ static enum {ISTREAM_PIPE, ISTREAM_FILE} istream_type; @@ -173,7 +173,7 @@ static void get_data PARAMS ((FILE *, unsigned char *, unsigned long, const char *)); static void define_fontdirs PARAMS ((void)); -/* Run `cmd' and redirect the output to `redir'. */ +/* Run `cmd' and redirect the output to `redir'. */ static int run_cmd (cmd, redir) @@ -481,6 +481,7 @@ read_rc_file (filename, preprocessor, preprocargs, language, use_temp_file) rcparse_set_language (language); yyin = cpp_pipe; yyparse (); + rcparse_discard_strings (); close_input_stream (); @@ -518,7 +519,7 @@ close_input_stream () pclose (cpp_pipe); } - /* Since this is also run via xatexit, safeguard. */ + /* Since this is also run via xatexit, safeguard. */ cpp_pipe = NULL; cpp_temp_file = NULL; } @@ -1580,7 +1581,7 @@ write_rc_directory (e, rd, type, name, language, level) case 2: /* If we're at level 2, the key of this resource is the name - we are going to use in the rc printout. */ + we are going to use in the rc printout. */ name = &re->id; break; @@ -1592,7 +1593,8 @@ write_rc_directory (e, rd, type, name, language, level) && (re->id.u.id & 0xffff) == re->id.u.id) { fprintf (e, "LANGUAGE %lu, %lu\n", - re->id.u.id & 0xff, (re->id.u.id >> 8) & 0xff); + re->id.u.id & ((1 << SUBLANG_SHIFT) - 1), + (re->id.u.id >> SUBLANG_SHIFT) & 0xff); *language = re->id.u.id; } break; @@ -2052,23 +2054,26 @@ write_rc_dialog (e, dialog) { const struct dialog_control *control; - if (dialog->style != 0) - fprintf (e, "STYLE 0x%lx\n", dialog->style); + fprintf (e, "STYLE 0x%lx\n", dialog->style); + if (dialog->exstyle != 0) fprintf (e, "EXSTYLE 0x%lx\n", dialog->exstyle); + if ((dialog->class.named && dialog->class.u.n.length > 0) || dialog->class.u.id != 0) { fprintf (e, "CLASS "); - res_id_print (e, dialog->class, 0); + res_id_print (e, dialog->class, 1); fprintf (e, "\n"); } + if (dialog->caption != NULL) { fprintf (e, "CAPTION \""); unicode_print (e, dialog->caption, -1); fprintf (e, "\"\n"); } + if ((dialog->menu.named && dialog->menu.u.n.length > 0) || dialog->menu.u.id != 0) { @@ -2076,14 +2081,18 @@ write_rc_dialog (e, dialog) res_id_print (e, dialog->menu, 0); fprintf (e, "\n"); } + if (dialog->font != NULL) { fprintf (e, "FONT %d, \"", dialog->pointsize); unicode_print (e, dialog->font, -1); fprintf (e, "\""); if (dialog->ex != NULL - && (dialog->ex->weight != 0 || dialog->ex->italic != 0)) - fprintf (e, ", %d, %d", dialog->ex->weight, dialog->ex->italic); + && (dialog->ex->weight != 0 + || dialog->ex->italic != 0 + || dialog->ex->charset != 1)) + fprintf (e, ", %d, %d, %d", + dialog->ex->weight, dialog->ex->italic, dialog->ex->charset); fprintf (e, "\n"); } diff --git a/contrib/binutils/binutils/size.c b/contrib/binutils/binutils/size.c index 3da7520..961593b 100644 --- a/contrib/binutils/binutils/size.c +++ b/contrib/binutils/binutils/size.c @@ -316,6 +316,7 @@ display_archive (file) bfd *file; { bfd *arfile = (bfd *) NULL; + bfd *last_arfile = (bfd *) NULL; for (;;) { @@ -333,8 +334,14 @@ display_archive (file) } display_bfd (arfile); - /* Don't close the archive elements; we need them for next_archive. */ + + if (last_arfile != NULL) + bfd_close (last_arfile); + last_arfile = arfile; } + + if (last_arfile != NULL) + bfd_close (last_arfile); } static void diff --git a/contrib/binutils/config/mh-s390pic b/contrib/binutils/config/mh-s390pic new file mode 100644 index 0000000..92e48d9 --- /dev/null +++ b/contrib/binutils/config/mh-s390pic @@ -0,0 +1 @@ +PICFLAG=-fpic diff --git a/contrib/binutils/config/mt-s390pic b/contrib/binutils/config/mt-s390pic new file mode 100644 index 0000000..ff98727 --- /dev/null +++ b/contrib/binutils/config/mt-s390pic @@ -0,0 +1 @@ +PICFLAG_FOR_TARGET=-fpic diff --git a/contrib/binutils/gas/ChangeLog b/contrib/binutils/gas/ChangeLog index fdba914..d5c95ae 100644 --- a/contrib/binutils/gas/ChangeLog +++ b/contrib/binutils/gas/ChangeLog @@ -1,3 +1,94 @@ +2002-05-13 Nick Clifton <nickc@cambridge.redhat.com> + + * stabs.c (s_stab_generic): Fix grammatical error in warning + message. + +2002-05-11 Nick Clifton <nickc@cambridge.redhat.com> + + * stabs.c (s_stab_generic): Warn about a description field that is + too big. + +2002-05-11 Daniel Jacobowitz <drow@mvista.com> + + Merge from mainline: + 2002-05-11 Nick Clifton <nickc@cambridge.redhat.com> + * config/obj-coff.c: Fix compile time warnings when compiling + without BFD_ASSEMBLER defined. + Fix formatting. + + * config/tc-sh.c (md_pcrel_from): Define for use with sh-hms + target. + (md_pcrel_from_section): Use md_pcrel_from(). + +2002-05-09 Alan Modra <amodra@bigpond.net.au> + + * config/tc-i386.c (md_estimate_size_before_relax) Don't lose + reloc when no_cond_jump_promotion. + + Merge from mainline + 2002-05-08 Jim Wilson <wilson@redhat.com> + * config/tc-i960.c (md_estimate_size_before_relax): Return size of + current variable part of frag. + + 2002-05-02 Alan Modra <amodra@bigpond.net.au> + * config/tc-ppc.c (mapping): Map sectoff to BFD_RELOC_16_BASEREL. + (ppc_elf_validate_fix): Replace BFD_RELOC_32_BASEREL with + BFD_RELOC_16_BASEREL. + (md_assemble): Likewise. + (md_apply_fix3): Likewise. + + 2002-05-01 Andrew Macleod <amacleod@cygnus.com> + * config/tc-i386.c (extra_symbol_chars): Add '[' to the list. + + 2002-04-28 Alan Modra <amodra@bigpond.net.au> + * config/tc-i386.c: Formatting fixes, add missing space in error + message. + +2002-05-03 Alexandre Oliva <aoliva@redhat.com> + + * config/tc-s390.c (md_gather_operands): Emit dwarf2 line-number + information for instructions. + +2002-05-02 Nick Clifton <nickc@cambridge.redhat.com> + + * config/tc-arm.c (thumb_add_sub): Do not convert a subtract of + zero into an add of zero - it is not the same. + +2002-04-27 Alan Modra <amodra@bigpond.net.au> + + Merge from mainline. + 2002-04-17 Martin Schwidefsky <schwidefsky@de.ibm.com> + * config/tc-s390.c (tc_s390_fix_adjustable): Prevent adjustments to + symbols in merge sections. + + 2002-02-19 Martin Schwidefsky <schwidefsky@de.ibm.com> + * config/tc-s390.c (md_parse_option): Add switches -m31 and -m64. + Make bit size independent of architecture switch. + (md_begin): Add warning for -m64 with -Aesa. + (s390_md_end): Use renamed architecture defines. + + 2002-02-19 Tom Tromey <tromey@redhat.com> + * config/tc-xstormy16.h (DWARF2_LINE_MIN_INSN_LENGTH): Define. + + Tue Apr 9 16:45:48 2002 J"orn Rennecke <joern.rennecke@superh.com> + * config/tc-sh.h (TC_FIX_ADJUSTABLE): Disable adjusting if + symbol_used_in_reloc_p is true. + * config/tc-sh.c (md_apply_fix3): Don't zero relocations on big + endian hosts. + + 2002-04-03 Alan Modra <amodra@bigpond.net.au> + * symbols.c (resolve_symbol_value <O_uminus, O_bit_not, + O_logical_not>): Derive final_seg from add_symbol. + <O_multiply..O_logical_or>: More final_seg twiddles. + +2002-04-24 Andreas Schwab <schwab@suse.de> + + * config/tc-i386.c (output_jump, output_disp) + (md_estimate_size_before_relax): Don't set fx_pcrel_adjust any + more. + (md_apply_fix3): Remember addend value for rela relocations. + (tc_gen_reloc): Correctly compute pc-relative relocation addend. + 2002-04-10 Alan Modra <amodra@bigpond.net.au> * as.c (parse_args <OPTION_VERSION>): Use VERSION is diff --git a/contrib/binutils/gas/config/obj-coff.c b/contrib/binutils/gas/config/obj-coff.c index c956d62..9eb4bdd 100644 --- a/contrib/binutils/gas/config/obj-coff.c +++ b/contrib/binutils/gas/config/obj-coff.c @@ -1713,9 +1713,9 @@ const short seg_N_TYPE[] = int function_lineoff = -1; /* Offset in line#s where the last function started (the odd entry for line #0) */ -/* structure used to keep the filenames which +/* Structure used to keep the filenames which are too long around so that we can stick them - into the string table */ + into the string table. */ struct filename_list { char *filename; @@ -1729,39 +1729,38 @@ static symbolS *last_line_symbol; /* Add 4 to the real value to get the index and compensate the negatives. This vector is used by S_GET_SEGMENT to turn a coff - section number into a segment number -*/ -static symbolS *previous_file_symbol; -void c_symbol_merge (); -static int line_base; + section number into a segment number. */ -symbolS *c_section_symbol (); bfd *abfd; +static symbolS *previous_file_symbol; +static int line_base; -static void fixup_segment PARAMS ((segment_info_type *segP, - segT this_segment_type)); - -static void fixup_mdeps PARAMS ((fragS *, - object_headers *, - segT)); - -static void fill_section PARAMS ((bfd * abfd, - object_headers *, - unsigned long *)); - -static int c_line_new PARAMS ((symbolS * symbol, long paddr, - int line_number, - fragS * frag)); - -static void w_symbols PARAMS ((bfd * abfd, char *where, - symbolS * symbol_rootP)); - -static void adjust_stab_section PARAMS ((bfd *abfd, segT seg)); - +void c_symbol_merge PARAMS ((symbolS *, symbolS *)); +symbolS *c_section_symbol PARAMS ((char *, int)); +void obj_coff_section PARAMS ((int)); +void do_relocs_for PARAMS ((bfd *, object_headers *, unsigned long *)); +char * symbol_to_chars PARAMS ((bfd *, char *, symbolS *)); +void w_strings PARAMS ((char *)); + +static void fixup_segment PARAMS ((segment_info_type *, segT)); +static void fixup_mdeps PARAMS ((fragS *, object_headers *, segT)); +static void fill_section PARAMS ((bfd *, object_headers *, unsigned long *)); +static int c_line_new PARAMS ((symbolS *, long, int, fragS *)); +static void w_symbols PARAMS ((bfd *, char *, symbolS *)); +static void adjust_stab_section PARAMS ((bfd *, segT)); static void obj_coff_lcomm PARAMS ((int)); static void obj_coff_text PARAMS ((int)); static void obj_coff_data PARAMS ((int)); -void obj_coff_section PARAMS ((int)); +static unsigned int count_entries_in_chain PARAMS ((unsigned int)); +static void coff_header_append PARAMS ((bfd *, object_headers *)); +static unsigned int yank_symbols PARAMS ((void)); +static unsigned int glue_symbols PARAMS ((symbolS **, symbolS **)); +static unsigned int tie_tags PARAMS ((void)); +static void crawl_symbols PARAMS ((object_headers *, bfd *)); +static void do_linenos_for PARAMS ((bfd *, object_headers *, unsigned long *)); +static void remove_subsegs PARAMS ((void)); + + /* When not using BFD_ASSEMBLER, we permit up to 40 sections. @@ -1800,6 +1799,8 @@ static const segT seg_info_off_by_4[] = #define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4]) +static relax_addressT relax_align PARAMS ((relax_addressT, long)); + static relax_addressT relax_align (address, alignment) relax_addressT address; @@ -1820,8 +1821,11 @@ s_get_segment (x) return SEG_INFO_FROM_SECTION_NUMBER (x->sy_symbol.ost_entry.n_scnum); } -/* calculate the size of the frag chain and fill in the section header - to contain all of it, also fill in the addr of the sections */ +static unsigned int size_section PARAMS ((bfd *, unsigned int)); + +/* Calculate the size of the frag chain and fill in the section header + to contain all of it, also fill in the addr of the sections. */ + static unsigned int size_section (abfd, idx) bfd *abfd ATTRIBUTE_UNUSED; @@ -1830,6 +1834,7 @@ size_section (abfd, idx) unsigned int size = 0; fragS *frag = segment_info[idx].frchainP->frch_root; + while (frag) { size = frag->fr_address; @@ -1882,7 +1887,7 @@ count_entries_in_chain (idx) unsigned int nrelocs; fixS *fixup_ptr; - /* Count the relocations */ + /* Count the relocations. */ fixup_ptr = segment_info[idx].fix_root; nrelocs = 0; while (fixup_ptr != (fixS *) NULL) @@ -1908,7 +1913,8 @@ count_entries_in_chain (idx) static int compare_external_relocs PARAMS ((const PTR, const PTR)); -/* AUX's ld expects relocations to be sorted */ +/* AUX's ld expects relocations to be sorted. */ + static int compare_external_relocs (x, y) const PTR x; @@ -1923,7 +1929,8 @@ compare_external_relocs (x, y) #endif -/* output all the relocations for a section */ +/* Output all the relocations for a section. */ + void do_relocs_for (abfd, h, file_cursor) bfd * abfd; @@ -1961,13 +1968,12 @@ do_relocs_for (abfd, h, file_cursor) { struct internal_reloc intr; - /* Only output some of the relocations */ + /* Only output some of the relocations. */ if (fix_ptr->fx_done == 0 && TC_COUNT_RELOC (fix_ptr)) { #ifdef TC_RELOC_MANGLE TC_RELOC_MANGLE (&segment_info[idx], fix_ptr, &intr, base); - #else symbolS *dot; symbolS *symbol_ptr = fix_ptr->fx_addsy; @@ -2012,36 +2018,26 @@ do_relocs_for (abfd, h, file_cursor) as_bad (_("bad relocation: symbol `%s' not in symbol table"), S_GET_NAME (symbol_ptr)); } + dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot; if (dot) - { - intr.r_symndx = dot->sy_number; - } + intr.r_symndx = dot->sy_number; else - { - intr.r_symndx = symbol_ptr->sy_number; - } - + intr.r_symndx = symbol_ptr->sy_number; } else - { - intr.r_symndx = -1; - } + intr.r_symndx = -1; #endif - (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr); ext_ptr++; - #if defined(TC_A29K) - /* The 29k has a special kludge for the high 16 bit reloc. Two relocations are emited, R_IHIHALF, and R_IHCONST. The second one doesn't contain a symbol, but uses the value for offset. */ - if (intr.r_type == R_IHIHALF) { - /* now emit the second bit */ + /* Now emit the second bit. */ intr.r_type = R_IHCONST; intr.r_symndx = fix_ptr->fx_addnumber; (void) bfd_coff_swap_reloc_out (abfd, &intr, ext_ptr); @@ -2066,14 +2062,12 @@ do_relocs_for (abfd, h, file_cursor) fix_ptr = fix_ptr->fx_next; } - #ifdef TE_AUX - /* Sort the reloc table */ + /* Sort the reloc table. */ qsort ((PTR) external_reloc_vec, nrelocs, sizeof (struct external_reloc), compare_external_relocs); #endif - - /* Write out the reloc table */ + /* Write out the reloc table. */ bfd_bwrite ((PTR) external_reloc_vec, (bfd_size_type) external_reloc_size, abfd); free (external_reloc_vec); @@ -2085,25 +2079,25 @@ do_relocs_for (abfd, h, file_cursor) } else { - /* No relocs */ + /* No relocs. */ segment_info[idx].scnhdr.s_relptr = 0; } } } - /* Set relocation_size field in file headers */ + + /* Set relocation_size field in file headers. */ H_SET_RELOCATION_SIZE (h, *file_cursor - reloc_start, 0); } -/* run through a frag chain and write out the data to go with it, fill - in the scnhdrs with the info on the file postions -*/ +/* Run through a frag chain and write out the data to go with it, fill + in the scnhdrs with the info on the file postions. */ + static void fill_section (abfd, h, file_cursor) bfd * abfd; object_headers *h ATTRIBUTE_UNUSED; unsigned long *file_cursor; { - unsigned int i; unsigned int paddr = 0; @@ -2229,7 +2223,7 @@ fill_section (abfd, h, file_cursor) } } -/* Coff file generation & utilities */ +/* Coff file generation & utilities. */ static void coff_header_append (abfd, h) @@ -2279,7 +2273,6 @@ coff_header_append (abfd, h) string_size += strlen (segment_info[i].name) + 1; } #endif - size = bfd_coff_swap_scnhdr_out (abfd, &(segment_info[i].scnhdr), buffer); @@ -2300,13 +2293,11 @@ symbol_to_chars (abfd, where, symbolP) unsigned int i; valueT val; - /* Turn any symbols with register attributes into abs symbols */ + /* Turn any symbols with register attributes into abs symbols. */ if (S_GET_SEGMENT (symbolP) == reg_section) - { - S_SET_SEGMENT (symbolP, absolute_section); - } - /* At the same time, relocate all symbols to their output value */ + S_SET_SEGMENT (symbolP, absolute_section); + /* At the same time, relocate all symbols to their output value. */ #ifndef TE_PE val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr + S_GET_VALUE (symbolP)); @@ -2329,25 +2320,25 @@ symbol_to_chars (abfd, where, symbolP) S_GET_STORAGE_CLASS (symbolP), i, numaux, where); } - return where; + return where; } void coff_obj_symbol_new_hook (symbolP) symbolS *symbolP; { - char underscore = 0; /* Symbol has leading _ */ + char underscore = 0; /* Symbol has leading _ */ - /* Effective symbol */ + /* Effective symbol. */ /* Store the pointer in the offset. */ S_SET_ZEROES (symbolP, 0L); S_SET_DATA_TYPE (symbolP, T_NULL); S_SET_STORAGE_CLASS (symbolP, 0); S_SET_NUMBER_AUXILIARY (symbolP, 0); - /* Additional information */ + /* Additional information. */ symbolP->sy_symbol.ost_flags = 0; - /* Auxiliary entries */ + /* Auxiliary entries. */ memset ((char *) &symbolP->sy_symbol.ost_auxent[0], 0, AUXESZ); if (S_IS_STRING (symbolP)) @@ -2356,9 +2347,7 @@ coff_obj_symbol_new_hook (symbolP) SF_SET_LOCAL (symbolP); } -/* - * Handle .ln directives. - */ +/* Handle .ln directives. */ static void obj_coff_ln (appline) @@ -2368,10 +2357,11 @@ obj_coff_ln (appline) if (! appline && def_symbol_in_progress != NULL) { + /* Wrong context. */ as_warn (_(".ln pseudo-op inside .def/.endef: ignored.")); demand_empty_rest_of_line (); return; - } /* wrong context */ + } l = get_absolute_expression (); c_line_new (0, frag_now_fix (), l, frag_now); @@ -2395,19 +2385,14 @@ obj_coff_ln (appline) demand_empty_rest_of_line (); } -/* - * def() - * - * Handle .def directives. - * - * One might ask : why can't we symbol_new if the symbol does not - * already exist and fill it with debug information. Because of - * the C_EFCN special symbol. It would clobber the value of the - * function symbol before we have a chance to notice that it is - * a C_EFCN. And a second reason is that the code is more clear this - * way. (at least I think it is :-). - * - */ +/* Handle .def directives. + + One might ask : why can't we symbol_new if the symbol does not + already exist and fill it with debug information. Because of + the C_EFCN special symbol. It would clobber the value of the + function symbol before we have a chance to notice that it is + a C_EFCN. And a second reason is that the code is more clear this + way. (at least I think it is :-). */ #define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';') #define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \ @@ -2418,9 +2403,9 @@ static void obj_coff_def (what) int what ATTRIBUTE_UNUSED; { - char name_end; /* Char after the end of name */ - char *symbol_name; /* Name of the debug symbol */ - char *symbol_name_copy; /* Temporary copy of the name */ + char name_end; /* Char after the end of name. */ + char *symbol_name; /* Name of the debug symbol. */ + char *symbol_name_copy; /* Temporary copy of the name. */ unsigned int symbol_name_length; if (def_symbol_in_progress != NULL) @@ -2428,7 +2413,7 @@ obj_coff_def (what) as_warn (_(".def pseudo-op used inside of .def/.endef: ignored.")); demand_empty_rest_of_line (); return; - } /* if not inside .def/.endef */ + } SKIP_WHITESPACES (); @@ -2444,7 +2429,7 @@ obj_coff_def (what) symbol_name_copy = tc_canonicalize_symbol_name (symbol_name_copy); #endif - /* Initialize the new symbol */ + /* Initialize the new symbol. */ #ifdef STRIP_UNDERSCORE S_SET_NAME (def_symbol_in_progress, (*symbol_name_copy == '_' ? symbol_name_copy + 1 @@ -2480,7 +2465,7 @@ obj_coff_endef (ignore) as_warn (_(".endef pseudo-op used outside of .def/.endef: ignored.")); demand_empty_rest_of_line (); return; - } /* if not inside .def/.endef */ + } /* Set the section number according to storage class. */ switch (S_GET_STORAGE_CLASS (def_symbol_in_progress)) @@ -2489,7 +2474,8 @@ obj_coff_endef (ignore) case C_ENTAG: case C_UNTAG: SF_SET_TAG (def_symbol_in_progress); - /* intentional fallthrough */ + /* Intentional fallthrough. */ + case C_FILE: case C_TPDEF: SF_SET_DEBUG (def_symbol_in_progress); @@ -2497,20 +2483,23 @@ obj_coff_endef (ignore) break; case C_EFCN: - SF_SET_LOCAL (def_symbol_in_progress); /* Do not emit this symbol. */ - /* intentional fallthrough */ + /* Do not emit this symbol. */ + SF_SET_LOCAL (def_symbol_in_progress); + /* Intentional fallthrough. */ + case C_BLOCK: - SF_SET_PROCESS (def_symbol_in_progress); /* Will need processing before writing */ - /* intentional fallthrough */ + /* Will need processing before writing. */ + SF_SET_PROCESS (def_symbol_in_progress); + /* Intentional fallthrough. */ + case C_FCN: S_SET_SEGMENT (def_symbol_in_progress, SEG_E0); if (strcmp (S_GET_NAME (def_symbol_in_progress), ".bf") == 0) { /* .bf */ if (function_lineoff < 0) - { - fprintf (stderr, _("`.bf' symbol without preceding function\n")); - } /* missing function symbol */ + fprintf (stderr, _("`.bf' symbol without preceding function\n")); + SA_GET_SYM_LNNOPTR (last_line_symbol) = function_lineoff; SF_SET_PROCESS (last_line_symbol); @@ -2518,6 +2507,7 @@ obj_coff_endef (ignore) SF_SET_PROCESS (def_symbol_in_progress); function_lineoff = -1; } + /* Value is always set to . */ def_symbol_in_progress->sy_frag = frag_now; S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ()); @@ -2546,7 +2536,7 @@ obj_coff_endef (ignore) #endif case C_STAT: case C_LABEL: - /* Valid but set somewhere else (s_comm, s_lcomm, colon) */ + /* Valid but set somewhere else (s_comm, s_lcomm, colon). */ break; case C_USTATIC: @@ -2554,7 +2544,7 @@ obj_coff_endef (ignore) case C_ULABEL: as_warn (_("unexpected storage class %d"), S_GET_STORAGE_CLASS (def_symbol_in_progress)); break; - } /* switch on storage class */ + } /* Now that we have built a debug symbol, try to find if we should merge with an existing symbol or not. If a symbol is C_EFCN or @@ -2609,16 +2599,16 @@ obj_coff_endef (ignore) /* For functions, and tags, and static symbols, the symbol *must* be where the debug symbol appears. Move the existing symbol to the current place. */ - /* If it already is at the end of the symbol list, do nothing */ + /* If it already is at the end of the symbol list, do nothing. */ if (def_symbol_in_progress != symbol_lastP) { symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP); symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP); - } /* if not already in place */ - } /* if function */ - } /* normal or mergable */ + } + } + } if (SF_GET_TAG (def_symbol_in_progress)) { @@ -2644,8 +2634,8 @@ obj_coff_endef (ignore) /* That is, if this is the first time we've seen the function... */ symbol_table_insert (def_symbol_in_progress); - } /* definition follows debug */ - } /* Create the line number entry pointing to the function being defined */ + } + } def_symbol_in_progress = NULL; demand_empty_rest_of_line (); @@ -2662,7 +2652,7 @@ obj_coff_dim (ignore) as_warn (_(".dim pseudo-op used outside of .def/.endef: ignored.")); demand_empty_rest_of_line (); return; - } /* if not inside .def/.endef */ + } S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); @@ -2680,7 +2670,8 @@ obj_coff_dim (ignore) default: as_warn (_("badly formed .dim directive ignored")); - /* intentional fallthrough */ + /* Intentional fallthrough. */ + case '\n': case ';': dim_index = DIMNUM; @@ -2715,17 +2706,13 @@ obj_coff_line (ignore) #if 0 /* XXX Can we ever have line numbers going backwards? */ if (this_base > line_base) #endif - { - line_base = this_base; - } + line_base = this_base; #ifndef NO_LISTING { extern int listing; if (listing) - { - listing_source_line ((unsigned int) line_base); - } + listing_source_line ((unsigned int) line_base); } #endif } @@ -2745,7 +2732,7 @@ obj_coff_size (ignore) as_warn (_(".size pseudo-op used outside of .def/.endef ignored.")); demand_empty_rest_of_line (); return; - } /* if not inside .def/.endef */ + } S_SET_NUMBER_AUXILIARY (def_symbol_in_progress, 1); SA_SET_SYM_SIZE (def_symbol_in_progress, get_absolute_expression ()); @@ -2761,7 +2748,7 @@ obj_coff_scl (ignore) as_warn (_(".scl pseudo-op used outside of .def/.endef ignored.")); demand_empty_rest_of_line (); return; - } /* if not inside .def/.endef */ + } S_SET_STORAGE_CLASS (def_symbol_in_progress, get_absolute_expression ()); demand_empty_rest_of_line (); @@ -2793,9 +2780,7 @@ obj_coff_tag (ignore) SA_SET_SYM_TAGNDX (def_symbol_in_progress, (long) tag_find_or_make (symbol_name)); if (SA_GET_SYM_TAGNDX (def_symbol_in_progress) == 0L) - { - as_warn (_("tag not found for .tag %s"), symbol_name); - } /* not defined */ + as_warn (_("tag not found for .tag %s"), symbol_name); SF_SET_TAGGED (def_symbol_in_progress); *input_line_pointer = name_end; @@ -2812,15 +2797,13 @@ obj_coff_type (ignore) as_warn (_(".type pseudo-op used outside of .def/.endef ignored.")); demand_empty_rest_of_line (); return; - } /* if not inside .def/.endef */ + } S_SET_DATA_TYPE (def_symbol_in_progress, get_absolute_expression ()); if (ISFCN (S_GET_DATA_TYPE (def_symbol_in_progress)) && S_GET_STORAGE_CLASS (def_symbol_in_progress) != C_TPDEF) - { - SF_SET_FUNCTION (def_symbol_in_progress); - } /* is a function */ + SF_SET_FUNCTION (def_symbol_in_progress); demand_empty_rest_of_line (); } @@ -2834,7 +2817,7 @@ obj_coff_val (ignore) as_warn (_(".val pseudo-op used outside of .def/.endef ignored.")); demand_empty_rest_of_line (); return; - } /* if not inside .def/.endef */ + } if (is_name_beginner (*input_line_pointer)) { @@ -2849,7 +2832,7 @@ obj_coff_val (ignore) { def_symbol_in_progress->sy_frag = frag_now; S_SET_VALUE (def_symbol_in_progress, (valueT) frag_now_fix ()); - /* If the .val is != from the .def (e.g. statics) */ + /* If the .val is != from the .def (e.g. statics). */ } else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name)) { @@ -2918,13 +2901,13 @@ coff_obj_read_begin_hook () } /* This function runs through the symbol table and puts all the - externals onto another chain */ + externals onto another chain. */ /* The chain of globals. */ symbolS *symbol_globalP; symbolS *symbol_global_lastP; -/* The chain of externals */ +/* The chain of externals. */ symbolS *symbol_externP; symbolS *symbol_extern_lastP; @@ -2961,7 +2944,7 @@ yank_symbols () if (!SF_GET_DEBUG (symbolP)) { - /* Debug symbols do not need all this rubbish */ + /* Debug symbols do not need all this rubbish. */ symbolS *real_symbolP; /* L* and C_EFCN symbols never merge. */ @@ -2980,20 +2963,18 @@ yank_symbols () list.) Because some pointers refer to the real symbol whereas no pointers refer to the debug symbol. */ c_symbol_merge (symbolP, real_symbolP); - /* Replace the current symbol by the real one */ + /* Replace the current symbol by the real one. */ /* The symbols will never be the last or the first because : 1st symbol is .file and 3 last symbols are - .text, .data, .bss */ + .text, .data, .bss. */ symbol_remove (real_symbolP, &symbol_rootP, &symbol_lastP); symbol_insert (real_symbolP, symbolP, &symbol_rootP, &symbol_lastP); symbol_remove (symbolP, &symbol_rootP, &symbol_lastP); symbolP = real_symbolP; - } /* if not local but dup'd */ + } if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_E1)) - { - S_SET_SEGMENT (symbolP, SEG_E0); - } /* push data into text */ + S_SET_SEGMENT (symbolP, SEG_E0); resolve_symbol_value (symbolP); @@ -3003,17 +2984,15 @@ yank_symbols () { S_SET_EXTERNAL (symbolP); } + else if (S_GET_SEGMENT (symbolP) == SEG_E0) - { - S_SET_STORAGE_CLASS (symbolP, C_LABEL); - } + S_SET_STORAGE_CLASS (symbolP, C_LABEL); + else - { - S_SET_STORAGE_CLASS (symbolP, C_STAT); - } + S_SET_STORAGE_CLASS (symbolP, C_STAT); } - /* Mainly to speed up if not -g */ + /* Mainly to speed up if not -g. */ if (SF_GET_PROCESS (symbolP)) { /* Handle the nested blocks auxiliary info. */ @@ -3022,8 +3001,10 @@ yank_symbols () if (!strcmp (S_GET_NAME (symbolP), ".bb")) stack_push (block_stack, (char *) &symbolP); else - { /* .eb */ - register symbolS *begin_symbolP; + { + /* .eb */ + symbolS *begin_symbolP; + begin_symbolP = *(symbolS **) stack_pop (block_stack); if (begin_symbolP == (symbolS *) 0) as_warn (_("mismatched .eb")); @@ -3041,13 +3022,11 @@ yank_symbols () last_functionP = symbolP; if (S_GET_NUMBER_AUXILIARY (symbolP) < 1) - { - S_SET_NUMBER_AUXILIARY (symbolP, 1); - } /* make it at least 1 */ + S_SET_NUMBER_AUXILIARY (symbolP, 1); /* Clobber possible stale .dim information. */ #if 0 - /* Iffed out by steve - this fries the lnnoptr info too */ + /* Iffed out by steve - this fries the lnnoptr info too. */ bzero (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen, sizeof (symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen)); #endif @@ -3078,19 +3057,19 @@ yank_symbols () else if (SF_GET_TAG (symbolP)) { /* First descriptor of a structure must point to - the first slot after the structure description. */ + the first slot after the structure description. */ last_tagP = symbolP; } else if (S_GET_STORAGE_CLASS (symbolP) == C_EOS) { - /* +2 take in account the current symbol */ + /* +2 take in account the current symbol. */ SA_SET_SYM_ENDNDX (last_tagP, symbol_number + 2); } else if (S_GET_STORAGE_CLASS (symbolP) == C_FILE) { /* If the filename was too long to fit in the - auxent, put it in the string table */ + auxent, put it in the string table. */ if (SA_GET_FILE_FNAME_ZEROS (symbolP) == 0 && SA_GET_FILE_FNAME_OFFSET (symbolP) != 0) { @@ -3102,8 +3081,8 @@ yank_symbols () { S_SET_VALUE (symbolP, last_file_symno); last_file_symno = symbol_number; - } /* no one points at the first .file symbol */ - } /* if debug or tag or eos or file */ + } + } #ifdef tc_frob_coff_symbol tc_frob_coff_symbol (symbolP); @@ -3122,8 +3101,8 @@ yank_symbols () if (SF_GET_LOCAL (symbolP)) { - /* remove C_EFCN and LOCAL (L...) symbols */ - /* next pointer remains valid */ + /* Remove C_EFCN and LOCAL (L...) symbols. */ + /* Next pointer remains valid. */ symbol_remove (symbolP, &symbol_rootP, &symbol_lastP); } @@ -3143,7 +3122,7 @@ yank_symbols () #endif || S_GET_STORAGE_CLASS (symbolP) == C_WEAKEXT)) { - /* if external, Remove from the list */ + /* If external, Remove from the list. */ symbolS *hold = symbol_previous (symbolP); symbol_remove (symbolP, &symbol_rootP, &symbol_lastP); @@ -3165,7 +3144,6 @@ yank_symbols () /* The O'Reilly COFF book says that defined global symbols come at the end of the symbol table, just before undefined global symbols. */ - symbol_remove (symbolP, &symbol_rootP, &symbol_lastP); symbol_clear_list_pointers (symbolP); symbol_append (symbolP, symbol_global_lastP, &symbol_globalP, @@ -3182,14 +3160,14 @@ yank_symbols () else { symbolP->sy_name_offset = 0; - } /* fix "long" names */ + } symbolP->sy_number = symbol_number; symbol_number += 1 + S_GET_NUMBER_AUXILIARY (symbolP); - } /* if local symbol */ - } /* traverse the symbol list */ - return symbol_number; + } + } + return symbol_number; } static unsigned int @@ -3203,11 +3181,11 @@ glue_symbols (head, tail) { symbolS *tmp = *head; - /* append */ + /* Append. */ symbol_remove (tmp, head, tail); symbol_append (tmp, symbol_lastP, &symbol_rootP, &symbol_lastP); - /* and process */ + /* Process. */ if (SF_GET_STRING (tmp)) { tmp->sy_name_offset = string_byte_count; @@ -3215,12 +3193,13 @@ glue_symbols (head, tail) } else { + /* Fix "long" names. */ tmp->sy_name_offset = 0; - } /* fix "long" names */ + } tmp->sy_number = symbol_number; symbol_number += 1 + S_GET_NUMBER_AUXILIARY (tmp); - } /* append the entire extern chain */ + } return symbol_number; } @@ -3248,6 +3227,7 @@ tie_tags () return symbol_number; } + static void crawl_symbols (h, abfd) object_headers *h; @@ -3255,40 +3235,35 @@ crawl_symbols (h, abfd) { unsigned int i; - /* Initialize the stack used to keep track of the matching .bb .be */ + /* Initialize the stack used to keep track of the matching .bb .be. */ block_stack = stack_init (512, sizeof (symbolS *)); /* The symbol list should be ordered according to the following sequence - * order : - * . .file symbol - * . debug entries for functions - * . fake symbols for the sections, including .text .data and .bss - * . defined symbols - * . undefined symbols - * But this is not mandatory. The only important point is to put the - * undefined symbols at the end of the list. - */ + order : + . .file symbol + . debug entries for functions + . fake symbols for the sections, including .text .data and .bss + . defined symbols + . undefined symbols + But this is not mandatory. The only important point is to put the + undefined symbols at the end of the list. */ /* Is there a .file symbol ? If not insert one at the beginning. */ if (symbol_rootP == NULL || S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE) - { - c_dot_file_symbol ("fake"); - } + c_dot_file_symbol ("fake"); - /* - * Build up static symbols for the sections, they are filled in later - */ + /* Build up static symbols for the sections, they are filled in later. */ for (i = SEG_E0; i < SEG_LAST; i++) if (segment_info[i].scnhdr.s_name[0]) - segment_info[i].dot = c_section_symbol (segment_info[i].name, + segment_info[i].dot = c_section_symbol ((char *) segment_info[i].name, i - SEG_E0 + 1); - /* Take all the externals out and put them into another chain */ + /* Take all the externals out and put them into another chain. */ H_SET_SYMBOL_TABLE_SIZE (h, yank_symbols ()); - /* Take the externals and glue them onto the end.*/ + /* Take the externals and glue them onto the end. */ H_SET_SYMBOL_TABLE_SIZE (h, (H_GET_SYMBOL_COUNT (h) + glue_symbols (&symbol_globalP, @@ -3303,9 +3278,7 @@ crawl_symbols (h, abfd) know (symbol_extern_lastP == NULL); } -/* - * Find strings by crawling along symbol table chain. - */ +/* Find strings by crawling along symbol table chain. */ void w_strings (where) @@ -3314,7 +3287,7 @@ w_strings (where) symbolS *symbolP; struct filename_list *filename_list_scan = filename_list_head; - /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */ + /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK. */ md_number_to_chars (where, (valueT) string_byte_count, 4); where += 4; @@ -3386,7 +3359,7 @@ do_linenos_for (abfd, h, file_cursor) struct external_lineno *dst = buffer; /* Run through the table we've built and turn it into its external - form, take this chance to remove duplicates */ + form, take this chance to remove duplicates. */ for (line_ptr = s->lineno_list_head; line_ptr != (struct lineno_list *) NULL; @@ -3401,13 +3374,10 @@ do_linenos_for (abfd, h, file_cursor) ((symbolS *) line_ptr->line.l_addr.l_symndx)->sy_number; } else - { - line_ptr->line.l_addr.l_paddr += ((struct frag *) (line_ptr->frag))->fr_address; - } + line_ptr->line.l_addr.l_paddr += ((struct frag *) (line_ptr->frag))->fr_address; (void) bfd_coff_swap_lineno_out (abfd, &(line_ptr->line), dst); dst++; - } s->scnhdr.s_lnnoptr = *file_cursor; @@ -3418,12 +3388,13 @@ do_linenos_for (abfd, h, file_cursor) *file_cursor += s->scnhdr.s_nlnno * LINESZ; } } + H_SET_LINENO_SIZE (h, *file_cursor - start); } /* Now we run through the list of frag chains in a segment and make all the subsegment frags appear at the end of the - list, as if the seg 0 was extra long */ + list, as if the seg 0 was extra long. */ static void remove_subsegs () @@ -3448,6 +3419,7 @@ remove_subsegs () unsigned long machine; int coff_flags; + extern void write_object_file () { @@ -3506,9 +3478,7 @@ write_object_file () remove_subsegs (); for (i = SEG_E0; i < SEG_UNKNOWN; i++) - { - relax_segment (segment_info[i].frchainP->frch_root, i); - } + relax_segment (segment_info[i].frchainP->frch_root, i); /* Relaxation has completed. Freeze all syms. */ finalize_syms = 1; @@ -3562,7 +3532,7 @@ write_object_file () H_SET_BSS_SIZE (&headers, size); } - /* Turn the gas native symbol table shape into a coff symbol table */ + /* Turn the gas native symbol table shape into a coff symbol table. */ crawl_symbols (&headers, abfd); if (string_byte_count == 4) @@ -3596,8 +3566,7 @@ write_object_file () bfd_seek (abfd, (file_ptr) file_cursor, 0); - /* Plant the data */ - + /* Plant the data. */ fill_section (abfd, &headers, &file_cursor); do_relocs_for (abfd, &headers, &file_cursor); @@ -3692,28 +3661,26 @@ obj_coff_add_segment (name) return (segT) i; } -/* - * implement the .section pseudo op: - * .section name {, "flags"} - * ^ ^ - * | +--- optional flags: 'b' for bss - * | 'i' for info - * +-- section name 'l' for lib - * 'n' for noload - * 'o' for over - * 'w' for data - * 'd' (apparently m88k for data) - * 'x' for text - * 'r' for read-only data - * But if the argument is not a quoted string, treat it as a - * subsegment number. - */ +/* Implement the .section pseudo op: + .section name {, "flags"} + ^ ^ + | +--- optional flags: 'b' for bss + | 'i' for info + +-- section name 'l' for lib + 'n' for noload + 'o' for over + 'w' for data + 'd' (apparently m88k for data) + 'x' for text + 'r' for read-only data + But if the argument is not a quoted string, treat it as a + subsegment number. */ void obj_coff_section (ignore) int ignore ATTRIBUTE_UNUSED; { - /* Strip out the section name */ + /* Strip out the section name. */ char *section_name, *name; char c; unsigned int exp; @@ -3810,11 +3777,12 @@ static void obj_coff_ident (ignore) int ignore ATTRIBUTE_UNUSED; { - segT current_seg = now_seg; /* save current seg */ + segT current_seg = now_seg; /* Save current seg. */ subsegT current_subseg = now_subseg; - subseg_new (".comment", 0); /* .comment seg */ - stringer (1); /* read string */ - subseg_set (current_seg, current_subseg); /* restore current seg */ + + subseg_new (".comment", 0); /* .comment seg. */ + stringer (1); /* Read string. */ + subseg_set (current_seg, current_subseg); /* Restore current seg. */ } void @@ -3826,20 +3794,16 @@ c_symbol_merge (debug, normal) S_SET_STORAGE_CLASS (normal, S_GET_STORAGE_CLASS (debug)); if (S_GET_NUMBER_AUXILIARY (debug) > S_GET_NUMBER_AUXILIARY (normal)) - { - S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug)); - } /* take the most we have */ + S_SET_NUMBER_AUXILIARY (normal, S_GET_NUMBER_AUXILIARY (debug)); if (S_GET_NUMBER_AUXILIARY (debug) > 0) - { - memcpy ((char *) &normal->sy_symbol.ost_auxent[0], - (char *) &debug->sy_symbol.ost_auxent[0], - (unsigned int) (S_GET_NUMBER_AUXILIARY (debug) * AUXESZ)); - } /* Move all the auxiliary information */ + memcpy ((char *) &normal->sy_symbol.ost_auxent[0], + (char *) &debug->sy_symbol.ost_auxent[0], + (unsigned int) (S_GET_NUMBER_AUXILIARY (debug) * AUXESZ)); /* Move the debug flags. */ SF_SET_DEBUG_FIELD (normal, SF_GET_DEBUG_FIELD (debug)); -} /* c_symbol_merge() */ +} static int c_line_new (symbol, paddr, line_number, frag) @@ -3868,13 +3832,10 @@ c_line_new (symbol, paddr, line_number, frag) new_line->next = (struct lineno_list *) NULL; if (s->lineno_list_head == (struct lineno_list *) NULL) - { - s->lineno_list_head = new_line; - } + s->lineno_list_head = new_line; else - { - s->lineno_list_tail->next = new_line; - } + s->lineno_list_tail->next = new_line; + s->lineno_list_tail = new_line; return LINESZ * s->scnhdr.s_nlnno++; } @@ -3898,7 +3859,7 @@ c_dot_file_symbol (filename) /* Filename is too long to fit into an auxent, we stick it into the string table instead. We keep a linked list of the filenames we find so we can emit - them later.*/ + them later. */ struct filename_list *f = ((struct filename_list *) xmalloc (sizeof (struct filename_list))); @@ -3922,29 +3883,23 @@ c_dot_file_symbol (filename) { extern int listing; if (listing) - { - listing_source_file (filename); - } - + listing_source_file (filename); } - #endif SF_SET_DEBUG (symbolP); S_SET_VALUE (symbolP, (valueT) previous_file_symbol); previous_file_symbol = symbolP; - /* Make sure that the symbol is first on the symbol chain */ + /* Make sure that the symbol is first on the symbol chain. */ if (symbol_rootP != symbolP) { symbol_remove (symbolP, &symbol_rootP, &symbol_lastP); symbol_insert (symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP); } -} /* c_dot_file_symbol() */ +} -/* - * Build a 'section static' symbol. - */ +/* Build a 'section static' symbol. */ symbolS * c_section_symbol (name, idx) @@ -4004,7 +3959,7 @@ c_section_symbol (name, idx) #endif /* TE_PE */ return symbolP; -} /* c_section_symbol() */ +} static void w_symbols (abfd, where, symbol_rootP) @@ -4015,7 +3970,7 @@ w_symbols (abfd, where, symbol_rootP) symbolS *symbolP; unsigned int i; - /* First fill in those values we have only just worked out */ + /* First fill in those values we have only just worked out. */ for (i = SEG_E0; i < SEG_LAST; i++) { symbolP = segment_info[i].dot; @@ -4027,23 +3982,19 @@ w_symbols (abfd, where, symbol_rootP) } } - /* - * Emit all symbols left in the symbol chain. - */ + /* Emit all symbols left in the symbol chain. */ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) { /* Used to save the offset of the name. It is used to point - to the string in memory but must be a file offset. */ - register char *temp; + to the string in memory but must be a file offset. */ + char *temp; /* We can't fix the lnnoptr field in yank_symbols with the other adjustments, because we have to wait until we know where they go in the file. */ if (SF_GET_ADJ_LNNOPTR (symbolP)) - { - SA_GET_SYM_LNNOPTR (symbolP) += - segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_lnnoptr; - } + SA_GET_SYM_LNNOPTR (symbolP) += + segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_lnnoptr; tc_coff_symbol_emit_hook (symbolP); @@ -4061,8 +4012,7 @@ w_symbols (abfd, where, symbol_rootP) where = symbol_to_chars (abfd, where, symbolP); S_SET_NAME (symbolP, temp); } - -} /* w_symbols() */ +} static void obj_coff_lcomm (ignore) @@ -4112,7 +4062,7 @@ obj_coff_lcomm (ignore) if (! need_pass_2) { char *p; - segT current_seg = now_seg; /* save current seg */ + segT current_seg = now_seg; /* Save current seg. */ subsegT current_subseg = now_subseg; subseg_set (SEG_E2, 1); @@ -4120,7 +4070,7 @@ obj_coff_lcomm (ignore) p = frag_var(rs_org, 1, 1, (relax_substateT)0, symbolP, (offsetT) temp, (char *) 0); *p = 0; - subseg_set (current_seg, current_subseg); /* restore current seg */ + subseg_set (current_seg, current_subseg); /* Restore current seg. */ S_SET_SEGMENT (symbolP, SEG_E2); S_SET_STORAGE_CLASS (symbolP, C_STAT); } @@ -4139,6 +4089,7 @@ fixup_mdeps (frags, h, this_segment) segT this_segment; { subseg_change (this_segment, 0); + while (frags) { switch (frags->fr_type) @@ -4177,16 +4128,16 @@ fixup_segment (segP, this_segment_type) segment_info_type * segP; segT this_segment_type; { - register fixS * fixP; - register symbolS *add_symbolP; - register symbolS *sub_symbolP; + fixS * fixP; + symbolS *add_symbolP; + symbolS *sub_symbolP; long add_number; - register int size; - register char *place; - register long where; - register char pcrel; - register fragS *fragP; - register segT add_symbol_segment = absolute_section; + int size; + char *place; + long where; + char pcrel; + fragS *fragP; + segT add_symbol_segment = absolute_section; for (fixP = segP->fix_root; fixP; fixP = fixP->fx_next) { @@ -4274,9 +4225,7 @@ fixup_segment (segP, this_segment_type) } if (add_symbolP) - { - add_symbol_segment = S_GET_SEGMENT (add_symbolP); - } /* if there is an addend */ + add_symbol_segment = S_GET_SEGMENT (add_symbolP); if (sub_symbolP) { @@ -4307,7 +4256,7 @@ fixup_segment (segP, this_segment_type) } /* not absolute */ /* if sub_symbol is in the same segment that add_symbol - and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */ + and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE. */ } else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment && SEG_NORMAL (add_symbol_segment)) @@ -4319,10 +4268,8 @@ fixup_segment (segP, this_segment_type) /* Makes no sense to use the difference of 2 arbitrary symbols as the target of a call instruction. */ if (fixP->fx_tcbit) - { - as_bad_where (fixP->fx_file, fixP->fx_line, - _("callj to difference of 2 symbols")); - } + as_bad_where (fixP->fx_file, fixP->fx_line, + _("callj to difference of 2 symbols")); #endif /* TC_I960 */ add_number += S_GET_VALUE (add_symbolP) - S_GET_VALUE (sub_symbolP); @@ -4345,9 +4292,8 @@ fixup_segment (segP, this_segment_type) know (!(S_IS_EXTERNAL (sub_symbolP) && (S_GET_SEGMENT (sub_symbolP) == absolute_section))); if ((S_GET_SEGMENT (sub_symbolP) == absolute_section)) - { - add_number -= S_GET_VALUE (sub_symbolP); - } + add_number -= S_GET_VALUE (sub_symbolP); + #ifdef DIFF_EXPR_OK else if (S_GET_SEGMENT (sub_symbolP) == this_segment_type #if 0 /* Okay for 68k, at least... */ @@ -4371,25 +4317,22 @@ fixup_segment (segP, this_segment_type) segment_name (S_GET_SEGMENT (sub_symbolP)), S_GET_NAME (sub_symbolP), (long) (fragP->fr_address + where)); - } /* if absolute */ + } } - } /* if sub_symbolP */ + } if (add_symbolP) { if (add_symbol_segment == this_segment_type && pcrel) { - /* - * This fixup was made when the symbol's segment was - * SEG_UNKNOWN, but it is now in the local segment. - * So we know how to do the address without relocation. - */ + /* This fixup was made when the symbol's segment was + SEG_UNKNOWN, but it is now in the local segment. + So we know how to do the address without relocation. */ #ifdef TC_I960 /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal', - * in which cases it modifies *fixP as appropriate. In the case - * of a 'calls', no further work is required, and *fixP has been - * set up to make the rest of the code below a no-op. - */ + in which cases it modifies *fixP as appropriate. In the case + of a 'calls', no further work is required, and *fixP has been + set up to make the rest of the code below a no-op. */ reloc_callj (fixP); #endif /* TC_I960 */ @@ -4423,7 +4366,8 @@ fixup_segment (segP, this_segment_type) { case absolute_section: #ifdef TC_I960 - reloc_callj (fixP); /* See comment about reloc_callj() above*/ + /* See comment about reloc_callj() above. */ + reloc_callj (fixP); #endif /* TC_I960 */ add_number += S_GET_VALUE (add_symbolP); add_symbolP = NULL; @@ -4451,16 +4395,15 @@ fixup_segment (segP, this_segment_type) if ((int) fixP->fx_bit_fixP == 13) { /* This is a COBR instruction. They have only a - * 13-bit displacement and are only to be used - * for local branches: flag as error, don't generate - * relocation. - */ + 13-bit displacement and are only to be used + for local branches: flag as error, don't generate + relocation. */ as_bad_where (fixP->fx_file, fixP->fx_line, _("can't use COBR format with external label")); fixP->fx_addsy = NULL; fixP->fx_done = 1; continue; - } /* COBR */ + } #endif /* TC_I960 */ #if ((defined (TC_I386) || defined (TE_LYNX) || defined (TE_AUX)) && !defined(TE_PE)) || defined (COFF_COMMON_ADDEND) /* 386 COFF uses a peculiar format in which the @@ -4476,9 +4419,9 @@ fixup_segment (segP, this_segment_type) #endif break; - } /* switch on symbol seg */ - } /* if not in local seg */ - } /* if there was a + symbol */ + } + } + } if (pcrel) { @@ -4488,9 +4431,7 @@ fixup_segment (segP, this_segment_type) add_number -= md_pcrel_from (fixP); #endif if (add_symbolP == 0) - { - fixP->fx_addsy = &abs_symbol; - } /* if there's an add_symbol */ + fixP->fx_addsy = &abs_symbol; #if defined (TC_I386) || defined (TE_LYNX) || defined (TC_I960) || defined (TC_M68K) /* On the 386 we must adjust by the segment vaddr as well. Ian Taylor. @@ -4510,7 +4451,7 @@ fixup_segment (segP, this_segment_type) add_number -= segP->scnhdr.s_vaddr; #endif - } /* if pcrel */ + } md_apply_fix3 (fixP, (valueT *) & add_number, this_segment_type); @@ -4549,9 +4490,9 @@ fixup_segment (segP, this_segment_type) (long) add_number, (unsigned long) (fragP->fr_address + where)); #endif - } /* not a bit fix */ - } /* For each fixS in this segment. */ -} /* fixup_segment() */ + } + } +} #endif diff --git a/contrib/binutils/gas/config/tc-arm.c b/contrib/binutils/gas/config/tc-arm.c index 162553f..2d8cc7c 100644 --- a/contrib/binutils/gas/config/tc-arm.c +++ b/contrib/binutils/gas/config/tc-arm.c @@ -521,7 +521,7 @@ struct vfp_reg unsigned long regno; }; -static const struct vfp_reg vfp_regs[] = +static const struct vfp_reg vfp_regs[] = { {"fpsid", 0x00000000}, {"FPSID", 0x00000000}, @@ -842,7 +842,7 @@ static void do_mav_binops_3a PARAMS ((char *)); static void do_mav_binops_3b PARAMS ((char *)); static void do_mav_binops_3c PARAMS ((char *)); static void do_mav_binops_3d PARAMS ((char *)); -static void do_mav_triple PARAMS ((char *, int, enum arm_reg_type, +static void do_mav_triple PARAMS ((char *, int, enum arm_reg_type, enum arm_reg_type, enum arm_reg_type)); static void do_mav_triple_4a PARAMS ((char *)); @@ -855,7 +855,7 @@ static void do_mav_triple_5e PARAMS ((char *)); static void do_mav_triple_5f PARAMS ((char *)); static void do_mav_triple_5g PARAMS ((char *)); static void do_mav_triple_5h PARAMS ((char *)); -static void do_mav_quad PARAMS ((char *, int, enum arm_reg_type, +static void do_mav_quad PARAMS ((char *, int, enum arm_reg_type, enum arm_reg_type, enum arm_reg_type, enum arm_reg_type)); @@ -1106,7 +1106,7 @@ static const struct asm_opcode insns[] = {"strh", 0xe00000b0, 3, ARM_EXT_V4, do_ldstv4}, /* ARM Architecture 4T. */ - /* Note: bx (and blx) are required on V5, even if the processor does + /* Note: bx (and blx) are required on V5, even if the processor does not support Thumb. */ {"bx", 0xe12fff10, 2, ARM_EXT_V4T | ARM_EXT_V5, do_bx}, @@ -7447,7 +7447,9 @@ thumb_add_sub (str, subtract) return; } } - else + /* Note - you cannot convert a subtract of 0 into an + add of 0 because the carry flag is set differently. */ + else if (offset > 0) subtract = 0; if (Rd == REG_SP) @@ -7927,7 +7929,7 @@ mav_reg_required_here (str, shift, regtype) /* Restore the start point. */ *str = start; - + /* In the few cases where we might be able to accept something else this error can be overridden. */ inst.error = _(all_reg_maps[regtype].expected); diff --git a/contrib/binutils/gas/config/tc-i386.c b/contrib/binutils/gas/config/tc-i386.c index 1d874af..f681014 100644 --- a/contrib/binutils/gas/config/tc-i386.c +++ b/contrib/binutils/gas/config/tc-i386.c @@ -182,9 +182,9 @@ typedef struct _i386_insn i386_insn; /* List of chars besides those in app.c:symbol_chars that can start an operand. Used to prevent the scrubber eating vital white-space. */ #ifdef LEX_AT -const char extra_symbol_chars[] = "*%-(@"; +const char extra_symbol_chars[] = "*%-(@["; #else -const char extra_symbol_chars[] = "*%-("; +const char extra_symbol_chars[] = "*%-(["; #endif #if (defined (TE_I386AIX) \ @@ -2208,15 +2208,15 @@ process_suffix () /* For movzx and movsx, need to check the register type. */ if (intel_syntax - && (i.tm.base_opcode == 0xfb6 || i.tm.base_opcode == 0xfbe)) - if (i.suffix && i.suffix == BYTE_MNEM_SUFFIX) - { - unsigned int prefix = DATA_PREFIX_OPCODE; + && (i.tm.base_opcode == 0xfb6 || i.tm.base_opcode == 0xfbe) + && i.suffix == BYTE_MNEM_SUFFIX) + { + unsigned int prefix = DATA_PREFIX_OPCODE; - if ((i.op[1].regs->reg_type & Reg16) != 0) - if (!add_prefix (prefix)) - return 0; - } + if ((i.op[1].regs->reg_type & Reg16) != 0) + if (!add_prefix (prefix)) + return 0; + } if (i.suffix && i.suffix != BYTE_MNEM_SUFFIX) { @@ -2228,6 +2228,7 @@ process_suffix () else i.tm.base_opcode |= 1; } + /* Now select between word & dword operations via the operand size prefix, except for instructions that will ignore this prefix anyway. */ @@ -2309,7 +2310,7 @@ check_byte_reg () if (flag_code == CODE_64BIT && (i.tm.operand_types[op] & InOutPortReg) == 0) { - as_bad (_("Incorrect register `%%%s' used with`%c' suffix"), + as_bad (_("Incorrect register `%%%s' used with `%c' suffix"), i.op[op].regs->reg_name, i.suffix); return 0; @@ -2368,7 +2369,7 @@ check_long_reg () lowering is more complicated. */ if (flag_code == CODE_64BIT) { - as_bad (_("Incorrect register `%%%s' used with`%c' suffix"), + as_bad (_("Incorrect register `%%%s' used with `%c' suffix"), i.op[op].regs->reg_name, i.suffix); return 0; @@ -2385,7 +2386,7 @@ check_long_reg () else if ((i.types[op] & Reg64) != 0 && (i.tm.operand_types[op] & (Reg32 | Acc)) != 0) { - as_bad (_("Incorrect register `%%%s' used with`%c' suffix"), + as_bad (_("Incorrect register `%%%s' used with `%c' suffix"), i.op[op].regs->reg_name, i.suffix); return 0; @@ -2417,7 +2418,7 @@ check_qword_reg () { /* Prohibit these changes in the 64bit mode, since the lowering is more complicated. */ - as_bad (_("Incorrect register `%%%s' used with`%c' suffix"), + as_bad (_("Incorrect register `%%%s' used with `%c' suffix"), i.op[op].regs->reg_name, i.suffix); return 0; @@ -2450,7 +2451,7 @@ check_word_reg () lowering is more complicated. */ if (flag_code == CODE_64BIT) { - as_bad (_("Incorrect register `%%%s' used with`%c' suffix"), + as_bad (_("Incorrect register `%%%s' used with `%c' suffix"), i.op[op].regs->reg_name, i.suffix); return 0; @@ -2980,7 +2981,6 @@ output_jump () { char *p; int size; - fixS *fixP; if (i.tm.opcode_modifier & JumpByte) { @@ -3031,9 +3031,8 @@ output_jump () p = frag_more (1 + size); *p++ = i.tm.base_opcode; - fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size, - i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0])); - fixP->fx_pcrel_adjust = size; + fix_new_exp (frag_now, p - frag_now->fr_literal, size, + i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0])); } static void @@ -3226,7 +3225,6 @@ output_disp () int size = 4; int sign = 0; int pcrel = (i.flags[n] & Operand_PCrel) != 0; - fixS *fixP; /* The PC relative address is computed relative to the instruction boundary, so in case immediate @@ -3266,11 +3264,9 @@ output_disp () } p = frag_more (size); - fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size, - i.op[n].disps, pcrel, - reloc (size, pcrel, sign, i.reloc[n])); - if (pcrel) - fixP->fx_pcrel_adjust = size; + fix_new_exp (frag_now, p - frag_now->fr_literal, size, + i.op[n].disps, pcrel, + reloc (size, pcrel, sign, i.reloc[n])); } } } @@ -4215,7 +4211,6 @@ md_estimate_size_before_relax (fragP, segment) RELOC_ENUM reloc_type; unsigned char *opcode; int old_fr_fix; - fixS *fixP; if (fragP->fr_var != NO_RELOC) reloc_type = fragP->fr_var; @@ -4233,18 +4228,15 @@ md_estimate_size_before_relax (fragP, segment) /* Make jmp (0xeb) a (d)word displacement jump. */ opcode[0] = 0xe9; fragP->fr_fix += size; - fixP = fix_new (fragP, old_fr_fix, size, - fragP->fr_symbol, - fragP->fr_offset, 1, - reloc_type); - fixP->fx_pcrel_adjust = size; + fix_new (fragP, old_fr_fix, size, + fragP->fr_symbol, + fragP->fr_offset, 1, + reloc_type); break; case COND_JUMP86: - if (no_cond_jump_promotion) - goto relax_guess; - - if (size == 2) + if (size == 2 + && (!no_cond_jump_promotion || fragP->fr_var != NO_RELOC)) { /* Negate the condition, and branch past an unconditional jump. */ @@ -4255,18 +4247,24 @@ md_estimate_size_before_relax (fragP, segment) /* We added two extra opcode bytes, and have a two byte offset. */ fragP->fr_fix += 2 + 2; - fixP = fix_new (fragP, old_fr_fix + 2, 2, - fragP->fr_symbol, - fragP->fr_offset, 1, - reloc_type); - fixP->fx_pcrel_adjust = size; + fix_new (fragP, old_fr_fix + 2, 2, + fragP->fr_symbol, + fragP->fr_offset, 1, + reloc_type); break; } /* Fall through. */ case COND_JUMP: - if (no_cond_jump_promotion) - goto relax_guess; + if (no_cond_jump_promotion && fragP->fr_var == NO_RELOC) + { + fragP->fr_fix += 1; + fix_new (fragP, old_fr_fix, 1, + fragP->fr_symbol, + fragP->fr_offset, 1, + BFD_RELOC_8_PCREL); + break; + } /* This changes the byte-displacement jump 0x7N to the (d)word-displacement jump 0x0f,0x8N. */ @@ -4274,11 +4272,10 @@ md_estimate_size_before_relax (fragP, segment) opcode[0] = TWO_BYTE_OPCODE_ESCAPE; /* We've added an opcode byte. */ fragP->fr_fix += 1 + size; - fixP = fix_new (fragP, old_fr_fix + 1, size, - fragP->fr_symbol, - fragP->fr_offset, 1, - reloc_type); - fixP->fx_pcrel_adjust = size; + fix_new (fragP, old_fr_fix + 1, size, + fragP->fr_symbol, + fragP->fr_offset, 1, + reloc_type); break; default: @@ -4289,7 +4286,6 @@ md_estimate_size_before_relax (fragP, segment) return fragP->fr_fix - old_fr_fix; } - relax_guess: /* Guess size depending on current relax state. Initially the relax state will correspond to a short jump and we return 1, because the variable part of the frag (the branch offset) is one byte @@ -4607,6 +4603,8 @@ md_apply_fix3 (fixP, valP, seg) else if (use_rela_relocations) { fixP->fx_no_overflow = 1; + /* Remember value for tc_gen_reloc. */ + fixP->fx_addnumber = value; value = 0; } #endif @@ -5120,9 +5118,23 @@ tc_gen_reloc (section, fixp) /* Use the rela in 64bit mode. */ else { - rel->addend = fixp->fx_offset; - if (fixp->fx_pcrel) - rel->addend -= fixp->fx_pcrel_adjust; + if (!fixp->fx_pcrel) + rel->addend = fixp->fx_offset; + else + switch (code) + { + case BFD_RELOC_X86_64_PLT32: + case BFD_RELOC_X86_64_GOT32: + case BFD_RELOC_X86_64_GOTPCREL: + rel->addend = fixp->fx_offset - fixp->fx_size; + break; + default: + rel->addend = (section->vma + - fixp->fx_size + + fixp->fx_addnumber + + md_pcrel_from (fixp)); + break; + } } rel->howto = bfd_reloc_type_lookup (stdoutput, code); diff --git a/contrib/binutils/gas/config/tc-ppc.c b/contrib/binutils/gas/config/tc-ppc.c index 560622b..f7872a0 100644 --- a/contrib/binutils/gas/config/tc-ppc.c +++ b/contrib/binutils/gas/config/tc-ppc.c @@ -1374,7 +1374,7 @@ ppc_elf_suffix (str_p, exp_p) MAP ("plt@h", (int) BFD_RELOC_HI16_PLTOFF), MAP ("plt@ha", (int) BFD_RELOC_HI16_S_PLTOFF), MAP ("sdarel", (int) BFD_RELOC_GPREL16), - MAP ("sectoff", (int) BFD_RELOC_32_BASEREL), + MAP ("sectoff", (int) BFD_RELOC_16_BASEREL), MAP ("sectoff@l", (int) BFD_RELOC_LO16_BASEREL), MAP ("sectoff@h", (int) BFD_RELOC_HI16_BASEREL), MAP ("sectoff@ha", (int) BFD_RELOC_HI16_S_BASEREL), @@ -1683,7 +1683,7 @@ ppc_elf_validate_fix (fixp, seg) && fixp->fx_r_type != BFD_RELOC_HI16_GOTOFF && fixp->fx_r_type != BFD_RELOC_LO16_GOTOFF && fixp->fx_r_type != BFD_RELOC_HI16_S_GOTOFF - && fixp->fx_r_type != BFD_RELOC_32_BASEREL + && fixp->fx_r_type != BFD_RELOC_16_BASEREL && fixp->fx_r_type != BFD_RELOC_LO16_BASEREL && fixp->fx_r_type != BFD_RELOC_HI16_BASEREL && fixp->fx_r_type != BFD_RELOC_HI16_S_BASEREL @@ -2236,7 +2236,7 @@ md_assemble (str) case BFD_RELOC_LO16_PLTOFF: reloc = BFD_RELOC_PPC64_PLT16_LO_DS; break; - case BFD_RELOC_32_BASEREL: + case BFD_RELOC_16_BASEREL: reloc = BFD_RELOC_PPC64_SECTOFF_DS; break; case BFD_RELOC_LO16_BASEREL: @@ -5280,7 +5280,6 @@ md_apply_fix3 (fixP, valP, seg) case BFD_RELOC_RVA: case BFD_RELOC_32_PCREL: - case BFD_RELOC_32_BASEREL: case BFD_RELOC_PPC_EMB_NADDR32: md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where, value, 4); @@ -5305,6 +5304,7 @@ md_apply_fix3 (fixP, valP, seg) case BFD_RELOC_LO16_GOTOFF: case BFD_RELOC_HI16_GOTOFF: case BFD_RELOC_HI16_S_GOTOFF: + case BFD_RELOC_16_BASEREL: case BFD_RELOC_LO16_BASEREL: case BFD_RELOC_HI16_BASEREL: case BFD_RELOC_HI16_S_BASEREL: diff --git a/contrib/binutils/gas/config/tc-s390.c b/contrib/binutils/gas/config/tc-s390.c new file mode 100644 index 0000000..4e09ab5 --- /dev/null +++ b/contrib/binutils/gas/config/tc-s390.c @@ -0,0 +1,1977 @@ +/* tc-s390.c -- Assemble for the S390 + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + + This file is part of GAS, the GNU Assembler. + + GAS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GAS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GAS; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include <stdio.h> +#include "as.h" +#include "safe-ctype.h" +#include "subsegs.h" +#include "struc-symbol.h" + +#include "opcode/s390.h" +#include "elf/s390.h" + +/* The default architecture. */ +#ifndef DEFAULT_ARCH +#define DEFAULT_ARCH "s390" +#endif +static char *default_arch = DEFAULT_ARCH; +/* Either 32 or 64, selects file format. */ +static int s390_arch_size; +/* Current architecture. Start with the smallest instruction set. */ +static enum s390_opcode_arch_val current_architecture = S390_OPCODE_ESA; +static int current_arch_mask = 1 << S390_OPCODE_ESA; +static int current_arch_requested = 0; + +/* Whether to use user friendly register names. Default is true. */ +#ifndef TARGET_REG_NAMES_P +#define TARGET_REG_NAMES_P true +#endif + +static boolean reg_names_p = TARGET_REG_NAMES_P; + +/* Set to TRUE if we want to warn about zero base/index registers. */ +static boolean warn_areg_zero = FALSE; + +/* Generic assembler global variables which must be defined by all + targets. */ + +const char comment_chars[] = "#"; + +/* Characters which start a comment at the beginning of a line. */ +const char line_comment_chars[] = "#"; + +/* Characters which may be used to separate multiple commands on a + single line. */ +const char line_separator_chars[] = ";"; + +/* Characters which are used to indicate an exponent in a floating + point number. */ +const char EXP_CHARS[] = "eE"; + +/* Characters which mean that a number is a floating point constant, + as in 0d1.0. */ +const char FLT_CHARS[] = "dD"; + +/* The target specific pseudo-ops which we support. */ + +/* Define the prototypes for the pseudo-ops */ +static void s390_byte PARAMS ((int)); +static void s390_elf_cons PARAMS ((int)); +static void s390_bss PARAMS ((int)); +static void s390_insn PARAMS ((int)); +static void s390_literals PARAMS ((int)); + +const pseudo_typeS md_pseudo_table[] = +{ + { "align", s_align_bytes, 0 }, + /* Pseudo-ops which must be defined. */ + { "bss", s390_bss, 0 }, + { "insn", s390_insn, 0 }, + /* Pseudo-ops which must be overridden. */ + { "byte", s390_byte, 0 }, + { "short", s390_elf_cons, 2 }, + { "long", s390_elf_cons, 4 }, + { "quad", s390_elf_cons, 8 }, + { "ltorg", s390_literals, 0 }, + { "string", stringer, 2 }, + { NULL, NULL, 0 } +}; + + +/* Structure to hold information about predefined registers. */ +struct pd_reg + { + char *name; + int value; + }; + +/* List of registers that are pre-defined: + + Each access register has a predefined name of the form: + a<reg_num> which has the value <reg_num>. + + Each control register has a predefined name of the form: + c<reg_num> which has the value <reg_num>. + + Each general register has a predefined name of the form: + r<reg_num> which has the value <reg_num>. + + Each floating point register a has predefined name of the form: + f<reg_num> which has the value <reg_num>. + + There are individual registers as well: + sp has the value 15 + lit has the value 12 + + The table is sorted. Suitable for searching by a binary search. */ + +static const struct pd_reg pre_defined_registers[] = +{ + { "a0", 0 }, /* Access registers */ + { "a1", 1 }, + { "a10", 10 }, + { "a11", 11 }, + { "a12", 12 }, + { "a13", 13 }, + { "a14", 14 }, + { "a15", 15 }, + { "a2", 2 }, + { "a3", 3 }, + { "a4", 4 }, + { "a5", 5 }, + { "a6", 6 }, + { "a7", 7 }, + { "a8", 8 }, + { "a9", 9 }, + + { "c0", 0 }, /* Control registers */ + { "c1", 1 }, + { "c10", 10 }, + { "c11", 11 }, + { "c12", 12 }, + { "c13", 13 }, + { "c14", 14 }, + { "c15", 15 }, + { "c2", 2 }, + { "c3", 3 }, + { "c4", 4 }, + { "c5", 5 }, + { "c6", 6 }, + { "c7", 7 }, + { "c8", 8 }, + { "c9", 9 }, + + { "f0", 0 }, /* Floating point registers */ + { "f1", 1 }, + { "f10", 10 }, + { "f11", 11 }, + { "f12", 12 }, + { "f13", 13 }, + { "f14", 14 }, + { "f15", 15 }, + { "f2", 2 }, + { "f3", 3 }, + { "f4", 4 }, + { "f5", 5 }, + { "f6", 6 }, + { "f7", 7 }, + { "f8", 8 }, + { "f9", 9 }, + + { "lit", 13 }, /* Pointer to literal pool */ + + { "r0", 0 }, /* General purpose registers */ + { "r1", 1 }, + { "r10", 10 }, + { "r11", 11 }, + { "r12", 12 }, + { "r13", 13 }, + { "r14", 14 }, + { "r15", 15 }, + { "r2", 2 }, + { "r3", 3 }, + { "r4", 4 }, + { "r5", 5 }, + { "r6", 6 }, + { "r7", 7 }, + { "r8", 8 }, + { "r9", 9 }, + + { "sp", 15 }, /* Stack pointer */ + +}; + +#define REG_NAME_CNT (sizeof (pre_defined_registers) / sizeof (struct pd_reg)) + +static int reg_name_search + PARAMS ((const struct pd_reg *, int, const char *)); +static boolean register_name PARAMS ((expressionS *)); +static void init_default_arch PARAMS ((void)); +static void s390_insert_operand + PARAMS ((unsigned char *, const struct s390_operand *, offsetT, char *, + unsigned int)); +static char *md_gather_operands + PARAMS ((char *, unsigned char *, const struct s390_opcode *)); + +/* Given NAME, find the register number associated with that name, return + the integer value associated with the given name or -1 on failure. */ + +static int +reg_name_search (regs, regcount, name) + const struct pd_reg *regs; + int regcount; + const char *name; +{ + int middle, low, high; + int cmp; + + low = 0; + high = regcount - 1; + + do + { + middle = (low + high) / 2; + cmp = strcasecmp (name, regs[middle].name); + if (cmp < 0) + high = middle - 1; + else if (cmp > 0) + low = middle + 1; + else + return regs[middle].value; + } + while (low <= high); + + return -1; +} + + +/* + * Summary of register_name(). + * + * in: Input_line_pointer points to 1st char of operand. + * + * out: A expressionS. + * The operand may have been a register: in this case, X_op == O_register, + * X_add_number is set to the register number, and truth is returned. + * Input_line_pointer->(next non-blank) char after operand, or is in its + * original state. + */ + +static boolean +register_name (expressionP) + expressionS *expressionP; +{ + int reg_number; + char *name; + char *start; + char c; + + /* Find the spelling of the operand. */ + start = name = input_line_pointer; + if (name[0] == '%' && ISALPHA (name[1])) + name = ++input_line_pointer; + else + return false; + + c = get_symbol_end (); + reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT, name); + + /* Put back the delimiting char. */ + *input_line_pointer = c; + + /* Look to see if it's in the register table. */ + if (reg_number >= 0) + { + expressionP->X_op = O_register; + expressionP->X_add_number = reg_number; + + /* Make the rest nice. */ + expressionP->X_add_symbol = NULL; + expressionP->X_op_symbol = NULL; + return true; + } + + /* Reset the line as if we had not done anything. */ + input_line_pointer = start; + return false; +} + +/* Local variables. */ + +/* Opformat hash table. */ +static struct hash_control *s390_opformat_hash; + +/* Opcode hash table. */ +static struct hash_control *s390_opcode_hash; + +/* Flags to set in the elf header */ +static flagword s390_flags = 0; + +symbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */ + +#ifndef WORKING_DOT_WORD +const int md_short_jump_size = 4; +const int md_long_jump_size = 4; +#endif + +CONST char *md_shortopts = "A:m:kVQ:"; +struct option md_longopts[] = { + {NULL, no_argument, NULL, 0} +}; +size_t md_longopts_size = sizeof (md_longopts); + +/* Initialize the default opcode arch and word size from the default + architecture name. */ +static void +init_default_arch () +{ + if (current_arch_requested) + return; + + if (strcmp (default_arch, "s390") == 0) + { + s390_arch_size = 32; + current_architecture = S390_OPCODE_ESA; + } + else if (strcmp (default_arch, "s390x") == 0) + { + s390_arch_size = 64; + current_architecture = S390_OPCODE_ESAME; + } + else + as_fatal ("Invalid default architecture, broken assembler."); + current_arch_mask = 1 << current_architecture; +} + +/* Called by TARGET_FORMAT. */ +const char * +s390_target_format () +{ + /* We don't get a chance to initialize anything before we're called, + so handle that now. */ + if (! s390_arch_size) + init_default_arch (); + + return s390_arch_size == 64 ? "elf64-s390" : "elf32-s390"; +} + +int +md_parse_option (c, arg) + int c; + char *arg; +{ + switch (c) + { + /* -k: Ignore for FreeBSD compatibility. */ + case 'k': + break; + case 'm': + if (arg != NULL && strcmp (arg, "regnames") == 0) + reg_names_p = true; + + else if (arg != NULL && strcmp (arg, "no-regnames") == 0) + reg_names_p = false; + + else if (arg != NULL && strcmp (arg, "warn-areg-zero") == 0) + warn_areg_zero = TRUE; + + else if (arg != NULL && strcmp (arg, "31") == 0) + s390_arch_size = 31; + + else if (arg != NULL && strcmp (arg, "64") == 0) + s390_arch_size = 64; + + else + { + as_bad (_("invalid switch -m%s"), arg); + return 0; + } + break; + + case 'A': + if (arg != NULL && strcmp (arg, "esa") == 0) + current_architecture = S390_OPCODE_ESA; + else if (arg != NULL && strcmp (arg, "esame") == 0) + current_architecture = S390_OPCODE_ESAME; + else + as_bad ("invalid architecture -A%s", arg); + current_arch_mask = 1 << current_architecture; + current_arch_requested = 1; + break; + + /* -V: SVR4 argument to print version ID. */ + case 'V': + print_version_id (); + break; + + /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section + should be emitted or not. FIXME: Not implemented. */ + case 'Q': + break; + + default: + return 0; + } + + return 1; +} + +void +md_show_usage (stream) + FILE *stream; +{ + fprintf (stream, _("\ + S390 options:\n\ + -mregnames Allow symbolic names for registers\n\ + -mwarn-areg-zero Warn about zero base/index registers\n\ + -mno-regnames Do not allow symbolic names for registers\n\ + -m31 Set file format to 31 bit format\n\ + -m64 Set file format to 64 bit format\n")); + fprintf (stream, _("\ + -V print assembler version number\n\ + -Qy, -Qn ignored\n")); +} + +/* This function is called when the assembler starts up. It is called + after the options have been parsed and the output file has been + opened. */ + +void +md_begin () +{ + register const struct s390_opcode *op; + const struct s390_opcode *op_end; + boolean dup_insn = false; + const char *retval; + + /* Give a warning if the combination -m64-bit and -Aesa is used. */ + if (s390_arch_size == 64 && current_arch_mask == (1 << S390_OPCODE_ESA)) + as_warn ("The 64 bit file format is used without esame instructions."); + + /* Set the ELF flags if desired. */ + if (s390_flags) + bfd_set_private_flags (stdoutput, s390_flags); + + /* Insert the opcode formats into a hash table. */ + s390_opformat_hash = hash_new (); + + op_end = s390_opformats + s390_num_opformats; + for (op = s390_opformats; op < op_end; op++) + { + retval = hash_insert (s390_opformat_hash, op->name, (PTR) op); + if (retval != (const char *) NULL) + { + as_bad (_("Internal assembler error for instruction format %s"), + op->name); + dup_insn = true; + } + } + + /* Insert the opcodes into a hash table. */ + s390_opcode_hash = hash_new (); + + op_end = s390_opcodes + s390_num_opcodes; + for (op = s390_opcodes; op < op_end; op++) + { + retval = hash_insert (s390_opcode_hash, op->name, (PTR) op); + if (retval != (const char *) NULL) + { + as_bad (_("Internal assembler error for instruction %s"), op->name); + dup_insn = true; + } + } + + if (dup_insn) + abort (); + + record_alignment (text_section, 2); + record_alignment (data_section, 2); + record_alignment (bss_section, 2); + +} + +/* Called after all assembly has been done. */ +void +s390_md_end () +{ + if (s390_arch_size == 64) + bfd_set_arch_mach (stdoutput, bfd_arch_s390, bfd_mach_s390_64); + else + bfd_set_arch_mach (stdoutput, bfd_arch_s390, bfd_mach_s390_31); +} + +void +s390_align_code (fragP, count) + fragS *fragP; + int count; +{ + /* We use nop pattern 0x0707. */ + if (count > 0) + { + memset (fragP->fr_literal + fragP->fr_fix, 0x07, count); + fragP->fr_var = count; + } +} + +/* Insert an operand value into an instruction. */ + +static void +s390_insert_operand (insn, operand, val, file, line) + unsigned char *insn; + const struct s390_operand *operand; + offsetT val; + char *file; + unsigned int line; +{ + addressT uval; + int offset; + + if (operand->flags & (S390_OPERAND_SIGNED|S390_OPERAND_PCREL)) + { + offsetT min, max; + + max = ((offsetT) 1 << (operand->bits - 1)) - 1; + min = - ((offsetT) 1 << (operand->bits - 1)); + /* Halve PCREL operands. */ + if (operand->flags & S390_OPERAND_PCREL) + val >>= 1; + /* Check for underflow / overflow. */ + if (val < min || val > max) + { + const char *err = + "operand out of range (%s not between %ld and %ld)"; + char buf[100]; + + if (operand->flags & S390_OPERAND_PCREL) + { + val <<= 1; + min <<= 1; + max <<= 1; + } + sprint_value (buf, val); + if (file == (char *) NULL) + as_bad (err, buf, (int) min, (int) max); + else + as_bad_where (file, line, err, buf, (int) min, (int) max); + return; + } + /* val is ok, now restrict it to operand->bits bits. */ + uval = (addressT) val & ((((addressT) 1 << (operand->bits-1)) << 1) - 1); + } + else + { + addressT min, max; + + max = (((addressT) 1 << (operand->bits - 1))<<1) - 1; + min = (offsetT) 0; + uval = (addressT) val; + /* Length x in an instructions has real length x+1. */ + if (operand->flags & S390_OPERAND_LENGTH) + uval--; + /* Check for underflow / overflow. */ + if (uval < min || uval > max) + { + const char *err = + "operand out of range (%s not between %ld and %ld)"; + char buf[100]; + + if (operand->flags & S390_OPERAND_LENGTH) + { + uval++; + min++; + max++; + } + sprint_value (buf, uval); + if (file == (char *) NULL) + as_bad (err, buf, (int) min, (int) max); + else + as_bad_where (file, line, err, buf, (int) min, (int) max); + return; + } + } + + /* Insert fragments of the operand byte for byte. */ + offset = operand->shift + operand->bits; + uval <<= (-offset) & 7; + insn += (offset - 1)/8; + while (uval != 0) + { + *insn-- |= uval; + uval >>= 8; + } +} + +/* Structure used to hold suffixes. */ +typedef enum + { + ELF_SUFFIX_NONE = 0, + ELF_SUFFIX_GOT, + ELF_SUFFIX_PLT, + ELF_SUFFIX_GOTENT + } +elf_suffix_type; + +struct map_bfd + { + char *string; + int length; + elf_suffix_type suffix; + }; + +static elf_suffix_type s390_elf_suffix PARAMS ((char **, expressionS *)); +static int s390_exp_compare PARAMS ((expressionS *exp1, expressionS *exp2)); +static elf_suffix_type s390_lit_suffix + PARAMS ((char **, expressionS *, elf_suffix_type)); + + +/* Parse @got/@plt/@gotoff. and return the desired relocation. */ +static elf_suffix_type +s390_elf_suffix (str_p, exp_p) + char **str_p; + expressionS *exp_p; +{ + static struct map_bfd mapping[] = + { + { "got", 3, ELF_SUFFIX_GOT }, + { "got12", 5, ELF_SUFFIX_GOT }, + { "plt", 3, ELF_SUFFIX_PLT }, + { "gotent", 6, ELF_SUFFIX_GOTENT }, + { NULL, 0, ELF_SUFFIX_NONE } + }; + + struct map_bfd *ptr; + char *str = *str_p; + char *ident; + int len; + + if (*str++ != '@') + return ELF_SUFFIX_NONE; + + ident = str; + while (ISALNUM (*str)) + str++; + len = str - ident; + + for (ptr = &mapping[0]; ptr->length > 0; ptr++) + if (len == ptr->length + && strncasecmp (ident, ptr->string, ptr->length) == 0) + { + if (exp_p->X_add_number != 0) + as_warn (_("identifier+constant@%s means identifier@%s+constant"), + ptr->string, ptr->string); + /* Now check for identifier@suffix+constant. */ + if (*str == '-' || *str == '+') + { + char *orig_line = input_line_pointer; + expressionS new_exp; + + input_line_pointer = str; + expression (&new_exp); + + switch (new_exp.X_op) + { + case O_constant: /* X_add_number (a constant expression). */ + exp_p->X_add_number += new_exp.X_add_number; + str = input_line_pointer; + break; + case O_symbol: /* X_add_symbol + X_add_number. */ + /* this case is used for e.g. xyz@PLT+.Label. */ + exp_p->X_add_number += new_exp.X_add_number; + exp_p->X_op_symbol = new_exp.X_add_symbol; + exp_p->X_op = O_add; + str = input_line_pointer; + break; + case O_uminus: /* (- X_add_symbol) + X_add_number. */ + /* this case is used for e.g. xyz@PLT-.Label. */ + exp_p->X_add_number += new_exp.X_add_number; + exp_p->X_op_symbol = new_exp.X_add_symbol; + exp_p->X_op = O_subtract; + str = input_line_pointer; + break; + default: + break; + } + + /* If s390_elf_suffix has not been called with + &input_line_pointer as first parameter, we have + clobbered the input_line_pointer. We have to + undo that. */ + if (&input_line_pointer != str_p) + input_line_pointer = orig_line; + } + *str_p = str; + return ptr->suffix; + } + + return BFD_RELOC_UNUSED; +} + +/* Structure used to hold a literal pool entry. */ +struct s390_lpe + { + struct s390_lpe *next; + expressionS ex; + FLONUM_TYPE floatnum; /* used if X_op == O_big && X_add_number <= 0 */ + LITTLENUM_TYPE bignum[4]; /* used if X_op == O_big && X_add_number > 0 */ + int nbytes; + bfd_reloc_code_real_type reloc; + symbolS *sym; + }; + +static struct s390_lpe *lpe_free_list = NULL; +static struct s390_lpe *lpe_list = NULL; +static struct s390_lpe *lpe_list_tail = NULL; +static symbolS *lp_sym = NULL; +static int lp_count = 0; +static int lpe_count = 0; + +static int +s390_exp_compare(exp1, exp2) + expressionS *exp1; + expressionS *exp2; +{ + if (exp1->X_op != exp2->X_op) + return 0; + + switch (exp1->X_op) + { + case O_constant: /* X_add_number must be equal. */ + case O_register: + return exp1->X_add_number == exp2->X_add_number; + + case O_big: + as_bad (_("Can't handle O_big in s390_exp_compare")); + + case O_symbol: /* X_add_symbol & X_add_number must be equal. */ + case O_symbol_rva: + case O_uminus: + case O_bit_not: + case O_logical_not: + return (exp1->X_add_symbol == exp2->X_add_symbol) + && (exp1->X_add_number == exp2->X_add_number); + + case O_multiply: /* X_add_symbol,X_op_symbol&X_add_number must be equal. */ + case O_divide: + case O_modulus: + case O_left_shift: + case O_right_shift: + case O_bit_inclusive_or: + case O_bit_or_not: + case O_bit_exclusive_or: + case O_bit_and: + case O_add: + case O_subtract: + case O_eq: + case O_ne: + case O_lt: + case O_le: + case O_ge: + case O_gt: + case O_logical_and: + case O_logical_or: + return (exp1->X_add_symbol == exp2->X_add_symbol) + && (exp1->X_op_symbol == exp2->X_op_symbol) + && (exp1->X_add_number == exp2->X_add_number); + default: + return 0; + } +} + +/* Test for @lit and if its present make an entry in the literal pool and + modify the current expression to be an offset into the literal pool. */ +static elf_suffix_type +s390_lit_suffix (str_p, exp_p, suffix) + char **str_p; + expressionS *exp_p; + elf_suffix_type suffix; +{ + bfd_reloc_code_real_type reloc; + char tmp_name[64]; + char *str = *str_p; + char *ident; + struct s390_lpe *lpe; + int nbytes, len; + + if (*str++ != ':') + return suffix; /* No modification. */ + + /* We look for a suffix of the form "@lit1", "@lit2", "@lit4" or "@lit8". */ + ident = str; + while (ISALNUM (*str)) + str++; + len = str - ident; + if (len != 4 || strncasecmp (ident, "lit", 3) != 0 + || (ident[3]!='1' && ident[3]!='2' && ident[3]!='4' && ident[3]!='8')) + return suffix; /* no modification */ + nbytes = ident[3] - '0'; + + reloc = BFD_RELOC_UNUSED; + if (suffix == ELF_SUFFIX_GOT) + { + if (nbytes == 2) + reloc = BFD_RELOC_390_GOT16; + else if (nbytes == 4) + reloc = BFD_RELOC_32_GOT_PCREL; + else if (nbytes == 8) + reloc = BFD_RELOC_390_GOT64; + } + else if (suffix == ELF_SUFFIX_PLT) + { + if (nbytes == 4) + reloc = BFD_RELOC_390_PLT32; + else if (nbytes == 8) + reloc = BFD_RELOC_390_PLT64; + } + + if (suffix != ELF_SUFFIX_NONE && reloc == BFD_RELOC_UNUSED) + as_bad (_("Invalid suffix for literal pool entry")); + + /* Search the pool if the new entry is a duplicate. */ + if (exp_p->X_op == O_big) + { + /* Special processing for big numbers. */ + for (lpe = lpe_list; lpe != NULL; lpe = lpe->next) + { + if (lpe->ex.X_op == O_big) + { + if (exp_p->X_add_number <= 0 && lpe->ex.X_add_number <= 0) + { + if (memcmp (&generic_floating_point_number, &lpe->floatnum, + sizeof (FLONUM_TYPE)) == 0) + break; + } + else if (exp_p->X_add_number == lpe->ex.X_add_number) + { + if (memcmp (generic_bignum, lpe->bignum, + sizeof (LITTLENUM_TYPE)*exp_p->X_add_number) == 0) + break; + } + } + } + } + else + { + /* Processing for 'normal' data types. */ + for (lpe = lpe_list; lpe != NULL; lpe = lpe->next) + if (lpe->nbytes == nbytes && lpe->reloc == reloc + && s390_exp_compare(exp_p, &lpe->ex) != 0) + break; + } + + if (lpe == NULL) + { + /* A new literal. */ + if (lpe_free_list != NULL) + { + lpe = lpe_free_list; + lpe_free_list = lpe_free_list->next; + } + else + { + lpe = (struct s390_lpe *) xmalloc(sizeof (struct s390_lpe)); + } + + lpe->ex = *exp_p; + + if (exp_p->X_op == O_big) + { + if (exp_p->X_add_number <= 0) + lpe->floatnum = generic_floating_point_number; + else if (exp_p->X_add_number <= 4) + memcpy (lpe->bignum, generic_bignum, + exp_p->X_add_number*sizeof (LITTLENUM_TYPE)); + else + as_bad (_("Big number is too big")); + } + + lpe->nbytes = nbytes; + lpe->reloc = reloc; + /* Literal pool name defined ? */ + if (lp_sym == NULL) + { + sprintf (tmp_name, ".L\001%i", lp_count); + lp_sym = symbol_make(tmp_name); + } + + /* Make name for literal pool entry. */ + sprintf (tmp_name, ".L\001%i\002%i", lp_count, lpe_count); + lpe_count++; + lpe->sym = symbol_make(tmp_name); + + /* Add to literal pool list. */ + lpe->next = NULL; + if (lpe_list_tail != NULL) + { + lpe_list_tail->next = lpe; + lpe_list_tail = lpe; + } + else + lpe_list = lpe_list_tail = lpe; + } + + /* Now change exp_p to the offset into the literal pool. + Thats the expression: .L^Ax^By-.L^Ax */ + exp_p->X_add_symbol = lpe->sym; + exp_p->X_op_symbol = lp_sym; + exp_p->X_op = O_subtract; + exp_p->X_add_number = 0; + + *str_p = str; + + /* We change the suffix type to ELF_SUFFIX_NONE, because + the difference of two local labels is just a number. */ + return ELF_SUFFIX_NONE; +} + +/* Like normal .long/.short/.word, except support @got, etc. + clobbers input_line_pointer, checks end-of-line. */ +static void +s390_elf_cons (nbytes) + register int nbytes; /* 1=.byte, 2=.word, 4=.long */ +{ + expressionS exp; + elf_suffix_type suffix; + + if (is_it_end_of_statement ()) + { + demand_empty_rest_of_line (); + return; + } + + do + { + expression (&exp); + + if (exp.X_op == O_symbol + && *input_line_pointer == '@' + && (suffix = s390_elf_suffix (&input_line_pointer, &exp)) != ELF_SUFFIX_NONE) + { + bfd_reloc_code_real_type reloc; + reloc_howto_type *reloc_howto; + int size; + char *where; + + if (nbytes == 2 && suffix == ELF_SUFFIX_GOT) + reloc = BFD_RELOC_390_GOT16; + else if (nbytes == 4 && suffix == ELF_SUFFIX_GOT) + reloc = BFD_RELOC_32_GOT_PCREL; + else if (nbytes == 8 && suffix == ELF_SUFFIX_GOT) + reloc = BFD_RELOC_390_GOT64; + else if (nbytes == 4 && suffix == ELF_SUFFIX_PLT) + reloc = BFD_RELOC_390_PLT32; + else if (nbytes == 8 && suffix == ELF_SUFFIX_PLT) + reloc = BFD_RELOC_390_PLT64; + else + reloc = BFD_RELOC_UNUSED; + + if (reloc != BFD_RELOC_UNUSED) + { + reloc_howto = bfd_reloc_type_lookup (stdoutput, reloc); + size = bfd_get_reloc_size (reloc_howto); + if (size > nbytes) + as_bad (_("%s relocations do not fit in %d bytes"), + reloc_howto->name, nbytes); + where = frag_more (nbytes); + md_number_to_chars (where, 0, size); + /* To make fixup_segment do the pc relative conversion the + pcrel parameter on the fix_new_exp call needs to be false. */ + fix_new_exp (frag_now, where - frag_now->fr_literal, + size, &exp, false, reloc); + } + else + as_bad (_("relocation not applicable")); + } + else + emit_expr (&exp, (unsigned int) nbytes); + } + while (*input_line_pointer++ == ','); + + input_line_pointer--; /* Put terminator back into stream. */ + demand_empty_rest_of_line (); +} + +/* We need to keep a list of fixups. We can't simply generate them as + we go, because that would require us to first create the frag, and + that would screw up references to ``.''. */ + +struct s390_fixup + { + expressionS exp; + int opindex; + bfd_reloc_code_real_type reloc; + }; + +#define MAX_INSN_FIXUPS (4) + +/* This routine is called for each instruction to be assembled. */ + +static char * +md_gather_operands (str, insn, opcode) + char *str; + unsigned char *insn; + const struct s390_opcode *opcode; +{ + struct s390_fixup fixups[MAX_INSN_FIXUPS]; + const struct s390_operand *operand; + const unsigned char *opindex_ptr; + elf_suffix_type suffix; + bfd_reloc_code_real_type reloc; + int skip_optional; + int parentheses; + char *f; + int fc, i; + + while (ISSPACE (*str)) str++; + + parentheses = 0; + skip_optional = 0; + + /* Gather the operands. */ + fc = 0; + for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++) + { + expressionS ex; + char *hold; + + operand = s390_operands + *opindex_ptr; + + if (skip_optional && (operand->flags & S390_OPERAND_INDEX)) + { + /* We do an early skip. For D(X,B) constructions the index + register is skipped (X is optional). For D(L,B) the base + register will be the skipped operand, because L is NOT + optional. */ + skip_optional = 0; + continue; + } + + /* Gather the operand. */ + hold = input_line_pointer; + input_line_pointer = str; + + if (! register_name (&ex)) /* parse the operand */ + expression (&ex); + + str = input_line_pointer; + input_line_pointer = hold; + + /* Write the operand to the insn. */ + if (ex.X_op == O_illegal) + as_bad (_("illegal operand")); + else if (ex.X_op == O_absent) + as_bad (_("missing operand")); + else if (ex.X_op == O_register || ex.X_op == O_constant) + { + s390_lit_suffix (&str, &ex, ELF_SUFFIX_NONE); + + if (ex.X_op != O_register && ex.X_op != O_constant) + { + /* We need to generate a fixup for the + expression returned by s390_lit_suffix. */ + if (fc >= MAX_INSN_FIXUPS) + as_fatal (_("too many fixups")); + fixups[fc].exp = ex; + fixups[fc].opindex = *opindex_ptr; + fixups[fc].reloc = BFD_RELOC_UNUSED; + ++fc; + } + else + { + if ((operand->flags & S390_OPERAND_INDEX) + && ex.X_add_number == 0 + && warn_areg_zero == TRUE) + as_warn ("index register specified but zero"); + if ((operand->flags & S390_OPERAND_BASE) + && ex.X_add_number == 0 + && warn_areg_zero == TRUE) + as_warn ("base register specified but zero"); + s390_insert_operand (insn, operand, ex.X_add_number, NULL, 0); + } + } + else + { + suffix = s390_elf_suffix (&str, &ex); + suffix = s390_lit_suffix (&str, &ex, suffix); + reloc = BFD_RELOC_UNUSED; + + if (suffix == ELF_SUFFIX_GOT) + { + if (operand->flags & S390_OPERAND_DISP) + reloc = BFD_RELOC_390_GOT12; + else if ((operand->flags & S390_OPERAND_SIGNED) + && (operand->bits == 16)) + reloc = BFD_RELOC_390_GOT16; + else if ((operand->flags & S390_OPERAND_PCREL) + && (operand->bits == 32)) + reloc = BFD_RELOC_390_GOTENT; + } + else if (suffix == ELF_SUFFIX_PLT) + { + if ((operand->flags & S390_OPERAND_PCREL) + && (operand->bits == 16)) + reloc = BFD_RELOC_390_PLT16DBL; + else if ((operand->flags & S390_OPERAND_PCREL) + && (operand->bits == 32)) + reloc = BFD_RELOC_390_PLT32DBL; + } + else if (suffix == ELF_SUFFIX_GOTENT) + { + if ((operand->flags & S390_OPERAND_PCREL) + && (operand->bits == 32)) + reloc = BFD_RELOC_390_GOTENT; + } + + if (suffix != ELF_SUFFIX_NONE && reloc == BFD_RELOC_UNUSED) + as_bad (_("invalid operand suffix")); + /* We need to generate a fixup of type 'reloc' for this + expression. */ + if (fc >= MAX_INSN_FIXUPS) + as_fatal (_("too many fixups")); + fixups[fc].exp = ex; + fixups[fc].opindex = *opindex_ptr; + fixups[fc].reloc = reloc; + ++fc; + } + + /* Check the next character. The call to expression has advanced + str past any whitespace. */ + if (operand->flags & S390_OPERAND_DISP) + { + /* After a displacement a block in parentheses can start. */ + if (*str != '(') + { + /* Check if parethesed block can be skipped. If the next + operand is neiter an optional operand nor a base register + then we have a syntax error. */ + operand = s390_operands + *(++opindex_ptr); + if (!(operand->flags & (S390_OPERAND_INDEX|S390_OPERAND_BASE))) + as_bad (_("syntax error; missing '(' after displacement")); + + /* Ok, skip all operands until S390_OPERAND_BASE. */ + while (!(operand->flags & S390_OPERAND_BASE)) + operand = s390_operands + *(++opindex_ptr); + + /* If there is a next operand it must be seperated by a comma. */ + if (opindex_ptr[1] != '\0') + { + if (*str++ != ',') + as_bad (_("syntax error; expected ,")); + } + } + else + { + /* We found an opening parentheses. */ + str++; + for (f = str; *f != '\0'; f++) + if (*f == ',' || *f == ')') + break; + /* If there is no comma until the closing parentheses OR + there is a comma right after the opening parentheses, + we have to skip optional operands. */ + if (*f == ',' && f == str) + { + /* comma directly after '(' ? */ + skip_optional = 1; + str++; + } + else + skip_optional = (*f != ','); + } + } + else if (operand->flags & S390_OPERAND_BASE) + { + /* After the base register the parenthesed block ends. */ + if (*str++ != ')') + as_bad (_("syntax error; missing ')' after base register")); + skip_optional = 0; + /* If there is a next operand it must be seperated by a comma. */ + if (opindex_ptr[1] != '\0') + { + if (*str++ != ',') + as_bad (_("syntax error; expected ,")); + } + } + else + { + /* We can find an 'early' closing parentheses in e.g. D(L) instead + of D(L,B). In this case the base register has to be skipped. */ + if (*str == ')') + { + operand = s390_operands + *(++opindex_ptr); + + if (!(operand->flags & S390_OPERAND_BASE)) + as_bad (_("syntax error; ')' not allowed here")); + str++; + } + /* If there is a next operand it must be seperated by a comma. */ + if (opindex_ptr[1] != '\0') + { + if (*str++ != ',') + as_bad (_("syntax error; expected ,")); + } + } + } + + while (ISSPACE (*str)) + ++str; + + if (*str != '\0') + { + char *linefeed; + + if ((linefeed = strchr (str, '\n')) != NULL) + *linefeed = '\0'; + as_bad (_("junk at end of line: `%s'"), str); + if (linefeed != NULL) + *linefeed = '\n'; + } + + /* Write out the instruction. */ + f = frag_more (opcode->oplen); + memcpy (f, insn, opcode->oplen); + dwarf2_emit_insn (opcode->oplen); + + /* Create any fixups. At this point we do not use a + bfd_reloc_code_real_type, but instead just use the + BFD_RELOC_UNUSED plus the operand index. This lets us easily + handle fixups for any operand type, although that is admittedly + not a very exciting feature. We pick a BFD reloc type in + md_apply_fix3. */ + for (i = 0; i < fc; i++) + { + operand = s390_operands + fixups[i].opindex; + + if (fixups[i].reloc != BFD_RELOC_UNUSED) + { + reloc_howto_type *reloc_howto; + fixS *fixP; + int size; + + reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc); + if (!reloc_howto) + abort (); + + size = bfd_get_reloc_size (reloc_howto); + + if (size < 1 || size > 4) + abort (); + + fixP = fix_new_exp (frag_now, + f - frag_now->fr_literal + (operand->shift/8), + size, &fixups[i].exp, reloc_howto->pc_relative, + fixups[i].reloc); + /* Turn off overflow checking in fixup_segment. This is necessary + because fixup_segment will signal an overflow for large 4 byte + quantities for GOT12 relocations. */ + if ( fixups[i].reloc == BFD_RELOC_390_GOT12 + || fixups[i].reloc == BFD_RELOC_390_GOT16) + fixP->fx_no_overflow = 1; + } + else + fix_new_exp (frag_now, f - frag_now->fr_literal, 4, &fixups[i].exp, + (operand->flags & S390_OPERAND_PCREL) != 0, + ((bfd_reloc_code_real_type) + (fixups[i].opindex + (int) BFD_RELOC_UNUSED))); + } + return str; +} + +/* This routine is called for each instruction to be assembled. */ + +void +md_assemble (str) + char *str; +{ + const struct s390_opcode *opcode; + unsigned char insn[6]; + char *s; + + /* Get the opcode. */ + for (s = str; *s != '\0' && ! ISSPACE (*s); s++) + ; + if (*s != '\0') + *s++ = '\0'; + + /* Look up the opcode in the hash table. */ + opcode = (struct s390_opcode *) hash_find (s390_opcode_hash, str); + if (opcode == (const struct s390_opcode *) NULL) + { + as_bad (_("Unrecognized opcode: `%s'"), str); + return; + } + else if (!(opcode->architecture & current_arch_mask)) + { + as_bad ("Opcode %s not available in this architecture", str); + return; + } + + memcpy (insn, opcode->opcode, sizeof (insn)); + md_gather_operands (s, insn, opcode); +} + +#ifndef WORKING_DOT_WORD +/* Handle long and short jumps. We don't support these */ +void +md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol) + char *ptr; + addressT from_addr, to_addr; + fragS *frag; + symbolS *to_symbol; +{ + abort (); +} + +void +md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol) + char *ptr; + addressT from_addr, to_addr; + fragS *frag; + symbolS *to_symbol; +{ + abort (); +} +#endif + +void +s390_bss (ignore) + int ignore ATTRIBUTE_UNUSED; +{ + /* We don't support putting frags in the BSS segment, we fake it + by marking in_bss, then looking at s_skip for clues. */ + + subseg_set (bss_section, 0); + demand_empty_rest_of_line (); +} + +/* Pseudo-op handling. */ + +void +s390_insn (ignore) + int ignore ATTRIBUTE_UNUSED; +{ + expressionS exp; + const struct s390_opcode *opformat; + unsigned char insn[6]; + char *s; + + /* Get the opcode format. */ + s = input_line_pointer; + while (*s != '\0' && *s != ',' && ! ISSPACE (*s)) + s++; + if (*s != ',') + as_bad (_("Invalid .insn format\n")); + *s++ = '\0'; + + /* Look up the opcode in the hash table. */ + opformat = (struct s390_opcode *) + hash_find (s390_opformat_hash, input_line_pointer); + if (opformat == (const struct s390_opcode *) NULL) + { + as_bad (_("Unrecognized opcode format: `%s'"), input_line_pointer); + return; + } + input_line_pointer = s; + expression (&exp); + if (exp.X_op == O_constant) + { + if ( ((opformat->oplen == 6) && (exp.X_op > 0) && (exp.X_op < (1ULL << 48))) + || ((opformat->oplen == 4) && (exp.X_op > 0) && (exp.X_op < (1ULL << 32))) + || ((opformat->oplen == 2) && (exp.X_op > 0) && (exp.X_op < (1ULL << 16)))) + md_number_to_chars (insn, exp.X_add_number, opformat->oplen); + else + as_bad (_("Invalid .insn format\n")); + } + else if (exp.X_op == O_big) + { + if (exp.X_add_number > 0 + && opformat->oplen == 6 + && generic_bignum[3] == 0) + { + md_number_to_chars (insn, generic_bignum[2], 2); + md_number_to_chars (&insn[2], generic_bignum[1], 2); + md_number_to_chars (&insn[4], generic_bignum[0], 2); + } + else + as_bad (_("Invalid .insn format\n")); + } + else + as_bad (_("second operand of .insn not a constant\n")); + + if (strcmp (opformat->name, "e") != 0 && *input_line_pointer++ != ',') + as_bad (_("missing comma after insn constant\n")); + + if ((s = strchr (input_line_pointer, '\n')) != NULL) + *s = '\0'; + input_line_pointer = md_gather_operands (input_line_pointer, insn, + opformat); + if (s != NULL) + *s = '\n'; + demand_empty_rest_of_line (); +} + +/* The .byte pseudo-op. This is similar to the normal .byte + pseudo-op, but it can also take a single ASCII string. */ + +static void +s390_byte (ignore) + int ignore ATTRIBUTE_UNUSED; +{ + if (*input_line_pointer != '\"') + { + cons (1); + return; + } + + /* Gather characters. A real double quote is doubled. Unusual + characters are not permitted. */ + ++input_line_pointer; + while (1) + { + char c; + + c = *input_line_pointer++; + + if (c == '\"') + { + if (*input_line_pointer != '\"') + break; + ++input_line_pointer; + } + + FRAG_APPEND_1_CHAR (c); + } + + demand_empty_rest_of_line (); +} + +/* The .ltorg pseudo-op.This emits all literals defined since the last + .ltorg or the invocation of gas. Literals are defined with the + @lit suffix. */ + +static void +s390_literals (ignore) + int ignore ATTRIBUTE_UNUSED; +{ + struct s390_lpe *lpe; + + if (lp_sym == NULL || lpe_count == 0) + return; /* nothing to be done */ + + /* Emit symbol for start of literal pool. */ + S_SET_SEGMENT (lp_sym, now_seg); + S_SET_VALUE (lp_sym, (valueT) frag_now_fix ()); + lp_sym->sy_frag = frag_now; + + while (lpe_list) + { + lpe = lpe_list; + lpe_list = lpe_list->next; + S_SET_SEGMENT (lpe->sym, now_seg); + S_SET_VALUE (lpe->sym, (valueT) frag_now_fix ()); + lpe->sym->sy_frag = frag_now; + + /* Emit literal pool entry. */ + if (lpe->reloc != BFD_RELOC_UNUSED) + { + reloc_howto_type *reloc_howto = + bfd_reloc_type_lookup (stdoutput, lpe->reloc); + int size = bfd_get_reloc_size (reloc_howto); + char *where; + + if (size > lpe->nbytes) + as_bad (_("%s relocations do not fit in %d bytes"), + reloc_howto->name, lpe->nbytes); + where = frag_more (lpe->nbytes); + md_number_to_chars (where, 0, size); + fix_new_exp (frag_now, where - frag_now->fr_literal, + size, &lpe->ex, reloc_howto->pc_relative, lpe->reloc); + } + else + { + if (lpe->ex.X_op == O_big) + { + if (lpe->ex.X_add_number <= 0) + generic_floating_point_number = lpe->floatnum; + else + memcpy (generic_bignum, lpe->bignum, + lpe->ex.X_add_number*sizeof (LITTLENUM_TYPE)); + } + emit_expr (&lpe->ex, lpe->nbytes); + } + + lpe->next = lpe_free_list; + lpe_free_list = lpe; + } + lpe_list_tail = NULL; + lp_sym = NULL; + lp_count++; + lpe_count = 0; +} + +/* Turn a string in input_line_pointer into a floating point constant + of type type, and store the appropriate bytes in *litp. The number + of LITTLENUMS emitted is stored in *sizep . An error message is + returned, or NULL on OK. */ + +char * +md_atof (type, litp, sizep) + int type; + char *litp; + int *sizep; +{ + int prec; + LITTLENUM_TYPE words[4]; + char *t; + int i; + + switch (type) + { + case 'f': + prec = 2; + break; + + case 'd': + prec = 4; + break; + + default: + *sizep = 0; + return "bad call to md_atof"; + } + + t = atof_ieee (input_line_pointer, type, words); + if (t) + input_line_pointer = t; + + *sizep = prec * 2; + + for (i = 0; i < prec; i++) + { + md_number_to_chars (litp, (valueT) words[i], 2); + litp += 2; + } + + return NULL; +} + +/* Align a section (I don't know why this is machine dependent). */ + +valueT +md_section_align (seg, addr) + asection *seg; + valueT addr; +{ + int align = bfd_get_section_alignment (stdoutput, seg); + + return ((addr + (1 << align) - 1) & (-1 << align)); +} + +/* We don't have any form of relaxing. */ + +int +md_estimate_size_before_relax (fragp, seg) + fragS *fragp ATTRIBUTE_UNUSED; + asection *seg ATTRIBUTE_UNUSED; +{ + abort (); + return 0; +} + +/* Convert a machine dependent frag. We never generate these. */ + +void +md_convert_frag (abfd, sec, fragp) + bfd *abfd ATTRIBUTE_UNUSED; + asection *sec ATTRIBUTE_UNUSED; + fragS *fragp ATTRIBUTE_UNUSED; +{ + abort (); +} + +symbolS * +md_undefined_symbol (name) + char *name; +{ + if (*name == '_' && *(name+1) == 'G' + && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0) + { + if (!GOT_symbol) + { + if (symbol_find (name)) + as_bad (_("GOT already in symbol table")); + GOT_symbol = symbol_new (name, undefined_section, + (valueT) 0, &zero_address_frag); + } + return GOT_symbol; + } + return 0; +} + +/* Functions concerning relocs. */ + +/* The location from which a PC relative jump should be calculated, + given a PC relative reloc. */ + +long +md_pcrel_from_section (fixp, sec) + fixS *fixp; + segT sec ATTRIBUTE_UNUSED; +{ + return fixp->fx_frag->fr_address + fixp->fx_where; +} + +/* Here we decide which fixups can be adjusted to make them relative to + the beginning of the section instead of the symbol. Basically we need + to make sure that the dynamic relocations are done correctly, so in + some cases we force the original symbol to be used. */ +int +tc_s390_fix_adjustable(fixP) + fixS * fixP; +{ + /* Prevent all adjustments to global symbols. */ + if (S_IS_EXTERN (fixP->fx_addsy)) + return 0; + if (S_IS_WEAK (fixP->fx_addsy)) + return 0; + /* Don't adjust pc-relative references to merge sections. */ + if ((S_GET_SEGMENT(fixP->fx_addsy)->flags & SEC_MERGE) != 0 + && fixP->fx_pcrel) + return 0; + /* adjust_reloc_syms doesn't know about the GOT. */ + if ( fixP->fx_r_type == BFD_RELOC_32_GOTOFF + || fixP->fx_r_type == BFD_RELOC_390_PLT16DBL + || fixP->fx_r_type == BFD_RELOC_390_PLT32 + || fixP->fx_r_type == BFD_RELOC_390_PLT32DBL + || fixP->fx_r_type == BFD_RELOC_390_PLT64 + || fixP->fx_r_type == BFD_RELOC_390_GOT12 + || fixP->fx_r_type == BFD_RELOC_390_GOT16 + || fixP->fx_r_type == BFD_RELOC_32_GOT_PCREL + || fixP->fx_r_type == BFD_RELOC_390_GOT64 + || fixP->fx_r_type == BFD_RELOC_390_GOTENT + || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT + || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) + return 0; + return 1; +} + +/* Return true if we must always emit a reloc for a type and false if + there is some hope of resolving it a assembly time. */ +int +tc_s390_force_relocation (fixp) + struct fix *fixp; +{ + /* Ensure we emit a relocation for every reference to the global + offset table or to the procedure link table. */ + switch (fixp->fx_r_type) + { + case BFD_RELOC_390_GOT12: + case BFD_RELOC_32_GOT_PCREL: + case BFD_RELOC_32_GOTOFF: + case BFD_RELOC_390_GOTPC: + case BFD_RELOC_390_GOT16: + case BFD_RELOC_390_GOTPCDBL: + case BFD_RELOC_390_GOT64: + case BFD_RELOC_390_GOTENT: + case BFD_RELOC_390_PLT32: + case BFD_RELOC_390_PLT16DBL: + case BFD_RELOC_390_PLT32DBL: + case BFD_RELOC_390_PLT64: + case BFD_RELOC_VTABLE_INHERIT: + case BFD_RELOC_VTABLE_ENTRY: + return 1; + default: + return 0; + } +} + +/* Apply a fixup to the object code. This is called for all the + fixups we generated by the call to fix_new_exp, above. In the call + above we used a reloc code which was the largest legal reloc code + plus the operand index. Here we undo that to recover the operand + index. At this point all symbol values should be fully resolved, + and we attempt to completely resolve the reloc. If we can not do + that, we determine the correct reloc code and put it back in the + fixup. */ + +void +md_apply_fix3 (fixP, valP, seg) + fixS *fixP; + valueT *valP; + segT seg; +{ + char *where; + valueT value = * valP; + + where = fixP->fx_frag->fr_literal + fixP->fx_where; + + if (fixP->fx_subsy != NULL) + { + if ((fixP->fx_addsy != NULL + && S_GET_SEGMENT (fixP->fx_addsy) == S_GET_SEGMENT (fixP->fx_subsy) + && SEG_NORMAL (S_GET_SEGMENT (fixP->fx_addsy))) + || (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)) + value += S_GET_VALUE (fixP->fx_subsy); + if (!S_IS_DEFINED (fixP->fx_subsy)) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("unresolved fx_subsy symbol that must be resolved")); + value -= S_GET_VALUE(fixP->fx_subsy); + + if (S_GET_SEGMENT (fixP->fx_subsy) == seg && ! fixP->fx_pcrel) + value += MD_PCREL_FROM_SECTION (fixP, seg); + } + + if (fixP->fx_addsy != NULL) + { + if ((fixP->fx_subsy != NULL + && S_GET_SEGMENT (fixP->fx_addsy) == S_GET_SEGMENT (fixP->fx_subsy) + && SEG_NORMAL (S_GET_SEGMENT(fixP->fx_addsy))) + || (S_GET_SEGMENT (fixP->fx_addsy) == seg + && fixP->fx_pcrel && TC_RELOC_RTSYM_LOC_FIXUP (fixP)) + || (!fixP->fx_pcrel + && S_GET_SEGMENT (fixP->fx_addsy) == absolute_section) + || (S_GET_SEGMENT (fixP->fx_addsy) != undefined_section + && !bfd_is_com_section (S_GET_SEGMENT (fixP->fx_addsy)) + && TC_FIX_ADJUSTABLE(fixP))) + value -= S_GET_VALUE (fixP->fx_addsy); + + if (fixP->fx_pcrel) + value += fixP->fx_frag->fr_address + fixP->fx_where; + } + else + fixP->fx_done = 1; + + if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED) + { + const struct s390_operand *operand; + int opindex; + + opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED; + operand = &s390_operands[opindex]; + + if (fixP->fx_done) + { + /* Insert the fully resolved operand value. */ + s390_insert_operand (where, operand, (offsetT) value, + fixP->fx_file, fixP->fx_line); + return; + } + + /* Determine a BFD reloc value based on the operand information. + We are only prepared to turn a few of the operands into + relocs. */ + fixP->fx_offset = value; + if (operand->bits == 12 && operand->shift == 20) + { + fixP->fx_size = 2; + fixP->fx_where += 2; + fixP->fx_r_type = BFD_RELOC_390_12; + } + else if (operand->bits == 12 && operand->shift == 36) + { + fixP->fx_size = 2; + fixP->fx_where += 4; + fixP->fx_r_type = BFD_RELOC_390_12; + } + else if (operand->bits == 8 && operand->shift == 8) + { + fixP->fx_size = 1; + fixP->fx_where += 1; + fixP->fx_r_type = BFD_RELOC_8; + } + else if (operand->bits == 16 && operand->shift == 16) + { + fixP->fx_size = 2; + fixP->fx_where += 2; + if (operand->flags & S390_OPERAND_PCREL) + { + fixP->fx_r_type = BFD_RELOC_390_PC16DBL; + fixP->fx_offset += 2; + } + else + fixP->fx_r_type = BFD_RELOC_16; + } + else if (operand->bits == 32 && operand->shift == 16 + && (operand->flags & S390_OPERAND_PCREL)) + { + fixP->fx_size = 4; + fixP->fx_where += 2; + fixP->fx_offset += 2; + fixP->fx_r_type = BFD_RELOC_390_PC32DBL; + } + else + { + char *sfile; + unsigned int sline; + + /* Use expr_symbol_where to see if this is an expression + symbol. */ + if (expr_symbol_where (fixP->fx_addsy, &sfile, &sline)) + as_bad_where (fixP->fx_file, fixP->fx_line, + _("unresolved expression that must be resolved")); + else + as_bad_where (fixP->fx_file, fixP->fx_line, + _("unsupported relocation type")); + fixP->fx_done = 1; + return; + } + } + else + { + switch (fixP->fx_r_type) + { + case BFD_RELOC_8: + if (fixP->fx_pcrel) + abort (); + if (fixP->fx_done) + md_number_to_chars (where, value, 1); + break; + case BFD_RELOC_390_12: + case BFD_RELOC_390_GOT12: + if (fixP->fx_done) + { + unsigned short mop; + + mop = bfd_getb16 ((unsigned char *) where); + mop |= (unsigned short) (value & 0xfff); + bfd_putb16 ((bfd_vma) mop, (unsigned char *) where); + } + break; + + case BFD_RELOC_16: + case BFD_RELOC_GPREL16: + case BFD_RELOC_16_GOT_PCREL: + case BFD_RELOC_16_GOTOFF: + if (fixP->fx_pcrel) + as_bad_where (fixP->fx_file, fixP->fx_line, + "cannot emit PC relative %s relocation%s%s", + bfd_get_reloc_code_name (fixP->fx_r_type), + fixP->fx_addsy != NULL ? " against " : "", + (fixP->fx_addsy != NULL + ? S_GET_NAME (fixP->fx_addsy) + : "")); + if (fixP->fx_done) + md_number_to_chars (where, value, 2); + break; + case BFD_RELOC_390_GOT16: + if (fixP->fx_done) + md_number_to_chars (where, value, 2); + break; + case BFD_RELOC_390_PC16DBL: + case BFD_RELOC_390_PLT16DBL: + value += 2; + if (fixP->fx_done) + md_number_to_chars (where, (offsetT) value >> 1, 2); + break; + + case BFD_RELOC_32: + if (fixP->fx_pcrel) + fixP->fx_r_type = BFD_RELOC_32_PCREL; + else + fixP->fx_r_type = BFD_RELOC_32; + if (fixP->fx_done) + md_number_to_chars (where, value, 4); + break; + case BFD_RELOC_32_PCREL: + case BFD_RELOC_32_BASEREL: + fixP->fx_r_type = BFD_RELOC_32_PCREL; + if (fixP->fx_done) + md_number_to_chars (where, value, 4); + break; + case BFD_RELOC_32_GOT_PCREL: + case BFD_RELOC_390_PLT32: + if (fixP->fx_done) + md_number_to_chars (where, value, 4); + break; + case BFD_RELOC_390_PC32DBL: + case BFD_RELOC_390_PLT32DBL: + case BFD_RELOC_390_GOTPCDBL: + case BFD_RELOC_390_GOTENT: + value += 2; + if (fixP->fx_done) + md_number_to_chars (where, (offsetT) value >> 1, 4); + break; + + case BFD_RELOC_32_GOTOFF: + if (fixP->fx_done) + md_number_to_chars (where, value, sizeof (int)); + break; + + case BFD_RELOC_390_GOT64: + case BFD_RELOC_390_PLT64: + if (fixP->fx_done) + md_number_to_chars (where, value, 8); + break; + + case BFD_RELOC_64: + if (fixP->fx_pcrel) + fixP->fx_r_type = BFD_RELOC_64_PCREL; + else + fixP->fx_r_type = BFD_RELOC_64; + if (fixP->fx_done) + md_number_to_chars (where, value, 8); + break; + + case BFD_RELOC_64_PCREL: + fixP->fx_r_type = BFD_RELOC_64_PCREL; + if (fixP->fx_done) + md_number_to_chars (where, value, 8); + break; + + case BFD_RELOC_VTABLE_INHERIT: + case BFD_RELOC_VTABLE_ENTRY: + fixP->fx_done = 0; + return; + + default: + { + const char *reloc_name = bfd_get_reloc_code_name (fixP->fx_r_type); + + if (reloc_name != NULL) + fprintf (stderr, "Gas failure, reloc type %s\n", reloc_name); + else + fprintf (stderr, "Gas failure, reloc type #%i\n", fixP->fx_r_type); + fflush (stderr); + abort (); + } + } + + fixP->fx_offset = value; + } +} + +/* Generate a reloc for a fixup. */ + +arelent * +tc_gen_reloc (seg, fixp) + asection *seg ATTRIBUTE_UNUSED; + fixS *fixp; +{ + bfd_reloc_code_real_type code; + arelent *reloc; + + code = fixp->fx_r_type; + if (GOT_symbol && fixp->fx_addsy == GOT_symbol) + { + if ( (s390_arch_size == 32 && code == BFD_RELOC_32_PCREL) + || (s390_arch_size == 64 && code == BFD_RELOC_64_PCREL)) + code = BFD_RELOC_390_GOTPC; + if (code == BFD_RELOC_390_PC32DBL) + code = BFD_RELOC_390_GOTPCDBL; + } + + reloc = (arelent *) xmalloc (sizeof (arelent)); + reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); + *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); + reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; + reloc->howto = bfd_reloc_type_lookup (stdoutput, code); + if (reloc->howto == NULL) + { + as_bad_where (fixp->fx_file, fixp->fx_line, + _("cannot represent relocation type %s"), + bfd_get_reloc_code_name (code)); + /* Set howto to a garbage value so that we can keep going. */ + reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32); + assert (reloc->howto != NULL); + } + reloc->addend = fixp->fx_offset; + + return reloc; +} diff --git a/contrib/binutils/gas/config/tc-s390.h b/contrib/binutils/gas/config/tc-s390.h new file mode 100644 index 0000000..1837b1a --- /dev/null +++ b/contrib/binutils/gas/config/tc-s390.h @@ -0,0 +1,115 @@ +/* tc-s390.h -- Header file for tc-s390.c. + Copyright 2000, 2001 Free Software Foundation, Inc. + Written by Martin Schwidefsky (schwidefsky@de.ibm.com). + + This file is part of GAS, the GNU Assembler. + + GAS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GAS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GAS; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#define TC_S390 + +#ifdef ANSI_PROTOTYPES +struct fix; +#endif + +#ifndef BFD_ASSEMBLER + #error S390 support requires BFD_ASSEMBLER +#endif + +/* This expression evaluates to false if the relocation is for a local object + for which we still want to do the relocation at runtime. True if we + are willing to perform this relocation while building the .o file. + This is only used for pcrel relocations, so GOTOFF does not need to be + checked here. I am not sure if some of the others are ever used with + pcrel, but it is easier to be safe than sorry. */ + +#define TC_RELOC_RTSYM_LOC_FIXUP(FIX) \ + ((FIX)->fx_r_type != BFD_RELOC_390_GOTENT \ + && ((FIX)->fx_addsy == NULL \ + || (! S_IS_EXTERNAL ((FIX)->fx_addsy) \ + && ! S_IS_WEAK ((FIX)->fx_addsy) \ + && S_IS_DEFINED ((FIX)->fx_addsy) \ + && ! S_IS_COMMON ((FIX)->fx_addsy)))) + +#define TC_FORCE_RELOCATION(FIXP) tc_s390_force_relocation(FIXP) +extern int tc_s390_force_relocation PARAMS ((struct fix *)); + +#define tc_fix_adjustable(X) tc_s390_fix_adjustable(X) +extern int tc_s390_fix_adjustable PARAMS ((struct fix *)); + +#define TC_FIX_ADJUSTABLE(fixP) \ + (! symbol_used_in_reloc_p ((fixP)->fx_addsy) && tc_fix_adjustable (fixP)) + +/* The target BFD architecture. */ +#define TARGET_ARCH bfd_arch_s390 +extern enum bfd_architecture s390_arch PARAMS ((void)); + +/* The target BFD format. */ +#define TARGET_FORMAT s390_target_format() +extern const char * s390_target_format PARAMS ((void)); + +/* Set the endianness we are using. */ +#define TARGET_BYTES_BIG_ENDIAN 1 + +/* Whether or not the target is big endian */ +extern int target_big_endian; + +/* Permit temporary numeric labels. */ +#define LOCAL_LABELS_FB 1 + +/* $ is used to refer to the current location. */ +/* #define DOLLAR_DOT */ + +/* We need to be able to make relocations involving the difference of + two symbols. This includes the difference of two symbols when + one of them is undefined (this comes up in PIC code generation). + */ +#define UNDEFINED_DIFFERENCE_OK + +/* foo-. gets turned into PC relative relocs */ +#define DIFF_EXPR_OK + +/* We don't need to handle .word strangely. */ +#define WORKING_DOT_WORD + +#define md_number_to_chars number_to_chars_bigendian + +#define md_do_align(n, fill, len, max, around) \ +if ((n) && !need_pass_2 && (fill == 0) && \ + (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0) { \ + char *p; \ + p = frag_var (rs_align_code, 15, 1, (relax_substateT) max, \ + (symbolS *) 0, (offsetT) (n), (char *) 0); \ + *p = 0x07; \ + goto around; \ +} + +extern void s390_align_code PARAMS ((fragS *, int)); + +#define HANDLE_ALIGN(fragP) \ +if (fragP->fr_type == rs_align_code) \ + s390_align_code (fragP, (fragP->fr_next->fr_address \ + - fragP->fr_address \ + - fragP->fr_fix)); + +/* call md_pcrel_from_section, not md_pcrel_from */ +#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC) +extern long md_pcrel_from_section PARAMS ((struct fix *, segT)); + +#define md_operand(x) + +extern void s390_md_end PARAMS ((void)); +#define md_end() s390_md_end () diff --git a/contrib/binutils/gas/doc/as.1 b/contrib/binutils/gas/doc/as.1 index 5f0971c..99d3284 100644 --- a/contrib/binutils/gas/doc/as.1 +++ b/contrib/binutils/gas/doc/as.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "AS 1" -.TH AS 1 "2002-03-08" "binutils-2.12" "GNU Development Tools" +.TH AS 1 "2002-05-14" "binutils-2.12.1" "GNU Development Tools" .UC .SH "NAME" \&\s-1AS\s0 \- the portable \s-1GNU\s0 assembler. diff --git a/contrib/binutils/gas/stabs.c b/contrib/binutils/gas/stabs.c index 60b03c4..c692c2c 100644 --- a/contrib/binutils/gas/stabs.c +++ b/contrib/binutils/gas/stabs.c @@ -240,6 +240,14 @@ s_stab_generic (what, stab_secname, stabstr_secname) other = longint; desc = get_absolute_expression (); + + if ((desc > 0xffff) || (desc < -0x8000)) + /* This could happen for example with a source file with a huge + number of lines. The only cure is to use a different debug + format, probably DWARF. */ + as_warn (_(".stab%c: description field '%x' too big, try a different debug format"), + what, desc); + if (what == 's' || what == 'n') { if (*input_line_pointer != ',') diff --git a/contrib/binutils/gas/symbols.c b/contrib/binutils/gas/symbols.c index 5dd3040..5a55fca 100644 --- a/contrib/binutils/gas/symbols.c +++ b/contrib/binutils/gas/symbols.c @@ -986,6 +986,7 @@ resolve_symbol_value (symp) case O_bit_not: case O_logical_not: left = resolve_symbol_value (add_symbol); + seg_left = S_GET_SEGMENT (add_symbol); if (op == O_uminus) left = -left; @@ -996,7 +997,7 @@ resolve_symbol_value (symp) final_val += left + symp->sy_frag->fr_address; if (final_seg == expr_section || final_seg == undefined_section) - final_seg = absolute_section; + final_seg = seg_left; resolved = symbol_resolved_p (add_symbol); break; @@ -1062,15 +1063,19 @@ resolve_symbol_value (symp) Don't emit messages unless we're finalizing the symbol value, otherwise we may get the same message multiple times. */ - if (op != O_eq && op != O_ne - && (seg_left != absolute_section - || seg_right != absolute_section) - && ((op != O_subtract - && op != O_lt && op != O_le && op != O_ge && op != O_gt) - || seg_left != seg_right - || (seg_left == undefined_section - && add_symbol != op_symbol)) - && finalize_syms) + if ((op == O_eq || op == O_ne) + || ((op == O_subtract + || op == O_lt || op == O_le || op == O_ge || op == O_gt) + && seg_left == seg_right + && (seg_left != undefined_section + || add_symbol == op_symbol)) + || (seg_left == absolute_section + && seg_right == absolute_section)) + { + if (final_seg == expr_section || final_seg == undefined_section) + final_seg = absolute_section; + } + else if (finalize_syms) { char *file; unsigned int line; @@ -1105,6 +1110,9 @@ resolve_symbol_value (symp) as_bad (_("invalid section for operation setting `%s'"), S_GET_NAME (symp)); } + /* Prevent the error propagating. */ + if (final_seg == expr_section || final_seg == undefined_section) + final_seg = absolute_section; } /* Check for division by zero. */ @@ -1160,7 +1168,15 @@ resolve_symbol_value (symp) final_val += symp->sy_frag->fr_address + left; if (final_seg == expr_section || final_seg == undefined_section) - final_seg = absolute_section; + { + if (seg_left == undefined_section + || seg_right == undefined_section) + final_seg = undefined_section; + else if (seg_left == absolute_section) + final_seg = seg_right; + else + final_seg = seg_left; + } resolved = (symbol_resolved_p (add_symbol) && symbol_resolved_p (op_symbol)); break; diff --git a/contrib/binutils/include/elf/ChangeLog b/contrib/binutils/include/elf/ChangeLog index e70f7fd..20e8096 100644 --- a/contrib/binutils/include/elf/ChangeLog +++ b/contrib/binutils/include/elf/ChangeLog @@ -1,3 +1,9 @@ +2002-04-2 Alan Modra <amodra@bigpond.net.au> + + Merge from mainline. + 2002-04-24 Elena Zannoni <ezannoni@redhat.com> + * dwarf2.h: Add DW_AT_GNU_vector. + 2002-02-13 Matt Fredette <fredette@netbsd.org> * m68k.h (EF_M68000): Define. diff --git a/contrib/binutils/include/elf/dwarf2.h b/contrib/binutils/include/elf/dwarf2.h index 53eb655..750a720 100644 --- a/contrib/binutils/include/elf/dwarf2.h +++ b/contrib/binutils/include/elf/dwarf2.h @@ -328,6 +328,7 @@ enum dwarf_attribute DW_AT_src_coords = 0x2104, DW_AT_body_begin = 0x2105, DW_AT_body_end = 0x2106, + DW_AT_GNU_vector = 0x2107, /* VMS Extensions. */ DW_AT_VMS_rtnbeg_pd_address = 0x2201 }; diff --git a/contrib/binutils/include/opcode/ChangeLog b/contrib/binutils/include/opcode/ChangeLog index 9d143c7..d7b0582 100644 --- a/contrib/binutils/include/opcode/ChangeLog +++ b/contrib/binutils/include/opcode/ChangeLog @@ -1,3 +1,10 @@ +2002-04-27 Alan Modra <amodra@bigpond.net.au> + + Merge from mainline + 2002-04-11 Alan Modra <amodra@bigpond.net.au> + * i386.h: Add intel mode cmpsd and movsd. + Put them before SSE2 insns, so that rep prefix works. + 2002-02-25 Alan Modra <amodra@bigpond.net.au> * ppc.h (PPC_OPCODE_POWER4, PPC_OPCODE_NOPOWER4): Define. diff --git a/contrib/binutils/include/opcode/i386.h b/contrib/binutils/include/opcode/i386.h index 43d7208..0171f62 100644 --- a/contrib/binutils/include/opcode/i386.h +++ b/contrib/binutils/include/opcode/i386.h @@ -1231,6 +1231,9 @@ static const template i386_optab[] = { {"cmpunordpd",2, 0x660fc2, 3, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LLongMem, RegXMM, 0 } }, {"cmpunordsd",2, 0xf20fc2, 3, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LongMem, RegXMM, 0 } }, {"cmppd", 3, 0x660fc2, X, CpuSSE2, FP|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } }, +/* Intel mode string compare. */ +{"cmpsd", 0, 0xa7, X, 0, NoSuf|Size32|IsString, { 0, 0, 0} }, +{"cmpsd", 2, 0xa7, X, 0, NoSuf|Size32|IsString, { AnyMem, AnyMem|EsSeg, 0} }, {"cmpsd", 3, 0xf20fc2, X, CpuSSE2, FP|Modrm, { Imm8, RegXMM|LongMem, RegXMM } }, {"comisd", 2, 0x660f2f, X, CpuSSE2, FP|Modrm, { RegXMM|LongMem, RegXMM, 0 } }, {"cvtpi2pd", 2, 0x660f2a, X, CpuSSE2, FP|Modrm, { RegMMX|LLongMem, RegXMM, 0 } }, @@ -1249,6 +1252,9 @@ static const template i386_optab[] = { {"movlpd", 2, 0x660f13, X, CpuSSE2, FP|Modrm, { RegXMM, LLongMem, 0 } }, {"movmskpd", 2, 0x660f50, X, CpuSSE2, lq_Suf|IgnoreSize|Modrm, { RegXMM|InvMem, Reg32|Reg64, 0 } }, {"movntpd", 2, 0x660f2b, X, CpuSSE2, FP|Modrm, { RegXMM, LLongMem, 0 } }, +/* Intel mode string move. */ +{"movsd", 0, 0xa5, X, 0, NoSuf|Size32|IsString, { 0, 0, 0} }, +{"movsd", 2, 0xa5, X, 0, NoSuf|Size32|IsString, { AnyMem, AnyMem|EsSeg, 0} }, {"movsd", 2, 0xf20f10, X, CpuSSE2, FP|Modrm, { RegXMM|LongMem, RegXMM, 0 } }, {"movsd", 2, 0xf20f11, X, CpuSSE2, FP|Modrm, { RegXMM, RegXMM|LongMem, 0 } }, {"movupd", 2, 0x660f10, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, diff --git a/contrib/binutils/include/opcode/s390.h b/contrib/binutils/include/opcode/s390.h new file mode 100644 index 0000000..1a42be6 --- /dev/null +++ b/contrib/binutils/include/opcode/s390.h @@ -0,0 +1,130 @@ +/* s390.h -- Header file for S390 opcode table + Copyright 2000, 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef S390_H +#define S390_H + +/* List of instruction sets variations. */ + +enum s390_opcode_arch_val + { + S390_OPCODE_ESA = 0, + S390_OPCODE_ESAME + }; + +/* The opcode table is an array of struct s390_opcode. */ + +struct s390_opcode + { + /* The opcode name. */ + const char * name; + + /* The opcode itself. Those bits which will be filled in with + operands are zeroes. */ + unsigned char opcode[6]; + + /* The opcode mask. This is used by the disassembler. This is a + mask containing ones indicating those bits which must match the + opcode field, and zeroes indicating those bits which need not + match (and are presumably filled in by operands). */ + unsigned char mask[6]; + + /* The opcode length in bytes. */ + int oplen; + + /* An array of operand codes. Each code is an index into the + operand table. They appear in the order which the operands must + appear in assembly code, and are terminated by a zero. */ + unsigned char operands[6]; + + /* Bitmask of architectures this opcode is available for. */ + unsigned int architecture; + }; + +/* The table itself is sorted by major opcode number, and is otherwise + in the order in which the disassembler should consider + instructions. */ +extern const struct s390_opcode s390_opcodes[]; +extern const int s390_num_opcodes; + +/* A opcode format table for the .insn pseudo mnemonic. */ +extern const struct s390_opcode s390_opformats[]; +extern const int s390_num_opformats; + +/* Values defined for the flags field of a struct powerpc_opcode. */ + +/* The operands table is an array of struct s390_operand. */ + +struct s390_operand + { + /* The number of bits in the operand. */ + int bits; + + /* How far the operand is left shifted in the instruction. */ + int shift; + + /* One bit syntax flags. */ + unsigned long flags; + }; + +/* Elements in the table are retrieved by indexing with values from + the operands field of the powerpc_opcodes table. */ + +extern const struct s390_operand s390_operands[]; + +/* Values defined for the flags field of a struct s390_operand. */ + +/* This operand names a register. The disassembler uses this to print + register names with a leading 'r'. */ +#define S390_OPERAND_GPR 0x1 + +/* This operand names a floating point register. The disassembler + prints these with a leading 'f'. */ +#define S390_OPERAND_FPR 0x2 + +/* This operand names an access register. The disassembler + prints these with a leading 'a'. */ +#define S390_OPERAND_AR 0x4 + +/* This operand names a control register. The disassembler + prints these with a leading 'c'. */ +#define S390_OPERAND_CR 0x8 + +/* This operand is a displacement. */ +#define S390_OPERAND_DISP 0x10 + +/* This operand names a base register. */ +#define S390_OPERAND_BASE 0x20 + +/* This operand names an index register, it can be skipped. */ +#define S390_OPERAND_INDEX 0x40 + +/* This operand is a relative branch displacement. The disassembler + prints these symbolically if possible. */ +#define S390_OPERAND_PCREL 0x80 + +/* This operand takes signed values. */ +#define S390_OPERAND_SIGNED 0x100 + +/* This operand is a length. */ +#define S390_OPERAND_LENGTH 0x200 + +#endif /* S390_H */ diff --git a/contrib/binutils/ld/ChangeLog b/contrib/binutils/ld/ChangeLog index 0848b49..6f6e0d3f 100644 --- a/contrib/binutils/ld/ChangeLog +++ b/contrib/binutils/ld/ChangeLog @@ -1,3 +1,39 @@ +2002-05-09 Alan Modra <amodra@bigpond.net.au> + + Merge from mainline. + 2002-05-02 Alan Modra <amodra@bigpond.net.au> + * emultempl/ppc64elf.em (gld${EMULATION_NAME}_after_allocation): + Adjust for ppc64_elf_set_toc change. #include libbfd.h. + + 2002-04-28 Alan Modra <amodra@bigpond.net.au> + * Makefile.am (mpw): New maintainer mode rule to make mpw-*.c files. + * Makefile.in: Regenerate. + * mpw-elfmips.c: Delete. + * mpw-eppcmac.c: Delete. + * mpw-esh.c: Delete. + * mpw-idtmips.c: Delete. + +2002-04-27 Alan Modra <amodra@bigpond.net.au> + + Merge from mainline + 2002-04-08 Alan Modra <amodra@bigpond.net.au> + * ldlang.c (lang_size_sections): Don't complain about + SEC_NEVER_LOAD sections having no memory region specified. + * ld.texinfo (Format Commands <OUTPUT_FORMAT>): Typo fix. + + 2002-04-07 matthew green <mrg@redhat.com> + * ld/configure.host (*-*-netbsd*): Add support for NetBSD/ELF. + + 2002-02-19 Martin Schwidefsky <schwidefsky@de.ibm.com> + * emulparams/elf64_s390.sh (ARCH): Change to "s390:64-bit". + * emulparams/elf_s390.sh (ARCH): Change to "s390:31-bit". + +2002-04-11 Nick Clifton <nickc@cambridge.redhat.com> + + * emultempl/armelf.em (PARSE_AND_LIST_SHORTOPTS): Add 'n' in order + to prevent "-n" from being taken as an abbreviation for + "--no-pipeline-knowledge". + 2002-04-04 Alan Modra <amodra@bigpond.net.au> * dep-in.sed: Cope with absolute paths. diff --git a/contrib/binutils/ld/Makefile.am b/contrib/binutils/ld/Makefile.am index 3959ac5..595228a 100644 --- a/contrib/binutils/ld/Makefile.am +++ b/contrib/binutils/ld/Makefile.am @@ -1196,6 +1196,29 @@ dep-am: DEP .PHONY: dep dep-in dep-am +@MAINT@.PHONY: mpw +@MAINT@mpw: $(srcdir)/mpw-ei386go32.c $(srcdir)/mpw-elfmips.c \ +@MAINT@ $(srcdir)/mpw-em68kcoff.c $(srcdir)/mpw-eppcmac.c \ +@MAINT@ $(srcdir)/mpw-esh.c $(srcdir)/mpw-idtmips.c +@MAINT@ +@MAINT@$(srcdir)/mpw-ei386go32.c: ei386go32.c +@MAINT@ $(srcdir)/../move-if-change $< $@ +@MAINT@ +@MAINT@$(srcdir)/mpw-elfmips.c: eelf32ebmip.c +@MAINT@ $(srcdir)/../move-if-change $< $@ +@MAINT@ +@MAINT@$(srcdir)/mpw-em68kcoff.c: em68kcoff.c +@MAINT@ $(srcdir)/../move-if-change $< $@ +@MAINT@ +@MAINT@$(srcdir)/mpw-eppcmac.c: eppcmacos.c +@MAINT@ $(srcdir)/../move-if-change $< $@ +@MAINT@ +@MAINT@$(srcdir)/mpw-esh.c: esh.c +@MAINT@ $(srcdir)/../move-if-change $< $@ +@MAINT@ +@MAINT@$(srcdir)/mpw-idtmips.c: emipsidt.c +@MAINT@ $(srcdir)/../move-if-change $< $@ + # What appears below is generated by a hacked mkdep using gcc -MM. # DO NOT DELETE THIS LINE -- mkdep uses it. diff --git a/contrib/binutils/ld/Makefile.in b/contrib/binutils/ld/Makefile.in index 1521f5e..3a652fe 100644 --- a/contrib/binutils/ld/Makefile.in +++ b/contrib/binutils/ld/Makefile.in @@ -1891,6 +1891,29 @@ dep-am: DEP .PHONY: dep dep-in dep-am +@MAINT@.PHONY: mpw +@MAINT@mpw: $(srcdir)/mpw-ei386go32.c $(srcdir)/mpw-elfmips.c \ +@MAINT@ $(srcdir)/mpw-em68kcoff.c $(srcdir)/mpw-eppcmac.c \ +@MAINT@ $(srcdir)/mpw-esh.c $(srcdir)/mpw-idtmips.c +@MAINT@ +@MAINT@$(srcdir)/mpw-ei386go32.c: ei386go32.c +@MAINT@ $(srcdir)/../move-if-change $< $@ +@MAINT@ +@MAINT@$(srcdir)/mpw-elfmips.c: eelf32ebmip.c +@MAINT@ $(srcdir)/../move-if-change $< $@ +@MAINT@ +@MAINT@$(srcdir)/mpw-em68kcoff.c: em68kcoff.c +@MAINT@ $(srcdir)/../move-if-change $< $@ +@MAINT@ +@MAINT@$(srcdir)/mpw-eppcmac.c: eppcmacos.c +@MAINT@ $(srcdir)/../move-if-change $< $@ +@MAINT@ +@MAINT@$(srcdir)/mpw-esh.c: esh.c +@MAINT@ $(srcdir)/../move-if-change $< $@ +@MAINT@ +@MAINT@$(srcdir)/mpw-idtmips.c: emipsidt.c +@MAINT@ $(srcdir)/../move-if-change $< $@ + # What appears below is generated by a hacked mkdep using gcc -MM. # DO NOT DELETE THIS LINE -- mkdep uses it. diff --git a/contrib/binutils/ld/configure.host b/contrib/binutils/ld/configure.host index 56a950c..65c2fc7 100644 --- a/contrib/binutils/ld/configure.host +++ b/contrib/binutils/ld/configure.host @@ -223,6 +223,13 @@ x86_64-*-linux-gnu*) *-*-linux*) ;; +*-*-netbsd*) + NATIVE_LIB_DIRS=/usr/lib + # NetBSD typically does not use the GCC crtstuff, so ignore it. + HOSTING_CRT0='-dynamic-linker /usr/libexec/ld.elf_so /usr/lib/crt0.o /usr/lib/crtbegin.o' + HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else ${CC} -print-libgcc-file-name; fi` -lc `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else ${CC} -print-libgcc-file-name; fi` /usr/lib/crtend.o' + ;; + alpha*-*-*) HOSTING_CRT0=/usr/ccs/lib/crt0.o NATIVE_LIB_DIRS=/usr/ccs/lib diff --git a/contrib/binutils/ld/emulparams/elf64_s390.sh b/contrib/binutils/ld/emulparams/elf64_s390.sh new file mode 100644 index 0000000..8416c89 --- /dev/null +++ b/contrib/binutils/ld/emulparams/elf64_s390.sh @@ -0,0 +1,11 @@ +SCRIPT_NAME=elf +ELFSIZE=64 +OUTPUT_FORMAT="elf64-s390" +TEXT_START_ADDR=0x80000000 +MAXPAGESIZE=0x1000 +NONPAGED_TEXT_START_ADDR=0x80000000 +ARCH="s390:64-bit" +MACHINE= +NOP=0x07070707 +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes diff --git a/contrib/binutils/ld/emulparams/elf_s390.sh b/contrib/binutils/ld/emulparams/elf_s390.sh new file mode 100644 index 0000000..2804ace --- /dev/null +++ b/contrib/binutils/ld/emulparams/elf_s390.sh @@ -0,0 +1,10 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-s390" +TEXT_START_ADDR=0x00400000 +MAXPAGESIZE=0x1000 +NONPAGED_TEXT_START_ADDR=0x00400000 +ARCH="s390:31-bit" +MACHINE= +NOP=0x07070707 +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes diff --git a/contrib/binutils/ld/emultempl/armelf.em b/contrib/binutils/ld/emultempl/armelf.em index c570486..78a0c35 100644 --- a/contrib/binutils/ld/emultempl/armelf.em +++ b/contrib/binutils/ld/emultempl/armelf.em @@ -156,7 +156,12 @@ PARSE_AND_LIST_PROLOGUE=' #define OPTION_THUMB_ENTRY 301 ' -PARSE_AND_LIST_SHORTOPTS=p +# Note we add 'n' to the short option list in order to prevent +# getopt_long_only from thinking that -n is a unique abbreviation +# for --no-pipeline-knowledge. There is no case to handle 'n' here +# however, so instead it will be passed back to parse_args() in +# lexsup.c where it will be handled. +PARSE_AND_LIST_SHORTOPTS=pn PARSE_AND_LIST_LONGOPTS=' { "no-pipeline-knowledge", no_argument, NULL, '\'p\''}, diff --git a/contrib/binutils/ld/emultempl/ppc64elf.em b/contrib/binutils/ld/emultempl/ppc64elf.em index 27b20ce..2128fe7 100644 --- a/contrib/binutils/ld/emultempl/ppc64elf.em +++ b/contrib/binutils/ld/emultempl/ppc64elf.em @@ -23,6 +23,7 @@ # cat >>e${EMULATION_NAME}.c <<EOF +#include "libbfd.h" #include "elf64-ppc.h" static int need_laying_out = 0; @@ -35,8 +36,8 @@ static void gld${EMULATION_NAME}_finish PARAMS ((void)); static void gld${EMULATION_NAME}_after_allocation () { - if (!ppc64_elf_set_toc (output_bfd, &link_info)) - einfo ("%X%P: can not set TOC base: %E\n"); + if (!link_info.relocateable) + _bfd_set_gp_value (output_bfd, ppc64_elf_toc (output_bfd)); } /* Final emulation specific call. PowerPC64 has 24 byte .plt entries, diff --git a/contrib/binutils/ld/ld.1 b/contrib/binutils/ld/ld.1 index 1c8f858..272a133 100644 --- a/contrib/binutils/ld/ld.1 +++ b/contrib/binutils/ld/ld.1 @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "LD 1" -.TH LD 1 "2002-03-08" "binutils-2.12" "GNU Development Tools" +.TH LD 1 "2002-05-11" "binutils-2.12.1" "GNU Development Tools" .UC .SH "NAME" ld \- Using \s-1LD\s0, the \s-1GNU\s0 linker diff --git a/contrib/binutils/ld/ld.texinfo b/contrib/binutils/ld/ld.texinfo index 936bf39..dee9874 100644 --- a/contrib/binutils/ld/ld.texinfo +++ b/contrib/binutils/ld/ld.texinfo @@ -2277,7 +2277,7 @@ A couple of linker script commands deal with object file formats. @cindex output file format in linker script The @code{OUTPUT_FORMAT} command names the BFD format to use for the output file (@pxref{BFD}). Using @code{OUTPUT_FORMAT(@var{bfdname})} is -exactly like using @samp{-oformat @var{bfdname}} on the command line +exactly like using @samp{--oformat @var{bfdname}} on the command line (@pxref{Options,,Command Line Options}). If both are used, the command line option takes precedence. diff --git a/contrib/binutils/ld/ldlang.c b/contrib/binutils/ld/ldlang.c index 5257547..414a034 100644 --- a/contrib/binutils/ld/ldlang.c +++ b/contrib/binutils/ld/ldlang.c @@ -2914,6 +2914,8 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) defined, issue a warning. */ if ((bfd_get_section_flags (output_bfd, os->bfd_section) & (SEC_ALLOC | SEC_LOAD)) != 0 + && (bfd_get_section_flags (output_bfd, os->bfd_section) + & SEC_NEVER_LOAD) == 0 && ! link_info.relocateable && strcmp (os->region->name, "*default*") == 0 && lang_memory_region_list != NULL diff --git a/contrib/binutils/opcodes/ChangeLog b/contrib/binutils/opcodes/ChangeLog index 1a37508..c29dd31 100644 --- a/contrib/binutils/opcodes/ChangeLog +++ b/contrib/binutils/opcodes/ChangeLog @@ -1,3 +1,31 @@ +2002-05-09 Anton Blanchard <anton@samba.org> + + * ppc-opc.c: Add "tlbiel" for POWER4. + +2002-05-09 Alan Modra <amodra@bigpond.net.au> + + Merge from mainline. + 2002-05-01 Alan Modra <amodra@bigpond.net.au> + * ppc-opc.c: Add "tlbsx." and "tlbsxe." for booke. + + 2002-04-17 matthew green <mrg@redhat.com> + * ppc-opc.c (powerpc_opcode): Fix dssall operand list. + +2002-04-29 Chris Demetriou <cgd@broadcom.com> + + Merge from mainline: + 2002-03-06 Chris Demetriou <cgd@broadcom.com> + * mips-opc.c (mips_builtin_opcodes): Mark "pref" as being + present on I4. + + Merge from mainline: + 2002-03-06 Chris Demetriou <cgd@broadcom.com> + * mips-opc.c (mips_builtin_opcodes): Add "movn.ps" and "movz.ps". + + Merge from mainline: + 2002-03-15 Chris Demetriou <cgd@broadcom.com> + * mips-dis.c (is_newabi): Fix ABI decoding. + 2002-04-04 Alan Modra <amodra@bigpond.net.au> * dep-in.sed: Cope with absolute paths. diff --git a/contrib/binutils/opcodes/ppc-opc.c b/contrib/binutils/opcodes/ppc-opc.c index c868ccc..70167f7 100644 --- a/contrib/binutils/opcodes/ppc-opc.c +++ b/contrib/binutils/opcodes/ppc-opc.c @@ -3065,6 +3065,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "addo.", XO(31,266,1,1), XO_MASK, PPCCOM, { RT, RA, RB } }, { "caxo.", XO(31,266,1,1), XO_MASK, PWRCOM, { RT, RA, RB } }, +{ "tlbiel", X(31,274), XRTRA_MASK, POWER4, { RB } }, + { "mfapidi", X(31,275), X_MASK, BOOKE, { RT, RA } }, { "lscbx", XRC(31,277,0), X_MASK, M601, { RT, RA, RB } }, @@ -3672,7 +3674,7 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "rac", X(31,818), X_MASK, PWRCOM, { RT, RA, RB } }, { "dss", XDSS(31,822,0), XDSS_MASK, PPCVEC, { STRM } }, -{ "dssall", XDSS(31,822,1), XDSS_MASK, PPCVEC, { STRM } }, +{ "dssall", XDSS(31,822,1), XDSS_MASK, PPCVEC, { 0 } }, { "srawi", XRC(31,824,0), X_MASK, PPCCOM, { RA, RS, SH } }, { "srai", XRC(31,824,0), X_MASK, PWRCOM, { RA, RS, SH } }, @@ -3688,7 +3690,9 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "tlbsx.", XRC(31,914,1), X_MASK, PPC403, { RT, RA, RB } }, { "tlbsx", XRC(31,914,0), X_MASK, BOOKE, { RA, RB } }, +{ "tlbsx.", XRC(31,914,1), X_MASK, BOOKE, { RA, RB } }, { "tlbsxe", XRC(31,915,0), X_MASK, BOOKE, { RA, RB } }, +{ "tlbsxe.", XRC(31,915,1), X_MASK, BOOKE, { RA, RB } }, { "slbmfee", X(31,915), XRA_MASK, PPC64, { RT, RB } }, diff --git a/contrib/binutils/opcodes/s390-dis.c b/contrib/binutils/opcodes/s390-dis.c new file mode 100644 index 0000000..8745a89 --- /dev/null +++ b/contrib/binutils/opcodes/s390-dis.c @@ -0,0 +1,257 @@ +/* s390-dis.c -- Disassemble S390 instructions + Copyright 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + + This file is part of GDB, GAS and the GNU binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include <stdio.h> +#include "ansidecl.h" +#include "sysdep.h" +#include "dis-asm.h" +#include "opcode/s390.h" + +static int init_flag = 0; +static int opc_index[256]; +static int current_arch_mask = 0; + +static void init_disasm PARAMS ((struct disassemble_info *)); +static unsigned int s390_extract_operand + PARAMS ((unsigned char *, const struct s390_operand *)); + +/* Set up index table for first opcode byte. */ + +static void +init_disasm (info) + struct disassemble_info *info; +{ + const struct s390_opcode *opcode; + const struct s390_opcode *opcode_end; + + memset (opc_index, 0, sizeof (opc_index)); + opcode_end = s390_opcodes + s390_num_opcodes; + for (opcode = s390_opcodes; opcode < opcode_end; opcode++) + { + opc_index[(int) opcode->opcode[0]] = opcode - s390_opcodes; + while ((opcode < opcode_end) && + (opcode[1].opcode[0] == opcode->opcode[0])) + opcode++; + } + switch (info->mach) + { + case bfd_mach_s390_31: + current_arch_mask = 1 << S390_OPCODE_ESA; + break; + case bfd_mach_s390_64: + current_arch_mask = 1 << S390_OPCODE_ESAME; + break; + default: + abort (); + } + init_flag = 1; +} + +/* Extracts an operand value from an instruction. */ + +static inline unsigned int +s390_extract_operand (insn, operand) + unsigned char *insn; + const struct s390_operand *operand; +{ + unsigned int val; + int bits; + + /* Extract fragments of the operand byte for byte. */ + insn += operand->shift / 8; + bits = (operand->shift & 7) + operand->bits; + val = 0; + do + { + val <<= 8; + val |= (unsigned int) *insn++; + bits -= 8; + } + while (bits > 0); + val >>= -bits; + val &= ((1U << (operand->bits - 1)) << 1) - 1; + + /* Sign extend value if the operand is signed or pc relative. */ + if ((operand->flags & (S390_OPERAND_SIGNED | S390_OPERAND_PCREL)) + && (val & (1U << (operand->bits - 1)))) + val |= (-1U << (operand->bits - 1)) << 1; + + /* Double value if the operand is pc relative. */ + if (operand->flags & S390_OPERAND_PCREL) + val <<= 1; + + /* Length x in an instructions has real length x+1. */ + if (operand->flags & S390_OPERAND_LENGTH) + val++; + return val; +} + +/* Print a S390 instruction. */ + +int +print_insn_s390 (memaddr, info) + bfd_vma memaddr; + struct disassemble_info *info; +{ + bfd_byte buffer[6]; + const struct s390_opcode *opcode; + const struct s390_opcode *opcode_end; + unsigned int value; + int status, opsize, bufsize; + char separator; + + if (init_flag == 0) + init_disasm (info); + + /* The output looks better if we put 6 bytes on a line. */ + info->bytes_per_line = 6; + + /* Every S390 instruction is max 6 bytes long. */ + memset (buffer, 0, 6); + status = (*info->read_memory_func) (memaddr, buffer, 6, info); + if (status != 0) + { + for (bufsize = 0; bufsize < 6; bufsize++) + if ((*info->read_memory_func) (memaddr, buffer, bufsize + 1, info) != 0) + break; + if (bufsize <= 0) + { + (*info->memory_error_func) (status, memaddr, info); + return -1; + } + /* Opsize calculation looks strange but it works + 00xxxxxx -> 2 bytes, 01xxxxxx/10xxxxxx -> 4 bytes, + 11xxxxxx -> 6 bytes. */ + opsize = ((((buffer[0] >> 6) + 1) >> 1) + 1) << 1; + status = opsize > bufsize; + } + else + { + bufsize = 6; + opsize = ((((buffer[0] >> 6) + 1) >> 1) + 1) << 1; + } + + if (status == 0) + { + /* Find the first match in the opcode table. */ + opcode_end = s390_opcodes + s390_num_opcodes; + for (opcode = s390_opcodes + opc_index[(int) buffer[0]]; + (opcode < opcode_end) && (buffer[0] == opcode->opcode[0]); + opcode++) + { + const struct s390_operand *operand; + const unsigned char *opindex; + + /* Check architecture. */ + if (!(opcode->architecture & current_arch_mask)) + continue; + /* Check signature of the opcode. */ + if ((buffer[1] & opcode->mask[1]) != opcode->opcode[1] + || (buffer[2] & opcode->mask[2]) != opcode->opcode[2] + || (buffer[3] & opcode->mask[3]) != opcode->opcode[3] + || (buffer[4] & opcode->mask[4]) != opcode->opcode[4] + || (buffer[5] & opcode->mask[5]) != opcode->opcode[5]) + continue; + + /* The instruction is valid. */ + if (opcode->operands[0] != 0) + (*info->fprintf_func) (info->stream, "%s\t", opcode->name); + else + (*info->fprintf_func) (info->stream, "%s", opcode->name); + + /* Extract the operands. */ + separator = 0; + for (opindex = opcode->operands; *opindex != 0; opindex++) + { + unsigned int value; + + operand = s390_operands + *opindex; + value = s390_extract_operand (buffer, operand); + + if ((operand->flags & S390_OPERAND_INDEX) && value == 0) + continue; + if ((operand->flags & S390_OPERAND_BASE) && + value == 0 && separator == '(') + { + separator = ','; + continue; + } + + if (separator) + (*info->fprintf_func) (info->stream, "%c", separator); + + if (operand->flags & S390_OPERAND_GPR) + (*info->fprintf_func) (info->stream, "%%r%i", value); + else if (operand->flags & S390_OPERAND_FPR) + (*info->fprintf_func) (info->stream, "%%f%i", value); + else if (operand->flags & S390_OPERAND_AR) + (*info->fprintf_func) (info->stream, "%%a%i", value); + else if (operand->flags & S390_OPERAND_CR) + (*info->fprintf_func) (info->stream, "%%c%i", value); + else if (operand->flags & S390_OPERAND_PCREL) + (*info->print_address_func) (memaddr + (int) value, info); + else if (operand->flags & S390_OPERAND_SIGNED) + (*info->fprintf_func) (info->stream, "%i", (int) value); + else + (*info->fprintf_func) (info->stream, "%i", value); + + if (operand->flags & S390_OPERAND_DISP) + { + separator = '('; + } + else if (operand->flags & S390_OPERAND_BASE) + { + (*info->fprintf_func) (info->stream, ")"); + separator = ','; + } + else + separator = ','; + } + + /* Found instruction, printed it, return its size. */ + return opsize; + } + /* No matching instruction found, fall through to hex print. */ + } + + if (bufsize >= 4) + { + value = (unsigned int) buffer[0]; + value = (value << 8) + (unsigned int) buffer[1]; + value = (value << 8) + (unsigned int) buffer[2]; + value = (value << 8) + (unsigned int) buffer[3]; + (*info->fprintf_func) (info->stream, ".long\t0x%08x", value); + return 4; + } + else if (bufsize >= 2) + { + value = (unsigned int) buffer[0]; + value = (value << 8) + (unsigned int) buffer[1]; + (*info->fprintf_func) (info->stream, ".short\t0x%04x", value); + return 2; + } + else + { + value = (unsigned int) buffer[0]; + (*info->fprintf_func) (info->stream, ".byte\t0x%02x", value); + return 1; + } +} diff --git a/contrib/binutils/opcodes/s390-mkopc.c b/contrib/binutils/opcodes/s390-mkopc.c new file mode 100644 index 0000000..d79ff81 --- /dev/null +++ b/contrib/binutils/opcodes/s390-mkopc.c @@ -0,0 +1,190 @@ +/* s390-mkopc.c -- Generates opcode table out of s390-opc.txt + Copyright 2000, 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + + This file is part of GDB, GAS, and the GNU binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* ARCHBITS_ESA and ARCH_ESAME correspond to the bit numbers defined + by s390_opcode_arch_val in include/opcode/s390.h: + ARCHBITS_ESAONLY = (1<<S390_OPCODE_ESA) + ARCHBITS_ESA = (1<<S390_OPCODE_ESA) + (1<<S390_OPCODE_ESAME) + ARCHBITS_ESA = (1<<S390_OPCODE_ESAME). */ +#define ARCHBITS_ESAONLY 1 +#define ARCHBITS_ESA 3 +#define ARCHBITS_ESAME 2 + +struct op_struct + { + char opcode[16]; + char mnemonic[16]; + char format[16]; + int archbits; + unsigned long long sort_value; + int no_nibbles; + }; + +struct op_struct *op_array; +int max_ops; +int no_ops; + +static void +createTable (void) +{ + max_ops = 256; + op_array = malloc (max_ops * sizeof (struct op_struct)); + no_ops = 0; +} + +/* `insertOpcode': insert an op_struct into sorted opcode array. */ + +static void +insertOpcode (char *opcode, char *mnemonic, char *format, int archbits) +{ + char *str; + unsigned long long sort_value; + int no_nibbles; + int ix, k; + + while (no_ops >= max_ops) + { + max_ops = max_ops * 2; + op_array = realloc (op_array, max_ops * sizeof (struct op_struct)); + } + + sort_value = 0; + str = opcode; + for (ix = 0; ix < 16; ix++) + { + if (*str >= '0' && *str <= '9') + sort_value = (sort_value << 4) + (*str - '0'); + else if (*str >= 'a' && *str <= 'f') + sort_value = (sort_value << 4) + (*str - 'a' + 10); + else if (*str >= 'A' && *str <= 'F') + sort_value = (sort_value << 4) + (*str - 'A' + 10); + else if (*str == '?') + sort_value <<= 4; + else + break; + str ++; + } + sort_value <<= 4*(16 - ix); + no_nibbles = ix; + for (ix = 0; ix < no_ops; ix++) + if (sort_value > op_array[ix].sort_value) + break; + for (k = no_ops; k > ix; k--) + op_array[k] = op_array[k-1]; + strcpy(op_array[ix].opcode, opcode); + strcpy(op_array[ix].mnemonic, mnemonic); + strcpy(op_array[ix].format, format); + op_array[ix].sort_value = sort_value; + op_array[ix].no_nibbles = no_nibbles; + op_array[ix].archbits = archbits; + no_ops++; +} + +static char file_header[] = + "/* The opcode table. This file was generated by s390-mkopc.\n\n" + " The format of the opcode table is:\n\n" + " NAME OPCODE MASK OPERANDS\n\n" + " Name is the name of the instruction.\n" + " OPCODE is the instruction opcode.\n" + " MASK is the opcode mask; this is used to tell the disassembler\n" + " which bits in the actual opcode must match OPCODE.\n" + " OPERANDS is the list of operands.\n\n" + " The disassembler reads the table in order and prints the first\n" + " instruction which matches. */\n\n" + "const struct s390_opcode s390_opcodes[] =\n {\n"; + +/* `dumpTable': write opcode table. */ + +static void +dumpTable (void) +{ + char *str; + int ix; + + /* Write hash table entries (slots). */ + printf (file_header); + + for (ix = 0; ix < no_ops; ix++) + { + printf (" { \"%s\", ", op_array[ix].mnemonic); + for (str = op_array[ix].opcode; *str != 0; str++) + if (*str == '?') + *str = '0'; + printf ("OP%i(0x%sLL), ", + op_array[ix].no_nibbles*4, op_array[ix].opcode); + printf ("MASK_%s, INSTR_%s, ", + op_array[ix].format, op_array[ix].format); + printf ("%i}", op_array[ix].archbits); + if (ix < no_ops-1) + printf (",\n"); + else + printf ("\n"); + } + printf ("};\n\n"); + printf ("const int s390_num_opcodes =\n"); + printf (" sizeof (s390_opcodes) / sizeof (s390_opcodes[0]);\n\n"); +} + +int +main (void) +{ + char currentLine[256]; + + createTable (); + + /* Read opcode descriptions from `stdin'. For each mnemonic, + make an entry into the opcode table. */ + while (fgets (currentLine, sizeof (currentLine), stdin) != NULL) + { + char opcode[16]; + char mnemonic[16]; + char format[16]; + char description[64]; + char archtag[16]; + int archbits; + + if (currentLine[0] == '#') + continue; + memset (opcode, 0, 8); + if (sscanf (currentLine, "%15s %15s %15s \"%[^\"]\" %15s", + opcode, mnemonic, format, description, archtag) == 5) + { + if (strcmp (archtag, "esaonly") == 0) + archbits = ARCHBITS_ESAONLY; + else if (strcmp (archtag, "esa") == 0) + archbits = ARCHBITS_ESA; + else if (strcmp (archtag, "esame") == 0) + archbits = ARCHBITS_ESAME; + else + archbits = 0; + insertOpcode (opcode, mnemonic, format, archbits); + } + else + fprintf (stderr, "Couldn't scan line %s\n", currentLine); + } + + dumpTable (); + return 0; +} diff --git a/contrib/binutils/opcodes/s390-opc.c b/contrib/binutils/opcodes/s390-opc.c new file mode 100644 index 0000000..7cd8231 --- /dev/null +++ b/contrib/binutils/opcodes/s390-opc.c @@ -0,0 +1,318 @@ +/* s390-opc.c -- S390 opcode list + Copyright 2000, 2001 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + + This file is part of GDB, GAS, and the GNU binutils. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include <stdio.h> +#include "ansidecl.h" +#include "opcode/s390.h" + +/* This file holds the S390 opcode table. The opcode table + includes almost all of the extended instruction mnemonics. This + permits the disassembler to use them, and simplifies the assembler + logic, at the cost of increasing the table size. The table is + strictly constant data, so the compiler should be able to put it in + the .text section. + + This file also holds the operand table. All knowledge about + inserting operands into instructions and vice-versa is kept in this + file. */ + +/* The operands table. + The fields are bits, shift, insert, extract, flags. */ + +const struct s390_operand s390_operands[] = +{ +#define UNUSED 0 + { 0, 0, 0 }, /* Indicates the end of the operand list */ + +#define R_8 1 /* GPR starting at position 8 */ + { 4, 8, S390_OPERAND_GPR }, +#define R_12 2 /* GPR starting at position 12 */ + { 4, 12, S390_OPERAND_GPR }, +#define R_16 3 /* GPR starting at position 16 */ + { 4, 16, S390_OPERAND_GPR }, +#define R_20 4 /* GPR starting at position 20 */ + { 4, 20, S390_OPERAND_GPR }, +#define R_24 5 /* GPR starting at position 24 */ + { 4, 24, S390_OPERAND_GPR }, +#define R_28 6 /* GPR starting at position 28 */ + { 4, 28, S390_OPERAND_GPR }, +#define R_32 7 /* GPR starting at position 32 */ + { 4, 32, S390_OPERAND_GPR }, + +#define F_8 8 /* FPR starting at position 8 */ + { 4, 8, S390_OPERAND_FPR }, +#define F_12 9 /* FPR starting at position 12 */ + { 4, 12, S390_OPERAND_FPR }, +#define F_16 10 /* FPR starting at position 16 */ + { 4, 16, S390_OPERAND_FPR }, +#define F_20 11 /* FPR starting at position 16 */ + { 4, 16, S390_OPERAND_FPR }, +#define F_24 12 /* FPR starting at position 24 */ + { 4, 24, S390_OPERAND_FPR }, +#define F_28 13 /* FPR starting at position 28 */ + { 4, 28, S390_OPERAND_FPR }, +#define F_32 14 /* FPR starting at position 32 */ + { 4, 32, S390_OPERAND_FPR }, + +#define A_8 15 /* Access reg. starting at position 8 */ + { 4, 8, S390_OPERAND_AR }, +#define A_12 16 /* Access reg. starting at position 12 */ + { 4, 12, S390_OPERAND_AR }, +#define A_24 17 /* Access reg. starting at position 24 */ + { 4, 24, S390_OPERAND_AR }, +#define A_28 18 /* Access reg. starting at position 28 */ + { 4, 28, S390_OPERAND_AR }, + +#define C_8 19 /* Control reg. starting at position 8 */ + { 4, 8, S390_OPERAND_CR }, +#define C_12 20 /* Control reg. starting at position 12 */ + { 4, 12, S390_OPERAND_CR }, + +#define B_16 21 /* Base register starting at position 16 */ + { 4, 16, S390_OPERAND_BASE|S390_OPERAND_GPR }, +#define B_32 22 /* Base register starting at position 32 */ + { 4, 32, S390_OPERAND_BASE|S390_OPERAND_GPR }, + +#define X_12 23 /* Index register starting at position 12 */ + { 4, 12, S390_OPERAND_INDEX|S390_OPERAND_GPR }, + +#define D_20 24 /* Displacement starting at position 20 */ + { 12, 20, S390_OPERAND_DISP }, +#define D_36 25 /* Displacement starting at position 36 */ + { 12, 36, S390_OPERAND_DISP }, + +#define L4_8 26 /* 4 bit length starting at position 8 */ + { 4, 8, S390_OPERAND_LENGTH }, +#define L4_12 27 /* 4 bit length starting at position 12 */ + { 4, 12, S390_OPERAND_LENGTH }, +#define L8_8 28 /* 8 bit length starting at position 8 */ + { 8, 8, S390_OPERAND_LENGTH }, + +#define U4_8 29 /* 4 bit unsigned value starting at 8 */ + { 4, 8, 0 }, +#define U4_12 30 /* 4 bit unsigned value starting at 12 */ + { 4, 12, 0 }, +#define U4_16 31 /* 4 bit unsigned value starting at 16 */ + { 4, 16, 0 }, +#define U4_20 32 /* 4 bit unsigned value starting at 20 */ + { 4, 20, 0 }, +#define U8_8 33 /* 8 bit unsigned value starting at 8 */ + { 8, 8, 0 }, +#define U8_16 34 /* 8 bit unsigned value starting at 16 */ + { 8, 16, 0 }, +#define I16_16 35 /* 16 bit signed value starting at 16 */ + { 16, 16, S390_OPERAND_SIGNED }, +#define U16_16 36 /* 16 bit unsigned value starting at 16 */ + { 16, 16, 0 }, +#define J16_16 37 /* PC relative jump offset at 16 */ + { 16, 16, S390_OPERAND_PCREL }, +#define J32_16 38 /* PC relative long offset at 16 */ + { 32, 16, S390_OPERAND_PCREL } +}; + + +/* Macros used to form opcodes. */ + +/* 8/16/48 bit opcodes. */ +#define OP8(x) { x, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define OP16(x) { x >> 8, x & 255, 0x00, 0x00, 0x00, 0x00 } +#define OP48(x) { x >> 40, (x >> 32) & 255, (x >> 24) & 255, \ + (x >> 16) & 255, (x >> 8) & 255, x & 255} + +/* The new format of the INSTR_x_y and MASK_x_y defines is based + on the following rules: + 1) the middle part of the definition (x in INSTR_x_y) is the official + names of the instruction format that you can find in the principals + of operation. + 2) the last part of the definition (y in INSTR_x_y) gives you an idea + which operands the binary represenation of the instruction has. + The meanings of the letters in y are: + a - access register + c - control register + d - displacement, 12 bit + f - floating pointer register + i - signed integer, 4 or 8 bit + l - length, 4 or 8 bit + p - pc relative + r - general purpose register + u - unsigned integer, 4 or 8 bit + 0 - operand skipped. + The order of the letters reflects the layout of the format in + storage and not the order of the paramaters of the instructions. + The use of the letters is not a 100% match with the PoP but it is + quite close. + + For example the instruction "mvo" is defined in the PoP as follows: + + MVO D1(L1,B1),D2(L2,B2) [SS] + + -------------------------------------- + | 'F1' | L1 | L2 | B1 | D1 | B2 | D2 | + -------------------------------------- + 0 8 12 16 20 32 36 + + The instruction format is: INSTR_SS_LLRDRD / MASK_SS_LLRDRD. */ + +#define INSTR_E 2, { 0,0,0,0,0,0 } /* e.g. pr */ +#define INSTR_RIE_RRP 6, { R_8,R_12,J16_16,0,0,0 } /* e.g. brxhg */ +#define INSTR_RIL_0P 6, { J32_16,0,0,0,0 } /* e.g. jg */ +#define INSTR_RIL_RP 6, { R_8,J32_16,0,0,0,0 } /* e.g. brasl */ +#define INSTR_RIL_UP 6, { U4_8,J32_16,0,0,0,0 } /* e.g. brcl */ +#define INSTR_RI_0P 4, { J16_16,0,0,0,0,0 } /* e.g. j */ +#define INSTR_RI_RI 4, { R_8,I16_16,0,0,0,0 } /* e.g. ahi */ +#define INSTR_RI_RP 4, { R_8,J16_16,0,0,0,0 } /* e.g. brct */ +#define INSTR_RI_RU 4, { R_8,U16_16,0,0,0,0 } /* e.g. tml */ +#define INSTR_RI_UP 4, { U4_8,J16_16,0,0,0,0 } /* e.g. brc */ +#define INSTR_RRE_00 4, { 0,0,0,0,0,0 } /* e.g. palb */ +#define INSTR_RRE_0R 4, { R_28,0,0,0,0,0 } /* e.g. tb */ +#define INSTR_RRE_AA 4, { A_24,A_28,0,0,0,0 } /* e.g. cpya */ +#define INSTR_RRE_AR 4, { A_24,R_28,0,0,0,0 } /* e.g. sar */ +#define INSTR_RRE_F0 4, { F_24,0,0,0,0,0 } /* e.g. sqer */ +#define INSTR_RRE_FF 4, { F_24,F_28,0,0,0,0 } /* e.g. debr */ +#define INSTR_RRE_R0 4, { R_24,0,0,0,0,0 } /* e.g. ipm */ +#define INSTR_RRE_RA 4, { R_24,A_28,0,0,0,0 } /* e.g. ear */ +#define INSTR_RRE_RF 4, { R_24,F_28,0,0,0,0 } /* e.g. cefbr */ +#define INSTR_RRE_RR 4, { R_24,R_28,0,0,0,0 } /* e.g. lura */ +#define INSTR_RRF_F0FF 4, { F_16,F_24,F_28,0,0,0 } /* e.g. madbr */ +#define INSTR_RRF_FUFF 4, { F_24,F_16,F_28,U4_20,0,0 } /* e.g. didbr */ +#define INSTR_RRF_RURR 4, { R_24,R_28,R_16,U4_20,0,0 } /* e.g. .insn */ +#define INSTR_RRF_U0FF 4, { F_24,U4_16,F_28,0,0,0 } /* e.g. cfxbr */ +#define INSTR_RRF_U0FR 4, { F_24,U4_16,R_28,0,0,0 } /* e.g. cfebr */ +#define INSTR_RRF_U0FR 4, { F_24,U4_16,R_28,0,0,0 } /* e.g. cfxbr */ +#define INSTR_RR_0R 2, { R_12, 0,0,0,0,0 } /* e.g. br */ +#define INSTR_RR_FF 2, { F_8,F_12,0,0,0,0 } /* e.g. adr */ +#define INSTR_RR_R0 2, { R_8, 0,0,0,0,0 } /* e.g. spm */ +#define INSTR_RR_RR 2, { R_8,R_12,0,0,0,0 } /* e.g. lr */ +#define INSTR_RR_U0 2, { U8_8, 0,0,0,0,0 } /* e.g. svc */ +#define INSTR_RR_UR 2, { U4_8,R_12,0,0,0,0 } /* e.g. bcr */ +#define INSTR_RSE_RRRD 6, { R_8,R_12,D_20,B_16,0,0 } /* e.g. lmh */ +#define INSTR_RSE_RURD 6, { R_8,U4_12,D_20,B_16,0,0 } /* e.g. icmh */ +#define INSTR_RSI_RRP 4, { R_8,R_12,J16_16,0,0,0 } /* e.g. brxh */ +#define INSTR_RS_AARD 4, { A_8,A_12,D_20,B_16,0,0 } /* e.g. lam */ +#define INSTR_RS_CCRD 4, { C_8,C_12,D_20,B_16,0,0 } /* e.g. lctl */ +#define INSTR_RS_R0RD 4, { R_8,D_20,B_16,0,0,0 } /* e.g. sll */ +#define INSTR_RS_RRRD 4, { R_8,R_12,D_20,B_16,0,0 } /* e.g. cs */ +#define INSTR_RS_RURD 4, { R_8,U4_12,D_20,B_16,0,0 } /* e.g. icm */ +#define INSTR_RXE_FRRD 6, { F_8,D_20,X_12,B_16,0,0 } /* e.g. axbr */ +#define INSTR_RXE_RRRD 6, { R_8,D_20,X_12,B_16,0,0 } /* e.g. lg */ +#define INSTR_RXF_FRRDF 6, { F_32,F_8,D_20,X_12,B_16,0 } /* e.g. madb */ +#define INSTR_RXF_RRRDR 6, { R_32,R_8,D_20,X_12,B_16,0 } /* e.g. .insn */ +#define INSTR_RX_0RRD 4, { D_20,X_12,B_16,0,0,0 } /* e.g. be */ +#define INSTR_RX_FRRD 4, { F_8,D_20,X_12,B_16,0,0 } /* e.g. ae */ +#define INSTR_RX_RRRD 4, { R_8,D_20,X_12,B_16,0,0 } /* e.g. l */ +#define INSTR_RX_URRD 4, { U4_8,D_20,X_12,B_16,0,0 } /* e.g. bc */ +#define INSTR_SI_URD 4, { D_20,B_16,U8_8,0,0,0 } /* e.g. cli */ +#define INSTR_SSE_RDRD 6, { D_20,B_16,D_36,B_32,0,0 } /* e.g. mvsdk */ +#define INSTR_SS_L0RDRD 6, { D_20,L8_8,B_16,D_36,B_32,0 } /* e.g. mvc */ +#define INSTR_SS_LIRDRD 6, { D_20,L4_8,B_16,D_36,B_32,U4_12 } /* e.g. srp */ +#define INSTR_SS_LLRDRD 6, { D_20,L4_8,B_16,D_36,L4_12,B_32 } /* e.g. pack */ +#define INSTR_SS_RRRDRD 6, { D_20,R_8,B_16,D_36,B_32,R_12 } /* e.g. mvck */ +#define INSTR_SS_RRRDRD2 6, { R_8,D_20,B_16,R_12,D_36,B_32 } /* e.g. plo */ +#define INSTR_SS_RRRDRD3 6, { R_8,R_12,D_20,B_16,D_36,B_32 } /* e.g. lmd */ +#define INSTR_S_00 4, { 0,0,0,0,0,0 } /* e.g. hsch */ +#define INSTR_S_RD 4, { D_20,B_16,0,0,0,0 } /* e.g. lpsw */ + +#define MASK_E { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RIE_RRP { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RIL_0P { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RIL_RP { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RIL_UP { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RI_0P { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RI_RI { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RI_RP { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RI_RU { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RI_UP { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRE_00 { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } +#define MASK_RRE_0R { 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00 } +#define MASK_RRE_AA { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_AR { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_F0 { 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00 } +#define MASK_RRE_FF { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_R0 { 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00 } +#define MASK_RRE_RA { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_RF { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRE_RR { 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 } +#define MASK_RRF_F0FF { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_FUFF { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_RURR { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RRF_U0FF { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_U0FR { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RRF_U0FR { 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00 } +#define MASK_RR_0R { 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_FF { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_R0 { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_RR { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_U0 { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RR_UR { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RSE_RRRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RSE_RURD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RSI_RRP { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RS_AARD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RS_CCRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RS_R0RD { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RS_RRRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RS_RURD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RXE_FRRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RXE_RRRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RXF_FRRDF { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RXF_RRRDR { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff } +#define MASK_RX_0RRD { 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RX_FRRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RX_RRRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_RX_URRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SI_URD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SSE_RDRD { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SS_L0RDRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SS_LIRDRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SS_LLRDRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SS_RRRDRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SS_RRRDRD2 { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_SS_RRRDRD3 { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } +#define MASK_S_00 { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } +#define MASK_S_RD { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } + +/* The opcode formats table (blueprints for .insn pseudo mnemonic). */ + +const struct s390_opcode s390_opformats[] = + { + { "e", OP8(0x00LL), MASK_E, INSTR_E, 3 }, + { "ri", OP8(0x00LL), MASK_RI_RI, INSTR_RI_RI, 3 }, + { "rie", OP8(0x00LL), MASK_RIE_RRP, INSTR_RIE_RRP, 3 }, + { "ril", OP8(0x00LL), MASK_RIL_RP, INSTR_RIL_RP, 3 }, + { "rr", OP8(0x00LL), MASK_RR_RR, INSTR_RR_RR, 3 }, + { "rre", OP8(0x00LL), MASK_RRE_RR, INSTR_RRE_RR, 3 }, + { "rrf", OP8(0x00LL), MASK_RRF_RURR, INSTR_RRF_RURR, 3 }, + { "rs", OP8(0x00LL), MASK_RS_RRRD, INSTR_RS_RRRD, 3 }, + { "rse", OP8(0x00LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 3 }, + { "rsi", OP8(0x00LL), MASK_RSI_RRP, INSTR_RSI_RRP, 3 }, + { "rx", OP8(0x00LL), MASK_RX_RRRD, INSTR_RX_RRRD, 3 }, + { "rxe", OP8(0x00LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3 }, + { "rxf", OP8(0x00LL), MASK_RXF_RRRDR, INSTR_RXF_RRRDR,3 }, + { "s", OP8(0x00LL), MASK_S_RD, INSTR_S_RD, 3 }, + { "si", OP8(0x00LL), MASK_SI_URD, INSTR_SI_URD, 3 }, + { "ss", OP8(0x00LL), MASK_SS_RRRDRD, INSTR_SS_RRRDRD,3 }, + { "sse", OP8(0x00LL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 3 }, +}; + +const int s390_num_opformats = + sizeof (s390_opformats) / sizeof (s390_opformats[0]); + +#include "s390-opc.tab" diff --git a/contrib/binutils/opcodes/s390-opc.txt b/contrib/binutils/opcodes/s390-opc.txt new file mode 100644 index 0000000..ddcf089 --- /dev/null +++ b/contrib/binutils/opcodes/s390-opc.txt @@ -0,0 +1,626 @@ +# S/390 opcodes list. Use s390-mkopc to convert it into the opcode table. +# Copyright 2000, 2001 Free Software Foundation, Inc. +# Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). +5a a RX_RRRD "add" esa +6a ad RX_FRRD "add normalized (long)" esa +2a adr RR_FF "add normalized (long)" esa +7a ae RX_FRRD "add normalized (short)" esa +3a aer RR_FF "add normalized (short)" esa +4a ah RX_RRRD "add halfword" esa +5e al RX_RRRD "add logical" esa +1e alr RR_RR "add logical" esa +fa ap SS_LLRDRD "add decimal" esa +1a ar RR_RR "add" esa +7e au RX_FRRD "add unnormalized (short)" esa +3e aur RR_FF "add unnormalized (short)" esa +6e aw RX_FRRD "add unnormalized (long)" esa +2e awr RR_FF "add unnormalized (long)" esa +36 axr RR_FF "add normalized" esa +b240 bakr RRE_RR "branch and stack" esa +45 bal RX_RRRD "branch and link" esa +05 balr RR_RR "branch and link" esa +4d bas RX_RRRD "branch and save" esa +0d basr RR_RR "branch and save" esa +0c bassm RR_RR "branch and save and set mode" esa +47 bc RX_URRD "branch on condition" esa +07 bcr RR_UR "branch on condition" esa +46 bct RX_RRRD "branch on count" esa +06 bctr RR_RR "branch on count" esa +b258 bsg RRE_RR "branch in subspace group" esa +0b bsm RR_RR "branch and set mode" esa +86 bxh RS_RRRD "branch on index high" esa +87 bxle RS_RRRD "branch on index low or equal" esa +59 c RX_RRRD "compare" esa +69 cd RX_FRRD "compare (long)" esa +29 cdr RR_FF "compare (long)" esa +bb cds RS_RRRD "compare double and swap" esa +79 ce RX_FRRD "compare (short)" esa +39 cer RR_FF "compare (short)" esa +b21a cfc S_RD "compare and form codeword" esa +49 ch RX_RRRD "compare halfword" esa +55 cl RX_RRRD "compare logical" esa +d5 clc SS_L0RDRD "compare logical" esa +0f clcl RR_RR "compare logical long" esa +95 cli SI_URD "compare logical" esa +bd clm RS_RURD "compare logical characters under mask" esa +15 clr RR_RR "compare logical" esa +b25d clst RRE_RR "compare logical string" esa +b263 cmpsc RRE_RR "compression call" esa +f9 cp SS_LLRDRD "compare decimal" esa +b24d cpya RRE_AA "copy access" esa +19 cr RR_RR "compare" esa +ba cs RS_RRRD "compare and swap" esa +b230 csch S_00 "clear subchannel" esa +b257 cuse RRE_RR "compare until substring equal" esa +b250 csp RRE_RR "compare and swap and purge" esa +4f cvb RX_RRRD "convert to binary" esa +4e cvd RX_RRRD "convert to decimal" esa +5d d RX_RRRD "divide" esa +6d dd RX_FRRD "divide (long)" esa +2d ddr RR_FF "divide (long)" esa +7d de RX_FRRD "divide (short)" esa +3d der RR_FF "divide (short)" esa +83 diag RS_RRRD "diagnose" esa +fd dp SS_LLRDRD "divide decimal" esa +1d dr RR_RR "divide" esa +b22d dxr RRE_F0 "divide (ext.)" esa +b24f ear RRE_RA "extract access" esa +de ed SS_L0RDRD "edit" esa +df edmk SS_L0RDRD "edit and mark" esa +b226 epar RRE_R0 "extract primary ASN" esa +b249 ereg RRE_RR "extract stacked registers" esa +b227 esar RRE_R0 "extract secondary ASN" esa +b24a esta RRE_RR "extract stacked state" esa +44 ex RX_RRRD "execute" esa +24 hdr RR_FF "halve (long)" esa +34 her RR_FF "halve (short)" esa +b231 hsch S_00 "halt subchannel" esa +b224 iac RRE_R0 "insert address space control" esa +43 ic RX_RRRD "insert character" esa +bf icm RS_RURD "insert characters under mask" esa +b20b ipk S_00 "insert PSW key" esa +b222 ipm RRE_R0 "insert program mask" esa +b221 ipte RRE_RR "invalidate page table entry" esa +b229 iske RRE_RR "insert storage key extended" esa +b223 ivsk RRE_RR "insert virtual storage key" esa +58 l RX_RRRD "load" esa +41 la RX_RRRD "load address" esa +51 lae RX_RRRD "load address extended" esa +9a lam RS_AARD "load access multiple" esa +e500 lasp SSE_RDRD "load address space parameters" esa +23 lcdr RR_FF "load complement (long)" esa +33 lcer RR_FF "load complement (short)" esa +13 lcr RR_RR "load complement" esa +b7 lctl RS_CCRD "load control" esa +68 ld RX_FRRD "load (long)" esa +28 ldr RR_FF "load (long)" esa +78 le RX_FRRD "load (short)" esa +38 ler RR_FF "load (short)" esa +48 lh RX_RRRD "load halfword" esa +98 lm RS_RRRD "load multiple" esa +21 lndr RR_FF "load negative (long)" esa +31 lner RR_FF "load negative (short)" esa +11 lnr RR_RR "load negative" esa +20 lpdr RR_FF "load positive (long)" esa +30 lper RR_FF "load positive (short)" esa +10 lpr RR_RR "load positive" esa +82 lpsw S_RD "load PSW" esa +18 lr RR_RR "load" esa +b1 lra RX_RRRD "load real address" esa +25 lrdr RR_FF "load rounded (ext. to long)" esa +35 lrer RR_FF "load rounded (long to short)" esa +22 ltdr RR_FF "load and test (long)" esa +32 lter RR_FF "load and test (short)" esa +12 ltr RR_RR "load and test" esa +b24b lura RRE_RR "load using real address" esa +5c m RX_RRRD "multiply" esa +af mc SI_URD "monitor call" esa +6c md RX_FRRD "multiply (long)" esa +2c mdr RR_FF "multiply (long)" esa +7c me RX_FRRD "multiply (short to long)" esa +3c mer RR_FF "multiply (short to long)" esa +4c mh RX_RRRD "multiply halfword" esa +fc mp SS_LLRDRD "multiply decimal" esa +1c mr RR_RR "multiply" esa +b232 msch S_RD "modify subchannel" esa +b247 msta RRE_R0 "modify stacked state" esa +d2 mvc SS_L0RDRD "move" esa +e50f mvcdk SSE_RDRD "move with destination key" esa +e8 mvcin SS_L0RDRD "move inverse" esa +d9 mvck SS_RRRDRD "move with key" esa +0e mvcl RR_RR "move long" esa +da mvcp SS_RRRDRD "move to primary" esa +db mvcs SS_RRRDRD "move to secondary" esa +e50e mvcsk SSE_RDRD "move with source key" esa +92 mvi SI_URD "move" esa +d1 mvn SS_L0RDRD "move numerics" esa +f1 mvo SS_LLRDRD "move with offset" esa +b254 mvpg RRE_RR "move page" esa +b255 mvst RRE_RR "move string" esa +d3 mvz SS_L0RDRD "move zones" esa +67 mxd RX_FRRD "multiply (long to ext.)" esa +27 mxdr RR_FF "multiply (long to ext.)" esa +26 mxr RR_FF "multiply (ext.)" esa +54 n RX_RRRD "AND" esa +d4 nc SS_L0RDRD "AND" esa +94 ni SI_URD "AND" esa +14 nr RR_RR "AND" esa +56 o RX_RRRD "OR" esa +d6 oc SS_L0RDRD "OR" esa +96 oi SI_URD "OR" esa +16 or RR_RR "OR" esa +f2 pack SS_LLRDRD "pack" esa +b248 palb RRE_00 "purge ALB" esa +b218 pc S_RD "program call" esa +0101 pr E "program return" esa +b228 pt RRE_RR "program transfer" esa +b20d ptlb S_00 "purge TLB" esa +b23b rchp S_00 "reset channel path" esa +b22a rrbe RRE_RR "reset reference bit extended" esa +b238 rsch S_00 "resume subchannel" esa +5b s RX_RRRD "subtract" esa +b219 sac S_RD "set address space control" esa +b279 sacf S_RD "set address space control fast" esa +b237 sal S_00 "set address limit" esa +b24e sar RRE_AR "set access" esa +b23c schm S_00 "set channel monitor" esa +b204 sck S_RD "set clock" esa +b206 sckc S_RD "set clock comparator" esa +6b sd RX_FRRD "subtract normalized (long)" esa +2b sdr RR_FF "subtract normalized (long)" esa +7b se RX_FRRD "subtract normalized (short)" esa +3b ser RR_FF "subtract normalized (short)" esa +4b sh RX_RRRD "subtract halfword" esa +b214 sie S_RD "start interpretive execution" esa +ae sigp RS_RRRD "signal processor" esa +5f sl RX_RRRD "subtract logical" esa +8b sla RS_R0RD "shift left single" esa +8f slda RS_R0RD "shift left double (long)" esa +8d sldl RS_R0RD "shift left double logical (long)" esa +89 sll RS_R0RD "shift left single logical" esa +1f slr RR_RR "subtract logical" esa +fb sp SS_LLRDRD "subtract decimal" esa +b20a spka S_RD "set PSW key from address" esa +04 spm RR_R0 "set program mask" esa +b208 spt S_RD "set CPU timer" esa +b210 spx S_RD "set prefix" esa +b244 sqdr RRE_F0 "square root (long)" esa +b245 sqer RRE_F0 "square root (short)" esa +1b sr RR_RR "subtract" esa +8a sra RS_R0RD "shift right single" esa +8e srda RS_R0RD "shift right double (long)" esa +8c srdl RS_R0RD "shift right double logical (long)" esa +88 srl RS_R0RD "shift right single logical" esa +f0 srp SS_LIRDRD "shift and round decimal" esa +b25e srst RRE_RR "search string" esa +b225 ssar RRE_R0 "set secondary ASN" esa +b233 ssch S_RD "start subchannel" esa +b22b sske RRE_RR "set storage key extended" esa +80 ssm S_RD "set system mask" esa +50 st RX_RRRD "store" esa +9b stam RS_AARD "store access multiple" esa +b212 stap S_RD "store CPU address" esa +42 stc RX_RRRD "store character" esa +b205 stck S_RD "store clock" esa +b207 stckc S_RD "store clock comparator" esa +be stcm RS_RURD "store characters under mask" esa +b23a stcps S_RD "store channel path status" esa +b239 stcrw S_RD "store channel report word" esa +b6 stctl RS_CCRD "store control" esa +60 std RX_FRRD "store (long)" esa +70 ste RX_FRRD "store (short)" esa +40 sth RX_RRRD "store halfword" esa +b202 stidp S_RD "store CPU id" esa +90 stm RS_RRRD "store multiple" esa +ac stnsm SI_URD "store then AND system mask" esa +ad stosm SI_URD "store then OR system mask" esa +b209 stpt S_RD "store CPU timer" esa +b211 stpx S_RD "store prefix" esa +b234 stsch S_RD "store subchannel" esa +b246 stura RRE_RR "store using real address" esa +7f su RX_FRRD "subtract unnormalized (short)" esa +3f sur RR_FF "subtract unnormalized (short)" esa +0a svc RR_U0 "supervisor call" esa +6f sw RX_FRRD "subtract unnormalized (long)" esa +2f swr RR_FF "subtract unnormalized (long)" esa +37 sxr RR_FF "subtract normalized (ext.)" esa +b24c tar RRE_AR "test access" esa +b22c tb RRE_0R "test block" esa +91 tm SI_URD "test under mask" esa +b236 tpi S_RD "test pending interruption" esa +e501 tprot SSE_RDRD "test protection" esa +dc tr SS_L0RDRD "translate" esa +99 trace RS_RRRD "trace" esa +dd trt SS_L0RDRD "translate and test" esa +93 ts S_RD "test and set" esa +b235 tsch S_RD "test subchannel" esa +f3 unpk SS_LLRDRD "unpack" esa +0102 upt E "update tree" esa +57 x RX_RRRD "exclusive OR" esa +d7 xc SS_L0RDRD "exclusive OR" esa +97 xi SI_URD "exclusive OR" esa +17 xr RR_RR "exclusive OR" esa +f8 zap SS_LLRDRD "zero and add" esa +a70a ahi RI_RI "add halfword immediate" esa +84 brxh RSI_RRP "branch relative on index high" esa +85 brxle RSI_RRP "branch relative on index low or equal" esa +a705 bras RI_RP "branch relative and save" esa +a704 brc RI_UP "branch relative on condition" esa +a706 brct RI_RP "branch relative on count" esa +b241 cksm RRE_RR "checksum" esa +a70e chi RI_RI "compare halfword immediate" esa +a9 clcle RS_RRRD "compare logical long extended" esa +a708 lhi RI_RI "load halfword immediate" esa +a8 mvcle RS_RRRD "move long extended" esa +a70c mhi RI_RI "multiply halfword immediate" esa +b252 msr RRE_RR "multiply single" esa +71 ms RX_RRRD "multiply single" esa +a700 tmh RI_RU "test under mask high" esa +a701 tml RI_RU "test under mask low" esa +0700 nopr RR_0R "no operation" esa +0710 bor RR_0R "branch on overflow / if ones" esa +0720 bhr RR_0R "branch on high" esa +0720 bpr RR_0R "branch on plus" esa +0730 bnler RR_0R "branch on not low or equal" esa +0740 blr RR_0R "branch on low" esa +0740 bmr RR_0R "branch on minus / if mixed" esa +0750 bnher RR_0R "branch on not high or equal" esa +0760 blhr RR_0R "branch on low or high" esa +0770 bner RR_0R "branch on not equal" esa +0770 bnzr RR_0R "branch on not zero / if not zeros" esa +0780 ber RR_0R "branch on equal" esa +0780 bzr RR_0R "branch on zero / if zeros" esa +0790 bnlhr RR_0R "branch on not low or high" esa +07a0 bher RR_0R "branch on high or equal" esa +07b0 bnlr RR_0R "branch on not low" esa +07b0 bnmr RR_0R "branch on not minus / if not mixed" esa +07c0 bler RR_0R "brach on low or equal" esa +07d0 bnhr RR_0R "branch on not high" esa +07d0 bnpr RR_0R "branch on not plus" esa +07e0 bnor RR_0R "branch on not overflow / if not ones" esa +07f0 br RR_0R "unconditional branch" esa +4700 nop RX_0RRD "no operation" esa +4710 bo RX_0RRD "branch on overflow / if ones" esa +4720 bh RX_0RRD "branch on high" esa +4720 bp RX_0RRD "branch on plus" esa +4730 bnle RX_0RRD "branch on not low or equal" esa +4740 bl RX_0RRD "branch on low" esa +4740 bm RX_0RRD "branch on minus / if mixed" esa +4750 bnhe RX_0RRD "branch on not high or equal" esa +4760 blh RX_0RRD "branch on low or high" esa +4770 bne RX_0RRD "branch on not equal" esa +4770 bnz RX_0RRD "branch on not zero / if not zeros" esa +4780 be RX_0RRD "branch on equal" esa +4780 bz RX_0RRD "branch on zero / if zeros" esa +4790 bnlh RX_0RRD "branch on not low or high" esa +47a0 bhe RX_0RRD "branch on high or equal" esa +47b0 bnl RX_0RRD "branch on not low" esa +47b0 bnm RX_0RRD "branch on not minus / if not mixed" esa +47c0 ble RX_0RRD "branch on low or equal" esa +47d0 bnh RX_0RRD "branch on not high" esa +47d0 bnp RX_0RRD "branch on not plus" esa +47e0 bno RX_0RRD "branch on not overflow / if not ones" esa +47f0 b RX_0RRD "unconditional branch" esa +a714 jo RI_0P "jump on overflow / if ones" esa +a724 jh RI_0P "jump on A high" esa +a724 jp RI_0P "jump on plus" esa +a734 jnle RI_0P "jump on not low or equal" esa +a744 jl RI_0P "jump on A low" esa +a744 jm RI_0P "jump on minus / if mixed" esa +a754 jnhe RI_0P "jump on not high or equal" esa +a764 jlh RI_0P "jump on low or high" esa +a774 jne RI_0P "jump on A not equal B" esa +a774 jnz RI_0P "jump on not zero / if not zeros" esa +a784 je RI_0P "jump on A equal B" esa +a784 jz RI_0P "jump on zero / if zeros" esa +a794 jnlh RI_0P "jump on not low or high" esa +a7a4 jhe RI_0P "jump on high or equal" esa +a7b4 jnl RI_0P "jump on A not low" esa +a7b4 jnm RI_0P "jump on not minus / if not mixed" esa +a7c4 jle RI_0P "jump on low or equal" esa +a7d4 jnh RI_0P "jump on A not high" esa +a7d4 jnp RI_0P "jump on not plus" esa +a7e4 jno RI_0P "jump on not overflow / if not ones" esa +a7f4 j RI_0P "jump" esa +b34a axbr RRE_FF "add extended bfp" esa +b31a adbr RRE_FF "add long bfp" esa +ed000000001a adb RXE_FRRD "add long bfp" esa +b30a aebr RRE_FF "add short bfp" esa +ed000000000a aeb RXE_FRRD "add short bfp" esa +b349 cxbr RRE_FF "compare extended bfp" esa +b319 cdbr RRE_FF "compare long bfp" esa +ed0000000019 cdb RXE_FRRD "compare long bfp" esa +b309 cebr RRE_FF "compare short bfp" esa +ed0000000009 ceb RXE_FRRD "compare short bfp" esa +b348 kxbr RRE_FF "compare and signal extended bfp" esa +b318 kdbr RRE_FF "compare and signal long bfp" esa +ed0000000018 kdb RXE_FRRD "compare and signal long bfp" esa +b308 kebr RRE_FF "compare and signal short bfp" esa +ed0000000008 keb RXE_FRRD "compare and signal short bfp" esa +b396 cxfbr RRE_RF "convert from fixed 32 to extended bfp" esa +b395 cdfbr RRE_RF "convert from fixed 32 to long bfp" esa +b394 cefbr RRE_RF "convert from fixed 32 to short bfp" esa +b39a cfxbr RRF_U0FR "convert to fixed extended bfp to 32" esa +b399 cfdbr RRF_U0FR "convert to fixed long bfp to 32" esa +b398 cfebr RRF_U0FR "convert to fixed short bfp to 32" esa +b34d dxbr RRE_FF "divide extended bfp" esa +b31d ddbr RRE_FF "divide long bfp" esa +ed000000001d ddb RXE_FRRD "divide long bfp" esa +b30d debr RRE_FF "divide short bfp" esa +ed000000000d deb RXE_FRRD "divide short bfp" esa +b35b didbr RRF_FUFF "divide to integer long bfp" esa +b353 diebr RRF_FUFF "divide to integer short bfp" esa +b38c efpc RRE_RR "extract fpc" esa +b342 ltxbr RRE_FF "load and test extended bfp" esa +b312 ltdbr RRE_FF "load and test long bfp" esa +b302 ltebr RRE_FF "load and test short bfp" esa +b343 lcxbr RRE_FF "load complement extended bfp" esa +b313 lcdbr RRE_FF "load complement long bfp" esa +b303 lcebr RRE_FF "load complement short bfp" esa +b347 fixbr RRF_U0FF "load fp integer extended bfp" esa +b35f fidbr RRF_U0FF "load fp integer long bfp" esa +b357 fiebr RRF_U0FF "load fp integer short bfp" esa +b29d lfpc S_RD "load fpc" esa +b305 lxdbr RRE_FF "load lengthened long to extended bfp" esa +ed0000000005 lxdb RXE_FRRD "load lengthened long to extended bfp" esa +b306 lxebr RRE_FF "load lengthened short to extended bfp" esa +ed0000000006 lxeb RXE_FRRD "load lengthened short to extended bfp" esa +b304 ldebr RRE_FF "load lengthened short to long bfp" esa +ed0000000004 ldeb RXE_FRRD "load lengthened short to long bfp" esa +b341 lnxbr RRE_FF "load negative extended bfp" esa +b311 lndbr RRE_FF "load negative long bfp" esa +b301 lnebr RRE_FF "load negative short bfp" esa +b340 lpxbr RRE_FF "load positive extended bfp" esa +b310 lpdbr RRE_FF "load positive long bfp" esa +b300 lpebr RRE_FF "load positive short bfp" esa +b345 ldxbr RRE_FF "load rounded extended to long bfp" esa +b346 lexbr RRE_FF "load rounded extended to short bfp" esa +b344 ledbr RRE_FF "load rounded long to short bfp" esa +b34c mxbr RRE_FF "multiply extended bfp" esa +b31c mdbr RRE_FF "multiply long bfp" esa +ed000000001c mdb RXE_FRRD "multiply long bfp" esa +b307 mxdbr RRE_FF "multiply long to extended bfp" esa +ed0000000007 mxdb RXE_FRRD "multiply long to extended bfp" esa +b317 meebr RRE_FF "multiply short bfp" esa +ed0000000017 meeb RXE_FRRD "multiply short bfp" esa +b30c mdebr RRE_FF "multiply short to long bfp" esa +ed000000000c mdeb RXE_FRRD "multiply short to long bfp" esa +b31e madbr RRF_F0FF "multiply and add long bfp" esa +ed000000001e madb RXF_FRRDF "multiply and add long bfp" esa +b30e maebr RRF_F0FF "multiply and add short bfp" esa +ed000000000e maeb RXF_FRRDF "multiply and add short bfp" esa +b31f msdbr RRF_F0FF "multiply and subtract long bfp" esa +ed000000001f msdb RXF_FRRDF "multiply and subtract long bfp" esa +b30f msebr RRF_F0FF "multiply and subtract short bfp" esa +ed000000000f mseb RXF_FRRDF "multiply and subtract short bfp" esa +b384 sfpc RRE_RR "set fpc" esa +b299 srnm S_RD "set rounding mode" esa +b316 sqxbr RRE_FF "square root extended bfp" esa +b315 sqdbr RRE_FF "square root long bfp" esa +ed0000000015 sqdb RXE_FRRD "square root long bfp" esa +b314 sqebr RRE_FF "square root short bfp" esa +ed0000000014 sqeb RXE_FRRD "square root short bfp" esa +b29c stfpc S_RD "store fpc" esa +b34b sxbr RRE_FF "subtract extended bfp" esa +b31b sdbr RRE_FF "subtract long bfp" esa +ed000000001b sdb RXE_FRRD "subtract long bfp" esa +b30b sebr RRE_FF "subtract short bfp" esa +ed000000000b seb RXE_FRRD "subtract short bfp" esa +ed0000000012 tcxb RXE_FRRD "test data class extended bfp" esa +ed0000000011 tcdb RXE_FRRD "test data class long bfp" esa +ed0000000010 tceb RXE_FRRD "test data class short bfp" esa +b274 siga S_RD "signal adapter" esa +# are the following instructions confidential ?? +b2a6 cuutf RRE_RR "convert unicode to utf-8" esa +b2a7 cutfu RRE_RR "convert utf-8 to unicode" esa +ee plo SS_RRRDRD2 "perform locked operation" esa +b25a bsa RRE_RR "branch and set authority" esa +b277 rp S_RD "resume program" esa +0107 sckpf E "set clock programmable field" esa +b27d stsi S_RD "store system information" esa +01ff trap2 E "trap" esa +b2ff trap4 S_RD "trap4" esa +# Here are the new esame instructions: +b946 bctgr RRE_RR "branch on count 64" esame +b900 lpgr RRE_RR "load positive 64" esame +b910 lpgfr RRE_RR "load positive 64<32" esame +b901 lngr RRE_RR "load negative 64" esame +b911 lngfr RRE_RR "load negative 64<32" esame +b902 ltgr RRE_RR "load and test 64" esame +b912 ltgfr RRE_RR "load and test 64<32" esame +b903 lcgr RRE_RR "load complement 64" esame +b913 lcgfr RRE_RR "load complement 64<32" esame +b980 ngr RRE_RR "and 64" esame +b921 clgr RRE_RR "compare logical 64" esame +b931 clgfr RRE_RR "compare logical 64<32" esame +b981 ogr RRE_RR "or 64" esame +b982 xgr RRE_RR "exclusive or 64" esame +b904 lgr RRE_RR "load 64" esame +b914 lgfr RRE_RR "load 64<32" esame +b920 cgr RRE_RR "compare 64" esame +b930 cgfr RRE_RR "compare 64<32" esame +b908 agr RRE_RR "add 64" esame +b918 agfr RRE_RR "add 64<32" esame +b909 sgr RRE_RR "subtract 64" esame +b919 sgfr RRE_RR "subtract 64<32" esame +b90a algr RRE_RR "add logical 64" esame +b91a algfr RRE_RR "add logical 64<32" esame +b90b slgr RRE_RR "subtract logical 64" esame +b91b slgfr RRE_RR "subtract logical 64<32" esame +e30000000046 bctg RXE_RRRD "branch on count 64" esame +e3000000002e cvdg RXE_RRRD "convert to decimal 64" esame +e3000000000e cvbg RXE_RRRD "convert to binary 64" esame +e30000000024 stg RXE_RRRD "store 64" esame +e30000000080 ng RXE_RRRD "and 64" esame +e30000000021 clg RXE_RRRD "compare logical 64" esame +e30000000031 clgf RXE_RRRD "comparee logical 64<32" esame +e30000000081 og RXE_RRRD "or 64" esame +e30000000082 xg RXE_RRRD "exclusive or 64" esame +e30000000004 lg RXE_RRRD "load 64" esame +e30000000014 lgf RXE_RRRD "load 64<32" esame +e30000000015 lgh RXE_RRRD "load halfword 64" esame +e30000000020 cg RXE_RRRD "compare 64" esame +e30000000030 cgf RXE_RRRD "compare 64<32" esame +e30000000008 ag RXE_RRRD "add 64" esame +e30000000018 agf RXE_RRRD "add 64<32" esame +e30000000009 sg RXE_RRRD "subtract 64" esame +e30000000019 sgf RXE_RRRD "subtract 64<32" esame +e3000000000a alg RXE_RRRD "add logical 64" esame +e3000000001a algf RXE_RRRD "add logical 64<32" esame +e3000000000b slg RXE_RRRD "subtract logical 64" esame +e3000000001b slgf RXE_RRRD "subtract logical 64<32" esame +e3000000000c msg RXE_RRRD "multiply single 64" esame +e3000000001c msgf RXE_RRRD "multiply single 64<32" esame +ec0000000044 brxhg RIE_RRP "branch relative on index high 64" esame +ec0000000045 brxlg RIE_RRP "branch relative on index low or equal 64" esame +eb0000000044 bxhg RSE_RRRD "branch on index high 64" esame +eb0000000045 bxleg RSE_RRRD "branch on index low or equal 64" esame +eb000000000c srlg RSE_RRRD "shift right single logical 64" esame +eb000000000d sllg RSE_RRRD "shift left single logical 64" esame +eb000000000a srag RSE_RRRD "shift right single 64" esame +eb000000000b slag RSE_RRRD "shift left single 64" esame +eb0000000024 stmg RSE_RRRD "store multiple 64" esame +eb0000000026 stmh RSE_RRRD "store multiple high" esame +eb0000000004 lmg RSE_RRRD "load multiple 64" esame +eb0000000096 lmh RSE_RRRD "load multiple high" esame +ef lmd SS_RRRDRD3 "load multiple disjoint" esame +eb000000000f tracg RSE_RRRD "trace 64" esame +e30000000003 lrag RXE_RRRD "load real address 64" esame +e50000000002 strag SSE_RDRD "store read address" esame +eb0000000025 stctg RSE_RRRD "store control 64" esame +eb000000002f lctlg RSE_RRRD "load control 64" esame +eb0000000030 csg RSE_RRRD "compare and swap 64" esame +eb000000003e cdsg RSE_RRRD "compare double and swap 64" esame +eb0000000020 clmh RSE_RURD "compare logical characters under mask high" esame +eb000000002c stcmh RSE_RURD "store characters under mask high" esame +eb0000000080 icmh RSE_RURD "insert characters under mask high" esame +a700 tmlh RI_RU "test under mask low high" esame +a702 tmhh RI_RU "test under mask high high" esame +a701 tmll RI_RU "test under mask low low" esame +a703 tmhl RI_RU "test under mask high low" esame +c004 brcl RIL_UP "branch relative on condition long" esame +c014 jgo RIL_0P "jump long on overflow / if ones" esame +c024 jgh RIL_0P "jump long on high" esame +c024 jgp RIL_0P "jump long on plus" esame +c034 jgnle RIL_0P "jump long on not low or equal" esame +c044 jgl RIL_0P "jump long on low" esame +c044 jgm RIL_0P "jump long on minus / if mixed" esame +c054 jgnhe RIL_0P "jump long on not high or equal" esame +c064 jglh RIL_0P "jump long on low or high" esame +c074 jgne RIL_0P "jump long on not equal" esame +c074 jgnz RIL_0P "jump long on not zero / if not zeros" esame +c084 jge RIL_0P "jump long on equal" esame +c084 jgz RIL_0P "jump long on zero / if zeros" esame +c094 jgnlh RIL_0P "jump long on not low or high" esame +c0a4 jghe RIL_0P "jump long on high or equal" esame +c0b4 jgnl RIL_0P "jump long on not low" esame +c0b4 jgnm RIL_0P "jump long on not minus / if not mixed" esame +c0c4 jgle RIL_0P "jump long on low or equal" esame +c0d4 jgnh RIL_0P "jump long on not high" esame +c0d4 jgnp RIL_0P "jump long on not plus" esame +c0e4 jgno RIL_0P "jump long on not overflow / if not ones" esame +c0f4 jg RIL_0P "jump long" esame +c005 brasl RIL_RP "branch relative and save long" esame +a707 brctg RI_RP "branch relative on count 64" esame +a709 lghi RI_RI "load halfword immediate 64" esame +a70b aghi RI_RI "add halfword immediate 64" esame +a70d mghi RI_RI "multiply halfword immediate 64" esame +a70f cghi RI_RI "compare halfword immediate 64" esame +b925 sturg RRE_RR "store using real address 64" esame +b90e eregg RRE_RR "extract stacked registers 64" esame +b905 lurag RRE_RR "load using real address 64" esame +b90c msgr RRE_RR "multiply single 64" esame +b91c msgfr RRE_RR "multiply single 64<32" esame +b3a4 cegbr RRE_RR "convert from fixed 64 to short bfp" esame +b3a5 cdgbr RRE_RR "convert from fixed 64 to long bfp" esame +b3a6 cxgbr RRE_RR "convert from fixed 64 to extended bfp" esame +b3a8 cgebr RRF_U0FR "convert to fixed short bfd to 64" esame +b3a9 cgdbr RRF_U0FR "convert to fixed long bfp to 64" esame +b3aa cgxbr RRF_U0FR "convert to fixed extended bfp to 64" esame +b3c4 cegr RRE_RR "convert from fixed 64 to short hfp" esame +b3c5 cdgr RRE_RR "convert from fixed 64 to long hfp" esame +b3c6 cxgr RRE_RR "convert from fixed 64 to extended hfp" esame +b3c8 cger RRF_U0FR "convert to fixed short hfp to 64" esame +b3c9 cgdr RRF_U0FR "convert to fixed long hfp to 64" esame +b3ca cgxr RRF_U0FR "convert to fixed extended hfp to 64" esame +010b tam E "test addressing mode" esame +010c sam24 E "set addressing mode 24" esame +010d sam31 E "set addressing mode 31" esame +010e sam64 E "set addressing mode 64" esame +a500 iihh RI_RU "insert immediate high high" esame +a501 iihl RI_RU "insert immediate high low" esame +a502 iilh RI_RU "insert immediate low high" esame +a503 iill RI_RU "insert immediate low low" esame +a504 nihh RI_RU "and immediate high high" esame +a505 nihl RI_RU "and immediate high low" esame +a506 nilh RI_RU "and immediate low high" esame +a507 nill RI_RU "and immediate low low" esame +a508 oihh RI_RU "or immediate high high" esame +a509 oihl RI_RU "or immediate high low" esame +a50a oilh RI_RU "or immediate low high" esame +a50b oill RI_RU "or immediate low low" esame +a50c llihh RI_RU "load logical immediate high high" esame +a50d llihl RI_RU "load logical immediate high low" esame +a50e llilh RI_RU "load logical immediate low high" esame +a50f llill RI_RU "load logical immediate low low" esame +b2b1 stfl S_RD "store facility list" esame +b2b2 lpswe S_RD "load psw extended" esame +b90d dsgr RRE_RR "divide single 64" esame +b90f lrvgr RRE_RR "load reversed 64" esame +b916 llgfr RRE_RR "load logical 64<32" esame +b917 llgtr RRE_RR "load logical thirty one bits" esame +b91d dsgfr RRE_RR "divide single 64<32" esame +b91f lrvr RRE_RR "load reversed 32" esame +b986 mlgr RRE_RR "multiply logical 64" esame +b987 dlgr RRE_RR "divide logical 64" esame +b988 alcgr RRE_RR "add logical with carry 64" esame +b989 slbgr RRE_RR "subtract logical with borrow 64" esame +b98d epsw RRE_RR "extract psw" esame +b996 mlr RRE_RR "multiply logical 32" esame +b997 dlr RRE_RR "divide logical 32" esame +b998 alcr RRE_RR "add logical with carry 32" esame +b999 slbr RRE_RR "subtract logical with borrow 32" esame +b99d esea RRE_R0 "extract and set extended authority" esame +c000 larl RIL_RP "load address relative long" esame +e3000000000d dsg RXE_RRRD "divide single 64" esame +e3000000000f lrvg RXE_RRRD "load reversed 64" esame +e30000000016 llgf RXE_RRRD "load logical 64<32" esame +e30000000017 llgt RXE_RRRD "load logical thirty one bits" esame +e3000000001d dsgf RXE_RRRD "divide single 64<32" esame +e3000000001e lrv RXE_RRRD "load reversed 32" esame +e3000000001f lrvh RXE_RRRD "load reversed 16" esame +e3000000002f strvg RXE_RRRD "store reversed 64" esame +e3000000003e strv RXE_RRRD "store reversed 32" esame +e3000000003f strvh RXE_RRRD "store reversed 64" esame +e30000000086 mlg RXE_RRRD "multiply logical 64" esame +e30000000087 dlg RXE_RRRD "divide logical 64" esame +e30000000088 alcg RXE_RRRD "add logical with carry 64" esame +e30000000089 slbg RXE_RRRD "subtract logical with borrow 64" esame +e3000000008e stpq RXE_RRRD "store pair to quadword" esame +e3000000008f lpq RXE_RRRD "load pair from quadword" esame +e30000000096 ml RXE_RRRD "multiply logical 32" esame +e30000000097 dl RXE_RRRD "divide logical 32" esame +e30000000098 alc RXE_RRRD "add logical with carry 32" esame +e30000000099 slb RXE_RRRD "subtract logical with borrow 32" esame +e30000000090 llgc RXE_RRRD "load logical character" esame +e30000000091 llgh RXE_RRRD "load logical halfword" esame +eb000000001c rllg RSE_RRRD "rotate left single logical 64" esame +eb000000001d rll RSE_RRRD "rotate left single logical 32" esame +b278 stcke S_RD "store clock extended" esame +b2a5 tre RRE_RR "translate extended" esame +eb000000008e mvclu RSE_RRRD "move long unicode" esame +e9 pka SS_L0RDRD "pack ascii" esame +e1 pku SS_L0RDRD "pack unicode" esame +b993 troo RRE_RR "translate one to one" esame +b992 trot RRE_RR "translate one to two" esame +b991 trto RRE_RR "translate two to one" esame +b990 trtt RRE_RR "translate two to two" esame +ea unpka SS_L0RDRD "unpack ascii" esame +e2 unpku SS_L0RDRD "unpack unicode" esame +b358 thder RRE_RR "convert short bfp to long hfp" esame +b359 thdr RRE_RR "convert long bfp to long hfp" esame +b350 tbedr RRF_U0FF "convert long hfp to short bfp" esame +b351 tbdr RRF_U0FF "convert long hfp to long bfp" esame +b374 lzer RRE_R0 "load short zero" esame +b375 lzdr RRE_R0 "load long zero" esame +b376 lzxr RRE_R0 "load extended zero" esame |