From: niklas Date: Wed, 4 Sep 1996 17:34:35 +0000 (+0000) Subject: Import of binutils, gas, ld & gprof from Cygnus 960904 tree X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=4361b62e1e00d0f5a67533135ab16f1f168005d6;p=openbsd Import of binutils, gas, ld & gprof from Cygnus 960904 tree --- diff --git a/gnu/usr.bin/binutils/bfd/aout-sparcle.c b/gnu/usr.bin/binutils/bfd/aout-sparcle.c new file mode 100644 index 00000000000..903b1367cb3 --- /dev/null +++ b/gnu/usr.bin/binutils/bfd/aout-sparcle.c @@ -0,0 +1,32 @@ +/* BFD backend for sparc little-endian aout binaries. + Copyright (C) 1996 Free Software Foundation, Inc. + Written by Cygnus Support. + +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. */ + +#define TARGETNAME "a.out-sparc-little" +#define MY(OP) CAT(sparcle_aout_,OP) + +#include "bfd.h" +#include "bfdlink.h" +#include "libaout.h" + +#define MACHTYPE_OK(mtype) ((mtype) == M_SPARC || (mtype) == M_SPARCLET) + +/* Include the usual a.out support. */ +#define TARGET_IS_LITTLE_ENDIAN_P +#include "aoutf1.h" diff --git a/gnu/usr.bin/binutils/bfd/config.h-vms b/gnu/usr.bin/binutils/bfd/config.h-vms new file mode 100644 index 00000000000..66c4344973d --- /dev/null +++ b/gnu/usr.bin/binutils/bfd/config.h-vms @@ -0,0 +1,59 @@ +/* config.h-vms. Generated by hand by Klaus Kämpf, kkaempf@didymus.rmi.de. */ +/* config.in. Generated automatically from configure.in by autoheader. */ + +/* Whether malloc must be declared even if is included. */ +/* #undef NEED_DECLARATION_MALLOC */ + +/* Whether free must be declared even if is included. */ +/* #undef NEED_DECLARATION_FREE */ + +/* Define if you have a working `mmap' system call. */ +/* #define HAVE_MMAP 1 */ + +/* Do we need to use the b modifier when opening binary files? */ +/* #undef USE_BINARY_FOPEN */ + +/* Name of host specific header file to include in trad-core.c. */ +/* #undef TRAD_HEADER */ + +/* Define only if is available *and* it defines prstatus_t. */ +/* #undef HAVE_SYS_PROCFS_H */ + +/* Do we really want to use mmap if it's available? */ +/* #undef USE_MMAP */ + +/* Define if you have the fcntl function. */ +#define HAVE_FCNTL 1 + +/* Define if you have the getpagesize function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the madvise function. */ +#define HAVE_MADVISE 1 + +/* Define if you have the mprotect function. */ +#define HAVE_MPROTECT 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 diff --git a/gnu/usr.bin/binutils/bfd/cpu-h8300.c b/gnu/usr.bin/binutils/bfd/cpu-h8300.c index 380dfb5556e..567b7df9de2 100644 --- a/gnu/usr.bin/binutils/bfd/cpu-h8300.c +++ b/gnu/usr.bin/binutils/bfd/cpu-h8300.c @@ -22,134 +22,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sysdep.h" #include "libbfd.h" -#if 0 /* not used currently */ -/* -Relocations for the H8 - -*/ -static bfd_reloc_status_type -howto16_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd * abfd; - arelent * reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection * ignore_input_section; - bfd * ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_16 (abfd, (bfd_byte *) data + addr); - - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_16 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - - -static bfd_reloc_status_type -howto8_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd * abfd; - arelent * reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection * ignore_input_section; - bfd * ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - - -static bfd_reloc_status_type -howto8_FFnn_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd * abfd; - arelent * reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection * ignore_input_section; - bfd * ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - abort (); - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - -static bfd_reloc_status_type -howto8_pcrel_callback (abfd, reloc_entry, symbol_in, data, - ignore_input_section, ignore_bfd) - bfd * abfd; - arelent * reloc_entry; - struct symbol_cache_entry *symbol_in; - PTR data; - asection * ignore_input_section; - bfd * ignore_bfd; -{ - long relocation = 0; - bfd_vma addr = reloc_entry->address; - long x = bfd_get_8 (abfd, (bfd_byte *) data + addr); - abort (); - HOWTO_PREPARE (relocation, symbol_in); - - x = (x + relocation + reloc_entry->addend); - - bfd_put_8 (abfd, x, (bfd_byte *) data + addr); - return bfd_reloc_ok; -} - -static reloc_howto_type howto_16 -= NEWHOWTO (howto16_callback, "abs16", 1, false, false); -static reloc_howto_type howto_8 -= NEWHOWTO (howto8_callback, "abs8", 0, false, false); - -static reloc_howto_type howto_8_FFnn -= NEWHOWTO (howto8_FFnn_callback, "ff00+abs8", 0, false, false); - -static reloc_howto_type howto_8_pcrel -= NEWHOWTO (howto8_pcrel_callback, "pcrel8", 0, false, true); - -static reloc_howto_type * -local_bfd_reloc_type_lookup (arch, code) - const struct bfd_arch_info *arch; - bfd_reloc_code_real_type code; -{ - switch (code) - { - case BFD_RELOC_16: - return &howto_16; - case BFD_RELOC_8_FFnn: - return &howto_8_FFnn; - case BFD_RELOC_8: - return &howto_8; - case BFD_RELOC_8_PCREL: - return &howto_8_pcrel; - default: - return (reloc_howto_type *) NULL; - } - } -#endif - int bfd_default_scan_num_mach (); static boolean @@ -183,6 +55,10 @@ h8300_scan (info, string) { return (info->mach == bfd_mach_h8300h); } + else if (*string == 's' || *string == 'S') + { + return (info->mach == bfd_mach_h8300s); + } else { return info->mach == bfd_mach_h8300; @@ -199,15 +75,11 @@ compatible (in, out) const bfd_arch_info_type * in; const bfd_arch_info_type * out; { - /* If the output is non-H and the input is -H, that's bad */ - if (in->mach == bfd_mach_h8300h && - out->mach == bfd_mach_h8300) + /* It's really not a good idea to mix and match modes. */ + if (in->mach != out->mach) return 0; - - /* If either is an -H, the answer is -H */ - if (in->mach == bfd_mach_h8300h) + else return in; - return out; } static const bfd_arch_info_type h8300_info_struct = @@ -227,8 +99,7 @@ static const bfd_arch_info_type h8300_info_struct = 0, }; - -const bfd_arch_info_type bfd_h8300_arch = +static const bfd_arch_info_type h8300h_info_struct = { 32, /* 32 bits in a word */ 32, /* 32 bits in an address */ @@ -244,3 +115,20 @@ const bfd_arch_info_type bfd_h8300_arch = /* local_bfd_reloc_type_lookup, */ &h8300_info_struct, }; + +const bfd_arch_info_type bfd_h8300_arch = +{ + 32, /* 32 bits in a word */ + 32, /* 32 bits in an address */ + 8, /* 8 bits in a byte */ + bfd_arch_h8300, + bfd_mach_h8300s, + "h8300s", /* arch_name */ + "h8300s", /* printable name */ + 1, + false, /* the default machine */ + compatible, + h8300_scan, +/* local_bfd_reloc_type_lookup, */ + &h8300h_info_struct, +}; diff --git a/gnu/usr.bin/binutils/bfd/cpu-i386.c b/gnu/usr.bin/binutils/bfd/cpu-i386.c index 404109033b7..518176d8bcc 100644 --- a/gnu/usr.bin/binutils/bfd/cpu-i386.c +++ b/gnu/usr.bin/binutils/bfd/cpu-i386.c @@ -1,5 +1,5 @@ /* BFD support for the Intel 386 architecture. - Copyright 1992 Free Software Foundation, Inc. + Copyright 1992, 94, 95, 1996 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -21,18 +21,34 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sysdep.h" #include "libbfd.h" +static const bfd_arch_info_type i8086_arch = +{ + 32, /* 32 bits in a word */ + 32, /* 32 bits in an address (well, not really) */ + 8, /* 8 bits in a byte */ + bfd_arch_i386, + bfd_mach_i386_i8086, + "i8086", + "i8086", + 3, + false, + bfd_default_compatible, + bfd_default_scan , + 0, +}; + const bfd_arch_info_type bfd_i386_arch = - { - 32, /* 32 bits in a word */ - 32, /* 32 bits in an address */ - 8, /* 8 bits in a byte */ - bfd_arch_i386, - 0, /* only 1 machine */ - "i386", - "i386", - 3, - true, /* the one and only */ - bfd_default_compatible, - bfd_default_scan , - 0, - }; +{ + 32, /* 32 bits in a word */ + 32, /* 32 bits in an address */ + 8, /* 8 bits in a byte */ + bfd_arch_i386, + bfd_mach_i386_i386, + "i386", + "i386", + 3, + true, + bfd_default_compatible, + bfd_default_scan , + &i8086_arch, +}; diff --git a/gnu/usr.bin/binutils/bfd/cpu-mips.c b/gnu/usr.bin/binutils/bfd/cpu-mips.c index 5e1934210a2..f9ae42b32e8 100644 --- a/gnu/usr.bin/binutils/bfd/cpu-mips.c +++ b/gnu/usr.bin/binutils/bfd/cpu-mips.c @@ -24,6 +24,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ static const bfd_arch_info_type arch_info_struct[] = { + { + 32, /* 32 bits in a word */ + 32, /* 32 bits in an address */ + 8, /* 8 bits in a byte */ + bfd_arch_mips, + 3000, + "mips", + "mips:3000", + 3, + false, + bfd_default_compatible, + bfd_default_scan, + &arch_info_struct[1], + }, { 32, /* 32 bits in a word */ 32, /* 32 bits in an address */ @@ -36,7 +50,7 @@ static const bfd_arch_info_type arch_info_struct[] = false, bfd_default_compatible, bfd_default_scan, - &arch_info_struct[1], + &arch_info_struct[2], }, { 64, /* 64 bits in a word */ @@ -50,7 +64,7 @@ static const bfd_arch_info_type arch_info_struct[] = false, bfd_default_compatible, bfd_default_scan , - &arch_info_struct[2], + &arch_info_struct[3], }, { 64, /* 64 bits in a word */ @@ -68,15 +82,19 @@ static const bfd_arch_info_type arch_info_struct[] = } }; +/* The default architecture is mips:3000, but with a machine number of + zero. This lets the linker distinguish between a default setting + of mips, and an explicit setting of mips:3000. */ + const bfd_arch_info_type bfd_mips_arch = { 32, /* 32 bits in a word */ 32, /* 32 bits in an address */ 8, /* 8 bits in a byte */ bfd_arch_mips, - 3000, + 0, + "mips", "mips", - "mips:3000", 3, true, bfd_default_compatible, diff --git a/gnu/usr.bin/binutils/bfd/doc/chew.c b/gnu/usr.bin/binutils/bfd/doc/chew.c index 5c04404f7a6..3958f30ef9c 100644 --- a/gnu/usr.bin/binutils/bfd/doc/chew.c +++ b/gnu/usr.bin/binutils/bfd/doc/chew.c @@ -943,6 +943,8 @@ WORD(kill_bogus_lines) if (dot == 2)dot=1;else dot = 0; } + else + sl = 0; c++; diff --git a/gnu/usr.bin/binutils/bfd/elf32-hppa.h b/gnu/usr.bin/binutils/bfd/elf32-hppa.h index 63ee52200e0..46bde3b6552 100644 --- a/gnu/usr.bin/binutils/bfd/elf32-hppa.h +++ b/gnu/usr.bin/binutils/bfd/elf32-hppa.h @@ -141,7 +141,7 @@ elf32_hppa_reloc_type; #define R_HPPA_COMPLEX R_PARISC_UNIMPLEMENTED elf32_hppa_reloc_type **hppa_elf_gen_reloc_type - PARAMS ((bfd *, elf32_hppa_reloc_type, int, int, int)); + PARAMS ((bfd *, elf32_hppa_reloc_type, int, int, int, asymbol *)); boolean elf32_hppa_size_stubs PARAMS ((bfd *, bfd *, struct bfd_link_info *)); diff --git a/gnu/usr.bin/binutils/bfd/elf32-sh.c b/gnu/usr.bin/binutils/bfd/elf32-sh.c new file mode 100644 index 00000000000..c65114caac3 --- /dev/null +++ b/gnu/usr.bin/binutils/bfd/elf32-sh.c @@ -0,0 +1,1905 @@ +/* Hitachi SH specific support for 32-bit ELF + Copyright 1996 Free Software Foundation, Inc. + Contributed by Ian Lance Taylor, Cygnus Support. + +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 bfd_reloc_status_type sh_elf_reloc + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static bfd_reloc_status_type sh_elf_ignore_reloc + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static reloc_howto_type *sh_elf_reloc_type_lookup + PARAMS ((bfd *, bfd_reloc_code_real_type)); +static void sh_elf_info_to_howto + PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); +static boolean sh_elf_relax_section + PARAMS ((bfd *, asection *, struct bfd_link_info *, boolean *)); +static boolean sh_elf_relax_delete_bytes + PARAMS ((bfd *, asection *, bfd_vma, int)); +static boolean sh_elf_align_loads + PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, boolean *)); +static boolean sh_elf_swap_insns + PARAMS ((bfd *, asection *, PTR, bfd_byte *, bfd_vma)); +static boolean sh_elf_relocate_section + PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, + Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); +static bfd_byte *sh_elf_get_relocated_section_contents + PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, + bfd_byte *, boolean, asymbol **)); + +enum sh_reloc_type +{ + R_SH_NONE = 0, + R_SH_DIR32, + R_SH_REL32, + R_SH_DIR8WPN, + R_SH_IND12W, + R_SH_DIR8WPL, + R_SH_DIR8WPZ, + R_SH_DIR8BP, + R_SH_DIR8W, + R_SH_DIR8L, + FIRST_INVALID_RELOC, + LAST_INVALID_RELOC = 24, + /* The remaining relocs are a GNU extension used for relaxation. We + use the same constants as COFF uses, not that it really matters. */ + R_SH_SWITCH16 = 25, + R_SH_SWITCH32, + R_SH_USES, + R_SH_COUNT, + R_SH_ALIGN, + R_SH_CODE, + R_SH_DATA, + R_SH_LABEL, + R_SH_max +}; + +static reloc_howto_type sh_elf_howto_table[] = +{ + /* No relocation. */ + HOWTO (R_SH_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 */ + sh_elf_reloc, /* special_function */ + "R_SH_NONE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit absolute relocation. Setting partial_inplace to true and + src_mask to a non-zero value is similar to the COFF toolchain. */ + HOWTO (R_SH_DIR32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + sh_elf_reloc, /* special_function */ + "R_SH_DIR32", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit PC relative relocation. */ + HOWTO (R_SH_REL32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + sh_elf_reloc, /* special_function */ + "R_SH_REL32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xffffffff, /* dst_mask */ + true), /* pcrel_offset */ + + /* 8 bit PC relative branch divided by 2. */ + HOWTO (R_SH_DIR8WPN, /* type */ + 1, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + sh_elf_reloc, /* special_function */ + "R_SH_DIR8WPN", /* name */ + true, /* partial_inplace */ + 0xff, /* src_mask */ + 0xff, /* dst_mask */ + true), /* pcrel_offset */ + + /* 12 bit PC relative branch divided by 2. */ + HOWTO (R_SH_IND12W, /* type */ + 1, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 12, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + sh_elf_reloc, /* special_function */ + "R_SH_IND12W", /* name */ + true, /* partial_inplace */ + 0xfff, /* src_mask */ + 0xfff, /* dst_mask */ + true), /* pcrel_offset */ + + /* 8 bit unsigned PC relative divided by 4. */ + HOWTO (R_SH_DIR8WPL, /* type */ + 2, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + sh_elf_reloc, /* special_function */ + "R_SH_DIR8WPL", /* name */ + true, /* partial_inplace */ + 0xff, /* src_mask */ + 0xff, /* dst_mask */ + true), /* pcrel_offset */ + + /* 8 bit unsigned PC relative divided by 2. */ + HOWTO (R_SH_DIR8WPZ, /* type */ + 1, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + sh_elf_reloc, /* special_function */ + "R_SH_DIR8WPZ", /* name */ + true, /* partial_inplace */ + 0xff, /* src_mask */ + 0xff, /* dst_mask */ + true), /* pcrel_offset */ + + /* 8 bit GBR relative. FIXME: This only makes sense if we have some + special symbol for the GBR relative area, and that is not + implemented. */ + HOWTO (R_SH_DIR8BP, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + sh_elf_reloc, /* special_function */ + "R_SH_DIR8BP", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xff, /* dst_mask */ + true), /* pcrel_offset */ + + /* 8 bit GBR relative divided by 2. FIXME: This only makes sense if + we have some special symbol for the GBR relative area, and that + is not implemented. */ + HOWTO (R_SH_DIR8W, /* type */ + 1, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + sh_elf_reloc, /* special_function */ + "R_SH_DIR8W", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xff, /* dst_mask */ + true), /* pcrel_offset */ + + /* 8 bit GBR relative divided by 4. FIXME: This only makes sense if + we have some special symbol for the GBR relative area, and that + is not implemented. */ + HOWTO (R_SH_DIR8L, /* type */ + 2, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + sh_elf_reloc, /* special_function */ + "R_SH_DIR8L", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0xff, /* dst_mask */ + true), /* pcrel_offset */ + + { 10 }, + { 11 }, + { 12 }, + { 13 }, + { 14 }, + { 15 }, + { 16 }, + { 17 }, + { 18 }, + { 19 }, + { 20 }, + { 21 }, + { 22 }, + { 23 }, + { 24 }, + + /* The remaining relocs are a GNU extension used for relaxing. The + final pass of the linker never needs to do anything with any of + these relocs. Any required operations are handled by the + relaxation code. */ + + /* A 16 bit switch table entry. This is generated for an expression + such as ``.word L1 - L2''. The offset holds the difference + between the reloc address and L2. */ + HOWTO (R_SH_SWITCH16, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + sh_elf_ignore_reloc, /* special_function */ + "R_SH_SWITCH16", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + true), /* pcrel_offset */ + + /* A 32 bit switch table entry. This is generated for an expression + such as ``.long L1 - L2''. The offset holds the difference + between the reloc address and L2. */ + HOWTO (R_SH_SWITCH32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + sh_elf_ignore_reloc, /* special_function */ + "R_SH_SWITCH32", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + true), /* pcrel_offset */ + + /* Indicates a .uses pseudo-op. The compiler will generate .uses + pseudo-ops when it finds a function call which can be relaxed. + The offset field holds the PC relative offset to the instruction + which loads the register used in the function call. */ + HOWTO (R_SH_USES, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + sh_elf_ignore_reloc, /* special_function */ + "R_SH_USES", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + true), /* pcrel_offset */ + + /* The assembler will generate this reloc for addresses referred to + by the register loads associated with USES relocs. The offset + field holds the number of times the address is referenced in the + object file. */ + HOWTO (R_SH_COUNT, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + sh_elf_ignore_reloc, /* special_function */ + "R_SH_COUNT", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + true), /* pcrel_offset */ + + /* Indicates an alignment statement. The offset field is the power + of 2 to which subsequent portions of the object file must be + aligned. */ + HOWTO (R_SH_ALIGN, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + sh_elf_ignore_reloc, /* special_function */ + "R_SH_ALIGN", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + true), /* pcrel_offset */ + + /* The assembler will generate this reloc before a block of + instructions. A section should be processed as assumining it + contains data, unless this reloc is seen. */ + HOWTO (R_SH_CODE, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + sh_elf_ignore_reloc, /* special_function */ + "R_SH_CODE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + true), /* pcrel_offset */ + + /* The assembler will generate this reloc after a block of + instructions when it sees data that is not instructions. */ + HOWTO (R_SH_DATA, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + sh_elf_ignore_reloc, /* special_function */ + "R_SH_DATA", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + true), /* pcrel_offset */ + + /* The assembler generates this reloc for each label within a block + of instructions. This permits the linker to avoid swapping + instructions which are the targets of branches. */ + HOWTO (R_SH_LABEL, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_unsigned, /* complain_on_overflow */ + sh_elf_ignore_reloc, /* special_function */ + "R_SH_LABEL", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + true) /* pcrel_offset */ +}; + +/* This function is used for normal relocs. This is like the COFF + function, and is almost certainly incorrect for other ELF targets. */ + +static bfd_reloc_status_type +sh_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd, + error_message) + bfd *abfd; + arelent *reloc_entry; + asymbol *symbol_in; + PTR data; + asection *input_section; + bfd *output_bfd; + char **error_message; +{ + unsigned long insn; + bfd_vma sym_value; + enum sh_reloc_type r_type; + bfd_vma addr = reloc_entry->address; + bfd_byte *hit_data = addr + (bfd_byte *) data; + + r_type = (enum sh_reloc_type) reloc_entry->howto->type; + + if (output_bfd != NULL) + { + /* Partial linking--do nothing. */ + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + /* Almost all relocs have to do with relaxing. If any work must be + done for them, it has been done in sh_relax_section. */ + if (r_type != R_SH_DIR32 + && (r_type != R_SH_IND12W + || (symbol_in->flags & BSF_LOCAL) != 0)) + return bfd_reloc_ok; + + if (symbol_in != NULL + && bfd_is_und_section (symbol_in->section)) + return bfd_reloc_undefined; + + if (bfd_is_com_section (symbol_in->section)) + sym_value = 0; + else + sym_value = (symbol_in->value + + symbol_in->section->output_section->vma + + symbol_in->section->output_offset); + + switch (r_type) + { + case R_SH_DIR32: + insn = bfd_get_32 (abfd, hit_data); + insn += sym_value + reloc_entry->addend; + bfd_put_32 (abfd, insn, hit_data); + break; + case R_SH_IND12W: + insn = bfd_get_16 (abfd, hit_data); + sym_value += reloc_entry->addend; + sym_value -= (input_section->output_section->vma + + input_section->output_offset + + addr + + 4); + sym_value += (insn & 0xfff) << 1; + if (insn & 0x800) + sym_value -= 0x1000; + insn = (insn & 0xf000) | (sym_value & 0xfff); + bfd_put_16 (abfd, insn, hit_data); + if (sym_value < (bfd_vma) -0x1000 || sym_value >= 0x1000) + return bfd_reloc_overflow; + break; + default: + abort (); + break; + } + + return bfd_reloc_ok; +} + +/* This function is used for relocs which are only used for relaxing, + which the linker should otherwise ignore. */ + +static bfd_reloc_status_type +sh_elf_ignore_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 (output_bfd != NULL) + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; +} + +/* This structure is used to map BFD reloc codes to SH ELF relocs. */ + +struct elf_reloc_map +{ + unsigned char bfd_reloc_val; + unsigned char elf_reloc_val; +}; + +/* An array mapping BFD reloc codes to SH ELF relocs. */ + +static const struct elf_reloc_map sh_reloc_map[] = +{ + { BFD_RELOC_NONE, R_SH_NONE }, + { BFD_RELOC_32, R_SH_DIR32 }, + { BFD_RELOC_CTOR, R_SH_DIR32 }, + { BFD_RELOC_32_PCREL, R_SH_REL32 }, + { BFD_RELOC_SH_PCDISP8BY2, R_SH_DIR8WPN }, + { BFD_RELOC_SH_PCDISP12BY2, R_SH_IND12W }, + { BFD_RELOC_SH_PCRELIMM8BY2, R_SH_DIR8WPZ }, + { BFD_RELOC_SH_PCRELIMM8BY4, R_SH_DIR8WPL }, + { BFD_RELOC_SH_SWITCH16, R_SH_SWITCH16 }, + { BFD_RELOC_SH_SWITCH32, R_SH_SWITCH32 }, + { BFD_RELOC_SH_USES, R_SH_USES }, + { BFD_RELOC_SH_COUNT, R_SH_COUNT }, + { BFD_RELOC_SH_ALIGN, R_SH_ALIGN }, + { BFD_RELOC_SH_CODE, R_SH_CODE }, + { BFD_RELOC_SH_DATA, R_SH_DATA }, + { BFD_RELOC_SH_LABEL, R_SH_LABEL } +}; + +/* Given a BFD reloc code, return the howto structure for the + corresponding SH ELf reloc. */ + +static reloc_howto_type * +sh_elf_reloc_type_lookup (abfd, code) + bfd *abfd; + bfd_reloc_code_real_type code; +{ + unsigned int i; + + for (i = 0; i < sizeof (sh_reloc_map) / sizeof (struct elf_reloc_map); i++) + { + if (sh_reloc_map[i].bfd_reloc_val == code) + return &sh_elf_howto_table[(int) sh_reloc_map[i].elf_reloc_val]; + } + + return NULL; +} + +/* Given an ELF reloc, fill in the howto field of a relent. */ + +static void +sh_elf_info_to_howto (abfd, cache_ptr, dst) + bfd *abfd; + arelent *cache_ptr; + Elf_Internal_Rela *dst; +{ + unsigned int r; + + r = ELF32_R_TYPE (dst->r_info); + + BFD_ASSERT (r < (unsigned int) R_SH_max); + BFD_ASSERT (r < FIRST_INVALID_RELOC || r > LAST_INVALID_RELOC); + + cache_ptr->howto = &sh_elf_howto_table[r]; +} + +/* This function handles relaxing for SH ELF. See the corresponding + function in coff-sh.c for a description of what this does. FIXME: + There is a lot of duplication here between this code and the COFF + specific code. The format of relocs and symbols is wound deeply + into this code, but it would still be better if the duplication + could be eliminated somehow. Note in particular that although both + functions use symbols like R_SH_CODE, those symbols have different + values; in coff-sh.c they come from include/coff/sh.h, whereas here + they come from enum sh_reloc_type in this file. */ + +static boolean +sh_elf_relax_section (abfd, sec, link_info, again) + bfd *abfd; + asection *sec; + struct bfd_link_info *link_info; + boolean *again; +{ + Elf_Internal_Shdr *symtab_hdr; + Elf_Internal_Rela *internal_relocs; + Elf_Internal_Rela *free_relocs = NULL; + boolean have_code; + Elf_Internal_Rela *irel, *irelend; + bfd_byte *contents = NULL; + bfd_byte *free_contents = NULL; + Elf32_External_Sym *extsyms = NULL; + Elf32_External_Sym *free_extsyms = NULL; + + *again = false; + + if (link_info->relocateable + || (sec->flags & SEC_RELOC) == 0 + || sec->reloc_count == 0) + return true; + + /* If this is the first time we have been called for this section, + initialize the cooked size. */ + if (sec->_cooked_size == 0) + sec->_cooked_size = sec->_raw_size; + + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + + internal_relocs = (_bfd_elf32_link_read_relocs + (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL, + link_info->keep_memory)); + if (internal_relocs == NULL) + goto error_return; + if (! link_info->keep_memory) + free_relocs = internal_relocs; + + have_code = false; + + irelend = internal_relocs + sec->reloc_count; + for (irel = internal_relocs; irel < irelend; irel++) + { + bfd_vma laddr, paddr, symval; + unsigned short insn; + Elf_Internal_Rela *irelfn, *irelscan, *irelcount; + bfd_signed_vma foff; + + if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_CODE) + have_code = true; + + if (ELF32_R_TYPE (irel->r_info) != (int) R_SH_USES) + continue; + + /* Get the section contents. */ + if (contents == NULL) + { + if (elf_section_data (sec)->this_hdr.contents != NULL) + contents = elf_section_data (sec)->this_hdr.contents; + else + { + contents = (bfd_byte *) bfd_malloc (sec->_raw_size); + if (contents == NULL) + goto error_return; + free_contents = contents; + + if (! bfd_get_section_contents (abfd, sec, contents, + (file_ptr) 0, sec->_raw_size)) + goto error_return; + } + } + + /* The r_addend field of the R_SH_USES reloc will point us to + the register load. The 4 is because the r_addend field is + computed as though it were a jump offset, which are based + from 4 bytes after the jump instruction. */ + laddr = irel->r_offset + 4 + irel->r_addend; + if (laddr >= sec->_raw_size) + { + (*_bfd_error_handler) ("%s: 0x%lx: warning: bad R_SH_USES offset", + bfd_get_filename (abfd), + (unsigned long) irel->r_offset); + continue; + } + insn = bfd_get_16 (abfd, contents + laddr); + + /* If the instruction is not mov.l NN,rN, we don't know what to + do. */ + if ((insn & 0xf000) != 0xd000) + { + ((*_bfd_error_handler) + ("%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x", + bfd_get_filename (abfd), (unsigned long) irel->r_offset, insn)); + continue; + } + + /* Get the address from which the register is being loaded. The + displacement in the mov.l instruction is quadrupled. It is a + displacement from four bytes after the movl instruction, but, + before adding in the PC address, two least significant bits + of the PC are cleared. We assume that the section is aligned + on a four byte boundary. */ + paddr = insn & 0xff; + paddr *= 4; + paddr += (laddr + 4) &~ 3; + if (paddr >= sec->_raw_size) + { + ((*_bfd_error_handler) + ("%s: 0x%lx: warning: bad R_SH_USES load offset", + bfd_get_filename (abfd), (unsigned long) irel->r_offset)); + continue; + } + + /* Get the reloc for the address from which the register is + being loaded. This reloc will tell us which function is + actually being called. */ + for (irelfn = internal_relocs; irelfn < irelend; irelfn++) + if (irelfn->r_offset == paddr + && ELF32_R_TYPE (irelfn->r_info) == (int) R_SH_DIR32) + break; + if (irelfn >= irelend) + { + ((*_bfd_error_handler) + ("%s: 0x%lx: warning: could not find expected reloc", + bfd_get_filename (abfd), (unsigned long) paddr)); + continue; + } + + /* Read the local symbols. */ + if (extsyms == NULL) + { + if (symtab_hdr->contents != NULL) + extsyms = (Elf32_External_Sym *) symtab_hdr->contents; + else + { + extsyms = ((Elf32_External_Sym *) + bfd_malloc (symtab_hdr->sh_info + * sizeof (Elf32_External_Sym))); + if (extsyms == NULL) + goto error_return; + free_extsyms = extsyms; + if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0 + || (bfd_read (extsyms, sizeof (Elf32_External_Sym), + symtab_hdr->sh_info, abfd) + != (symtab_hdr->sh_info * sizeof (Elf32_External_Sym)))) + goto error_return; + } + } + + /* Get the value of the symbol referred to by the reloc. */ + if (ELF32_R_SYM (irelfn->r_info) < symtab_hdr->sh_info) + { + Elf_Internal_Sym isym; + + /* A local symbol. */ + bfd_elf32_swap_symbol_in (abfd, + extsyms + ELF32_R_SYM (irelfn->r_info), + &isym); + + if (isym.st_shndx != _bfd_elf_section_from_bfd_section (abfd, sec)) + { + ((*_bfd_error_handler) + ("%s: 0x%lx: warning: symbol in unexpected section", + bfd_get_filename (abfd), (unsigned long) paddr)); + continue; + } + + symval = (isym.st_value + + sec->output_section->vma + + sec->output_offset); + } + else + { + unsigned long indx; + struct elf_link_hash_entry *h; + + indx = ELF32_R_SYM (irelfn->r_info) - symtab_hdr->sh_info; + h = elf_sym_hashes (abfd)[indx]; + BFD_ASSERT (h != NULL); + if (h->root.type != bfd_link_hash_defined + && h->root.type != bfd_link_hash_defweak) + { + /* This appears to be a reference to an undefined + symbol. Just ignore it--it will be caught by the + regular reloc processing. */ + continue; + } + + symval = (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset); + } + + symval += bfd_get_32 (abfd, contents + paddr); + + /* See if this function call can be shortened. */ + foff = (symval + - (irel->r_offset + + sec->output_section->vma + + sec->output_offset + + 4)); + if (foff < -0x1000 || foff >= 0x1000) + { + /* After all that work, we can't shorten this function call. */ + continue; + } + + /* Shorten the function call. */ + + /* For simplicity of coding, we are going to modify the section + contents, the section relocs, and the BFD symbol table. We + must tell the rest of the code not to free up this + information. It would be possible to instead create a table + of changes which have to be made, as is done in coff-mips.c; + that would be more work, but would require less memory when + the linker is run. */ + + elf_section_data (sec)->relocs = internal_relocs; + free_relocs = NULL; + + elf_section_data (sec)->this_hdr.contents = contents; + free_contents = NULL; + + symtab_hdr->contents = (bfd_byte *) extsyms; + free_extsyms = NULL; + + /* Replace the jsr with a bsr. */ + + /* Change the R_SH_USES reloc into an R_SH_IND12W reloc, and + replace the jsr with a bsr. */ + irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irelfn->r_info), R_SH_IND12W); + if (ELF32_R_SYM (irelfn->r_info) < symtab_hdr->sh_info) + { + /* If this needs to be changed because of future relaxing, + it will be handled here like other internal IND12W + relocs. */ + bfd_put_16 (abfd, + 0xb000 | ((foff >> 1) & 0xfff), + contents + irel->r_offset); + } + else + { + /* We can't fully resolve this yet, because the external + symbol value may be changed by future relaxing. We let + the final link phase handle it. */ + bfd_put_16 (abfd, 0xb000, contents + irel->r_offset); + } + + /* See if there is another R_SH_USES reloc referring to the same + register load. */ + for (irelscan = internal_relocs; irelscan < irelend; irelscan++) + if (ELF32_R_TYPE (irelscan->r_info) == (int) R_SH_USES + && laddr == irelscan->r_offset + 4 + irelscan->r_addend) + break; + if (irelscan < irelend) + { + /* Some other function call depends upon this register load, + and we have not yet converted that function call. + Indeed, we may never be able to convert it. There is + nothing else we can do at this point. */ + continue; + } + + /* Look for a R_SH_COUNT reloc on the location where the + function address is stored. Do this before deleting any + bytes, to avoid confusion about the address. */ + for (irelcount = internal_relocs; irelcount < irelend; irelcount++) + if (irelcount->r_offset == paddr + && ELF32_R_TYPE (irelcount->r_info) == (int) R_SH_COUNT) + break; + + /* Delete the register load. */ + if (! sh_elf_relax_delete_bytes (abfd, sec, laddr, 2)) + goto error_return; + + /* That will change things, so, just in case it permits some + other function call to come within range, we should relax + again. Note that this is not required, and it may be slow. */ + *again = true; + + /* Now check whether we got a COUNT reloc. */ + if (irelcount >= irelend) + { + ((*_bfd_error_handler) + ("%s: 0x%lx: warning: could not find expected COUNT reloc", + bfd_get_filename (abfd), (unsigned long) paddr)); + continue; + } + + /* The number of uses is stored in the r_addend field. We've + just deleted one. */ + if (irelcount->r_addend == 0) + { + ((*_bfd_error_handler) ("%s: 0x%lx: warning: bad count", + bfd_get_filename (abfd), + (unsigned long) paddr)); + continue; + } + + --irelcount->r_addend; + + /* If there are no more uses, we can delete the address. Reload + the address from irelfn, in case it was changed by the + previous call to sh_elf_relax_delete_bytes. */ + if (irelcount->r_addend == 0) + { + if (! sh_elf_relax_delete_bytes (abfd, sec, irelfn->r_offset, 4)) + goto error_return; + } + + /* We've done all we can with that function call. */ + } + + /* Look for load and store instructions that we can align on four + byte boundaries. */ + if (have_code) + { + boolean swapped; + + /* Get the section contents. */ + if (contents == NULL) + { + if (elf_section_data (sec)->this_hdr.contents != NULL) + contents = elf_section_data (sec)->this_hdr.contents; + else + { + contents = (bfd_byte *) bfd_malloc (sec->_raw_size); + if (contents == NULL) + goto error_return; + free_contents = contents; + + if (! bfd_get_section_contents (abfd, sec, contents, + (file_ptr) 0, sec->_raw_size)) + goto error_return; + } + } + + if (! sh_elf_align_loads (abfd, sec, internal_relocs, contents, + &swapped)) + goto error_return; + + if (swapped) + { + elf_section_data (sec)->relocs = internal_relocs; + free_relocs = NULL; + + elf_section_data (sec)->this_hdr.contents = contents; + free_contents = NULL; + + symtab_hdr->contents = (bfd_byte *) extsyms; + free_extsyms = NULL; + } + } + + if (free_relocs != NULL) + { + free (free_relocs); + free_relocs = NULL; + } + + if (free_contents != NULL) + { + if (! link_info->keep_memory) + free (free_contents); + else + { + /* Cache the section contents for elf_link_input_bfd. */ + elf_section_data (sec)->this_hdr.contents = contents; + } + free_contents = NULL; + } + + if (free_extsyms != NULL) + { + if (! link_info->keep_memory) + free (free_extsyms); + else + { + /* Cache the symbols for elf_link_input_bfd. */ + symtab_hdr->contents = extsyms; + } + free_extsyms = NULL; + } + + return true; + + error_return: + if (free_relocs != NULL) + free (free_relocs); + if (free_contents != NULL) + free (free_contents); + if (free_extsyms != NULL) + free (free_extsyms); + return false; +} + +/* Delete some bytes from a section while relaxing. FIXME: There is a + lot of duplication between this function and sh_relax_delete_bytes + in coff-sh.c. */ + +static boolean +sh_elf_relax_delete_bytes (abfd, sec, addr, count) + bfd *abfd; + asection *sec; + bfd_vma addr; + int count; +{ + Elf_Internal_Shdr *symtab_hdr; + Elf32_External_Sym *extsyms; + int shndx; + bfd_byte *contents; + Elf_Internal_Rela *irel, *irelend; + Elf_Internal_Rela *irelalign; + bfd_vma toaddr; + Elf32_External_Sym *esym, *esymend; + struct elf_link_hash_entry **sym_hash, **sym_hash_end; + asection *o; + + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + extsyms = (Elf32_External_Sym *) symtab_hdr->contents; + + shndx = _bfd_elf_section_from_bfd_section (abfd, sec); + + contents = elf_section_data (sec)->this_hdr.contents; + + /* The deletion must stop at the next ALIGN reloc for an aligment + power larger than the number of bytes we are deleting. */ + + irelalign = NULL; + toaddr = sec->_cooked_size; + + irel = elf_section_data (sec)->relocs; + irelend = irel + sec->reloc_count; + for (; irel < irelend; irel++) + { + if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_ALIGN + && irel->r_offset > addr + && count < (1 << irel->r_addend)) + { + irelalign = irel; + toaddr = irel->r_offset; + break; + } + } + + /* Actually delete the bytes. */ + memmove (contents + addr, contents + addr + count, toaddr - addr - count); + if (irelalign == NULL) + sec->_cooked_size -= count; + else + { + int i; + +#define NOP_OPCODE (0x0009) + + BFD_ASSERT ((count & 1) == 0); + for (i = 0; i < count; i += 2) + bfd_put_16 (abfd, NOP_OPCODE, contents + toaddr - count + i); + } + + /* Adjust all the relocs. */ + for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) + { + bfd_vma nraddr, start, stop; + int insn = 0; + Elf_Internal_Sym sym; + int off, adjust, oinsn; + bfd_signed_vma voff; + boolean overflow; + + /* Get the new reloc address. */ + nraddr = irel->r_offset; + if ((irel->r_offset > addr + && irel->r_offset < toaddr) + || (ELF32_R_TYPE (irel->r_info) == (int) R_SH_ALIGN + && irel->r_offset == toaddr)) + nraddr -= count; + + /* See if this reloc was for the bytes we have deleted, in which + case we no longer care about it. Don't delete relocs which + represent addresses, though. */ + if (irel->r_offset >= addr + && irel->r_offset < addr + count + && ELF32_R_TYPE (irel->r_info) != (int) R_SH_ALIGN + && ELF32_R_TYPE (irel->r_info) != (int) R_SH_CODE + && ELF32_R_TYPE (irel->r_info) != (int) R_SH_DATA) + irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), + (int) R_SH_NONE); + + /* If this is a PC relative reloc, see if the range it covers + includes the bytes we have deleted. */ + switch ((enum sh_reloc_type) ELF32_R_TYPE (irel->r_info)) + { + default: + break; + + case R_SH_DIR8WPN: + case R_SH_IND12W: + case R_SH_DIR8WPZ: + case R_SH_DIR8WPL: + start = irel->r_offset; + insn = bfd_get_16 (abfd, contents + nraddr); + break; + } + + switch ((enum sh_reloc_type) ELF32_R_TYPE (irel->r_info)) + { + default: + start = stop = addr; + break; + + case R_SH_DIR32: + /* If this reloc is against a symbol defined in this + section, and the symbol will not be adjusted below, we + must check the addend to see it will put the value in + range to be adjusted, and hence must be changed. */ + if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) + { + bfd_elf32_swap_symbol_in (abfd, + extsyms + ELF32_R_SYM (irel->r_info), + &sym); + if (sym.st_shndx == shndx + && (sym.st_value <= addr + || sym.st_value >= toaddr)) + { + bfd_vma val; + + val = bfd_get_32 (abfd, contents + nraddr); + val += sym.st_value; + if (val >= addr && val < toaddr) + bfd_put_32 (abfd, val - count, contents + nraddr); + } + } + start = stop = addr; + break; + + case R_SH_DIR8WPN: + off = insn & 0xff; + if (off & 0x80) + off -= 0x100; + stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2); + break; + + case R_SH_IND12W: + if (ELF32_R_SYM (irel->r_info) >= symtab_hdr->sh_info) + start = stop = addr; + else + { + off = insn & 0xfff; + if (off & 0x800) + off -= 0x1000; + stop = (bfd_vma) ((bfd_signed_vma) start + 4 + off * 2); + } + break; + + case R_SH_DIR8WPZ: + off = insn & 0xff; + stop = start + 4 + off * 2; + break; + + case R_SH_DIR8WPL: + off = insn & 0xff; + stop = (start &~ (bfd_vma) 3) + 4 + off * 4; + break; + + case R_SH_SWITCH16: + case R_SH_SWITCH32: + /* These relocs types represent + .word L2-L1 + The r_offset field holds the difference between the reloc + address and L1. That is the start of the reloc, and + adding in the contents gives us the top. We must adjust + both the r_offset field and the section contents. */ + + start = irel->r_offset; + stop = (bfd_vma) ((bfd_signed_vma) start - (long) irel->r_addend); + + if (start > addr + && start < toaddr + && (stop <= addr || stop >= toaddr)) + irel->r_addend += count; + else if (stop > addr + && stop < toaddr + && (start <= addr || start >= toaddr)) + irel->r_addend -= count; + + start = stop; + + if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_SWITCH16) + voff = bfd_get_signed_16 (abfd, contents + nraddr); + else + voff = bfd_get_signed_32 (abfd, contents + nraddr); + stop = (bfd_vma) ((bfd_signed_vma) start + voff); + + break; + + case R_SH_USES: + start = irel->r_offset; + stop = (bfd_vma) ((bfd_signed_vma) start + + (long) irel->r_addend + + 4); + break; + } + + if (start > addr + && start < toaddr + && (stop <= addr || stop >= toaddr)) + adjust = count; + else if (stop > addr + && stop < toaddr + && (start <= addr || start >= toaddr)) + adjust = - count; + else + adjust = 0; + + if (adjust != 0) + { + oinsn = insn; + overflow = false; + switch ((enum sh_reloc_type) ELF32_R_TYPE (irel->r_info)) + { + default: + abort (); + break; + + case R_SH_DIR8WPN: + case R_SH_DIR8WPZ: + insn += adjust / 2; + if ((oinsn & 0xff00) != (insn & 0xff00)) + overflow = true; + bfd_put_16 (abfd, insn, contents + nraddr); + break; + + case R_SH_IND12W: + insn += adjust / 2; + if ((oinsn & 0xf000) != (insn & 0xf000)) + overflow = true; + bfd_put_16 (abfd, insn, contents + nraddr); + break; + + case R_SH_DIR8WPL: + BFD_ASSERT (adjust == count || count >= 4); + if (count >= 4) + insn += adjust / 4; + else + { + if ((irel->r_offset & 3) == 0) + ++insn; + } + if ((oinsn & 0xff00) != (insn & 0xff00)) + overflow = true; + bfd_put_16 (abfd, insn, contents + nraddr); + break; + + case R_SH_SWITCH16: + voff += adjust; + if (voff < - 0x8000 || voff >= 0x8000) + overflow = true; + bfd_put_signed_16 (abfd, voff, contents + nraddr); + break; + + case R_SH_SWITCH32: + voff += adjust; + bfd_put_signed_32 (abfd, voff, contents + nraddr); + break; + + case R_SH_USES: + irel->r_addend += adjust; + break; + } + + if (overflow) + { + ((*_bfd_error_handler) + ("%s: 0x%lx: fatal: reloc overflow while relaxing", + bfd_get_filename (abfd), (unsigned long) irel->r_offset)); + bfd_set_error (bfd_error_bad_value); + return false; + } + } + + irel->r_offset = nraddr; + } + + /* Look through all the other sections. If there contain any IMM32 + relocs against internal symbols which we are not going to adjust + below, we may need to adjust the addends. */ + for (o = abfd->sections; o != NULL; o = o->next) + { + Elf_Internal_Rela *internal_relocs; + Elf_Internal_Rela *irelscan, *irelscanend; + bfd_byte *ocontents; + + if (o == sec + || (o->flags & SEC_RELOC) == 0 + || o->reloc_count == 0) + continue; + + /* We always cache the relocs. Perhaps, if info->keep_memory is + false, we should free them, if we are permitted to, when we + leave sh_coff_relax_section. */ + internal_relocs = (_bfd_elf32_link_read_relocs + (abfd, o, (PTR) NULL, (Elf_Internal_Rela *) NULL, + true)); + if (internal_relocs == NULL) + return false; + + ocontents = NULL; + irelscanend = internal_relocs + o->reloc_count; + for (irelscan = internal_relocs; irelscan < irelscanend; irelscan++) + { + Elf_Internal_Sym sym; + + if (ELF32_R_TYPE (irelscan->r_info) != (int) R_SH_DIR32) + continue; + + if (ELF32_R_SYM (irelscan->r_info) >= symtab_hdr->sh_info) + continue; + + bfd_elf32_swap_symbol_in (abfd, + extsyms + ELF32_R_SYM (irelscan->r_info), + &sym); + + if (sym.st_shndx == shndx + && (sym.st_value <= addr + || sym.st_value >= toaddr)) + { + bfd_vma val; + + if (ocontents == NULL) + { + if (elf_section_data (o)->this_hdr.contents != NULL) + ocontents = elf_section_data (o)->this_hdr.contents; + else + { + /* We always cache the section contents. + Perhaps, if info->keep_memory is false, we + should free them, if we are permitted to, + when we leave sh_coff_relax_section. */ + ocontents = (bfd_byte *) bfd_malloc (o->_raw_size); + if (ocontents == NULL) + return false; + if (! bfd_get_section_contents (abfd, o, ocontents, + (file_ptr) 0, + o->_raw_size)) + return false; + elf_section_data (o)->this_hdr.contents = ocontents; + } + } + + val = bfd_get_32 (abfd, ocontents + irelscan->r_offset); + val += sym.st_value; + if (val >= addr && val < toaddr) + bfd_put_32 (abfd, val - count, + ocontents + irelscan->r_offset); + } + } + } + + /* Adjust all the symbols. */ + esym = extsyms; + esymend = esym + symtab_hdr->sh_info; + for (; esym < esymend; esym++) + { + Elf_Internal_Sym isym; + + bfd_elf32_swap_symbol_in (abfd, esym, &isym); + + if (isym.st_shndx == shndx + && isym.st_value > addr + && isym.st_value < toaddr) + { + isym.st_value -= count; + bfd_elf32_swap_symbol_out (abfd, &isym, esym); + } + } + + sym_hash = elf_sym_hashes (abfd); + sym_hash_end = (sym_hash + + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) + - symtab_hdr->sh_info)); + for (; sym_hash < sym_hash_end; sym_hash++) + { + if (((*sym_hash)->root.type == bfd_link_hash_defined + || (*sym_hash)->root.type == bfd_link_hash_defweak) + && (*sym_hash)->root.u.def.section == sec + && (*sym_hash)->root.u.def.value > addr + && (*sym_hash)->root.u.def.value < toaddr) + { + (*sym_hash)->root.u.def.value -= count; + } + } + + /* See if we can move the ALIGN reloc forward. We have adjusted + r_offset for it already. */ + if (irelalign != NULL) + { + bfd_vma alignto, alignaddr; + + alignto = BFD_ALIGN (toaddr, 1 << irelalign->r_addend); + alignaddr = BFD_ALIGN (irelalign->r_offset, + 1 << irelalign->r_addend); + if (alignto != alignaddr) + { + /* Tail recursion. */ + return sh_elf_relax_delete_bytes (abfd, sec, alignaddr, + alignto - alignaddr); + } + } + + return true; +} + +/* Look for loads and stores which we can align to four byte + boundaries. This is like sh_align_loads in coff-sh.c. */ + +static boolean +sh_elf_align_loads (abfd, sec, internal_relocs, contents, pswapped) + bfd *abfd; + asection *sec; + Elf_Internal_Rela *internal_relocs; + bfd_byte *contents; + boolean *pswapped; +{ + Elf_Internal_Rela *irel, *irelend; + bfd_vma *labels = NULL; + bfd_vma *label, *label_end; + + *pswapped = false; + + irelend = internal_relocs + sec->reloc_count; + + /* Get all the addresses with labels on them. */ + labels = (bfd_vma *) bfd_malloc (sec->reloc_count * sizeof (bfd_vma)); + if (labels == NULL) + goto error_return; + label_end = labels; + for (irel = internal_relocs; irel < irelend; irel++) + { + if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_LABEL) + { + *label_end = irel->r_offset; + ++label_end; + } + } + + /* Note that the assembler currently always outputs relocs in + address order. If that ever changes, this code will need to sort + the label values and the relocs. */ + + label = labels; + + for (irel = internal_relocs; irel < irelend; irel++) + { + bfd_vma start, stop; + + if (ELF32_R_TYPE (irel->r_info) != (int) R_SH_CODE) + continue; + + start = irel->r_offset; + + for (irel++; irel < irelend; irel++) + if (ELF32_R_TYPE (irel->r_info) == (int) R_SH_DATA) + break; + if (irel < irelend) + stop = irel->r_offset; + else + stop = sec->_cooked_size; + + if (! _bfd_sh_align_load_span (abfd, sec, contents, sh_elf_swap_insns, + (PTR) internal_relocs, &label, + label_end, start, stop, pswapped)) + goto error_return; + } + + free (labels); + + return true; + + error_return: + if (labels != NULL) + free (labels); + return false; +} + +/* Swap two SH instructions. This is like sh_swap_insns in coff-sh.c. */ + +static boolean +sh_elf_swap_insns (abfd, sec, relocs, contents, addr) + bfd *abfd; + asection *sec; + PTR relocs; + bfd_byte *contents; + bfd_vma addr; +{ + Elf_Internal_Rela *internal_relocs = (Elf_Internal_Rela *) relocs; + unsigned short i1, i2; + Elf_Internal_Rela *irel, *irelend; + + /* Swap the instructions themselves. */ + i1 = bfd_get_16 (abfd, contents + addr); + i2 = bfd_get_16 (abfd, contents + addr + 2); + bfd_put_16 (abfd, i2, contents + addr); + bfd_put_16 (abfd, i1, contents + addr + 2); + + /* Adjust all reloc addresses. */ + irelend = internal_relocs + sec->reloc_count; + for (irel = internal_relocs; irel < irelend; irel++) + { + enum sh_reloc_type type; + int add; + + /* There are a few special types of relocs that we don't want to + adjust. These relocs do not apply to the instruction itself, + but are only associated with the address. */ + type = (enum sh_reloc_type) ELF32_R_TYPE (irel->r_info); + if (type == R_SH_ALIGN + || type == R_SH_CODE + || type == R_SH_DATA + || type == R_SH_LABEL) + continue; + + /* If an R_SH_USES reloc points to one of the addresses being + swapped, we must adjust it. It would be incorrect to do this + for a jump, though, since we want to execute both + instructions after the jump. (We have avoided swapping + around a label, so the jump will not wind up executing an + instruction it shouldn't). */ + if (type == R_SH_USES) + { + bfd_vma off; + + off = irel->r_offset + 4 + irel->r_addend; + if (off == addr) + irel->r_offset += 2; + else if (off == addr + 2) + irel->r_offset -= 2; + } + + if (irel->r_offset == addr) + { + irel->r_offset += 2; + add = -2; + } + else if (irel->r_offset == addr + 2) + { + irel->r_offset -= 2; + add = 2; + } + else + add = 0; + + if (add != 0) + { + bfd_byte *loc; + unsigned short insn, oinsn; + boolean overflow; + + loc = contents + irel->r_offset; + overflow = false; + switch (type) + { + default: + break; + + case R_SH_DIR8WPN: + case R_SH_DIR8WPZ: + insn = bfd_get_16 (abfd, loc); + oinsn = insn; + insn += add / 2; + if ((oinsn & 0xff00) != (insn & 0xff00)) + overflow = true; + bfd_put_16 (abfd, insn, loc); + break; + + case R_SH_IND12W: + insn = bfd_get_16 (abfd, loc); + oinsn = insn; + insn += add / 2; + if ((oinsn & 0xf000) != (insn & 0xf000)) + overflow = true; + bfd_put_16 (abfd, insn, loc); + break; + + case R_SH_DIR8WPL: + /* This reloc ignores the least significant 3 bits of + the program counter before adding in the offset. + This means that if ADDR is at an even address, the + swap will not affect the offset. If ADDR is an at an + odd address, then the instruction will be crossing a + four byte boundary, and must be adjusted. */ + if ((addr & 3) != 0) + { + insn = bfd_get_16 (abfd, loc); + oinsn = insn; + insn += add / 2; + if ((oinsn & 0xff00) != (insn & 0xff00)) + overflow = true; + bfd_put_16 (abfd, insn, loc); + } + + break; + } + + if (overflow) + { + ((*_bfd_error_handler) + ("%s: 0x%lx: fatal: reloc overflow while relaxing", + bfd_get_filename (abfd), (unsigned long) irel->r_offset)); + bfd_set_error (bfd_error_bad_value); + return false; + } + } + } + + return true; +} + +/* Relocate an SH ELF section. */ + +static boolean +sh_elf_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; +{ + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + Elf_Internal_Rela *rel, *relend; + + symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (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; + Elf_Internal_Sym *sym; + asection *sec; + struct elf_link_hash_entry *h; + bfd_vma relocation; + bfd_reloc_status_type r; + + 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]; + rel->r_addend += sec->output_offset + sym->st_value; + } + } + + continue; + } + + r_type = ELF32_R_TYPE (rel->r_info); + + /* Many of the relocs are only used for relaxing, and are + handled entirely by the relaxation code. */ + if (r_type > (int) LAST_INVALID_RELOC) + continue; + + if (r_type < 0 + || r_type >= (int) FIRST_INVALID_RELOC) + { + bfd_set_error (bfd_error_bad_value); + return false; + } + + /* FIXME: This is certainly incorrect. However, it is how the + COFF linker works. */ + if (r_type != (int) R_SH_DIR32 + && r_type != (int) R_SH_IND12W) + continue; + + howto = sh_elf_howto_table + r_type; + + r_symndx = ELF32_R_SYM (rel->r_info); + + /* This is a final link. */ + h = NULL; + sym = NULL; + sec = NULL; + if (r_symndx < symtab_hdr->sh_info) + { + /* There is nothing to be done for an internal IND12W + relocation. FIXME: This is probably wrong, but it's how + the COFF relocations work. */ + if (r_type == (int) R_SH_IND12W) + continue; + sym = local_syms + r_symndx; + sec = local_sections[r_symndx]; + relocation = (sec->output_section->vma + + sec->output_offset + + sym->st_value); + } + 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; + 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->callbacks->undefined_symbol) + (info, h->root.root.string, input_bfd, + input_section, rel->r_offset))) + return false; + relocation = 0; + } + } + + /* FIXME: This is how the COFF relocations work. */ + if (r_type == (int) R_SH_IND12W) + relocation -= 4; + + /* FIXME: We should use the addend, but the COFF relocations + don't. */ + r = _bfd_final_link_relocate (howto, input_bfd, input_section, + contents, rel->r_offset, + relocation, 0); + + if (r != bfd_reloc_ok) + { + switch (r) + { + 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, rel->r_offset))) + return false; + } + break; + } + } + } + + return true; +} + +/* This is a version of bfd_generic_get_relocated_section_contents + which uses sh_elf_relocate_section. */ + +static bfd_byte * +sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order, + data, relocateable, symbols) + bfd *output_bfd; + struct bfd_link_info *link_info; + struct bfd_link_order *link_order; + bfd_byte *data; + boolean relocateable; + asymbol **symbols; +{ + Elf_Internal_Shdr *symtab_hdr; + asection *input_section = link_order->u.indirect.section; + bfd *input_bfd = input_section->owner; + asection **sections = NULL; + Elf_Internal_Rela *internal_relocs = NULL; + Elf32_External_Sym *external_syms = NULL; + Elf_Internal_Sym *internal_syms = NULL; + + /* We only need to handle the case of relaxing, or of having a + particular set of section contents, specially. */ + if (relocateable + || elf_section_data (input_section)->this_hdr.contents == NULL) + return bfd_generic_get_relocated_section_contents (output_bfd, link_info, + link_order, data, + relocateable, + symbols); + + symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; + + memcpy (data, elf_section_data (input_section)->this_hdr.contents, + input_section->_raw_size); + + if ((input_section->flags & SEC_RELOC) != 0 + && input_section->reloc_count > 0) + { + Elf_Internal_Sym *isymp; + asection **secpp; + Elf32_External_Sym *esym, *esymend; + + if (symtab_hdr->contents != NULL) + external_syms = (Elf32_External_Sym *) symtab_hdr->contents; + else + { + external_syms = ((Elf32_External_Sym *) + bfd_malloc (symtab_hdr->sh_info + * sizeof (Elf32_External_Sym))); + if (external_syms == NULL && symtab_hdr->sh_info > 0) + goto error_return; + if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0 + || (bfd_read (external_syms, sizeof (Elf32_External_Sym), + symtab_hdr->sh_info, input_bfd) + != (symtab_hdr->sh_info * sizeof (Elf32_External_Sym)))) + goto error_return; + } + + internal_relocs = (_bfd_elf32_link_read_relocs + (input_bfd, input_section, (PTR) NULL, + (Elf_Internal_Rela *) NULL, false)); + if (internal_relocs == NULL) + goto error_return; + + internal_syms = ((Elf_Internal_Sym *) + bfd_malloc (symtab_hdr->sh_info + * sizeof (Elf_Internal_Sym))); + if (internal_syms == NULL && symtab_hdr->sh_info > 0) + goto error_return; + + sections = (asection **) bfd_malloc (symtab_hdr->sh_info + * sizeof (asection *)); + if (sections == NULL && symtab_hdr->sh_info > 0) + goto error_return; + + isymp = internal_syms; + secpp = sections; + esym = external_syms; + esymend = esym + symtab_hdr->sh_info; + for (; esym < esymend; ++esym, ++isymp, ++secpp) + { + asection *isec; + + bfd_elf32_swap_symbol_in (input_bfd, esym, isymp); + + if (isymp->st_shndx == SHN_UNDEF) + isec = bfd_und_section_ptr; + else if (isymp->st_shndx > 0 && isymp->st_shndx < SHN_LORESERVE) + isec = bfd_section_from_elf_index (input_bfd, isymp->st_shndx); + else if (isymp->st_shndx == SHN_ABS) + isec = bfd_abs_section_ptr; + else if (isymp->st_shndx == SHN_COMMON) + isec = bfd_com_section_ptr; + else + { + /* Who knows? */ + isec = NULL; + } + + *secpp = isec; + } + + if (! sh_elf_relocate_section (output_bfd, link_info, input_bfd, + input_section, data, internal_relocs, + internal_syms, sections)) + goto error_return; + + if (sections != NULL) + free (sections); + sections = NULL; + if (internal_syms != NULL) + free (internal_syms); + internal_syms = NULL; + if (external_syms != NULL && symtab_hdr->contents == NULL) + free (external_syms); + external_syms = NULL; + if (internal_relocs != elf_section_data (input_section)->relocs) + free (internal_relocs); + internal_relocs = NULL; + } + + return data; + + error_return: + if (internal_relocs != NULL + && internal_relocs != elf_section_data (input_section)->relocs) + free (internal_relocs); + if (external_syms != NULL && symtab_hdr->contents == NULL) + free (external_syms); + if (internal_syms != NULL) + free (internal_syms); + if (sections != NULL) + free (sections); + return NULL; +} + +#define TARGET_BIG_SYM bfd_elf32_sh_vec +#define TARGET_BIG_NAME "elf32-sh" +#define TARGET_LITTLE_SYM bfd_elf32_shl_vec +#define TARGET_LITTLE_NAME "elf32-shl" +#define ELF_ARCH bfd_arch_sh +#define ELF_MACHINE_CODE EM_SH +#define ELF_MAXPAGESIZE 0x1 + +#define elf_symbol_leading_char '_' + +#define bfd_elf32_bfd_reloc_type_lookup sh_elf_reloc_type_lookup +#define elf_info_to_howto sh_elf_info_to_howto +#define bfd_elf32_bfd_relax_section sh_elf_relax_section +#define elf_backend_relocate_section sh_elf_relocate_section +#define bfd_elf32_bfd_get_relocated_section_contents \ + sh_elf_get_relocated_section_contents + +#include "elf32-target.h" diff --git a/gnu/usr.bin/binutils/bfd/elf64-alpha.c b/gnu/usr.bin/binutils/bfd/elf64-alpha.c new file mode 100644 index 00000000000..52d1732b2d0 --- /dev/null +++ b/gnu/usr.bin/binutils/bfd/elf64-alpha.c @@ -0,0 +1,3335 @@ +/* ALPHA-specific support for 64-bit ELF + Copyright 1996 Free Software Foundation, Inc. + Contributed by Richard Henderson . + +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. */ + +/* We need a published ABI spec for this. Until one comes out, don't + assume this'll remain unchanged forever. */ + +#include "bfd.h" +#include "sysdep.h" +#include "libbfd.h" +#include "elf-bfd.h" + +#include "elf/alpha.h" + +#define ALPHAECOFF + +#define NO_COFF_RELOCS +#define NO_COFF_SYMBOLS +#define NO_COFF_LINENOS + +/* Get the ECOFF swapping routines. Needed for the debug information. */ +#include "coff/internal.h" +#include "coff/sym.h" +#include "coff/symconst.h" +#include "coff/ecoff.h" +#include "coff/alpha.h" +#include "aout/ar.h" +#include "libcoff.h" +#include "libecoff.h" +#define ECOFF_64 +#include "ecoffswap.h" + +static struct bfd_hash_entry * elf64_alpha_link_hash_newfunc + PARAMS((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); +static struct bfd_link_hash_table * elf64_alpha_bfd_link_hash_table_create + PARAMS((bfd *)); + +static bfd_reloc_status_type elf64_alpha_reloc_nil + PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static bfd_reloc_status_type elf64_alpha_do_reloc_gpdisp + PARAMS((bfd *, bfd_vma, bfd_byte *, bfd_byte *)); +static bfd_reloc_status_type elf64_alpha_reloc_gpdisp + PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static bfd_reloc_status_type elf64_alpha_reloc_op_push + PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static bfd_reloc_status_type elf64_alpha_reloc_op_store + PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static bfd_reloc_status_type elf64_alpha_reloc_op_psub + PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static bfd_reloc_status_type elf64_alpha_reloc_op_prshift + PARAMS((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); + +static reloc_howto_type * elf64_alpha_bfd_reloc_type_lookup + PARAMS((bfd *, bfd_reloc_code_real_type)); +static void elf64_alpha_info_to_howto + PARAMS((bfd *, arelent *, Elf64_Internal_Rela *)); + +static boolean elf64_alpha_object_p + PARAMS((bfd *)); +static boolean elf64_alpha_section_from_shdr + PARAMS((bfd *, Elf64_Internal_Shdr *, char *)); +static boolean elf64_alpha_fake_sections + PARAMS((bfd *, Elf64_Internal_Shdr *, asection *)); +static int elf64_alpha_additional_program_headers + PARAMS((bfd *)); +static boolean elf64_alpha_create_got_section + PARAMS((bfd *, struct bfd_link_info *)); +static boolean elf64_alpha_create_dynamic_sections + PARAMS((bfd *, struct bfd_link_info *)); + +static boolean elf64_alpha_read_ecoff_info + PARAMS((bfd *, asection *, struct ecoff_debug_info *)); +static boolean elf64_alpha_is_local_label + PARAMS((bfd *, asymbol *)); +static boolean elf64_alpha_find_nearest_line + PARAMS((bfd *, asection *, asymbol **, bfd_vma, const char **, + const char **, unsigned int *)); + +#if defined(__STDC__) || defined(ALMOST_STDC) +struct alpha_elf_link_hash_entry; +#endif + +static boolean elf64_alpha_output_extsym + PARAMS((struct alpha_elf_link_hash_entry *, PTR)); + +static boolean elf64_alpha_check_relocs + PARAMS((bfd *, struct bfd_link_info *, asection *sec, + const Elf_Internal_Rela *)); +static boolean elf64_alpha_adjust_dynamic_symbol + PARAMS((struct bfd_link_info *, struct elf_link_hash_entry *)); +static boolean elf64_alpha_size_dynamic_sections + PARAMS((bfd *, struct bfd_link_info *)); +static boolean elf64_alpha_adjust_dynindx + PARAMS((struct elf_link_hash_entry *, PTR)); +static boolean elf64_alpha_relocate_section + PARAMS((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, + Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); +static boolean elf64_alpha_finish_dynamic_symbol + PARAMS((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, + Elf_Internal_Sym *)); +static boolean elf64_alpha_finish_dynamic_sections + PARAMS((bfd *, struct bfd_link_info *)); +static boolean elf64_alpha_final_link + PARAMS((bfd *, struct bfd_link_info *)); + + +#define alpha_elf_tdata(bfd) \ + ((struct alpha_elf_obj_tdata *)elf_tdata(bfd)->tdata) + +struct alpha_elf_link_hash_entry +{ + struct elf_link_hash_entry root; + + /* External symbol information. */ + EXTR esym; + + unsigned char flags; + /* Contexts (LITUSE) in which a literal was referenced. */ +#define ALPHA_ELF_LINK_HASH_LU_ADDR 01 +#define ALPHA_ELF_LINK_HASH_LU_MEM 02 +#define ALPHA_ELF_LINK_HASH_LU_FUNC 04 +}; + +/* Alpha ELF linker hash table. */ + +struct alpha_elf_link_hash_table +{ + struct elf_link_hash_table root; +}; + +/* Look up an entry in a Alpha ELF linker hash table. */ + +#define alpha_elf_link_hash_lookup(table, string, create, copy, follow) \ + ((struct alpha_elf_link_hash_entry *) \ + elf_link_hash_lookup (&(table)->root, (string), (create), \ + (copy), (follow))) + +/* Traverse a Alpha ELF linker hash table. */ + +#define alpha_elf_link_hash_traverse(table, func, info) \ + (elf_link_hash_traverse \ + (&(table)->root, \ + (boolean (*) PARAMS ((struct elf_link_hash_entry *, PTR))) (func), \ + (info))) + +/* Get the Alpha ELF linker hash table from a link_info structure. */ + +#define alpha_elf_hash_table(p) \ + ((struct alpha_elf_link_hash_table *) ((p)->hash)) + +/* Create an entry in a Alpha ELF linker hash table. */ + +static struct bfd_hash_entry * +elf64_alpha_link_hash_newfunc (entry, table, string) + struct bfd_hash_entry *entry; + struct bfd_hash_table *table; + const char *string; +{ + struct alpha_elf_link_hash_entry *ret = + (struct alpha_elf_link_hash_entry *) entry; + + /* Allocate the structure if it has not already been allocated by a + subclass. */ + if (ret == (struct alpha_elf_link_hash_entry *) NULL) + ret = ((struct alpha_elf_link_hash_entry *) + bfd_hash_allocate (table, + sizeof (struct alpha_elf_link_hash_entry))); + if (ret == (struct alpha_elf_link_hash_entry *) NULL) + return (struct bfd_hash_entry *) ret; + + /* Call the allocation method of the superclass. */ + ret = ((struct alpha_elf_link_hash_entry *) + _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, + table, string)); + if (ret != (struct alpha_elf_link_hash_entry *) NULL) + { + /* Set local fields. */ + memset (&ret->esym, 0, sizeof (EXTR)); + /* We use -2 as a marker to indicate that the information has + not been set. -1 means there is no associated ifd. */ + ret->esym.ifd = -2; + ret->flags = 0; + } + + return (struct bfd_hash_entry *) ret; +} + +/* Create a Alpha ELF linker hash table. */ + +static struct bfd_link_hash_table * +elf64_alpha_bfd_link_hash_table_create (abfd) + bfd *abfd; +{ + struct alpha_elf_link_hash_table *ret; + + ret = ((struct alpha_elf_link_hash_table *) + bfd_zalloc (abfd, sizeof (struct alpha_elf_link_hash_table))); + if (ret == (struct alpha_elf_link_hash_table *) NULL) + return NULL; + + if (! _bfd_elf_link_hash_table_init (&ret->root, abfd, + elf64_alpha_link_hash_newfunc)) + { + bfd_release (abfd, ret); + return NULL; + } + + return &ret->root.root; +} + + +/* 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) + +static reloc_howto_type elf64_alpha_howto_table[] = +{ + HOWTO (R_ALPHA_NONE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + elf64_alpha_reloc_nil, /* special_function */ + "NONE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + true), /* pcrel_offset */ + + /* A 32 bit reference to a symbol. */ + HOWTO (R_ALPHA_REFLONG, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "REFLONG", /* name */ + false, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* A 64 bit reference to a symbol. */ + HOWTO (R_ALPHA_REFQUAD, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "REFQUAD", /* name */ + false, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + + /* A 32 bit GP relative offset. This is just like REFLONG except + that when the value is used the value of the gp register will be + added in. */ + HOWTO (R_ALPHA_GPREL32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + 0, /* special_function */ + "GPREL32", /* name */ + false, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* Used for an instruction that refers to memory off the GP register. */ + HOWTO (R_ALPHA_LITERAL, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + 0, /* special_function */ + "LITERAL", /* name */ + false, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* This reloc only appears immediately following a LITERAL reloc. + It identifies a use of the literal. The symbol index is special: + 1 means the literal address is in the base register of a memory + format instruction; 2 means the literal address is in the byte + offset register of a byte-manipulation instruction; 3 means the + literal address is in the target register of a jsr instruction. + This does not actually do any relocation. */ + HOWTO (R_ALPHA_LITUSE, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + elf64_alpha_reloc_nil, /* special_function */ + "LITUSE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Load the gp register. This is always used for a ldah instruction + which loads the upper 16 bits of the gp register. The symbol + index of the GPDISP instruction is an offset in bytes to the lda + instruction that loads the lower 16 bits. The value to use for + the relocation is the difference between the GP value and the + current location; the load will always be done against a register + holding the current address. + + NOTE: Unlike ECOFF, partial inplace relocation is not done. If + any offset is present in the instructions, it is an offset from + the register to the ldah instruction. This lets us avoid any + stupid hackery like inventing a gp value to do partial relocation + against. Also unlike ECOFF, we do the whole relocation off of + the GPDISP rather than a GPDISP_HI16/GPDISP_LO16 pair. An odd, + space consuming bit, that, since all the information was present + in the GPDISP_HI16 reloc. */ + HOWTO (R_ALPHA_GPDISP, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + elf64_alpha_reloc_gpdisp, /* special_function */ + "GPDISP", /* name */ + false, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + true), /* pcrel_offset */ + + /* A 21 bit branch. */ + HOWTO (R_ALPHA_BRADDR, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 21, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + 0, /* special_function */ + "BRADDR", /* name */ + false, /* partial_inplace */ + 0x1fffff, /* src_mask */ + 0x1fffff, /* dst_mask */ + true), /* pcrel_offset */ + + /* A hint for a jump to a register. */ + HOWTO (R_ALPHA_HINT, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 14, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + 0, /* special_function */ + "HINT", /* name */ + false, /* partial_inplace */ + 0x3fff, /* src_mask */ + 0x3fff, /* dst_mask */ + true), /* pcrel_offset */ + + /* 16 bit PC relative offset. */ + HOWTO (R_ALPHA_SREL16, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + 0, /* special_function */ + "SREL16", /* name */ + false, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit PC relative offset. */ + HOWTO (R_ALPHA_SREL32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + 0, /* special_function */ + "SREL32", /* name */ + false, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* A 64 bit PC relative offset. */ + HOWTO (R_ALPHA_SREL64, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + 0, /* special_function */ + "SREL64", /* name */ + false, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + + /* Push a value on the reloc evaluation stack. */ + HOWTO (ALPHA_R_OP_PUSH, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + elf64_alpha_reloc_op_push, /* special_function */ + "OP_PUSH", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Store the value from the stack at the given address. Store it in + a bitfield of size r_size starting at bit position r_offset. */ + HOWTO (ALPHA_R_OP_STORE, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + elf64_alpha_reloc_op_store, /* special_function */ + "OP_STORE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + + /* Subtract the reloc address from the value on the top of the + relocation stack. */ + HOWTO (ALPHA_R_OP_PSUB, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + elf64_alpha_reloc_op_psub, /* special_function */ + "OP_PSUB", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Shift the value on the top of the relocation stack right by the + given value. */ + HOWTO (ALPHA_R_OP_PRSHIFT, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + elf64_alpha_reloc_op_prshift, /* special_function */ + "OP_PRSHIFT", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Misc ELF relocations. */ + HOWTO (R_ALPHA_COPY, + 0, + 0, + 0, + false, + 0, + complain_overflow_dont, + bfd_elf_generic_reloc, + "COPY", + false, + 0, + 0, + true), + + HOWTO (R_ALPHA_GLOB_DAT, + 0, + 0, + 0, + false, + 0, + complain_overflow_dont, + bfd_elf_generic_reloc, + "GLOB_DAT", + false, + 0, + 0, + true), + + HOWTO (R_ALPHA_JMP_SLOT, + 0, + 0, + 0, + false, + 0, + complain_overflow_dont, + bfd_elf_generic_reloc, + "JMP_SLOT", + false, + 0, + 0, + true), + + HOWTO (R_ALPHA_RELATIVE, + 0, + 0, + 0, + false, + 0, + complain_overflow_dont, + bfd_elf_generic_reloc, + "RELATIVE", + false, + 0, + 0, + true) +}; + +static bfd_reloc_status_type +elf64_alpha_reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message) + bfd *abfd; + arelent *reloc; + asymbol *sym; + PTR data; + asection *sec; + bfd *output_bfd; + char **error_message; +{ + if (output_bfd) + reloc->address += sec->output_offset; + return bfd_reloc_ok; +} + +static bfd_reloc_status_type +elf64_alpha_do_reloc_gpdisp (abfd, gpdisp, p_ldah, p_lda) + bfd *abfd; + bfd_vma gpdisp; + bfd_byte *p_ldah, *p_lda; +{ + bfd_reloc_status_type ret = bfd_reloc_ok; + bfd_vma addend; + unsigned long i_ldah, i_lda; + + i_ldah = bfd_get_32(abfd, p_ldah); + i_lda = bfd_get_32(abfd, p_lda); + + /* Complain if the instructions are not correct. */ + if (((i_ldah >> 26) & 0x3f) != 0x09 + || ((i_lda >> 26) & 0x3f) != 0x08) + ret = bfd_reloc_dangerous; + + /* Extract the user-supplied offset, mirroring the sign extensions + that the instructions perform. */ + addend = ((i_ldah & 0xffff) << 16) | (i_lda & 0xffff); + addend = (addend ^ 0x80008000) - 0x80008000; + + gpdisp += addend; + + if ((bfd_signed_vma)gpdisp < -(bfd_signed_vma)0x80000000 + || gpdisp >= 0x7fff8000) + ret = bfd_reloc_overflow; + + /* compensate for the sign extension again. */ + i_ldah = ((i_ldah & 0xffff0000) + | (((gpdisp >> 16) + ((gpdisp >> 15) & 1)) & 0xffff)); + i_lda = (i_lda & 0xffff0000) | (gpdisp & 0xffff); + + bfd_put_32 (abfd, i_ldah, p_ldah); + bfd_put_32 (abfd, i_lda, p_lda); + + return ret; +} + +static bfd_reloc_status_type +elf64_alpha_reloc_gpdisp (abfd, reloc_entry, sym, data, input_section, + output_bfd, err_msg) + bfd *abfd; + arelent *reloc_entry; + asymbol *sym; + PTR data; + asection *input_section; + bfd *output_bfd; + char **err_msg; +{ + bfd_reloc_status_type ret; + bfd_vma gp, relocation; + bfd_byte *p_ldah, *p_lda; + + /* Don't do anything if we're not doing a final link. */ + if (output_bfd) + { + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + if (reloc_entry->address > input_section->_cooked_size || + reloc_entry->address + reloc_entry->addend > input_section->_cooked_size) + return bfd_reloc_outofrange; + + /* The gp used in the portion of the output object to which this + input object belongs is cached on the input bfd. */ + gp = _bfd_get_gp_value (abfd); + + relocation = (input_section->output_section->vma + + input_section->output_offset + + reloc_entry->address); + + p_ldah = (bfd_byte *)data + reloc_entry->address; + p_lda = p_ldah + reloc_entry->addend; + + ret = elf64_alpha_do_reloc_gpdisp (abfd, gp - relocation, p_ldah, p_lda); + + /* Complain if the instructions are not correct. */ + if (ret == bfd_reloc_dangerous) + { + *err_msg = "GPDISP relocation did not find ldah and lda instructions"; + } + + return ret; +} + +/* Due to the nature of the stack operations, I don't think more + that one entry is useful. Test this theory by setting the + stack size to a minimum. */ +/* FIXME: BFD should not use static variables. */ +#define OP_STACK_SIZE 1 +static bfd_vma elf64_alpha_op_stack[OP_STACK_SIZE]; +static int elf64_alpha_op_tos; + +static bfd_reloc_status_type +elf64_alpha_reloc_op_push (abfd, reloc_entry, sym, data, input_section, + output_bfd, err_msg) + bfd *abfd; + arelent *reloc_entry; + asymbol *sym; + PTR data; + asection *input_section; + bfd *output_bfd; + char **err_msg; +{ + bfd_reloc_status_type r = bfd_reloc_ok; + bfd_vma value; + + /* Don't do anything if we're not doing a final link. */ + if (output_bfd) + { + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + if (elf64_alpha_op_tos >= OP_STACK_SIZE) + { + *err_msg = "operation stack overflow"; + return bfd_reloc_dangerous; + } + + /* Get the symbol value. */ + /* FIXME: We should fail if this is a dynamic symbol. Check on that. */ + if (bfd_is_und_section (sym->section)) + r = bfd_reloc_undefined; + if (bfd_is_com_section (sym->section)) + value = 0; + else + value = sym->value; + value += sym->section->output_section->vma; + value += sym->section->output_offset; + value += reloc_entry->addend; + + elf64_alpha_op_stack[elf64_alpha_op_tos++] = value; + + return r; +} + +static bfd_reloc_status_type +elf64_alpha_reloc_op_store (abfd, reloc_entry, sym, data, input_section, + output_bfd, err_msg) + bfd *abfd; + arelent *reloc_entry; + asymbol *sym; + PTR data; + asection *input_section; + bfd *output_bfd; + char **err_msg; +{ + int size, offset; + bfd_vma value; + + /* Don't do anything before the final link. */ + if (output_bfd) + { + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + if (elf64_alpha_op_tos <= 0) + { + *err_msg = "operation stack underflow"; + return bfd_reloc_dangerous; + } + + /* The offset and size for this reloc are encoded into the addend + field by alpha_adjust_reloc_in. */ + offset = (reloc_entry->addend >> 8) & 0xff; + size = reloc_entry->addend & 0xff; + + value = bfd_get_64 (abfd, data + reloc_entry->address); + value &= ~((((bfd_vma)1 << size) - 1) << offset); + value |= (elf64_alpha_op_stack[--elf64_alpha_op_tos] + & (((bfd_vma)1 << size) - 1)) << offset; + bfd_put_64 (abfd, value, data + reloc_entry->address); + + return bfd_reloc_ok; +} + +static bfd_reloc_status_type +elf64_alpha_reloc_op_psub (abfd, reloc_entry, sym, data, input_section, + output_bfd, err_msg) + bfd *abfd; + arelent *reloc_entry; + asymbol *sym; + PTR data; + asection *input_section; + bfd *output_bfd; + char **err_msg; +{ + bfd_reloc_status_type r; + bfd_vma value; + + /* Don't do anything before the final link. */ + if (output_bfd) + { + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + if (elf64_alpha_op_tos <= 0) + { + *err_msg = "operation stack underflow"; + return bfd_reloc_dangerous; + } + + if (bfd_is_und_section (sym->section)) + r = bfd_reloc_undefined; + if (bfd_is_com_section (sym->section)) + value = 0; + else + value = sym->value; + value += sym->section->output_section->vma; + value += sym->section->output_offset; + value += reloc_entry->addend; + + elf64_alpha_op_stack[elf64_alpha_op_tos-1] -= value; + + return r; +} + +static bfd_reloc_status_type +elf64_alpha_reloc_op_prshift (abfd, reloc_entry, sym, data, input_section, + output_bfd, err_msg) + bfd *abfd; + arelent *reloc_entry; + asymbol *sym; + PTR data; + asection *input_section; + bfd *output_bfd; + char **err_msg; +{ + /* Don't do anything before the final link. */ + if (output_bfd) + { + reloc_entry->address += input_section->output_offset; + return bfd_reloc_ok; + } + + if (elf64_alpha_op_tos <= 0) + { + *err_msg = "operation stack underflow"; + return bfd_reloc_dangerous; + } + + elf64_alpha_op_stack[elf64_alpha_op_tos-1] >>= reloc_entry->addend; + + return bfd_reloc_ok; +} + +/* A mapping from BFD reloc types to Alpha ELF reloc types. */ + +struct elf_reloc_map +{ + bfd_reloc_code_real_type bfd_reloc_val; + int elf_reloc_val; +}; + +static const struct elf_reloc_map elf64_alpha_reloc_map[] = +{ + {BFD_RELOC_NONE, R_ALPHA_NONE}, + {BFD_RELOC_32, R_ALPHA_REFLONG}, + {BFD_RELOC_64, R_ALPHA_REFQUAD}, + {BFD_RELOC_CTOR, R_ALPHA_REFQUAD}, + {BFD_RELOC_GPREL32, R_ALPHA_GPREL32}, + {BFD_RELOC_ALPHA_LITERAL, R_ALPHA_LITERAL}, + {BFD_RELOC_ALPHA_LITUSE, R_ALPHA_LITUSE}, + {BFD_RELOC_ALPHA_GPDISP, R_ALPHA_GPDISP}, + {BFD_RELOC_23_PCREL_S2, R_ALPHA_BRADDR}, + {BFD_RELOC_ALPHA_HINT, R_ALPHA_HINT}, + {BFD_RELOC_16_PCREL, R_ALPHA_SREL16}, + {BFD_RELOC_32_PCREL, R_ALPHA_SREL32}, + {BFD_RELOC_64_PCREL, R_ALPHA_SREL64}, +#if 0 + {BFD_RELOC_ALPHA_OP_PUSH, R_ALPHA_OP_PUSH}, + {BFD_RELOC_ALPHA_OP_STORE, R_ALPHA_OP_STORE}, + {BFD_RELOC_ALPHA_OP_PSUB, R_ALPHA_OP_PSUB}, + {BFD_RELOC_ALPHA_OP_PRSHIFT, R_ALPHA_OP_PRSHIFT} +#endif +}; + +/* Given a BFD reloc type, return a HOWTO structure. */ + +static reloc_howto_type * +elf64_alpha_bfd_reloc_type_lookup (abfd, code) + bfd *abfd; + bfd_reloc_code_real_type code; +{ + const struct elf_reloc_map *i, *e; + i = e = elf64_alpha_reloc_map; + e += sizeof (elf64_alpha_reloc_map) / sizeof (struct elf_reloc_map); + for (; i != e; ++i) + { + if (i->bfd_reloc_val == code) + return &elf64_alpha_howto_table[i->elf_reloc_val]; + } + return 0; +} + +/* Given an Alpha ELF reloc type, fill in an arelent structure. */ + +static void +elf64_alpha_info_to_howto (abfd, cache_ptr, dst) + bfd *abfd; + arelent *cache_ptr; + Elf64_Internal_Rela *dst; +{ + unsigned r_type; + + r_type = ELF64_R_TYPE(dst->r_info); + BFD_ASSERT (r_type < (unsigned int) R_ALPHA_max); + cache_ptr->howto = &elf64_alpha_howto_table[r_type]; +} + +/* PLT/GOT Stuff */ +#define PLT_HEADER_SIZE 32 +#define PLT_HEADER_WORD1 0xc3600000 /* br $27,.+4 */ +#define PLT_HEADER_WORD2 0xa77b000c /* ldq $27,12($27) */ +#define PLT_HEADER_WORD3 0x47ff041f /* nop */ +#define PLT_HEADER_WORD4 0x6b7b0000 /* jmp $27,($27) */ + +#define PLT_ENTRY_SIZE 12 +#define PLT_ENTRY_WORD1 0x279f0000 /* ldah $28, 0($31) */ +#define PLT_ENTRY_WORD2 0x239c0000 /* lda $28, 0($28) */ +#define PLT_ENTRY_WORD3 0xc3e00000 /* br $31, plt0 */ + +#define RESERVED_GOT_ENTRIES 1 + +#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so" + +/* Set the right machine number for an Alpha ELF file. */ + +static boolean +elf64_alpha_object_p (abfd) + bfd *abfd; +{ + return bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0); +} + +/* Handle a alpha specific section when reading an object file. This + is called when elfcode.h finds a section with an unknown type. + FIXME: We need to handle the SHF_MIPS_GPREL flag, but I'm not sure + how to. */ + +static boolean +elf64_alpha_section_from_shdr (abfd, hdr, name) + bfd *abfd; + Elf64_Internal_Shdr *hdr; + char *name; +{ + asection *newsect; + + /* There ought to be a place to keep ELF backend specific flags, but + at the moment there isn't one. We just keep track of the + sections by their name, instead. Fortunately, the ABI gives + suggested names for all the MIPS specific sections, so we will + probably get away with this. */ + switch (hdr->sh_type) + { + case SHT_ALPHA_DEBUG: + if (strcmp (name, ".mdebug") != 0) + return false; + break; +#ifdef ERIC_neverdef + case SHT_ALPHA_REGINFO: + if (strcmp (name, ".reginfo") != 0 + || hdr->sh_size != sizeof (Elf64_External_RegInfo)) + return false; + break; +#endif + default: + return false; + } + + if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name)) + return false; + newsect = hdr->bfd_section; + + if (hdr->sh_type == SHT_ALPHA_DEBUG) + { + if (! bfd_set_section_flags (abfd, newsect, + (bfd_get_section_flags (abfd, newsect) + | SEC_DEBUGGING))) + return false; + } + +#ifdef ERIC_neverdef + /* For a .reginfo section, set the gp value in the tdata information + from the contents of this section. We need the gp value while + processing relocs, so we just get it now. */ + if (hdr->sh_type == SHT_ALPHA_REGINFO) + { + Elf64_External_RegInfo ext; + Elf64_RegInfo s; + + if (! bfd_get_section_contents (abfd, newsect, (PTR) &ext, + (file_ptr) 0, sizeof ext)) + return false; + bfd_alpha_elf64_swap_reginfo_in (abfd, &ext, &s); + elf_gp (abfd) = s.ri_gp_value; + } +#endif + + return true; +} + +/* Set the correct type for an Alpha ELF section. We do this by the + section name, which is a hack, but ought to work. */ + +static boolean +elf64_alpha_fake_sections (abfd, hdr, sec) + bfd *abfd; + Elf64_Internal_Shdr *hdr; + asection *sec; +{ + register const char *name; + + name = bfd_get_section_name (abfd, sec); + + if (strcmp (name, ".mdebug") == 0) + { + hdr->sh_type = SHT_ALPHA_DEBUG; + /* In a shared object on Irix 5.3, the .mdebug section has an + entsize of 0. FIXME: Does this matter? */ + if ((abfd->flags & DYNAMIC) != 0 ) + hdr->sh_entsize = 0; + else + hdr->sh_entsize = 1; + } +#ifdef ERIC_neverdef + else if (strcmp (name, ".reginfo") == 0) + { + hdr->sh_type = SHT_ALPHA_REGINFO; + /* In a shared object on Irix 5.3, the .reginfo section has an + entsize of 0x18. FIXME: Does this matter? */ + if ((abfd->flags & DYNAMIC) != 0) + hdr->sh_entsize = sizeof (Elf64_External_RegInfo); + else + hdr->sh_entsize = 1; + + /* Force the section size to the correct value, even if the + linker thinks it is larger. The link routine below will only + write out this much data for .reginfo. */ + hdr->sh_size = sec->_raw_size = sizeof (Elf64_External_RegInfo); + } + else if (strcmp (name, ".hash") == 0 + || strcmp (name, ".dynamic") == 0 + || strcmp (name, ".dynstr") == 0) + { + hdr->sh_entsize = 0; + hdr->sh_info = SIZEOF_ALPHA_DYNSYM_SECNAMES; + } + else if (strcmp (name, ".sdata") == 0 + || strcmp (name, ".sbss") == 0 + || strcmp (name, ".lit4") == 0 + || strcmp (name, ".lit8") == 0) + hdr->sh_flags |= SHF_ALPHA_GPREL; +#endif + + return true; +} + +static int +elf64_alpha_additional_program_headers (abfd) + bfd *abfd; +{ + asection *s; + int ret; + + ret = 0; + + s = bfd_get_section_by_name (abfd, ".reginfo"); + if (s != NULL && (s->flags & SEC_LOAD) != 0) + { + /* We need a PT_ALPHA_REGINFO segment. */ + ++ret; + } + + if (bfd_get_section_by_name (abfd, ".dynamic") != NULL + && bfd_get_section_by_name (abfd, ".mdebug") != NULL) + { + /* We need a PT_ALPHA_RTPROC segment. */ + ++ret; + } + + return ret; +} + +static boolean +elf64_alpha_create_got_section(abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + asection *s; + struct elf_link_hash_entry *h; + + if (bfd_get_section_by_name (abfd, ".got")) + return true; + + s = bfd_make_section(abfd, ".rela.got"); + if (s == NULL + || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD + | SEC_HAS_CONTENTS | SEC_IN_MEMORY + | SEC_READONLY)) + || !bfd_set_section_alignment (abfd, s, 3)) + return false; + + s = bfd_make_section(abfd, ".got"); + if (s == NULL + || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD + | SEC_HAS_CONTENTS | SEC_IN_MEMORY)) + || !bfd_set_section_alignment (abfd, s, 3)) + return false; + + s->_raw_size = RESERVED_GOT_ENTRIES * 8; + + /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got + (or .got.plt) section. We don't do this in the linker script + because we don't want to define the symbol if we are not creating + a global offset table. */ + h = NULL; + if (!(_bfd_generic_link_add_one_symbol + (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s, (bfd_vma) 0, + (const char *) NULL, false, get_elf_backend_data (abfd)->collect, + (struct bfd_link_hash_entry **) &h))) + return false; + h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; + h->type = STT_OBJECT; + + if (info->shared + && ! _bfd_elf_link_record_dynamic_symbol (info, h)) + return false; + + elf_hash_table (info)->hgot = h; + + return true; +} + +static boolean +elf64_alpha_create_dynamic_sections (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + register asection *s; + struct elf_link_hash_entry *h; + + /* We need to create .plt, .rela.plt, .got, and .rela.got sections. */ + + s = bfd_make_section (abfd, ".plt"); + if (s == NULL + || ! bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD + | SEC_HAS_CONTENTS | SEC_IN_MEMORY + | SEC_CODE)) + || ! bfd_set_section_alignment (abfd, s, 3)) + return false; + + /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the + .plt section. */ + h = NULL; + if (! (_bfd_generic_link_add_one_symbol + (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, + (bfd_vma) 0, (const char *) NULL, false, + get_elf_backend_data (abfd)->collect, + (struct bfd_link_hash_entry **) &h))) + return false; + h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; + h->type = STT_OBJECT; + + if (info->shared + && ! _bfd_elf_link_record_dynamic_symbol (info, h)) + return false; + + s = bfd_make_section (abfd, ".rela.plt"); + if (s == NULL + || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD + | SEC_HAS_CONTENTS | SEC_IN_MEMORY + | SEC_READONLY)) + || ! bfd_set_section_alignment (abfd, s, 3)) + return false; + + if (!elf64_alpha_create_got_section (abfd, info)) + return false; + + return true; +} + +/* The structure of the runtile procedure descriptor created by the + loader for use by the static exception system. */ + +/* FIXME */ + +/* Read ECOFF debugging information from a .mdebug section into a + ecoff_debug_info structure. */ + +static boolean +elf64_alpha_read_ecoff_info (abfd, section, debug) + bfd *abfd; + asection *section; + struct ecoff_debug_info *debug; +{ + HDRR *symhdr; + const struct ecoff_debug_swap *swap; + char *ext_hdr = NULL; + + swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; + + ext_hdr = (char *) bfd_malloc ((size_t) swap->external_hdr_size); + if (ext_hdr == NULL && swap->external_hdr_size != 0) + goto error_return; + + if (bfd_get_section_contents (abfd, section, ext_hdr, (file_ptr) 0, + swap->external_hdr_size) + == false) + goto error_return; + + symhdr = &debug->symbolic_header; + (*swap->swap_hdr_in) (abfd, ext_hdr, symhdr); + + /* The symbolic header contains absolute file offsets and sizes to + read. */ +#define READ(ptr, offset, count, size, type) \ + if (symhdr->count == 0) \ + debug->ptr = NULL; \ + else \ + { \ + debug->ptr = (type) bfd_malloc ((size_t) (size * symhdr->count)); \ + if (debug->ptr == NULL) \ + goto error_return; \ + if (bfd_seek (abfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \ + || (bfd_read (debug->ptr, size, symhdr->count, \ + abfd) != size * symhdr->count)) \ + goto error_return; \ + } + + READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *); + READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR); + READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR); + READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR); + READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR); + READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext), + union aux_ext *); + READ (ss, cbSsOffset, issMax, sizeof (char), char *); + READ (ssext, cbSsExtOffset, issExtMax, sizeof (char), char *); + READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR); + READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR); + READ (external_ext, cbExtOffset, iextMax, swap->external_ext_size, PTR); +#undef READ + + debug->fdr = NULL; + debug->adjust = NULL; + + return true; + + error_return: + if (ext_hdr != NULL) + free (ext_hdr); + if (debug->line != NULL) + free (debug->line); + if (debug->external_dnr != NULL) + free (debug->external_dnr); + if (debug->external_pdr != NULL) + free (debug->external_pdr); + if (debug->external_sym != NULL) + free (debug->external_sym); + if (debug->external_opt != NULL) + free (debug->external_opt); + if (debug->external_aux != NULL) + free (debug->external_aux); + if (debug->ss != NULL) + free (debug->ss); + if (debug->ssext != NULL) + free (debug->ssext); + if (debug->external_fdr != NULL) + free (debug->external_fdr); + if (debug->external_rfd != NULL) + free (debug->external_rfd); + if (debug->external_ext != NULL) + free (debug->external_ext); + return false; +} + +/* Alpha ELF local labels start with '$'. */ + +static boolean +elf64_alpha_is_local_label (abfd, symbol) + bfd *abfd; + asymbol *symbol; +{ + return symbol->name[0] == '$'; +} + +/* Alpha ELF follows MIPS ELF in using a special find_nearest_line + routine in order to handle the ECOFF debugging information. We + still call this mips_elf_find_line because of the slot + find_line_info in elf_obj_tdata is declared that way. */ + +struct mips_elf_find_line +{ + struct ecoff_debug_info d; + struct ecoff_find_line i; +}; + +static boolean +elf64_alpha_find_nearest_line (abfd, section, symbols, offset, filename_ptr, + functionname_ptr, line_ptr) + bfd *abfd; + asection *section; + asymbol **symbols; + bfd_vma offset; + const char **filename_ptr; + const char **functionname_ptr; + unsigned int *line_ptr; +{ + asection *msec; + + msec = bfd_get_section_by_name (abfd, ".mdebug"); + if (msec != NULL) + { + flagword origflags; + struct mips_elf_find_line *fi; + const struct ecoff_debug_swap * const swap = + get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; + + /* If we are called during a link, alpha_elf_final_link may have + cleared the SEC_HAS_CONTENTS field. We force it back on here + if appropriate (which it normally will be). */ + origflags = msec->flags; + if (elf_section_data (msec)->this_hdr.sh_type != SHT_NOBITS) + msec->flags |= SEC_HAS_CONTENTS; + + fi = elf_tdata (abfd)->find_line_info; + if (fi == NULL) + { + bfd_size_type external_fdr_size; + char *fraw_src; + char *fraw_end; + struct fdr *fdr_ptr; + + fi = ((struct mips_elf_find_line *) + bfd_zalloc (abfd, sizeof (struct mips_elf_find_line))); + if (fi == NULL) + { + msec->flags = origflags; + return false; + } + + if (!elf64_alpha_read_ecoff_info (abfd, msec, &fi->d)) + { + msec->flags = origflags; + return false; + } + + /* Swap in the FDR information. */ + fi->d.fdr = ((struct fdr *) + bfd_alloc (abfd, + (fi->d.symbolic_header.ifdMax * + sizeof (struct fdr)))); + if (fi->d.fdr == NULL) + { + msec->flags = origflags; + return false; + } + external_fdr_size = swap->external_fdr_size; + fdr_ptr = fi->d.fdr; + fraw_src = (char *) fi->d.external_fdr; + fraw_end = (fraw_src + + fi->d.symbolic_header.ifdMax * external_fdr_size); + for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++) + (*swap->swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr); + + elf_tdata (abfd)->find_line_info = fi; + + /* Note that we don't bother to ever free this information. + find_nearest_line is either called all the time, as in + objdump -l, so the information should be saved, or it is + rarely called, as in ld error messages, so the memory + wasted is unimportant. Still, it would probably be a + good idea for free_cached_info to throw it away. */ + } + + if (_bfd_ecoff_locate_line (abfd, section, offset, &fi->d, swap, + &fi->i, filename_ptr, functionname_ptr, + line_ptr)) + { + msec->flags = origflags; + return true; + } + + msec->flags = origflags; + } + + /* Fall back on the generic ELF find_nearest_line routine. */ + + return _bfd_elf_find_nearest_line (abfd, section, symbols, offset, + filename_ptr, functionname_ptr, + line_ptr); +} + +/* Structure used to pass information to alpha_elf_output_extsym. */ + +struct extsym_info +{ + bfd *abfd; + struct bfd_link_info *info; + struct ecoff_debug_info *debug; + const struct ecoff_debug_swap *swap; + boolean failed; +}; + +static boolean +elf64_alpha_output_extsym (h, data) + struct alpha_elf_link_hash_entry *h; + PTR data; +{ + struct extsym_info *einfo = (struct extsym_info *) data; + boolean strip; + asection *sec, *output_section; + + if (h->root.indx == -2) + strip = false; + else if (((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 + || (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0) + && (h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 + && (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) + strip = true; + else if (einfo->info->strip == strip_all + || (einfo->info->strip == strip_some + && bfd_hash_lookup (einfo->info->keep_hash, + h->root.root.root.string, + false, false) == NULL)) + strip = true; + else + strip = false; + + if (strip) + return true; + + if (h->esym.ifd == -2) + { + h->esym.jmptbl = 0; + h->esym.cobol_main = 0; + h->esym.weakext = 0; + h->esym.reserved = 0; + h->esym.ifd = ifdNil; + h->esym.asym.value = 0; + h->esym.asym.st = stGlobal; + + if (h->root.root.type != bfd_link_hash_defined + && h->root.root.type != bfd_link_hash_defweak) + h->esym.asym.sc = scAbs; + else + { + const char *name; + + sec = h->root.root.u.def.section; + output_section = sec->output_section; + + /* When making a shared library and symbol h is the one from + the another shared library, OUTPUT_SECTION may be null. */ + if (output_section == NULL) + h->esym.asym.sc = scUndefined; + else + { + name = bfd_section_name (output_section->owner, output_section); + + if (strcmp (name, ".text") == 0) + h->esym.asym.sc = scText; + else if (strcmp (name, ".data") == 0) + h->esym.asym.sc = scData; + else if (strcmp (name, ".sdata") == 0) + h->esym.asym.sc = scSData; + else if (strcmp (name, ".rodata") == 0 + || strcmp (name, ".rdata") == 0) + h->esym.asym.sc = scRData; + else if (strcmp (name, ".bss") == 0) + h->esym.asym.sc = scBss; + else if (strcmp (name, ".sbss") == 0) + h->esym.asym.sc = scSBss; + else if (strcmp (name, ".init") == 0) + h->esym.asym.sc = scInit; + else if (strcmp (name, ".fini") == 0) + h->esym.asym.sc = scFini; + else + h->esym.asym.sc = scAbs; + } + } + + h->esym.asym.reserved = 0; + h->esym.asym.index = indexNil; + } + + if (h->root.root.type == bfd_link_hash_common) + h->esym.asym.value = h->root.root.u.c.size; + else if (h->root.root.type == bfd_link_hash_defined + || h->root.root.type == bfd_link_hash_defweak) + { + if (h->esym.asym.sc == scCommon) + h->esym.asym.sc = scBss; + else if (h->esym.asym.sc == scSCommon) + h->esym.asym.sc = scSBss; + + sec = h->root.root.u.def.section; + output_section = sec->output_section; + if (output_section != NULL) + h->esym.asym.value = (h->root.root.u.def.value + + sec->output_offset + + output_section->vma); + else + h->esym.asym.value = 0; + } + else if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) + { + /* Set type and value for a symbol with a function stub. */ + h->esym.asym.st = stProc; + sec = bfd_get_section_by_name (einfo->abfd, ".plt"); + if (sec == NULL) + h->esym.asym.value = 0; + else + { + output_section = sec->output_section; + if (output_section != NULL) + h->esym.asym.value = (h->root.plt_offset + + sec->output_offset + + output_section->vma); + else + h->esym.asym.value = 0; + } +#if 0 /* FIXME? */ + h->esym.ifd = 0; +#endif + } + + if (! bfd_ecoff_debug_one_external (einfo->abfd, einfo->debug, einfo->swap, + h->root.root.root.string, + &h->esym)) + { + einfo->failed = true; + return false; + } + + return true; +} + +/* FIXME: Create a runtime procedure table from the .mdebug section. + +static boolean +mips_elf_create_procedure_table (handle, abfd, info, s, debug) + PTR handle; + bfd *abfd; + struct bfd_link_info *info; + asection *s; + struct ecoff_debug_info *debug; + */ + + +static boolean +elf64_alpha_check_relocs (abfd, info, sec, relocs) + bfd *abfd; + struct bfd_link_info *info; + asection *sec; + const Elf_Internal_Rela *relocs; +{ + bfd *dynobj; + asection *sgot; + asection *srelgot; + asection *sreloc; + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + const Elf_Internal_Rela *rel, *relend; + + if (info->relocateable) + return true; + + sgot = srelgot = sreloc = NULL; + symtab_hdr = &elf_tdata(abfd)->symtab_hdr; + sym_hashes = elf_sym_hashes(abfd); + dynobj = elf_hash_table(info)->dynobj; + if (dynobj) + { + 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) + { + unsigned long r_symndx; + struct alpha_elf_link_hash_entry *h; + + r_symndx = ELF64_R_SYM (rel->r_info); + if (r_symndx < symtab_hdr->sh_info) + h = NULL; + else + h = ((struct alpha_elf_link_hash_entry *) + sym_hashes[r_symndx - symtab_hdr->sh_info]); + + switch (ELF64_R_TYPE (rel->r_info)) + { + case R_ALPHA_LITERAL: + /* If this is a load of a function symbol and we are building a + shared library or calling a shared library, then we need a + .plt entry as well. + + We can tell if it is a function either by noticing the + type of the symbol, or, if the type is undefined, by + noticing that we have a LITUSE(3) reloc next. + + Note that it is not fatal to be wrong guessing that a symbol + is an object, but it is fatal to be wrong guessing that a + symbol is a function. + + Furthermore, the .plt trampoline does not give constant + function addresses, so if we ever see a function's address + taken, we cannot do lazy binding on that function. */ + + if (h) + { + if (rel+1 < relend + && ELF64_R_TYPE (rel[1].r_info) == R_ALPHA_LITUSE) + { + switch (rel[1].r_addend) + { + case 1: /* Memory reference */ + h->flags |= ALPHA_ELF_LINK_HASH_LU_MEM; + break; + case 3: /* Call reference */ + h->flags |= ALPHA_ELF_LINK_HASH_LU_FUNC; + break; + } + } + else + h->flags |= ALPHA_ELF_LINK_HASH_LU_ADDR; + + if (h->root.root.type != bfd_link_hash_undefweak + && (info->shared + || !(h->root.elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR)) + && (h->root.type == STT_FUNC + || (h->root.type == STT_NOTYPE + && (h->flags & ALPHA_ELF_LINK_HASH_LU_FUNC)))) + { + h->root.elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; + } + } + + if (dynobj == NULL) + { + elf_hash_table(info)->dynobj = dynobj = abfd; + + /* Create the .got section. */ + if (!elf64_alpha_create_got_section(dynobj, info)) + return false; + + sgot = bfd_get_section_by_name(dynobj, ".got"); + srelgot = bfd_get_section_by_name(dynobj, ".rela.got"); + } + + if (h != NULL) + { + if (h->root.got_offset != MINUS_ONE) + { + /* We have already allocated space in this .got. */ + break; + } + + /* Make sure this becomes a dynamic symbol. */ + if (h->root.dynindx == -1 + && ! _bfd_elf_link_record_dynamic_symbol (info, &h->root)) + return false; + + /* Reserve space for a reloc even if we won't use it. */ + srelgot->_raw_size += sizeof(Elf64_External_Rela); + + /* Create the relocation in adjust_dynamic_symbol */ + + h->root.got_offset = sgot->_raw_size; + sgot->_raw_size += 8; + } + else + { + bfd_vma *lgotoff = elf_local_got_offsets(abfd); + if (lgotoff == NULL) + { + size_t size; + + size = elf_tdata(abfd)->symtab_hdr.sh_info * sizeof(bfd_vma); + lgotoff = (bfd_vma *)bfd_alloc(abfd, size); + if (lgotoff == NULL) + return false; + + elf_local_got_offsets(abfd) = lgotoff; + memset(lgotoff, -1, size); + } + + if (lgotoff[ELF64_R_SYM(rel->r_info)] != MINUS_ONE) + { + /* We have already allocated space in the .got. */ + break; + } + lgotoff[ELF64_R_SYM(rel->r_info)] = sgot->_raw_size; + sgot->_raw_size += 8; + + if (info->shared) + { + /* If we are generating a shared object, we need to + output a R_ALPHA_RELATIVE reloc so that the dynamic + linker can adjust this GOT entry. */ + srelgot->_raw_size += sizeof(Elf64_External_Rela); + } + } + break; + + case R_ALPHA_SREL16: + case R_ALPHA_SREL32: + case R_ALPHA_SREL64: + if (h == NULL) + break; + /* FALLTHRU */ + + case R_ALPHA_REFLONG: + case R_ALPHA_REFQUAD: + if (info->shared + || (h != NULL + && !(h->root.elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR))) + { + /* When creating a shared object or referring to a symbol in + a shared object, we must copy these relocs into the + object file. We create a reloc section in dynobj and + make room for the reloc. */ + if (sreloc == NULL) + { + const char *name; + 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; + + BFD_ASSERT (strncmp (name, ".rela", 5) == 0 + && strcmp (bfd_get_section_name (abfd, sec), + name+5) == 0); + + sreloc = bfd_get_section_by_name (dynobj, name); + if (sreloc == NULL) + { + sreloc = bfd_make_section (dynobj, name); + if (sreloc == NULL + || !bfd_set_section_flags (dynobj, sreloc, + (SEC_ALLOC|SEC_LOAD + |SEC_HAS_CONTENTS + |SEC_IN_MEMORY + |SEC_READONLY)) + || !bfd_set_section_alignment (dynobj, sreloc, 3)) + return false; + } + } + sreloc->_raw_size += sizeof (Elf64_External_Rela); + } + 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 +elf64_alpha_adjust_dynamic_symbol (info, h) + struct bfd_link_info *info; + struct elf_link_hash_entry *h; +{ + bfd *dynobj; + asection *s; + + dynobj = elf_hash_table(info)->dynobj; + + /* If this is a function, put it in the procedure linkage table. We + will fill in the contents of the procedure linkage table later, + though we could actually do it here. */ + + if (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) + { + /* We hadn't seen all of the input symbols or all of the relocations + when we guessed that we needed a .plt entry. Revise our decision. */ + if ((!info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) + || (((struct alpha_elf_link_hash_entry *) h)->flags + & ALPHA_ELF_LINK_HASH_LU_ADDR)) + { + h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; + return true; + } + + s = bfd_get_section_by_name(dynobj, ".plt"); + BFD_ASSERT(s != NULL); + + /* The first bit of the .plt is reserved. */ + if (s->_raw_size == 0) + s->_raw_size = PLT_HEADER_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 the location + in the .plt. This is required to make function pointers compare + equal between the normal executable and the shared library. */ + if (!info->shared) + { + h->root.u.def.section = s; + h->root.u.def.value = s->_raw_size; + } + + s->_raw_size += PLT_ENTRY_SIZE; + + /* We also need 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; + } + + /* 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. The Alpha, since it uses .got entries for + symbols even in regular objects, does not need the hackery of a + .dynbss section and COPY dynamic relocations. */ + + return true; +} + +/* Set the sizes of the dynamic sections. */ + +static boolean +elf64_alpha_size_dynamic_sections (output_bfd, info) + bfd *output_bfd; + struct bfd_link_info *info; +{ + bfd *dynobj; + asection *s; + boolean reltext; + boolean relplt; + + dynobj = elf_hash_table(info)->dynobj; + BFD_ASSERT(dynobj != NULL); + + if (elf_hash_table(info)->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); + 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 .rel.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; + } + + /* The check_relocs and adjust_dynamic_symbol entry points have + determined the sizes of the various dynamic sections. Allocate + memory for them. */ + reltext = false; + relplt = false; + for (s = dynobj->sections; s != NULL; s = s->next) + { + const char *name; + boolean strip; + + if (!(s->flags & SEC_IN_MEMORY)) + 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); + + /* 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. */ + + strip = false; + + if (strncmp(name, ".rela", 5) == 0) + { + strip = (s->_raw_size == 0); + + if (!strip) + { + asection *target; + + /* If this relocation section applies to a read only + section, then we probably need a DT_TEXTREL entry. */ + target = bfd_get_section_by_name (output_bfd, name + 5); + if (target != NULL + && (target->flags & SEC_READONLY) != 0) + reltext = true; + + if (strcmp(name, ".rela.plt") == 0) + relplt = 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 if (strcmp(name, ".got") == 0) + { + /* If we are generating a shared library, we generate a + section symbol for each output section. These are local + symbols, which means that they must come first in the + dynamic symbol table. That means we must increment the + dynamic symbol index of every other dynamic symbol. */ + if (info->shared) + { + long c[2], i; + asection *p; + + c[0] = 0; + c[1] = bfd_count_sections(output_bfd); + + elf_link_hash_traverse (elf_hash_table(info), + elf64_alpha_adjust_dynindx, + (PTR)c); + elf_hash_table (info)->dynsymcount += c[1]; + + for (i = 1, p = output_bfd->sections; + p != NULL; + p = p->next, i++) + { + elf_section_data (p)->dynindx = i; + /* These symbols will have no names, so we don't need to + fiddle with dynstr_index. */ + } + } + } + else if (strcmp (name, ".plt") != 0) + { + /* It's not one of our sections, so don't allocate space. */ + continue; + } + + if (strip) + { + asection **spp; + + for (spp = &s->output_section->owner->sections; + *spp != s->output_section; + spp = &(*spp)->next) + continue; + *spp = s->output_section->next; + --s->output_section->owner->section_count; + + continue; + } + + /* Allocate memory for the section contents. */ + s->contents = (bfd_byte *) bfd_zalloc(dynobj, s->_raw_size); + if (s->contents == NULL && s->_raw_size != 0) + return false; + } + + if (elf_hash_table (info)->dynamic_sections_created) + { + /* Add some entries to the .dynamic section. We fill in the + values later, in elf64_alpha_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. */ + if (!info->shared) + { + if (!bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0)) + return false; + } + + if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0)) + return false; + + if (relplt) + { + if (! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0) + || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA) + || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0)) + return false; + } + + if (! bfd_elf64_add_dynamic_entry (info, DT_RELA, 0) + || ! bfd_elf64_add_dynamic_entry (info, DT_RELASZ, 0) + || ! bfd_elf64_add_dynamic_entry (info, DT_RELAENT, + sizeof(Elf64_External_Rela))) + return false; + + if (reltext) + { + if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0)) + return false; + } + } + + return true; +} + +/* Increment the index of a dynamic symbol by a given amount. Called + via elf_link_hash_traverse. */ + +static boolean +elf64_alpha_adjust_dynindx (h, cparg) + struct elf_link_hash_entry *h; + PTR cparg; +{ + long *cp = (long *)cparg; + + if (h->dynindx >= cp[0]) + h->dynindx += cp[1]; + + return true; +} + +/* Relocate an Alpha ELF section. */ + +static boolean +elf64_alpha_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; +{ + Elf_Internal_Shdr *symtab_hdr; + Elf_Internal_Rela *rel; + Elf_Internal_Rela *relend; + asection *sec, *sgot, *splt; + bfd *dynobj; + bfd_vma gp; + + symtab_hdr = &elf_tdata(input_bfd)->symtab_hdr; + + /* Find the gp value for this input bfd. */ + sgot = NULL; + gp = 0; + dynobj = elf_hash_table(info)->dynobj; + if (dynobj) + { + sgot = bfd_get_section_by_name (dynobj, ".got"); + splt = bfd_get_section_by_name (dynobj, ".plt"); + + gp = _bfd_get_gp_value(dynobj); + if (gp == 0) + { + gp = (sgot->output_section->vma + + sgot->output_offset + + 0x8000); + _bfd_set_gp_value(dynobj, gp); + } + } + + 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; + bfd_vma relocation; + bfd_vma addend; + bfd_reloc_status_type r; + + r_type = ELF64_R_TYPE(rel->r_info); + if (r_type < 0 || r_type >= (int) R_ALPHA_max) + { + bfd_set_error (bfd_error_bad_value); + return false; + } + howto = elf64_alpha_howto_table + r_type; + + r_symndx = ELF64_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) + { + sec = local_sections[r_symndx]; + rel->r_addend += sec->output_offset + sym->st_value; + } + } + + continue; + } + + /* This is a final link. */ + + h = NULL; + sym = NULL; + sec = NULL; + + if (r_symndx < symtab_hdr->sh_info) + { + sym = local_syms + r_symndx; + sec = local_sections[r_symndx]; + relocation = (sec->output_section->vma + + sec->output_offset + + sym->st_value); + } + else + { + h = elf_sym_hashes(input_bfd)[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 the symbol was defined as a common symbol in a + regular object file, and there was no definition in + any dynamic object, then the linker will have + allocated space for the symbol in a common section + but the ELF_LINK_HASH_DEF_REGULAR flag will not have + been set. This is done for dynamic symbols in + elf_adjust_dynamic_symbol but this is not done for + non-dynamic symbols, somehow. */ + if ((h->elf_link_hash_flags + & (ELF_LINK_HASH_DEF_REGULAR + | ELF_LINK_HASH_REF_REGULAR + | ELF_LINK_HASH_DEF_DYNAMIC)) + == ELF_LINK_HASH_REF_REGULAR + && !(sec->owner->flags & DYNAMIC)) + h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; + +#if rth_notdef + if ((r_type == R_ALPHA_LITERAL + && elf_hash_table(info)->dynamic_sections_created + && (!info->shared + || !info->symbolic + || !(h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR))) + || (info->shared + && (!info->symbolic + || !(h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR)) + && (input_section->flags & SEC_ALLOC) + && (r_type == R_ALPHA_REFLONG + || r_type == R_ALPHA_REFQUAD + || r_type == R_ALPHA_LITERAL))) + { + /* 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 + /* FIXME: Are not these obscure cases simply bugs? Let's + get something working and come back to this. */ + if (sec->output_section == NULL) + relocation = 0; +#endif /* rth_notdef */ + 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) + relocation = 0; + else + { + if (!((*info->callbacks->undefined_symbol) + (info, h->root.root.string, input_bfd, + input_section, rel->r_offset))) + return false; + relocation = 0; + } + } + addend = rel->r_addend; + + switch (r_type) + { + case R_ALPHA_GPDISP: + { + bfd_byte *p_ldah, *p_lda; + + relocation = (input_section->output_section->vma + + input_section->output_offset + + rel->r_offset); + + p_ldah = contents + rel->r_offset - input_section->vma; + p_lda = p_ldah + rel->r_addend; + + r = elf64_alpha_do_reloc_gpdisp (input_bfd, gp - relocation, + p_ldah, p_lda); + } + break; + + case R_ALPHA_OP_PUSH: + case R_ALPHA_OP_STORE: + case R_ALPHA_OP_PSUB: + case R_ALPHA_OP_PRSHIFT: + /* FIXME */ + abort(); + + case R_ALPHA_LITERAL: + { + bfd_vma gotoff; + + BFD_ASSERT(gp != 0); + BFD_ASSERT(sgot != NULL); + if (h != NULL) + { + gotoff = h->got_offset; + } + else + { + gotoff = elf_local_got_offsets (input_bfd)[r_symndx]; + + /* Use the lsb as a flag indicating that we've already + output the relocation entry. */ + if (info->shared) + if (gotoff & 1) + gotoff &= ~(bfd_vma)1; + else + { + asection *srel; + Elf_Internal_Rela outrel; + + srel = bfd_get_section_by_name (dynobj, ".rela.got"); + BFD_ASSERT(srel != NULL); + + outrel.r_offset = (sgot->output_section->vma + + sgot->output_offset + gotoff); + outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE); + outrel.r_addend = 0; + + bfd_elf64_swap_reloca_out (output_bfd, &outrel, + ((Elf64_External_Rela *) + srel->contents) + + srel->reloc_count++); + + elf_local_got_offsets (input_bfd)[r_symndx] |= 1; + } + } + + /* Initialize the .got entry. */ + bfd_put_64 (output_bfd, relocation, sgot->contents + gotoff); + + /* Figure the gprel relocation. */ + addend = 0; + relocation = (sgot->output_section->vma + + sgot->output_offset + + gotoff); + relocation -= gp; + } + /* overflow handled by _bfd_final_link_relocate */ + goto default_reloc; + + case R_ALPHA_GPREL32: + BFD_ASSERT(gp != 0); + relocation -= gp; + goto default_reloc; + + case R_ALPHA_BRADDR: + case R_ALPHA_HINT: + /* The regular PC-relative stuff measures from the start of + the instruction rather than the end. */ + addend -= 4; + goto default_reloc; + + case R_ALPHA_REFLONG: + case R_ALPHA_REFQUAD: + if (info->shared + || (h && !(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) + { + asection *srel; + const char *name; + Elf_Internal_Rela outrel; + + name = (bfd_elf_string_from_elf_section + (input_bfd, elf_elfheader(input_bfd)->e_shstrndx, + elf_section_data(input_section)->rel_hdr.sh_name)); + BFD_ASSERT(name != NULL); + + srel = bfd_get_section_by_name(dynobj, name); + BFD_ASSERT(srel != NULL); + + outrel.r_offset = (input_section->output_section->vma + + input_section->output_offset + + rel->r_offset); + outrel.r_addend = 0; + if (h) + { + BFD_ASSERT(h->dynindx != -1); + outrel.r_info = ELF64_R_INFO(h->dynindx, r_type); + relocation = 0; + } + else + { + outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE); + } + + bfd_elf64_swap_reloca_out (output_bfd, &outrel, + ((Elf64_External_Rela *) + srel->contents) + + srel->reloc_count++); + } + goto default_reloc; + + default: + default_reloc: + r = _bfd_final_link_relocate (howto, input_bfd, input_section, + contents, rel->r_offset, relocation, + addend); + break; + } + + switch (r) + { + case bfd_reloc_ok: + break; + + 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, rel->r_offset))) + return false; + } + break; + + default: + case bfd_reloc_outofrange: + abort (); + } + } + + return true; +} + +/* Finish up dynamic symbol handling. We set the contents of various + dynamic sections here. */ + +static boolean +elf64_alpha_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; +{ + bfd *dynobj = elf_hash_table(info)->dynobj; + + if (h->plt_offset != MINUS_ONE) + { + asection *splt, *sgot, *srel; + Elf_Internal_Rela outrel; + bfd_vma got_addr, plt_addr; + bfd_vma plt_index; + + /* This symbol has an entry in the procedure linkage table. */ + + BFD_ASSERT(h->dynindx != -1); + BFD_ASSERT(h->got_offset != MINUS_ONE); + + splt = bfd_get_section_by_name(dynobj, ".plt"); + BFD_ASSERT(splt != NULL); + srel = bfd_get_section_by_name(dynobj, ".rela.plt"); + BFD_ASSERT(srel != NULL); + sgot = bfd_get_section_by_name(dynobj, ".got"); + BFD_ASSERT(sgot != NULL); + + got_addr = (sgot->output_section->vma + + sgot->output_offset + + h->got_offset); + plt_addr = (splt->output_section->vma + + splt->output_offset + + h->plt_offset); + + plt_index = (h->plt_offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE; + + /* Fill in the entry in the procedure linkage table. */ + { + unsigned insn1, insn2, insn3; + long hi, lo; + + /* decompose the reloc offset for the plt for ldah+lda */ + hi = plt_index * sizeof(Elf64_External_Rela); + lo = ((hi & 0xffff) ^ 0x8000) - 0x8000; + hi = (hi - lo) >> 16; + + insn1 = PLT_ENTRY_WORD1 | (hi & 0xffff); + insn2 = PLT_ENTRY_WORD2 | (lo & 0xffff); + insn3 = PLT_ENTRY_WORD3 | ((-(h->plt_offset + 12) >> 2) & 0x1fffff); + + bfd_put_32 (output_bfd, insn1, splt->contents + h->plt_offset); + bfd_put_32 (output_bfd, insn2, splt->contents + h->plt_offset + 4); + bfd_put_32 (output_bfd, insn3, splt->contents + h->plt_offset + 8); + } + + /* Fill in the entry in the .rela.plt section. */ + outrel.r_offset = got_addr; + outrel.r_info = ELF64_R_INFO(h->dynindx, R_ALPHA_JMP_SLOT); + outrel.r_addend = 0; + + bfd_elf64_swap_reloca_out (output_bfd, &outrel, + ((Elf64_External_Rela *)srel->contents + + plt_index)); + + if (!(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) + { + /* Mark the symbol as undefined, rather than as defined in the + .plt section. Leave the value alone. */ + sym->st_shndx = SHN_UNDEF; + } + + /* Fill in the entry in the global offset table. */ + bfd_put_64 (output_bfd, plt_addr, sgot->contents + h->got_offset); + } + else if (h->got_offset != MINUS_ONE) + { + asection *sgot, *srel; + Elf_Internal_Rela outrel; + + BFD_ASSERT(h->dynindx != -1); + + sgot = bfd_get_section_by_name (dynobj, ".got"); + BFD_ASSERT (sgot != NULL); + srel = bfd_get_section_by_name (dynobj, ".rela.got"); + BFD_ASSERT (srel != NULL); + + outrel.r_offset = (sgot->output_section->vma + + sgot->output_offset + + h->got_offset); + outrel.r_addend = 0; + if (info->shared + && info->symbolic + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)) + outrel.r_info = ELF64_R_INFO(0, R_ALPHA_RELATIVE); + else + { + bfd_put_64(output_bfd, (bfd_vma)0, sgot->contents + h->got_offset); + outrel.r_info = ELF64_R_INFO(h->dynindx, R_ALPHA_GLOB_DAT); + } + + bfd_elf64_swap_reloca_out (output_bfd, &outrel, + ((Elf64_External_Rela *)srel->contents + + srel->reloc_count++)); + } + + /* 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; +} + +/* Finish up the dynamic sections. */ + +static boolean +elf64_alpha_finish_dynamic_sections (output_bfd, info) + bfd *output_bfd; + struct bfd_link_info *info; +{ + bfd *dynobj; + asection *sdyn; + asection *sgot; + + dynobj = elf_hash_table (info)->dynobj; + sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); + + if (elf_hash_table (info)->dynamic_sections_created) + { + asection *splt; + Elf64_External_Dyn *dyncon, *dynconend; + + splt = bfd_get_section_by_name (dynobj, ".plt"); + BFD_ASSERT (splt != NULL && sdyn != NULL); + + 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); + + switch (dyn.d_tag) + { + case DT_PLTGOT: + name = ".plt"; + goto get_vma; + case DT_PLTRELSZ: + name = ".rela.plt"; + goto get_size; + case DT_JMPREL: + name = ".rela.plt"; + goto get_vma; + + case DT_RELASZ: + /* 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) + { + dyn.d_un.d_val -= + (s->_cooked_size ? s->_cooked_size : s->_raw_size); + } + break; + + get_vma: + s = bfd_get_section_by_name (output_bfd, name); + dyn.d_un.d_ptr = (s ? s->vma : 0); + break; + + get_size: + s = bfd_get_section_by_name (output_bfd, name); + dyn.d_un.d_val = + (s->_cooked_size ? s->_cooked_size : s->_raw_size); + break; + } + + bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); + } + + /* Initialize the PLT0 entry */ + if (splt->_raw_size > 0) + { + bfd_put_32 (output_bfd, PLT_HEADER_WORD1, splt->contents); + bfd_put_32 (output_bfd, PLT_HEADER_WORD2, splt->contents + 4); + bfd_put_32 (output_bfd, PLT_HEADER_WORD3, splt->contents + 8); + bfd_put_32 (output_bfd, PLT_HEADER_WORD4, splt->contents + 12); + + /* The next two words will be filled in by ld.so */ + bfd_put_64 (output_bfd, 0, splt->contents + 16); + bfd_put_64 (output_bfd, 0, splt->contents + 24); + + elf_section_data (splt->output_section)->this_hdr.sh_entsize = + PLT_HEADER_SIZE; + } + } + + /* Set the first entry in the global offset table to the address of + the dynamic section. */ + sgot = bfd_get_section_by_name (dynobj, ".got"); + if (sgot && sgot->_raw_size > 0) + { + 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); + + elf_section_data (sgot->output_section)->this_hdr.sh_entsize = + 8 * RESERVED_GOT_ENTRIES; + } + + if (info->shared) + { + asection *sdynsym; + asection *s; + Elf_Internal_Sym sym; + + /* Set up the section symbols for the output sections. */ + + sdynsym = bfd_get_section_by_name (dynobj, ".dynsym"); + BFD_ASSERT (sdynsym != NULL); + + sym.st_size = 0; + sym.st_name = 0; + sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); + sym.st_other = 0; + + for (s = output_bfd->sections; s != NULL; s = s->next) + { + int indx; + + sym.st_value = s->vma; + + indx = elf_section_data (s)->this_idx; + BFD_ASSERT (indx > 0); + sym.st_shndx = indx; + + bfd_elf64_swap_symbol_out (output_bfd, &sym, + (PTR) (((Elf64_External_Sym *) + sdynsym->contents) + + elf_section_data (s)->dynindx)); + } + + /* Set the sh_info field of the output .dynsym section to the + index of the first global symbol. */ + elf_section_data (sdynsym->output_section)->this_hdr.sh_info = + bfd_count_sections (output_bfd) + 1; + } + + return true; +} + +/* We need to use a special link routine to handle the .reginfo and + the .mdebug sections. We need to merge all instances of these + sections together, not write them all out sequentially. */ + +static boolean +elf64_alpha_final_link (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + asection *o; + struct bfd_link_order *p; + asection *reginfo_sec, *mdebug_sec, *gptab_data_sec, *gptab_bss_sec; + struct ecoff_debug_info debug; + const struct ecoff_debug_swap *swap + = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap; + HDRR *symhdr = &debug.symbolic_header; + PTR mdebug_handle = NULL; + + /* Go through the sections and collect the .reginfo and .mdebug + information. */ + reginfo_sec = NULL; + mdebug_sec = NULL; + gptab_data_sec = NULL; + gptab_bss_sec = NULL; + for (o = abfd->sections; o != (asection *) NULL; o = o->next) + { +#ifdef ERIC_neverdef + if (strcmp (o->name, ".reginfo") == 0) + { + memset (®info, 0, sizeof reginfo); + + /* We have found the .reginfo section in the output file. + Look through all the link_orders comprising it and merge + the information together. */ + for (p = o->link_order_head; + p != (struct bfd_link_order *) NULL; + p = p->next) + { + asection *input_section; + bfd *input_bfd; + Elf64_External_RegInfo ext; + Elf64_RegInfo sub; + + if (p->type != bfd_indirect_link_order) + { + if (p->type == bfd_fill_link_order) + continue; + abort (); + } + + input_section = p->u.indirect.section; + input_bfd = input_section->owner; + + /* The linker emulation code has probably clobbered the + size to be zero bytes. */ + if (input_section->_raw_size == 0) + input_section->_raw_size = sizeof (Elf64_External_RegInfo); + + if (! bfd_get_section_contents (input_bfd, input_section, + (PTR) &ext, + (file_ptr) 0, + sizeof ext)) + return false; + + bfd_alpha_elf64_swap_reginfo_in (input_bfd, &ext, &sub); + + reginfo.ri_gprmask |= sub.ri_gprmask; + reginfo.ri_cprmask[0] |= sub.ri_cprmask[0]; + reginfo.ri_cprmask[1] |= sub.ri_cprmask[1]; + reginfo.ri_cprmask[2] |= sub.ri_cprmask[2]; + reginfo.ri_cprmask[3] |= sub.ri_cprmask[3]; + + /* ri_gp_value is set by the function + alpha_elf_section_processing when the section is + finally written out. */ + + /* Hack: reset the SEC_HAS_CONTENTS flag so that + elf_link_input_bfd ignores this section. */ + input_section->flags &=~ SEC_HAS_CONTENTS; + } + + /* Force the section size to the value we want. */ + o->_raw_size = sizeof (Elf64_External_RegInfo); + + /* Skip this section later on (I don't think this currently + matters, but someday it might). */ + o->link_order_head = (struct bfd_link_order *) NULL; + + reginfo_sec = o; + } +#endif + + if (strcmp (o->name, ".mdebug") == 0) + { + struct extsym_info einfo; + + /* We have found the .mdebug section in the output file. + Look through all the link_orders comprising it and merge + the information together. */ + symhdr->magic = swap->sym_magic; + /* FIXME: What should the version stamp be? */ + symhdr->vstamp = 0; + symhdr->ilineMax = 0; + symhdr->cbLine = 0; + symhdr->idnMax = 0; + symhdr->ipdMax = 0; + symhdr->isymMax = 0; + symhdr->ioptMax = 0; + symhdr->iauxMax = 0; + symhdr->issMax = 0; + symhdr->issExtMax = 0; + symhdr->ifdMax = 0; + symhdr->crfd = 0; + symhdr->iextMax = 0; + + /* We accumulate the debugging information itself in the + debug_info structure. */ + debug.line = NULL; + debug.external_dnr = NULL; + debug.external_pdr = NULL; + debug.external_sym = NULL; + debug.external_opt = NULL; + debug.external_aux = NULL; + debug.ss = NULL; + debug.ssext = debug.ssext_end = NULL; + debug.external_fdr = NULL; + debug.external_rfd = NULL; + debug.external_ext = debug.external_ext_end = NULL; + + mdebug_handle = bfd_ecoff_debug_init (abfd, &debug, swap, info); + if (mdebug_handle == (PTR) NULL) + return false; + + if (1) + { + asection *s; + EXTR esym; + bfd_vma last; + unsigned int i; + static const char * const name[] = + { + ".text", ".init", ".fini", ".data", + ".rodata", ".sdata", ".sbss", ".bss" + }; + static const int sc[] = { scText, scInit, scFini, scData, + scRData, scSData, scSBss, scBss }; + + esym.jmptbl = 0; + esym.cobol_main = 0; + esym.weakext = 0; + esym.reserved = 0; + esym.ifd = ifdNil; + esym.asym.iss = issNil; + esym.asym.st = stLocal; + esym.asym.reserved = 0; + esym.asym.index = indexNil; + for (i = 0; i < 8; i++) + { + esym.asym.sc = sc[i]; + s = bfd_get_section_by_name (abfd, name[i]); + if (s != NULL) + { + esym.asym.value = s->vma; + last = s->vma + s->_raw_size; + } + else + esym.asym.value = last; + + if (! bfd_ecoff_debug_one_external (abfd, &debug, swap, + name[i], &esym)) + return false; + } + } + + for (p = o->link_order_head; + p != (struct bfd_link_order *) NULL; + p = p->next) + { + asection *input_section; + bfd *input_bfd; + const struct ecoff_debug_swap *input_swap; + struct ecoff_debug_info input_debug; + char *eraw_src; + char *eraw_end; + + if (p->type != bfd_indirect_link_order) + { + if (p->type == bfd_fill_link_order) + continue; + abort (); + } + + input_section = p->u.indirect.section; + input_bfd = input_section->owner; + + if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour + || (get_elf_backend_data (input_bfd) + ->elf_backend_ecoff_debug_swap) == NULL) + { + /* I don't know what a non ALPHA ELF bfd would be + doing with a .mdebug section, but I don't really + want to deal with it. */ + continue; + } + + input_swap = (get_elf_backend_data (input_bfd) + ->elf_backend_ecoff_debug_swap); + + BFD_ASSERT (p->size == input_section->_raw_size); + + /* The ECOFF linking code expects that we have already + read in the debugging information and set up an + ecoff_debug_info structure, so we do that now. */ + if (!elf64_alpha_read_ecoff_info (input_bfd, input_section, + &input_debug)) + return false; + + if (! (bfd_ecoff_debug_accumulate + (mdebug_handle, abfd, &debug, swap, input_bfd, + &input_debug, input_swap, info))) + return false; + + /* Loop through the external symbols. For each one with + interesting information, try to find the symbol in + the linker global hash table and save the information + for the output external symbols. */ + eraw_src = input_debug.external_ext; + eraw_end = (eraw_src + + (input_debug.symbolic_header.iextMax + * input_swap->external_ext_size)); + for (; + eraw_src < eraw_end; + eraw_src += input_swap->external_ext_size) + { + EXTR ext; + const char *name; + struct alpha_elf_link_hash_entry *h; + + (*input_swap->swap_ext_in) (input_bfd, (PTR) eraw_src, &ext); + if (ext.asym.sc == scNil + || ext.asym.sc == scUndefined + || ext.asym.sc == scSUndefined) + continue; + + name = input_debug.ssext + ext.asym.iss; + h = alpha_elf_link_hash_lookup (alpha_elf_hash_table (info), + name, false, false, true); + if (h == NULL || h->esym.ifd != -2) + continue; + + if (ext.ifd != -1) + { + BFD_ASSERT (ext.ifd + < input_debug.symbolic_header.ifdMax); + ext.ifd = input_debug.ifdmap[ext.ifd]; + } + + h->esym = ext; + } + + /* Free up the information we just read. */ + free (input_debug.line); + free (input_debug.external_dnr); + free (input_debug.external_pdr); + free (input_debug.external_sym); + free (input_debug.external_opt); + free (input_debug.external_aux); + free (input_debug.ss); + free (input_debug.ssext); + free (input_debug.external_fdr); + free (input_debug.external_rfd); + free (input_debug.external_ext); + + /* Hack: reset the SEC_HAS_CONTENTS flag so that + elf_link_input_bfd ignores this section. */ + input_section->flags &=~ SEC_HAS_CONTENTS; + } + +#ifdef ERIC_neverdef + if (info->shared) + { + /* Create .rtproc section. */ + rtproc_sec = bfd_get_section_by_name (abfd, ".rtproc"); + if (rtproc_sec == NULL) + { + flagword flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY + | SEC_READONLY); + + rtproc_sec = bfd_make_section (abfd, ".rtproc"); + if (rtproc_sec == NULL + || ! bfd_set_section_flags (abfd, rtproc_sec, flags) + || ! bfd_set_section_alignment (abfd, rtproc_sec, 12)) + return false; + } + + if (! alpha_elf_create_procedure_table (mdebug_handle, abfd, + info, rtproc_sec, &debug)) + return false; + } +#endif + + + /* Build the external symbol information. */ + einfo.abfd = abfd; + einfo.info = info; + einfo.debug = &debug; + einfo.swap = swap; + einfo.failed = false; + elf_link_hash_traverse (elf_hash_table (info), + elf64_alpha_output_extsym, + (PTR) &einfo); + if (einfo.failed) + return false; + + /* Set the size of the .mdebug section. */ + o->_raw_size = bfd_ecoff_debug_size (abfd, &debug, swap); + + /* Skip this section later on (I don't think this currently + matters, but someday it might). */ + o->link_order_head = (struct bfd_link_order *) NULL; + + mdebug_sec = o; + } + +#ifdef ERIC_neverdef + if (strncmp (o->name, ".gptab.", sizeof ".gptab." - 1) == 0) + { + const char *subname; + unsigned int c; + Elf64_gptab *tab; + Elf64_External_gptab *ext_tab; + unsigned int i; + + /* The .gptab.sdata and .gptab.sbss sections hold + information describing how the small data area would + change depending upon the -G switch. These sections + not used in executables files. */ + if (! info->relocateable) + { + asection **secpp; + + for (p = o->link_order_head; + p != (struct bfd_link_order *) NULL; + p = p->next) + { + asection *input_section; + + if (p->type != bfd_indirect_link_order) + { + if (p->type == bfd_fill_link_order) + continue; + abort (); + } + + input_section = p->u.indirect.section; + + /* Hack: reset the SEC_HAS_CONTENTS flag so that + elf_link_input_bfd ignores this section. */ + input_section->flags &=~ SEC_HAS_CONTENTS; + } + + /* Skip this section later on (I don't think this + currently matters, but someday it might). */ + o->link_order_head = (struct bfd_link_order *) NULL; + + /* Really remove the section. */ + for (secpp = &abfd->sections; + *secpp != o; + secpp = &(*secpp)->next) + ; + *secpp = (*secpp)->next; + --abfd->section_count; + + continue; + } + + /* There is one gptab for initialized data, and one for + uninitialized data. */ + if (strcmp (o->name, ".gptab.sdata") == 0) + gptab_data_sec = o; + else if (strcmp (o->name, ".gptab.sbss") == 0) + gptab_bss_sec = o; + else + { + (*_bfd_error_handler) + ("%s: illegal section name `%s'", + bfd_get_filename (abfd), o->name); + bfd_set_error (bfd_error_nonrepresentable_section); + return false; + } + + /* The linker script always combines .gptab.data and + .gptab.sdata into .gptab.sdata, and likewise for + .gptab.bss and .gptab.sbss. It is possible that there is + no .sdata or .sbss section in the output file, in which + case we must change the name of the output section. */ + subname = o->name + sizeof ".gptab" - 1; + if (bfd_get_section_by_name (abfd, subname) == NULL) + { + if (o == gptab_data_sec) + o->name = ".gptab.data"; + else + o->name = ".gptab.bss"; + subname = o->name + sizeof ".gptab" - 1; + BFD_ASSERT (bfd_get_section_by_name (abfd, subname) != NULL); + } + + /* Set up the first entry. */ + c = 1; + tab = (Elf64_gptab *) bfd_malloc (c * sizeof (Elf64_gptab)); + if (tab == NULL) + return false; + tab[0].gt_header.gt_current_g_value = elf_gp_size (abfd); + tab[0].gt_header.gt_unused = 0; + + /* Combine the input sections. */ + for (p = o->link_order_head; + p != (struct bfd_link_order *) NULL; + p = p->next) + { + asection *input_section; + bfd *input_bfd; + bfd_size_type size; + unsigned long last; + bfd_size_type gpentry; + + if (p->type != bfd_indirect_link_order) + { + if (p->type == bfd_fill_link_order) + continue; + abort (); + } + + input_section = p->u.indirect.section; + input_bfd = input_section->owner; + + /* Combine the gptab entries for this input section one + by one. We know that the input gptab entries are + sorted by ascending -G value. */ + size = bfd_section_size (input_bfd, input_section); + last = 0; + for (gpentry = sizeof (Elf64_External_gptab); + gpentry < size; + gpentry += sizeof (Elf64_External_gptab)) + { + Elf64_External_gptab ext_gptab; + Elf64_gptab int_gptab; + unsigned long val; + unsigned long add; + boolean exact; + unsigned int look; + + if (! (bfd_get_section_contents + (input_bfd, input_section, (PTR) &ext_gptab, + gpentry, sizeof (Elf64_External_gptab)))) + { + free (tab); + return false; + } + + bfd_alpha_elf64_swap_gptab_in (input_bfd, &ext_gptab, + &int_gptab); + val = int_gptab.gt_entry.gt_g_value; + add = int_gptab.gt_entry.gt_bytes - last; + + exact = false; + for (look = 1; look < c; look++) + { + if (tab[look].gt_entry.gt_g_value >= val) + tab[look].gt_entry.gt_bytes += add; + + if (tab[look].gt_entry.gt_g_value == val) + exact = true; + } + + if (! exact) + { + Elf64_gptab *new_tab; + unsigned int max; + + /* We need a new table entry. */ + new_tab = ((Elf64_gptab *) + bfd_realloc ((PTR) tab, + (c + 1) * sizeof (Elf64_gptab))); + if (new_tab == NULL) + { + free (tab); + return false; + } + tab = new_tab; + tab[c].gt_entry.gt_g_value = val; + tab[c].gt_entry.gt_bytes = add; + + /* Merge in the size for the next smallest -G + value, since that will be implied by this new + value. */ + max = 0; + for (look = 1; look < c; look++) + { + if (tab[look].gt_entry.gt_g_value < val + && (max == 0 + || (tab[look].gt_entry.gt_g_value + > tab[max].gt_entry.gt_g_value))) + max = look; + } + if (max != 0) + tab[c].gt_entry.gt_bytes += + tab[max].gt_entry.gt_bytes; + + ++c; + } + + last = int_gptab.gt_entry.gt_bytes; + } + + /* Hack: reset the SEC_HAS_CONTENTS flag so that + elf_link_input_bfd ignores this section. */ + input_section->flags &=~ SEC_HAS_CONTENTS; + } + + /* The table must be sorted by -G value. */ + if (c > 2) + qsort (tab + 1, c - 1, sizeof (tab[0]), gptab_compare); + + /* Swap out the table. */ + ext_tab = ((Elf64_External_gptab *) + bfd_alloc (abfd, c * sizeof (Elf64_External_gptab))); + if (ext_tab == NULL) + { + free (tab); + return false; + } + + for (i = 0; i < c; i++) + bfd_alpha_elf64_swap_gptab_out (abfd, tab + i, ext_tab + i); + free (tab); + + o->_raw_size = c * sizeof (Elf64_External_gptab); + o->contents = (bfd_byte *) ext_tab; + + /* Skip this section later on (I don't think this currently + matters, but someday it might). */ + o->link_order_head = (struct bfd_link_order *) NULL; + } +#endif + + } + + /* Invoke the regular ELF backend linker to do all the work. */ + if (! bfd_elf64_bfd_final_link (abfd, info)) + return false; + + /* Now write out the computed sections. */ + +#ifdef ERIC_neverdef + if (reginfo_sec != (asection *) NULL) + { + Elf64_External_RegInfo ext; + + bfd_alpha_elf64_swap_reginfo_out (abfd, ®info, &ext); + if (! bfd_set_section_contents (abfd, reginfo_sec, (PTR) &ext, + (file_ptr) 0, sizeof ext)) + return false; + } +#endif + + if (mdebug_sec != (asection *) NULL) + { + BFD_ASSERT (abfd->output_has_begun); + if (! bfd_ecoff_write_accumulated_debug (mdebug_handle, abfd, &debug, + swap, info, + mdebug_sec->filepos)) + return false; + + bfd_ecoff_debug_free (mdebug_handle, abfd, &debug, swap, info); + } + + if (gptab_data_sec != (asection *) NULL) + { + if (! bfd_set_section_contents (abfd, gptab_data_sec, + gptab_data_sec->contents, + (file_ptr) 0, + gptab_data_sec->_raw_size)) + return false; + } + + if (gptab_bss_sec != (asection *) NULL) + { + if (! bfd_set_section_contents (abfd, gptab_bss_sec, + gptab_bss_sec->contents, + (file_ptr) 0, + gptab_bss_sec->_raw_size)) + return false; + } + + return true; +} + +/* ECOFF swapping routines. These are used when dealing with the + .mdebug section, which is in the ECOFF debugging format. Copied + from elf32-mips.c. */ +static const struct ecoff_debug_swap +elf64_alpha_ecoff_debug_swap = +{ + /* Symbol table magic number. */ + magicSym2, + /* Alignment of debugging information. E.g., 4. */ + 8, + /* Sizes of external symbolic information. */ + sizeof (struct hdr_ext), + sizeof (struct dnr_ext), + sizeof (struct pdr_ext), + sizeof (struct sym_ext), + sizeof (struct opt_ext), + sizeof (struct fdr_ext), + sizeof (struct rfd_ext), + sizeof (struct ext_ext), + /* Functions to swap in external symbolic data. */ + ecoff_swap_hdr_in, + ecoff_swap_dnr_in, + ecoff_swap_pdr_in, + ecoff_swap_sym_in, + ecoff_swap_opt_in, + ecoff_swap_fdr_in, + ecoff_swap_rfd_in, + ecoff_swap_ext_in, + _bfd_ecoff_swap_tir_in, + _bfd_ecoff_swap_rndx_in, + /* Functions to swap out external symbolic data. */ + ecoff_swap_hdr_out, + ecoff_swap_dnr_out, + ecoff_swap_pdr_out, + ecoff_swap_sym_out, + ecoff_swap_opt_out, + ecoff_swap_fdr_out, + ecoff_swap_rfd_out, + ecoff_swap_ext_out, + _bfd_ecoff_swap_tir_out, + _bfd_ecoff_swap_rndx_out, + /* Function to read in symbolic data. */ + elf64_alpha_read_ecoff_info +}; + +#define TARGET_LITTLE_SYM bfd_elf64_alpha_vec +#define TARGET_LITTLE_NAME "elf64-alpha" +#define ELF_ARCH bfd_arch_alpha +#define ELF_MACHINE_CODE EM_ALPHA +#define ELF_MAXPAGESIZE 0x100000 + +#define bfd_elf64_bfd_link_hash_table_create \ + elf64_alpha_bfd_link_hash_table_create + +#define bfd_elf64_bfd_reloc_type_lookup \ + elf64_alpha_bfd_reloc_type_lookup +#define elf_info_to_howto \ + elf64_alpha_info_to_howto + +#define elf_backend_object_p \ + elf64_alpha_object_p +#define elf_backend_section_from_shdr \ + elf64_alpha_section_from_shdr +#define elf_backend_fake_sections \ + elf64_alpha_fake_sections +#define elf_backend_additional_program_headers \ + elf64_alpha_additional_program_headers + +#define bfd_elf64_bfd_is_local_label \ + elf64_alpha_is_local_label +#define bfd_elf64_find_nearest_line \ + elf64_alpha_find_nearest_line + +#define elf_backend_check_relocs \ + elf64_alpha_check_relocs +#define elf_backend_create_dynamic_sections \ + elf64_alpha_create_dynamic_sections +#define elf_backend_adjust_dynamic_symbol \ + elf64_alpha_adjust_dynamic_symbol +#define elf_backend_size_dynamic_sections \ + elf64_alpha_size_dynamic_sections +#define elf_backend_relocate_section \ + elf64_alpha_relocate_section +#define elf_backend_finish_dynamic_symbol \ + elf64_alpha_finish_dynamic_symbol +#define elf_backend_finish_dynamic_sections \ + elf64_alpha_finish_dynamic_sections +#define bfd_elf64_bfd_final_link \ + elf64_alpha_final_link + +#define elf_backend_ecoff_debug_swap \ + &elf64_alpha_ecoff_debug_swap + +/* + * A few constants that determine how the .plt section is set up. + */ +#define elf_backend_want_got_plt 0 +#define elf_backend_plt_readonly 0 +#define elf_backend_want_plt_sym 1 + +#include "elf64-target.h" diff --git a/gnu/usr.bin/binutils/bfd/elf64-mips.c b/gnu/usr.bin/binutils/bfd/elf64-mips.c index 978b921bb49..4ca8d4b26b5 100644 --- a/gnu/usr.bin/binutils/bfd/elf64-mips.c +++ b/gnu/usr.bin/binutils/bfd/elf64-mips.c @@ -22,11 +22,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ The MIPS 64-bit ELF ABI uses an unusual reloc format. This file overrides the usual ELF reloc handling, and handles reading and - writing the relocations here. */ + writing the relocations here. + + The MIPS 64-bit ELF ABI also uses an unusual archive map format. */ #include "bfd.h" #include "sysdep.h" #include "libbfd.h" +#include "aout/ar.h" #include "bfdlink.h" #include "genlink.h" #include "elf-bfd.h" @@ -69,6 +72,9 @@ static boolean mips_elf64_section_from_shdr PARAMS ((bfd *, Elf_Internal_Shdr *, char *)); static boolean mips_elf64_section_processing PARAMS ((bfd *, Elf_Internal_Shdr *)); +static boolean mips_elf64_slurp_armap PARAMS ((bfd *)); +static boolean mips_elf64_write_armap + PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int)); /* The relocation types. */ @@ -1829,6 +1835,215 @@ mips_elf64_section_processing (abfd, hdr) return _bfd_mips_elf_section_processing (abfd, hdr); } +/* Irix 6 defines a brand new archive map format, so that they can + have archives more than 4 GB in size. */ + +/* Read an Irix 6 armap. */ + +static boolean +mips_elf64_slurp_armap (abfd) + bfd *abfd; +{ + struct artdata *ardata = bfd_ardata (abfd); + char nextname[17]; + file_ptr arhdrpos; + bfd_size_type i, parsed_size, nsymz, stringsize, carsym_size, ptrsize; + struct areltdata *mapdata; + bfd_byte int_buf[8]; + char *stringbase; + bfd_byte *raw_armap = NULL; + carsym *carsyms; + + ardata->symdefs = NULL; + + /* Get the name of the first element. */ + arhdrpos = bfd_tell (abfd); + i = bfd_read ((PTR) nextname, 1, 16, abfd); + if (i == 0) + return true; + if (i != 16) + return false; + + if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0) + return false; + + /* Archives with traditional armaps are still permitted. */ + if (strncmp (nextname, "/ ", 16) == 0) + return bfd_slurp_armap (abfd); + + if (strncmp (nextname, "/SYM64/ ", 16) != 0) + { + bfd_has_map (abfd) = false; + return true; + } + + mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); + if (mapdata == NULL) + return false; + parsed_size = mapdata->parsed_size; + bfd_release (abfd, (PTR) mapdata); + + if (bfd_read (int_buf, 1, 8, abfd) != 8) + { + if (bfd_get_error () != bfd_error_system_call) + bfd_set_error (bfd_error_malformed_archive); + return false; + } + + nsymz = bfd_getb64 (int_buf); + stringsize = parsed_size - 8 * nsymz - 8; + + carsym_size = nsymz * sizeof (carsym); + ptrsize = 8 * nsymz; + + ardata->symdefs = (carsym *) bfd_zalloc (abfd, carsym_size + stringsize + 1); + if (ardata->symdefs == NULL) + return false; + carsyms = ardata->symdefs; + stringbase = ((char *) ardata->symdefs) + carsym_size; + + raw_armap = (bfd_byte *) bfd_alloc (abfd, ptrsize); + if (raw_armap == NULL) + goto error_return; + + if (bfd_read (raw_armap, 1, ptrsize, abfd) != ptrsize + || bfd_read (stringbase, 1, stringsize, abfd) != stringsize) + { + if (bfd_get_error () != bfd_error_system_call) + bfd_set_error (bfd_error_malformed_archive); + goto error_return; + } + + for (i = 0; i < nsymz; i++) + { + carsyms->file_offset = bfd_getb64 (raw_armap + i * 8); + carsyms->name = stringbase; + stringbase += strlen (stringbase) + 1; + ++carsyms; + } + *stringbase = '\0'; + + ardata->symdef_count = nsymz; + ardata->first_file_filepos = arhdrpos + sizeof (struct ar_hdr) + parsed_size; + + bfd_has_map (abfd) = true; + bfd_release (abfd, raw_armap); + + return true; + + error_return: + if (raw_armap != NULL) + bfd_release (abfd, raw_armap); + if (ardata->symdefs != NULL) + bfd_release (abfd, ardata->symdefs); + return false; +} + +/* Write out an Irix 6 armap. The Irix 6 tools are supposed to be + able to handle ordinary ELF armaps, but at least on Irix 6.2 the + linker crashes. */ + +static boolean +mips_elf64_write_armap (arch, elength, map, symbol_count, stridx) + bfd *arch; + unsigned int elength; + struct orl *map; + unsigned int symbol_count; + int stridx; +{ + unsigned int ranlibsize = (symbol_count * 8) + 8; + unsigned int stringsize = stridx; + unsigned int mapsize = stringsize + ranlibsize; + file_ptr archive_member_file_ptr; + bfd *current = arch->archive_head; + unsigned int count; + struct ar_hdr hdr; + unsigned int i; + int padding; + bfd_byte buf[8]; + + padding = BFD_ALIGN (mapsize, 8) - mapsize; + mapsize += padding; + + /* work out where the first object file will go in the archive */ + archive_member_file_ptr = (mapsize + + elength + + sizeof (struct ar_hdr) + + SARMAG); + + memset ((char *) (&hdr), 0, sizeof (struct ar_hdr)); + strcpy (hdr.ar_name, "/SYM64/"); + sprintf (hdr.ar_size, "%-10d", (int) mapsize); + sprintf (hdr.ar_date, "%ld", (long) time (NULL)); + /* This, at least, is what Intel coff sets the values to.: */ + sprintf ((hdr.ar_uid), "%d", 0); + sprintf ((hdr.ar_gid), "%d", 0); + sprintf ((hdr.ar_mode), "%-7o", (unsigned) 0); + strncpy (hdr.ar_fmag, ARFMAG, 2); + + for (i = 0; i < sizeof (struct ar_hdr); i++) + if (((char *) (&hdr))[i] == '\0') + (((char *) (&hdr))[i]) = ' '; + + /* Write the ar header for this item and the number of symbols */ + + if (bfd_write ((PTR) &hdr, 1, sizeof (struct ar_hdr), arch) + != sizeof (struct ar_hdr)) + return false; + + bfd_putb64 (symbol_count, buf); + if (bfd_write (buf, 1, 8, arch) != 8) + return false; + + /* Two passes, first write the file offsets for each symbol - + remembering that each offset is on a two byte boundary. */ + + /* Write out the file offset for the file associated with each + symbol, and remember to keep the offsets padded out. */ + + current = arch->archive_head; + count = 0; + while (current != (bfd *) NULL && count < symbol_count) + { + /* For each symbol which is used defined in this object, write out + the object file's address in the archive */ + + while (((bfd *) (map[count]).pos) == current) + { + bfd_putb64 (archive_member_file_ptr, buf); + if (bfd_write (buf, 1, 8, arch) != 8) + return false; + count++; + } + /* Add size of this archive entry */ + archive_member_file_ptr += (arelt_size (current) + + sizeof (struct ar_hdr)); + /* remember about the even alignment */ + archive_member_file_ptr += archive_member_file_ptr % 2; + current = current->next; + } + + /* now write the strings themselves */ + for (count = 0; count < symbol_count; count++) + { + size_t len = strlen (*map[count].name) + 1; + + if (bfd_write (*map[count].name, 1, len, arch) != len) + return false; + } + + /* The spec says that this should be padded to an 8 byte boundary. + However, the Irix 6.2 tools do not appear to do this. */ + while (padding != 0) + { + if (bfd_write ("", 1, 1, arch) != 1) + return false; + --padding; + } + + return true; +} + /* ECOFF swapping routines. These are used when dealing with the .mdebug section, which is in the ECOFF debugging format. */ static const struct ecoff_debug_swap mips_elf64_ecoff_debug_swap = @@ -1928,4 +2143,23 @@ const struct elf_size_info mips_elf64_size_info = _bfd_mips_elf_merge_private_bfd_data #define bfd_elf64_bfd_set_private_flags _bfd_mips_elf_set_private_flags +#define bfd_elf64_archive_functions +#define bfd_elf64_archive_slurp_armap mips_elf64_slurp_armap +#define bfd_elf64_archive_slurp_extended_name_table \ + _bfd_archive_coff_slurp_extended_name_table +#define bfd_elf64_archive_construct_extended_name_table \ + _bfd_archive_coff_construct_extended_name_table +#define bfd_elf64_archive_truncate_arname \ + _bfd_archive_coff_truncate_arname +#define bfd_elf64_archive_write_armap mips_elf64_write_armap +#define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr +#define bfd_elf64_archive_openr_next_archived_file \ + _bfd_archive_coff_openr_next_archived_file +#define bfd_elf64_archive_get_elt_at_index \ + _bfd_archive_coff_get_elt_at_index +#define bfd_elf64_archive_generic_stat_arch_elt \ + _bfd_archive_coff_generic_stat_arch_elt +#define bfd_elf64_archive_update_armap_timestamp \ + _bfd_archive_coff_update_armap_timestamp + #include "elf64-target.h" diff --git a/gnu/usr.bin/binutils/bfd/evax-alpha.c b/gnu/usr.bin/binutils/bfd/evax-alpha.c new file mode 100644 index 00000000000..20a5a979fd2 --- /dev/null +++ b/gnu/usr.bin/binutils/bfd/evax-alpha.c @@ -0,0 +1,1783 @@ +/* evax-alpha.c -- BFD back-end for ALPHA EVAX (openVMS/AXP) files. + Copyright 1996 Free Software Foundation, Inc. + Written by Klaus Kämpf (kkaempf@progis.de) + of proGIS Softwareentwicklung, Aachen, Germany + +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 + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "libbfd.h" + +#include "evax.h" + +static boolean evax_initialize PARAMS ((bfd *)); +static boolean fill_section_ptr PARAMS ((struct bfd_hash_entry *, PTR)); +static boolean evax_fixup_sections PARAMS ((bfd *)); +static boolean copy_symbols PARAMS ((struct bfd_hash_entry *, PTR)); +static bfd_reloc_status_type reloc_nil + PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); +static const struct bfd_target *evax_object_p PARAMS ((bfd *abfd)); +static const struct bfd_target *evax_archive_p PARAMS ((bfd *abfd)); +static boolean evax_mkobject PARAMS ((bfd *abfd)); +static boolean evax_write_object_contents PARAMS ((bfd *abfd)); +static boolean evax_close_and_cleanup PARAMS ((bfd *abfd)); +static boolean evax_bfd_free_cached_info PARAMS ((bfd *abfd)); +static boolean evax_new_section_hook PARAMS ((bfd *abfd, asection *section)); +static boolean evax_get_section_contents + PARAMS ((bfd *abfd, asection *section, PTR x1, file_ptr x2, + bfd_size_type x3)); +static boolean evax_get_section_contents_in_window + PARAMS ((bfd *abfd, asection *section, bfd_window *w, file_ptr offset, + bfd_size_type count)); +static boolean evax_bfd_copy_private_bfd_data PARAMS ((bfd *src, bfd *dest)); +static boolean evax_bfd_copy_private_section_data + PARAMS ((bfd *srcbfd, asection *srcsec, bfd *dstbfd, asection *dstsec)); +static boolean evax_bfd_copy_private_symbol_data + PARAMS ((bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym)); +static boolean evax_bfd_print_private_bfd_data + PARAMS ((bfd *abfd, void *file)); +static char *evax_core_file_failing_command PARAMS ((bfd *abfd)); +static int evax_core_file_failing_signal PARAMS ((bfd *abfd)); +static boolean evax_core_file_matches_executable_p + PARAMS ((bfd *abfd, bfd *bbfd)); +static boolean evax_slurp_armap PARAMS ((bfd *abfd)); +static boolean evax_slurp_extended_name_table PARAMS ((bfd *abfd)); +static boolean evax_construct_extended_name_table + PARAMS ((bfd *abfd, char **tabloc, bfd_size_type *tablen, + const char **name)); +static void evax_truncate_arname + PARAMS ((bfd *abfd, CONST char *pathname, char *arhdr)); +static boolean evax_write_armap + PARAMS ((bfd *arch, unsigned int elength, struct orl *map, + unsigned int orl_count, int stridx)); +static PTR evax_read_ar_hdr PARAMS ((bfd *abfd)); +static bfd *evax_get_elt_at_index PARAMS ((bfd *abfd, symindex index)); +static bfd *evax_openr_next_archived_file PARAMS ((bfd *arch, bfd *prev)); +static boolean evax_update_armap_timestamp PARAMS ((bfd *abfd)); +static int evax_generic_stat_arch_elt PARAMS ((bfd *abfd, struct stat *stat)); +static long evax_get_symtab_upper_bound PARAMS ((bfd *abfd)); +static long evax_get_symtab PARAMS ((bfd *abfd, asymbol **symbols)); +static void evax_print_symbol + PARAMS ((bfd *abfd, PTR file, asymbol *symbol, bfd_print_symbol_type how)); +static void evax_get_symbol_info + PARAMS ((bfd *abfd, asymbol *symbol, symbol_info *ret)); +static boolean evax_bfd_is_local_label PARAMS ((bfd *abfd, asymbol *symbol)); +static alent *evax_get_lineno PARAMS ((bfd *abfd, asymbol *symbol)); +static boolean evax_find_nearest_line + PARAMS ((bfd *abfd, asection *section, asymbol **symbols, bfd_vma offset, + const char **file, const char **func, unsigned int *line)); +static asymbol *evax_bfd_make_debug_symbol + PARAMS ((bfd *abfd, void *ptr, unsigned long size)); +static long evax_read_minisymbols + PARAMS ((bfd *abfd, boolean dynamic, PTR *minisymsp, unsigned int *sizep)); +static asymbol *evax_minisymbol_to_symbol + PARAMS ((bfd *abfd, boolean dynamic, const PTR minisym, asymbol *sym)); +static long evax_get_reloc_upper_bound PARAMS ((bfd *abfd, asection *sect)); +static long evax_canonicalize_reloc + PARAMS ((bfd *abfd, asection *srcsec, arelent **location, + asymbol **symbols)); +static const struct reloc_howto_struct *evax_bfd_reloc_type_lookup + PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); +static boolean evax_set_arch_mach + PARAMS ((bfd *abfd, enum bfd_architecture arch, unsigned long mach)); +static boolean evax_set_section_contents + PARAMS ((bfd *abfd, asection *section, PTR location, file_ptr offset, + bfd_size_type count)); +static int evax_sizeof_headers PARAMS ((bfd *abfd, boolean reloc)); +static bfd_byte *evax_bfd_get_relocated_section_contents + PARAMS ((bfd *abfd, struct bfd_link_info *link_info, + struct bfd_link_order *link_order, bfd_byte *data, + boolean relocateable, asymbol **symbols)); +static boolean evax_bfd_relax_section + PARAMS ((bfd *abfd, asection *section, struct bfd_link_info *link_info, + boolean *again)); +static struct bfd_link_hash_table *evax_bfd_link_hash_table_create + PARAMS ((bfd *abfd)); +static boolean evax_bfd_link_add_symbols + PARAMS ((bfd *abfd, struct bfd_link_info *link_info)); +static boolean evax_bfd_final_link + PARAMS ((bfd *abfd, struct bfd_link_info *link_info)); +static boolean evax_bfd_link_split_section + PARAMS ((bfd *abfd, asection *section)); +static long evax_get_dynamic_symtab_upper_bound PARAMS ((bfd *abfd)); +static long evax_canonicalize_dynamic_symtab + PARAMS ((bfd *abfd, asymbol **symbols)); +static long evax_get_dynamic_reloc_upper_bound PARAMS ((bfd *abfd)); +static long evax_canonicalize_dynamic_reloc + PARAMS ((bfd *abfd, arelent **arel, asymbol **symbols)); +static boolean evax_bfd_merge_private_bfd_data PARAMS ((bfd *ibfd, bfd *obfd)); +static boolean evax_bfd_set_private_flags PARAMS ((bfd *abfd, flagword flags)); + +#define evax_make_empty_symbol _bfd_evax_make_empty_symbol + +/*===========================================================================*/ + +const bfd_target evax_alpha_vec = +{ + + "evax-alpha", /* name */ + bfd_target_evax_flavour, + false, /* data byte order is little */ + false, /* header byte order is little */ + + (HAS_RELOC | HAS_SYMS + | WP_TEXT | D_PAGED), /* object flags */ + (SEC_ALLOC | SEC_LOAD | SEC_RELOC + | SEC_READONLY | SEC_CODE | SEC_DATA + | SEC_HAS_CONTENTS | SEC_IN_MEMORY), /* sect flags */ + 0, /* symbol_leading_char */ + ' ', /* ar_pad_char */ + 15, /* ar_max_namelen */ + bfd_getl64, bfd_getl_signed_64, bfd_putl64, + bfd_getl32, bfd_getl_signed_32, bfd_putl32, + bfd_getl16, bfd_getl_signed_16, bfd_putl16, + bfd_getl64, bfd_getl_signed_64, bfd_putl64, + bfd_getl32, bfd_getl_signed_32, bfd_putl32, + bfd_getl16, bfd_getl_signed_16, bfd_putl16, + + {_bfd_dummy_target, evax_object_p, /* bfd_check_format */ + evax_archive_p, _bfd_dummy_target}, + {bfd_false, evax_mkobject, /* bfd_set_format */ + _bfd_generic_mkarchive, bfd_false}, + {bfd_false, evax_write_object_contents, /* bfd_write_contents */ + _bfd_write_archive_contents, bfd_false}, + + BFD_JUMP_TABLE_GENERIC (evax), + BFD_JUMP_TABLE_COPY (evax), + BFD_JUMP_TABLE_CORE (evax), + BFD_JUMP_TABLE_ARCHIVE (evax), + BFD_JUMP_TABLE_SYMBOLS (evax), + BFD_JUMP_TABLE_RELOCS (evax), + BFD_JUMP_TABLE_WRITE (evax), + BFD_JUMP_TABLE_LINK (evax), + BFD_JUMP_TABLE_DYNAMIC (evax), + + (PTR) 0 +}; + + +/*===========================================================================*/ + +/* Initialize private data */ + +static boolean +evax_initialize (abfd) + bfd *abfd; +{ + int i; + + if (abfd->tdata.any != 0) + return true; + + bfd_set_start_address (abfd, (bfd_vma)-1); + + abfd->tdata.any = ((struct evax_private_data_struct*) + bfd_malloc (sizeof (struct evax_private_data_struct))); + if (abfd->tdata.any == 0) + return false; + PRIV(evax_buf) = 0; + PRIV(buf_size) = 0; + PRIV(rec_length) = 0; + PRIV(file_format) = FF_UNKNOWN; + PRIV(filename) = NULL; + PRIV(fixup_done) = false; + PRIV(sections) = NULL; + + PRIV(stack) = ((struct stack_struct *) + bfd_malloc (sizeof (struct stack_struct) * STACKSIZE)); + if (PRIV(stack) == 0) + { + evax_init_no_mem1: + free (abfd->tdata.any); + abfd->tdata.any = 0; + return false; + } + PRIV(stackptr) = 0; + + PRIV(evax_symbol_table) = ((struct bfd_hash_table *) + bfd_malloc (sizeof (struct bfd_hash_table))); + if (PRIV(evax_symbol_table) == 0) + { + evax_init_no_mem2: + free (PRIV(stack)); + PRIV(stack) = 0; + goto evax_init_no_mem1; + } + + if (!bfd_hash_table_init (PRIV(evax_symbol_table), _bfd_evax_hash_newfunc)) + return false; + + PRIV(location_stack) = ((struct location_struct *) + bfd_malloc (sizeof (struct location_struct) + * LOCATION_SAVE_SIZE)); + if (PRIV(location_stack) == 0) + { + evax_init_no_mem3: + free (PRIV(evax_symbol_table)); + PRIV(evax_symbol_table) = 0; + goto evax_init_no_mem2; + } + + for (i = 0; i < EVAX_SECTION_COUNT; i++) + PRIV(evax_section_table)[i] = NULL; + + PRIV(output_buf) = (unsigned char *) malloc (MAX_OUTREC_SIZE); + if (PRIV(output_buf) == 0) + { + free (PRIV(location_stack)); + PRIV(location_stack) = 0; + goto evax_init_no_mem3; + } + PRIV(push_level) = 0; + PRIV(pushed_size) = 0; + PRIV(length_pos) = 2; + PRIV(output_size) = 0; + PRIV(output_alignment) = 1; + + return true; +} + + +/* Fill symbol->section with section ptr + symbol->section is filled with the section index for defined symbols + during reading the EGSD section. But we need the pointer to the + bfd section later. + + It has the correct value for referenced (undefined section) symbols + + called from bfd_hash_traverse in evax_fixup_sections */ + +static boolean +fill_section_ptr (entry, sections) + struct bfd_hash_entry *entry; + PTR sections; +{ + asection *sec; + asymbol *sym; + + sym = ((evax_symbol_entry *)entry)->symbol; + sec = sym->section; + + if (!bfd_is_und_section (sec)) + { + sec = ((evax_symbol_entry *)entry)->symbol->section = + ((asection **)sections)[(int)sec]; + } + + if (strcmp (sym->name, sec->name) == 0) + sym->flags |= BSF_SECTION_SYM; + + return true; +} + + +/* Fixup sections + set up all pointers and arrays, counters and sizes are fixed now + + we build a private sections vector for easy access since sections + are always referenced by an index number. + + alloc PRIV(sections) according to abfd->section_count + copy abfd->sections to PRIV(sections) */ + +static boolean +evax_fixup_sections (abfd) + bfd *abfd; +{ + asection *s; + + if (PRIV(fixup_done)) + return true; + + PRIV(sections) = ((asection **) + bfd_malloc (abfd->section_count * sizeof (asection *))); + if (PRIV(sections) == 0) + return false; + PRIV(egsd_sec_count) = abfd->section_count; + s = abfd->sections; + while (s) + { + PRIV(sections)[s->index] = s; + s = s->next; + } + + /* + * traverse symbol table and fill in all section pointers + */ + + bfd_hash_traverse (PRIV(evax_symbol_table), fill_section_ptr, + (PTR)(PRIV(sections))); + + PRIV(fixup_done) = true; + + return true; +} + +/*===========================================================================*/ + +/* Check the format for a file being read. + Return a (bfd_target *) if it's an object file or zero if not. */ + +static const struct bfd_target * +evax_object_p (abfd) + bfd *abfd; +{ + int err = 0; + int prev_type; +#if EVAX_DEBUG + evax_debug (1, "evax_object_p(%p)\n", abfd); +#endif + if (bfd_seek (abfd, 0L, SEEK_SET)) + { + bfd_set_error (bfd_error_file_truncated); + return 0; + } + + prev_type = -1; + + do + { +#if EVAX_DEBUG + evax_debug (3, "reading at %08lx\n", bfd_tell(abfd)); +#endif + if (_bfd_evax_next_record (abfd) < 0) + { +#if EVAX_DEBUG + evax_debug (2, "next_record failed\n"); +#endif + bfd_set_error (bfd_error_wrong_format); + return 0; + } + + if ((prev_type == EOBJ_S_C_EGSD) && (PRIV(rec_type) != EOBJ_S_C_EGSD)) + { + if (evax_fixup_sections (abfd) == false) + { +#if EVAX_DEBUG + evax_debug (2, "evax_fixup_sections failed\n"); +#endif + bfd_set_error (bfd_error_wrong_format); + return 0; + } + } + + prev_type = PRIV(rec_type); + + switch (PRIV(rec_type)) + { + case EOBJ_S_C_EMH: + err = _bfd_evax_slurp_emh (abfd); + break; + case EOBJ_S_C_EEOM: + err = _bfd_evax_slurp_eeom (abfd); + break; + case EOBJ_S_C_EGSD: + err = _bfd_evax_slurp_egsd (abfd); + break; + case EOBJ_S_C_ETIR: + err = _bfd_evax_slurp_etir (abfd); + break; + case EOBJ_S_C_EDBG: + err = _bfd_evax_slurp_edbg (abfd); + break; + case EOBJ_S_C_ETBT: + err = _bfd_evax_slurp_etbt (abfd); + break; + default: + err = -1; + } + if (err != 0) + { +#if EVAX_DEBUG + evax_debug (2, "slurp type %d failed with %d\n", PRIV(rec_type), err); +#endif + bfd_set_error (bfd_error_wrong_format); + return 0; + } + } + while (prev_type != EOBJ_S_C_EEOM); + + /* set arch_info to alpha */ + + { + const bfd_arch_info_type *arch = bfd_scan_arch ("alpha"); + if (arch == 0) + { +#if EVAX_DEBUG + evax_debug (2, "arch not found\n"); +#endif + bfd_set_error (bfd_error_wrong_format); + return 0; + } + abfd->arch_info = arch; + } + + return &evax_alpha_vec; +} + + +/* Check the format for a file being read. + Return a (bfd_target *) if it's an archive file or zero. */ + +static const struct bfd_target * +evax_archive_p (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_archive_p(%p)\n", abfd); +#endif + + if (!evax_initialize (abfd)) + return 0; + + return 0; +} + + +/* Set the format of a file being written. */ + +static boolean +evax_mkobject (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_mkobject(%p)\n", abfd); +#endif + + if (!evax_initialize (abfd)) + return 0; + + { + const bfd_arch_info_type *arch = bfd_scan_arch ("alpha"); + if (arch == 0) + { + bfd_set_error(bfd_error_wrong_format); + return 0; + } + abfd->arch_info = arch; + } + + return true; +} + + +/* Write cached information into a file being written, at bfd_close. */ + +static boolean +evax_write_object_contents (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_write_object_contents(%p)\n", abfd); +#endif + + if (abfd->section_count > 0) /* we have sections */ + { + if (_bfd_evax_write_emh (abfd) != 0) + return false; + if (_bfd_evax_write_egsd (abfd) != 0) + return false; + if (_bfd_evax_write_etir (abfd) != 0) + return false; + if (_bfd_evax_write_etbt (abfd) != 0) + return false; + if (_bfd_evax_write_eeom (abfd) != 0) + return false; + } + return true; +} + +/*-- 4.1, generic -----------------------------------------------------------*/ + +/* Called when the BFD is being closed to do any necessary cleanup. */ + +static boolean +evax_close_and_cleanup (abfd) + bfd *abfd; +{ + asection *sec; + evax_section *es, *es1; + evax_reloc *er, *er1; + int i; + +#if EVAX_DEBUG + evax_debug (1, "evax_close_and_cleanup(%p)\n", abfd); +#endif + if (abfd == 0) + return true; + + if (PRIV(evax_buf) != NULL) + { + free (PRIV(evax_buf)); + PRIV(evax_buf) = NULL; + } + PRIV(buf_size) = 0; + + if (PRIV(filename) != NULL) + { + free (PRIV(filename)); + PRIV(filename) = NULL; + } + + if (PRIV(output_buf) != 0) + { + free (PRIV(output_buf)); + PRIV(output_buf) = 0; + } + + sec = abfd->sections; + while (sec != NULL) + { + if (sec->contents) + free (sec->contents); + sec = sec->next; + } + + if (PRIV(sections) != NULL) + { + free (PRIV(sections)); + PRIV(sections) = NULL; + } + + if (PRIV(evax_symbol_table)) + { + bfd_hash_table_free (PRIV(evax_symbol_table)); + PRIV(evax_symbol_table) = 0; + } + + if (PRIV(stack)) + { + free (PRIV(stack)); + PRIV(stack) = 0; + } + + if (PRIV(location_stack)) + { + free (PRIV(location_stack)); + PRIV(location_stack) = 0; + } + + for (i = 0; i < EVAX_SECTION_COUNT; i++) + { + es = PRIV(evax_section_table)[i]; + while (es != NULL) + { + es1 = es->next; + free (es); + es = es1; + } + PRIV(evax_section_table)[i] = NULL; + } + + free (abfd->tdata.any); + abfd->tdata.any = NULL; + + return true; +} + + +/* Ask the BFD to free all cached information. */ +static boolean +evax_bfd_free_cached_info (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_bfd_free_cached_info(%p)\n", abfd); +#endif + return true; +} + + +/* Called when a new section is created. */ + +static boolean +evax_new_section_hook (abfd, section) + bfd *abfd; + asection *section; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_new_section_hook(%p, %s)\n", abfd, section->name); +#endif + bfd_set_section_alignment(abfd, section, 4); + return true; +} + + +/* Read the contents of a section. + buf points to a buffer of buf_size bytes to be filled with + section data (starting at offset into section) */ + +static boolean +evax_get_section_contents (abfd, section, buf, offset, buf_size) + bfd *abfd; + asection *section; + PTR buf; + file_ptr offset; + bfd_size_type buf_size; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_get_section_contents(%p, %s, %p, off %ld, size %d)\n", + abfd, section->name, buf, offset, (int)buf_size); +#endif + + /* shouldn't be called, since all sections are IN_MEMORY */ + + return false; +} + +/* Read the contents of a section. + buf points to a buffer of buf_size bytes to be filled with + section data (starting at offset into section) */ + +static boolean +evax_get_section_contents_in_window (abfd, section, w, offset, count) + bfd *abfd; + asection *section; + bfd_window *w; + file_ptr offset; + bfd_size_type count; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_get_section_contents_in_window(%p, %s, %p, off %ld, count %d)\n", + abfd, section->name, w, offset, (int)count); +#endif + + /* shouldn't be called, since all sections are IN_MEMORY */ + + return false; +} + +/*-- Part 4.2, copy private data --------------------------------------------*/ + +/* Called to copy BFD general private data from one object file + to another. */ + +static boolean +evax_bfd_copy_private_bfd_data (src, dest) + bfd *src; + bfd *dest; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_bfd_copy_private_bfd_data(%p, %p)\n", src, dest); +#endif + return true; +} + + +/* Merge private BFD information from the BFD @var{ibfd} to the + the output file BFD @var{obfd} when linking. Return <> + on success, <> on error. Possible error returns are: + + o <> - + Not enough memory exists to create private data for @var{obfd}. */ + +static boolean +evax_bfd_merge_private_bfd_data (ibfd, obfd) + bfd *ibfd; + bfd *obfd; +{ +#if EVAX_DEBUG + evax_debug (1,"evax_bfd_merge_private_bfd_data(%p, %p)\n", ibfd, obfd); +#endif + return true; +} + + +/* Set private BFD flag information in the BFD @var{abfd}. + Return <> on success, <> on error. Possible error + returns are: + + o <> - + Not enough memory exists to create private data for @var{obfd}. */ + +static boolean +evax_bfd_set_private_flags (abfd, flags) + bfd *abfd; + flagword flags; +{ +#if EVAX_DEBUG + evax_debug (1,"evax_bfd_set_private_flags(%p, %lx)\n", abfd, (long)flags); +#endif + return true; +} + + +/* Called to copy BFD private section data from one object file + to another. */ + +static boolean +evax_bfd_copy_private_section_data (srcbfd, srcsec, dstbfd, dstsec) + bfd *srcbfd; + asection *srcsec; + bfd *dstbfd; + asection *dstsec; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_bfd_copy_private_section_data(%p, %s, %p, %s)\n", + srcbfd, srcsec->name, dstbfd, dstsec->name); +#endif + return true; +} + +/* Called to copy BFD private symbol data from one object file + to another. */ + +static boolean +evax_bfd_copy_private_symbol_data (ibfd, isym, obfd, osym) + bfd *ibfd; + asymbol *isym; + bfd *obfd; + asymbol *osym; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_bfd_copy_private_symbol_data(%p, %s, %p, %s)\n", + ibfd, isym->name, obfd, osym->name); +#endif + return true; +} + +/*-- Part 4.3, core file ----------------------------------------------------*/ + +/* Return a read-only string explaining which program was running + when it failed and produced the core file abfd. */ + +static char * +evax_core_file_failing_command (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_core_file_failing_command(%p)\n", abfd); +#endif + return 0; +} + + +/* Returns the signal number which caused the core dump which + generated the file the BFD abfd is attached to. */ + +static int +evax_core_file_failing_signal (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_core_file_failing_signal(%p)\n", abfd); +#endif + return 0; +} + + +/* Return true if the core file attached to core_bfd was generated + by a run of the executable file attached to exec_bfd, false otherwise. */ + +static boolean +evax_core_file_matches_executable_p (abfd, bbfd) + bfd *abfd; + bfd *bbfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_core_file_matches_executable_p(%p, %p)\n", abfd, bbfd); +#endif + return false; +} + +/*-- Part 4.4, archive ------------------------------------------------------*/ + +/* ??? do something with an archive map. + Return false on error, true otherwise. */ + +static boolean +evax_slurp_armap (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_slurp_armap(%p)\n", abfd); +#endif + return false; +} + + +/* ??? do something with an extended name table. + Return false on error, true otherwise. */ + +static boolean +evax_slurp_extended_name_table (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_slurp_extended_name_table(%p)\n", abfd); +#endif + return false; +} + + +/* ??? do something with an extended name table. + Return false on error, true otherwise. */ + +static boolean +evax_construct_extended_name_table (abfd, tabloc, tablen, name) + bfd *abfd; + char **tabloc; + bfd_size_type *tablen; + const char **name; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_construct_extended_name_table(%p)\n", abfd); +#endif + return false; +} + + +/* Truncate the name of an archive to match system-dependent restrictions */ + +static void +evax_truncate_arname (abfd, pathname, arhdr) + bfd *abfd; + CONST char *pathname; + char *arhdr; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_truncate_arname(%p, %s, %s)\n", abfd, pathname, arhdr); +#endif + return; +} + + +/* ??? write archive map */ + +static boolean +evax_write_armap (arch, elength, map, orl_count, stridx) + bfd *arch; + unsigned int elength; + struct orl *map; + unsigned int orl_count; + int stridx; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_write_armap(%p, %d, %p, %d %d)\n", + arch, elength, map, orl_count, stridx); +#endif + return true; +} + +/* Read archive header ??? */ + +static PTR +evax_read_ar_hdr (abfd) + bfd * abfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_read_ar_hdr(%p)\n", abfd); +#endif + return (PTR)0; +} + + +/* Provided a BFD, @var{archive}, containing an archive and NULL, open + an input BFD on the first contained element and returns that. + Subsequent calls should pass the archive and the previous return value + to return a created BFD to the next contained element. + NULL is returned when there are no more. */ + +static bfd * +evax_openr_next_archived_file (arch, prev) + bfd *arch; + bfd *prev; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_openr_next_archived_file(%p, %p)\n", arch, prev); +#endif + return false; +} + + +/* Return the BFD which is referenced by the symbol in ABFD indexed by + INDEX. INDEX should have been returned by bfd_get_next_mapent. */ + +static bfd * +evax_get_elt_at_index (abfd, index) + bfd *abfd; + symindex index; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_get_elt_at_index(%p, %p)\n", abfd, index); +#endif + return _bfd_generic_get_elt_at_index(abfd, index); +} + + +/* ??? + -> bfd_generic_stat_arch_elt */ + +static int +evax_generic_stat_arch_elt (abfd, stat) + bfd *abfd; + struct stat *stat; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_generic_stat_arch_elt(%p, %p)\n", abfd, stat); +#endif + return bfd_generic_stat_arch_elt(abfd, stat); +} + + +/* This is a new function in bfd 2.5 */ + +static boolean +evax_update_armap_timestamp (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_update_armap_timestamp(%p)\n", abfd); +#endif + return true; +} + +/*-- Part 4.5, symbols --------------------------------------------------------*/ + +/* Return the number of bytes required to store a vector of pointers + to asymbols for all the symbols in the BFD abfd, including a + terminal NULL pointer. If there are no symbols in the BFD, + then return 0. If an error occurs, return -1. */ + +static long +evax_get_symtab_upper_bound (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_get_symtab_upper_bound(%p), %d symbols\n", abfd, PRIV(egsd_sym_count)); +#endif + return (PRIV(egsd_sym_count)+1) * sizeof(asymbol *); +} + + +/* Copy symbols from hash table to symbol vector + + called from bfd_hash_traverse in evax_get_symtab + init counter to 0 if entry == 0 */ + +static boolean +copy_symbols (entry, arg) + struct bfd_hash_entry *entry; + PTR arg; +{ + bfd *abfd = (bfd *) arg; + + if (entry == NULL) /* init counter */ + PRIV(symnum) = 0; + else /* fill vector, inc counter */ + PRIV(symcache)[PRIV(symnum)++] = ((evax_symbol_entry *)entry)->symbol; + + return true; +} + + +/* Read the symbols from the BFD abfd, and fills in the vector + location with pointers to the symbols and a trailing NULL. + + return # of symbols read */ + +static long +evax_get_symtab (abfd, symbols) + bfd *abfd; + asymbol **symbols; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_get_symtab(%p, )\n", abfd); +#endif + + /* init counter */ + (void)copy_symbols((struct bfd_hash_entry *)0, abfd); + + /* traverse table and fill symbols vector */ + + PRIV(symcache) = symbols; + bfd_hash_traverse(PRIV(evax_symbol_table), copy_symbols, (PTR)abfd); + + symbols[bfd_get_symcount(abfd)] = NULL; + + return bfd_get_symcount(abfd); +} + + +/* Create a new asymbol structure for the BFD abfd and return a pointer + to it. + This routine is necessary because each back end has private information + surrounding the asymbol. Building your own asymbol and pointing to it + will not create the private information, and will cause problems later on. */ + +asymbol * +_bfd_evax_make_empty_symbol (abfd) + bfd *abfd; +{ + asymbol *symbol = (asymbol *)bfd_zalloc(abfd, sizeof(asymbol)); + +#if EVAX_DEBUG + evax_debug (1, "_bfd_evax_make_empty_symbol(%p)\n", abfd); +#endif + + if (symbol == 0) + { + bfd_set_error (bfd_error_no_memory); + return 0; + } + symbol->the_bfd = abfd; + + return symbol; +} + + +/* Print symbol to file according to how. how is one of + bfd_print_symbol_name just print the name + bfd_print_symbol_more print more (???) + bfd_print_symbol_all print all we know, which is not much right now :-) */ + +static void +evax_print_symbol (abfd, file, symbol, how) + bfd *abfd; + PTR file; + asymbol *symbol; + bfd_print_symbol_type how; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_print_symbol(%p, %p, %p, %d)\n", abfd, file, symbol, how); +#endif + + switch (how) + { + case bfd_print_symbol_name: + case bfd_print_symbol_more: + fprintf((FILE *)file," %s", symbol->name); + break; + + break; + + case bfd_print_symbol_all: + { + CONST char *section_name = symbol->section->name; + + bfd_print_symbol_vandf((PTR)file,symbol); + + fprintf((FILE *)file," %-8s %s", section_name, symbol->name); + } + break; + } + return; +} + + +/* Return information about symbol in ret. + + fill type, value and name + type: + A absolute + B bss segment symbol + C common symbol + D data segment symbol + f filename + t a static function symbol + T text segment symbol + U undefined + - debug */ + +static void +evax_get_symbol_info (abfd, symbol, ret) + bfd *abfd; + asymbol *symbol; + symbol_info *ret; +{ + asection *sec; + +#if EVAX_DEBUG + evax_debug (1, "evax_get_symbol_info(%p, %p, )\n", abfd, symbol); +#endif + + sec = symbol->section; + + if (bfd_is_com_section (sec)) + ret->type = 'C'; + else if (bfd_is_abs_section (sec)) + ret->type = 'A'; + else if (bfd_is_und_section (sec)) + ret->type = 'U'; + else if (bfd_is_abs_section (sec)) + ret->type = 'A'; + else if (bfd_is_ind_section (sec)) + ret->type = 'I'; + else if (bfd_get_section_flags (abfd, sec) & SEC_CODE) + ret->type = 'T'; + else if (bfd_get_section_flags (abfd, sec) & SEC_DATA) + ret->type = 'D'; + else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC) + ret->type = 'B'; + else + ret->type = '-'; + + if (ret->type != 'U') + ret->value = symbol->value + symbol->section->vma; + else + ret->value = 0; + ret->name = symbol->name; + + return; +} + + +/* Return true if the given symbol sym in the BFD abfd is + a compiler generated local label, else return false. */ + +static boolean +evax_bfd_is_local_label (abfd, symbol) + bfd *abfd; + asymbol *symbol; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_bfd_is_local_label(%p, %p)\n", abfd, symbol); +#endif + return false; +} + + +/* Get source line number for symbol */ + +static alent * +evax_get_lineno (abfd, symbol) + bfd *abfd; + asymbol *symbol; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_get_lineno(%p, %p)\n", abfd, symbol); +#endif + return 0; +} + + +/* Provided a BFD, a section and an offset into the section, calculate and + return the name of the source file and the line nearest to the wanted + location. */ + +static boolean +evax_find_nearest_line (abfd, section, symbols, offset, file, func, line) + bfd *abfd; + asection *section; + asymbol **symbols; + bfd_vma offset; + CONST char **file; + CONST char **func; + unsigned int *line; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_find_nearest_line(%p, %s, %p, %ld, , , )\n", + abfd, section->name, symbols, (long int)offset); +#endif + return false; +} + + +/* Back-door to allow format-aware applications to create debug symbols + while using BFD for everything else. Currently used by the assembler + when creating COFF files. */ + +static asymbol * +evax_bfd_make_debug_symbol (abfd, ptr, size) + bfd *abfd; + void *ptr; + unsigned long size; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_bfd_make_debug_symbol(%p, %p, %ld)\n", abfd, ptr, size); +#endif + return 0; +} + + +/* Read minisymbols. For minisymbols, we use the unmodified a.out + symbols. The minisymbol_to_symbol function translates these into + BFD asymbol structures. */ + +static long +evax_read_minisymbols (abfd, dynamic, minisymsp, sizep) + bfd *abfd; + boolean dynamic; + PTR *minisymsp; + unsigned int *sizep; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_read_minisymbols(%p, %d, %p, %d)\n", abfd, dynamic, minisymsp, *sizep); +#endif + return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep); +} + +/* Convert a minisymbol to a BFD asymbol. A minisymbol is just an + unmodified a.out symbol. The SYM argument is a structure returned + by bfd_make_empty_symbol, which we fill in here. */ + +static asymbol * +evax_minisymbol_to_symbol (abfd, dynamic, minisym, sym) + bfd *abfd; + boolean dynamic; + const PTR minisym; + asymbol *sym; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_minisymbol_to_symbol(%p, %d, %p, %p)\n", abfd, dynamic, minisym, sym); +#endif + return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym); +} + +/*-- Part 4.6, relocations --------------------------------------------------*/ + +/* Return the number of bytes required to store the relocation information + associated with section sect attached to bfd abfd. + If an error occurs, return -1. */ + +static long +evax_get_reloc_upper_bound (abfd, section) + bfd *abfd; + asection *section; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_get_reloc_upper_bound(%p, %s)\n", abfd, section->name); +#endif + return -1L; +} + + +/* Call the back end associated with the open BFD abfd and translate the + external form of the relocation information attached to sec into the + internal canonical form. Place the table into memory at loc, which has + been preallocated, usually by a call to bfd_get_reloc_upper_bound. + Returns the number of relocs, or -1 on error. */ + +static long +evax_canonicalize_reloc (abfd, section, location, symbols) + bfd *abfd; + asection *section; + arelent **location; + asymbol **symbols; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_canonicalize_reloc(%p, %s, , )\n", abfd, section->name); +#endif + return false; +} + +/*---------------------------------------------------------------------------*/ +/* this is just copied from ecoff-alpha, needs to be fixed probably */ + +/* How to process the various reloc types. */ + +static bfd_reloc_status_type +reloc_nil (abfd, reloc, sym, data, sec, output_bfd, error_message) + bfd *abfd; + arelent *reloc; + asymbol *sym; + PTR data; + asection *sec; + bfd *output_bfd; + char **error_message; +{ +#if EVAX_DEBUG + evax_debug (1, "reloc_nil(abfd %p, output_bfd %p)\n", abfd, output_bfd); + evax_debug (2, "In section %s, symbol %s\n", + sec->name, sym->name); + evax_debug (2, "reloc sym %s, addr %08lx, addend %08lx, reloc is a %s\n", + reloc->sym_ptr_ptr[0]->name, + (unsigned long)reloc->address, + (unsigned long)reloc->addend, reloc->howto->name); + evax_debug (2, "data at %p\n", data); +/* _bfd_hexdump (2, data, bfd_get_reloc_size(reloc->howto),0); */ +#endif + + return bfd_reloc_ok; +} + +/* 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) + +static reloc_howto_type alpha_howto_table[] = +{ + HOWTO (ALPHA_R_IGNORE, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 8, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + reloc_nil, /* special_function */ + "IGNORE", /* name */ + true, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + true), /* pcrel_offset */ + + /* A 64 bit reference to a symbol. */ + HOWTO (ALPHA_R_REFQUAD, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + reloc_nil, /* special_function */ + "REFQUAD", /* name */ + true, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + + /* A 21 bit branch. The native assembler generates these for + branches within the text segment, and also fills in the PC + relative offset in the instruction. */ + HOWTO (ALPHA_R_BRADDR, /* type */ + 2, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 21, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + reloc_nil, /* special_function */ + "BRADDR", /* name */ + true, /* partial_inplace */ + 0x1fffff, /* src_mask */ + 0x1fffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* A hint for a jump to a register. */ + HOWTO (ALPHA_R_HINT, /* type */ + 2, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 14, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + reloc_nil, /* special_function */ + "HINT", /* name */ + true, /* partial_inplace */ + 0x3fff, /* src_mask */ + 0x3fff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 16 bit PC relative offset. */ + HOWTO (ALPHA_R_SREL16, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + reloc_nil, /* special_function */ + "SREL16", /* name */ + true, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* 32 bit PC relative offset. */ + HOWTO (ALPHA_R_SREL32, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + reloc_nil, /* special_function */ + "SREL32", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + + /* A 64 bit PC relative offset. */ + HOWTO (ALPHA_R_SREL64, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + true, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_signed, /* complain_on_overflow */ + reloc_nil, /* special_function */ + "SREL64", /* name */ + true, /* partial_inplace */ + MINUS_ONE, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + + /* Push a value on the reloc evaluation stack. */ + HOWTO (ALPHA_R_OP_PUSH, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + reloc_nil, /* special_function */ + "OP_PUSH", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Store the value from the stack at the given address. Store it in + a bitfield of size r_size starting at bit position r_offset. */ + HOWTO (ALPHA_R_OP_STORE, /* type */ + 0, /* rightshift */ + 4, /* size (0 = byte, 1 = short, 2 = long) */ + 64, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + reloc_nil, /* special_function */ + "OP_STORE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + false), /* pcrel_offset */ + + /* Subtract the reloc address from the value on the top of the + relocation stack. */ + HOWTO (ALPHA_R_OP_PSUB, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + reloc_nil, /* special_function */ + "OP_PSUB", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Shift the value on the top of the relocation stack right by the + given value. */ + HOWTO (ALPHA_R_OP_PRSHIFT, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 0, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + reloc_nil, /* special_function */ + "OP_PRSHIFT", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* Hack. Linkage is done by linker. */ + HOWTO (ALPHA_R_LINKAGE, /* type */ + 0, /* rightshift */ + 8, /* size (0 = byte, 1 = short, 2 = long) */ + 256, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + reloc_nil, /* special_function */ + "LINKAGE", /* name */ + false, /* partial_inplace */ + 0, /* src_mask */ + 0, /* dst_mask */ + false), /* pcrel_offset */ + + /* A 32 bit reference to a symbol. */ + HOWTO (ALPHA_R_REFLONG, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + false, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_bitfield, /* complain_on_overflow */ + reloc_nil, /* special_function */ + "REFLONG", /* name */ + true, /* partial_inplace */ + 0xffffffff, /* src_mask */ + 0xffffffff, /* dst_mask */ + false), /* pcrel_offset */ + +}; + +/* Return a pointer to a howto structure which, when invoked, will perform + the relocation code on data from the architecture noted. */ + +static const struct reloc_howto_struct * +evax_bfd_reloc_type_lookup (abfd, code) + bfd *abfd; + bfd_reloc_code_real_type code; +{ + int alpha_type; + +#if EVAX_DEBUG + evax_debug (1, "evax_bfd_reloc_type_lookup(%p, %d)\t", abfd, code); +#endif + + switch (code) + { + case BFD_RELOC_16: alpha_type = ALPHA_R_SREL16; break; + case BFD_RELOC_32: alpha_type = ALPHA_R_REFLONG; break; + case BFD_RELOC_64: alpha_type = ALPHA_R_REFQUAD; break; + case BFD_RELOC_CTOR: alpha_type = ALPHA_R_REFQUAD; break; + case BFD_RELOC_23_PCREL_S2: alpha_type = ALPHA_R_BRADDR; break; + case BFD_RELOC_ALPHA_HINT: alpha_type = ALPHA_R_HINT; break; + case BFD_RELOC_16_PCREL: alpha_type = ALPHA_R_SREL16; break; + case BFD_RELOC_32_PCREL: alpha_type = ALPHA_R_SREL32; break; + case BFD_RELOC_64_PCREL: alpha_type = ALPHA_R_SREL64; break; + case BFD_RELOC_ALPHA_LINKAGE: alpha_type = ALPHA_R_LINKAGE; break; +#if 0 + case ???: alpha_type = ALPHA_R_OP_PUSH; break; + case ???: alpha_type = ALPHA_R_OP_STORE; break; + case ???: alpha_type = ALPHA_R_OP_PSUB; break; + case ???: alpha_type = ALPHA_R_OP_PRSHIFT;break; + case ???: alpha_type = ALPHA_R_GPVALUE; break; +#endif + default: + (*_bfd_error_handler) ("reloc (%d) is *UNKNOWN*", code); + return (const struct reloc_howto_struct *) NULL; + } +#if EVAX_DEBUG + evax_debug (2, "reloc is %s\n", alpha_howto_table[alpha_type].name); +#endif + return &alpha_howto_table[alpha_type]; +} + + +/*-- Part 4.7, writing an object file ---------------------------------------*/ + +/* Set the architecture and machine type in BFD abfd to arch and mach. + Find the correct pointer to a structure and insert it into the arch_info + pointer. */ + +static boolean +evax_set_arch_mach (abfd, arch, mach) + bfd *abfd; + enum bfd_architecture arch; + unsigned long mach; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_set_arch_mach(%p, %d, %ld)\n", abfd, arch, mach); +#endif + abfd->arch_info = bfd_scan_arch("alpha"); + + return true; +} + + +/* Sets the contents of the section section in BFD abfd to the data starting + in memory at data. The data is written to the output section starting at + offset offset for count bytes. + + Normally true is returned, else false. Possible error returns are: + o bfd_error_no_contents - The output section does not have the + SEC_HAS_CONTENTS attribute, so nothing can be written to it. + o and some more too */ + +static boolean +evax_set_section_contents (abfd, section, location, offset, count) + bfd *abfd; + asection *section; + PTR location; + file_ptr offset; + bfd_size_type count; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_set_section_contents(%p, sec %s, loc %p, off %ld, count %d)\n", + abfd, section->name, location, (long int)offset, (int)count); + evax_debug (2, "secraw %d, seccooked %d\n", (int)section->_raw_size, (int)section->_cooked_size); +#endif + return _bfd_save_evax_section(abfd, section, location, offset, count); +} + + +/*-- Part 4.8, linker -------------------------------------------------------*/ + +/* Get the size of the section headers. */ + +static int +evax_sizeof_headers (abfd, reloc) + bfd *abfd; + boolean reloc; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_sizeof_headers(%p, %s)\n", abfd, (reloc)?"True":"False"); +#endif + return 0; +} + + +/* Provides default handling of relocation effort for back ends + which can't be bothered to do it efficiently. */ + +static bfd_byte * +evax_bfd_get_relocated_section_contents (abfd, link_info, link_order, data, + relocateable, symbols) + bfd *abfd; + struct bfd_link_info *link_info; + struct bfd_link_order *link_order; + bfd_byte *data; + boolean relocateable; + asymbol **symbols; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_bfd_get_relocated_section_contents(%p, %p, %p, %p, %s, %p)\n", + abfd, link_info, link_order, data, (relocateable)?"True":"False", symbols); +#endif + return 0; +} + + +/* ??? */ + +static boolean +evax_bfd_relax_section (abfd, section, link_info, again) + bfd *abfd; + asection *section; + struct bfd_link_info *link_info; + boolean *again; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_bfd_relax_section(%p, %s, %p, )\n", + abfd, section->name, link_info); +#endif + return true; +} + + +/* Create a hash table for the linker. Different backends store + different information in this table. */ + +static struct bfd_link_hash_table * +evax_bfd_link_hash_table_create (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_bfd_link_hash_table_create(%p)\n", abfd); +#endif + return 0; +} + + +/* Add symbols from this object file into the hash table. */ + +static boolean +evax_bfd_link_add_symbols (abfd, link_info) + bfd *abfd; + struct bfd_link_info *link_info; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_bfd_link_add_symbols(%p, %p)\n", abfd, link_info); +#endif + return false; +} + + +/* Do a link based on the link_order structures attached to each + section of the BFD. */ + +static boolean +evax_bfd_final_link (abfd, link_info) + bfd *abfd; + struct bfd_link_info *link_info; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_bfd_final_link(%p, %p)\n", abfd, link_info); +#endif + return true; +} + +/* Should this section be split up into smaller pieces during linking. */ + +static boolean +evax_bfd_link_split_section (abfd, section) + bfd *abfd; + asection *section; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_bfd_link_split_section(%p, %s)\n", abfd, section->name); +#endif + return false; +} + +/*-- Part 4.9, dynamic symbols and relocations ------------------------------*/ + +/* Get the amount of memory required to hold the dynamic symbols. */ + +static long +evax_get_dynamic_symtab_upper_bound (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_get_dynamic_symtab_upper_bound(%p)\n", abfd); +#endif + return 0; +} + +static boolean +evax_bfd_print_private_bfd_data (abfd, file) + bfd *abfd; + void *file; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_bfd_print_private_bfd_data(%p)\n", abfd); +#endif + return 0; +} + + +/* Read in the dynamic symbols. */ + +static long +evax_canonicalize_dynamic_symtab (abfd, symbols) + bfd *abfd; + asymbol **symbols; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_canonicalize_dynamic_symtab(%p, )\n", abfd); +#endif + return 0L; +} + + +/* Get the amount of memory required to hold the dynamic relocs. */ + +static long +evax_get_dynamic_reloc_upper_bound (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_get_dynamic_reloc_upper_bound(%p)\n", abfd); +#endif + return 0L; +} + + +/* Read in the dynamic relocs. */ + +static long +evax_canonicalize_dynamic_reloc (abfd, arel, symbols) + bfd *abfd; + arelent **arel; + asymbol **symbols; +{ +#if EVAX_DEBUG + evax_debug (1, "evax_canonicalize_dynamic_reloc(%p)\n", abfd); +#endif + return 0L; +} diff --git a/gnu/usr.bin/binutils/bfd/evax-egsd.c b/gnu/usr.bin/binutils/bfd/evax-egsd.c new file mode 100644 index 00000000000..f5275a98567 --- /dev/null +++ b/gnu/usr.bin/binutils/bfd/evax-egsd.c @@ -0,0 +1,582 @@ +/* evax-egsd.c -- BFD back-end for ALPHA EVAX (openVMS/AXP) files. + Copyright 1996 Free Software Foundation Inc. + + go and read the openVMS linker manual (esp. appendix B) + if you don't know what's going on here :-) + + Written by Klaus Kämpf (kkaempf@progis.de) + of proGIS Softwareentwicklung, Aachen, Germany + +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 +#include + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "libbfd.h" + +#include "evax.h" + +/*-----------------------------------------------------------------------------*/ + +/* sections every evax object file has */ + +#define EVAX_ABS_NAME "$ABS$" +#define EVAX_CODE_NAME "$CODE$" +#define EVAX_LINK_NAME "$LINK$" +#define EVAX_DATA_NAME "$DATA$" +#define EVAX_BSS_NAME "$BSS$" +#define EVAX_READONLY_NAME "$READONLY$" +#define EVAX_LITERAL_NAME "$LITERAL$" + +struct sec_flags_struct { + char *name; /* name of section */ + int eflags_always; + flagword flags_always; /* flags we set always */ + int eflags_hassize; + flagword flags_hassize; /* flags we set if the section has a size > 0 */ +}; + +/* just a dummy flag array since i don't understand it yet */ + +static struct sec_flags_struct evax_section_flags[] = { + { EVAX_ABS_NAME, + (EGPS_S_V_SHR), + (SEC_DATA), + (EGPS_S_V_SHR), + (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }, + { EVAX_CODE_NAME, + (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE), + (SEC_CODE), + (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_EXE), + (SEC_IN_MEMORY|SEC_CODE|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }, + { EVAX_LINK_NAME, + (EGPS_S_V_REL|EGPS_S_V_RD), + (SEC_DATA|SEC_READONLY), + (EGPS_S_V_REL|EGPS_S_V_RD), + (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) }, + { EVAX_DATA_NAME, + (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT), + (SEC_DATA), + (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT), + (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }, + { EVAX_BSS_NAME, + (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD), + (SEC_NO_FLAGS), + (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT|EGPS_S_V_NOMOD), + (SEC_IN_MEMORY|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) }, + { EVAX_READONLY_NAME, + (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD), + (SEC_DATA|SEC_READONLY), + (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD), + (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) }, + { EVAX_LITERAL_NAME, + (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD), + (SEC_DATA|SEC_READONLY), + (EGPS_S_V_PIC|EGPS_S_V_REL|EGPS_S_V_SHR|EGPS_S_V_RD), + (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_READONLY|SEC_LOAD) }, + { NULL, + (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT), + (SEC_DATA), + (EGPS_S_V_REL|EGPS_S_V_RD|EGPS_S_V_WRT), + (SEC_IN_MEMORY|SEC_DATA|SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD) } +}; + +/* Retrieve bfd section flags by name and size */ + +static flagword +evax_secflag_by_name(name, size) + char *name; + int size; +{ + int i = 0; + + while (evax_section_flags[i].name != NULL) + { + if (strcmp (name, evax_section_flags[i].name) == 0) + { + if (size > 0) + return evax_section_flags[i].flags_hassize; + else + return evax_section_flags[i].flags_always; + } + i++; + } + if (size > 0) + return evax_section_flags[i].flags_hassize; + return evax_section_flags[i].flags_always; +} + + +/* Retrieve evax section flags by name and size */ + +static flagword +evax_esecflag_by_name(name, size) + char *name; + int size; +{ + int i = 0; + + while (evax_section_flags[i].name != NULL) + { + if (strcmp (name, evax_section_flags[i].name) == 0) + { + if (size > 0) + return evax_section_flags[i].eflags_hassize; + else + return evax_section_flags[i].eflags_always; + } + i++; + } + if (size > 0) + return evax_section_flags[i].eflags_hassize; + return evax_section_flags[i].eflags_always; +} + +/*-----------------------------------------------------------------------------*/ +#if EVAX_DEBUG +/* debug */ + +struct flagdescstruct { char *name; flagword value; }; + +/* Convert flag to printable string */ + +static char * +flag2str(flagdesc, flags) + struct flagdescstruct *flagdesc; + flagword flags; +{ + + static char res[64]; + int next = 0; + + res[0] = 0; + while (flagdesc->name != NULL) + { + if ((flags & flagdesc->value) != 0) + { + if (next) + strcat(res, ","); + else + next = 1; + strcat (res, flagdesc->name); + } + flagdesc++; + } + return res; +} +#endif + +/*-----------------------------------------------------------------------------*/ +/* input routines */ + +/* Process EGSD record + return 0 on success, -1 on error */ + +int +_bfd_evax_slurp_egsd (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + static struct flagdescstruct gpsflagdesc[] = + { + { "PIC", 0x0001 }, + { "LIB", 0x0002 }, + { "OVR", 0x0004 }, + { "REL", 0x0008 }, + { "GBL", 0x0010 }, + { "SHR", 0x0020 }, + { "EXE", 0x0040 }, + { "RD", 0x0080 }, + { "WRT", 0x0100 }, + { "VEC", 0x0200 }, + { "NOMOD", 0x0400 }, + { "COM", 0x0800 }, + { NULL, 0 } + }; + + static struct flagdescstruct gsyflagdesc[] = + { + { "WEAK", 0x0001 }, + { "DEF", 0x0002 }, + { "UNI", 0x0004 }, + { "REL", 0x0008 }, + { "COMM", 0x0010 }, + { "VECEP", 0x0020 }, + { "NORM", 0x0040 }, + { NULL, 0 } + }; +#endif + + int gsd_type, gsd_size; + asection *section; + unsigned char *evax_rec; + flagword new_flags, old_flags; + char *name; + asymbol *symbol; + evax_symbol_entry *entry; + unsigned long base_addr; + unsigned long align_addr; + +#if EVAX_DEBUG + evax_debug (2, "EGSD\n"); +#endif + + PRIV(evax_rec) += 8; /* skip type, size, l_temp */ + PRIV(rec_size) -= 8; + + /* calculate base address for each section */ + base_addr = 0L; + + abfd->symcount = 0; + + while (PRIV(rec_size) > 0) + { + evax_rec = PRIV(evax_rec); + _bfd_evax_get_header_values (abfd, evax_rec, &gsd_type, &gsd_size); + switch (gsd_type) + { + case EGSD_S_C_PSC: + { + /* program section definition */ + + name = _bfd_evax_save_counted_string ((char *)evax_rec+12); + section = bfd_make_section (abfd, name); + if (!section) + return -1; + old_flags = bfd_getl16 (evax_rec + 6); + section->_raw_size = bfd_getl32 (evax_rec + 8); /* allocation */ + new_flags = evax_secflag_by_name (name, (int) section->_raw_size); + if (old_flags & EGPS_S_V_REL) + new_flags |= SEC_RELOC; + if (!bfd_set_section_flags (abfd, section, new_flags)) + return -1; + section->alignment_power = evax_rec[4]; + align_addr = (1 << section->alignment_power); + if ((base_addr % align_addr) != 0) + base_addr += (align_addr - (base_addr % align_addr)); + section->vma = (bfd_vma)base_addr; + base_addr += section->_raw_size; + section->contents = ((unsigned char *) + bfd_malloc (section->_raw_size)); + if (section->contents == NULL) + return -1; + memset (section->contents, 0, (size_t) section->_raw_size); + section->_cooked_size = section->_raw_size; +#if EVAX_DEBUG + evax_debug(3, "egsd psc %d (%s, flags %04x=%s) ", + section->index, name, old_flags, flag2str(gpsflagdesc, old_flags)); + evax_debug(3, "%d bytes at 0x%08lx (mem %p)\n", + section->_raw_size, section->vma, section->contents); +#endif + } + break; + + case EGSD_S_C_SYM: + { + /* symbol specification (definition or reference) */ + + symbol = _bfd_evax_make_empty_symbol (abfd); + if (symbol == 0) + return -1; + + old_flags = bfd_getl16 (evax_rec + 6); + new_flags = BSF_NO_FLAGS; + + if (old_flags & EGSY_S_V_WEAK) + new_flags |= BSF_WEAK; + + if (evax_rec[6] & EGSY_S_V_DEF) /* symbol definition */ + { + symbol->name = + _bfd_evax_save_counted_string ((char *)evax_rec+32); + if (old_flags & EGSY_S_V_NORM) + { /* proc def */ + new_flags |= BSF_FUNCTION; + } + symbol->value = bfd_getl64 (evax_rec+8); + symbol->section = (asection *)((unsigned long) bfd_getl32 (evax_rec+28)); +#if EVAX_DEBUG + evax_debug(3, "egsd sym def #%d (%s, %d, %04x=%s)\n", abfd->symcount, + symbol->name, (int)symbol->section, old_flags, flag2str(gsyflagdesc, old_flags)); +#endif + } + else /* symbol reference */ + { +#if EVAX_DEBUG + evax_debug(3, "egsd sym ref #%d (%s, %04x=%s)\n", abfd->symcount, evax_rec+9, old_flags, flag2str(gsyflagdesc, old_flags)); +#endif + symbol->name = + _bfd_evax_save_counted_string ((char *)evax_rec+8); + symbol->section = bfd_make_section (abfd, BFD_UND_SECTION_NAME); + } + + symbol->flags = new_flags; + + /* save symbol in evax_symbol_table */ + + entry = (evax_symbol_entry *) bfd_hash_lookup (PRIV(evax_symbol_table), symbol->name, true, false); + if (entry == (evax_symbol_entry *)NULL) + { + bfd_set_error (bfd_error_no_memory); + return -1; + } + if (entry->symbol != (asymbol *)NULL) + { /* FIXME ?, DEC C generates this */ +#if EVAX_DEBUG + evax_debug(3, "EGSD_S_C_SYM: duplicate \"%s\"\n", symbol->name); +#endif + } + else + { + entry->symbol = symbol; + PRIV(egsd_sym_count)++; + abfd->symcount++; + } + } + break; + + case EGSD_S_C_IDC: + break; + + default: + (*_bfd_error_handler) ("unknown egsd subtype %d", gsd_type); + bfd_set_error (bfd_error_bad_value); + return -1; + + } /* switch */ + + PRIV(rec_size) -= gsd_size; + PRIV(evax_rec) += gsd_size; + + } /* while (recsize > 0) */ + + if (abfd->symcount > 0) + abfd->flags |= HAS_SYMS; + + return 0; +} + +/*-----------------------------------------------------------------------------*/ +/* output routines */ + +/* Write section and symbol directory of bfd abfd */ + +int +_bfd_evax_write_egsd (abfd) + bfd *abfd; +{ + asection *section; + asymbol *symbol; + int symnum; + int last_index = -1; + char dummy_name[10]; + char *sname; + flagword new_flags, old_flags; + char uname[200]; + char *nptr, *uptr; + +#if EVAX_DEBUG + evax_debug (2, "evax_write_egsd(%p)\n", abfd); +#endif + + /* output sections */ + + section = abfd->sections; +#if EVAX_DEBUG + evax_debug (3, "%d sections found\n", abfd->section_count); +#endif + + /* egsd is quadword aligned */ + + _bfd_evax_output_alignment (abfd, 8); + + _bfd_evax_output_begin (abfd, EOBJ_S_C_EGSD, -1); + _bfd_evax_output_long (abfd, 0); + _bfd_evax_output_push (abfd); /* prepare output for subrecords */ + + while (section != 0) + { +#if EVAX_DEBUG + evax_debug (3, "Section #%d %s, %d bytes\n", section->index, section->name, (int)section->_raw_size); +#endif + + /* 13 bytes egsd, max 31 chars name -> should be 44 bytes */ + if (_bfd_evax_output_check (abfd, 64) < 0) + { + _bfd_evax_output_pop (abfd); + _bfd_evax_output_end (abfd); + _bfd_evax_output_begin (abfd, EOBJ_S_C_EGSD, -1); + _bfd_evax_output_long (abfd, 0); + _bfd_evax_output_push (abfd); /* prepare output for subrecords */ + } + + /* Create dummy sections to keep consecutive indices */ + + while (section->index - last_index > 1) + { +#if EVAX_DEBUG + evax_debug (3, "index %d, last %d\n", section->index, last_index); +#endif + _bfd_evax_output_begin (abfd, EGSD_S_C_PSC, -1); + _bfd_evax_output_short (abfd, 0); + _bfd_evax_output_short (abfd, 0); + _bfd_evax_output_long (abfd, 0); + sprintf (dummy_name, ".DUMMY%02d", last_index); + _bfd_evax_output_counted (abfd, dummy_name); + _bfd_evax_output_flush (abfd); + last_index++; + } + + /* Don't know if this is neccesary for the linker but for now it keeps + evax_slurp_egsd happy */ + + sname = (char *)section->name; + if (*sname == '.') + { + sname++; + if ((*sname == 't') && (strcmp (sname, "text") == 0)) + sname = EVAX_CODE_NAME; + else if ((*sname == 'd') && (strcmp (sname, "data") == 0)) + sname = EVAX_DATA_NAME; + else if ((*sname == 'b') && (strcmp (sname, "bss") == 0)) + sname = EVAX_BSS_NAME; + else if ((*sname == 'l') && (strcmp (sname, "link") == 0)) + sname = EVAX_LINK_NAME; + else if ((*sname == 'r') && (strcmp (sname, "rdata") == 0)) + sname = EVAX_READONLY_NAME; + else if ((*sname == 'l') && (strcmp (sname, "literal") == 0)) + sname = EVAX_LITERAL_NAME; + } + + _bfd_evax_output_begin (abfd, EGSD_S_C_PSC, -1); + _bfd_evax_output_short (abfd, section->alignment_power & 0xff); + _bfd_evax_output_short (abfd, + evax_esecflag_by_name (sname, + section->_raw_size)); + _bfd_evax_output_long (abfd, section->_raw_size); + _bfd_evax_output_counted (abfd, sname); + _bfd_evax_output_flush (abfd); + + last_index = section->index; + section = section->next; + } + + /* output symbols */ + +#if EVAX_DEBUG + evax_debug (3, "%d symbols found\n", abfd->symcount); +#endif + + bfd_set_start_address (abfd, (bfd_vma)-1); + + for (symnum = 0; symnum < abfd->symcount; symnum++) + { + + symbol = abfd->outsymbols[symnum]; + if (*(symbol->name) == '_') + { + if (strcmp (symbol->name, "__main") == 0) + bfd_set_start_address (abfd, (bfd_vma)symbol->value); + } + old_flags = symbol->flags; + + if (((old_flags & BSF_GLOBAL) == 0) /* not xdef */ + && (!bfd_is_und_section (symbol->section))) /* and not xref */ + continue; /* dont output */ + + /* 13 bytes egsd, max 64 chars name -> should be 77 bytes */ + + if (_bfd_evax_output_check (abfd, 80) < 0) + { + _bfd_evax_output_pop (abfd); + _bfd_evax_output_end (abfd); + _bfd_evax_output_begin (abfd, EOBJ_S_C_EGSD, -1); + _bfd_evax_output_long (abfd, 0); + _bfd_evax_output_push (abfd); /* prepare output for subrecords */ + } + + _bfd_evax_output_begin (abfd, EGSD_S_C_SYM, -1); + + _bfd_evax_output_short (abfd, 0); /* data type, alignment */ + + new_flags = 0; + if (old_flags & BSF_WEAK) + new_flags |= EGSY_S_V_WEAK; + if (old_flags & BSF_FUNCTION) + { + new_flags |= EGSY_S_V_NORM; + new_flags |= EGSY_S_V_REL; + } + if (old_flags & BSF_GLOBAL) + { + new_flags |= EGSY_S_V_DEF; + if (!bfd_is_abs_section (symbol->section)) + new_flags |= EGSY_S_V_REL; + } + _bfd_evax_output_short (abfd, new_flags); + + if (old_flags & BSF_GLOBAL) /* symbol definition */ + { + if (old_flags & BSF_FUNCTION) + { + _bfd_evax_output_quad (abfd, symbol->value); + _bfd_evax_output_quad (abfd, + ((asymbol *)(symbol->udata.p))->value); + _bfd_evax_output_long (abfd, + (((asymbol *)(symbol->udata.p)) + ->section->index)); + _bfd_evax_output_long (abfd, symbol->section->index); + } + else + { + _bfd_evax_output_quad (abfd, symbol->value); /* L_VALUE */ + _bfd_evax_output_quad (abfd, 0); /* L_CODE_ADDRESS */ + _bfd_evax_output_long (abfd, 0); /* L_CA_PSINDX */ + _bfd_evax_output_long (abfd, symbol->section->index);/* L_PSINDX, FIXME */ + } + } + if (strlen ((char *)symbol->name) > 198) + { + (*_bfd_error_handler) ("Name '%s' too long\n", symbol->name); + abort (); + } + nptr = (char *)symbol->name; + uptr = uname; + while (*nptr) + { + if (islower (*nptr)) + *uptr = toupper (*nptr); + else + *uptr = *nptr; + uptr++; + nptr++; + } + *uptr = 0; + _bfd_evax_output_counted (abfd, uname); + + _bfd_evax_output_flush (abfd); + + } + + _bfd_evax_output_alignment (abfd, 8); + _bfd_evax_output_pop (abfd); + _bfd_evax_output_end (abfd); + + return 0; +} diff --git a/gnu/usr.bin/binutils/bfd/evax-emh.c b/gnu/usr.bin/binutils/bfd/evax-emh.c new file mode 100644 index 00000000000..69f7e0be91b --- /dev/null +++ b/gnu/usr.bin/binutils/bfd/evax-emh.c @@ -0,0 +1,266 @@ +/* evax-emh.c -- BFD back-end for ALPHA EVAX (openVMS/AXP) files. + Copyright 1996 Free Software Foundation, Inc. + + EMH record handling functions + and + EEOM record handling functions + + Written by Klaus Kämpf (kkaempf@progis.de) + of proGIS Softwareentwicklung, Aachen, Germany + +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 + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "libbfd.h" + +#include "evax.h" + +/*---------------------------------------------------------------------------*/ + + +/* Read & process emh record + return 0 on success, -1 on error */ + +int +_bfd_evax_slurp_emh (abfd) + bfd *abfd; +{ + unsigned char *ptr; + unsigned char *evax_rec; + + evax_rec = PRIV(evax_rec); + +#if EVAX_DEBUG + evax_debug(2, "EMH\n"); +#endif + + switch (bfd_getl16 (evax_rec + 4)) + { + + case EMH_S_C_MHD: + /* + * module header + */ + PRIV(emh_data).emh_b_strlvl = evax_rec[6]; + PRIV(emh_data).emh_l_arch1 = bfd_getl32 (evax_rec + 8); + PRIV(emh_data).emh_l_arch2 = bfd_getl32 (evax_rec + 12); + PRIV(emh_data).emh_l_recsiz = bfd_getl32 (evax_rec + 16); + PRIV(emh_data).emh_t_name = + _bfd_evax_save_counted_string ((char *)evax_rec + 20); + ptr = evax_rec + 20 + evax_rec[20] + 1; + PRIV(emh_data).emh_t_version = + _bfd_evax_save_counted_string ((char *)ptr); + ptr += *ptr + 1; + PRIV(emh_data).emh_t_date = + _bfd_evax_save_sized_string ((char *)ptr, 17); + + break; + + case EMH_S_C_LNM: + /* + * + */ + PRIV(emh_data).emh_c_lnm = + _bfd_evax_save_sized_string ((char *)evax_rec, PRIV(rec_length-6)); + break; + + case EMH_S_C_SRC: + /* + * + */ + PRIV(emh_data).emh_c_src = + _bfd_evax_save_sized_string ((char *)evax_rec, PRIV(rec_length-6)); + break; + + case EMH_S_C_TTL: + /* + * + */ + PRIV(emh_data).emh_c_ttl = + _bfd_evax_save_sized_string ((char *)evax_rec, PRIV(rec_length-6)); + break; + + case EMH_S_C_CPR: + /* + * + */ + break; + + case EMH_S_C_MTC: + /* + * + */ + break; + + case EMH_S_C_GTX: + /* + * + */ + break; + + default: + bfd_set_error (bfd_error_wrong_format); + return -1; + + } /* switch */ + + return 0; +} + + +/* write object header for bfd abfd */ + +int +_bfd_evax_write_emh (abfd) + bfd *abfd; +{ + char *name; + +#if EVAX_DEBUG + evax_debug (2, "evax_write_emh(%p)\n", abfd); +#endif + + _bfd_evax_output_alignment (abfd, 2); + + /* MHD */ + + _bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_MHD); + _bfd_evax_output_short (abfd, EOBJ_S_C_STRLVL); + _bfd_evax_output_long (abfd, 0); + _bfd_evax_output_long (abfd, 0); + _bfd_evax_output_long (abfd, MAX_OUTREC_SIZE); + if (bfd_get_filename (abfd) != NULL) + { + name = strdup (bfd_get_filename (abfd)); + _bfd_evax_output_counted (abfd, _bfd_evax_basename (name)); + } + else + _bfd_evax_output_counted (abfd, "NONAME"); + _bfd_evax_output_counted (abfd, BFD_VERSION); + _bfd_evax_output_dump (abfd, (unsigned char *)_bfd_get_vms_time_string (), + 17); + _bfd_evax_output_fill (abfd, 0, 17); + _bfd_evax_output_flush (abfd); + + /* LMN */ + + _bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_LNM); + _bfd_evax_output_dump (abfd, (unsigned char *)"GAS proGIS", 10); + _bfd_evax_output_flush (abfd); + + /* SRC */ + + _bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_SRC); + if (PRIV(filename) != 0) + _bfd_evax_output_dump (abfd, (unsigned char *)PRIV(filename), strlen (PRIV(filename))); + else + _bfd_evax_output_dump (abfd, (unsigned char *)"noname", 6); + _bfd_evax_output_flush (abfd); + + /* TTL */ + + _bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_TTL); + _bfd_evax_output_dump (abfd, (unsigned char *)"TTL", 3); + _bfd_evax_output_flush (abfd); + + /* CPR */ + + _bfd_evax_output_begin (abfd, EOBJ_S_C_EMH, EMH_S_C_CPR); + _bfd_evax_output_dump (abfd, + (unsigned char *)"GNU BFD ported by Klaus Kämpf 1994-1996", + 39); + _bfd_evax_output_flush (abfd); + + return 0; +} + +/*-----------------------------------------------------------------------------*/ + +/* Process EEOM record + return 0 on success, -1 on error */ + +int +_bfd_evax_slurp_eeom (abfd) + bfd *abfd; +{ + unsigned char *evax_rec; + +#if EVAX_DEBUG + evax_debug(2, "EEOM\n"); +#endif + + evax_rec = PRIV(evax_rec); + + PRIV(eeom_data).eeom_l_total_lps = bfd_getl32 (evax_rec + 4); + PRIV(eeom_data).eeom_b_comcod = *(evax_rec + 8); + if (PRIV(eeom_data).eeom_b_comcod > 1) + { + (*_bfd_error_handler) ("Object module NOT error-free !\n"); + bfd_set_error (bfd_error_bad_value); + return -1; + } + PRIV(eeom_data).eeom_has_transfer = false; + if (PRIV(rec_size) > 10) + { + PRIV(eeom_data).eeom_has_transfer = true; + PRIV(eeom_data).eeom_b_tfrflg = *(evax_rec + 9); + PRIV(eeom_data).eeom_l_psindx = bfd_getl32 (evax_rec + 12); + PRIV(eeom_data).eeom_l_tfradr = bfd_getl32 (evax_rec + 16); + + abfd->start_address = PRIV(eeom_data).eeom_l_tfradr; + } + return 0; +} + + +/* Write eom record for bfd abfd */ + +int +_bfd_evax_write_eeom (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (2, "evax_write_eeom(%p)\n", abfd); +#endif + + _bfd_evax_output_begin (abfd,EOBJ_S_C_EEOM, -1); + _bfd_evax_output_long (abfd, (unsigned long)(PRIV(evax_linkage_index) >> 1)); + _bfd_evax_output_byte (abfd, 0); /* completion code */ + _bfd_evax_output_byte (abfd, 0); /* fill byte */ + + if (bfd_get_start_address (abfd) != (bfd_vma)-1) + { + asection *section; + + section = bfd_get_section_by_name (abfd, ".link"); + if (section == 0) + { + bfd_set_error (bfd_error_nonrepresentable_section); + return -1; + } + _bfd_evax_output_short (abfd, 0); + _bfd_evax_output_long (abfd, (unsigned long)(section->index)); + _bfd_evax_output_long (abfd, + (unsigned long) bfd_get_start_address (abfd)); + _bfd_evax_output_long (abfd, 0); + } + + _bfd_evax_output_end (abfd); + return 0; +} diff --git a/gnu/usr.bin/binutils/bfd/evax-etir.c b/gnu/usr.bin/binutils/bfd/evax-etir.c new file mode 100644 index 00000000000..cb186f11e96 --- /dev/null +++ b/gnu/usr.bin/binutils/bfd/evax-etir.c @@ -0,0 +1,1553 @@ +/* evax-etir.c -- BFD back-end for ALPHA EVAX (openVMS/AXP) files. + Copyright 1996 Free Software Foundation, Inc. + ETIR record handling functions + + go and read the openVMS linker manual (esp. appendix B) + if you don't know what's going on here :-) + + Written by Klaus Kämpf (kkaempf@progis.de) + of proGIS Softwareentwicklung, Aachen, Germany + +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. */ + + +/* The following type abbreviations are used: + + cs counted string (ascii string with length byte) + by byte (1 byte) + sh short (2 byte, 16 bit) + lw longword (4 byte, 32 bit) + qw quadword (8 byte, 64 bit) + da data stream */ + +#include +#include + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "libbfd.h" + +#include "evax.h" + +#if 0 +static void location_save + PARAMS ((bfd *abfd, unsigned long index, unsigned long loc, int section)); +static unsigned long location_restore + PARAMS ((bfd *abfd, unsigned long index, int *section)); +#endif /* 0 */ + +static void image_set_ptr PARAMS ((bfd *abfd, int psect, uquad offset)); +static void image_inc_ptr PARAMS ((bfd *abfd, uquad offset)); +static void image_dump PARAMS ((bfd *abfd, unsigned char *ptr, int size, int offset)); +static void image_write_b PARAMS ((bfd *abfd, unsigned int value)); +static void image_write_w PARAMS ((bfd *abfd, unsigned int value)); +static void image_write_l PARAMS ((bfd *abfd, unsigned long value)); +static void image_write_q PARAMS ((bfd *abfd, uquad value)); + +/*-----------------------------------------------------------------------------*/ + +#if 0 + +/* Save location counter at index */ + +static void +location_save (abfd, index, loc, section) + bfd *abfd; + unsigned long index; + unsigned long loc; + int section; +{ + PRIV(location_stack)[index].value = loc; + PRIV(location_stack)[index].psect = section; + + return; +} + +/* Restore location counter from index */ + +static unsigned long +location_restore (abfd, index, section) + bfd *abfd; + unsigned long index; + int *section; +{ + if (section != NULL) + *section = PRIV(location_stack)[index].psect; + return PRIV(location_stack)[index].value; +} + +#endif /* 0 */ + +/* routines to fill sections contents during etir read */ + +/* Initialize image buffer pointer to be filled */ + +static void +image_set_ptr (abfd, psect, offset) + bfd *abfd; + int psect; + uquad offset; +{ +#if EVAX_DEBUG + evax_debug (4, "image_set_ptr(%d=%s, %d)\n", + psect, PRIV(sections)[psect]->name, offset); +#endif + + PRIV(image_ptr) = PRIV(sections)[psect]->contents + offset; + return; +} + + +/* Increment image buffer pointer by offset */ + +static void +image_inc_ptr (abfd, offset) + bfd *abfd; + uquad offset; +{ +#if EVAX_DEBUG + evax_debug (4, "image_inc_ptr(%d)\n", offset); +#endif + + PRIV(image_ptr) += offset; + + return; +} + + +/* Dump multiple bytes to section image */ + +static void +image_dump (abfd, ptr, size, offset) + bfd *abfd; + unsigned char *ptr; + int size; + int offset; +{ +#if EVAX_DEBUG + evax_debug (6, "image_dump from (%p, %d) to (%p)\n", ptr, size, PRIV(image_ptr)); + _bfd_hexdump (7, ptr, size, offset); +#endif + + while (size-- > 0) + *PRIV(image_ptr)++ = *ptr++; + return; +} + + +/* Write byte to section image */ + +static void +image_write_b (abfd, value) + bfd *abfd; + unsigned int value; +{ +#if EVAX_DEBUG + evax_debug (6, "image_write_b(%02x)\n", (int)value); +#endif + + *PRIV(image_ptr)++ = (value & 0xff); + return; +} + + +/* Write 2-byte word to image */ + +static void +image_write_w (abfd, value) + bfd *abfd; + unsigned int value; +{ +#if EVAX_DEBUG + evax_debug (6, "image_write_w(%04x)\n", (int)value); +#endif + + bfd_putl16 (value, PRIV(image_ptr)); + PRIV(image_ptr) += 2; + + return; +} + + +/* Write 4-byte long to image */ + +static void +image_write_l (abfd, value) + bfd *abfd; + unsigned long value; +{ +#if EVAX_DEBUG + evax_debug (6, "image_write_l(%08lx)\n", value); +#endif + + bfd_putl32 (value, PRIV(image_ptr)); + PRIV(image_ptr) += 4; + + return; +} + + +/* Write 4-byte long to image */ + +static void +image_write_q (abfd, value) + bfd *abfd; + uquad value; +{ +#if EVAX_DEBUG + evax_debug (6, "image_write_q(%016lx)\n", value); +#endif + + bfd_putl64 (value, PRIV(image_ptr)); + PRIV(image_ptr) += 8; + + return; +} + + +#define HIGHBIT(op) ((op & 0x80000000L) == 0x80000000L) + +/* etir_sta + + evax stack commands + + handle sta_xxx commands in etir section + ptr points to data area in record + + see table B-8 of the openVMS linker manual */ + +static boolean +etir_sta (abfd, cmd, ptr) + bfd *abfd; + int cmd; + unsigned char *ptr; +{ + + switch (cmd) + { + /* stack */ + + /* stack global + arg: cs symbol name + + stack 32 bit value of symbol (high bits set to 0) */ + + case ETIR_S_C_STA_GBL: + { + char *name; + evax_symbol_entry *entry; + + name = _bfd_evax_save_counted_string ((char *)ptr); + entry = (evax_symbol_entry *) + bfd_hash_lookup (PRIV(evax_symbol_table), name, false, false); + if (entry == (evax_symbol_entry *)NULL) + { +#if EVAX_DEBUG + evax_debug (3, "ETIR_S_C_STA_GBL: no symbol \"%s\"\n", name); +#endif + return false; + } + else + { + _bfd_evax_push (abfd, (uquad)(entry->symbol->value), -1); + } + } + break; + + /* stack longword + arg: lw value + + stack 32 bit value, sign extend to 64 bit */ + + case ETIR_S_C_STA_LW: + _bfd_evax_push (abfd, (uquad)bfd_getl32 (ptr), -1); + break; + + /* stack global + arg: qw value + + stack 64 bit value of symbol */ + + case ETIR_S_C_STA_QW: + _bfd_evax_push (abfd, (uquad)bfd_getl64(ptr), -1); + break; + + /* stack psect base plus quadword offset + arg: lw section index + qw signed quadword offset (low 32 bits) + + stack qw argument and section index + (see ETIR_S_C_STO_OFF, ETIR_S_C_CTL_SETRB) */ + + case ETIR_S_C_STA_PQ: + { + uquad dummy; + int psect; + + psect = bfd_getl32 (ptr); + if (psect >= PRIV(egsd_sec_count)) + { + (*_bfd_error_handler) ("Bad section index in ETIR_S_C_STA_PQ"); + bfd_set_error (bfd_error_bad_value); + return false; + } + dummy = bfd_getl64 (ptr+4); + _bfd_evax_push (abfd, dummy, psect); + } + break; + + /* all not supported */ + + case ETIR_S_C_STA_LI: + case ETIR_S_C_STA_MOD: + case ETIR_S_C_STA_CKARG: + + (*_bfd_error_handler) ("Unsupported STA cmd %d", cmd); + return false; + break; + + default: + (*_bfd_error_handler) ("Reserved STA cmd %d", cmd); + return false; + break; + } + return true; +} + + +/* + etir_sto + + evax store commands + + handle sto_xxx commands in etir section + ptr points to data area in record + + see table B-9 of the openVMS linker manual */ + +static boolean +etir_sto (abfd, cmd, ptr) + bfd *abfd; + int cmd; + unsigned char *ptr; +{ + uquad dummy; + int psect; + + switch (cmd) + { + + /* store byte: pop stack, write byte + arg: - */ + + case ETIR_S_C_STO_B: + dummy = _bfd_evax_pop (abfd, &psect); +#if 0 + if (is_share) /* FIXME */ + (*_bfd_error_handler) ("ETIR_S_C_STO_B: byte fixups not supported"); +#endif + image_write_b (abfd, dummy & 0xff); /* FIXME: check top bits */ + break; + + /* store word: pop stack, write word + arg: - */ + + case ETIR_S_C_STO_W: + dummy = _bfd_evax_pop (abfd, &psect); +#if 0 + if (is_share) /* FIXME */ + (*_bfd_error_handler) ("ETIR_S_C_STO_B: word fixups not supported"); +#endif + image_write_w (abfd, dummy & 0xffff); /* FIXME: check top bits */ + break; + + /* store longword: pop stack, write longword + arg: - */ + + case ETIR_S_C_STO_LW: + dummy = _bfd_evax_pop (abfd, &psect); + dummy += (PRIV(sections)[psect])->vma; + image_write_l (abfd, dummy & 0xffffffff);/* FIXME: check top bits */ +#if 0 /* FIXME */ + if (is_rel) + evax_debug (3, "ETIR_S_C_STO_LW: Relocation !\n"); + if (is_share) + evax_debug (3, "ETIR_S_C_STO_LW: Fix-up share !\n"); +#endif + break; + + /* store quadword: pop stack, write quadword + arg: - */ + + case ETIR_S_C_STO_QW: + dummy = _bfd_evax_pop (abfd, &psect); + dummy += (PRIV(sections)[psect])->vma; + image_write_q(abfd, dummy); /* FIXME: check top bits */ +#if 0 /* FIXME */ + if (is_rel) + evax_debug (3, "ETIR_S_C_STO_LW: Relocation !\n"); + if (is_share) + evax_debug (3, "ETIR_S_C_STO_LW: Fix-up share !\n"); +#endif + break; + + /* store immediate repeated: pop stack for repeat count + arg: lw byte count + da data */ + + case ETIR_S_C_STO_IMMR: + { + unsigned long size; + + size = bfd_getl32 (ptr); + dummy = (unsigned long)_bfd_evax_pop (abfd, NULL); + while (dummy-- > 0L) + image_dump (abfd, ptr+4, size, 0); + } + break; + + /* store global: write symbol value + arg: cs global symbol name */ + + case ETIR_S_C_STO_GBL: + { + evax_symbol_entry *entry; + char *name; + + name = _bfd_evax_save_counted_string ((char *)ptr); + entry = (evax_symbol_entry *)bfd_hash_lookup (PRIV(evax_symbol_table), name, false, false); + if (entry == (evax_symbol_entry *)NULL) + { + (*_bfd_error_handler) ("ETIR_S_C_STO_GBL: no symbol \"%s\"", + name); + return false; + } + else + image_write_q (abfd, (uquad)(entry->symbol->value)); /* FIXME, reloc */ + } + break; + + /* store code address: write address of entry point + arg: cs global symbol name (procedure) */ + + case ETIR_S_C_STO_CA: + { + evax_symbol_entry *entry; + char *name; + + name = _bfd_evax_save_counted_string ((char *)ptr); + entry = (evax_symbol_entry *) bfd_hash_lookup (PRIV(evax_symbol_table), name, false, false); + if (entry == (evax_symbol_entry *)NULL) + { + (*_bfd_error_handler) ("ETIR_S_C_STO_CA: no symbol \"%s\"", + name); + return false; + } + else + image_write_q (abfd, (uquad)(entry->symbol->value)); /* FIXME, reloc */ + } + break; + + /* not supported */ + + case ETIR_S_C_STO_RB: + case ETIR_S_C_STO_AB: + (*_bfd_error_handler) ("ETIR_S_C_STO_RB/AB: Not supported"); + break; + + /* store offset to psect: pop stack, add low 32 bits to base of psect + arg: - */ + + case ETIR_S_C_STO_OFF: + { + uquad q; + int psect; + + q = _bfd_evax_pop (abfd, &psect); + q += (PRIV(sections)[psect])->vma; + image_write_q (abfd, q); + } + break; + + /* store immediate + arg: lw count of bytes + da data */ + + case ETIR_S_C_STO_IMM: + { + int size; + + size = bfd_getl32 (ptr); + image_dump (abfd, ptr+4, size, 0); + } + break; + + /* this code is 'reserved to digital' according to the openVMS linker manual, + however it is generated by the DEC C compiler and defined in the include file. + FIXME, since the following is just a guess + store global longword: store 32bit value of symbol + arg: cs symbol name */ + + case ETIR_S_C_STO_GBL_LW: + { + evax_symbol_entry *entry; + char *name; + + name = _bfd_evax_save_counted_string ((char *)ptr); + entry = (evax_symbol_entry *)bfd_hash_lookup (PRIV(evax_symbol_table), name, false, false); + if (entry == (evax_symbol_entry *)NULL) + { +#if EVAX_DEBUG + evax_debug (3, "ETIR_S_C_STO_GBL_LW: no symbol \"%s\"\n", name); +#endif + return false; + } + else + image_write_l (abfd, (unsigned long)(entry->symbol->value)); /* FIXME, reloc */ + } + break; + + /* not supported */ + + case ETIR_S_C_STO_LP_PSB: + (*_bfd_error_handler) ("ETIR_S_C_STO_LP_PSB: Not supported"); + break; + + /* */ + + case ETIR_S_C_STO_HINT_GBL: + (*_bfd_error_handler) ("ETIR_S_C_STO_HINT_GBL: not implemented"); + break; + + /* */ + + case ETIR_S_C_STO_HINT_PS: + (*_bfd_error_handler) ("ETIR_S_C_STO_HINT_PS: not implemented"); + break; + + default: + (*_bfd_error_handler) ("Reserved STO cmd %d", cmd); + break; + } + + return true; +} + +/* stack operator commands + all 32 bit signed arithmetic + all word just like a stack calculator + arguments are popped from stack, results are pushed on stack + + see table B-10 of the openVMS linker manual */ + +static boolean +etir_opr (abfd, cmd, ptr) + bfd *abfd; + int cmd; + unsigned char *ptr; +{ + long op1, op2; + + switch (cmd) + { + /* operation */ + + /* no-op */ + + case ETIR_S_C_OPR_NOP: + break; + + /* add */ + + case ETIR_S_C_OPR_ADD: + op1 = (long)_bfd_evax_pop (abfd, NULL); + op2 = (long)_bfd_evax_pop (abfd, NULL); + _bfd_evax_push (abfd, (uquad)(op1 + op2), -1); + break; + + /* subtract */ + + case ETIR_S_C_OPR_SUB: + op1 = (long)_bfd_evax_pop (abfd, NULL); + op2 = (long)_bfd_evax_pop (abfd, NULL); + _bfd_evax_push (abfd, (uquad)(op2 - op1), -1); + break; + + /* multiply */ + + case ETIR_S_C_OPR_MUL: + op1 = (long)_bfd_evax_pop (abfd, NULL); + op2 = (long)_bfd_evax_pop (abfd, NULL); + _bfd_evax_push (abfd, (uquad)(op1 * op2), -1); + break; + + /* divide */ + + case ETIR_S_C_OPR_DIV: + op1 = (long)_bfd_evax_pop (abfd, NULL); + op2 = (long)_bfd_evax_pop (abfd, NULL); + if (op2 == 0) + _bfd_evax_push (abfd, (uquad)0L, -1); + else + _bfd_evax_push (abfd, (uquad)(op2 / op1), -1); + break; + + /* logical and */ + + case ETIR_S_C_OPR_AND: + op1 = (long)_bfd_evax_pop (abfd, NULL); + op2 = (long)_bfd_evax_pop (abfd, NULL); + _bfd_evax_push (abfd, (uquad)(op1 & op2), -1); + break; + + /* logical inclusive or */ + + case ETIR_S_C_OPR_IOR: + op1 = (long)_bfd_evax_pop (abfd, NULL); + op2 = (long)_bfd_evax_pop (abfd, NULL); + _bfd_evax_push (abfd, (uquad)(op1 | op2), -1); + break; + + /* logical exclusive or */ + + case ETIR_S_C_OPR_EOR: + op1 = (long)_bfd_evax_pop (abfd, NULL); + op2 = (long)_bfd_evax_pop (abfd, NULL); + _bfd_evax_push (abfd, (uquad)(op1 ^ op2), -1); + break; + + /* negate */ + + case ETIR_S_C_OPR_NEG: + op1 = (long)_bfd_evax_pop (abfd, NULL); + _bfd_evax_push (abfd, (uquad)(-op1), -1); + break; + + /* complement */ + + case ETIR_S_C_OPR_COM: + op1 = (long)_bfd_evax_pop (abfd, NULL); + _bfd_evax_push (abfd, (uquad)(op1 ^ -1L), -1); + break; + + /* insert field */ + + case ETIR_S_C_OPR_INSV: + (void)_bfd_evax_pop (abfd, NULL); + (*_bfd_error_handler) ("ETIR_S_C_OPR_INSV: Not supported"); + break; + + /* arithmetic shift */ + + case ETIR_S_C_OPR_ASH: + op1 = (long)_bfd_evax_pop (abfd, NULL); + op2 = (long)_bfd_evax_pop (abfd, NULL); + if (op2 < 0) /* shift right */ + op1 >>= -op2; + else /* shift left */ + op1 <<= op2; + _bfd_evax_push (abfd, (uquad)op1, -1); + break; + + /* unsigned shift */ + + case ETIR_S_C_OPR_USH: + (*_bfd_error_handler) ("ETIR_S_C_OPR_USH: Not supported"); + break; + + /* rotate */ + + case ETIR_S_C_OPR_ROT: + (*_bfd_error_handler) ("ETIR_S_C_OPR_ROT: Not supported"); + break; + + /* select */ + + case ETIR_S_C_OPR_SEL: + if ((long)_bfd_evax_pop (abfd, NULL) & 0x01L) + (void)_bfd_evax_pop (abfd, NULL); + else + { + op1 = (long)_bfd_evax_pop (abfd, NULL); + (void)_bfd_evax_pop (abfd, NULL); + _bfd_evax_push (abfd, (uquad)op1, -1); + } + break; + + /* redefine symbol to current location */ + + case ETIR_S_C_OPR_REDEF: + (*_bfd_error_handler) ("ETIR_S_C_OPR_REDEF: Not supported"); + break; + + /* define a literal */ + + case ETIR_S_C_OPR_DFLIT: + (*_bfd_error_handler) ("ETIR_S_C_OPR_DFLIT: Not supported"); + break; + + default: + (*_bfd_error_handler) ("Reserved OPR cmd %d", cmd); + break; + } + + return true; +} + + +/* control commands + + see table B-11 of the openVMS linker manual */ + +static boolean +etir_ctl (abfd, cmd, ptr) + bfd *abfd; + int cmd; + unsigned char *ptr; +{ + uquad dummy; + int psect; + + switch (cmd) + { + /* set relocation base: pop stack, set image location counter + arg: - */ + + case ETIR_S_C_CTL_SETRB: + dummy = _bfd_evax_pop (abfd, &psect); + image_set_ptr (abfd, psect, dummy); + break; + + /* augment relocation base: increment image location counter by offset + arg: lw offset value */ + + case ETIR_S_C_CTL_AUGRB: + dummy = bfd_getl32 (ptr); + image_inc_ptr (abfd, dummy); + break; + + /* define location: pop index, save location counter under index + arg: - */ + + case ETIR_S_C_CTL_DFLOC: + dummy = _bfd_evax_pop (abfd, NULL); + /* FIXME */ + break; + + /* set location: pop index, restore location counter from index + arg: - */ + + case ETIR_S_C_CTL_STLOC: + dummy = _bfd_evax_pop (abfd, &psect); + /* FIXME */ + break; + + /* stack defined location: pop index, push location counter from index + arg: - */ + + case ETIR_S_C_CTL_STKDL: + dummy = _bfd_evax_pop (abfd, &psect); + /* FIXME */ + break; + + default: + (*_bfd_error_handler) ("Reserved CTL cmd %d", cmd); + break; + } + return true; +} + + +/* store conditional commands + + see table B-12 and B-13 of the openVMS linker manual */ + +static boolean +etir_stc (abfd, cmd, ptr) + bfd *abfd; + int cmd; + unsigned char *ptr; +{ + + switch (cmd) + { + /* 200 Store-conditional Linkage Pair + arg: */ + + case ETIR_S_C_STC_LP: + (*_bfd_error_handler) ("ETIR_S_C_STC_LP: not supported"); + break; + + /* 201 Store-conditional Linkage Pair with Procedure Signature + arg: lw linkage index + cs procedure name + by signature length + da signature */ + + case ETIR_S_C_STC_LP_PSB: + image_inc_ptr (abfd, 16); /* skip entry,procval */ + break; + + /* 202 Store-conditional Address at global address + arg: lw linkage index + cs global name */ + + case ETIR_S_C_STC_GBL: + (*_bfd_error_handler) ("ETIR_S_C_STC_GBL: not supported"); + break; + + /* 203 Store-conditional Code Address at global address + arg: lw linkage index + cs procedure name */ + + case ETIR_S_C_STC_GCA: + (*_bfd_error_handler) ("ETIR_S_C_STC_GCA: not supported"); + break; + + /* 204 Store-conditional Address at psect + offset + arg: lw linkage index + lw psect index + qw offset */ + + case ETIR_S_C_STC_PS: + (*_bfd_error_handler) ("ETIR_S_C_STC_PS: not supported"); + break; + + /* 205 Store-conditional NOP at address of global + arg: */ + + case ETIR_S_C_STC_NOP_GBL: + + /* 206 Store-conditional NOP at pect + offset + arg: */ + + case ETIR_S_C_STC_NOP_PS: + + /* 207 Store-conditional BSR at global address + arg: */ + + case ETIR_S_C_STC_BSR_GBL: + + /* 208 Store-conditional BSR at pect + offset + arg: */ + + case ETIR_S_C_STC_BSR_PS: + + /* 209 Store-conditional LDA at global address + arg: */ + + case ETIR_S_C_STC_LDA_GBL: + + /* 210 Store-conditional LDA at psect + offset + arg: */ + + case ETIR_S_C_STC_LDA_PS: + + /* 211 Store-conditional BSR or Hint at global address + arg: */ + + case ETIR_S_C_STC_BOH_GBL: + + /* 212 Store-conditional BSR or Hint at pect + offset + arg: */ + + case ETIR_S_C_STC_BOH_PS: + + /* 213 Store-conditional NOP,BSR or HINT at global address + arg: */ + + case ETIR_S_C_STC_NBH_GBL: + + /* 214 Store-conditional NOP,BSR or HINT at psect + offset + arg: */ + + case ETIR_S_C_STC_NBH_PS: +/* FIXME (*_bfd_error_handler) ("ETIR_S_C_STC_xx: (%d) not supported", cmd); */ + break; + + default: +#if EVAX_DEBUG + evax_debug (3, "Reserved STC cmd %d", cmd); +#endif + break; + } + return true; +} + + +/* handle command from ETIR section */ + +static boolean +tir_cmd (abfd, cmd, ptr) + bfd *abfd; + int cmd; + unsigned char *ptr; +{ + static struct { + int mincod; + int maxcod; + boolean (*explain) PARAMS((bfd *, int, unsigned char *)); + } tir_table[] = { + { ETIR_S_C_MINSTACOD, ETIR_S_C_MAXSTACOD, etir_sta }, + { ETIR_S_C_MINSTOCOD, ETIR_S_C_MAXSTOCOD, etir_sto }, + { ETIR_S_C_MINOPRCOD, ETIR_S_C_MAXOPRCOD, etir_opr }, + { ETIR_S_C_MINCTLCOD, ETIR_S_C_MAXCTLCOD, etir_ctl }, + { ETIR_S_C_MINSTCCOD, ETIR_S_C_MAXSTCCOD, etir_stc }, + { -1, -1, NULL } + }; + + int i = 0; + boolean res = true; + + while (tir_table[i].mincod >= 0) + { + if ( (tir_table[i].mincod <= cmd) + && (cmd <= tir_table[i].maxcod)) + { + res = tir_table[i].explain (abfd, cmd, ptr); + break; + } + i++; + } + + return res; +} + + +/* Text Information and Relocation Records (OBJ$C_TIR) + handle etir record */ + +static boolean +analyze_etir (abfd, ptr, length) + bfd *abfd; + unsigned char *ptr; + unsigned int length; +{ + int cmd; + unsigned char *maxptr; + boolean res = true; + + maxptr = ptr + length; + + while (ptr < maxptr) + { + cmd = bfd_getl16 (ptr); + length = bfd_getl16 (ptr + 2); + res = tir_cmd (abfd, cmd, ptr+4); + if (!res) + break; + ptr += length; + } + return res; +} + + +/* process ETIR record + + return 0 on success, -1 on error */ + +int +_bfd_evax_slurp_etir (abfd) + bfd *abfd; +{ + +#if EVAX_DEBUG + evax_debug (2, "ETIR\n"); +#endif + + PRIV(evax_rec) += 4; /* skip type, size */ + PRIV(rec_size) -= 4; + if (analyze_etir (abfd, PRIV(evax_rec), PRIV(rec_size))) + return 0; + + return -1; +} + + +/* process EDBG record + return 0 on success, -1 on error + + not implemented yet */ + +int +_bfd_evax_slurp_edbg (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (2, "EDBG\n"); +#endif + + abfd->flags |= (HAS_DEBUG | HAS_LINENO); + return 0; +} + + +/* process ETBT record + return 0 on success, -1 on error + + not implemented yet */ + +int +_bfd_evax_slurp_etbt (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (2, "ETBT\n"); +#endif + + return 0; +} + +/*----------------------------------------------------------------------*/ +/* */ +/* WRITE ETIR SECTION */ +/* */ +/* this is still under construction and therefore not documented */ +/* */ +/*----------------------------------------------------------------------*/ + +static void start_etir_record PARAMS ((bfd *abfd, int index, uquad offset, boolean justoffset)); +static void sto_imm PARAMS ((bfd *abfd, evax_section *sptr, bfd_vma vaddr, int index)); +static void end_etir_record PARAMS ((bfd *abfd)); + +static void +sto_imm (abfd, sptr, vaddr, index) + bfd *abfd; + evax_section *sptr; + bfd_vma vaddr; + int index; +{ + int size; + int ssize; + unsigned char *cptr; + +#if EVAX_DEBUG + evax_debug (8, "sto_imm %d bytes\n", sptr->size); + _bfd_hexdump (9, sptr->contents, (int)sptr->size, (int)vaddr); +#endif + + ssize = sptr->size; + cptr = sptr->contents; + + while (ssize > 0) + { + + size = ssize; /* try all the rest */ + + if (_bfd_evax_output_check (abfd, size) < 0) + { /* doesn't fit, split ! */ + end_etir_record (abfd); + start_etir_record (abfd, index, vaddr, false); + size = _bfd_evax_output_check (abfd, 0); /* get max size */ + if (size > ssize) /* more than what's left ? */ + size = ssize; + } + + _bfd_evax_output_begin (abfd, ETIR_S_C_STO_IMM, -1); + _bfd_evax_output_long (abfd, (unsigned long)(size)); + _bfd_evax_output_dump (abfd, cptr, size); + _bfd_evax_output_flush (abfd); + +#if EVAX_DEBUG + evax_debug (10, "dumped %d bytes\n", size); + _bfd_hexdump (10, cptr, (int)size, (int)vaddr); +#endif + + vaddr += size; + ssize -= size; + cptr += size; + } + + return; +} + +/*-------------------------------------------------------------------*/ + +/* start ETIR record for section #index at virtual addr offset. */ + +static void +start_etir_record (abfd, index, offset, justoffset) + bfd *abfd; + int index; + uquad offset; + boolean justoffset; +{ + if (!justoffset) + { + _bfd_evax_output_begin (abfd, EOBJ_S_C_ETIR, -1); /* one ETIR per section */ + _bfd_evax_output_push (abfd); + } + + _bfd_evax_output_begin (abfd, ETIR_S_C_STA_PQ, -1); /* push start offset */ + _bfd_evax_output_long (abfd, (unsigned long)index); + _bfd_evax_output_quad (abfd, (uquad)offset); + _bfd_evax_output_flush (abfd); + + _bfd_evax_output_begin (abfd, ETIR_S_C_CTL_SETRB, -1); /* start = pop() */ + _bfd_evax_output_flush (abfd); + + return; +} + + +/* end etir record */ +static void +end_etir_record (abfd) + bfd *abfd; +{ + _bfd_evax_output_pop (abfd); + _bfd_evax_output_end (abfd); +} + +/* write section contents for bfd abfd */ + +int +_bfd_evax_write_etir (abfd) + bfd *abfd; +{ + asection *section; + evax_section *sptr; + int nextoffset; + char uname[200]; + char *nptr, *uptr; + +#if EVAX_DEBUG + evax_debug (2, "evax_write_etir(%p)\n", abfd); +#endif + + _bfd_evax_output_alignment (abfd, 4); + + nextoffset = 0; + PRIV(evax_linkage_index) = 1; + + /* dump all other sections */ + + section = abfd->sections; + + while (section != NULL) + { + +#if EVAX_DEBUG + evax_debug (4, "writing %d. section '%s' (%d bytes)\n", section->index, section->name, (int)(section->_raw_size)); +#endif + + if (section->flags & SEC_RELOC) + { + int i; + + if ((i = section->reloc_count) <= 0) + { + (*_bfd_error_handler) ("SEC_RELOC with no relocs in section %s", + section->name); + } +#if EVAX_DEBUG + else + { + arelent **rptr; + evax_debug (4, "%d relocations:\n", i); + rptr = section->orelocation; + while (i-- > 0) + { + evax_debug (4, "sym %s in sec %s, value %08lx, addr %08lx, off %08lx, len %d: %s\n", + (*(*rptr)->sym_ptr_ptr)->name, + (*(*rptr)->sym_ptr_ptr)->section->name, + (long)(*(*rptr)->sym_ptr_ptr)->value, + (*rptr)->address, (*rptr)->addend, + bfd_get_reloc_size((*rptr)->howto), + (*rptr)->howto->name); + rptr++; + } + } +#endif + } + + if (section->flags & SEC_HAS_CONTENTS) + { + bfd_vma vaddr; /* virtual addr in section */ + + sptr = _bfd_get_evax_section (abfd, section->index); + if (sptr == NULL) + { + bfd_set_error (bfd_error_no_contents); + return -1; + } + + vaddr = (bfd_vma)(sptr->offset); + + start_etir_record (abfd, section->index, (uquad) sptr->offset, + false); + + while (sptr != NULL) /* one STA_PQ, CTL_SETRB per evax_section */ + { + + if (section->flags & SEC_RELOC) /* check for relocs */ + { + arelent **rptr = section->orelocation; + int i = section->reloc_count; + for (;;) + { + bfd_size_type addr = (*rptr)->address; + int len = bfd_get_reloc_size ((*rptr)->howto); + if (sptr->offset < addr) /* sptr starts before reloc */ + { + int before = addr - sptr->offset; + if (sptr->size <= before) /* complete before */ + { + sto_imm (abfd, sptr, vaddr, section->index); + vaddr += sptr->size; + break; + } + else /* partly before */ + { + int after = sptr->size - before; + sptr->size = before; + sto_imm (abfd, sptr, vaddr, section->index); + vaddr += sptr->size; + sptr->contents += before; + sptr->offset += before; + sptr->size = after; + } + } + else if (sptr->offset == addr) /* sptr starts at reloc */ + { + asymbol *sym = *(*rptr)->sym_ptr_ptr; + asection *sec = sym->section; + + switch ((*rptr)->howto->type) + { + case ALPHA_R_IGNORE: + break; + + case ALPHA_R_REFLONG: + { + if (bfd_is_und_section (sym->section)) + { + if (_bfd_evax_output_check (abfd, + strlen((char *)sym->name)) + < 0) + { + end_etir_record (abfd); + start_etir_record (abfd, + section->index, + vaddr, false); + } + _bfd_evax_output_begin (abfd, + ETIR_S_C_STO_GBL_LW, + -1); + uptr = uname; + nptr = (char *)sym->name; + while (*nptr) + { + if (islower (*nptr)) + *uptr = toupper (*nptr); + else + *uptr = *nptr; + nptr++; + uptr++; + } + *uptr = 0; + _bfd_evax_output_counted (abfd, uname); + _bfd_evax_output_flush (abfd); + } + else if (bfd_is_abs_section (sym->section)) + { + if (_bfd_evax_output_check (abfd, 16) < 0) + { + end_etir_record (abfd); + start_etir_record (abfd, + section->index, + vaddr, false); + } + _bfd_evax_output_begin (abfd, + ETIR_S_C_STA_LW, + -1); + _bfd_evax_output_quad (abfd, + (uquad)sym->value); + _bfd_evax_output_flush (abfd); + _bfd_evax_output_begin (abfd, + ETIR_S_C_STO_LW, + -1); + _bfd_evax_output_flush (abfd); + } + else + { + if (_bfd_evax_output_check (abfd, 32) < 0) + { + end_etir_record (abfd); + start_etir_record (abfd, + section->index, + vaddr, false); + } + _bfd_evax_output_begin (abfd, + ETIR_S_C_STA_PQ, + -1); + _bfd_evax_output_long (abfd, + (unsigned long)(sec->index)); + _bfd_evax_output_quad (abfd, + ((uquad)(*rptr)->addend + + (uquad)sym->value)); + _bfd_evax_output_flush (abfd); + _bfd_evax_output_begin (abfd, + ETIR_S_C_STO_LW, + -1); + _bfd_evax_output_flush (abfd); + } + } + break; + + case ALPHA_R_REFQUAD: + { + if (bfd_is_und_section (sym->section)) + { + if (_bfd_evax_output_check (abfd, + strlen((char *)sym->name)) + < 0) + { + end_etir_record (abfd); + start_etir_record (abfd, + section->index, + vaddr, false); + } + _bfd_evax_output_begin (abfd, + ETIR_S_C_STO_GBL, + -1); + uptr = uname; + nptr = (char *)sym->name; + while (*nptr) + { + if (islower (*nptr)) + *uptr = toupper (*nptr); + else + *uptr = *nptr; + nptr++; + uptr++; + } + *uptr = 0; + _bfd_evax_output_counted (abfd, uname); + _bfd_evax_output_flush (abfd); + } + else if (bfd_is_abs_section (sym->section)) + { + if (_bfd_evax_output_check (abfd, 16) < 0) + { + end_etir_record (abfd); + start_etir_record (abfd, + section->index, + vaddr, false); + } + _bfd_evax_output_begin (abfd, + ETIR_S_C_STA_QW, + -1); + _bfd_evax_output_quad (abfd, + (uquad)sym->value); + _bfd_evax_output_flush (abfd); + _bfd_evax_output_begin (abfd, + ETIR_S_C_STO_QW, + -1); + _bfd_evax_output_flush (abfd); + } + else + { + if (_bfd_evax_output_check (abfd, 32) < 0) + { + end_etir_record (abfd); + start_etir_record (abfd, + section->index, + vaddr, false); + } + _bfd_evax_output_begin (abfd, + ETIR_S_C_STA_PQ, + -1); + _bfd_evax_output_long (abfd, + (unsigned long)(sec->index)); + _bfd_evax_output_quad (abfd, + ((uquad)(*rptr)->addend + + (uquad)sym->value)); + _bfd_evax_output_flush (abfd); + _bfd_evax_output_begin (abfd, + ETIR_S_C_STO_OFF, + -1); + _bfd_evax_output_flush (abfd); + } + } + break; + + case ALPHA_R_HINT: + { + int hint_size; + + hint_size = sptr->size; + sptr->size = len; + sto_imm (abfd, sptr, vaddr, section->index); + sptr->size = hint_size; +#if 0 + evax_output_begin(abfd, ETIR_S_C_STO_HINT_GBL, -1); + evax_output_long(abfd, (unsigned long)(sec->index)); + evax_output_quad(abfd, (uquad)addr); + uptr = uname; + nptr = (char *)(*(*rptr)->sym_ptr_ptr)->name; + while (*nptr) + { + if (islower (*nptr)) + *uptr = toupper (*nptr); + else + *uptr = *nptr; + nptr++; + uptr++; + } + *uptr = 0; + + evax_output_counted(abfd, uname); + evax_output_flush(abfd); +#endif + } + break; +#if 0 + case ALPHA_R_BRADDR: + break; + case ALPHA_R_SREL16: + break; + case ALPHA_R_SREL32: + break; + case ALPHA_R_SREL64: + break; + case ALPHA_R_OP_PUSH: + break; + case ALPHA_R_OP_STORE: + break; + case ALPHA_R_OP_PSUB: + break; + case ALPHA_R_OP_PRSHIFT: + break; +#endif + case ALPHA_R_LINKAGE: + { + if (_bfd_evax_output_check (abfd, 64) < 0) + { + end_etir_record (abfd); + start_etir_record (abfd, section->index, + vaddr, false); + } + _bfd_evax_output_begin (abfd, + ETIR_S_C_STC_LP_PSB, + -1); + _bfd_evax_output_long (abfd, + (unsigned long)PRIV(evax_linkage_index)); + PRIV(evax_linkage_index) += 2; + uptr = uname; + nptr = (char *)(*(*rptr)->sym_ptr_ptr)->name; + while (*nptr) + { + if (islower (*nptr)) + *uptr = toupper (*nptr); + else + *uptr = *nptr; + nptr++; + uptr++; + } + *uptr = 0; + _bfd_evax_output_counted (abfd, uname); + _bfd_evax_output_byte (abfd, 0); + _bfd_evax_output_flush (abfd); + } + break; + + default: + (*_bfd_error_handler) ("Unhandled relocation %s", + (*rptr)->howto->name); + break; + } + + vaddr += len; + + if (len == sptr->size) + { + break; + } + else + { + sptr->contents += len; + sptr->offset += len; + sptr->size -= len; + i--; + rptr++; + } + } + else /* sptr starts after reloc */ + { + i--; /* check next reloc */ + rptr++; + } + + if (i==0) /* all reloc checked */ + { + if (sptr->size > 0) + { + sto_imm (abfd, sptr, vaddr, section->index); /* dump rest */ + vaddr += sptr->size; + } + break; + } + } /* for (;;) */ + } /* if SEC_RELOC */ + else /* no relocs, just dump */ + { + sto_imm (abfd, sptr, vaddr, section->index); + vaddr += sptr->size; + } + + sptr = sptr->next; + + } /* while (sptr != 0) */ + + end_etir_record (abfd); + + } /* has_contents */ + + section = section->next; + } + + _bfd_evax_output_alignment(abfd, 2); + return 0; +} + + +/* write traceback data for bfd abfd */ + +int +_bfd_evax_write_etbt (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (2, "evax_write_etbt(%p)\n", abfd); +#endif + + return 0; +} + + +/* write debug info for bfd abfd */ + +int +_bfd_evax_write_edbg (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (2, "evax_write_edbg(%p)\n", abfd); +#endif + + return 0; +} diff --git a/gnu/usr.bin/binutils/bfd/evax-misc.c b/gnu/usr.bin/binutils/bfd/evax-misc.c new file mode 100644 index 00000000000..3da89997805 --- /dev/null +++ b/gnu/usr.bin/binutils/bfd/evax-misc.c @@ -0,0 +1,1049 @@ +/* evax-misc.c -- Miscellaneous functions for ALPHA EVAX (openVMS/AXP) files. + Copyright 1996 Free Software Foundation, Inc. + Written by Klaus Kämpf (kkaempf@progis.de) + of proGIS Softwareentwicklung, Aachen, Germany + +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. */ + + +#if __STDC__ +#include +#endif +#include + +#include "bfd.h" +#include "sysdep.h" +#include "bfdlink.h" +#include "libbfd.h" + +#include "evax.h" + +/*-----------------------------------------------------------------------------*/ +#if EVAX_DEBUG +/* debug functions */ + +/* debug function for all evax extensions + evaluates environment variable EVAX_DEBUG for a + numerical value on the first call + all error levels below this value are printed + + levels: + 1 toplevel bfd calls (functions from the bfd vector) + 2 functions called by bfd calls + ... + 9 almost everything + + level is also identation level. Indentation is performed + if level > 0 + */ + +#if __STDC__ +void +_bfd_evax_debug (int level, char *format, ...) +{ + static int min_level = -1; + static FILE *output = NULL; + char *eptr; + va_list args; + int abslvl = (level > 0)?level:-level; + + if (min_level == -1) + { + if ((eptr = getenv("EVAX_DEBUG")) != NULL) + { + min_level = atoi(eptr); + output = stderr; + } + else + min_level = 0; + } + if (output == NULL) + return; + if (abslvl > min_level) + return; + + while(--level>0) + fprintf(output, " "); + va_start(args, format); + vfprintf(output, format, args); + fflush(output); + va_end(args); + + return; +} + +#else /* not __STDC__ */ + +void +_bfd_evax_debug (level, format, a1, a2, a3, a4, a5, a6) + int level; + char *format; + long a1; long a2; long a3; + long a4; long a5; long a6; +{ + static int min_level = -1; + static FILE *output = NULL; + char *eptr; + + if (min_level == -1) + { + if ((eptr = getenv("EVAX_DEBUG")) != NULL) + { + min_level = atoi(eptr); + output = stderr; + } + else + min_level = 0; + } + if (output == NULL) + return; + if (level > min_level) + return; + + while(--level>0) + fprintf(output, " "); + fprintf(output, format, a1, a2, a3, a4, a5, a6); + fflush(output); + + return; +} +#endif /* __STDC__ */ + + +/* a debug function + hex dump 'size' bytes starting at 'ptr' */ + +void +_bfd_hexdump (level, ptr, size, offset) + int level; + unsigned char *ptr; + int size; + int offset; +{ + unsigned char *lptr = ptr; + int count = 0; + long start = offset; + + while (size-- > 0) + { + if ((count%16) == 0) + evax_debug (level, "%08lx:", start); + evax_debug (-level, " %02x", *ptr++); + count++; + start++; + if (size == 0) + { + while ((count%16) != 0) + { + evax_debug (-level, " "); + count++; + } + } + if ((count%16) == 0) + { + evax_debug (-level, " "); + while (lptr < ptr) + { + evax_debug (-level, "%c", (*lptr < 32)?'.':*lptr); + lptr++; + } + evax_debug (-level, "\n"); + } + } + if ((count%16) != 0) + evax_debug (-level, "\n"); + + return; +} +#endif + + +/* hash functions + + These are needed when reading an object file. */ + +/* allocate new evax_hash_entry + keep the symbol name and a pointer to the bfd symbol in the table */ + +struct bfd_hash_entry * +_bfd_evax_hash_newfunc (entry, table, string) + struct bfd_hash_entry *entry; + struct bfd_hash_table *table; + const char *string; +{ + evax_symbol_entry *ret = (evax_symbol_entry *)entry; + +#if EVAX_DEBUG + evax_debug (5, "_bfd_evax_hash_newfunc(%p, %p, %s)\n", entry, table, string); +#endif + + if (ret == (evax_symbol_entry *)NULL) + ret = ((evax_symbol_entry *) bfd_hash_allocate (table, sizeof (evax_symbol_entry))); + if (ret == (evax_symbol_entry *)NULL) + { + bfd_set_error (bfd_error_no_memory); + return (struct bfd_hash_entry *)NULL; + } + ret = (evax_symbol_entry *) bfd_hash_newfunc ((struct bfd_hash_entry *)ret, table, string); + + ret->symbol = (asymbol *)NULL; + + return (struct bfd_hash_entry *)ret; +} + + +/* object file input functions */ + +/* Return type and length from record header (buf) */ + +void +_bfd_evax_get_header_values (abfd, buf, type, length) + bfd *abfd; + unsigned char *buf; + int *type; + int *length; +{ + if (type != 0) + *type = bfd_getl16 (buf); + buf += 2; + if (length != 0) + *length = bfd_getl16 (buf); + + return; +} + + +/* Get next record from object file to evax_buf + set PRIV(buf_size) and return it + + this is a little tricky since it should be portable. + + the openVMS/AXP object file has 'variable length' which means that + read() returns data in chunks of (hopefully) correct and expected + size. The linker (and other tools on vms) depend on that. Unix doesn't + know about 'formatted' files, so reading and writing such an object + file in a unix environment is not trivial. + + With the tool 'file' (available on all vms ftp sites), one + can view and change the attributes of a file. Changing from + 'variable length' to 'fixed length, 512 bytes' reveals the + record length at the first 2 bytes of every record. The same + happens during the transfer of object files from vms to unix, + at least with ucx, dec's implementation of tcp/ip. + + The EVAX format repeats the length at bytes 2 & 3 of every record. + + On the first call (file_format == FF_UNKNOWN) we check if + the first and the third byte pair (!) of the record match. + If they do it's an object file in an unix environment or with + wrong attributes (FF_FOREIGN), else we should be in a vms + environment where read() returns the record size (FF_NATIVE). + + reading is always done in 2 steps. + first just the record header is read and the length extracted + by get_header_values + then the read buffer is adjusted and the remaining bytes are + read in. + + all file i/o is always done on even file positions */ + +int +_bfd_evax_get_record (abfd) + bfd *abfd; +{ + int test_len, test_start, remaining; + unsigned char *evax_buf; + +#if EVAX_DEBUG + evax_debug (8, "_bfd_evax_get_record\n"); +#endif + + /* minimum is 6 bytes + (2 bytes length, 2 bytes record id, 2 bytes length repeated) */ + + if (PRIV(buf_size) == 0) + { + PRIV(evax_buf) = (unsigned char *) malloc (6); +#if EVAX_DEBUG + evax_debug (9, "PRIV(evax_buf) %p\n", PRIV(evax_buf)); +#endif + } + + evax_buf = PRIV(evax_buf); + + if (evax_buf == 0) + { +#if EVAX_DEBUG + evax_debug (9, "can't alloc evax_buf\n"); +#endif + bfd_set_error (bfd_error_no_memory); + return -1; + } + + switch (PRIV(file_format)) + { + case FF_UNKNOWN: + case FF_FOREIGN: + test_len = 6; /* probe 6 bytes */ + test_start = 2; /* where the record starts */ + break; + + case FF_NATIVE: + test_len = 4; + test_start = 0; + break; + } + + /* skip odd alignment byte */ +#if 0 + if (PRIV(file_format) == FF_FOREIGN) + { +#endif + if (bfd_tell (abfd) & 1) + { +#if EVAX_DEBUG + evax_debug (10, "skip odd\n"); +#endif + if (bfd_read (PRIV(evax_buf), 1, 1, abfd) != 1) + { +#if EVAX_DEBUG + evax_debug (9, "skip odd failed\n"); +#endif + bfd_set_error (bfd_error_file_truncated); + return 0; + } + } +#if 0 + } +#endif + /* read the record header */ + + if (bfd_read (PRIV(evax_buf), 1, test_len, abfd) != test_len) + { +#if EVAX_DEBUG + evax_debug (9, "can't bfd_read test %d bytes\n", test_len); +#endif + bfd_set_error (bfd_error_file_truncated); + return 0; + } + + /* check file format on first call */ + + if (PRIV(file_format) == FF_UNKNOWN) + { /* record length repeats ? */ + if ( (evax_buf[0] == evax_buf[4]) + && (evax_buf[1] == evax_buf[5])) + { + PRIV(file_format) = FF_FOREIGN; /* Y: foreign environment */ + test_start = 2; + } + else + { + PRIV(file_format) = FF_NATIVE; /* N: native environment */ + test_start = 0; + } +#if EVAX_DEBUG + evax_debug (10, "File format is %s\n", (PRIV(file_format) == FF_FOREIGN)?"foreign":"native"); +#endif + } + + /* extract evax record length */ + + _bfd_evax_get_header_values (abfd, evax_buf+test_start, NULL, + &PRIV(rec_length)); + + if (PRIV(rec_length) <= 0) + { + bfd_set_error (bfd_error_file_truncated); + return 0; + } + + /* that's what the linker manual says */ + + if (PRIV(rec_length) > EOBJ_S_C_MAXRECSIZ) + { + bfd_set_error (bfd_error_file_truncated); + return 0; + } + + /* adjust the buffer */ + + if (PRIV(rec_length) > PRIV(buf_size)) + { + PRIV(evax_buf) = (unsigned char *) realloc (evax_buf, PRIV(rec_length)); +#if EVAX_DEBUG + evax_debug (3, "adjusted the buffer (%p) from %d to %d\n", PRIV(evax_buf), PRIV(buf_size), PRIV(rec_length)); +#endif + evax_buf = PRIV(evax_buf); + if (evax_buf == 0) + { +#if EVAX_DEBUG + evax_debug (9, "can't realloc evax_buf to %d bytes\n", PRIV(rec_length)); +#endif + bfd_set_error (bfd_error_no_memory); + return -1; + } + PRIV(buf_size) = PRIV(rec_length); + } + + /* read the remaining record */ + + remaining = PRIV(rec_length) - test_len + test_start; + + if (bfd_read (evax_buf + test_len, 1, remaining, abfd) != remaining) + { +#if EVAX_DEBUG + evax_debug (9, "can't bfd_read remaining %d bytes\n", remaining); +#endif + bfd_set_error (bfd_error_file_truncated); + return 0; + } + + PRIV(evax_rec) = evax_buf + test_start; + + return PRIV(rec_length); +} + + +/* get next EVAX record from file + update evax_rec and rec_length to new (remaining) values */ + +int +_bfd_evax_next_record (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (8, "_bfd_evax_next_record (len %d, size %d)\n", + PRIV(rec_length), PRIV(rec_size)); +#endif + + if (PRIV(rec_length) > 0) + { + PRIV(evax_rec) += PRIV(rec_size); + } + else + { + if (_bfd_evax_get_record (abfd) <= 0) + return -1; + } + _bfd_evax_get_header_values (abfd, PRIV(evax_rec), &PRIV(rec_type), + &PRIV(rec_size)); + PRIV(rec_length) -= PRIV(rec_size); + +#if EVAX_DEBUG + evax_debug (8, "_bfd_evax_next_record: rec %p, size %d, length %d, type %d\n", + PRIV(evax_rec), PRIV(rec_size), PRIV(rec_length), + PRIV(rec_type)); +#endif + + return PRIV(rec_type); +} + + + +/* Copy sized string (string with fixed length) to new allocated area + size is string length (size of record) */ + +char * +_bfd_evax_save_sized_string (str, size) + char *str; + int size; +{ + char *newstr = bfd_malloc (size + 1); + + if (newstr == NULL) + return 0; + strncpy (newstr, str, size); + newstr[size] = 0; + + return newstr; +} + +/* Copy counted string (string with length at first byte) to new allocated area + ptr points to length byte on entry */ + +char * +_bfd_evax_save_counted_string (ptr) + char *ptr; +{ + int len = *ptr++; + + return _bfd_evax_save_sized_string (ptr, len); +} + + +/* stack routines for EVAX ETIR commands */ + +/* Push value and section index */ + +void +_bfd_evax_push (abfd, val, psect) + bfd *abfd; + uquad val; + int psect; +{ + static int last_psect; + +#if EVAX_DEBUG + evax_debug (4, "\n", val, psect, PRIV(stackptr)); +#endif + + if (psect >= 0) + last_psect = psect; + + PRIV(stack[PRIV(stackptr)]).value = val; + PRIV(stack[PRIV(stackptr)]).psect = last_psect; + PRIV(stackptr)++; + if (PRIV(stackptr) >= STACKSIZE) + { + bfd_set_error (bfd_error_bad_value); + exit(1); + } + return; +} + + +/* Pop value and section index */ + +uquad +_bfd_evax_pop (abfd, psect) + bfd *abfd; + int *psect; +{ + uquad value; + + if (PRIV(stackptr) == 0) + { + bfd_set_error (bfd_error_bad_value); + exit(1); + } + PRIV(stackptr)--; + value = PRIV(stack[PRIV(stackptr)]).value; + if ((psect != NULL) && (PRIV(stack[PRIV(stackptr)]).psect >= 0)) + *psect = PRIV(stack[PRIV(stackptr)]).psect; + +#if EVAX_DEBUG + evax_debug (4, "\n", value, PRIV(stack[PRIV(stackptr)]).psect); +#endif + + return value; +} + + +/* object file output functions */ + +/* GAS tends to write sections in little chunks (bfd_set_section_contents) + which we can't use directly. So we save the little chunks in linked + lists (one per section) and write them later. */ + +/* Add a new evax_section structure to evax_section_table + - forward chaining - */ + +static evax_section * +add_new_contents (abfd, section) + bfd *abfd; + sec_ptr section; +{ + evax_section *sptr, *newptr; + + sptr = PRIV(evax_section_table)[section->index]; + if (sptr != NULL) + return sptr; + + newptr = (evax_section *) bfd_malloc (sizeof (evax_section)); + if (newptr == (evax_section *) NULL) + return NULL; + newptr->contents = (unsigned char *) bfd_alloc (abfd, section->_raw_size); + if (newptr->contents == (unsigned char *)NULL) + return NULL; + newptr->offset = 0; + newptr->size = section->_raw_size; + newptr->next = 0; + PRIV(evax_section_table)[section->index] = newptr; + return newptr; +} + + +/* Save section data & offset to an evax_section structure + evax_section_table[] holds the evax_section chain */ + +boolean +_bfd_save_evax_section (abfd, section, data, offset, count) + bfd *abfd; + sec_ptr section; + PTR data; + file_ptr offset; + bfd_size_type count; +{ + evax_section *sptr; + + if (section->index >= EVAX_SECTION_COUNT) + { + bfd_set_error (bfd_error_nonrepresentable_section); + return false; + } + if (count == (bfd_size_type)0) + return true; + sptr = add_new_contents (abfd, section); + if (sptr == NULL) + return false; + memcpy (sptr->contents + offset, data, (size_t) count); + + return true; +} + + +/* Get evax_section pointer to saved contents for section # index */ + +evax_section * +_bfd_get_evax_section (abfd, index) + bfd *abfd; + int index; +{ + if (index >= EVAX_SECTION_COUNT) + { + bfd_set_error (bfd_error_nonrepresentable_section); + return NULL; + } + return PRIV(evax_section_table)[index]; +} + + +/* Object output routines */ + +/* Begin new record or record header + write 2 bytes rectype + write 2 bytes record length (filled in at flush) + write 2 bytes header type (ommitted if rechead == -1) */ + +void +_bfd_evax_output_begin (abfd, rectype, rechead) + bfd *abfd; + int rectype; + int rechead; +{ +#if EVAX_DEBUG + evax_debug (6, "_bfd_evax_output_begin(type %d, head %d)\n", rectype, + rechead); +#endif + + _bfd_evax_output_short (abfd,rectype); + + /* save current output position to fill in lenght later */ + + if (PRIV(push_level) > 0) + PRIV(length_pos) = PRIV(output_size); + +#if EVAX_DEBUG + evax_debug (6, "_bfd_evax_output_begin: length_pos = %d\n", + PRIV(length_pos)); +#endif + + _bfd_evax_output_short (abfd,0); /* placeholder for length */ + + if (rechead != -1) + _bfd_evax_output_short (abfd,rechead); + + return; +} + + +/* Set record/subrecord alignment */ + +void +_bfd_evax_output_alignment (abfd, alignto) + bfd *abfd; + int alignto; +{ +#if EVAX_DEBUG + evax_debug (6, "_bfd_evax_output_alignment(%d)\n", alignto); +#endif + + PRIV(output_alignment) = alignto; + return; +} + + +/* Prepare for subrecord fields */ + +void +_bfd_evax_output_push (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (6, "evax_output_push(pushed_size = %d)\n", PRIV(output_size)); +#endif + + PRIV(push_level)++; + PRIV(pushed_size) = PRIV(output_size); + return; +} + + +/* End of subrecord fields */ + +void +_bfd_evax_output_pop (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (6, "evax_output_pop(pushed_size = %d)\n", PRIV(pushed_size)); +#endif + + _bfd_evax_output_flush (abfd); + PRIV(length_pos) = 2; + +#if EVAX_DEBUG + evax_debug (6, "evax_output_pop: length_pos = %d\n", PRIV(length_pos)); +#endif + + PRIV(pushed_size) = 0; + PRIV(push_level)--; + return; +} + + +/* Flush unwritten output, ends current record */ + +void +_bfd_evax_output_flush (abfd) + bfd *abfd; +{ + int real_size = PRIV(output_size); + int aligncount; + int length; + +#if EVAX_DEBUG + evax_debug (6, "_bfd_evax_output_flush(real_size = %d, pushed_size %d at lenpos %d)\n", + real_size, PRIV(pushed_size), PRIV(length_pos)); +#endif + + if (PRIV(push_level) > 0) + length = real_size - PRIV(pushed_size); + else + length = real_size; + + if (length == 0) + return; + aligncount = (PRIV(output_alignment) + - (length % PRIV(output_alignment))) % PRIV(output_alignment); + +#if EVAX_DEBUG + evax_debug (6, "align: adding %d bytes\n", aligncount); +#endif + + while(aligncount-- > 0) + { + PRIV(output_buf)[real_size++] = 0; +#if 0 + /* this is why I *love* vms: inconsistency :-} + alignment is added to the subrecord length + but not to the record length */ + if (PRIV(push_level) > 0) +#endif + length++; + } + + /* put length to buffer */ + PRIV(output_size) = PRIV(length_pos); + _bfd_evax_output_short (abfd, (unsigned int)length); + + if (PRIV(push_level) == 0) + { +#ifndef VMS + /* write length first, see FF_FOREIGN in the input routines */ + fwrite (PRIV(output_buf)+2, 2, 1, (FILE *)abfd->iostream); +#endif + fwrite (PRIV(output_buf), real_size, 1, (FILE *)abfd->iostream); + + PRIV(output_size) = 0; + } + else + { + PRIV(output_size) = real_size; + PRIV(pushed_size) = PRIV(output_size); + } + + return; +} + + +/* End record output */ + +void +_bfd_evax_output_end (abfd) + bfd *abfd; +{ +#if EVAX_DEBUG + evax_debug (6, "_bfd_evax_output_end\n"); +#endif + + _bfd_evax_output_flush (abfd); + + return; +} + + +/* check remaining buffer size + + return what's left. */ + +int +_bfd_evax_output_check (abfd, size) + bfd *abfd; + int size; +{ +#if EVAX_DEBUG + evax_debug (6, "_bfd_evax_output_check(%d)\n", size); +#endif + + return (MAX_OUTREC_SIZE - (PRIV(output_size) + size + MIN_OUTREC_LUFT)); +} + + +/* Output byte (8 bit) value */ + +void +_bfd_evax_output_byte (abfd, value) + bfd *abfd; + unsigned int value; +{ +#if EVAX_DEBUG + evax_debug (6, "_bfd_evax_output_byte(%02x)\n", value); +#endif + + bfd_put_8 (abfd, value & 0xff, PRIV(output_buf) + PRIV(output_size)); + PRIV(output_size) += 1; + return; +} + + +/* Output short (16 bit) value */ + +void +_bfd_evax_output_short (abfd, value) + bfd *abfd; + unsigned int value; +{ +#if EVAX_DEBUG + evax_debug (6, "_bfd_evax_output_short (%04x)\n", value); +#endif + + bfd_put_16 (abfd, value & 0xffff, PRIV(output_buf) + PRIV(output_size)); + PRIV(output_size) += 2; + return; +} + + +/* Output long (32 bit) value */ + +void +_bfd_evax_output_long (abfd, value) + bfd *abfd; + unsigned long value; +{ +#if EVAX_DEBUG + evax_debug (6, "_bfd_evax_output_long (%08lx)\n", value); +#endif + + bfd_put_32 (abfd, value, PRIV(output_buf) + PRIV(output_size)); + PRIV(output_size) += 4; + return; +} + + +/* Output quad (64 bit) value */ + +void +_bfd_evax_output_quad (abfd, value) + bfd *abfd; + uquad value; +{ +#if EVAX_DEBUG + evax_debug (6, "_bfd_evax_output_quad(%016lx)\n", value); +#endif + + bfd_put_64(abfd, value, PRIV(output_buf) + PRIV(output_size)); + PRIV(output_size) += 8; + return; +} + + +/* Output c-string as counted string */ + +void +_bfd_evax_output_counted (abfd, value) + bfd *abfd; + char *value; +{ +int len; + +#if EVAX_DEBUG + evax_debug (6, "_bfd_evax_output_counted(%s)\n", value); +#endif + + len = strlen (value); + if (len == 0) + { + (*_bfd_error_handler) ("_bfd_evax_output_counted called with zero bytes"); + return; + } + if (len > 255) + { + (*_bfd_error_handler) ("_bfd_evax_output_counted called with too many bytes"); + return; + } + _bfd_evax_output_byte (abfd, len & 0xff); + _bfd_evax_output_dump (abfd, (unsigned char *)value, len); +} + + +/* Output character area */ + +void +_bfd_evax_output_dump (abfd, data, length) + bfd *abfd; + unsigned char *data; + int length; +{ +#if EVAX_DEBUG + evax_debug (6, "_bfd_evax_output_dump(%d)\n", length); +#endif + + if (length == 0) + return; + + memcpy (PRIV(output_buf) + PRIV(output_size), data, length); + PRIV(output_size) += length; + + return; +} + + +/* Output count bytes of value */ + +void +_bfd_evax_output_fill (abfd, value, count) + bfd *abfd; + int value; + int count; +{ +#if EVAX_DEBUG + evax_debug (6, "_bfd_evax_output_fill(val %02x times %d)\n", value, count); +#endif + + if (count == 0) + return; + memset (PRIV(output_buf) + PRIV(output_size), value, count); + PRIV(output_size) += count; + + return; +} + +/*-----------------------------------------------------------------------------*/ + +/* Return basename (stripped of directory information) of filename */ + +char * +_bfd_evax_basename (name) + char *name; +{ + char *ptr; + +#if EVAX_DEBUG + evax_debug (6, "_bfd_evax_basename %s -> ", name); +#endif + +#ifndef VMS + /* assume unix host */ + ptr = strrchr (name, '.'); + if (ptr) + *ptr = 0; + ptr = strrchr (name, '/'); + if (ptr) + *ptr++ = 0; + else + ptr = name; +#else + /* assume vms host */ + ptr = strrchr (name, '.'); + if (ptr) + { + *ptr = 0; + ptr = name; + } + else + { + ptr = strrchr (name, ']'); + if (ptr) + *ptr++ = 0; + else + { + ptr = strrchr (name, ':'); + if (ptr) + *ptr++ = 0; + else + ptr = name; + } + } +#endif + +#if EVAX_DEBUG + evax_debug (6, "%s\n", ptr); +#endif + + return ptr; +} + + +/* Manufacure a VMS like time on a unix based system. + stolen from obj-vms.c */ + +char * +_bfd_get_vms_time_string () +{ + static char tbuf[18]; +#ifndef VMS +#include +#include + + char *pnt; + time_t timeb; + time (&timeb); + pnt = ctime (&timeb); + pnt[3] = 0; + pnt[7] = 0; + pnt[10] = 0; + pnt[16] = 0; + pnt[24] = 0; + sprintf (tbuf, "%2s-%3s-%s %s", pnt + 8, pnt + 4, pnt + 20, pnt + 11); +#else +#include + struct + { + int Size; + char *Ptr; + } Descriptor; + Descriptor.Size = 17; + Descriptor.Ptr = tbuf; + sys$asctim (0, &Descriptor, 0, 0); +#endif /* not VMS */ + +#if EVAX_DEBUG + evax_debug (6, "vmstimestring:'%s'\n", tbuf); +#endif + + return tbuf; +} diff --git a/gnu/usr.bin/binutils/bfd/evax.h b/gnu/usr.bin/binutils/bfd/evax.h new file mode 100644 index 00000000000..7d6c9b4ec42 --- /dev/null +++ b/gnu/usr.bin/binutils/bfd/evax.h @@ -0,0 +1,379 @@ +/* evax.h -- Header file for ALPHA EVAX (openVMS/AXP) support. + Copyright 1996 Free Software Foundation, Inc. + Written by Klaus Kämpf (kkaempf@progis.de) + of proGIS Softwareentwicklung, Aachen, Germany + +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 EVAX_H +#define EVAX_H + +/* EVAX Text, information and relocation record (ETIR) definitions. */ + +#define ETIR_S_C_MINSTACOD 0 /* Minimum store code */ +#define ETIR_S_C_STA_GBL 0 /* Stack global symbol value */ +#define ETIR_S_C_STA_LW 1 /* Stack longword */ +#define ETIR_S_C_STA_QW 2 /* Stack quadword */ +#define ETIR_S_C_STA_PQ 3 /* Stack psect base plus quadword offset */ +#define ETIR_S_C_STA_LI 4 /* Stack literal */ +#define ETIR_S_C_STA_MOD 5 /* Stack module */ +#define ETIR_S_C_STA_CKARG 6 /* Check Arguments */ +#define ETIR_S_C_MAXSTACOD 6 /* Maximum stack code */ +#define ETIR_S_C_MINSTOCOD 50 /* Minimum store code */ +#define ETIR_S_C_STO_B 50 /* Store byte */ +#define ETIR_S_C_STO_W 51 /* Store word */ +#define ETIR_S_C_STO_LW 52 /* Store longword */ +#define ETIR_S_C_STO_QW 53 /* Store quadword */ +#define ETIR_S_C_STO_IMMR 54 /* Store immediate Repeated */ +#define ETIR_S_C_STO_GBL 55 /* Store global */ +#define ETIR_S_C_STO_CA 56 /* Store code address */ +#define ETIR_S_C_STO_RB 57 /* Store relative branch */ +#define ETIR_S_C_STO_AB 58 /* Store absolute branch */ +#define ETIR_S_C_STO_OFF 59 /* Store offset within psect */ +#define ETIR_S_C_STO_IMM 61 /* Store immediate */ +#define ETIR_S_C_STO_GBL_LW 62 /* Store global Longword */ +#define ETIR_S_C_STO_LP_PSB 63 /* STO_LP_PSB not valid in level 2 use STC_LP_PSB */ +#define ETIR_S_C_STO_HINT_GBL 64 /* Store 14 bit HINT at global address */ +#define ETIR_S_C_STO_HINT_PS 65 /* Store 14 bit HINT at psect + offset */ +#define ETIR_S_C_MAXSTOCOD 65 /* Maximum store code */ +#define ETIR_S_C_MINOPRCOD 100 /* Minimum operate code */ +#define ETIR_S_C_OPR_NOP 100 /* No-op */ +#define ETIR_S_C_OPR_ADD 101 /* Add */ +#define ETIR_S_C_OPR_SUB 102 /* Subtract */ +#define ETIR_S_C_OPR_MUL 103 /* Multiply */ +#define ETIR_S_C_OPR_DIV 104 /* Divide */ +#define ETIR_S_C_OPR_AND 105 /* Logical AND */ +#define ETIR_S_C_OPR_IOR 106 /* Logical inclusive OR */ +#define ETIR_S_C_OPR_EOR 107 /* Logical exclusive OR */ +#define ETIR_S_C_OPR_NEG 108 /* Negate */ +#define ETIR_S_C_OPR_COM 109 /* Complement */ +#define ETIR_S_C_OPR_INSV 110 /* Insert bit field */ +#define ETIR_S_C_OPR_ASH 111 /* Arithmetic shift */ +#define ETIR_S_C_OPR_USH 112 /* Unsigned shift */ +#define ETIR_S_C_OPR_ROT 113 /* Rotate */ +#define ETIR_S_C_OPR_SEL 114 /* Select one of three longwords on top of stack */ +#define ETIR_S_C_OPR_REDEF 115 /* Redefine this symbol after pass 2 */ +#define ETIR_S_C_OPR_DFLIT 116 /* Define a literal */ +#define ETIR_S_C_MAXOPRCOD 116 /* Maximum operate code */ +#define ETIR_S_C_MINCTLCOD 150 /* Minimum control code */ +#define ETIR_S_C_CTL_SETRB 150 /* Set relocation base */ +#define ETIR_S_C_CTL_AUGRB 151 /* Augment relocation base */ +#define ETIR_S_C_CTL_DFLOC 152 /* Define debug location */ +#define ETIR_S_C_CTL_STLOC 153 /* Set debug location */ +#define ETIR_S_C_CTL_STKDL 154 /* Stack debug location */ +#define ETIR_S_C_MAXCTLCOD 154 /* Maximum control code */ +#define ETIR_S_C_MINSTCCOD 200 /* Minimum store-conditional code */ +#define ETIR_S_C_STC_LP 200 /* Store-conditional Linkage Pair */ +#define ETIR_S_C_STC_LP_PSB 201 /* Store-conditional Linkage Pair with Procedure Signature */ +#define ETIR_S_C_STC_GBL 202 /* Store-conditional Address at global address */ +#define ETIR_S_C_STC_GCA 203 /* Store-conditional Code Address at global address */ +#define ETIR_S_C_STC_PS 204 /* Store-conditional Address at psect + offset */ +#define ETIR_S_C_STC_NOP_GBL 205 /* Store-conditional NOP at address of global */ +#define ETIR_S_C_STC_NOP_PS 206 /* Store-conditional NOP at pect + offset */ +#define ETIR_S_C_STC_BSR_GBL 207 /* Store-conditional BSR at global address */ +#define ETIR_S_C_STC_BSR_PS 208 /* Store-conditional BSR at pect + offset */ +#define ETIR_S_C_STC_LDA_GBL 209 /* Store-conditional LDA at global address */ +#define ETIR_S_C_STC_LDA_PS 210 /* Store-conditional LDA at psect + offset */ +#define ETIR_S_C_STC_BOH_GBL 211 /* Store-conditional BSR or Hint at global address */ +#define ETIR_S_C_STC_BOH_PS 212 /* Store-conditional BSR or Hint at pect + offset */ +#define ETIR_S_C_STC_NBH_GBL 213 /* Store-conditional NOP,BSR or HINT at global address */ +#define ETIR_S_C_STC_NBH_PS 214 /* Store-conditional NOP,BSR or HINT at psect + offset */ +#define ETIR_S_C_MAXSTCCOD 214 /* Maximum store-conditional code */ + +/* EVAX Global symbol definition record (EGSD). */ + +#define EGSD_S_K_ENTRIES 2 /* Offset to first entry in record */ +#define EGSD_S_C_ENTRIES 2 /* Offset to first entry in record */ +#define EGSD_S_C_PSC 0 /* Psect definition */ +#define EGSD_S_C_SYM 1 /* Symbol specification */ +#define EGSD_S_C_IDC 2 /* Random entity check */ +#define EGSD_S_C_SPSC 5 /* Shareable image psect definition */ +#define EGSD_S_C_SYMV 6 /* Vectored (dual-valued) versions of SYM, */ +#define EGSD_S_C_SYMM 7 /* Masked versions of SYM, */ +#define EGSD_S_C_SYMG 8 /* EGST - gst version of SYM */ +#define EGSD_S_C_MAXRECTYP 8 /* Maximum entry type defined */ + +#define EGPS_S_V_PIC 0x0001 +#define EGPS_S_V_LIB 0x0002 +#define EGPS_S_V_OVR 0x0004 +#define EGPS_S_V_REL 0x0008 +#define EGPS_S_V_GBL 0x0010 +#define EGPS_S_V_SHR 0x0020 +#define EGPS_S_V_EXE 0x0040 +#define EGPS_S_V_RD 0x0080 +#define EGPS_S_V_WRT 0x0100 +#define EGPS_S_V_VEC 0x0200 +#define EGPS_S_V_NOMOD 0x0400 +#define EGPS_S_V_COM 0x0800 + +#define EGSY_S_V_WEAK 0x0001 +#define EGSY_S_V_DEF 0x0002 +#define EGSY_S_V_UNI 0x0004 +#define EGSY_S_V_REL 0x0008 +#define EGSY_S_V_COMM 0x0010 +#define EGSY_S_V_VECEP 0x0020 +#define EGSY_S_V_NORM 0x0040 + +/* EVAX Module header record (EMH) definitions. */ + +#define EMH_S_C_MHD 0 /* Main header record */ +#define EMH_S_C_LNM 1 /* Language name and version */ +#define EMH_S_C_SRC 2 /* Source file specification */ +#define EMH_S_C_TTL 3 /* Title text of module */ +#define EMH_S_C_CPR 4 /* Copyright notice */ +#define EMH_S_C_MTC 5 /* Maintenance status */ +#define EMH_S_C_GTX 6 /* General text */ +#define EMH_S_C_MAXHDRTYP 6 /* Maximum allowable type */ + +/* evax-alpha.c. */ + +extern asymbol *_bfd_evax_make_empty_symbol PARAMS ((bfd *abfd)); + +/* evax-egsd.c. */ + +extern int _bfd_evax_slurp_egsd PARAMS ((bfd *abfd)); +extern int _bfd_evax_write_egsd PARAMS ((bfd *abfd)); + +/* evax-emh.c. */ + +extern int _bfd_evax_slurp_emh PARAMS ((bfd *abfd)); +extern int _bfd_evax_write_emh PARAMS ((bfd *abfd)); +extern int _bfd_evax_slurp_eeom PARAMS ((bfd *abfd)); +extern int _bfd_evax_write_eeom PARAMS ((bfd *abfd)); + +/* evax-etir.c. */ + +extern int _bfd_evax_slurp_etir PARAMS ((bfd *abfd)); +extern int _bfd_evax_slurp_edbg PARAMS ((bfd *abfd)); +extern int _bfd_evax_slurp_etbt PARAMS ((bfd *abfd)); + +extern int _bfd_evax_write_etir PARAMS ((bfd *abfd)); +extern int _bfd_evax_write_etbt PARAMS ((bfd *abfd)); +extern int _bfd_evax_write_edbg PARAMS ((bfd *abfd)); + +/* The r_type field in a reloc is one of the following values. */ +#define ALPHA_R_IGNORE 0 +#define ALPHA_R_REFQUAD 1 +#define ALPHA_R_BRADDR 2 +#define ALPHA_R_HINT 3 +#define ALPHA_R_SREL16 4 +#define ALPHA_R_SREL32 5 +#define ALPHA_R_SREL64 6 +#define ALPHA_R_OP_PUSH 7 +#define ALPHA_R_OP_STORE 8 +#define ALPHA_R_OP_PSUB 9 +#define ALPHA_R_OP_PRSHIFT 10 +#define ALPHA_R_LINKAGE 11 +#define ALPHA_R_REFLONG 12 + +/* Object language definitions. */ + +#define EOBJ_S_C_EMH 8 /*EVAX module header record */ +#define EOBJ_S_C_EEOM 9 /*EVAX end of module record */ +#define EOBJ_S_C_EGSD 10 /*EVAX global symbol definition record */ +#define EOBJ_S_C_ETIR 11 /*EVAX text information record */ +#define EOBJ_S_C_EDBG 12 /*EVAX Debugger information record */ +#define EOBJ_S_C_ETBT 13 /*EVAX Traceback information record */ +#define EOBJ_S_C_MAXRECTYP 13 /*Last assigned record type */ +#define EOBJ_S_K_SUBTYP 4 +#define EOBJ_S_C_SUBTYP 4 +#define EOBJ_S_C_MAXRECSIZ 8192 /*Maximum legal record size */ +#define EOBJ_S_C_STRLVL 2 /*Structure level */ +#define EOBJ_S_C_SYMSIZ 64 /*Maxymum symbol length */ +#define EOBJ_S_C_STOREPLIM -1 /*Maximum repeat count on store commands */ +#define EOBJ_S_C_PSCALILIM 16 /*Maximum p-sect alignment */ + +/* Miscellaneous definitions. */ + +#if __GNUC__ +typedef unsigned long long uquad; +#else +typedef unsigned long uquad; +#endif + +#define MAX_OUTREC_SIZE 4096 +#define MIN_OUTREC_LUFT 64 + +typedef struct _evax_section { + unsigned char *contents; + bfd_vma offset; + bfd_size_type size; + struct _evax_section *next; +} evax_section; + +extern boolean _bfd_save_evax_section + PARAMS ((bfd *abfd, asection *section, PTR data, file_ptr offset, + bfd_size_type count)); +extern evax_section *_bfd_get_evax_section PARAMS ((bfd *abfd, int index)); + +typedef struct _evax_reloc { + struct _evax_reloc *next; + arelent *reloc; + asection *section; +} evax_reloc; + +/* evax module header */ + +struct emh_struc { + int emh_b_strlvl; + long emh_l_arch1; + long emh_l_arch2; + long emh_l_recsiz; + char *emh_t_name; + char *emh_t_version; + char *emh_t_date; + char *emh_c_lnm; + char *emh_c_src; + char *emh_c_ttl; +}; + + +/* evax end of module */ + +struct eeom_struc { + long eeom_l_total_lps; + unsigned char eeom_b_comcod; + boolean eeom_has_transfer; + unsigned char eeom_b_tfrflg; + long eeom_l_psindx; + long eeom_l_tfradr; +}; + +enum file_format_enum { FF_UNKNOWN, FF_FOREIGN, FF_NATIVE }; + +typedef struct evax_symbol_struct { + struct bfd_hash_entry bfd_hash; + asymbol *symbol; +} evax_symbol_entry; + +/* stack value for push/pop commands */ + +struct stack_struct { + uquad value; + int psect; +}; +#define STACKSIZE 50 + +/* location stack definitions for CTL_DFLOC, CTL_STLOC, and CTL_STKDL */ + +struct location_struct { + unsigned long value; + int psect; +}; +#define LOCATION_SAVE_SIZE 32 + +#define EVAX_SECTION_COUNT 32 + +struct evax_private_data_struct { + char *filename; /* Filename of object file */ + boolean fixup_done; /* Flag to indicate if all + section pointers and PRIV(sections) + are set up correctly */ + unsigned char *evax_buf; /* buffer to record */ + int buf_size; /* max size of buffer */ + unsigned char *evax_rec; /* actual record ptr */ + int rec_length; /* remaining record length */ + int rec_size; /* actual record size */ + int rec_type; /* actual record type */ + enum file_format_enum file_format; + + struct emh_struc emh_data; /* data from EMH record */ + struct eeom_struc eeom_data; /* data from EEOM record */ + int egsd_sec_count; /* # of EGSD sections */ + asection **sections; /* vector of EGSD sections */ + int egsd_sym_count; /* # of EGSD symbols */ + asymbol **symbols; /* vector of EGSD symbols */ + struct proc_value *procedure; + + struct stack_struct *stack; + int stackptr; + + evax_section *evax_section_table[EVAX_SECTION_COUNT]; + + struct bfd_hash_table *evax_symbol_table; + struct symbol_cache_entry **symcache; + int symnum; + + struct location_struct *location_stack; + + unsigned char *image_ptr; /* a pointer to section->contents */ + + unsigned char pdsc[8]; /* procedure descriptor */ + + /* Output routine storage */ + + unsigned char *output_buf; /* output data */ + int push_level; + int pushed_size; + int length_pos; + int output_size; + int output_alignment; + + /* linkage index counter + used by conditional store commands (ETIR_S_C_STC_) */ + + int evax_linkage_index; + +}; + +#define PRIV(name) ((struct evax_private_data_struct *)abfd->tdata.any)->name + +#if EVAX_DEBUG +extern void _bfd_evax_debug PARAMS((int level, char *format, ...)); +extern void _bfd_hexdump + PARAMS ((int level, unsigned char *ptr, int size, int offset)); + +#define evax_debug _bfd_evax_debug + +#endif + +extern struct bfd_hash_entry *_bfd_evax_hash_newfunc + PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table, + const char *string)); +extern void _bfd_evax_get_header_values + PARAMS ((bfd *abfd, unsigned char *buf, int *type, int *length)); +extern int _bfd_evax_get_record PARAMS ((bfd *abfd)); +extern int _bfd_evax_next_record PARAMS ((bfd *abfd)); + +extern char *_bfd_evax_save_sized_string PARAMS ((char *str, int size)); +extern char *_bfd_evax_save_counted_string PARAMS ((char *ptr)); +extern void _bfd_evax_push PARAMS ((bfd *abfd, uquad val, int psect)); +extern uquad _bfd_evax_pop PARAMS ((bfd *abfd, int *psect)); + +extern boolean _bfd_save_evax_section + PARAMS ((bfd *abfd, asection *section, PTR data, file_ptr offset, + bfd_size_type count)); +extern void _bfd_evax_output_begin + PARAMS ((bfd *abfd, int rectype, int rechead)); +extern void _bfd_evax_output_alignment PARAMS ((bfd *abfd, int alignto)); +extern void _bfd_evax_output_push PARAMS ((bfd *abfd)); +extern void _bfd_evax_output_pop PARAMS ((bfd *abfd)); +extern void _bfd_evax_output_flush PARAMS ((bfd *abfd)); +extern void _bfd_evax_output_end PARAMS ((bfd *abfd)); +extern int _bfd_evax_output_check PARAMS ((bfd *abfd, int size)); +extern void _bfd_evax_output_byte PARAMS ((bfd *abfd, unsigned int value)); +extern void _bfd_evax_output_short PARAMS ((bfd *abfd, unsigned int value)); +extern void _bfd_evax_output_long PARAMS ((bfd *abfd, unsigned long value)); +extern void _bfd_evax_output_quad PARAMS ((bfd *abfd, uquad value)); +extern void _bfd_evax_output_counted PARAMS ((bfd *abfd, char *value)); +extern void _bfd_evax_output_dump PARAMS ((bfd *abfd, unsigned char *data, + int length)); +extern void _bfd_evax_output_fill PARAMS ((bfd *abfd, int value, int length)); +extern char *_bfd_get_vms_time_string PARAMS ((void)); +extern char *_bfd_evax_basename PARAMS ((char *name)); + +#endif /* EVAX_H */ diff --git a/gnu/usr.bin/binutils/bfd/hosts/alphavms.h b/gnu/usr.bin/binutils/bfd/hosts/alphavms.h new file mode 100644 index 00000000000..eee391a97fb --- /dev/null +++ b/gnu/usr.bin/binutils/bfd/hosts/alphavms.h @@ -0,0 +1,69 @@ +/* alphavms.h -- BFD definitions for an openVMS host + Copyright 1996 Free Software Foundation, Inc. + Written by Klaus Kämpf (kkaempf@progis.de) + of proGIS Softwareentwicklung, Aachen, Germany + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bfd.h" + +#ifndef BFD_HOST_64_BIT +/* Make the basic types 64-bit quantities on the host. + Also provide the support macros BFD needs. */ +# ifdef __GNUC__ +# define BFD_HOST_64_BIT long long +# else +# define BFD_HOST_64_BIT long +# endif +typedef unsigned BFD_HOST_64_BIT uint64_type; +typedef BFD_HOST_64_BIT int64_type; + +# define sprintf_vma(s,x) sprintf (s, "%016lx", x) /* BFD_HOST_64_BIT */ +# define fprintf_vma(f,x) fprintf (f, "%016lx", x) /* BFD_HOST_64_BIT */ + +# define BYTES_IN_PRINTF_INT 4 + +/* These must have type unsigned long because they are used as + arguments in printf functions. */ +# define uint64_typeLOW(x) ((unsigned long) (((x) & 0xffffffff))) /* BFD_HOST_64_BIT */ +# define uint64_typeHIGH(x) ((unsigned long) (((x) >> 32) & 0xffffffff)) /* BFD_HOST_64_BIT */ + +#endif /* BFD_HOST_64_BIT */ + +#include "fopen-vms.h" + +#define NO_FCNTL 1 + +#ifndef O_ACCMODE +#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) +#endif + +extern int getpagesize PARAMS ((void)); diff --git a/gnu/usr.bin/binutils/bfd/i386aout.c b/gnu/usr.bin/binutils/bfd/i386aout.c index 0801832d16d..ef4b99f786c 100644 --- a/gnu/usr.bin/binutils/bfd/i386aout.c +++ b/gnu/usr.bin/binutils/bfd/i386aout.c @@ -1,5 +1,5 @@ /* BFD back-end for i386 a.out binaries. - Copyright 1990, 1991, 1992 Free Software Foundation, Inc. + Copyright 1990, 91, 92, 94, 95, 1996 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -47,7 +47,29 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" #include "sysdep.h" #include "libbfd.h" +#include "aout/aout64.h" #include "libaout.h" + +/* Set the machine type correctly. */ + +static boolean +i386aout_write_object_contents (abfd) + bfd *abfd; +{ + struct external_exec exec_bytes; + struct internal_exec *execp = exec_hdr (abfd); + + N_SET_MACHTYPE (*execp, M_386); + + obj_reloc_entry_size (abfd) = RELOC_STD_SIZE; + + WRITE_HEADERS (abfd, execp); + + return true; +} + +#define MY_write_object_contents i386aout_write_object_contents + static boolean MY(set_sizes)(); #define MY_backend_data &MY(backend_data) static CONST struct aout_backend_data MY(backend_data) = { diff --git a/gnu/usr.bin/binutils/bfd/ihex.c b/gnu/usr.bin/binutils/bfd/ihex.c index abe61c676c2..819b9867547 100644 --- a/gnu/usr.bin/binutils/bfd/ihex.c +++ b/gnu/usr.bin/binutils/bfd/ihex.c @@ -1,5 +1,5 @@ /* BFD back-end for Intel Hex objects. - Copyright 1995 Free Software Foundation, Inc. + Copyright 1995, 1996 Free Software Foundation, Inc. Written by Ian Lance Taylor of Cygnus Support . This file is part of BFD, the Binary File Descriptor library. @@ -269,7 +269,6 @@ ihex_scan (abfd) bfd *abfd; { bfd_vma segbase; - bfd_vma extbase; asection *sec; int lineno; boolean error; @@ -282,7 +281,6 @@ ihex_scan (abfd) abfd->start_address = 0; - extbase = 0; segbase = 0; sec = NULL; lineno = 1; @@ -378,7 +376,7 @@ ihex_scan (abfd) case 0: /* This is a data record. */ if (sec != NULL - && sec->vma + sec->_raw_size == extbase + segbase + addr) + && sec->vma + sec->_raw_size == segbase + addr) { /* This data goes at the end of the section we are currently building. */ @@ -398,8 +396,8 @@ ihex_scan (abfd) if (sec == NULL) goto error_return; sec->flags = SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC; - sec->vma = extbase + segbase + addr; - sec->lma = extbase + segbase + addr; + sec->vma = segbase + addr; + sec->lma = segbase + addr; sec->_raw_size = len; sec->filepos = pos; } @@ -793,11 +791,9 @@ static boolean ihex_write_object_contents (abfd) bfd *abfd; { - bfd_vma extbase; bfd_vma segbase; struct ihex_data_list *l; - extbase = 0; segbase = 0; for (l = abfd->tdata.ihex_data->head; l != NULL; l = l->next) { @@ -816,7 +812,7 @@ ihex_write_object_contents (abfd) if (now > CHUNK) now = CHUNK; - if (where > extbase + segbase + 0xffff) + if (where > segbase + 0xffff) { bfd_byte addr[2]; @@ -831,8 +827,8 @@ ihex_write_object_contents (abfd) } else { - extbase = where & 0xffff0000; - if (where > extbase + 0xffff) + segbase = where & 0xffff0000; + if (where > segbase + 0xffff) { char buf[20]; @@ -843,15 +839,14 @@ ihex_write_object_contents (abfd) bfd_set_error (bfd_error_bad_value); return false; } - addr[0] = (extbase >> 24) & 0xff; - addr[1] = (extbase >> 16) & 0xff; + addr[0] = (segbase >> 24) & 0xff; + addr[1] = (segbase >> 16) & 0xff; if (! ihex_write_record (abfd, 2, 0, 4, addr)) return false; } } - if (! ihex_write_record (abfd, now, where - (extbase + segbase), - 0, p)) + if (! ihex_write_record (abfd, now, where - segbase, 0, p)) return false; where += now; diff --git a/gnu/usr.bin/binutils/bfd/libieee.h b/gnu/usr.bin/binutils/bfd/libieee.h index c3729cbf517..30e806eaa70 100644 --- a/gnu/usr.bin/binutils/bfd/libieee.h +++ b/gnu/usr.bin/binutils/bfd/libieee.h @@ -1,5 +1,5 @@ /* IEEE-695 object file formats: definitions internal to BFD. - Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc. + Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. Written by Cygnus Support. Mostly Steve Chamberlain's fault. This file is part of BFD, the Binary File Descriptor library. @@ -60,9 +60,6 @@ typedef struct ieee_per_section } ieee_per_section_type; #define ieee_per_section(x) ((ieee_per_section_type *)((x)->used_by_bfd)) -/* FIXME! There should be no limit to the number of sections! */ -#define NSECTIONS 20 - typedef struct { unsigned char *input_p; @@ -77,7 +74,8 @@ typedef struct ieee_data_struct boolean read_data; file_ptr output_cursor; /* Map of section indexes to section ptrs */ - asection * section_table[NSECTIONS]; + asection **section_table; + unsigned int section_table_size; ieee_address_descriptor_type ad; ieee_module_begin_type mb; ieee_w_variable_type w; diff --git a/gnu/usr.bin/binutils/bfd/makefile.vms b/gnu/usr.bin/binutils/bfd/makefile.vms new file mode 100644 index 00000000000..1d131d63379 --- /dev/null +++ b/gnu/usr.bin/binutils/bfd/makefile.vms @@ -0,0 +1,46 @@ +# +# Makefile for bfd library under openVMS/AXP +# +# For use with gnu-make for vms +# +# Created by Klaus Kaempf, kkaempf@progis.de +# +# +CC=gcc + +OBJS=archive.obj,archures.obj,bfd.obj,cache.obj,coffgen.obj,corefile.obj,format.obj,\ + init.obj,libbfd.obj,opncls.obj,reloc.obj,section.obj,syms.obj,targets.obj,\ + hash.obj,linker.obj,elf.obj,srec.obj,binary.obj,tekhex.obj,ihex.obj,stab-syms.obj,\ + evax-alpha.obj,evax-emh.obj,evax-egsd.obj,evax-etir.obj,evax-misc.obj,\ + cpu-alpha.obj + +ifeq ($(CC),gcc) +DEFS=/define=(SELECT_VECS="&evax_alpha_vec",SELECT_ARCHITECTURES="&bfd_alpha_arch","unlink=remove") +CFLAGS=/include=([],[-.include])$(DEFS) +else +DEFS=/define=(DEFAULT_VECTOR="evax_alpha_vec",SELECT_VECS="&evax_alpha_vec",\ +SELECT_ARCHITECTURES="&bfd_alpha_arch","unlink=remove","const=",\ +"_bfd_generic_get_section_contents_in_window"="_bfd_generic_get_win_section_cont",\ +"_bfd_elf_section_from_bfd_section"="_bfd_elf_sec_from_bfd_sec") +CFLAGS=/noopt/debug/include=([],[-.include])$(DEFS)/warnings=disable=(missingreturn,implicitfunc) +endif + + +libbfd.olb: sysdep.h bfd.h $(OBJS) + purge + lib/create libbfd $(OBJS) + +sysdep.h: [.hosts]alphavms.h config.h + $(CP) $< $@ + +bfd.h: bfd.h-vms + $(CP) $< $@ + +config.h: config.h-vms + $(CP) $< $@ + +evax-alpha.c: evax.h +evax-emh.c: evax.h +evax-egsd.c: evax.h +evax-etir.c: evax.h +evax-misc.c: evax.h diff --git a/gnu/usr.bin/binutils/bfd/netbsd.h b/gnu/usr.bin/binutils/bfd/netbsd.h index dd73d37e789..f47400a8fd9 100644 --- a/gnu/usr.bin/binutils/bfd/netbsd.h +++ b/gnu/usr.bin/binutils/bfd/netbsd.h @@ -65,6 +65,17 @@ MY(write_object_contents) (abfd) struct external_exec exec_bytes; struct internal_exec *execp = exec_hdr (abfd); + /* We must make certain that the magic number has been set. This + will normally have been done by set_section_contents, but only if + there actually are some section contents. */ + if (! abfd->output_has_begun) + { + bfd_size_type text_size; + file_ptr text_end; + + NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); + } + #if CHOOSE_RELOC_SIZE CHOOSE_RELOC_SIZE(abfd); #else diff --git a/gnu/usr.bin/binutils/bfd/som.h b/gnu/usr.bin/binutils/bfd/som.h index 6290e88f948..cbfa0b33489 100644 --- a/gnu/usr.bin/binutils/bfd/som.h +++ b/gnu/usr.bin/binutils/bfd/som.h @@ -211,6 +211,8 @@ struct som_section_data_struct #define R_HPPA_COMPLEX R_COMP1 #define R_HPPA_BEGIN_BRTAB R_BEGIN_BRTAB #define R_HPPA_END_BRTAB R_END_BRTAB +#define R_HPPA_BEGIN_TRY R_BEGIN_TRY +#define R_HPPA_END_TRY R_END_TRY /* Exported functions, mostly for use by GAS. */ boolean bfd_som_set_section_attributes PARAMS ((asection *, int, int, @@ -220,5 +222,6 @@ boolean bfd_som_set_subsection_attributes PARAMS ((asection *, asection *, void bfd_som_set_symbol_type PARAMS ((asymbol *, unsigned int)); boolean bfd_som_attach_aux_hdr PARAMS ((bfd *, int, char *)); int ** hppa_som_gen_reloc_type - PARAMS ((bfd *, int, int, enum hppa_reloc_field_selector_type_alt, int)); + PARAMS ((bfd *, int, int, enum hppa_reloc_field_selector_type_alt, + int, asymbol *)); #endif /* _SOM_H */ diff --git a/gnu/usr.bin/binutils/bfd/stabs.c b/gnu/usr.bin/binutils/bfd/stabs.c index 26508976a59..a79216ca03d 100644 --- a/gnu/usr.bin/binutils/bfd/stabs.c +++ b/gnu/usr.bin/binutils/bfd/stabs.c @@ -199,9 +199,8 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo) if (*psinfo == NULL) { /* Initialize the stabs information we need to keep track of. */ - *psinfo = ((struct stab_info *) - bfd_alloc (abfd, sizeof (struct stab_info))); - sinfo = *psinfo; + *psinfo = (PTR) bfd_alloc (abfd, sizeof (struct stab_info)); + sinfo = (struct stab_info *) *psinfo; sinfo->strings = _bfd_stringtab_init (); if (sinfo->strings == NULL) goto error_return; diff --git a/gnu/usr.bin/binutils/binutils/TODO b/gnu/usr.bin/binutils/binutils/TODO index 7953c6122e6..1433a9cc808 100644 --- a/gnu/usr.bin/binutils/binutils/TODO +++ b/gnu/usr.bin/binutils/binutils/TODO @@ -1,12 +1,7 @@ -o - size - Currently assumes that the only relevant sections are named .text, - .data and either .bss or .stack. This is not very general, and it - doesn't work for ECOFF. - o - strip Make faster by using ftruncate if available (and format is suitable). -o - nm, objdump +o - objdump Add option to demangle C++ names. o - nm, BFD @@ -15,6 +10,4 @@ o - nm, BFD o - See also ../ld/TODO and ../bfd/TODO. -o - ar q is flakey: e.g., doesn't handle long file names properly. - o - objdump -d: Print relocatable addresses intelligently. diff --git a/gnu/usr.bin/binutils/binutils/ar.c b/gnu/usr.bin/binutils/binutils/ar.c index abb5b24809f..ca5487de2fe 100644 --- a/gnu/usr.bin/binutils/binutils/ar.c +++ b/gnu/usr.bin/binutils/binutils/ar.c @@ -518,7 +518,8 @@ main (argc, argv) } #endif - arch = open_inarch (inarch_filename); + arch = open_inarch (inarch_filename, + files == NULL ? (char *) NULL : files[0]); switch (operation) { @@ -565,18 +566,24 @@ main (argc, argv) } bfd * -open_inarch (archive_filename) +open_inarch (archive_filename, file) const char *archive_filename; + const char *file; { + const char *target; bfd **last_one; bfd *next_one; struct stat sbuf; bfd *arch; + char **matching; bfd_set_error (bfd_error_no_error); + target = NULL; + if (stat (archive_filename, &sbuf) != 0) { + bfd *obj; #ifndef __GO32__ @@ -596,23 +603,42 @@ open_inarch (archive_filename) return NULL; } + /* Try to figure out the target to use for the archive from the + first object on the list. */ + obj = bfd_openr (file, NULL); + if (obj != NULL) + { + if (bfd_check_format (obj, bfd_object)) + target = bfd_get_target (obj); + (void) bfd_close (obj); + } + /* Create an empty archive. */ - arch = bfd_openw (archive_filename, NULL); + arch = bfd_openw (archive_filename, target); if (arch == NULL || ! bfd_set_format (arch, bfd_archive) || ! bfd_close (arch)) bfd_fatal (archive_filename); } - arch = bfd_openr (archive_filename, NULL); + arch = bfd_openr (archive_filename, target); if (arch == NULL) { bloser: bfd_fatal (archive_filename); } - if (bfd_check_format (arch, bfd_archive) != true) - fatal ("%s is not an archive", archive_filename); + if (! bfd_check_format_matches (arch, bfd_archive, &matching)) + { + bfd_nonfatal (archive_filename); + if (bfd_get_error () == bfd_error_file_ambiguously_recognized) + { + list_matching_formats (matching); + free (matching); + } + xexit (1); + } + last_one = &(arch->next); /* Read all the contents right away, regardless. */ for (next_one = bfd_openr_next_archived_file (arch, NULL); @@ -1178,7 +1204,7 @@ ranlib_only (archname) bfd *arch; write_armap = 1; - arch = open_inarch (archname); + arch = open_inarch (archname, (char *) NULL); if (arch == NULL) xexit (1); write_archive (arch); @@ -1196,6 +1222,7 @@ ranlib_touch (archname) #else int f; bfd *arch; + char **matching; f = open (archname, O_RDWR, 0); if (f < 0) @@ -1205,9 +1232,18 @@ ranlib_touch (archname) } arch = bfd_fdopenr (archname, (const char *) NULL, f); - if (arch == NULL - || ! bfd_check_format (arch, bfd_archive)) + if (arch == NULL) bfd_fatal (archname); + if (! bfd_check_format_matches (arch, bfd_archive, &matching)) + { + bfd_nonfatal (archname); + if (bfd_get_error () == bfd_error_file_ambiguously_recognized) + { + list_matching_formats (matching); + free (matching); + } + xexit (1); + } if (! bfd_has_map (arch)) fatal ("%s: no archive map to update", archname); diff --git a/gnu/usr.bin/binutils/binutils/arsup.h b/gnu/usr.bin/binutils/binutils/arsup.h index f94909e6ccb..f54a34bcf35 100644 --- a/gnu/usr.bin/binutils/binutils/arsup.h +++ b/gnu/usr.bin/binutils/binutils/arsup.h @@ -62,7 +62,7 @@ void ar_extract PARAMS ((struct list *)); bfd * -open_inarch PARAMS ((const char *archive_filename)); +open_inarch PARAMS ((const char *archive_filename, const char *)); int yyparse PARAMS ((void)); diff --git a/gnu/usr.bin/binutils/binutils/config.h-vms b/gnu/usr.bin/binutils/binutils/config.h-vms new file mode 100644 index 00000000000..5c42f6b4a40 --- /dev/null +++ b/gnu/usr.bin/binutils/binutils/config.h-vms @@ -0,0 +1,46 @@ +/* config.h. Generated automatically by configure. */ +/* config.in. Generated automatically from configure.in by autoheader. */ + +/* Is the type time_t defined in ? */ +#define HAVE_TIME_T_IN_TIME_H 1 + +/* Is the type time_t defined in ? */ +#define HAVE_TIME_T_IN_TYPES_H 1 + +/* Does define struct utimbuf? */ +#define HAVE_GOOD_UTIME_H 1 + +/* Whether fprintf must be declared even if is included. */ +#define NEED_DECLARATION_FPRINTF 1 + +/* Do we need to use the b modifier when opening binary files? */ +/* #undef USE_BINARY_FOPEN */ + +/* Define if you have the sbrk function. */ +/* #undef HAVE_SBRK */ + +/* Define if you have the utimes function. */ +#define HAVE_UTIMES 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +#if __GNUC__ +#define _bfd_generic_get_section_contents_in_window _bfd_generic_get_win_section_cont +#define _elf_section_from_bfd_section _bfd_elf_sec_from_bfd_sec +#endif diff --git a/gnu/usr.bin/binutils/binutils/debug.c b/gnu/usr.bin/binutils/binutils/debug.c index f508922edd8..2442cf99d54 100644 --- a/gnu/usr.bin/binutils/binutils/debug.c +++ b/gnu/usr.bin/binutils/binutils/debug.c @@ -1955,7 +1955,7 @@ debug_name_type (handle, name, type) if (info->current_unit == NULL || info->current_file == NULL) { - debug_error ("debug_record_variable: no current file"); + debug_error ("debug_name_type: no current file"); return false; } diff --git a/gnu/usr.bin/binutils/binutils/ieee.c b/gnu/usr.bin/binutils/binutils/ieee.c index 1ed3315645f..5476368007e 100644 --- a/gnu/usr.bin/binutils/binutils/ieee.c +++ b/gnu/usr.bin/binutils/binutils/ieee.c @@ -154,6 +154,8 @@ struct ieee_info const bfd_byte *pend; /* The block stack. */ struct ieee_blockstack blockstack; + /* Whether we have seen a BB1 or BB2. */ + boolean saw_filename; /* The variables. */ struct ieee_vars vars; /* The global variables, after a global typedef block. */ @@ -893,6 +895,7 @@ parse_ieee (dhandle, abfd, bytes, len) info.bytes = bytes; info.pend = bytes + len; info.blockstack.bsp = info.blockstack.stack; + info.saw_filename = false; info.vars.alloc = 0; info.vars.vars = NULL; info.types.alloc = 0; @@ -1001,6 +1004,17 @@ parse_ieee_bb (info, pp) return false; if (! debug_set_filename (info->dhandle, namcopy)) return false; + info->saw_filename = true; + + /* Discard any variables or types we may have seen before. */ + if (info->vars.vars != NULL) + free (info->vars.vars); + info->vars.vars = NULL; + info->vars.alloc = 0; + if (info->types.types != NULL) + free (info->types.types); + info->types.types = NULL; + info->types.alloc = 0; break; case 2: @@ -1008,6 +1022,7 @@ parse_ieee_bb (info, pp) empty, but we don't check. */ if (! debug_set_filename (info->dhandle, "*global*")) return false; + info->saw_filename = true; break; case 3: @@ -1147,8 +1162,8 @@ parse_ieee_bb (info, pp) break; case 10: - /* BB10: Assembler module scope. We completely ignore all this - information. FIXME. */ + /* BB10: Assembler module scope. In the normal case, we + completely ignore all this information. FIXME. */ { const char *inam, *vstr; unsigned long inamlen, vstrlen; @@ -1156,6 +1171,16 @@ parse_ieee_bb (info, pp) boolean present; unsigned int i; + if (! info->saw_filename) + { + namcopy = savestring (name, namlen); + if (namcopy == NULL) + return false; + if (! debug_set_filename (info->dhandle, namcopy)) + return false; + info->saw_filename = true; + } + if (! ieee_read_id (info, pp, &inam, &inamlen) || ! ieee_read_number (info, pp, &tool_type) || ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present)) @@ -1818,16 +1843,31 @@ parse_ieee_ty (info, pp) case 'g': /* Bitfield type. */ { - bfd_vma signedp, bitsize; + bfd_vma signedp, bitsize, dummy; + const bfd_byte *hold; + boolean present; if (! ieee_read_number (info, pp, &signedp) - || ! ieee_read_number (info, pp, &bitsize) - || ! ieee_read_type_index (info, pp, &type)) + || ! ieee_read_number (info, pp, &bitsize)) return false; - /* FIXME: This is just a guess. */ - if (! signedp) - type = debug_make_int_type (dhandle, 4, true); + /* I think the documentation says that there is a type index, + but some actual files do not have one. */ + hold = *pp; + if (! ieee_read_optional_number (info, pp, &dummy, &present)) + return false; + if (! present) + { + /* FIXME: This is just a guess. */ + type = debug_make_int_type (dhandle, 4, + signedp ? false : true); + } + else + { + *pp = hold; + if (! ieee_read_type_index (info, pp, &type)) + return false; + } type_bitsize = bitsize; } break; @@ -5366,7 +5406,10 @@ ieee_enum_type (p, tag, names, vals) } if ((names == NULL && e->names == NULL) - || (names[i] == NULL && e->names[i] == NULL)) + || (names != NULL + && e->names != NULL + && names[i] == NULL + && e->names[i] == NULL)) { /* We've seen this enum before. */ return ieee_push_type (info, e->indx, 0, true, false); diff --git a/gnu/usr.bin/binutils/binutils/makefile.vms b/gnu/usr.bin/binutils/binutils/makefile.vms new file mode 100644 index 00000000000..a3b0d60985e --- /dev/null +++ b/gnu/usr.bin/binutils/binutils/makefile.vms @@ -0,0 +1,67 @@ +# +# Makefile for binutils under openVMS/AXP +# +# For use with gnu-make for vms +# +# Created by Klaus Kämpf, kkaempf@progis.de +# +# + +CC=gcc + +ifeq ($(CC),gcc) +CFLAGS=/include=([],[-.include],[-.bfd])$(DEFS) +DEFS=/define=("unlink=remove") +LIBS=,GNU_CC:[000000]LIBGCC2/lib,GNU_CC:[000000]LIBGCCLIB/lib,sys$$library:vaxcrtl.olb/lib,GNU_CC:[000000]crt0.obj +else +CFLAGS=/noopt/debug/include=([],[-.include],[-.bfd])$(DEFS)/warnings=disable=(missingreturn,implicitfunc) +DEFS=/define=("const=","unlink=remove",\ +"_bfd_generic_get_section_contents_in_window"="_bfd_generic_get_win_section_cont",\ +"_bfd_elf_section_from_bfd_section"="_bfd_elf_sec_from_bfd_sec") +LIBS=,sys$$library:vaxcrtl.olb/lib +endif + +BFDLIB = [-.bfd]libbfd.olb/lib +BFDLIB_DEP = [-.bfd]libbfd.olb +LIBIBERTY_DEP = [-.libiberty]libiberty.olb +LIBIBERTY = [-.libiberty]libiberty.olb/lib +OPCODES_DEP = [-.opcodes]libopcodes.olb +OPCODES = [-.opcodes]libopcodes.olb/lib + +DEBUG_OBJS = rddbg.obj,debug.obj,stabs.obj,ieee.obj,rdcoff.obj + +WRITE_DEBUG_OBJS = $(DEBUG_OBJS),wrstabs.obj + +BULIBS = []bucomm.obj,version.obj,filemode.obj + +ADDL_DEPS = $(BULIBS),$(BFDLIB_DEP),$(LIBIBERTY_DEP) +ADDL_LIBS = $(BULIBS),$(BFDLIB),$(LIBIBERTY) + +SIZEOBJS = $(ADDL_DEPS),size.obj + +STRINGSOBJS = $(ADDL_DEPS),strings.obj + +NMOBJS = $(ADDL_DEPS),nm.obj + +OBJDUMPOBJS = $(ADDL_DEPS),objdump.obj,prdbg.obj,$(DEBUG_OBJS),$(OPCODES_DEP) + +all: config.h size.exe strings.exe objdump.exe nm.exe + +size.exe: $(SIZEOBJS) + link/exe=$@ size.obj,$(ADDL_LIBS)$(LIBS) + +strings.exe: $(STRINGSOBJS) + link/exe=$@ strings.obj,$(ADDL_LIBS)$(LIBS) + +nm.exe: $(NMOBJS) + link/exe=$@ nm.obj,$(ADDL_LIBS)$(LIBS) + +objdump.exe: $(OBJDUMPOBJS) + link/exe=$@ objdump.obj,prdbg.obj,$(DEBUG_OBJS),$(BFDLIB),$(OPCODES),$(ADDL_LIBS)$(LIBS) + + +version.obj: version.c + $(CC) $(CFLAGS)/define=(VERSION="""960723""") $< + +config.h: config.h-vms + $(CP) $< $@ diff --git a/gnu/usr.bin/binutils/binutils/nm.1 b/gnu/usr.bin/binutils/binutils/nm.1 index 13681bea9a7..c2ad99e559a 100644 --- a/gnu/usr.bin/binutils/binutils/nm.1 +++ b/gnu/usr.bin/binutils/binutils/nm.1 @@ -27,6 +27,7 @@ nm \- list symbols from object files. .RB "[\|" \-r | \-\-reverse\-sort "\|]" .RB "[\|" \-\-size\-sort "\|]" .RB "[\|" \-u | \-\-undefined\-only "\|]" +.RB "[\|" \-l | \-\-line\-numbers "\|]" .RB "[\|" \-\-help "\|]" .RB "[\|" \-\-version "\|]" .RB "[\|" "\-t \fIradix" | \-\-radix=\fIradix "\|]" @@ -172,6 +173,16 @@ for information on listing available formats. .B \-\-undefined\-only Display only undefined symbols (those external to each object file). +.TP +.B \-l +.TP +.B \-\-line\-numbers +For each symbol, use debugging information to try to find a filename and +line number. For a defined symbol, look for the line number of the +address of the symbol. For an undefined symbol, look for the line +number of a relocation entry which refers to the symbol. If line number +information can be found, print it after the other symbol information. + .TP .B \-V .TP diff --git a/gnu/usr.bin/binutils/binutils/prdbg.c b/gnu/usr.bin/binutils/binutils/prdbg.c index d82791b524b..958cbd2c6bf 100644 --- a/gnu/usr.bin/binutils/binutils/prdbg.c +++ b/gnu/usr.bin/binutils/binutils/prdbg.c @@ -1007,6 +1007,9 @@ pr_fix_visibility (info, visibility) case DEBUG_VISIBILITY_PROTECTED: s = "protected"; break; + case DEBUG_VISIBILITY_IGNORE: + s = "/* ignore */"; + break; default: abort (); return false; @@ -1092,7 +1095,7 @@ pr_end_struct_type (p) /* Change the trailing indentation to have a close brace. */ s = info->stack->type + strlen (info->stack->type) - 2; - assert (strcmp (s, " ") == 0); + assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0'); *s++ = '}'; *s = '\0'; diff --git a/gnu/usr.bin/binutils/binutils/rdcoff.c b/gnu/usr.bin/binutils/binutils/rdcoff.c index 9f7660b278e..287b3cc4b1f 100644 --- a/gnu/usr.bin/binutils/binutils/rdcoff.c +++ b/gnu/usr.bin/binutils/binutils/rdcoff.c @@ -199,6 +199,12 @@ parse_coff_type (abfd, symbols, types, coff_symno, ntype, pauxent, useaux, NULL, dhandle), 0, n - 1, false); } + else + { + fprintf (stderr, "%s: parse_coff_type: Bad type code 0x%x\n", + program_name, ntype); + return DEBUG_TYPE_NULL; + } return type; } @@ -668,6 +674,7 @@ parse_coff (abfd, syms, symcount, dhandle) const char *fnname; int fnclass; int fntype; + bfd_vma fnend; alent *linenos; boolean within_function; long this_coff_symno; @@ -685,6 +692,7 @@ parse_coff (abfd, syms, symcount, dhandle) fnname = NULL; fnclass = 0; fntype = 0; + fnend = 0; linenos = NULL; within_function = false; @@ -766,6 +774,10 @@ parse_coff (abfd, syms, symcount, dhandle) fnname = name; fnclass = syment.n_sclass; fntype = syment.n_type; + if (syment.n_numaux > 0) + fnend = bfd_asymbol_value (sym) + auxent.x_sym.x_misc.x_fsize; + else + fnend = 0; linenos = BFD_SEND (abfd, _get_lineno, (abfd, sym)); break; } @@ -838,9 +850,12 @@ parse_coff (abfd, syms, symcount, dhandle) return false; } - if (! debug_end_function (dhandle, bfd_asymbol_value (sym))) + if (bfd_asymbol_value (sym) > fnend) + fnend = bfd_asymbol_value (sym); + if (! debug_end_function (dhandle, fnend)) return false; + fnend = 0; within_function = false; } break; diff --git a/gnu/usr.bin/binutils/binutils/rddbg.c b/gnu/usr.bin/binutils/binutils/rddbg.c index d14c40df6c3..53548a28923 100644 --- a/gnu/usr.bin/binutils/binutils/rddbg.c +++ b/gnu/usr.bin/binutils/binutils/rddbg.c @@ -270,6 +270,7 @@ read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound) *pfound = true; s = i.name; + f = NULL; while (s[strlen (s) - 1] == '\\' && ps + 1 < symend) { diff --git a/gnu/usr.bin/binutils/binutils/stabs.c b/gnu/usr.bin/binutils/binutils/stabs.c index af43fea303d..24d89cc9bb9 100644 --- a/gnu/usr.bin/binutils/binutils/stabs.c +++ b/gnu/usr.bin/binutils/binutils/stabs.c @@ -588,10 +588,27 @@ parse_stab (dhandle, handle, type, desc, value, string) return false; break; + case N_FUN: + if (*string == '\0') + { + if (info->within_function) + { + if (info->sections) + value += info->function_start_offset; + if (! stab_emit_pending_vars (dhandle, info) + || ! debug_end_function (dhandle, value)) + return false; + info->within_function = false; + } + break; + } + + /* Fall through. */ /* FIXME: gdb checks the string for N_STSYM, N_LCSYM or N_ROSYM symbols, and if it does not start with :S, gdb relocates the value to the start of the section. gcc always seems to use :S, so we don't worry about this. */ + /* Fall through. */ default: { const char *colon; @@ -2666,6 +2683,7 @@ parse_stab_members (dhandle, info, tagname, pp, typenums, retp) if (**pp == ':') { /* g++ version 1 overloaded methods. */ + context = DEBUG_TYPE_NULL; } else { @@ -4222,7 +4240,7 @@ stab_demangle_template (minfo, pp) done = true; break; default: - /* Assume it's a uder defined integral type. */ + /* Assume it's a user defined integral type. */ integralp = true; done = true; break; @@ -4923,7 +4941,20 @@ stab_demangle_fund_type (minfo, pp, ptype) case 't': if (! stab_demangle_template (minfo, pp)) return false; - abort (); + if (ptype != NULL) + { + debug_type t; + + /* FIXME: I really don't know how a template should be + represented in the current type system. Perhaps the + template should be demangled into a string, and the type + should be represented as a named type. However, I don't + know what the base type of the named type should be. */ + t = debug_make_void_type (minfo->dhandle); + t = debug_make_pointer_type (minfo->dhandle, t); + t = debug_name_type (minfo->dhandle, "TEMPLATE", t); + *ptype = t; + } break; default: diff --git a/gnu/usr.bin/binutils/binutils/strip.1 b/gnu/usr.bin/binutils/binutils/strip.1 index 7ecadaa1fd8..5b47414cd29 100644 --- a/gnu/usr.bin/binutils/binutils/strip.1 +++ b/gnu/usr.bin/binutils/binutils/strip.1 @@ -25,7 +25,8 @@ strip \- Discard symbols from object files. .RB "[\|" \-x\fR\ |\ \fB\-\-discard\-all "\|]" .RB "[\|" \-X\fR\ |\ \fB\-\-discard\-locals "\|]" .RB "[\|" \-K\ \fIsymbolname\fR\ |\ \fB\-\-keep\-symbol=\fIsymbolname\fR "\|]" -.RB "[\|" \-N\ \fIsymbolname\fR\ |\ \fB\-\-strip\-symbol=\fIsymbolname\fR "\|]" +.RB "[\|" \-N\ \fIsymbolname\fR\ |\ \fB\-\-strip\-symbol=\fIsymbolname\fR "\|]" +.RB "[\|" \-o\ \fIfile\f\R "\|]" .RB "[\|" \-v\fR\ |\ \fB\-\-verbose "\|]" .RB "[\|" \-V\fR\ |\ \fB\-\-version "\|]" .RB "[\|" \-V\fR\ |\ \fB\-\-help "\|]" @@ -106,6 +107,12 @@ Remove symbol \fIsymbolname\fP from the source file. This option may be given more than once, and may be combined with other strip options. +.TP +.B \-o \fIfile\fR +Put the stripped output in \fIfile\fR, rather than replacing the +existing file. When this argument is used, only one \fIobjfile\fR +argument may be specified. + .TP .B \-x .TP diff --git a/gnu/usr.bin/binutils/binutils/wrstabs.c b/gnu/usr.bin/binutils/binutils/wrstabs.c index a4a7293c6a3..260104bbd29 100644 --- a/gnu/usr.bin/binutils/binutils/wrstabs.c +++ b/gnu/usr.bin/binutils/binutils/wrstabs.c @@ -47,6 +47,8 @@ struct string_hash_entry { struct bfd_hash_entry root; + /* Next string in this table. */ + struct string_hash_entry *next; /* Index in string table. */ long index; /* Size of type if this is a typedef. */ @@ -139,10 +141,12 @@ struct stab_write_handle bfd_byte *symbols; size_t symbols_size; size_t symbols_alloc; - /* This buffer holds the strings. */ - bfd_byte *strings; + /* This is a list of hash table entries for the strings. */ + struct string_hash_entry *strings; + /* The last string hash table entry. */ + struct string_hash_entry *last_string; + /* The size of the strings. */ size_t strings_size; - size_t strings_alloc; /* This hash table eliminates duplicate strings. */ struct string_hash_table strhash; /* The type stack. */ @@ -323,6 +327,7 @@ string_hash_newfunc (entry, table, string) if (ret) { /* Initialize the local fields. */ + ret->next = NULL; ret->index = -1; ret->size = 0; } @@ -355,7 +360,7 @@ stab_write_symbol (info, type, desc, value, string) { struct string_hash_entry *h; - h = string_hash_lookup (&info->strhash, string, true, false); + h = string_hash_lookup (&info->strhash, string, true, true); if (h == NULL) { fprintf (stderr, "string_hash_lookup failed: %s\n", @@ -366,20 +371,14 @@ stab_write_symbol (info, type, desc, value, string) strx = h->index; else { - size_t len; - strx = info->strings_size; h->index = strx; - - len = strlen (string); - while (info->strings_size + len + 1 > info->strings_alloc) - { - info->strings_alloc *= 2; - info->strings = (bfd_byte *) xrealloc (info->strings, - info->strings_alloc); - } - strcpy (info->strings + info->strings_size, string); - info->strings_size += len + 1; + if (info->last_string == NULL) + info->strings = h; + else + info->last_string->next = h; + info->last_string = h; + info->strings_size += strlen (string) + 1; } } @@ -489,6 +488,8 @@ write_stabs_in_sections_debugging_info (abfd, dhandle, psyms, psymsize, bfd_size_type *pstringsize; { struct stab_write_handle info; + struct string_hash_entry *h; + bfd_byte *p; info.abfd = abfd; @@ -496,10 +497,10 @@ write_stabs_in_sections_debugging_info (abfd, dhandle, psyms, psymsize, info.symbols_alloc = 500; info.symbols = (bfd_byte *) xmalloc (info.symbols_alloc); + info.strings = NULL; + info.last_string = NULL; + /* Reserve 1 byte for a null byte. */ info.strings_size = 1; - info.strings_alloc = 500; - info.strings = (bfd_byte *) xmalloc (info.strings_alloc); - info.strings[0] = '\0'; if (! bfd_hash_table_init (&info.strhash.table, string_hash_newfunc) || ! bfd_hash_table_init (&info.typedef_hash.table, string_hash_newfunc)) @@ -544,8 +545,16 @@ write_stabs_in_sections_debugging_info (abfd, dhandle, psyms, psymsize, *psyms = info.symbols; *psymsize = info.symbols_size; - *pstrings = info.strings; *pstringsize = info.strings_size; + *pstrings = (bfd_byte *) xmalloc (info.strings_size); + + p = *pstrings; + *p++ = '\0'; + for (h = info.strings; h != NULL; h = h->next) + { + strcpy (p, h->root.string); + p += strlen (p) + 1; + } return true; } @@ -922,12 +931,14 @@ stab_modify_type (info, mod, size, cache, cache_alloc) } index = (*cache)[targindex]; - if (index != 0) + if (index != 0 && ! info->type_stack->definition) { - /* If we have already defined a modification of this type, - then the entry on the type stack can not be a definition, - so we can safely discard it. */ - assert (! info->type_stack->definition); + /* We have already defined a modification of this type, and + the entry on the type stack is not a definition, so we + can safely discard it (we may have a definition on the + stack, even if we already defined a modification, if it + is a struct which we did not define at the time it was + referenced). */ free (stab_pop_type (info)); if (! stab_push_defined_type (info, index, size)) return false; @@ -1092,7 +1103,7 @@ stab_array_type (p, low, high, stringp) free (range); free (element); - if (high <= low) + if (high < low) size = 0; else size = element_size * ((high - low) + 1); diff --git a/gnu/usr.bin/binutils/config/mh-cygwin32 b/gnu/usr.bin/binutils/config/mh-cygwin32 new file mode 100644 index 00000000000..a798f8b0609 --- /dev/null +++ b/gnu/usr.bin/binutils/config/mh-cygwin32 @@ -0,0 +1,6 @@ +# We set MAKEINFOFLAGS to not split .info files, because the resulting +# file names don't work on DOS. +MAKEINFOFLAGS=--no-split + +# custom installation rules for cygwin32 (append .exe to binaries, etc.) +INSTALL_DOSREL=install-dosrel diff --git a/gnu/usr.bin/binutils/config/mh-irix4 b/gnu/usr.bin/binutils/config/mh-irix4 index a48334c72f5..6872145e833 100644 --- a/gnu/usr.bin/binutils/config/mh-irix4 +++ b/gnu/usr.bin/binutils/config/mh-irix4 @@ -5,4 +5,3 @@ CC = cc -cckr -Wf,-XNg1500 -Wf,-XNk1000 -Wf,-XNh2000 -Wf,-XNl8192 SYSV = -DSYSV -RANLIB = true diff --git a/gnu/usr.bin/binutils/config/mh-irix6 b/gnu/usr.bin/binutils/config/mh-irix6 new file mode 100644 index 00000000000..6d25c16b2f4 --- /dev/null +++ b/gnu/usr.bin/binutils/config/mh-irix6 @@ -0,0 +1,7 @@ +# Makefile changes for SGI's running IRIX-6.x. +SYSV = -DSYSV +RANLIB = true +# Specify the ABI, to ensure that all Irix 6 systems will behave the same. +# Also, using -32 avoids bugs that exist in the n32/n64 support in some +# versions of the SGI compiler. +CC = cc -32 diff --git a/gnu/usr.bin/binutils/config/mpw/ChangeLog b/gnu/usr.bin/binutils/config/mpw/ChangeLog new file mode 100644 index 00000000000..242ad0ffed0 --- /dev/null +++ b/gnu/usr.bin/binutils/config/mpw/ChangeLog @@ -0,0 +1,45 @@ +Thu Aug 15 19:49:23 1996 Stan Shebs + + * true: New script, identical to mpw-true. + * g-mpw-make.sed: Add @DASH_C_FLAG@ and @SEGMENT_FLAG()@ + to the editors for compile commands. + +Thu Aug 1 15:01:42 1996 Stan Shebs + + * mpw-true, mpw-touch, null-command: New scripts. + * README: Describe usage in more detail. + +Tue Dec 12 14:51:51 1995 Stan Shebs + + * g-mpw-make.sed: Don't edit out "version=" occurrences. + +Fri Dec 1 11:46:18 1995 Stan Shebs + + * g-mpw-make.sed (bindir, libdir): Edit the positions of + pathname separators to work with other pathnames better. + +Tue Nov 7 15:08:07 1995 Stan Shebs + + * g-mpw-make.sed: Add comment about Duplicate vs Catenate, + add additional pattern for editing link-compile commands. + +Tue Oct 24 14:28:51 1995 Stan Shebs + + * g-mpw-make.sed: Add handling for *.tab.[hc] files. + (CHILL_FOR_TARGET, CHILL_LIB): Edit out tricky definitions + of these. + +Thu Sep 28 21:05:10 1995 Stan Shebs + + * g-mpw-make.sed: New file, generic sed commands to translate + Unix makefiles into MPW makefile syntax. + +Fri Mar 17 11:51:20 1995 Stan Shebs + + * README: Clarify instructions. + * fi: Remove. + +Wed Dec 21 15:45:53 1994 Stan Shebs + + * MoveIfChange, README, fi, forward-include, open-brace, + tr-7to8-src: New files. diff --git a/gnu/usr.bin/binutils/config/mpw/MoveIfChange b/gnu/usr.bin/binutils/config/mpw/MoveIfChange new file mode 100644 index 00000000000..0dbc12582f5 --- /dev/null +++ b/gnu/usr.bin/binutils/config/mpw/MoveIfChange @@ -0,0 +1,19 @@ +# Rename a file only if it is different from a previously existing +# file of the same name. This is useful for keeping make from doing +# too much work if the contents of a file haven't changed. + +# This is an MPW translation of the standard GNU sh script move-if-change. + +Set exit 0 + +If "`exists -f "{2}"`" + Compare "{1}" "{2}" >dev:null + If {status} != 0 + Rename -y "{1}" "{2}" + Else + Echo "{2}" is unchanged + Delete -i -y "{1}" + End +Else + Rename -y "{1}" "{2}" +End diff --git a/gnu/usr.bin/binutils/config/mpw/README b/gnu/usr.bin/binutils/config/mpw/README new file mode 100644 index 00000000000..554700adc81 --- /dev/null +++ b/gnu/usr.bin/binutils/config/mpw/README @@ -0,0 +1,23 @@ +This directory contains MPW scripts and related files that are needed to +build Cygnus GNU tools for MPW. The scripts should be somewhere on the +command path; our usual practice has been to have a separate directory +for the scripts, and put the tools (byacc, flex, and sed at least) there +also; then it's easier to drag the support bits around as a group, or to +upgrade MPW versions. The complete package of scripts and tool binaries +is usually available as pub/mac/buildtools.cpt.hqx on ftp.cygnus.com. + +"tr-7to8-src" is actually the source to an MPW script that transforms +sequences like "\Option-d" into the actual 8-bit chars that MPW needs. +It's only the source because it can't itself include any 8-bit chars. +It *can* be processed into a genuine "tr-7to8" by using itself: + + tr-7to8 tr-7to8-src | sed -e 's/Src//' >new-tr-7to8 + +Use this to verify: + + compare tr-7to8 new-tr-7to8 + +If you don't have a working tr-7to8, then you will have to manually +replace all occurrences of "\Option-d" with real Option-d (which looks +like a delta), then do similarly with all the other "\Option-..." +strings, and then change "\SrcOption-d" into the string "\Option-d". diff --git a/gnu/usr.bin/binutils/config/mpw/forward-include b/gnu/usr.bin/binutils/config/mpw/forward-include new file mode 100644 index 00000000000..ddd6bd71105 --- /dev/null +++ b/gnu/usr.bin/binutils/config/mpw/forward-include @@ -0,0 +1,3 @@ +Echo '#include' ¶""{1}"¶" >"{2}".tem +MoveIfChange "{2}".tem "{2}" + diff --git a/gnu/usr.bin/binutils/config/mpw/g-mpw-make.sed b/gnu/usr.bin/binutils/config/mpw/g-mpw-make.sed new file mode 100644 index 00000000000..201196306a0 --- /dev/null +++ b/gnu/usr.bin/binutils/config/mpw/g-mpw-make.sed @@ -0,0 +1,290 @@ +# Sed commands to translate Unix makefiles into MPW makefiles. +# These are nominally generic, but work best on the makefiles used +# for GNU programs. + +# Whack out any commented-out lines that are probably commands; +# they can only cause trouble later on. +/^# /d + +# Change dependency char. +/:$/s/:/ \\Option-f/g +/^[^ :#][^:]*:/s/\([ ]*\):\([ ]*\)/ \\Option-f /g + +# Change syntax of Makefile vars. +/\$/s/\${\([a-zA-Z0-9_-]*\)}/{\1}/g +/\$/s/\$(\([a-zA-Z0-9_-]*\))/{\1}/g +/ $@/s/ $@/ {Targ}/ + +# Double-$ are literals to Unix but not to MPW make. +/\$\$/s/\$\$/$/g + +# Change pathname syntax. +/\//s,\.\./\/\.\./,:::,g +/\//s,\.\./,::,g +/\.\//s,\./,:,g +/\//s,/,:,g +# Undo excess changes. +/and/s,and:or$,and/or, +/and/s,and:or ,and/or , +/want/s,want:need,want/need, +# Fixing up sed commands. +/-e/s_":\([^:]*\):d"_"/\1/d"_g +/-e/s_":\([^:]*\):,:\([^:]*\):d"_"/\1/,/\2/d"_g + +/=/s/ = \.$/ = :/ + +# Comment out any explicit srcdir setting. +/srcdir/s/^srcdir/# srcdir/ + +/BASEDIR/s/^BASEDIR =.*$/BASEDIR = "{srcroot}"/ +/{BASEDIR}:/s/{BASEDIR}:/{BASEDIR}/g +/{srcdir}:/s/{srcdir}:/"{srcdir}"/g +/"{srcdir}":/s/"{srcdir}":/"{srcdir}"/g + +# Tweak some conventions that are backwards for the Mac. +/bindir/s/{exec_prefix}:bin/{exec_prefix}bin:/ +/libdir/s/{exec_prefix}:lib/{exec_prefix}lib:/ + +# Comment out settings of anything set by mpw host config. +/CC/s/^CC *=/#CC =/ +/CFLAGS/s/^CFLAGS *=/#CFLAGS =/ +/AR/s/^AR *=/#AR =/ +/AR_FLAGS/s/^AR_FLAGS *=/#AR_FLAGS =/ +/RANLIB/s/^RANLIB *=/#RANLIB =/ +/CC_LD/s/^CC_LD *=/#CC_LD =/ +/LDFLAGS/s/^LDFLAGS *=/#LDFLAGS =/ + +# Change -I usages. (not for GCC) +/-I/s/-I\./-i :/g +/-I/s/-I::bfd/-i ::bfd:/g +/-I/s/-I::include/-i ::include:/g +/-I/s/-I/-i /g + +# Change -D usage. (not for GCC) +/-D/s/\([ =]\)-D\([^ ]*\)/\1-d \2/g + +# Change continuation char. +/\\$/s/\\$/\\Option-d/ + +# Change wildcard char. +/\*/s/\*/\\Option-x/g + +# Change path of various types of source files. This rule does not allow +# for file names with multiple dots in the name. +/\.[chly]/s/\([ ><=]\)\([-a-zA-Z0-9_${}:"]*\)\.\([chly]\)/\1"{s}"\2.\3/g +/\.[chly]/s/^\([-a-zA-Z0-9_${}:"]*\)\.\([chly]\)/"{s}"\1.\2/ +# Allow files named *.tab.[ch] as a special case. +/\.tab\.[ch]/s/\([ ><=]\)\([-a-zA-Z0-9_${}:"]*\.tab\)\.\([ch]\)/\1"{s}"\2.\3/g +/\.tab\.[ch]/s/^\([-a-zA-Z0-9_${}:"]*\.tab\)\.\([ch]\)/"{s}"\1.\2/ +# Fix some overenthusiasms. +/{s}/s/"{s}""{srcdir}"/"{srcdir}"/g +/{s}/s/"{s}"{\([a-zA-Z0-9_]*\)dir}/"{\1dir}"/g +/{s}/s/"{s}"{\([a-zA-Z0-9_]*\)DIR}/"{\1DIR}"/g +/{s}/s/"{s}""{\([a-zA-Z0-9_]*\)dir}"/"{\1dir}"/g +/{s}/s/"{s}""{\([a-zA-Z0-9_]*\)DIR}"/"{\1DIR}"/g +/{s}/s/"{s}":/:/g +/{s}/s/^"{s}"//g +/{s}/s/"{s}""{s}"/"{s}"/g +/{s}/s/"{s}""{srcdir}"/"{s}"/g +/{s}/s/"{srcdir}""{s}"/"{s}"/g + +# The .def files are also typically source files. +/\.def/s/\([ ><]\)\([-a-zA-Z0-9_${}:"]*\)\.def/\1"{s}"\2.def/g +/\.def/s/^\([-a-zA-Z0-9_${}:"]*\)\.def/"{s}"\1.def/g + +# Change extension and path of objects. +/\.o/s/\([ =]\)\([-a-zA-Z0-9_${}:"]*\)\.o/\1"{o}"\2.c.o/g +/\.o/s/^\([-a-zA-Z0-9_${}:"]*\)\.o/"{o}"\1.c.o/ +# Allow *.tab.o files as a special case of a 2-dot-name file. +/\.o/s/\([ =]\)\([-a-zA-Z0-9_${}:"]*\)\.tab\.o/\1"{o}"\2.tab.c.o/g +/\.o/s/^\([-a-zA-Z0-9_${}:"]*\)\.tab\.o/"{o}"\1.tab.c.o/ +# Clean up. +/"{o}"/s/"{o}""{o}"/"{o}"/g +/"{o}"/s/^"{o}"\([a-zA-Z0-9_]*\)=/\1=/ + +# Change extension of libs. +/\.a/s/lib\([a-z]*\)\.a/lib\1.o/g + +# Remove non-fail option. +/-/s/^\([ ]*\)-/\1/ +# Fix overeagernesses - assumes no one-letter commands. +/^[ ]*[a-z] /s/^\([ ]*\)\([a-z]\) /\1-\2 / + +# Remove non-echo option. (watch out for autoconf things) +/@/s/^\([ ]*\)@/\1/ + +# Change cp to Duplicate. +# Catenate is perhaps more accurate, but the pattern would have to +# identify the output file and add a '>' redirection into it. +/cp/s/^\([ ]*\)cp /\1Duplicate -d -y / +# Change mv to Rename. +/mv/s/^\([ ]*\)mv /\1Rename -y / +/Rename/s/^\([ ]*\)Rename -y -f/\1Rename -y/ +# Change rm to Delete. +/rm -rf/s/^\([ ]*\)rm -rf /\1Delete -i -y / +/rm -f/s/^\([ ]*\)rm -f /\1Delete -i -y / +/rm/s/^\([ ]*\)rm /\1Delete -i -y / +# Note that we don't mess with ln - directory-specific scripts +# must decide what to do with symlinks. +# Change cat to Catenate. +/cat/s/^\([ ]*\)cat /\1Catenate / +# Change touch to mpw-touch. +/touch/s/^\([ ]*\)touch /\1mpw-touch / +# Change mkdir to NewFolder. +/mkdir/s/^\([ ]*\)mkdir /\1NewFolder / +# Change var setting to Set. +/=/s/^\([ ]*\)\([-a-zA-Z0-9_]*\)=\([^;]*\); \\Option-d/\1Set \2 \3/ + +# Change tests. +/if /s/if \[ *-f \([^ ]*\) ] *; *\\Option-d/If "`Exists "\1"`" != ""/ +/if /s/if \[ *-f \([^ ]*\) ] *; *then *\\Option-d/If "`Exists "\1"`" != ""/ +/if /s/if \[ ! *-f \([^ ]*\) ] *; *\\Option-d/If "`Exists "\1"`" == ""/ +/if /s/if \[ ! *-f \([^ ]*\) ] *; *then \\Option-d/If "`Exists "\1"`" == ""/ + +/if /s/if \[ *-d \([^ ]*\) ] *; *\\Option-d/If "`Exists "\1"`" != ""/ +/if /s/if \[ *-d \([^ ]*\) ] *; *then *\\Option-d/If "`Exists "\1"`" != ""/ +/if /s/if \[ ! *-d \([^ ]*\) ] *; *\\Option-d/If "`Exists "\1"`" == ""/ +/if /s/if \[ ! *-d \([^ ]*\) ] *; *then *\\Option-d/If "`Exists "\1"`" == ""/ + +/if /s/if \[ -d \([^ ]*\) ] *; then true *; else mkdir \([^ ;]*\) *; fi/If "`Exists "\1"`" != "" NewFolder \2 End If/ + +/if /s/if \[ \([^ ]*\) = \([^ ]*\) ] *; *\\Option-d/If "\1" == "\2"/ +/if /s/if \[ \([^ ]*\) = \([^ ]*\) ] *; *then *\\Option-d/If "\1" == "\2"/ + +/if /s/if \[ \([^ ]*\) != \([^ ]*\) ] *; *\\Option-d/If "\1" != "\2"/ +/if /s/if \[ \([^ ]*\) != \([^ ]*\) ] *; *then *\\Option-d/If "\1" != "\2"/ + +/if /s/if \[ \([^ ]*\) -eq \([^ ]*\) ] *; *\\Option-d/If "\1" != "\2"/ +/if /s/if \[ \([^ ]*\) -eq \([^ ]*\) ] *; *then *\\Option-d/If "\1" != "\2"/ + +/^[ ]*else true$/c\ + Else\ + mpw-true\ + + +/else/s/^\([ ]*\)else[ ]*$/\1Else/ +/else/s/^\([ ]*\)else[; ]*\\Option-d$/\1Else/ + +/^[ ]*else[ ]*true[ ]*$/c\ + Else\ + mpw-true + +/^[ ]*else[ ]*true[; ]*fi$/c\ + Else\ + mpw-true\ + End If + +/fi/s/^\([ ]*\)fi *$/\1End/ +/fi/s/^\([ ]*\)fi *; *\\Option-d/\1End/ + +# Change looping. +/for/s/^\([ ]*\)for \([-a-zA-Z0-9_]*\) in \([^;]*\); *do *\\Option-d/\1For \2 In \3/ +/^\([ ]*\)do *\\Option-d/d +/done/s/^\([ ]*\)done *; *\\Option-d/\1End/ +/done/s/^\([ ]*\)done$/\1End/ + +# Trailing semicolons and continued lines are unneeded sh syntax. +/; \\Option-d/s/; \\Option-d// + +# Change move-if-change to MoveIfChange. +/move-if-change/s/\([^ ]*\)move-if-change/MoveIfChange/g + +# Change $(SHELL) to the script name by itself. +/SHELL/s/^\([ ]*\){SHELL} /\1/ + +# Change syntax of default rule dependency. +/^\.c\.o/s/^\.c\.o \\Option-f$/.c.o \\Option-f .c/ + +# Change default rule's action. +/{CC} -c/s/{CC} -c \(.*\) \$<$/{CC} @DASH_C_FLAG@ {DepDir}{Default}.c \1 @SEGMENT_FLAG({Default})@ -o {TargDir}{Default}.c.o/ + +# This is pretty disgusting, but I can't seem to detect empty rules. +/Option-f$/s/Option-f$/Option-f _oldest/g + +# Remove -c from explicit compiler calls. (but should not if GCC) +# Handle the case of a source file that is "{xxx}"file.c. +/ -c /s/{\([A-Z_]*\)CC}\(.*\) -c \(.*\)"\([^"]*\)"\([-a-z_]*\)\.c/{\1CC}\2 @DASH_C_FLAG@ \3"\4"\5.c -o "{o}"\5.c.o/ +# Handle the case of a source file that is "{xxx}"dir:file.c. +/ -c /s/{\([A-Z_]*\)CC}\(.*\) -c \(.*\)"\([^"]*\)"\([-a-z_]*\):\([-a-z_]*\)\.c/{\1CC}\2 @DASH_C_FLAG@ \3"\4"\5:\6.c -o "{o}"\6.c.o/ + +# Change linking cc to linking sequence. +/-o/s/^\([ ]*\){CC} \(.*\){\([A-Z_]*\)CFLAGS} \(.*\){LDFLAGS} \(.*\)-o \([^ ]*\) \(.*\)$/\1{CC_LD} \2 {\3CFLAGS} \4 {LDFLAGS} \5 -o \6{PROG_EXT} \7\ +\1{MAKEPEF} \6{PROG_EXT} -o \6 {MAKEPEF_TOOL_FLAGS} {MAKEPEF_FLAGS}\ +\1{REZ} "{s}"\6.r -o \6 -append -d PROG_NAME='"'\6'"' -d VERSION_STRING='"'{version}'"'/ +/-o/s/^\([ ]*\){CC} \(.*\){\([A-Z_]*\)CFLAGS} \(.*\)-o \([^ ]*\) \(.*\){LDFLAGS} \(.*\)$/\1{CC_LD} \2 {\3CFLAGS} \4 {LDFLAGS} \6 -o \5{PROG_EXT} \7\ +\1{MAKEPEF} \5{PROG_EXT} -o \5 {MAKEPEF_TOOL_FLAGS} {MAKEPEF_FLAGS}\ +\1{REZ} "{s}"\5.r -o \5 -append -d PROG_NAME='"'\5'"' -d VERSION_STRING='"'{version}'"'/ +/-o/s/^\([ ]*\){HOST_CC} \(.*\)-o \([^ ]*\) \(.*\)$/\1{HOST_CC_LD} \2 -o \3{PROG_EXT} \4\ +\1{MAKEPEF} \3{PROG_EXT} -o \3 {MAKEPEF_TOOL_FLAGS} {MAKEPEF_FLAGS}\ +\1{REZ} "{s}"\3.r -o \3 -append -d PROG_NAME='"'\3'"' -d VERSION_STRING='"'{version}'"'/ + +# Comment out .NOEXPORT rules. +/\.NOEXPORT/s/^\.NOEXPORT/#\.NOEXPORT/ +# Comment out .PHONY rules. +/\.PHONY/s/^\.PHONY/#\.PHONY/ +# Comment out .PRECIOUS rules. +/\.PRECIOUS/s/^\.PRECIOUS/#\.PRECIOUS/ +# Comment out .SUFFIXES rules. +/\.SUFFIXES/s/^\.SUFFIXES/#\.SUFFIXES/ + +# Set the install program appropriately. +/INSTALL/s/^INSTALL *= *`.*`:install.sh -c/INSTALL = Duplicate -y/ + +# Don't try to decide whether to use the tree's own tools. +/bison/s/`.*bison:bison.*`/bison -y/ +/byacc/s/`.*byacc:byacc.*`/byacc/ +/flex/s/`.*flex:flex.*`/flex/ + +# Turn transformed C comments in echo commands back into comments. +/echo/s,echo '\(.*\):\\Option-x\(.*\)\\Option-x:\(.*\)',echo '\1/*\2*/\3', + +# Whack out various clever expressions that search for tools, since +# the clever code is too /bin/sh specific. + +/^AR_FOR_TARGET = `/,/`$/c\ +AR_FOR_TARGET = ::binutils:ar\ + + +/^RANLIB_FOR_TARGET = `/,/`$/c\ +RANLIB_FOR_TARGET = ::binutils:ranlib\ + + +/^RANLIB_TEST_FOR_TARGET = /,/ranlib ] )$/c\ +RANLIB_TEST_FOR_TARGET = \ + + +/^EXPECT = `/,/`$/c\ +EXPECT = \ + + +/^RUNTEST = `/,/`$/c\ +RUNTEST = \ + + +/^CC_FOR_TARGET = `/,/`$/c\ +CC_FOR_TARGET = \ + + +/^CXX_FOR_TARGET = `/,/`$/c\ +CXX_FOR_TARGET = \ + + +/^CHILL_FOR_TARGET = `/,/`$/c\ +CHILL_FOR_TARGET = \ + + +/^CHILL_LIB = `/,/`$/c\ +CHILL_LIB = \ + +/sanit/s/{start-sanit...-[a-z0-9]*}// +/sanit/s/{end-sanit...-[a-z0-9]*}// + +# Add standard defines and default rules. +/^# srcdir/a\ +\ +s = "{srcdir}"\ +\ +o = :\ +\ +"{o}" \\Option-f : "{s}" + diff --git a/gnu/usr.bin/binutils/config/mpw/mpw-touch b/gnu/usr.bin/binutils/config/mpw/mpw-touch new file mode 100644 index 00000000000..c743a5122b5 --- /dev/null +++ b/gnu/usr.bin/binutils/config/mpw/mpw-touch @@ -0,0 +1,7 @@ +# "Touch" command. + +If "`Exists "{1}"`" != "" + SetFile -m . "{1}" +Else + Echo ' ' > "{1}" +End If diff --git a/gnu/usr.bin/binutils/config/mpw/mpw-true b/gnu/usr.bin/binutils/config/mpw/mpw-true new file mode 100644 index 00000000000..0506530d3c6 --- /dev/null +++ b/gnu/usr.bin/binutils/config/mpw/mpw-true @@ -0,0 +1 @@ +Exit 0 diff --git a/gnu/usr.bin/binutils/config/mpw/null-command b/gnu/usr.bin/binutils/config/mpw/null-command new file mode 100644 index 00000000000..4844c8ec553 --- /dev/null +++ b/gnu/usr.bin/binutils/config/mpw/null-command @@ -0,0 +1 @@ +# This command does nothing. diff --git a/gnu/usr.bin/binutils/config/mpw/open-brace b/gnu/usr.bin/binutils/config/mpw/open-brace new file mode 100644 index 00000000000..58465dcc18c --- /dev/null +++ b/gnu/usr.bin/binutils/config/mpw/open-brace @@ -0,0 +1,4 @@ +# MPW makefiles seem not to have any way to get a literal open +# brace into a rule anywhere, so this does the job. + +Echo '{' diff --git a/gnu/usr.bin/binutils/config/mpw/tr-7to8-src b/gnu/usr.bin/binutils/config/mpw/tr-7to8-src new file mode 100644 index 00000000000..b20b649c895 --- /dev/null +++ b/gnu/usr.bin/binutils/config/mpw/tr-7to8-src @@ -0,0 +1,9 @@ +StreamEdit -e \Option-d + '/\Option-x/ \Option-d + Replace /\Option-d\SrcOption-d/ "\Option-d\Option-d" -c \Option-5 ; \Option-d + Replace /\Option-d\SrcOption-f/ "\Option-d\Option-f" -c \Option-5 ; \Option-d + Replace /\Option-d\SrcOption-8/ "\Option-d\Option-8" -c \Option-5 ; \Option-d + Replace /\Option-d\SrcOption-5/ "\Option-d\Option-5" -c \Option-5 ; \Option-d + Replace /\Option-d\SrcOption-x/ "\Option-d\Option-x" -c \Option-5 ; \Option-d + Replace /\Option-d\SrcOption-r/ "\Option-d\Option-r" -c \Option-5' \Option-d + "{1}" diff --git a/gnu/usr.bin/binutils/config/mpw/true b/gnu/usr.bin/binutils/config/mpw/true new file mode 100644 index 00000000000..0506530d3c6 --- /dev/null +++ b/gnu/usr.bin/binutils/config/mpw/true @@ -0,0 +1 @@ +Exit 0 diff --git a/gnu/usr.bin/binutils/config/mt-ppc b/gnu/usr.bin/binutils/config/mt-ppc new file mode 100644 index 00000000000..148f897f430 --- /dev/null +++ b/gnu/usr.bin/binutils/config/mt-ppc @@ -0,0 +1,2 @@ +CFLAGS_FOR_TARGET = $(CFLAGS) -mrelocatable-lib -mno-eabi +CXXFLAGS_FOR_TARGET = $(CXXFLAGS) -mrelocatable-lib -mno-eabi diff --git a/gnu/usr.bin/binutils/config/mt-sparcpic b/gnu/usr.bin/binutils/config/mt-sparcpic index ff987275575..35b8c9e4dc2 100644 --- a/gnu/usr.bin/binutils/config/mt-sparcpic +++ b/gnu/usr.bin/binutils/config/mt-sparcpic @@ -1 +1 @@ -PICFLAG_FOR_TARGET=-fpic +PICFLAG_FOR_TARGET=-fPIC diff --git a/gnu/usr.bin/binutils/etc/ChangeLog b/gnu/usr.bin/binutils/etc/ChangeLog index 7cf82e39c12..972410cf882 100644 --- a/gnu/usr.bin/binutils/etc/ChangeLog +++ b/gnu/usr.bin/binutils/etc/ChangeLog @@ -1,3 +1,7 @@ +Tue Jun 25 18:56:08 1996 Jason Molenda (crash@godzilla.cygnus.co.jp) + + * Makefile.in (datadir): Changed to $(prefix)/share. + Fri Mar 29 11:38:01 1996 J.T. Conklin (jtc@lisa.cygnus.com) * configure.man: Changed to be recognized by catman -w on Solaris. diff --git a/gnu/usr.bin/binutils/etc/Makefile.in b/gnu/usr.bin/binutils/etc/Makefile.in index 699ada6ae9a..829bf621c7f 100644 --- a/gnu/usr.bin/binutils/etc/Makefile.in +++ b/gnu/usr.bin/binutils/etc/Makefile.in @@ -9,7 +9,7 @@ srcdir = . bindir = $(exec_prefix)/bin libdir = $(exec_prefix)/lib tooldir = $(libdir) -datadir = $(prefix)/lib +datadir = $(prefix)/share mandir = $(prefix)/man man1dir = $(mandir)/man1 diff --git a/gnu/usr.bin/binutils/gas/CONTRIBUTORS b/gnu/usr.bin/binutils/gas/CONTRIBUTORS index 49ec2960852..c888e74b2b6 100644 --- a/gnu/usr.bin/binutils/gas/CONTRIBUTORS +++ b/gnu/usr.bin/binutils/gas/CONTRIBUTORS @@ -87,7 +87,7 @@ fixes and configuration enhancements. The initial Alpha support was contributed by Carnegie-Mellon University. Additional work was done by Ken Raeburn of Cygnus -Support. +Support. Richard Henderson then rewrote much of the Alpha support. Ian Dall updated the support code for the National Semiconductor 32000 series, and added support for Mach 3 and NetBSD running on the PC532. diff --git a/gnu/usr.bin/binutils/gas/NOTES b/gnu/usr.bin/binutils/gas/NOTES index b062909db12..18b29b81914 100644 --- a/gnu/usr.bin/binutils/gas/NOTES +++ b/gnu/usr.bin/binutils/gas/NOTES @@ -5,23 +5,16 @@ PORTING: Sorry, no description of the interfaces is written up yet. Look at existing back ends and work from there. -New hosts: If your host system has a strange header file setup, create a -config/ho-foo.h file for it and include the appropriate header files or -definitions there. If your host has a broken compiler, or some broken macros -in header files, create a host-specific file and repair the damage there. -(See, for example, ho-rs6000.h. The "assert" macro on that system doesn't work -right, and a flag is set to rewrite an expression in tc-m68k.c that the native -compiler mis-compiles.) - -New target formats: Look at the BFD_ASSEMBLER code. The a.out code might be a -fair example. There are no "good" examples yet, unfortunately, nor any good -documentation of the changes. +New hosts: The configure script, which is generated by autoconf, +should handle all host specific configuration. + +New target formats: Look at the BFD_ASSEMBLER code. The a.out or ELF +code might be a fair example. There are no "good" examples yet, +unfortunately, nor any good documentation of the changes. New target processors: Check first to see if the BFD_ASSEMBLER interface is supported by the file format code you need to use. -New environments: ??? - DOCUMENTATION: The internals of gas need documenting. @@ -45,10 +38,6 @@ non-BFD_ASSEMBLER version often has multiple conditional tests inside it for various processors or formats. As the various targets get converted over, these will gradually go away. -As of the moment I'm editing this file, only the "sun4" and "decstation-bsd" -targets can really use the BFD code. Other back ends still need merging or -touching up. - TO DO: Remove DONTDEF code, commented-out code. @@ -105,30 +94,6 @@ Torbjorn Granlund writes, regarding alpha .align: since these two instructions can dual-issue. Since .align is ued a lot by gcc, it is an important optimization. -Torbjorn Granlund writes, regarding i386/i486/pentium: - - In a new publication from Intel, "Optimization for Intel's 32 bit - Processors", they recommended code alignment on a 16 byte boundary if that - requires less than 8 bytes of fill instructions. The Pentium is not - affected by such alignment, the 386 wants alignment on a 4 byte boundary. - It is the 486 that is most helped by large alignment. - - Recommended nop instructions: - 1 byte: 90 xchg %eax,%eax - 2 bytes: 8b c0 movl %eax,%eax - 3 bytes: 8d 76 00 leal 0(%esi),%esi - 4 bytes: 8d 74 26 00 leal 0(%esi),%esi - 5 bytes: 8b c0 8d 76 00 movl %eax,%eax; leal 0(%esi),%esi - 6 bytes: 8d b6 00 00 00 00 leal 0(%esi),%esi - 7 bytes: 8d b4 26 00 00 00 00 leal 0(%esi),%esi - - Note that `leal 0(%esi),%esi' has a few different encodings... - - There are faster instructions for certain lengths, that are not true nops. - If you can determine that a register and the condition code is dead (by - scanning forwards for a register that is written before it is read, and - similar for cc) you can use a `incl reg' for a 3 times faster 1 cycle nop... - (From old "NOTES" file to-do list, not really reviewed:) fix relocation types for i860, perhaps by adding a ref pointer to fixS? diff --git a/gnu/usr.bin/binutils/gas/NOTES.config b/gnu/usr.bin/binutils/gas/NOTES.config index e12797d51c1..79832e64d7a 100644 --- a/gnu/usr.bin/binutils/gas/NOTES.config +++ b/gnu/usr.bin/binutils/gas/NOTES.config @@ -3,30 +3,20 @@ Theory: -The goal of the new configuration scheme is to bury all object format, -target processor, and host machine dependancies in object, target, and -host specific files. That is, to move all #ifdef's out of the gas -common code. +The goal of the new configuration scheme is to bury all object format +and target processor dependancies in object and target specific files. +That is, to move all #ifdef's out of the gas common code. Here's how it works. There is a .h and a .c file for each object file -format, a .h and a .c file for each target processor, and a .h for -each host. config.gas creates {sym}links in the current directory to -the appropriate files in the config directory. config.gas also serves -as a list of triplets {host, target, object-format} that have been -tested at one time or another. I also recommend that config.gas be -used to document triplet specific notes as to purpose of the triplet, -etc. +format and a .h and a .c file for each target processor. The +configure script creates symlinks in the current directory to the +appropriate files in the config directory. configure also serves as a +list of triplets {host, target, object-format} that have been tested +at one time or another. I also recommend that configure be used to +document triplet specific notes as to purpose of the triplet, etc. Implementation: -host.h is a {sym}link to .../config/xm-yourhost.h. It is intended to -be used to hide host compiler, system header file, and system library -differences between host machines. If your host needs actual c source -files, then either: these are generally useful functions, in which -case you should probably build a local library outside of the gas -source tree, or someone, perhaps me, is confused about what is needed -by different hosts. - obj-format.h is a {sym}link to .../config/obj-something.h. It is intended All gas .c files include as.h. diff --git a/gnu/usr.bin/binutils/gas/README b/gnu/usr.bin/binutils/gas/README index 7a25d9a0844..7cf2ca39270 100644 --- a/gnu/usr.bin/binutils/gas/README +++ b/gnu/usr.bin/binutils/gas/README @@ -14,6 +14,8 @@ Unpacking and Installation - Summary See ../binutils/README. +To build just the assembler, make the target all-gas. + Documentation ============= @@ -28,14 +30,14 @@ DVI file into a form your system can print. If you wish to build the DVI file, you will need to have TeX installed on your system. You can rebuild it by typing: - cd gas-2.5/gas/doc + cd gas/doc make as.dvi The Info form is viewable with the GNU Emacs `info' subsystem, or the standalone `info' program, available as part of the GNU Texinfo distribution. To build the info files, you will need the `makeinfo' program. Type: - cd gas-2.5/gas/doc + cd gas/doc make info Specifying names for hosts and targets @@ -71,9 +73,6 @@ you can use it to test your guesses on abbreviations--for example: % sh config.sub i786v Invalid configuration `i786v': machine `i786v' not recognized -`config.sub' is also distributed in the GAS source directory -(`gas-2.5', for version 2.5). - `configure' options =================== @@ -116,9 +115,6 @@ prefer; but you may abbreviate option names if you use `--'. Configure only the directory level where `configure' is executed; do not propagate configuration to subdirectories. -`--rm' - Remove the configuration that the other arguments specify. - `--target=TARGET' Configure GAS for cross-assembling programs for the specified TARGET. Without this option, GAS is configured to assemble .o files @@ -131,7 +127,7 @@ prefer; but you may abbreviate option names if you use `--'. These flags tell the program or library being configured to configure itself differently from the default for the specified host/target combination. See below for a list of `--enable' - options recognized in the gas-2.5 distribution. + options recognized in the gas distribution. `HOST ...' Configure GAS to run on the specified HOST. @@ -143,7 +139,7 @@ prefer; but you may abbreviate option names if you use `--'. other GNU tools recursively; but these are the only options that affect GAS or its supporting libraries. -The `--enable' options recognized by software in the gas-2.5 distribution are: +The `--enable' options recognized by software in the gas distribution are: `--enable-targets=...' This causes one or more specified configurations to be added to those for @@ -186,6 +182,7 @@ Native assembling should work on: rs6000 unixware sco 3.2v4.2 + sco openserver 5.0 (a.k.a. 3.2v5.0 ) sparc solaris 2.3 For cross-assemblers, I believe hosting to work on any of the machines listed @@ -223,7 +220,7 @@ MIPS ECOFF support has been added, but GAS will not run a C-style preprocessor. If you want that, rename your file to have a ".S" suffix, and run gcc on it. Or run "gcc -xassembler-with-cpp foo.s". -Support for ELF should work now for sparc, hppa, i386. +Support for ELF should work now for sparc, hppa, i386, alpha, m68k. Support for ns32k, tahoe, i860, m88k may be suffering from bitrot. diff --git a/gnu/usr.bin/binutils/gas/conf-a-gas.com b/gnu/usr.bin/binutils/gas/conf-a-gas.com new file mode 100644 index 00000000000..ca5dd945644 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/conf-a-gas.com @@ -0,0 +1,168 @@ +$! +$! This file sets things up to build gas on a openVMS/Alpha system to generate +$! object files for a openVMS/Alpha system. +$! We do not use the configure script, since there is no /bin/sh to execute it. +$! +$! If you are running this file, then obviously the host is alpha-dec-vms. +$! +$gas_host="vms" +$! +$cpu_type="alpha" +$emulation="generic" +$obj_format="evax" +$atof="ieee" +$! +$ DELETE = "delete/noConfirm" +$ ECHO = "write sys$output" +$! +$! Target specific information +$call link targ-cpu.c [.config]tc-'cpu_type'.c +$call link targ-cpu.h [.config]tc-'cpu_type'.h +$call link targ-env.h [.config]te-'emulation'.h +$! +$! Code to handle the object file format. +$call link obj-format.h [.config]obj-'obj_format'.h +$call link obj-format.c [.config]obj-'obj_format'.c +$! +$! Code to handle floating point. +$call link atof-targ.c [.config]atof-'atof'.c +$! +$! +$! Create the file version.opt, which helps identify the executable. +$! +$if f$trnlnm("IFILE$").nes."" then close/noLog ifile$ +$search Makefile.in "VERSION="/Exact/Output=config-gas-tmp.tmp +$open ifile$ config-gas-tmp.tmp +$read ifile$ line +$close ifile$ +$DELETE config-gas-tmp.tmp;* +$! Discard "VERSION=" and "\n" parts. +$ijk=f$locate("=",line)+1 +$line=f$extract(ijk,f$length(line)-ijk,line) +$! [what "\n" part?? this seems to be useless, but is benign] +$ijk=f$locate("\n",line) +$line=f$extract(0,ijk,line) +$! +$ if f$search("version.opt").nes."" then DELETE version.opt;* +$copy _NL: version.opt +$open/Append ifile$ version.opt +$write ifile$ "identification="+""""+line+"""" +$close ifile$ +$! +$! Now write config.h. +$! +$ if f$search("config.h").nes."" then DELETE config.h;* +$copy _NL: config.h +$open/Append ifile$ config.h +$write ifile$ "/* config.h. Generated by config-gas.com. */ +$write ifile$ "#ifndef GAS_VERSION" +$write ifile$ "#define GAS_VERSION """,line,"""" +$write ifile$ "#endif" +$write ifile$ "/*--*/" +$append [.config]vms-a-conf.h ifile$: +$close ifile$ +$ECHO "Created config.h." +$! +$! Check for, and possibly make, header file . +$! +$ if f$search("tmp-chk-h.*").nes."" then DELETE tmp-chk-h.*;* +$!can't use simple `#include HDR' with `gcc /Define="HDR="' +$!because the 2.6.[0-3] preprocessor handles it wrong (VMS-specific gcc bug) +$ create tmp-chk-h.c +int tmp_chk_h; /* guarantee non-empty output */ +#ifdef HAVE_STDIO_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_UNIXIO_H +#include +#endif +#ifdef HAVE_UNIXLIB_H +#include +#endif +$ on warning then continue +$ CHECK = "call tmp_chk_h" +$ CHECK "HAVE_STDIO_H" +$ if .not.$status +$ then type sys$input: + +? could not compile . + Since gcc is not set up correctly, gas configuration cannot proceed. + +$ DELETE tmp-chk-h.c;* +$ exit %x002C +$ endif +$! +$ CHECK "HAVE_UNISTD_H" +$ if .not.$status +$ then +$ if f$trnlnm("HFILE$").nes."" then close/noLog hfile$ +$ CHECK "HAVE_UNIXIO_H" +$ got_unixio = ($status .and. 1) +$ CHECK "HAVE_UNIXLIB_H" +$ got_unixlib = ($status .and. 1) +$ create []unistd.h !with rudimentary contents +/* substitute for building gas */ +#ifndef UNISTD_H +#define UNISTD_H + +$ open/Append hfile$ []unistd.h +$ if got_unixio +$ then write hfile$ "#include " +$ else append sys$input: hfile$: +/* some of the routines normally prototyped in */ +extern int creat(), open(), close(), read(), write(); +extern int access(), dup(), dup2(), fstat(), stat(); +extern long lseek(); +$ endif +$ write hfile$ "" +$ if got_unixlib +$ then write hfile$ "#include " +$ else append sys$input: hfile$: +/* some of the routines normally prototyped in */ +extern char *sbrk(), *getcwd(), *cuserid(); +extern int brk(), chdir(), chmod(), chown(), mkdir(); +extern unsigned getuid(), umask(); +$ endif +$ append sys$input: hfile$: + +#endif /*UNISTD_H*/ +$ close hfile$ +$ ECHO "Created ""[]unistd.h""." +$ endif !gcc '#include ' failed +$ DELETE tmp-chk-h.c;* +$ +$tmp_chk_h: subroutine +$ set noOn +$ hname = f$edit("<" + (p1 - "HAVE_" - "_H") + ".h>","LOWERCASE") +$ write sys$output "Checking for ''hname'." +$ if f$search("tmp-chk-h.obj").nes."" then DELETE tmp-chk-h.obj;* +$ define/noLog sys$error _NL: !can't use /User_Mode here due to gcc +$ define/noLog sys$output _NL: ! driver's use of multiple image activation +$ gcc /Include=([],[-.include]) /Define=("''p1'") tmp-chk-h.c +$!can't just check $status; gcc 2.6.[0-3] preprocessor doesn't set it correctly +$ ok = (($status.and.1).and.(f$search("tmp-chk-h.obj").nes."")) .or. %x10000000 +$ deassign sys$error !restore, more or less +$ deassign sys$output +$ if ok then DELETE tmp-chk-h.obj;* +$ exit ok +$ endsubroutine !tmp_chk_h +$ +$! +$! Done +$! +$ if f$search("config.status") .nes. "" then DELETE config.status;* +$ create config.status +Links are now set up for use with an Alpha running openVMS. +$ type config.status +$exit +$! +$! +$link: +$subroutine +$ if f$search(p1).nes."" then DELETE 'p1';* +$ copy 'p2' 'p1' +$ ECHO "Copied ''f$edit(p2,"LOWERCASE")' to ''f$edit(p1,"LOWERCASE")'." +$endsubroutine diff --git a/gnu/usr.bin/binutils/gas/config/e-mipsecoff.c b/gnu/usr.bin/binutils/gas/config/e-mipsecoff.c index c2efde49ce4..9f318d5c9a4 100644 --- a/gnu/usr.bin/binutils/gas/config/e-mipsecoff.c +++ b/gnu/usr.bin/binutils/gas/config/e-mipsecoff.c @@ -5,6 +5,7 @@ static const char * mipsecoff_bfd_name () { abort (); + return NULL; } #define emul_bfd_name mipsecoff_bfd_name diff --git a/gnu/usr.bin/binutils/gas/config/e-mipself.c b/gnu/usr.bin/binutils/gas/config/e-mipself.c index d16cf7adef7..388b8bd0121 100644 --- a/gnu/usr.bin/binutils/gas/config/e-mipself.c +++ b/gnu/usr.bin/binutils/gas/config/e-mipself.c @@ -5,6 +5,7 @@ static const char * mipself_bfd_name () { abort (); + return NULL; } #define emul_bfd_name mipself_bfd_name diff --git a/gnu/usr.bin/binutils/gas/config/obj-evax.c b/gnu/usr.bin/binutils/gas/config/obj-evax.c new file mode 100644 index 00000000000..fbe5069a60a --- /dev/null +++ b/gnu/usr.bin/binutils/gas/config/obj-evax.c @@ -0,0 +1,42 @@ +/* obj-evax.c - EVAX (openVMS/Alpha) object file format. + Copyright (C) 1996 Free Software Foundation, Inc. + Contributed by Klaus Kämpf (kkaempf@progis.de) of + proGIS Software, Aachen, Germany. + + 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 OBJ_HEADER "obj-evax.h" + +#include "as.h" + +void obj_read_begin_hook () {} + +const pseudo_typeS obj_pseudo_table[] = +{ + {0, 0, 0}, +}; /* obj_pseudo_table */ + + +/* + * Local Variables: + * comment-column: 0 + * fill-column: 131 + * End: + */ + +/* end of obj-evax.c */ diff --git a/gnu/usr.bin/binutils/gas/config/obj-evax.h b/gnu/usr.bin/binutils/gas/config/obj-evax.h new file mode 100644 index 00000000000..03e3cbdf63f --- /dev/null +++ b/gnu/usr.bin/binutils/gas/config/obj-evax.h @@ -0,0 +1,115 @@ +/* This file is obj-evax.h + Copyright (C) 1996 Free Software Foundation, Inc. + Contributed by Klaus Kämpf (kkaempf@progis.de) of + proGIS Software, Aachen, Germany. + + 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. */ + +/* + * This file is obj-evax.h and is intended to be a template for + * object format specific header files. + */ + +/* define an obj specific macro off which target cpu back ends may key. */ +#define OBJ_EVAX 1 + +/* include whatever target cpu is appropriate. */ +#include "targ-cpu.h" + +#ifdef BFD_ASSEMBLER +#define OUTPUT_FLAVOR bfd_target_evax_flavour +#endif + +/* + * SYMBOLS + */ + +/* + * If your object format needs to reorder symbols, define this. When + * defined, symbols are kept on a doubly linked list and functions are + * made available for push, insert, append, and delete. If not defined, + * symbols are kept on a singly linked list, only the append and clear + * facilities are available, and they are macros. + */ + +/* #define SYMBOLS_NEED_PACKPOINTERS */ + +/* */ +typedef struct + { + void *nothing; + } +obj_symbol_type; /* should be the format's symbol structure */ + +typedef void *object_headers; + +#define DEFAULT_MAGIC_NUMBER_FOR_OBJECT_FILE (0) /* your magic number */ + +#define OBJ_EMIT_LINENO(a,b,c) /* must be *something*. This no-op's it out. */ + +#define obj_symbol_new_hook(s) {;} + +#define S_SET_OTHER(S,V) +#define S_SET_TYPE(S,T) +#define S_SET_DESC(S,D) +#define S_GET_OTHER(S) 0 +#define S_GET_TYPE(S) 0 +#define S_GET_DESC(S) 0 + +#undef AXP_REG_GP +#define AXP_REG_GP AXP_REG_PV + +#define PDSC_S_K_KIND_FP_STACK 9 +#define PDSC_S_K_KIND_FP_REGISTER 10 +#define PDSC_S_K_KIND_NULL 8 + +#define PDSC_S_K_MIN_STACK_SIZE 32 +#define PDSC_S_K_MIN_REGISTER_SIZE 24 +#define PDSC_S_K_NULL_SIZE 16 + +#define PDSC_S_M_BASE_REG_IS_FP 0x80 /* low byte */ +#define PDSC_S_M_NATIVE 0x10 /* high byte */ +#define PDSC_S_M_NO_JACKET 0x20 /* high byte */ + +#define LKP_S_K_SIZE 16 + +struct evaxProc { + symbolS *symbol; /* proc pdesc symbol */ + int pdsckind; + int framereg; /* register for frame pointer */ + int framesize; /* size of frame */ + int rsa_offset; + int ra_save; + int fp_save; + long imask; + long fmask; + int type; + int prologue; +}; + +typedef struct evaxProc evaxProcT; +typedef struct evaxProc *evaxProcP; + +/* + * Local Variables: + * comment-column: 0 + * fill-column: 131 + * End: + */ + +/* end of obj-evax.h */ diff --git a/gnu/usr.bin/binutils/gas/config/obj-vms.h b/gnu/usr.bin/binutils/gas/config/obj-vms.h index 1105bb2f860..7421bb5aacb 100644 --- a/gnu/usr.bin/binutils/gas/config/obj-vms.h +++ b/gnu/usr.bin/binutils/gas/config/obj-vms.h @@ -1,5 +1,5 @@ /* VMS object file format - Copyright (C) 1989, 1990, 1991, 1994, 1995 Free Software Foundation, Inc. + Copyright (C) 1989,90,91,94,95,1996 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -22,6 +22,8 @@ to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1 #include "targ-cpu.h" +#define LONGWORD_ALIGNMENT 2 + /* This macro controls subsection alignment within a section. * * Under VAX/VMS, the linker (and PSECT specifications) @@ -29,7 +31,8 @@ to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1 * Doing the alignment here (on initialized data) can * mess up the calculation of global data PSECT sizes. */ -#define SUB_SEGMENT_ALIGN(SEG) (((SEG) == data_section) ? 0 : 2) +#define SUB_SEGMENT_ALIGN(SEG) \ + (((SEG) == data_section) ? 0 : LONGWORD_ALIGNMENT) /* This flag is used to remember whether we are in the const or the data section. By and large they are identical, but we set a no-write @@ -132,6 +135,8 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ /* True if symbol has been defined, ie is in N_{TEXT,DATA,BSS,ABS} or N_EXT */ #define S_IS_DEFINED(s) (S_GET_TYPE(s) != N_UNDF) +#define S_IS_COMMON(s) (S_GET_TYPE(s) == N_UNDF && S_GET_VALUE(s) != 0) + #define S_IS_REGISTER(s) ((s)->sy_symbol.n_type == N_REGISTER) /* True if a debug special symbol entry */ @@ -141,7 +146,8 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */ nameless symbols come from .stab directives. */ #define S_IS_LOCAL(s) (S_GET_NAME(s) && \ !S_IS_DEBUG(s) && \ - (S_GET_NAME(s)[0] == '\001' || \ + (strchr(S_GET_NAME(s), '\001') != 0 || \ + strchr(S_GET_NAME(s), '\002') != 0 || \ (S_LOCAL_NAME(s) && !flag_keep_locals))) /* True if a symbol is not defined in this file */ #define S_IS_EXTERN(s) ((s)->sy_symbol.n_type & N_EXT) diff --git a/gnu/usr.bin/binutils/gas/config/tc-alpha.h b/gnu/usr.bin/binutils/gas/config/tc-alpha.h index 3a0790d812d..aea7690adb8 100644 --- a/gnu/usr.bin/binutils/gas/config/tc-alpha.h +++ b/gnu/usr.bin/binutils/gas/config/tc-alpha.h @@ -1,5 +1,5 @@ /* This file is tc-alpha.h - Copyright (C) 1994 Free Software Foundation, Inc. + Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. Written by Ken Raeburn . This file is part of GAS, the GNU Assembler. @@ -15,8 +15,9 @@ 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. */ + 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_ALPHA @@ -26,6 +27,8 @@ ? "ecoff-littlealpha" \ : OUTPUT_FLAVOR == bfd_target_elf_flavour \ ? "elf64-alpha" \ + : OUTPUT_FLAVOR == bfd_target_evax_flavour \ + ? "evax-alpha" \ : "unknown-format") #define NEED_LITERAL_POOL @@ -49,9 +52,19 @@ extern valueT alpha_gp_value; (as_fatal("estimate_size_before_relax called"),1) #define md_operand(x) ((void) (0)) -#define md_undefined_symbol(name) (0) - -#define LOCAL_LABEL(name) ((name)[0] == 'L') +#ifdef OBJ_ECOFF +#define LOCAL_LABEL(name) ((name)[0] == 'L') +#endif +#ifdef OBJ_ELF +#define LOCAL_LABEL(name) ((name)[0] == '$') +#define FAKE_LABEL_NAME "$L0\001" +#endif +#ifdef OBJ_EVAX +#define LOCAL_LABEL(name) ((name)[0] == '$') +#define FAKE_LABEL_NAME "$L0\001" +/* This field keeps the symbols position in the link section. */ +#define OBJ_SYMFIELD_TYPE valueT +#endif #define md_number_to_chars number_to_chars_littleendian @@ -61,5 +74,6 @@ extern void alpha_frob_ecoff_data PARAMS ((void)); #define tc_frob_label(sym) alpha_define_label (sym) extern void alpha_define_label PARAMS ((struct symbol *)); -#define md_flush_pending_output alpha_flush_pending_output -extern void alpha_flush_pending_output PARAMS ((void)); +#define md_cons_align(nbytes) alpha_cons_align (nbytes) +extern void alpha_cons_align PARAMS ((int)); + diff --git a/gnu/usr.bin/binutils/gas/config/tc-h8300.h b/gnu/usr.bin/binutils/gas/config/tc-h8300.h index bb81a6223d8..62dba2b881a 100644 --- a/gnu/usr.bin/binutils/gas/config/tc-h8300.h +++ b/gnu/usr.bin/binutils/gas/config/tc-h8300.h @@ -27,7 +27,7 @@ #define TC_COFF_FIX2RTYPE(fixP) abort(); #define BFD_ARCH bfd_arch_h8300 -#define COFF_MAGIC Hmode ? 0x8301 : 0x8300 +#define COFF_MAGIC ( Smode ? 0x8302 : Hmode ? 0x8301 : 0x8300) #define TC_COUNT_RELOC(x) (1) #define IGNORE_NONSTANDARD_ESCAPES @@ -44,6 +44,7 @@ extern void tc_reloc_mangle (); #define RELOC_32 1234 extern int Hmode; +extern int Smode; #define md_operand(x) diff --git a/gnu/usr.bin/binutils/gas/config/tc-ns32k.c b/gnu/usr.bin/binutils/gas/config/tc-ns32k.c index 1ea771d0ef6..554e656d425 100644 --- a/gnu/usr.bin/binutils/gas/config/tc-ns32k.c +++ b/gnu/usr.bin/binutils/gas/config/tc-ns32k.c @@ -1,5 +1,5 @@ /* ns32k.c -- Assemble on the National Semiconductor 32k series - Copyright (C) 1987, 1992, 1993 Free Software Foundation, Inc. + Copyright (C) 1987, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -1407,7 +1407,7 @@ convert_iif () size = 0; temp = -(rem_size - 4); - obstack_blank_fast (&frags, temp); + frag_grow (temp); { fragS *old_frag = frag_now; @@ -1475,7 +1475,7 @@ convert_iif () /* rewind the bytes not used */ temp = -(4 - size); md_number_to_disp (memP, exprP.X_add_number, size); - obstack_blank_fast (&frags, temp); + frag_grow (temp); memP += size; rem_size -= 4; /* we allocated this amount */ } @@ -1840,6 +1840,8 @@ md_number_to_field (buf, val, field_ptr) { mem_ptr = (unsigned long *) buf; } + mem_ptr = ((unsigned long *) + ((char *) mem_ptr + field_ptr->fx_bit_base_adj)); #else if (field_ptr->fx_bit_base) { /* override buf */ @@ -1849,8 +1851,8 @@ md_number_to_field (buf, val, field_ptr) { mem_ptr = buf; } -#endif mem_ptr += field_ptr->fx_bit_base_adj; +#endif #ifdef ENDIAN /* we have a nice ns32k machine with lowbyte at low-physical mem */ object = *mem_ptr; /* get some bytes */ #else /* OVE Goof! the machine is a m68k or dito */ diff --git a/gnu/usr.bin/binutils/gas/config/tc-vax.h b/gnu/usr.bin/binutils/gas/config/tc-vax.h index 977490eed92..7cfb9dff054 100644 --- a/gnu/usr.bin/binutils/gas/config/tc-vax.h +++ b/gnu/usr.bin/binutils/gas/config/tc-vax.h @@ -5,6 +5,7 @@ #define TC_VAX 1 #define NO_RELOC 0 +#define NOP_OPCODE 0x01 #define tc_aout_pre_write_hook(x) {;} /* not used */ #define tc_crawl_symbol_chain(a) {;} /* not used */ diff --git a/gnu/usr.bin/binutils/gas/config/te-riscix.h b/gnu/usr.bin/binutils/gas/config/te-riscix.h new file mode 100644 index 00000000000..7c7253ebcbe --- /dev/null +++ b/gnu/usr.bin/binutils/gas/config/te-riscix.h @@ -0,0 +1,6 @@ +#define TE_RISCIX + +#define LOCAL_LABELS_DOLLAR 1 +#define LOCAL_LABELS_FB 1 + +#include "obj-format.h" diff --git a/gnu/usr.bin/binutils/gas/config/vms-a-conf.h b/gnu/usr.bin/binutils/gas/config/vms-a-conf.h new file mode 100644 index 00000000000..688fc6890ca --- /dev/null +++ b/gnu/usr.bin/binutils/gas/config/vms-a-conf.h @@ -0,0 +1,129 @@ +/* vms-alpha-conf.h. Generated manually from conf.in, + and used by config-gas-alpha.com when constructing config.h. */ + +/* Define if using alloca.c. */ +#ifdef __GNUC__ +#undef C_ALLOCA +#else +#define C_ALLOCA +#endif + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +#undef CRAY_STACKSEG_END + +/* Define if you have and it should be used (not on Ultrix). */ +#undef HAVE_ALLOCA_H + +/* Define as __inline if that's what the C compiler calls it. */ +#ifdef __GNUC__ +#undef inline +#else +#define inline +#endif + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +#define STACK_DIRECTION (-1) + +/* Should gas use high-level BFD interfaces? */ +#define BFD_ASSEMBLER + +/* Some assert/preprocessor combinations are incapable of handling + certain kinds of constructs in the argument of assert. For example, + quoted strings (if requoting isn't done right) or newlines. */ +#ifdef __GNUC__ +#undef BROKEN_ASSERT +#else +#define BROKEN_ASSERT +#endif + +/* If we aren't doing cross-assembling, some operations can be optimized, + since byte orders and value sizes don't need to be adjusted. */ +#undef CROSS_COMPILE + +/* Some gas code wants to know these parameters. */ +#define TARGET_ALIAS "alpha-vms" +#define TARGET_CPU "alpha" +#define TARGET_CANONICAL "alpha-dec-vms" +#define TARGET_OS "openVMS/Alpha" +#define TARGET_VENDOR "dec" + +/* Sometimes the system header files don't declare malloc and realloc. */ +#undef NEED_DECLARATION_MALLOC + +/* Sometimes the system header files don't declare free. */ +#undef NEED_DECLARATION_FREE + +/* Sometimes errno.h doesn't declare errno itself. */ +#undef NEED_DECLARATION_ERRNO + +#undef MANY_SEGMENTS + +/* Needed only for sparc configuration */ +#undef sparcv9 + +/* Define if you have the remove function. */ +#define HAVE_REMOVE + +/* Define if you have the unlink function. */ +#undef HAVE_UNLINK + +/* Define if you have the header file. */ +#define HAVE_ERRNO_H + +/* Define if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if you have the header file. */ +#define HAVE_STDARG_H + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H + +/* Define if you have the header file. */ +#define HAVE_STRING_H + +/* Define if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define if you have the header file. */ +#ifdef __GNUC__ +#define HAVE_SYS_TYPES_H +#else +#undef HAVE_SYS_TYPES_H +#endif + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H /* config-gas.com will make one if necessary */ + +/* Define if you have the header file. */ +#undef HAVE_VARARGS_H + +/* VMS-specific: we need to set up EXIT_xxx here because the default + values in as.h are inappropriate for VMS, but we also want to prevent + as.h's inclusion of from triggering redefinition warnings. + guards itself against multiple inclusion, so including it + here turns as.h's later #include into a no-op. (We can't simply use + #ifndef HAVE_STDLIB_H here, because the in several older + gcc-vms distributions neglects to define these two required macros.) */ +#ifdef HAVE_STDLIB_H +#include +#endif +#if __DECC +#undef EXIT_SUCCESS +#undef EXIT_FAILURE +#define EXIT_SUCCESS 1 /* SS$_NORMAL, STS$K_SUCCESS */ +#define EXIT_FAILURE 0x10000002 /* (STS$K_ERROR | STS$M_INHIB_MSG) */ +#endif + +#include +#if __DECC +extern int strcasecmp (); +extern int strncasecmp (); +#endif diff --git a/gnu/usr.bin/binutils/gas/doc/c-vax.texi b/gnu/usr.bin/binutils/gas/doc/c-vax.texi index 7b56604178e..f460e5c2fa0 100644 --- a/gnu/usr.bin/binutils/gas/doc/c-vax.texi +++ b/gnu/usr.bin/binutils/gas/doc/c-vax.texi @@ -15,7 +15,7 @@ @end ifclear @menu -* Vax-Opts:: VAX Command-Line Options +* VAX-Opts:: VAX Command-Line Options * VAX-float:: VAX Floating Point * VAX-directives:: Vax Machine Directives * VAX-opcodes:: VAX Opcodes @@ -25,7 +25,7 @@ @end menu -@node Vax-Opts +@node VAX-Opts @section VAX Command-Line Options @cindex command-line options ignored, VAX diff --git a/gnu/usr.bin/binutils/gas/ecoff.h b/gnu/usr.bin/binutils/gas/ecoff.h index b3122cef49a..9a1f40a4bd4 100644 --- a/gnu/usr.bin/binutils/gas/ecoff.h +++ b/gnu/usr.bin/binutils/gas/ecoff.h @@ -1,5 +1,5 @@ /* ecoff.h -- header file for ECOFF debugging support - Copyright (C) 1993 Free Software Foundation, Inc. + Copyright (C) 1993, 94, 95, 1996 Free Software Foundation, Inc. Contributed by Cygnus Support. Put together by Ian Lance Taylor . @@ -16,8 +16,9 @@ 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. */ + 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. */ #ifdef ECOFF_DEBUGGING @@ -87,15 +88,19 @@ extern void ecoff_set_gp_prolog_size PARAMS ((int sz)); extern void obj_ecoff_set_ext PARAMS ((struct symbol *, EXTR *)); #endif -/* This function is called from read.c to peek at cur_file_ptr */ +/* This routine is used to patch up a line number directive when + instructions are moved around. */ +extern void ecoff_fix_loc PARAMS ((fragS *, unsigned long)); + +/* This function is called from read.c to peek at cur_file_ptr. */ extern int ecoff_no_current_file PARAMS ((void)); -/* This routine is called from read.c to generate line number for .s file -*/ +/* This routine is called from read.c to generate line number for .s + file. */ extern void ecoff_generate_asm_lineno PARAMS ((const char *, int)); -/* This routine is called from read.c to generate line number stabs for .s file -*/ +/* This routine is called from read.c to generate line number stabs + for .s file. */ extern void ecoff_generate_asm_line_stab PARAMS ((char *, int)); #endif /* ! GAS_ECOFF_H */ diff --git a/gnu/usr.bin/binutils/gas/flonum.h b/gnu/usr.bin/binutils/gas/flonum.h index dd21e6bdee0..6684f496c2c 100644 --- a/gnu/usr.bin/binutils/gas/flonum.h +++ b/gnu/usr.bin/binutils/gas/flonum.h @@ -1,6 +1,6 @@ /* flonum.h - Floating point package - Copyright (C) 1987, 1990, 1991, 1992, 1994 Free Software Foundation, Inc. + Copyright (C) 1987, 90, 91, 92, 94, 95, 1996 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -15,8 +15,9 @@ 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. */ + 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. */ /***********************************************************************\ * * @@ -31,12 +32,6 @@ * * \***********************************************************************/ -#if (__STDC__ != 1) -#ifndef const -#define const /* empty */ -#endif -#endif - #include "bignum.h" /***********************************************************************\ diff --git a/gnu/usr.bin/binutils/gas/listing.c b/gnu/usr.bin/binutils/gas/listing.c index 357ea316a0c..d6bdf46e66b 100644 --- a/gnu/usr.bin/binutils/gas/listing.c +++ b/gnu/usr.bin/binutils/gas/listing.c @@ -302,6 +302,9 @@ listing_newline (ps) static char *last_file = NULL; list_info_type *new; + if (listing == 0) + return; + if (now_seg == absolute_section) return; @@ -515,7 +518,8 @@ calc_hex (list) unsigned int var_rep_idx = byte_in_frag; /* Print as many bytes from the variable part as is sensible */ - while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset + while ((byte_in_frag + < frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset) && data_buffer_size < sizeof (data_buffer) - 10) { if (address == ~0) @@ -534,7 +538,7 @@ calc_hex (list) var_rep_idx++; byte_in_frag++; - if (var_rep_idx >= frag_ptr->fr_var) + if (var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var) var_rep_idx = var_rep_max; } } @@ -925,18 +929,27 @@ void listing_print (name) char *name; { + int using_stdout; + file_info_type *fi; + title = ""; subtitle = ""; if (name == NULL) - list_file = stdout; + { + list_file = stdout; + using_stdout = 1; + } else { list_file = fopen (name, "w"); - if (list_file == NULL) + if (list_file != NULL) + using_stdout = 0; + else { as_perror ("can't open list file: %s", name); list_file = stdout; + using_stdout = 1; } } @@ -948,12 +961,27 @@ listing_print (name) if (listing & LISTING_LISTING) { listing_listing (name); - } + if (listing & LISTING_SYMBOLS) { list_symbol_table (); } + + if (! using_stdout) + { + if (fclose (list_file) == EOF) + as_perror ("error closing list file: %s", name); + } + + for (fi = file_info_head; fi != NULL; fi = fi->next) + { + if (fi->file != NULL) + { + fclose (fi->file); + fi->file = NULL; + } + } } @@ -968,7 +996,8 @@ void listing_eject (ignore) int ignore; { - listing_tail->edict = EDICT_EJECT; + if (listing) + listing_tail->edict = EDICT_EJECT; } void @@ -984,7 +1013,8 @@ void listing_list (on) int on; { - listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST; + if (listing) + listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST; } @@ -1049,12 +1079,15 @@ listing_title (depth) ? *input_line_pointer == '\"' : is_end_of_line[(unsigned char) *input_line_pointer]) { - length = input_line_pointer - start; - ttl = xmalloc (length + 1); - memcpy (ttl, start, length); - ttl[length] = 0; - listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; - listing_tail->edict_arg = ttl; + if (listing) + { + length = input_line_pointer - start; + ttl = xmalloc (length + 1); + memcpy (ttl, start, length); + ttl[length] = 0; + listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; + listing_tail->edict_arg = ttl; + } if (quoted) input_line_pointer++; demand_empty_rest_of_line (); @@ -1079,17 +1112,19 @@ void listing_source_line (line) unsigned int line; { - new_frag (); - listing_tail->hll_line = line; - new_frag (); - + if (listing) + { + new_frag (); + listing_tail->hll_line = line; + new_frag (); + } } void listing_source_file (file) const char *file; { - if (listing_tail) + if (listing) listing_tail->hll_file = file_info (file); } diff --git a/gnu/usr.bin/binutils/gas/makefile.vms b/gnu/usr.bin/binutils/gas/makefile.vms new file mode 100644 index 00000000000..c9d4d7e5227 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/makefile.vms @@ -0,0 +1,54 @@ +# +# makefile for gas +# +# Created by Klaus Kämpf, kkaempf@progis.de +# + +CC=gcc + +ifeq ($(CC),gcc) +DEFS= +CFLAGS=/include=([],[-.bfd],[.config],[-.include],[-])$(DEFS) +LFLAGS= +LIBS=,GNU_CC:[000000]LIBGCC2/lib,GNU_CC:[000000]LIBGCCLIB/lib,\ + sys$$library:vaxcrtl.olb/lib,GNU_CC:[000000]crt0.obj +else +DEFS=/define=("table_size_of_flonum_powers_of_ten"="tabsiz_flonum_powers_of_ten",\ +"_bfd_generic_get_section_contents_in_window"="_bfd_generic_get_win_section_cont",\ +"_elf_section_from_bfd_section"="_bfd_elf_sec_from_bfd_sec","const=") +CFLAGS=/noopt/debug/include=([],[-.bfd],[.config],[-.include],[-])$(DEFS) +LFLAGS= +LIBS= +endif + +OBJS=targ-cpu.obj,obj-format.obj,atof-targ.obj,app.obj,as.obj,atof-generic.obj,\ + bignum-copy.obj,cond.obj,expr.obj,flonum-konst.obj,flonum-copy.obj,\ + flonum-mult.obj,frags.obj,hash.obj,input-file.obj,input-scrub.obj,\ + literal.obj,messages.obj,output-file.obj,read.obj,subsegs.obj,symbols.obj,\ + write.obj,listing.obj,ecoff.obj,stabs.obj,sb.obj,macro.obj + +LIBIBERTY = [-.libiberty]libiberty.olb +LIBBFD = [-.bfd]libbfd.olb +LIBOPCODES = [-.opcodes]libopcodes.olb + + +as.exe: $(OBJS) $(LIBOPCODES) $(LIBBFD) $(LIBIBERTY) + link$(LFLAGS)/exe=$@ $(OBJS),$(LIBOPCODES)/lib,$(LIBBFD)/lib,$(LIBIBERTY)/lib$(LIBS) + +gasp.exe: gasp.obj $(LIBBFD) $(LIBIBERTY) + link$(LFLAGS)/exe=$@ gasp.obj,$(LIBBFD)/lib,$(LIBIBERTY)/lib$(LIBS) + +targ-cpu.c: [.config]tc-alpha.c + copy $< $@ +targ-cpu.h: [.config]tc-alpha.h + copy $< $@ +targ-env.h: [.config]te-generic.h + copy $< $@ +obj-format.h: [.config]obj-evax.h + copy $< $@ +obj-format.c: [.config]obj-evax.c + copy $< $@ +atof-targ.c: [.config]atof-ieee.c + copy $< $@ + +targ-cpu.obj: targ-cpu.c targ-cpu.h [.config]atof-vax.c diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/all/cofftag.d b/gnu/usr.bin/binutils/gas/testsuite/gas/all/cofftag.d new file mode 100644 index 00000000000..59898b621ed --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/all/cofftag.d @@ -0,0 +1,25 @@ +#objdump: -t +#name: cofftag + +.*: file format .* + +SYMBOL TABLE: +\[ 0\]\(sec -2\)\(fl 0x00\)\(ty 0\)\(scl 103\) \(nx 1\) 0x0+0000 foo.c +File +\[ 2\]\(sec 1\)\(fl 0x00\)\(ty 0\)\(scl 6\) \(nx 0\) 0x0+0000 gcc2_compiled. +\[ 3\]\(sec 1\)\(fl 0x00\)\(ty 0\)\(scl 6\) \(nx 0\) 0x0+0000 ___gnu_compiled_c +\[ 4\]\(sec -2\)\(fl 0x00\)\(ty a\)\(scl 15\) \(nx 1\) 0x0+0000 _token +AUX lnno 0 size 0x4 tagndx 0 endndx 10 +\[ 6\]\(sec -1\)\(fl 0x00\)\(ty b\)\(scl 16\) \(nx 0\) 0x0+0000 _operator +\[ 7\]\(sec -1\)\(fl 0x00\)\(ty b\)\(scl 16\) \(nx 0\) 0x0+0001 _flags +\[ 8\]\(sec -1\)\(fl 0x00\)\(ty 0\)\(scl 102\) \(nx 1\) 0x0+0004 .eos +AUX lnno 0 size 0x4 tagndx 4 +\[ 10\]\(sec 1\)\(fl 0x00\)\(ty 0\)\(scl 3\) \(nx 1\) 0x[0-9a-f]+ .text +AUX scnlen 0x[0-9a-f]+ nreloc 0 nlnno 0 +\[ 12\]\(sec 2\)\(fl 0x00\)\(ty 0\)\(scl 3\) \(nx 1\) 0x[0-9a-f]+ .data +AUX scnlen 0x[0-9a-f]+ nreloc 0 nlnno 0 +\[ 14\]\(sec 3\)\(fl 0x00\)\(ty 0\)\(scl 3\) \(nx 1\) 0x[0-9a-f]+ .bss +AUX scnlen 0x[0-9a-f]+ nreloc 0 nlnno 0 +\[ 16\]\(sec 2\)\(fl 0x00\)\(ty 2\)\(scl 2\) \(nx 0\) 0x0+0000 _token +\[ 17\]\(sec 2\)\(fl 0x00\)\(ty a\)\(scl 2\) \(nx 1\) 0x[0-9a-f]+ _what +AUX lnno 0 size 0x4 tagndx 4 diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/all/cofftag.s b/gnu/usr.bin/binutils/gas/testsuite/gas/all/cofftag.s new file mode 100644 index 00000000000..432aa9a8f9f --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/all/cofftag.s @@ -0,0 +1,57 @@ +/* This file was compiled from this C source: + char token =0; + enum token { + operator, + flags + }; + + enum token what= operator; + */ + + .file "foo.c" +gcc2_compiled.: +___gnu_compiled_c: +.globl _token +.data +_token: + .byte 0 +.text + .def _token + .scl 15 + .type 012 + .size 4 + .endef + .def _operator + .val 0 + .scl 16 + .type 013 + .endef + .def _flags + .val 1 + .scl 16 + .type 013 + .endef + .def .eos + .val 4 + .scl 102 + .tag _token + .size 4 + .endef +.globl _what +.data + .align 2 +_what: + .long 0 +.text + .def _token + .val _token + .scl 2 + .type 02 + .endef + .def _what + .val _what + .scl 2 + .tag _token + .size 4 + .type 012 + .endef diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/arm/arch4t.s b/gnu/usr.bin/binutils/gas/testsuite/gas/arm/arch4t.s new file mode 100644 index 00000000000..8d28f7f3ec1 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/arm/arch4t.s @@ -0,0 +1,21 @@ +.text +.align 0 + + bx r0 + bxeq r1 + +foo: + ldrh r3, foo + ldrsh r4, [r5] + ldrsb r4, [r1, r3] + ldrsh r1, [r4, r4]! + ldreqsb r1, [r5, -r3] + ldrneh r2, [r6], r7 + ldrccsh r2, [r7], +r8 + ldrsb r2, [r3, #255] + ldrsh r1, [r4, #-250] + ldrsb r1, [r5, #+240] + + strh r2, bar + strneh r3, [r3] +bar: diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/arm/arm.exp b/gnu/usr.bin/binutils/gas/testsuite/gas/arm/arm.exp index 6a76fc3d8d6..f21c54df310 100644 --- a/gnu/usr.bin/binutils/gas/testsuite/gas/arm/arm.exp +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/arm/arm.exp @@ -2,7 +2,7 @@ # Some ARM tests # if [istarget arm-*-*] then { - gas_test "inst.s" "" $stdoptlist "Basic instruction set" + run_dump_test "inst" gas_test "arm3.s" "" $stdoptlist "Arm 3 instructions" @@ -10,8 +10,16 @@ if [istarget arm-*-*] then { gas_test "arm7dm.s" "" $stdoptlist "Arm 7DM instructions" + run_dump_test "arm7t" + + gas_test "thumb.s" "" $stdoptlist "Thumb instructions" + + gas_test "arch4t.s" "" $stdoptlist "Arm architecture 4t instructions" + gas_test "copro.s" "" $stdoptlist "Co processor instructions" + gas_test "immed.s" "" $stdoptlist "immediate expressions" + gas_test "float.s" "" $stdoptlist "Core floating point instructions" } diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/arm/arm7t.d b/gnu/usr.bin/binutils/gas/testsuite/gas/arm/arm7t.d new file mode 100644 index 00000000000..92613f9dabf --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/arm/arm7t.d @@ -0,0 +1,68 @@ +#objdump: -dr +#name: ARM arm7t +#as: -marm7t -EL + +# Test the halfword and signextend memory transfers: + +.*: +file format .*arm.*little + +Disassembly of section .text: +00000000 <[^>]*> e1d100b0 ldrh r0, \[r1\] +00000004 <[^>]*> e1f100b0 ldrh r0, \[r1\]! +00000008 <[^>]*> e19100b2 ldrh r0, \[r1, r2\] +0000000c <[^>]*> e1b100b2 ldrh r0, \[r1, r2\]! +00000010 <[^>]*> e1d100bc ldrh r0, \[r1, #c\] +00000014 <[^>]*> e1f100bc ldrh r0, \[r1, #c\]! +00000018 <[^>]*> e15100bc ldrh r0, \[r1, -#c\] +0000001c <[^>]*> e09100b2 ldrh r0, \[r1\], r2 +00000020 <[^>]*> e3a00cff mov r0, #ff00 +00000024 <[^>]*> e1df0bb4 ldrh r0, 000000e0 <\$\$lit_1> +00000028 <[^>]*> e1df0abc ldrh r0, 000000dc <.L2> +0000002c <[^>]*> e1c100b0 strh r0, \[r1\] +00000030 <[^>]*> e1e100b0 strh r0, \[r1\]! +00000034 <[^>]*> e18100b2 strh r0, \[r1, r2\] +00000038 <[^>]*> e1a100b2 strh r0, \[r1, r2\]! +0000003c <[^>]*> e1c100bc strh r0, \[r1, #c\] +00000040 <[^>]*> e1e100bc strh r0, \[r1, #c\]! +00000044 <[^>]*> e14100bc strh r0, \[r1, -#c\] +00000048 <[^>]*> e08100b2 strh r0, \[r1\], r2 +0000004c <[^>]*> e1cf08b8 strh r0, 000000dc <.L2> +00000050 <[^>]*> e1d100d0 ldrsb r0, \[r1\] +00000054 <[^>]*> e1f100d0 ldrsb r0, \[r1\]! +00000058 <[^>]*> e19100d2 ldrsb r0, \[r1, r2\] +0000005c <[^>]*> e1b100d2 ldrsb r0, \[r1, r2\]! +00000060 <[^>]*> e1d100dc ldrsb r0, \[r1, #c\] +00000064 <[^>]*> e1f100dc ldrsb r0, \[r1, #c\]! +00000068 <[^>]*> e15100dc ldrsb r0, \[r1, -#c\] +0000006c <[^>]*> e09100d2 ldrsb r0, \[r1\], r2 +00000070 <[^>]*> e3a000de mov r0, #de +00000074 <[^>]*> e1df06d0 ldrsb r0, 000000dc <.L2> +00000078 <[^>]*> e1d100f0 ldrsh r0, \[r1\] +0000007c <[^>]*> e1f100f0 ldrsh r0, \[r1\]! +00000080 <[^>]*> e19100f2 ldrsh r0, \[r1, r2\] +00000084 <[^>]*> e1b100f2 ldrsh r0, \[r1, r2\]! +00000088 <[^>]*> e1d100fc ldrsh r0, \[r1, #c\] +0000008c <[^>]*> e1f100fc ldrsh r0, \[r1, #c\]! +00000090 <[^>]*> e15100fc ldrsh r0, \[r1, -#c\] +00000094 <[^>]*> e09100f2 ldrsh r0, \[r1\], r2 +00000098 <[^>]*> e3a00cff mov r0, #ff00 +0000009c <[^>]*> e1df03fc ldrsh r0, 000000e0 <\$\$lit_1> +000000a0 <[^>]*> e1df03f4 ldrsh r0, 000000dc <.L2> +000000a4 <[^>]*> e19100b2 ldrh r0, \[r1, r2\] +000000a8 <[^>]*> 119100b2 ldrneh r0, \[r1, r2\] +000000ac <[^>]*> 819100b2 ldrhih r0, \[r1, r2\] +000000b0 <[^>]*> b19100b2 ldrlth r0, \[r1, r2\] +000000b4 <[^>]*> e19100f2 ldrsh r0, \[r1, r2\] +000000b8 <[^>]*> 119100f2 ldrnesh r0, \[r1, r2\] +000000bc <[^>]*> 819100f2 ldrhish r0, \[r1, r2\] +000000c0 <[^>]*> b19100f2 ldrltsh r0, \[r1, r2\] +000000c4 <[^>]*> e19100d2 ldrsb r0, \[r1, r2\] +000000c8 <[^>]*> 119100d2 ldrnesb r0, \[r1, r2\] +000000cc <[^>]*> 819100d2 ldrhisb r0, \[r1, r2\] +000000d0 <[^>]*> b19100d2 ldrltsb r0, \[r1, r2\] +000000d4 <[^>]*> e1df00f4 ldrsh r0, 000000e0 <\$\$lit_1> +000000d8 <[^>]*> e1df00f4 ldrsh r0, 000000e4 <\$\$lit_1\+4> +... +[ ]*RELOC: 000000dc 32 .LC0 +000000e0 <[^>]*> 0000c0de .* +000000e4 <[^>]*> 0000dead .* diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/arm/arm7t.s b/gnu/usr.bin/binutils/gas/testsuite/gas/arm/arm7t.s new file mode 100644 index 00000000000..656e90e0330 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/arm/arm7t.s @@ -0,0 +1,79 @@ + .section .rdata + .align 0 +.LC0: + .ascii "some data\000" + + .text + .align 0 + +loadhalfwords: + ldrh r0, [r1] + ldrh r0, [r1]! + ldrh r0, [r1, r2] + ldrh r0, [r1, r2]! + ldrh r0, [r1,#0x0C] + ldrh r0, [r1,#0x0C]! + ldrh r0, [r1,#-0x0C] + ldrh r0, [r1], r2 + ldrh r0, =0xFF00 + ldrh r0, =0xC0DE + ldrh r0, .L2 + +storehalfwords: + strh r0, [r1] + strh r0, [r1]! + strh r0, [r1, r2] + strh r0, [r1, r2]! + strh r0, [r1,#0x0C] + strh r0, [r1,#0x0C]! + strh r0, [r1,#-0x0C] + strh r0, [r1], r2 + strh r0, .L2 + +loadsignedbytes: + ldrsb r0, [r1] + ldrsb r0, [r1]! + ldrsb r0, [r1, r2] + ldrsb r0, [r1, r2]! + ldrsb r0, [r1,#0x0C] + ldrsb r0, [r1,#0x0C]! + ldrsb r0, [r1,#-0x0C] + ldrsb r0, [r1], r2 + ldrsb r0, =0xDE + ldrsb r0, .L2 + +loadsignedhalfwords: + ldrsh r0, [r1] + ldrsh r0, [r1]! + ldrsh r0, [r1, r2] + ldrsh r0, [r1, r2]! + ldrsh r0, [r1, #0x0C] + ldrsh r0, [r1, #0x0C]! + ldrsh r0, [r1, #-0x0C] + ldrsh r0, [r1], r2 + ldrsh r0, =0xFF00 + ldrsh r0, =0xC0DE + ldrsh r0, .L2 + +misc: + ldralh r0, [r1, r2] + ldrneh r0, [r1, r2] + ldrhih r0, [r1, r2] + ldrlth r0, [r1, r2] + + ldralsh r0, [r1, r2] + ldrnesh r0, [r1, r2] + ldrhish r0, [r1, r2] + ldrltsh r0, [r1, r2] + + ldralsb r0, [r1, r2] + ldrnesb r0, [r1, r2] + ldrhisb r0, [r1, r2] + ldrltsb r0, [r1, r2] + + ldrsh r0, =0xC0DE + ldrsh r0, =0xDEAD + + .align +.L2: + .word .LC0 diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/arm/immed.s b/gnu/usr.bin/binutils/gas/testsuite/gas/arm/immed.s new file mode 100644 index 00000000000..5d2092be18b --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/arm/immed.s @@ -0,0 +1,11 @@ +@ Tests for complex immediate expressions - none of these need +@ relocations + .text +bar: + mov r0, #0 + mov r0, #(. - bar - 8) + ldr r0, bar + ldr r0, [pc, # (bar - . -8)] + .space 4096 + mov r0, #(. - bar - 8) & 0xff + ldr r0, [pc, # (bar - . -8) & 0xff] diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/arm/inst.d b/gnu/usr.bin/binutils/gas/testsuite/gas/arm/inst.d new file mode 100644 index 00000000000..23c7f21f382 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/arm/inst.d @@ -0,0 +1,168 @@ +#objdump: -dr +#name: ARM basic instructions +#as: -marm2 -EL + +# Test the standard ARM instructions: + +.*: +file format .*arm.*little + +Disassembly of section .text: +00000000 <[^>]*> e3a00000 mov r0, #0 +00000004 <[^>]*> e1a01002 mov r1, r2 +00000008 <[^>]*> e1a03184 mov r3, r4, lsl #3 +0000000c <[^>]*> e1a05736 mov r5, r6, lsr r7 +00000010 <[^>]*> e1a08a59 mov r8, r9, asr sl +00000014 <[^>]*> e1a0bd1c mov fp, ip, lsl sp +00000018 <[^>]*> e1a0e06f mov lr, pc, rrx +0000001c <[^>]*> e1a01002 mov r1, r2 +00000020 <[^>]*> 01a02003 moveq r2, r3 +00000024 <[^>]*> 11a04005 movne r4, r5 +00000028 <[^>]*> b1a06007 movlt r6, r7 +0000002c <[^>]*> a1a08009 movge r8, r9 +00000030 <[^>]*> d1a0a00b movle sl, fp +00000034 <[^>]*> c1a0c00d movgt ip, sp +00000038 <[^>]*> 31a01002 movcc r1, r2 +0000003c <[^>]*> 21a01003 movcs r1, r3 +00000040 <[^>]*> 41a03006 movmi r3, r6 +00000044 <[^>]*> 51a07009 movpl r7, r9 +00000048 <[^>]*> 61a01008 movvs r1, r8 +0000004c <[^>]*> 71a09fa1 movvc r9, r1, lsr #1f +00000050 <[^>]*> 81a0800f movhi r8, pc +00000054 <[^>]*> 91a0f00e movls pc, lr +00000058 <[^>]*> 21a09008 movcs r9, r8 +0000005c <[^>]*> 31a01003 movcc r1, r3 +00000060 <[^>]*> e1b00008 movs r0, r8 +00000064 <[^>]*> 31b00007 movccs r0, r7 +00000068 <[^>]*> e281000a add r0, r1, #a +0000006c <[^>]*> e0832004 add r2, r3, r4 +00000070 <[^>]*> e0865287 add r5, r6, r7, lsl #5 +00000074 <[^>]*> e0821113 add r1, r2, r3, lsl r1 +00000078 <[^>]*> e201000a and r0, r1, #a +0000007c <[^>]*> e0032004 and r2, r3, r4 +00000080 <[^>]*> e0065287 and r5, r6, r7, lsl #5 +00000084 <[^>]*> e0021113 and r1, r2, r3, lsl r1 +00000088 <[^>]*> e221000a eor r0, r1, #a +0000008c <[^>]*> e0232004 eor r2, r3, r4 +00000090 <[^>]*> e0265287 eor r5, r6, r7, lsl #5 +00000094 <[^>]*> e0221113 eor r1, r2, r3, lsl r1 +00000098 <[^>]*> e241000a sub r0, r1, #a +0000009c <[^>]*> e0432004 sub r2, r3, r4 +000000a0 <[^>]*> e0465287 sub r5, r6, r7, lsl #5 +000000a4 <[^>]*> e0421113 sub r1, r2, r3, lsl r1 +000000a8 <[^>]*> e2a1000a adc r0, r1, #a +000000ac <[^>]*> e0a32004 adc r2, r3, r4 +000000b0 <[^>]*> e0a65287 adc r5, r6, r7, lsl #5 +000000b4 <[^>]*> e0a21113 adc r1, r2, r3, lsl r1 +000000b8 <[^>]*> e2c1000a sbc r0, r1, #a +000000bc <[^>]*> e0c32004 sbc r2, r3, r4 +000000c0 <[^>]*> e0c65287 sbc r5, r6, r7, lsl #5 +000000c4 <[^>]*> e0c21113 sbc r1, r2, r3, lsl r1 +000000c8 <[^>]*> e261000a rsb r0, r1, #a +000000cc <[^>]*> e0632004 rsb r2, r3, r4 +000000d0 <[^>]*> e0665287 rsb r5, r6, r7, lsl #5 +000000d4 <[^>]*> e0621113 rsb r1, r2, r3, lsl r1 +000000d8 <[^>]*> e2e1000a rsc r0, r1, #a +000000dc <[^>]*> e0e32004 rsc r2, r3, r4 +000000e0 <[^>]*> e0e65287 rsc r5, r6, r7, lsl #5 +000000e4 <[^>]*> e0e21113 rsc r1, r2, r3, lsl r1 +000000e8 <[^>]*> e381000a orr r0, r1, #a +000000ec <[^>]*> e1832004 orr r2, r3, r4 +000000f0 <[^>]*> e1865287 orr r5, r6, r7, lsl #5 +000000f4 <[^>]*> e1821113 orr r1, r2, r3, lsl r1 +000000f8 <[^>]*> e3c1000a bic r0, r1, #a +000000fc <[^>]*> e1c32004 bic r2, r3, r4 +00000100 <[^>]*> e1c65287 bic r5, r6, r7, lsl #5 +00000104 <[^>]*> e1c21113 bic r1, r2, r3, lsl r1 +00000108 <[^>]*> e3e0000a mvn r0, #a +0000010c <[^>]*> e1e02004 mvn r2, r4 +00000110 <[^>]*> e1e05287 mvn r5, r7, lsl #5 +00000114 <[^>]*> e1e01113 mvn r1, r3, lsl r1 +00000118 <[^>]*> e310000a tst r0, #a +0000011c <[^>]*> e1120004 tst r2, r4 +00000120 <[^>]*> e1150287 tst r5, r7, lsl #5 +00000124 <[^>]*> e1110113 tst r1, r3, lsl r1 +00000128 <[^>]*> e330000a teq r0, #a +0000012c <[^>]*> e1320004 teq r2, r4 +00000130 <[^>]*> e1350287 teq r5, r7, lsl #5 +00000134 <[^>]*> e1310113 teq r1, r3, lsl r1 +00000138 <[^>]*> e350000a cmp r0, #a +0000013c <[^>]*> e1520004 cmp r2, r4 +00000140 <[^>]*> e1550287 cmp r5, r7, lsl #5 +00000144 <[^>]*> e1510113 cmp r1, r3, lsl r1 +00000148 <[^>]*> e370000a cmn r0, #a +0000014c <[^>]*> e1720004 cmn r2, r4 +00000150 <[^>]*> e1750287 cmn r5, r7, lsl #5 +00000154 <[^>]*> e1710113 cmn r1, r3, lsl r1 +00000158 <[^>]*> e330f00a teqp r0, #a +0000015c <[^>]*> e132f004 teqp r2, r4 +00000160 <[^>]*> e135f287 teqp r5, r7, lsl #5 +00000164 <[^>]*> e131f113 teqp r1, r3, lsl r1 +00000168 <[^>]*> e370f00a cmnp r0, #a +0000016c <[^>]*> e172f004 cmnp r2, r4 +00000170 <[^>]*> e175f287 cmnp r5, r7, lsl #5 +00000174 <[^>]*> e171f113 cmnp r1, r3, lsl r1 +00000178 <[^>]*> e350f00a cmpp r0, #a +0000017c <[^>]*> e152f004 cmpp r2, r4 +00000180 <[^>]*> e155f287 cmpp r5, r7, lsl #5 +00000184 <[^>]*> e151f113 cmpp r1, r3, lsl r1 +00000188 <[^>]*> e310f00a tstp r0, #a +0000018c <[^>]*> e112f004 tstp r2, r4 +00000190 <[^>]*> e115f287 tstp r5, r7, lsl #5 +00000194 <[^>]*> e111f113 tstp r1, r3, lsl r1 +00000198 <[^>]*> e0000291 mul r0, r1, r2 +0000019c <[^>]*> e0110392 muls r1, r2, r3 +000001a0 <[^>]*> 10000091 mulne r0, r1, r0 +000001a4 <[^>]*> 90190798 mullss r9, r8, r7 +000001a8 <[^>]*> e021ba99 mla r1, r9, sl, fp +000001ac <[^>]*> e033c994 mlas r3, r4, r9, ip +000001b0 <[^>]*> b029d798 mlalt r9, r8, r7, sp +000001b4 <[^>]*> a034e391 mlages r4, r1, r3, lr +000001b8 <[^>]*> e5910000 ldr r0, \[r1\] +000001bc <[^>]*> e7911002 ldr r1, \[r1, r2\] +000001c0 <[^>]*> e7b32004 ldr r2, \[r3, r4\]! +000001c4 <[^>]*> e5922020 ldr r2, \[r2, #20\] +000001c8 <[^>]*> e7932424 ldr r2, \[r3, r4, lsr #8\] +000001cc <[^>]*> 07b54484 ldreq r4, \[r5, r4, lsl #9\]! +000001d0 <[^>]*> 14954006 ldrne r4, \[r5\], #6 +000001d4 <[^>]*> e6b21003 ldrt r1, \[r2\], r3 +000001d8 <[^>]*> e6942425 ldr r2, \[r4\], r5, lsr #8 +000001dc <[^>]*> e51f0008 ldr r0, 000001dc <[^>]*> +000001e0 <[^>]*> e5d43000 ldrb r3, \[r4\] +000001e4 <[^>]*> 14f85000 ldrnebt r5, \[r8\] +000001e8 <[^>]*> e5810000 str r0, \[r1\] +000001ec <[^>]*> e7811002 str r1, \[r1, r2\] +000001f0 <[^>]*> e7a33004 str r3, \[r3, r4\]! +000001f4 <[^>]*> e5822020 str r2, \[r2, #20\] +000001f8 <[^>]*> e7832424 str r2, \[r3, r4, lsr #8\] +000001fc <[^>]*> 07a54484 streq r4, \[r5, r4, lsl #9\]! +00000200 <[^>]*> 14854006 strne r4, \[r5\], #6 +00000204 <[^>]*> e6821003 str r1, \[r2\], r3 +00000208 <[^>]*> e6a42425 strt r2, \[r4\], r5, lsr #8 +0000020c <[^>]*> e50f1004 str r1, 00000210 <[^>]*> +00000210 <[^>]*> e5c71000 strb r1, \[r7\] +00000214 <[^>]*> e4e02000 strbt r2, \[r0\] +00000218 <[^>]*> e8900002 ldmia r0, {r1} +0000021c <[^>]*> 09920038 ldmeqib r2, {r3, r4, r5} +00000220 <[^>]*> e853ffff ldmda r3, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, sp, lr, pc}\^ +00000224 <[^>]*> e93b05ff ldmdb fp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, sl} +00000228 <[^>]*> e99100f7 ldmib r1, {r0, r1, r2, r4, r5, r6, r7} +0000022c <[^>]*> e89201f8 ldmia r2, {r3, r4, r5, r6, r7, r8} +00000230 <[^>]*> e9130003 ldmdb r3, {r0, r1} +00000234 <[^>]*> e8740300 ldmda r4!, {r8, r9}\^ +00000238 <[^>]*> e8800002 stmia r0, {r1} +0000023c <[^>]*> 09820038 stmeqib r2, {r3, r4, r5} +00000240 <[^>]*> e843ffff stmda r3, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, sp, lr, pc}\^ +00000244 <[^>]*> e92a05ff stmdb sl!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, sl} +00000248 <[^>]*> e8010007 stmda r1, {r0, r1, r2} +0000024c <[^>]*> e9020018 stmdb r2, {r3, r4} +00000250 <[^>]*> e8830003 stmia r3, {r0, r1} +00000254 <[^>]*> e9e40300 stmib r4!, {r8, r9}\^ +00000258 <[^>]*> ef123456 swi 0x00123456 +0000025c <[^>]*> 2f000033 swics 0x00000033 +00000260 <[^>]*> ebfffffe bl 00000260 <[^>]*> +[ ]*RELOC: 00000260 ARM26 _wombat +00000264 <[^>]*> 5bffffe9 blpl 00000210 +00000268 <[^>]*> eafffffe b 00000268 <[^>]*> +[ ]*RELOC: 00000268 ARM26 _wibble +0000026c <[^>]*> dafffffe ble 0000026c <[^>]*> +[ ]*RELOC: 0000026c ARM26 testerfunc diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/arm/thumb.s b/gnu/usr.bin/binutils/gas/testsuite/gas/arm/thumb.s new file mode 100644 index 00000000000..095befbcde8 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/arm/thumb.s @@ -0,0 +1,185 @@ + .text + .code 16 +foo: + lsl r2, r1, #3 + lsr r3, r4, #31 +wibble/data: + asr r7, r0, #5 + + lsl r1, r2, #0 + lsr r3, r4, #0 + asr r4, r5, #0 + + lsr r6, r7, #32 + asr r0, r1, #32 + + add r1, r2, r3 + add r2, r4, #2 + sub r3, r5, r7 + sub r2, r4, #7 + + mov r4, #255 + cmp r3, #250 + add r6, #123 + sub r5, #128 + + and r3, r5 + eor r4, r6 + lsl r1, r0 + lsr r2, r3 + asr r4, r6 + adc r5, r7 + sbc r0, r4 + ror r1, r4 + tst r2, r5 + neg r1, r1 + cmp r2, r3 + cmn r1, r4 + orr r0, r3 + mul r4, r5 + bic r5, r7 + mvn r5, r5 + + add r1, r13 + add r12, r2 + add r9, r9 + cmp r1, r14 + cmp r8, r0 + cmp r12, r14 + mov r0, r9 + mov r9, r4 + mov r8, r8 + bx r7 + bx r8 + .align 0 + bx pc + + ldr r3, [pc, #128] + ldr r4, bar + + str r0, [r1, r2] + strb r1, [r2, r4] + ldr r5, [r6, r7] + ldrb r2, [r4, r5] + + .align 0 +bar: + strh r1, [r2, r3] + ldrh r3, [r4, r0] + ldsb r1, [r6, r7] + ldsh r2, [r0, r5] + + str r3, [r3, #124] + ldr r1, [r4, #124] + ldr r5, [r5] + strb r1, [r5, #31] + strb r1, [r4, #5] + strb r2, [r6] + + strh r4, [r5, #62] + ldrh r5, [r0, #4] + ldrh r3, [r2] + + str r3, [r13, #1020] + ldr r1, [r13, #44] + ldr r2, [r13] + + add r7, r15, #1020 + add r4, r13, #512 + + add r13, #268 + add r13, #-104 + sub r13, #268 + sub r13, #-108 + + push {r0, r1, r2, r4} + push {r0, r3-r7, lr} + pop {r3, r4, r7} + pop {r0-r7, r15} + + stmia r3!, {r0, r1, r4-r7} + ldmia r0!, {r1-r7} + + beq bar + bne bar + bcs bar + bcc bar + bmi bar + bpl bar + bvs bar + bvc bar + bhi bar + bls bar + bge bar + bgt bar + blt bar + bgt bar + ble bar + bhi bar + blo bar + bul bar + +close: + lsl r4, r5, #near - close +near: + add r2, r3, #near - close + + add sp, sp, #127 << 2 + sub sp, sp, #127 << 2 + add r0, sp, #255 << 2 + add r0, pc, #255 << 2 + + add sp, sp, #bar - foo + sub sp, sp, #bar - foo + add r0, sp, #bar - foo + add r0, pc, #bar - foo + + add r1, #bar - foo + mov r6, #bar - foo + cmp r7, #bar - foo + + nop + nop + + .arm +localbar: + b localbar + b wombat + bl localbar + bl wombat + + bx r0 + swi 0x123456 + + .thumb + + adr r0, forwardonly + + b foo + b wombat + bl foo + bl wombat + + bx r0 + + swi 0xff + .align 0 +forwardonly: + beq wombat + bne wombat + bcs wombat + bcc wombat + bmi wombat + bpl wombat + bvs wombat + bvc wombat + bhi wombat + bls wombat + bge wombat + bgt wombat + blt wombat + bgt wombat + ble wombat + bhi wombat + blo wombat + bul wombat diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/addsubs.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/addsubs.s new file mode 100644 index 00000000000..b0b3699e458 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/addsubs.s @@ -0,0 +1,25 @@ + .h8300s + .text +h8300s_add_sub: + add.b #16,r1l + add.b r1h,r1l + add.w #32,r1 + add.w r1,r2 + add.l #64,er1 + add.l er1,er2 + adds #1,er4 + adds #2,er5 + adds #4,er6 + addx r0l,r1l + addx #16,r2h + sub.b r0l,r1l + sub.w #16,r1 + sub.w r0,r1 + sub.l #64,er1 + sub.l er1,er2 + subs #1,er4 + subs #2,er5 + subs #4,er6 + subx r0l,r1l + subx #16,r2h + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/bitops1s.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/bitops1s.s new file mode 100644 index 00000000000..c6599d41a9a --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/bitops1s.s @@ -0,0 +1,29 @@ + .h8300s + .text +h8300s_bit_ops_1: + band #0,r0l + band #0,@er0 + band #0,@64:8 + band #0,@128:16 + band #0,@65536:32 + bclr #0,r0l + bclr #0,@er0 + bclr #0,@64:8 + bclr #0,@128:16 + bclr #0,@65536:32 + bclr r1l,r0l + bclr r1l,@er0 + bclr r1l,@64:8 + bclr r1l,@128:16 + bclr r1l,@65536:32 + biand #0,r0l + biand #0,@er0 + biand #0,@64:8 + biand #0,@128:16 + biand #0,@65536:32 + bild #0,r0l + bild #0,@er0 + bild #0,@64:8 + bild #0,@128:16 + bild #0,@65536:32 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/bitops2s.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/bitops2s.s new file mode 100644 index 00000000000..94705201f0d --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/bitops2s.s @@ -0,0 +1,23 @@ + .h8300s + .text +h8300s_bit_ops_2: + bior #0,r0l + bior #0,@er0 + bior #0,@64:8 + bior #0,@128:16 + bior #0,@65536:32 + bist #0,r0l + bist #0,@er0 + bist #0,@64:8 + bist #0,@128:16 + bist #0,@65536:32 + bixor #0,r0l + bixor #0,@er0 + bixor #0,@64:8 + bixor #0,@128:16 + bixor #0,@65536:32 + bld #0,r0l + bld #0,@er0 + bld #0,@64:8 + bld #0,@128:16 + bld #0,@65536:32 diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/bitops3s.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/bitops3s.s new file mode 100644 index 00000000000..7c64e06d783 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/bitops3s.s @@ -0,0 +1,24 @@ + .h8300s + .text +h8300s_bit_ops_3: + bnot #0,r0l + bnot #0,@er0 + bnot #0,@64:8 + bnot #0,@128:16 + bnot #0,@65536:32 + bnot r1l,r0l + bnot r1l,@er0 + bnot r1l,@64:8 + bnot r1l,@128:16 + bnot r1l,@65536:32 + bset #0,r0l + bset #0,@er0 + bset #0,@64:8 + bset #0,@128:16 + bset #0,@65536:32 + bset r1l,r0l + bset r1l,@er0 + bset r1l,@64:8 + bset r1l,@128:16 + bset r1l,@65536:32 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/bitops4s.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/bitops4s.s new file mode 100644 index 00000000000..e8f47b6dc21 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/bitops4s.s @@ -0,0 +1,29 @@ + .h8300s + .text +h8300s_bit_ops_4: + bor #0,r0l + bor #0,@er0 + bor #0,@64:8 + bor #0,@128:16 + bor #0,@65536:32 + bst #0,r0l + bst #0,@er0 + bst #0,@64:8 + bst #0,@128:16 + bst #0,@65536:32 + btst #0,r0l + btst #0,@er0 + btst #0,@64:8 + btst #0,@128:16 + btst #0,@65536:32 + btst r1l,r0l + btst r1l,@er0 + btst r1l,@64:8 + btst r1l,@128:16 + btst r1l,@65536:32 + bxor #0,r0l + bxor #0,@er0 + bxor #0,@64:8 + bxor #0,@128:16 + bxor #0,@65536:32 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/branch.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/branch.s new file mode 100644 index 00000000000..25806153c42 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/branch.s @@ -0,0 +1,10 @@ + .text +h8300_branches: + bsr h8300_branches + jmp h8300_branches + jmp @r0 + jmp @@16:8 + jsr h8300_branches + jsr @r0 + jsr @@16:8 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/branchh.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/branchh.s new file mode 100644 index 00000000000..7cbc62f3e2b --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/branchh.s @@ -0,0 +1,12 @@ + .h8300h + .text +h8300h_branches: + bsr h8300h_branches:8 + bsr h8300h_branches:16 + jmp h8300h_branches + jmp @er0 + jmp @@16:8 + jsr h8300h_branches + jsr @er0 + jsr @@16:8 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/branchs.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/branchs.s new file mode 100644 index 00000000000..8f33e17967a --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/branchs.s @@ -0,0 +1,12 @@ + .h8300s + .text +h8300s_branches: + bsr h8300s_branches:8 + bsr h8300s_branches:16 + jmp h8300s_branches + jmp @er0 + jmp @@16:8 + jsr h8300s_branches + jsr @er0 + jsr @@16:8 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/cbranchh.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/cbranchh.s index 3582bb162ce..a64e1a2aade 100644 --- a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/cbranchh.s +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/cbranchh.s @@ -1,4 +1,5 @@ .text + .h8300h h8300h_cbranch: bra h8300h_cbranch:8 bt h8300h_cbranch:8 diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/cbranchs.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/cbranchs.s new file mode 100644 index 00000000000..14222ea7721 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/cbranchs.s @@ -0,0 +1,44 @@ + .text + .h8300s +h8300s_cbranch: + bra h8300s_cbranch:8 + bt h8300s_cbranch:8 + brn h8300s_cbranch:8 + bf h8300s_cbranch:8 + bhi h8300s_cbranch:8 + bls h8300s_cbranch:8 + bcc h8300s_cbranch:8 + bhs h8300s_cbranch:8 + bcs h8300s_cbranch:8 + blo h8300s_cbranch:8 + bne h8300s_cbranch:8 + beq h8300s_cbranch:8 + bvc h8300s_cbranch:8 + bvs h8300s_cbranch:8 + bpl h8300s_cbranch:8 + bmi h8300s_cbranch:8 + bge h8300s_cbranch:8 + blt h8300s_cbranch:8 + bgt h8300s_cbranch:8 + ble h8300s_cbranch:8 + bra h8300s_cbranch:16 + bt h8300s_cbranch:16 + brn h8300s_cbranch:16 + bf h8300s_cbranch:16 + bhi h8300s_cbranch:16 + bls h8300s_cbranch:16 + bcc h8300s_cbranch:16 + bhs h8300s_cbranch:16 + bcs h8300s_cbranch:16 + blo h8300s_cbranch:16 + bne h8300s_cbranch:16 + beq h8300s_cbranch:16 + bvc h8300s_cbranch:16 + bvs h8300s_cbranch:16 + bpl h8300s_cbranch:16 + bmi h8300s_cbranch:16 + bge h8300s_cbranch:16 + blt h8300s_cbranch:16 + bgt h8300s_cbranch:16 + ble h8300s_cbranch:16 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/compares.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/compares.s new file mode 100644 index 00000000000..e23f3fe8e94 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/compares.s @@ -0,0 +1,10 @@ + .h8300s + .text +h8300s_cmp: + cmp.b #0,r0l + cmp.b r0h,r0l + cmp.w #32,r0 + cmp.w r0,r1 + cmp.l #64,er0 + cmp.l er0,er1 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/decimals.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/decimals.s new file mode 100644 index 00000000000..b7802fcf1ac --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/decimals.s @@ -0,0 +1,6 @@ + .h8300s + .text +h8300s_decimal: + daa r0l + das r0l + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/divmuls.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/divmuls.s new file mode 100644 index 00000000000..db60f8f49aa --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/divmuls.s @@ -0,0 +1,12 @@ + .h8300h + .text +h8300h_div_mul: + divxu.b r0l,r1 + divxu.w r0,er1 + divxs.b r0l,r1 + divxs.w r0,er1 + mulxu.b r0l,r1 + mulxu.w r0,er1 + mulxs.b r0l,r1 + mulxs.w r0,er1 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/extends.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/extends.s new file mode 100644 index 00000000000..a26e9ba70a3 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/extends.s @@ -0,0 +1,8 @@ + .h8300s + .text +h8300s_extend: + exts.w r0 + exts.l er0 + extu.w r0 + extu.l er0 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/incdecs.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/incdecs.s new file mode 100644 index 00000000000..2345708b023 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/incdecs.s @@ -0,0 +1,14 @@ + .h8300s + .text +h8300s_incdec: + dec.b r0l + dec.w #1,r0 + dec.w #2,r0 + dec.l #1,er0 + dec.l #2,er0 + inc.b r0l + inc.w #1,r0 + inc.w #2,r0 + inc.l #1,er0 + inc.l #2,er0 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/logicals.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/logicals.s new file mode 100644 index 00000000000..c3c4cbaaf0f --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/logicals.s @@ -0,0 +1,34 @@ + .h8300s + .text +h8300s_logical: + and.b #16,r1l + and.b r1l,r1h + and.w #32,r1 + and.w r1,r1 + and.l #64,er1 + and.l er1,er1 + andc #16,ccr + andc #16,exr + or.b #16,r0l + or.b r1l,r0l + or.w #32,r1 + or.w r1,r1 + or.l #64,er1 + or.l er1,er1 + orc #16,ccr + orc #16,exr + xor.b #16,r0l + xor.b r0l,r1l + xor.w #32,r1 + xor.w r1,r1 + xor.l #64,er1 + xor.l er1,er1 + xorc #16,ccr + xorc #16,exr + neg.b r0l + neg.w r0 + neg.l er0 + not.b r0l + not.w r0 + not.l er0 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/macs.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/macs.s new file mode 100644 index 00000000000..3623ea36117 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/macs.s @@ -0,0 +1,9 @@ + .h8300s + .text +h8300s_mac: + clrmac + ldmac er0,mach + ldmac er1,macl + mac @er0+,@er1+ + + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/misch.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/misch.s index 4127c86695e..f7ecb3de079 100644 --- a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/misch.s +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/misch.s @@ -2,7 +2,7 @@ .text h8300h_misc: eepmov.b -; eepmov.w + eepmov.w ldc.b #0,ccr ldc.b r0l,ccr ldc.w @er0,ccr diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/miscs.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/miscs.s new file mode 100644 index 00000000000..d37a1770c75 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/miscs.s @@ -0,0 +1,41 @@ + .h8300s + .text +h8300s_misc: + eepmov.b + eepmov.w + ldc.b #0,ccr + ldc.b r0l,ccr + ldc.b #0,exr + ldc.b r0l,exr + ldc.w @er0,ccr + ldc.w @(16:16,er0),ccr + ldc.w @(32:32,er0),ccr + ldc.w @er0+,ccr + ldc.w @h8300s_misc:16,ccr + ldc.w @h8300s_misc:32,ccr + ldc.w @er0,exr + ldc.w @(16:16,er0),exr + ldc.w @(32:32,er0),exr + ldc.w @er0+,exr + ldc.w @h8300s_misc:16,exr + ldc.w @h8300s_misc:32,exr +; movfpe 16:16,r0l +; movtpe r0l,16:16 + nop + rte + rts + sleep + stc.b ccr,r0l + stc.b exr,r0l + stc.w ccr,@er0 + stc.w ccr,@(16:16,er0) + stc.w ccr,@(32:32,er0) + stc.w ccr,@-er0 + stc.w ccr,@h8300s_misc:16 + stc.w ccr,@h8300s_misc:32 + stc.w exr,@er0 + stc.w exr,@(16:16,er0) + stc.w exr,@(32:32,er0) + stc.w exr,@-er0 + stc.w exr,@h8300s_misc:16 + stc.w exr,@h8300s_misc:32 diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/movbs.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/movbs.s new file mode 100644 index 00000000000..925002c811a --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/movbs.s @@ -0,0 +1,20 @@ + .h8300s + .text +h8300s_movb: + mov.b r0l,r1l + mov.b #16,r0l + mov.b @er1,r0l + mov.b @(16:16,er1),r0l + mov.b @(32:32,er1),r0l + mov.b @er1+,r0l + mov.b @16:8,r0l + mov.b @h8300s_movb:16,r0l + mov.b @h8300s_movb:32,r0l + mov.b r0l,@er1 + mov.b r0l,@(16:16,er1) + mov.b r0l,@(32:32,er1) + mov.b r0l,@-er1 + mov.b r0l,@16:8 + mov.b r0l,@h8300s_movb:16 + mov.b r0l,@h8300s_movb:32 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/movls.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/movls.s new file mode 100644 index 00000000000..46437677389 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/movls.s @@ -0,0 +1,18 @@ + .h8300s + .text +h8300s_movl: + mov.l er0,er1 + mov.l #64,er0 + mov.l @er1,er0 + mov.l @(16:16,er1),er0 + mov.l @(32:32,er1),er0 + mov.l @er1+,er0 + mov.l @h8300s_movl:16,er0 + mov.l @h8300s_movl:32,er0 + mov.l er0,@er1 + mov.l er0,@(16:16,er1) + mov.l er0,@(32:32,er1) + mov.l er0,@-er1 + mov.l er0,@h8300s_movl:16 + mov.l er0,@h8300s_movl:32 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/movws.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/movws.s new file mode 100644 index 00000000000..a4f21df2542 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/movws.s @@ -0,0 +1,18 @@ + .h8300s + .text +h8300s_movw: + mov.w r0,r1 + mov.w #16,r0 + mov.w @er1,r0 + mov.w @(16:16,er1),r0 + mov.w @(32:32,er1),r0 + mov.w @er1+,r0 + mov.w @h8300s_movw:16,r0 + mov.w @h8300s_movw:32,r0 + mov.w r0,@er1 + mov.w r0,@(16:16,er1) + mov.w r0,@(32:32,er1) + mov.w r0,@-er1 + mov.w r0,@h8300s_movw:16 + mov.w r0,@h8300s_movw:32 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/multiples.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/multiples.s new file mode 100644 index 00000000000..52079b6d219 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/multiples.s @@ -0,0 +1,10 @@ + .h8300s + .text +h8300s_multiple: + ldm.l @sp+,er0-er1 + ldm.l @sp+,er0-er2 + ldm.l @sp+,er0-er3 + stm.l er0-er1,@-sp + stm.l er0-er2,@-sp + stm.l er0-er3,@-sp + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/pushpops.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/pushpops.s new file mode 100644 index 00000000000..741df04ecc5 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/pushpops.s @@ -0,0 +1,8 @@ + .h8300s + .text +h8300s_push_pop: + pop.w r0 + pop.l er0 + push.w r0 + push.l er0 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/rotsh.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/rotsh.s new file mode 100644 index 00000000000..a9aa87df95e --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/rotsh.s @@ -0,0 +1,11 @@ + .text +h8300_rotate_shift: + rotl r0l + rotr r0l + rotxl r0l + rotxr r0l + shal r0l + shar r0l + shll r0l + shlr r0l + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/rotshh.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/rotshh.s new file mode 100644 index 00000000000..c7abe40a28f --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/rotshh.s @@ -0,0 +1,27 @@ + .h8300h + .text +h8300h_rotate_shift: + rotl.b r0l + rotl.w r0 + rotl.l er0 + rotr.b r0l + rotr.w r0 + rotr.l er0 + rotxl.b r0l + rotxl.w r0 + rotxl.l er0 + rotxr.b r0l + rotxr.w r0 + rotxr.l er0 + shal.b r0l + shal.w r0 + shal.l er0 + shar.b r0l + shar.w r0 + shar.l er0 + shll.b r0l + shll.w r0 + shll.l er0 + shlr.b r0l + shlr.w r0 + shlr.l er0 diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/rotshs.s b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/rotshs.s new file mode 100644 index 00000000000..36c41cb59c5 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/h8300/rotshs.s @@ -0,0 +1,51 @@ + .h8300s + .text +h8300s_rotate_shift: + rotl.b r0l + rotl.b #2,r0l + rotl.w r0 + rotl.w #2,r0 + rotl.l er0 + rotl.l #2,er0 + rotr.b r0l + rotr.b #2,r0l + rotr.w r0 + rotr.w #2,r0 + rotr.l er0 + rotr.l #2,er0 + rotxl.b r0l + rotxl.b #2,r0l + rotxl.w r0 + rotxl.w #2,r0 + rotxl.l er0 + rotxl.l #2,er0 + rotxr.b r0l + rotxr.b #2,r0l + rotxr.w r0 + rotxr.w #2,r0 + rotxr.l er0 + rotxr.l #2,er0 + shal.b r0l + shal.b #2,r0l + shal.w r0 + shal.w #2,r0 + shal.l er0 + shal.l #2,er0 + shar.b r0l + shar.b #2,r0l + shar.w r0 + shar.w #2,r0 + shar.l er0 + shar.l #2,er0 + shll.b r0l + shll.b #2,r0l + shll.w r0 + shll.w #2,r0 + shll.l er0 + shll.l #2,er0 + shlr.b r0l + shlr.b #2,r0l + shlr.w r0 + shlr.w #2,r0 + shlr.l er0 + shlr.l #2,er0 diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/hppa/basic/basic.exp b/gnu/usr.bin/binutils/gas/testsuite/gas/hppa/basic/basic.exp index 30d9010b16e..73c5027595c 100644 --- a/gnu/usr.bin/binutils/gas/testsuite/gas/hppa/basic/basic.exp +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/hppa/basic/basic.exp @@ -1503,9 +1503,9 @@ proc do_system {} { -re "^ +\[0-9\]+ 0054 04A41326\[^\n]*\n" { set x [expr $x+1] } -re "^ +\[0-9\]+ 0058 04A41306\[^\n]*\n" { set x [expr $x+1] } -re "^ +\[0-9\]+ 005c 04A41040\[^\n]*\n" { set x [expr $x+1] } - -re "^ +\[0-9\]+ 0060 04A40040\[^\n]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0060 04A42040\[^\n]*\n" { set x [expr $x+1] } -re "^ +\[0-9\]+ 0064 04A41000\[^\n]*\n" { set x [expr $x+1] } - -re "^ +\[0-9\]+ 0068 04A40000\[^\n]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0068 04A42000\[^\n]*\n" { set x [expr $x+1] } -re "\[^\n\]*\n" { } timeout { perror "timeout\n"; break } eof { break } @@ -1537,22 +1537,22 @@ proc do_purge {} { expect { -re "^ +\[0-9\]+ 0000 04A41200\[^\n]*\n" { set x [expr $x+1] } -re "^ +\[0-9\]+ 0004 04A41220\[^\n]*\n" { set x [expr $x+1] } - -re "^ +\[0-9\]+ 0008 04A40200\[^\n]*\n" { set x [expr $x+1] } - -re "^ +\[0-9\]+ 000c 04A40220\[^\n]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0008 04A42200\[^\n]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 000c 04A42220\[^\n]*\n" { set x [expr $x+1] } -re "^ +\[0-9\]+ 0010 04A41240\[^\n]*\n" { set x [expr $x+1] } -re "^ +\[0-9\]+ 0014 04A41260\[^\n]*\n" { set x [expr $x+1] } - -re "^ +\[0-9\]+ 0018 04A40240\[^\n]*\n" { set x [expr $x+1] } - -re "^ +\[0-9\]+ 001c 04A40260\[^\n]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0018 04A42240\[^\n]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 001c 04A42260\[^\n]*\n" { set x [expr $x+1] } -re "^ +\[0-9\]+ 0020 04A41380\[^\n]*\n" { set x [expr $x+1] } -re "^ +\[0-9\]+ 0024 04A413A0\[^\n]*\n" { set x [expr $x+1] } -re "^ +\[0-9\]+ 0028 04A41280\[^\n]*\n" { set x [expr $x+1] } -re "^ +\[0-9\]+ 002c 04A412A0\[^\n]*\n" { set x [expr $x+1] } - -re "^ +\[0-9\]+ 0030 04A40280\[^\n]*\n" { set x [expr $x+1] } - -re "^ +\[0-9\]+ 0034 04A402A0\[^\n]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0030 04A42280\[^\n]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0034 04A422A0\[^\n]*\n" { set x [expr $x+1] } -re "^ +\[0-9\]+ 0038 04A412C0\[^\n]*\n" { set x [expr $x+1] } -re "^ +\[0-9\]+ 003c 04A412E0\[^\n]*\n" { set x [expr $x+1] } - -re "^ +\[0-9\]+ 0040 04A402C0\[^\n]*\n" { set x [expr $x+1] } - -re "^ +\[0-9\]+ 0044 04A402E0\[^\n]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0040 04A422C0\[^\n]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0044 04A422E0\[^\n]*\n" { set x [expr $x+1] } -re "\[^\n\]*\n" { } timeout { perror "timeout\n"; break } diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/hppa/basic/purge.s b/gnu/usr.bin/binutils/gas/testsuite/gas/hppa/basic/purge.s index 6c0f41c9305..2319f90839e 100644 --- a/gnu/usr.bin/binutils/gas/testsuite/gas/hppa/basic/purge.s +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/hppa/basic/purge.s @@ -16,20 +16,20 @@ ; selectors to make sure they're handled correctly. pdtlb %r4(%sr0,%r5) pdtlb,m %r4(%sr0,%r5) - pitlb %r4(%sr0,%r5) - pitlb,m %r4(%sr0,%r5) + pitlb %r4(%sr4,%r5) + pitlb,m %r4(%sr4,%r5) pdtlbe %r4(%sr0,%r5) pdtlbe,m %r4(%sr0,%r5) - pitlbe %r4(%sr0,%r5) - pitlbe,m %r4(%sr0,%r5) + pitlbe %r4(%sr4,%r5) + pitlbe,m %r4(%sr4,%r5) pdc %r4(%sr0,%r5) pdc,m %r4(%sr0,%r5) fdc %r4(%sr0,%r5) fdc,m %r4(%sr0,%r5) - fic %r4(%sr0,%r5) - fic,m %r4(%sr0,%r5) + fic %r4(%sr4,%r5) + fic,m %r4(%sr4,%r5) fdce %r4(%sr0,%r5) fdce,m %r4(%sr0,%r5) - fice %r4(%sr0,%r5) - fice,m %r4(%sr0,%r5) + fice %r4(%sr4,%r5) + fice,m %r4(%sr4,%r5) diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/hppa/basic/system.s b/gnu/usr.bin/binutils/gas/testsuite/gas/hppa/basic/system.s index d35e0016189..1b2e7bf1763 100644 --- a/gnu/usr.bin/binutils/gas/testsuite/gas/hppa/basic/system.s +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/hppa/basic/system.s @@ -41,6 +41,6 @@ lci %r4(%sr0,%r5),%r6 idtlba %r4,(%sr0,%r5) - iitlba %r4,(%sr0,%r5) + iitlba %r4,(%sr4,%r5) idtlbp %r4,(%sr0,%r5) - iitlbp %r4,(%sr0,%r5) + iitlbp %r4,(%sr4,%r5) diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/m68k/pcrel.d b/gnu/usr.bin/binutils/gas/testsuite/gas/m68k/pcrel.d new file mode 100644 index 00000000000..c5ced5bf2e1 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/m68k/pcrel.d @@ -0,0 +1,88 @@ +#name: pcrel +#objdump: -drs -j .text + +.*: file format .* + +Contents of section .text: + 0000 4e714e71 4cfa0300 fffa4cfa 0300fff4 NqNqL.....L..... + 0010 4cfb0300 08ee41fa ffea41fa ffe641fa L.....A...A...A. + 0020 ff6241fb 08de41fb 08da41fb 08d641fb .bA...A...A...A. + 0030 0920ffd2 41fb0920 ffcc41fb 0930ffff . ..A.. ..A..0.. + 0040 ffc641fb 0930ffff ffbe4e71 61ff0000 ..A..0....Nqa... + 0050 00586100 0052614e 614c4e71 41f90000 .Xa..RaNaLNqA... + 0060 00(a6|00)41fa 004241fa 00be41fb 083a41fb ..A..BA...A..:A. + 0070 083641fb 083241fb 0920002e 41fb0920 .6A..2A.. ..A.. + 0080 002841fb 09300000 002241fb 09300000 .\(A..0..."A..0.. + 0090 001a41fb 09300000 001241fb 0920000a ..A..0....A.. .. + 00a0 41fb0804 4e714e71 4e7141fb 088041fb A...NqNqNqA...A. + 00b0 0920ff7f 41fb0920 800041fb 0930ffff . ..A.. ..A..0.. + 00c0 7fff4e71 41fb087f 41fb0920 008041fb ..NqA...A.. ..A. + 00d0 09207fff 41fb0930 00008000 4e7141fa . ..A..0....NqA. + 00e0 800041fb 0170ffff 7fff4e71 41fa7fff ..A..p....NqA... + 00f0 41fb0170 00008000 4e7141fb 0170(ffff|0000) A..p....NqA..p.. + 0100 (ff04|0000)41fb 0930(ffff|0000) (fefc|0000)4e71 41f90000 ..A..0....NqA... + 0110 0000............................... ................ +Disassembly of section \.text: +0+0000 <.*> nop +0+0002 nop +0+0004 moveml 0+0002 ,%a0-%a1 +0+000a moveml 0+0002 ,%a0-%a1 +0+0010 moveml %pc@\(0+02 ,%d0:l\),%a0-%a1 +0+0016 lea 0+0002 ,%a0 +0+001a lea 0+0002 ,%a0 +0+001e lea f+ff82 <.*>,%a0 +0+0022 lea %pc@\(0+02 ,%d0:l\),%a0 +0+0026 lea %pc@\(0+02 ,%d0:l\),%a0 +0+002a lea %pc@\(0+02 ,%d0:l\),%a0 +0+002e lea %pc@\(0+02 ,%d0:l\),%a0 +0+0034 lea %pc@\(0+02 ,%d0:l\),%a0 +0+003a lea %pc@\(0+02 ,%d0:l\),%a0 +0+0042 lea %pc@\(0+02 ,%d0:l\),%a0 +0+004a nop +0+004c bsrl 0+00a6 +0+0052 bsrw 0+00a6 +0+0056 bsrs 0+00a6 +0+0058 bsrs 0+00a6 +0+005a nop +0+005c lea (0+00a6 |0+0 <.*>),%a0 + RELOC: 0+005e (32 \.text|R_68K_32 \.text\+0x0+00a6) +0+0062 lea 0+00a6 ,%a0 +0+0066 lea 0+0126 <.*>,%a0 +0+006a lea %pc@\(0+a6 ,%d0:l\),%a0 +0+006e lea %pc@\(0+a6 ,%d0:l\),%a0 +0+0072 lea %pc@\(0+a6 ,%d0:l\),%a0 +0+0076 lea %pc@\(0+a6 ,%d0:l\),%a0 +0+007c lea %pc@\(0+a6 ,%d0:l\),%a0 +0+0082 lea %pc@\(0+a6 ,%d0:l\),%a0 +0+008a lea %pc@\(0+a6 ,%d0:l\),%a0 +0+0092 lea %pc@\(0+a6 ,%d0:l\),%a0 +0+009a lea %pc@\(0+a6 ,%d0:l\),%a0 +0+00a0 lea %pc@\(0+a6 ,%d0:l\),%a0 +0+00a4 nop +0+00a6 nop +0+00a8 nop +0+00aa lea %pc@\(0+2c ,%d0:l\),%a0 +0+00ae lea %pc@\(0+2f ,%d0:l\),%a0 +0+00b4 lea %pc@\(f+80b6 <.*>,%d0:l\),%a0 +0+00ba lea %pc@\(f+80bb <.*>,%d0:l\),%a0 +0+00c2 nop +0+00c4 lea %pc@\(0+145 <.*>,%d0:l\),%a0 +0+00c8 lea %pc@\(0+14a <.*>,%d0:l\),%a0 +0+00ce lea %pc@\(0+80cf <.*>,%d0:l\),%a0 +0+00d4 lea %pc@\(0+80d6 <.*>,%d0:l\),%a0 +0+00dc nop +0+00de lea f+80e0 <.*>,%a0 +0+00e2 lea %pc@\(f+80e3 <.*>\),%a0 +0+00ea nop +0+00ec lea 0+80ed <.*>,%a0 +0+00f0 lea %pc@\(0+80f2 <.*>\),%a0 +0+00f8 nop +0+00fa lea %pc@\((0+0 <.*>|0+0fc )\),%a0 + RELOC: 0+00fe (DISP32 undef|R_68K_PC32 undef\+0x0+02) +0+0102 lea %pc@\((0+0 <.*>|0+0104 ),%d0:l\),%a0 + RELOC: 0+0106 (DISP32 undef|R_68K_PC32 undef\+0x0+02) +0+010a nop +0+010c lea 0+0 <.*>,%a0 + RELOC: 0+010e (R_68K_)?32 undef +0+0112 nop +\.\.\. diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/m68k/pcrel.s b/gnu/usr.bin/binutils/gas/testsuite/gas/m68k/pcrel.s new file mode 100644 index 00000000000..9c5c22b90fb --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/m68k/pcrel.s @@ -0,0 +1,59 @@ + nop +lbl_b: nop + moveml lbl_b,%a0-%a1 + moveml %pc@(lbl_b),%a0-%a1 + moveml %pc@(lbl_b,%d0),%a0-%a1 + lea lbl_b,%a0 + lea %pc@(lbl_b),%a0 + lea %pc@(lbl_b-128),%a0 + lea %pc@(lbl_b,%d0),%a0 + lea %pc@(lbl_b:b,%d0),%a0 + lea %pc@(lbl_b-.-2:b,%d0),%a0 + lea %pc@(lbl_b:w,%d0),%a0 + lea %pc@(lbl_b-.-2:w,%d0),%a0 + lea %pc@(lbl_b:l,%d0),%a0 + lea %pc@(lbl_b-.-2:l,%d0),%a0 + nop + bsrl lbl_a + bsr lbl_a + bsrs lbl_a + jbsr lbl_a + nop + lea lbl_a,%a0 + lea %pc@(lbl_a),%a0 + lea %pc@(lbl_a+128),%a0 + lea %pc@(lbl_a,%d0),%a0 + lea %pc@(lbl_a:b,%d0),%a0 + lea %pc@(lbl_a-.-2:b,%d0),%a0 + lea %pc@(lbl_a:w,%d0),%a0 + lea %pc@(lbl_a-.-2:w,%d0),%a0 + lea %pc@(lbl_a:l,%d0),%a0 + lea %pc@(lbl_a-.-2:l,%d0),%a0 + lea %pc@(18:l,%d0),%a0 + lea %pc@(10:w,%d0),%a0 + lea %pc@(4:b,%d0),%a0 + nop +lbl_a: nop + nop + lea %pc@(.-126,%d0),%a0 + lea %pc@(.-127,%d0),%a0 + lea %pc@(.-32766,%d0),%a0 + lea %pc@(.-32767,%d0),%a0 + nop + lea %pc@(.+129,%d0),%a0 + lea %pc@(.+130,%d0),%a0 + lea %pc@(.+32769,%d0),%a0 + lea %pc@(.+32770,%d0),%a0 + nop + lea %pc@(.-32766),%a0 + lea %pc@(.-32767),%a0 + nop + lea %pc@(.+32769),%a0 + lea %pc@(.+32770),%a0 + nop + lea %pc@(undef),%a0 + lea %pc@(undef,%d0),%a0 + nop + lea undef,%a0 + nop + .long 0 diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/mips/div-ilocks.d b/gnu/usr.bin/binutils/gas/testsuite/gas/mips/div-ilocks.d new file mode 100644 index 00000000000..282fb41ed50 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/mips/div-ilocks.d @@ -0,0 +1,117 @@ +#objdump: -dr +#name: MIPS div +#source: div.s + +# Test the div macro. + +.*: +file format .*mips.* + +No symbols in .* +Disassembly of section .text: +0+0000 div \$zero,\$a0,\$a1 +0+0004 div \$zero,\$a0,\$a1 +0+0008 bnez \$a1,0+0014 +... +0+0010 break 0x7 +0+0014 li \$at,-1 +0+0018 bne \$a1,\$at,0+002c +0+001c lui \$at,0x8000 +0+0020 bne \$a0,\$at,0+002c +... +0+0028 break 0x6 +0+002c mflo \$a0 +0+0030 div \$zero,\$a1,\$a2 +0+0034 bnez \$a2,0+0040 +... +0+003c break 0x7 +0+0040 li \$at,-1 +0+0044 bne \$a2,\$at,0+0058 +0+0048 lui \$at,0x8000 +0+004c bne \$a1,\$at,0+0058 +... +0+0054 break 0x6 +0+0058 mflo \$a0 +0+005c move \$a0,\$a0 +0+0060 move \$a0,\$a1 +0+0064 neg \$a0,\$a0 +0+0068 neg \$a0,\$a1 +0+006c li \$at,2 +0+0070 div \$zero,\$a0,\$at +0+0074 mflo \$a0 +0+0078 li \$at,2 +0+007c div \$zero,\$a1,\$at +0+0080 mflo \$a0 +0+0084 li \$at,0x8000 +0+0088 div \$zero,\$a0,\$at +0+008c mflo \$a0 +0+0090 li \$at,0x8000 +0+0094 div \$zero,\$a1,\$at +0+0098 mflo \$a0 +0+009c li \$at,-32768 +0+00a0 div \$zero,\$a0,\$at +0+00a4 mflo \$a0 +0+00a8 li \$at,-32768 +0+00ac div \$zero,\$a1,\$at +0+00b0 mflo \$a0 +0+00b4 lui \$at,0x1 +0+00b8 div \$zero,\$a0,\$at +0+00bc mflo \$a0 +0+00c0 lui \$at,0x1 +0+00c4 div \$zero,\$a1,\$at +0+00c8 mflo \$a0 +0+00cc lui \$at,0x1 +0+00d0 ori \$at,\$at,0xa5a5 +0+00d4 div \$zero,\$a0,\$at +0+00d8 mflo \$a0 +0+00dc lui \$at,0x1 +0+00e0 ori \$at,\$at,0xa5a5 +0+00e4 div \$zero,\$a1,\$at +0+00e8 mflo \$a0 +0+00ec divu \$zero,\$a0,\$a1 +0+00f0 divu \$zero,\$a0,\$a1 +0+00f4 bnez \$a1,0+0100 +... +0+00fc break 0x7 +0+0100 mflo \$a0 +0+0104 divu \$zero,\$a1,\$a2 +0+0108 bnez \$a2,0+0114 +... +0+0110 break 0x7 +0+0114 mflo \$a0 +0+0118 move \$a0,\$a0 +0+011c div \$zero,\$a1,\$a2 +0+0120 bnez \$a2,0+012c +... +0+0128 break 0x7 +0+012c li \$at,-1 +0+0130 bne \$a2,\$at,0+0144 +0+0134 lui \$at,0x8000 +0+0138 bne \$a1,\$at,0+0144 +... +0+0140 break 0x6 +0+0144 mfhi \$a0 +0+0148 li \$at,2 +0+014c divu \$zero,\$a1,\$at +0+0150 mfhi \$a0 +0+0154 ddiv \$zero,\$a1,\$a2 +0+0158 bnez \$a2,0+0164 +... +0+0160 break 0x7 +0+0164 daddiu \$at,\$zero,-1 +0+0168 bne \$a2,\$at,0+0180 +0+016c daddiu \$at,\$zero,1 +0+0170 dsll32 \$at,\$at,0x1f +0+0174 bne \$a1,\$at,0+0180 +... +0+017c break 0x6 +0+0180 mflo \$a0 +0+0184 li \$at,2 +0+0188 ddivu \$zero,\$a1,\$at +0+018c mflo \$a0 +0+0190 li \$at,0x8000 +0+0194 ddiv \$zero,\$a1,\$at +0+0198 mfhi \$a0 +0+019c li \$at,-32768 +0+01a0 ddivu \$zero,\$a1,\$at +0+01a4 mfhi \$a0 +... diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/mips/mul-ilocks.d b/gnu/usr.bin/binutils/gas/testsuite/gas/mips/mul-ilocks.d new file mode 100644 index 00000000000..257e2ad4c64 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/mips/mul-ilocks.d @@ -0,0 +1,81 @@ +#objdump: -dr +#name: MIPS mul +#source: mul.s + +# Test the mul macro. + +.*: +file format .*mips.* + +No symbols in .* +Disassembly of section .text: +0+0000 multu \$a0,\$a1 +0+0004 mflo \$a0 +0+0008 multu \$a1,\$a2 +0+000c mflo \$a0 +0+0010 li \$at,0 +0+0014 mult \$a1,\$at +0+0018 mflo \$a0 +0+001c li \$at,1 +0+0020 mult \$a1,\$at +0+0024 mflo \$a0 +0+0028 li \$at,0x8000 +0+002c mult \$a1,\$at +0+0030 mflo \$a0 +0+0034 li \$at,-32768 +0+0038 mult \$a1,\$at +0+003c mflo \$a0 +0+0040 lui \$at,0x1 +0+0044 mult \$a1,\$at +0+0048 mflo \$a0 +0+004c lui \$at,0x1 +0+0050 ori \$at,\$at,0xa5a5 +0+0054 mult \$a1,\$at +0+0058 mflo \$a0 +0+005c mult \$a0,\$a1 +0+0060 mflo \$a0 +0+0064 sra \$a0,\$a0,0x1f +0+0068 mfhi \$at +0+006c beq \$a0,\$at,0+78 +... +0+0074 break 0x6 +0+0078 mflo \$a0 +0+007c mult \$a1,\$a2 +0+0080 mflo \$a0 +0+0084 sra \$a0,\$a0,0x1f +0+0088 mfhi \$at +0+008c beq \$a0,\$at,0+98 +... +0+0094 break 0x6 +0+0098 mflo \$a0 +0+009c multu \$a0,\$a1 +0+00a0 mfhi \$at +0+00a4 mflo \$a0 +0+00a8 beqz \$at,0+b4 +... +0+00b0 break 0x6 +0+00b4 multu \$a1,\$a2 +0+00b8 mfhi \$at +0+00bc mflo \$a0 +0+00c0 beqz \$at,0+cc +... +0+00c8 break 0x6 +0+00cc dmultu \$a1,\$a2 +0+00d0 mflo \$a0 +0+00d4 li \$at,1 +0+00d8 dmult \$a1,\$at +0+00dc mflo \$a0 +0+00e0 dmult \$a1,\$a2 +0+00e4 mflo \$a0 +0+00e8 dsra32 \$a0,\$a0,0x1f +0+00ec mfhi \$at +0+00f0 beq \$a0,\$at,0+fc +... +0+00f8 break 0x6 +0+00fc mflo \$a0 +0+0100 dmultu \$a1,\$a2 +0+0104 mfhi \$at +0+0108 mflo \$a0 +0+010c beqz \$at,0+118 +... +0+0114 break 0x6 +... diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/sh/basic.exp b/gnu/usr.bin/binutils/gas/testsuite/gas/sh/basic.exp new file mode 100644 index 00000000000..869246e80c5 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/sh/basic.exp @@ -0,0 +1,87 @@ +# Copyright (C) 1995 Free Software Foundation, Inc. + +# 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. */ + +# Please email any bugs, comments, and/or additions to this file to: +# DejaGnu@cygnus.com + +# Written by Cygnus Support. + +proc do_fp {} { + set testname "fp.s: floating point tests (sh3e)" + set x 0 + + gas_start "fp.s" "-al" + + # Check the assembled instruction against a table built by the HP assembler + # Any differences should be checked by hand -- with the number of problems + # I've seen in the HP assembler I don't completely trust it. + # + # Instead of having a variable for each match string just increment the + # total number of matches seen. That's simpler when testing large numbers + # of instructions (as these tests to). + while 1 { + expect { + -re "^ +\[0-9\]+ 0000 F008\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0002 F00A\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0004 F009\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0006 F00B\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0008 F006\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 000a F007\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 000c F10C\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 000e F08D\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0010 F09D\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0012 F100\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0014 F101\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0016 F102\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0018 F103\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 001a F10E\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 001c F104\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 001e F105\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0020 F07D\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0022 F04D\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0024 F05D\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0026 F06D\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0028 F02D\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 002a F03D\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 002c F00D\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 002e F01D\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0030 435A\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0032 4356\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0034 436A\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0036 4366\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 0038 035A\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 003a 4352\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 003c 036A\[^\n\]*\n" { set x [expr $x+1] } + -re "^ +\[0-9\]+ 003e 4362\[^\n\]*\n" { set x [expr $x+1] } + -re "\[^\n\]*\n" { } + timeout { perror "timeout\n"; break } + eof { break } + } + } + + # This was intended to do any cleanup necessary. It kinda looks like it + # isn't needed, but just in case, please keep it in for now. + gas_finish + + # Did we find what we were looking for? If not, flunk it. + if [expr $x==32] then { pass $testname } else { fail $testname } +} + + +if [istarget sh*-*-*] then { + # Test the basic instruction parser. + do_fp +} diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/sh/fp.s b/gnu/usr.bin/binutils/gas/testsuite/gas/sh/fp.s new file mode 100644 index 00000000000..3da72499f44 --- /dev/null +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/sh/fp.s @@ -0,0 +1,45 @@ + .file "test.c" + .data + +! Hitachi SH cc1 (cygnus-2.7.1-950728) arguments: -O -fpeephole +! -ffunction-cse -freg-struct-return -fdelayed-branch -fcommon -fgnu-linker + +gcc2_compiled.: +___gnu_compiled_c: + .text + .align 2 + .global _foo +_foo: + fmov.s @r0,fr0 + fmov.s fr0,@r0 + fmov.s @r0+,fr0 + fmov.s fr0,@-r0 + fmov.s @(r0,r0),fr0 + fmov.s fr0,@(r0,r0) + fmov fr0,fr1 + fldi0 fr0 + fldi1 fr0 + fadd fr0,fr1 + fsub fr0,fr1 + fmul fr0,fr1 + fdiv fr0,fr1 + fmac fr0,fr0,fr1 + fcmp/eq fr0,fr1 + fcmp/gt fr0,fr1 + ftst/nan fr0 + fneg fr0 + fabs fr0 + fsqrt fr0 + float fpul,fr0 + ftrc fr0,fpul + fsts fpul,fr0 + flds fr0,fpul + lds r3,fpul + lds.l @r3+,fpul + lds r3,fpscr + lds.l @r3+,fpscr + sts fpul,r3 + sts.l fpul,@-r3 + sts fpscr,r3 + sts.l fpscr,@-r3 + diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/sparc/asi.s b/gnu/usr.bin/binutils/gas/testsuite/gas/sparc/asi.s index 6ade4100f54..c56fe9c24db 100644 --- a/gnu/usr.bin/binutils/gas/testsuite/gas/sparc/asi.s +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/sparc/asi.s @@ -16,8 +16,8 @@ lduwa [%g1]#ASI_SNF_L,%g2 lduwa [%g1]#ASI_AS_IF_USER_PRIMARY,%g2 lduwa [%g1]#ASI_AS_IF_USER_SECONDARY,%g2 - lduwa [%g1]#ASI_AS_IF_USER_PRIMARY_L,%g2 - lduwa [%g1]#ASI_AS_IF_USER_SECONDARY_L,%g2 + lduwa [%g1]#ASI_AS_IF_USER_PRIMARY_LITTLE,%g2 + lduwa [%g1]#ASI_AS_IF_USER_SECONDARY_LITTLE,%g2 lduwa [%g1]#ASI_PRIMARY,%g2 lduwa [%g1]#ASI_SECONDARY,%g2 lduwa [%g1]#ASI_PRIMARY_NOFAULT,%g2 diff --git a/gnu/usr.bin/binutils/gas/testsuite/gas/vax/quad.exp b/gnu/usr.bin/binutils/gas/testsuite/gas/vax/quad.exp index 46fc9ca52d4..34770c5b6cf 100644 --- a/gnu/usr.bin/binutils/gas/testsuite/gas/vax/quad.exp +++ b/gnu/usr.bin/binutils/gas/testsuite/gas/vax/quad.exp @@ -8,7 +8,7 @@ proc do_quad {} { expect { -re "^ +2\[ \t\]+0000+ 7D8F7856\[ \t\]+movq\[^\n\]*\n" { set x1 1 } -re "^ +2\[ \t\]+3412DDCC\[^\n\]*\n" { set x2 1 } - -re "^ +2\[ \t\]+BBAA50\[ \t\]*\r\n" { set x3 1 } + -re "^ +2\[ \t\]+BBAA5001\[ \t\]*\r\n" { set x3 1 } -re "\[^\n\]*\n" { } timeout { perror "timeout\n"; break } eof { break } diff --git a/gnu/usr.bin/binutils/gprof/bb_exit_func.c b/gnu/usr.bin/binutils/gprof/bb_exit_func.c new file mode 100644 index 00000000000..813321566c7 --- /dev/null +++ b/gnu/usr.bin/binutils/gprof/bb_exit_func.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1994 David Mosberger-Tang. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or (at + * your option) any later version. + * + * __bb_exit_func() dumps all the basic-block statistics linked into + * the bb_head chain to .d files. + */ +#include +#include +#include "bfd.h" +#include "gmon_out.h" + +/* structure emitted by -a */ +struct bb { + long zero_word; + const char *filename; + long *counts; + long ncounts; + struct bb *next; + const unsigned long *addresses; +}; + +struct bb *__bb_head = (struct bb *)0; + + +void +__bb_exit_func (void) +{ + const int version = GMON_VERSION; + struct gmon_hdr ghdr; + struct bb *ptr; + FILE *fp; + /* + * GEN_GMON_CNT_FILE should be defined on systems with mcleanup() + * functions that do not write basic-block to gmon.out. In such + * cases profiling with "-pg -a" would result in a gmon.out file + * without basic-block info (because the file written here would + * be overwritten. Thus, a separate file is generated instead. + * The two files can easily be combined by specifying them + * on gprof's command line (and possibly generating a gmon.sum + * file with "gprof -s"). + */ +#ifndef GEN_GMON_CNT_FILE +# define OUT_NAME "gmon.out" +#else +# define OUT_NAME "gmon.cnt" +#endif + fp = fopen(OUT_NAME, "wb"); + if (!fp) { + perror(OUT_NAME); + return; + } /* if */ + memcpy(&ghdr.cookie[0], GMON_MAGIC, 4); + memcpy(&ghdr.version, &version, sizeof(version)); + fwrite(&ghdr, sizeof(ghdr), 1, fp); + + for (ptr = __bb_head; ptr != 0; ptr = ptr->next) { + u_int ncounts = ptr->ncounts; + u_char tag; + u_int i; + + tag = GMON_TAG_BB_COUNT; + fwrite(&tag, sizeof(tag), 1, fp); + fwrite(&ncounts, sizeof(ncounts), 1, fp); + + for (i = 0; i < ncounts; ++i) { + fwrite(&ptr->addresses[i], sizeof(ptr->addresses[0]), 1, fp); + fwrite(&ptr->counts[i], sizeof(ptr->counts[0]), 1, fp); + } /* for */ + } /* for */ + fclose (fp); +} /* __bb_exit_func */ + + /*** end of __bb_exit_func.c ***/ diff --git a/gnu/usr.bin/binutils/gprof/hertz.c b/gnu/usr.bin/binutils/gprof/hertz.c index 9dbc89ffc61..75314acc0c3 100644 --- a/gnu/usr.bin/binutils/gprof/hertz.c +++ b/gnu/usr.bin/binutils/gprof/hertz.c @@ -16,7 +16,6 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#include #include "hertz.h" @@ -29,7 +28,8 @@ hertz () { #ifdef HERTZ return HERTZ; -#else +#else /* ! defined (HERTZ) */ +#ifdef HAVE_SETITIMER struct itimerval tim; tim.it_interval.tv_sec = 0; @@ -43,5 +43,12 @@ hertz () return HZ_WRONG; } return 1000000 / tim.it_interval.tv_usec; -#endif +#else /* ! defined (HAVE_SETITIMER) */ +#if defined (HAVE_SYSCONF) && defined (_SC_CLK_TCK) + return sysconf (_SC_CLK_TCK); +#else /* ! defined (HAVE_SYSCONF) || ! defined (_SC_CLK_TCK) */ + return HZ_WRONG; +#endif /* ! defined (HAVE_SYSCONF) || ! defined (_SC_CLK_TCK) */ +#endif /* ! defined (HAVE_SETITIMER) */ +#endif /* ! defined (HERTZ) */ } diff --git a/gnu/usr.bin/binutils/gprof/source.c b/gnu/usr.bin/binutils/gprof/source.c index b0c6ecdb479..4421e3f757e 100644 --- a/gnu/usr.bin/binutils/gprof/source.c +++ b/gnu/usr.bin/binutils/gprof/source.c @@ -36,7 +36,7 @@ DEFUN (source_file_lookup_path, (path), const char *path) sf = (Source_File *) xmalloc (sizeof (*sf)); memset (sf, 0, sizeof (*sf)); - sf->name = strdup (path); + sf->name = xstrdup (path); sf->next = first_src_file; first_src_file = sf; } diff --git a/gnu/usr.bin/binutils/include/ansidecl.h b/gnu/usr.bin/binutils/include/ansidecl.h index be04e42d56a..94068ebaf51 100644 --- a/gnu/usr.bin/binutils/include/ansidecl.h +++ b/gnu/usr.bin/binutils/include/ansidecl.h @@ -90,7 +90,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* LINTLIBRARY */ -#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32) +#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) /* All known AIX compilers implement these things (but don't always define __STDC__). The RISC/OS MIPS compiler defines these things in SVR4 mode, but does not define __STDC__. */ diff --git a/gnu/usr.bin/binutils/include/coff/a29k.h b/gnu/usr.bin/binutils/include/coff/a29k.h index 13b35f251af..8c3a646ca23 100644 --- a/gnu/usr.bin/binutils/include/coff/a29k.h +++ b/gnu/usr.bin/binutils/include/coff/a29k.h @@ -24,7 +24,7 @@ struct external_filehdr }; #define FILHDR struct external_filehdr -#define FILHSZ sizeof (FILHDR) +#define FILHSZ 20 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ @@ -70,8 +70,8 @@ typedef struct external_aouthdr char data_start[4]; /* base of data used for this file */ } AOUTHDR; -#define AOUTSZ (sizeof(AOUTHDR)) -#define AOUTHDRSZ (sizeof(AOUTHDR)) +#define AOUTSZ 28 +#define AOUTHDRSZ 28 /* aouthdr magic numbers */ #define NMAGIC 0410 /* separate i/d executable */ @@ -101,7 +101,7 @@ struct external_scnhdr }; #define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof (SCNHDR) +#define SCNHSZ 40 /* * names of "special" sections @@ -224,7 +224,7 @@ struct external_syment }; #define SYMENT struct external_syment -#define SYMESZ sizeof(SYMENT) +#define SYMESZ 18 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ diff --git a/gnu/usr.bin/binutils/include/coff/alpha.h b/gnu/usr.bin/binutils/include/coff/alpha.h index 1f1bfb6ccc7..b4466928905 100644 --- a/gnu/usr.bin/binutils/include/coff/alpha.h +++ b/gnu/usr.bin/binutils/include/coff/alpha.h @@ -23,7 +23,7 @@ struct external_filehdr { #define F_ALPHA_CALL_SHARED 0x3000 #define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) +#define FILHSZ 24 /********************** AOUT "OPTIONAL HEADER" **********************/ @@ -48,7 +48,8 @@ typedef struct external_aouthdr /* compute size of a header */ -#define AOUTSZ (sizeof(AOUTHDR)) +#define AOUTSZ 80 +#define AOUTHDRSZ 80 /********************** SECTION HEADER **********************/ @@ -66,7 +67,7 @@ struct external_scnhdr { }; #define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) +#define SCNHSZ 64 /********************** RELOCATION DIRECTIVES **********************/ @@ -119,6 +120,21 @@ struct external_reloc { #define ALPHA_R_OP_PSUB 14 #define ALPHA_R_OP_PRSHIFT 15 #define ALPHA_R_GPVALUE 16 +#define ALPHA_R_GPRELHIGH 17 +#define ALPHA_R_GPRELLOW 18 +#define ALPHA_R_IMMED 19 + +/* With ALPHA_R_LITUSE, the r_size field is one of the following values. */ +#define ALPHA_R_LU_BASE 1 +#define ALPHA_R_LU_BYTOFF 2 +#define ALPHA_R_LU_JSR 3 + +/* With ALPHA_R_IMMED, the r_size field is one of the following values. */ +#define ALPHA_R_IMMED_GP_16 1 +#define ALPHA_R_IMMED_GP_HI32 2 +#define ALPHA_R_IMMED_SCN_HI32 3 +#define ALPHA_R_IMMED_BR_HI32 4 +#define ALPHA_R_IMMED_LO32 5 /********************** SYMBOLIC INFORMATION **********************/ diff --git a/gnu/usr.bin/binutils/include/coff/apollo.h b/gnu/usr.bin/binutils/include/coff/apollo.h index c481d482e8b..d1347f1f532 100644 --- a/gnu/usr.bin/binutils/include/coff/apollo.h +++ b/gnu/usr.bin/binutils/include/coff/apollo.h @@ -34,7 +34,7 @@ struct external_filehdr { #define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) +#define FILHSZ 20 /********************** AOUT "OPTIONAL HEADER" **********************/ @@ -56,8 +56,8 @@ typedef struct AOUTHDR; #define APOLLO_COFF_VERSION_NUMBER 1 /* the value of the aouthdr magic */ -#define AOUTHDRSZ (sizeof(AOUTHDR)) -#define AOUTSZ (sizeof(AOUTHDR)) +#define AOUTHDRSZ 44 +#define AOUTSZ 44 @@ -107,7 +107,7 @@ struct external_scnhdr { #define _UNWIND ".unwind" /* Stack unwind information */ #define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) +#define SCNHSZ 40 /********************** LINE NUMBERS **********************/ @@ -127,7 +127,7 @@ struct external_lineno { #define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) +#define LINESZ 6 /********************** SYMBOLS **********************/ @@ -228,7 +228,11 @@ struct external_reloc { #define RELOC struct external_reloc -#define RELSZ sizeof(struct external_reloc) +#ifdef M68K_COFF_OFFSET +#define RELSZ 14 +#else +#define RELSZ 10 +#endif /* Apollo specific STYP flags */ diff --git a/gnu/usr.bin/binutils/include/coff/h8300.h b/gnu/usr.bin/binutils/include/coff/h8300.h index 8fe8f6165fe..9b62394f380 100644 --- a/gnu/usr.bin/binutils/include/coff/h8300.h +++ b/gnu/usr.bin/binutils/include/coff/h8300.h @@ -16,13 +16,14 @@ struct external_filehdr { #define H8300MAGIC 0x8300 #define H8300HMAGIC 0x8301 - +#define H8300SMAGIC 0x8302 #define H8300BADMAG(x) (((x).f_magic!=H8300MAGIC)) #define H8300HBADMAG(x) (((x).f_magic!=H8300HMAGIC)) +#define H8300SBADMAG(x) (((x).f_magic!=H8300SMAGIC)) #define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) +#define FILHSZ 20 /********************** AOUT "OPTIONAL HEADER" **********************/ @@ -42,8 +43,8 @@ typedef struct AOUTHDR; -#define AOUTHDRSZ (sizeof(AOUTHDR)) -#define AOUTSZ (sizeof(AOUTHDR)) +#define AOUTHDRSZ 28 +#define AOUTSZ 28 @@ -73,7 +74,7 @@ struct external_scnhdr { #define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) +#define SCNHSZ 40 /********************** LINE NUMBERS **********************/ @@ -95,7 +96,7 @@ struct external_lineno { #define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno)); #define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) +#define LINESZ 8 /********************** SYMBOLS **********************/ diff --git a/gnu/usr.bin/binutils/include/coff/h8500.h b/gnu/usr.bin/binutils/include/coff/h8500.h index 5a8c9feace9..0305bf2b76b 100644 --- a/gnu/usr.bin/binutils/include/coff/h8500.h +++ b/gnu/usr.bin/binutils/include/coff/h8500.h @@ -20,7 +20,7 @@ struct external_filehdr { #define H8500BADMAG(x) ((0xffff && ((x).f_magic)!=H8500MAGIC)) #define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) +#define FILHSZ 20 /********************** AOUT "OPTIONAL HEADER" **********************/ @@ -40,8 +40,8 @@ typedef struct AOUTHDR; -#define AOUTHDRSZ (sizeof(AOUTHDR)) -#define AOUTSZ (sizeof(AOUTHDR)) +#define AOUTHDRSZ 28 +#define AOUTSZ 28 @@ -71,7 +71,7 @@ struct external_scnhdr { #define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) +#define SCNHSZ 40 /********************** LINE NUMBERS **********************/ @@ -93,7 +93,7 @@ struct external_lineno { #define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno)); #define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) +#define LINESZ 8 /********************** SYMBOLS **********************/ diff --git a/gnu/usr.bin/binutils/include/coff/i860.h b/gnu/usr.bin/binutils/include/coff/i860.h index e09ec5f0e51..73686e92b7d 100644 --- a/gnu/usr.bin/binutils/include/coff/i860.h +++ b/gnu/usr.bin/binutils/include/coff/i860.h @@ -36,7 +36,7 @@ struct external_filehdr { #define I860BADMAG(x) ((x).f_magic != I860MAGIC) #define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) +#define FILHSZ 20 /********************** AOUT "OPTIONAL HEADER" **********************/ @@ -56,7 +56,8 @@ typedef struct AOUTHDR; -#define AOUTSZ (sizeof(AOUTHDR)) +#define AOUTSZ 28 +#define AOUTHDRSZ 28 /* FIXME: What are the a.out magic numbers? */ @@ -77,7 +78,7 @@ struct external_scnhdr { }; #define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) +#define SCNHSZ 40 /* * names of "special" sections diff --git a/gnu/usr.bin/binutils/include/coff/m88k.h b/gnu/usr.bin/binutils/include/coff/m88k.h index 9068dd3f124..e06eb4165ec 100644 --- a/gnu/usr.bin/binutils/include/coff/m88k.h +++ b/gnu/usr.bin/binutils/include/coff/m88k.h @@ -18,7 +18,7 @@ struct external_filehdr { #define MC88BADMAG(x) (((x).f_magic!=MC88MAGIC) &&((x).f_magic!=MC88DMAGIC) && ((x).f_magic != MC88OMAGIC)) #define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) +#define FILHSZ 20 /********************** AOUT "OPTIONAL HEADER" **********************/ @@ -44,7 +44,8 @@ AOUTHDR; /* compute size of a header */ -#define AOUTSZ (sizeof(AOUTHDR)) +#define AOUTSZ 28 +#define AOUTHDRSZ 28 /********************** SECTION HEADER **********************/ @@ -66,7 +67,7 @@ struct external_scnhdr #define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) +#define SCNHSZ 44 /* * names of "special" sections diff --git a/gnu/usr.bin/binutils/include/coff/mips.h b/gnu/usr.bin/binutils/include/coff/mips.h index f35187e83b1..d4665b1f396 100644 --- a/gnu/usr.bin/binutils/include/coff/mips.h +++ b/gnu/usr.bin/binutils/include/coff/mips.h @@ -46,7 +46,8 @@ typedef struct external_aouthdr /* compute size of a header */ -#define AOUTSZ (sizeof(AOUTHDR)) +#define AOUTSZ 56 +#define AOUTHDRSZ 56 /********************** SECTION HEADER **********************/ @@ -64,7 +65,7 @@ struct external_scnhdr { }; #define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) +#define SCNHSZ 40 /********************** RELOCATION DIRECTIVES **********************/ diff --git a/gnu/usr.bin/binutils/include/coff/rs6000.h b/gnu/usr.bin/binutils/include/coff/rs6000.h index 62a6f86cc7c..0def1d95d15 100644 --- a/gnu/usr.bin/binutils/include/coff/rs6000.h +++ b/gnu/usr.bin/binutils/include/coff/rs6000.h @@ -29,7 +29,7 @@ struct external_filehdr { (x).f_magic != U802TOCMAGIC) #define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) +#define FILHSZ 20 /********************** AOUT "OPTIONAL HEADER" **********************/ @@ -62,8 +62,9 @@ typedef struct } AOUTHDR; -#define AOUTSZ (sizeof(AOUTHDR)) +#define AOUTSZ 72 #define SMALL_AOUTSZ (28) +#define AOUTHDRSZ 72 #define RS6K_AOUTHDR_OMAGIC 0x0107 /* old: text & data writeable */ #define RS6K_AOUTHDR_NMAGIC 0x0108 /* new: text r/o, data r/w */ @@ -96,7 +97,7 @@ struct external_scnhdr { #define _LOADER ".loader" #define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) +#define SCNHSZ 40 /* XCOFF uses a special .loader section with type STYP_LOADER. */ #define STYP_LOADER 0x1000 @@ -125,7 +126,7 @@ struct external_lineno { #define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) +#define LINESZ 6 /********************** SYMBOLS **********************/ diff --git a/gnu/usr.bin/binutils/include/coff/sparc.h b/gnu/usr.bin/binutils/include/coff/sparc.h index 0e3217b25f1..82a24f01e7a 100644 --- a/gnu/usr.bin/binutils/include/coff/sparc.h +++ b/gnu/usr.bin/binutils/include/coff/sparc.h @@ -31,7 +31,7 @@ struct external_filehdr #define LYNXCOFFMAGIC (0415) #define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) +#define FILHSZ 20 /********************** AOUT "OPTIONAL HEADER" **********************/ @@ -48,7 +48,8 @@ typedef struct } AOUTHDR; -#define AOUTSZ (sizeof(AOUTHDR)) +#define AOUTSZ 28 +#define AOUTHDRSZ 28 #define OMAGIC 0404 /* object files, eg as output */ #define ZMAGIC 0413 /* demand load format, eg normal ld output */ @@ -72,7 +73,7 @@ struct external_scnhdr }; #define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) +#define SCNHSZ 40 /* Names of "special" sections. */ @@ -205,5 +206,5 @@ struct external_reloc { }; #define RELOC struct external_reloc -#define RELSZ sizeof (RELOC) +#define RELSZ 16 diff --git a/gnu/usr.bin/binutils/include/coff/w65.h b/gnu/usr.bin/binutils/include/coff/w65.h index c80b9fee5de..3378c2324d2 100644 --- a/gnu/usr.bin/binutils/include/coff/w65.h +++ b/gnu/usr.bin/binutils/include/coff/w65.h @@ -20,7 +20,7 @@ struct external_filehdr { #define W65BADMAG(x) (((x).f_magic!=W65MAGIC)) #define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) +#define FILHSZ 20 /********************** AOUT "OPTIONAL HEADER" **********************/ @@ -40,8 +40,8 @@ typedef struct AOUTHDR; -#define AOUTHDRSZ (sizeof(AOUTHDR)) -#define AOUTSZ (sizeof(AOUTHDR)) +#define AOUTHDRSZ 28 +#define AOUTSZ 28 @@ -71,7 +71,7 @@ struct external_scnhdr { #define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) +#define SCNHSZ 40 /********************** LINE NUMBERS **********************/ @@ -93,7 +93,7 @@ struct external_lineno { #define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno)); #define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) +#define LINESZ 8 /********************** SYMBOLS **********************/ diff --git a/gnu/usr.bin/binutils/include/coff/we32k.h b/gnu/usr.bin/binutils/include/coff/we32k.h index 414c4506e0b..553fa35cdad 100644 --- a/gnu/usr.bin/binutils/include/coff/we32k.h +++ b/gnu/usr.bin/binutils/include/coff/we32k.h @@ -38,7 +38,7 @@ struct external_filehdr { && ((x).f_magic != MTVMAGIC)) #define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) +#define FILHSZ 20 /********************** AOUT "OPTIONAL HEADER" **********************/ @@ -57,8 +57,8 @@ typedef struct } AOUTHDR; -#define AOUTSZ (sizeof(AOUTHDR)) - +#define AOUTSZ 28 +#define AOUTHDRSZ 28 /********************** SECTION HEADER **********************/ @@ -77,7 +77,7 @@ struct external_scnhdr { }; #define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) +#define SCNHSZ 40 /* * names of "special" sections @@ -106,7 +106,7 @@ struct external_lineno { #define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) +#define LINESZ 6 /********************** SYMBOLS **********************/ @@ -202,5 +202,5 @@ struct external_reloc { #define RELOC struct external_reloc -#define RELSZ sizeof(RELOC) +#define RELSZ 10 diff --git a/gnu/usr.bin/binutils/include/coff/z8k.h b/gnu/usr.bin/binutils/include/coff/z8k.h index 48817952829..19b846ca2e1 100644 --- a/gnu/usr.bin/binutils/include/coff/z8k.h +++ b/gnu/usr.bin/binutils/include/coff/z8k.h @@ -23,7 +23,7 @@ struct external_filehdr { #define Z8KBADMAG(x) (((x).f_magic!=Z8KMAGIC)) #define FILHDR struct external_filehdr -#define FILHSZ sizeof(FILHDR) +#define FILHSZ 20 /********************** AOUT "OPTIONAL HEADER" **********************/ @@ -43,8 +43,8 @@ typedef struct AOUTHDR; -#define AOUTHDRSZ (sizeof(AOUTHDR)) -#define AOUTSZ (sizeof(AOUTHDR)) +#define AOUTHDRSZ 28 +#define AOUTSZ 28 @@ -74,7 +74,7 @@ struct external_scnhdr { #define SCNHDR struct external_scnhdr -#define SCNHSZ sizeof(SCNHDR) +#define SCNHSZ 40 /********************** LINE NUMBERS **********************/ @@ -96,7 +96,7 @@ struct external_lineno { #define PUT_LINENO_LNNO(abfd,val, ext) bfd_h_put_32(abfd,val, (bfd_byte *) (ext->l_lnno)); #define LINENO struct external_lineno -#define LINESZ sizeof(LINENO) +#define LINESZ 8 /********************** SYMBOLS **********************/ diff --git a/gnu/usr.bin/binutils/include/elf/alpha.h b/gnu/usr.bin/binutils/include/elf/alpha.h new file mode 100644 index 00000000000..04ce3691412 --- /dev/null +++ b/gnu/usr.bin/binutils/include/elf/alpha.h @@ -0,0 +1,86 @@ +/* ALPHA ELF support for BFD. + Copyright (C) 1996 Free Software Foundation, Inc. + + By Eric Youngdale, . No processor supplement available + for this platform. + +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. */ + +/* This file holds definitions specific to the ALPHA ELF ABI. Note + that most of this is not actually implemented by BFD. */ + +#ifndef _ELF_ALPHA_H +#define _ELF_ALPHA_H + +/* Processor specific section flags. */ + +/* This section must be in the global data area. */ +#define SHF_ALPHA_GPREL 0x10000000 + +/* Section contains some sort of debugging information. The exact + format is unspecified. It's probably ECOFF symbols. */ +#define SHT_ALPHA_DEBUG 0x70000001 + +/* Section contains register usage information. */ +#define SHT_ALPHA_REGINFO 0x70000002 + +/* A section of type SHT_MIPS_REGINFO contains the following + structure. */ +typedef struct +{ + /* Mask of general purpose registers used. */ + unsigned long ri_gprmask; + /* Mask of co-processor registers used. */ + unsigned long ri_cprmask[4]; + /* GP register value for this object file. */ + long ri_gp_value; +} Elf64_RegInfo; + +/* Alpha relocs. */ + +#define R_ALPHA_NONE 0 /* No reloc */ +#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ +#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ +#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ +#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ +#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ +#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ +#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ +#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ +#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ +#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ +#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ +#define R_ALPHA_OP_PUSH 12 /* OP stack push */ +#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */ +#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */ +#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */ +#define R_ALPHA_GPVALUE 16 +#define R_ALPHA_GPRELHIGH 17 +#define R_ALPHA_GPRELLOW 18 +#define R_ALPHA_IMMED_GP_16 19 +#define R_ALPHA_IMMED_GP_HI32 20 +#define R_ALPHA_IMMED_SCN_HI32 21 +#define R_ALPHA_IMMED_BR_HI32 22 +#define R_ALPHA_IMMED_LO32 23 +#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ +#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ +#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ +#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ + +#define R_ALPHA_max 28 + +#endif /* _ELF_ALPHA_H */ diff --git a/gnu/usr.bin/binutils/include/elf/dwarf2.h b/gnu/usr.bin/binutils/include/elf/dwarf2.h new file mode 100644 index 00000000000..085ab797575 --- /dev/null +++ b/gnu/usr.bin/binutils/include/elf/dwarf2.h @@ -0,0 +1,623 @@ +/* Declarations and definitions of codes relating to the DWARF symbolic + debugging information format. + Copyright (C) 1992, 1993, 1995, 1996 Free Software Foundation, Inc. + + Written by Gary Funck (gary@intrepid.com) The Ada Joint Program + Office (AJPO), Florida State Unviversity and Silicon Graphics Inc. + provided support for this effort -- June 21, 1995. + + Derived from the DWARF 1 implementation written by Ron Guilmette + (rfg@netcom.com), November 1990. + +This file is part of GNU CC. + +GNU CC 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. + +GNU CC 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 GNU CC; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* This file is derived from the DWARF specification (a public document) + Revision 2.0.0 (July 27, 1993) developed by the UNIX International + Programming Languages Special Interest Group (UI/PLSIG) and distributed + by UNIX International. Copies of this specification are available from + UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054. */ + +#ifndef _ELF_DWARF2_H +#define _ELF_DWARF2_H + +/* Tag names and codes. */ + +enum dwarf_tag + { + DW_TAG_padding = 0x00, + DW_TAG_array_type = 0x01, + DW_TAG_class_type = 0x02, + DW_TAG_entry_point = 0x03, + DW_TAG_enumeration_type = 0x04, + DW_TAG_formal_parameter = 0x05, + DW_TAG_imported_declaration = 0x08, + DW_TAG_label = 0x0a, + DW_TAG_lexical_block = 0x0b, + DW_TAG_member = 0x0d, + DW_TAG_pointer_type = 0x0f, + DW_TAG_reference_type = 0x10, + DW_TAG_compile_unit = 0x11, + DW_TAG_string_type = 0x12, + DW_TAG_structure_type = 0x13, + DW_TAG_subroutine_type = 0x15, + DW_TAG_typedef = 0x16, + DW_TAG_union_type = 0x17, + DW_TAG_unspecified_parameters = 0x18, + DW_TAG_variant = 0x19, + DW_TAG_common_block = 0x1a, + DW_TAG_common_inclusion = 0x1b, + DW_TAG_inheritance = 0x1c, + DW_TAG_inlined_subroutine = 0x1d, + DW_TAG_module = 0x1e, + DW_TAG_ptr_to_member_type = 0x1f, + DW_TAG_set_type = 0x20, + DW_TAG_subrange_type = 0x21, + DW_TAG_with_stmt = 0x22, + DW_TAG_access_declaration = 0x23, + DW_TAG_base_type = 0x24, + DW_TAG_catch_block = 0x25, + DW_TAG_const_type = 0x26, + DW_TAG_constant = 0x27, + DW_TAG_enumerator = 0x28, + DW_TAG_file_type = 0x29, + DW_TAG_friend = 0x2a, + DW_TAG_namelist = 0x2b, + DW_TAG_namelist_item = 0x2c, + DW_TAG_packed_type = 0x2d, + DW_TAG_subprogram = 0x2e, + DW_TAG_template_type_param = 0x2f, + DW_TAG_template_value_param = 0x30, + DW_TAG_thrown_type = 0x31, + DW_TAG_try_block = 0x32, + DW_TAG_variant_part = 0x33, + DW_TAG_variable = 0x34, + DW_TAG_volatile_type = 0x35, + /* SGI/MIPS Extensions */ + DW_TAG_MIPS_loop = 0x4081, + /* GNU extensions */ + DW_TAG_format_label = 0x4101, /* for FORTRAN 77 and Fortran 90 */ + DW_TAG_function_template = 0x4102, /* for C++ */ + DW_TAG_class_template = 0x4103 /* for C++ */ + }; + +#define DW_TAG_lo_user 0x4080 +#define DW_TAG_hi_user 0xffff + +/* flag that tells whether entry has a child or not */ +#define DW_children_no 0 +#define DW_children_yes 1 + +/* Form names and codes. */ +enum dwarf_form + { + DW_FORM_addr = 0x01, + DW_FORM_block2 = 0x03, + DW_FORM_block4 = 0x04, + DW_FORM_data2 = 0x05, + DW_FORM_data4 = 0x06, + DW_FORM_data8 = 0x07, + DW_FORM_string = 0x08, + DW_FORM_block = 0x09, + DW_FORM_block1 = 0x0a, + DW_FORM_data1 = 0x0b, + DW_FORM_flag = 0x0c, + DW_FORM_sdata = 0x0d, + DW_FORM_strp = 0x0e, + DW_FORM_udata = 0x0f, + DW_FORM_ref_addr = 0x10, + DW_FORM_ref1 = 0x11, + DW_FORM_ref2 = 0x12, + DW_FORM_ref4 = 0x13, + DW_FORM_ref8 = 0x14, + DW_FORM_ref_udata = 0x15, + DW_FORM_indirect = 0x16 + }; + +/* Attribute names and codes. */ + +enum dwarf_attribute + { + DW_AT_sibling = 0x01, + DW_AT_location = 0x02, + DW_AT_name = 0x03, + DW_AT_ordering = 0x09, + DW_AT_subscr_data = 0x0a, + DW_AT_byte_size = 0x0b, + DW_AT_bit_offset = 0x0c, + DW_AT_bit_size = 0x0d, + DW_AT_element_list = 0x0f, + DW_AT_stmt_list = 0x10, + DW_AT_low_pc = 0x11, + DW_AT_high_pc = 0x12, + DW_AT_language = 0x13, + DW_AT_member = 0x14, + DW_AT_discr = 0x15, + DW_AT_discr_value = 0x16, + DW_AT_visibility = 0x17, + DW_AT_import = 0x18, + DW_AT_string_length = 0x19, + DW_AT_common_reference = 0x1a, + DW_AT_comp_dir = 0x1b, + DW_AT_const_value = 0x1c, + DW_AT_containing_type = 0x1d, + DW_AT_default_value = 0x1e, + DW_AT_inline = 0x20, + DW_AT_is_optional = 0x21, + DW_AT_lower_bound = 0x22, + DW_AT_producer = 0x25, + DW_AT_prototyped = 0x27, + DW_AT_return_addr = 0x2a, + DW_AT_start_scope = 0x2c, + DW_AT_stride_size = 0x2e, + DW_AT_upper_bound = 0x2f, + DW_AT_abstract_origin = 0x31, + DW_AT_accessibility = 0x32, + DW_AT_address_class = 0x33, + DW_AT_artificial = 0x34, + DW_AT_base_types = 0x35, + DW_AT_calling_convention = 0x36, + DW_AT_count = 0x37, + DW_AT_data_member_location = 0x38, + DW_AT_decl_column = 0x39, + DW_AT_decl_file = 0x3a, + DW_AT_decl_line = 0x3b, + DW_AT_declaration = 0x3c, + DW_AT_discr_list = 0x3d, + DW_AT_encoding = 0x3e, + DW_AT_external = 0x3f, + DW_AT_frame_base = 0x40, + DW_AT_friend = 0x41, + DW_AT_identifier_case = 0x42, + DW_AT_macro_info = 0x43, + DW_AT_namelist_items = 0x44, + DW_AT_priority = 0x45, + DW_AT_segment = 0x46, + DW_AT_specification = 0x47, + DW_AT_static_link = 0x48, + DW_AT_type = 0x49, + DW_AT_use_location = 0x4a, + DW_AT_variable_parameter = 0x4b, + DW_AT_virtuality = 0x4c, + DW_AT_vtable_elem_location = 0x4d, + /* SGI/MIPS Extensions */ + DW_AT_MIPS_fde = 0x2001, + DW_AT_MIPS_loop_begin = 0x2002, + DW_AT_MIPS_tail_loop_begin = 0x2003, + DW_AT_MIPS_epilog_begin = 0x2004, + DW_AT_MIPS_loop_unroll_factor = 0x2005, + DW_AT_MIPS_software_pipeline_depth = 0x2006, + DW_AT_MIPS_linkage_name = 0x2007, + /* GNU extensions. */ + DW_AT_sf_names = 0x2101, + DW_AT_src_info = 0x2102, + DW_AT_mac_info = 0x2103, + DW_AT_src_coords = 0x2104, + DW_AT_body_begin = 0x2105, + DW_AT_body_end = 0x2106 + }; + +#define DW_AT_lo_user 0x2000 /* implementation-defined range start */ +#define DW_AT_hi_user 0x3ff0 /* implementation-defined range end */ + +/* Location atom names and codes. */ + +enum dwarf_location_atom + { + DW_OP_addr = 0x03, + DW_OP_deref = 0x06, + DW_OP_const1u = 0x08, + DW_OP_const1s = 0x09, + DW_OP_const2u = 0x0a, + DW_OP_const2s = 0x0b, + DW_OP_const4u = 0x0c, + DW_OP_const4s = 0x0d, + DW_OP_const8u = 0x0e, + DW_OP_const8s = 0x0f, + DW_OP_constu = 0x10, + DW_OP_consts = 0x11, + DW_OP_dup = 0x12, + DW_OP_drop = 0x13, + DW_OP_over = 0x14, + DW_OP_pick = 0x15, + DW_OP_swap = 0x16, + DW_OP_rot = 0x17, + DW_OP_xderef = 0x18, + DW_OP_abs = 0x19, + DW_OP_and = 0x1a, + DW_OP_div = 0x1b, + DW_OP_minus = 0x1c, + DW_OP_mod = 0x1d, + DW_OP_mul = 0x1e, + DW_OP_neg = 0x1f, + DW_OP_not = 0x20, + DW_OP_or = 0x21, + DW_OP_plus = 0x22, + DW_OP_plus_uconst = 0x23, + DW_OP_shl = 0x24, + DW_OP_shr = 0x25, + DW_OP_shra = 0x26, + DW_OP_xor = 0x27, + DW_OP_bra = 0x28, + DW_OP_eq = 0x29, + DW_OP_ge = 0x2a, + DW_OP_gt = 0x2b, + DW_OP_le = 0x2c, + DW_OP_lt = 0x2d, + DW_OP_ne = 0x2e, + DW_OP_skip = 0x2f, + DW_OP_lit0 = 0x30, + DW_OP_lit1 = 0x31, + DW_OP_lit2 = 0x32, + DW_OP_lit3 = 0x33, + DW_OP_lit4 = 0x34, + DW_OP_lit5 = 0x35, + DW_OP_lit6 = 0x36, + DW_OP_lit7 = 0x37, + DW_OP_lit8 = 0x38, + DW_OP_lit9 = 0x39, + DW_OP_lit10 = 0x3a, + DW_OP_lit11 = 0x3b, + DW_OP_lit12 = 0x3c, + DW_OP_lit13 = 0x3d, + DW_OP_lit14 = 0x3e, + DW_OP_lit15 = 0x3f, + DW_OP_lit16 = 0x40, + DW_OP_lit17 = 0x41, + DW_OP_lit18 = 0x42, + DW_OP_lit19 = 0x43, + DW_OP_lit20 = 0x44, + DW_OP_lit21 = 0x45, + DW_OP_lit22 = 0x46, + DW_OP_lit23 = 0x47, + DW_OP_lit24 = 0x48, + DW_OP_lit25 = 0x49, + DW_OP_lit26 = 0x4a, + DW_OP_lit27 = 0x4b, + DW_OP_lit28 = 0x4c, + DW_OP_lit29 = 0x4d, + DW_OP_lit30 = 0x4e, + DW_OP_lit31 = 0x4f, + DW_OP_reg0 = 0x50, + DW_OP_reg1 = 0x51, + DW_OP_reg2 = 0x52, + DW_OP_reg3 = 0x53, + DW_OP_reg4 = 0x54, + DW_OP_reg5 = 0x55, + DW_OP_reg6 = 0x56, + DW_OP_reg7 = 0x57, + DW_OP_reg8 = 0x58, + DW_OP_reg9 = 0x59, + DW_OP_reg10 = 0x5a, + DW_OP_reg11 = 0x5b, + DW_OP_reg12 = 0x5c, + DW_OP_reg13 = 0x5d, + DW_OP_reg14 = 0x5e, + DW_OP_reg15 = 0x5f, + DW_OP_reg16 = 0x60, + DW_OP_reg17 = 0x61, + DW_OP_reg18 = 0x62, + DW_OP_reg19 = 0x63, + DW_OP_reg20 = 0x64, + DW_OP_reg21 = 0x65, + DW_OP_reg22 = 0x66, + DW_OP_reg23 = 0x67, + DW_OP_reg24 = 0x68, + DW_OP_reg25 = 0x69, + DW_OP_reg26 = 0x6a, + DW_OP_reg27 = 0x6b, + DW_OP_reg28 = 0x6c, + DW_OP_reg29 = 0x6d, + DW_OP_reg30 = 0x6e, + DW_OP_reg31 = 0x6f, + DW_OP_breg0 = 0x70, + DW_OP_breg1 = 0x71, + DW_OP_breg2 = 0x72, + DW_OP_breg3 = 0x73, + DW_OP_breg4 = 0x74, + DW_OP_breg5 = 0x75, + DW_OP_breg6 = 0x76, + DW_OP_breg7 = 0x77, + DW_OP_breg8 = 0x78, + DW_OP_breg9 = 0x79, + DW_OP_breg10 = 0x7a, + DW_OP_breg11 = 0x7b, + DW_OP_breg12 = 0x7c, + DW_OP_breg13 = 0x7d, + DW_OP_breg14 = 0x7e, + DW_OP_breg15 = 0x7f, + DW_OP_breg16 = 0x80, + DW_OP_breg17 = 0x81, + DW_OP_breg18 = 0x82, + DW_OP_breg19 = 0x83, + DW_OP_breg20 = 0x84, + DW_OP_breg21 = 0x85, + DW_OP_breg22 = 0x86, + DW_OP_breg23 = 0x87, + DW_OP_breg24 = 0x88, + DW_OP_breg25 = 0x89, + DW_OP_breg26 = 0x8a, + DW_OP_breg27 = 0x8b, + DW_OP_breg28 = 0x8c, + DW_OP_breg29 = 0x8d, + DW_OP_breg30 = 0x8e, + DW_OP_breg31 = 0x8f, + DW_OP_regx = 0x90, + DW_OP_fbreg = 0x91, + DW_OP_bregx = 0x92, + DW_OP_piece = 0x93, + DW_OP_deref_size = 0x94, + DW_OP_xderef_size = 0x95, + DW_OP_nop = 0x96 + }; + +#define DW_OP_lo_user 0x80 /* implementation-defined range start */ +#define DW_OP_hi_user 0xff /* implementation-defined range end */ + +/* Type encodings. */ + +enum dwarf_type + { + DW_ATE_void = 0x0, + DW_ATE_address = 0x1, + DW_ATE_boolean = 0x2, + DW_ATE_complex_float = 0x3, + DW_ATE_float = 0x4, + DW_ATE_signed = 0x5, + DW_ATE_signed_char = 0x6, + DW_ATE_unsigned = 0x7, + DW_ATE_unsigned_char = 0x8 + }; + +#define DW_ATE_lo_user 0x80 +#define DW_ATE_hi_user 0xff + +/* Array ordering names and codes. */ +enum dwarf_array_dim_ordering + { + DW_ORD_row_major = 0, + DW_ORD_col_major = 1 + }; + +/* access attribute */ +enum dwarf_access_attribute + { + DW_ACCESS_public = 1, + DW_ACCESS_protected = 2, + DW_ACCESS_private = 3 + }; + +/* visibility */ +enum dwarf_visibility_attribute + { + DW_VIS_local = 1, + DW_VIS_exported = 2, + DW_VIS_qualified = 3 + }; + +/* virtuality */ +enum dwarf_virtuality_attribute + { + DW_VIRTUALITY_none = 0, + DW_VIRTUALITY_virtual = 1, + DW_VIRTUALITY_pure_virtual = 2 + }; + +/* case sensitivity */ +enum dwarf_id_case + { + DW_ID_case_sensitive = 0, + DW_ID_up_case = 1, + DW_ID_down_case = 2, + DW_ID_case_insensitive = 3 + }; + +/* calling convention */ +enum dwarf_calling_convention + { + DW_CC_normal = 0x1, + DW_CC_program = 0x2, + DW_CC_nocall = 0x3 + }; + +#define DW_CC_lo_user 0x40 +#define DW_CC_hi_user 0xff + +/* inline attribute */ +enum dwarf_inline_attribute + { + DW_INL_not_inlined = 0, + DW_INL_inlined = 1, + DW_INL_declared_not_inlined = 2, + DW_INL_declared_inlined = 3 + }; + +/* descriminant lists */ +enum dwarf_descrim_list + { + DW_DSC_label = 0, + DW_DSC_range = 1 + }; + +/* line number opcodes */ +enum dwarf_line_number_ops + { + DW_LNS_extended_op = 0, + DW_LNS_copy = 1, + DW_LNS_advance_pc = 2, + DW_LNS_advance_line = 3, + DW_LNS_set_file = 4, + DW_LNS_set_column = 5, + DW_LNS_negate_stmt = 6, + DW_LNS_set_basic_block = 7, + DW_LNS_const_add_pc = 8, + DW_LNS_fixed_advance_pc = 9 + }; + +/* line number extended opcodes */ +enum dwarf_line_number_x_ops + { + DW_LNE_end_sequence = 1, + DW_LNE_set_address = 2, + DW_LNE_define_file = 3 + }; + +/* call frame information */ +enum dwarf_call_frame_info + { + DW_CFA_advance_loc = 0x40, + DW_CFA_offset = 0x80, + DW_CFA_restore = 0xc0, + DW_CFA_nop = 0x00, + DW_CFA_set_loc = 0x01, + DW_CFA_advance_loc1 = 0x02, + DW_CFA_advance_loc2 = 0x03, + DW_CFA_advance_loc4 = 0x04, + DW_CFA_offset_extended = 0x05, + DW_CFA_restore_extended = 0x06, + DW_CFA_undefined = 0x07, + DW_CFA_same_value = 0x08, + DW_CFA_register = 0x09, + DW_CFA_remember_state = 0x0a, + DW_CFA_restore_state = 0x0b, + DW_CFA_def_cfa = 0x0c, + DW_CFA_def_cfa_register = 0x0d, + DW_CFA_def_cfa_offset = 0x0e, + /* SGI/MIPS specific */ + DW_CFA_MIPS_advance_loc8 = 0x1d + }; + +#define DW_CIE_ID 0xffffffff +#define DW_CIE_VERSION 1 + +#define DW_CFA_extended 0 +#define DW_CFA_low_user 0x1c +#define DW_CFA_high_user 0x3f + +/* SGI/MIPS call frame register usage information */ +enum dwarf_call_reg_usage + { + DW_FRAME_CFA_COL = 0, + DW_FRAME_REG1 = 1, + DW_FRAME_REG2 = 2, + DW_FRAME_REG3 = 3, + DW_FRAME_REG4 = 4, + DW_FRAME_REG5 = 5, + DW_FRAME_REG6 = 6, + DW_FRAME_REG7 = 7, + DW_FRAME_REG8 = 8, + DW_FRAME_REG9 = 9, + DW_FRAME_REG10 = 10, + DW_FRAME_REG11 = 11, + DW_FRAME_REG12 = 12, + DW_FRAME_REG13 = 13, + DW_FRAME_REG14 = 14, + DW_FRAME_REG15 = 15, + DW_FRAME_REG16 = 16, + DW_FRAME_REG17 = 17, + DW_FRAME_REG18 = 18, + DW_FRAME_REG19 = 19, + DW_FRAME_REG20 = 20, + DW_FRAME_REG21 = 21, + DW_FRAME_REG22 = 22, + DW_FRAME_REG23 = 23, + DW_FRAME_REG24 = 24, + DW_FRAME_REG25 = 25, + DW_FRAME_REG26 = 26, + DW_FRAME_REG27 = 27, + DW_FRAME_REG28 = 28, + DW_FRAME_REG29 = 29, + DW_FRAME_REG30 = 30, + DW_FRAME_REG31 = 31, + DW_FRAME_FREG0 = 32, + DW_FRAME_FREG1 = 33, + DW_FRAME_FREG2 = 34, + DW_FRAME_FREG3 = 35, + DW_FRAME_FREG4 = 36, + DW_FRAME_FREG5 = 37, + DW_FRAME_FREG6 = 38, + DW_FRAME_FREG7 = 39, + DW_FRAME_FREG8 = 40, + DW_FRAME_FREG9 = 41, + DW_FRAME_FREG10 = 42, + DW_FRAME_FREG11 = 43, + DW_FRAME_FREG12 = 44, + DW_FRAME_FREG13 = 45, + DW_FRAME_FREG14 = 46, + DW_FRAME_FREG15 = 47, + DW_FRAME_FREG16 = 48, + DW_FRAME_FREG17 = 49, + DW_FRAME_FREG18 = 50, + DW_FRAME_FREG19 = 51, + DW_FRAME_FREG20 = 52, + DW_FRAME_FREG21 = 53, + DW_FRAME_FREG22 = 54, + DW_FRAME_FREG23 = 55, + DW_FRAME_FREG24 = 56, + DW_FRAME_FREG25 = 57, + DW_FRAME_FREG26 = 58, + DW_FRAME_FREG27 = 59, + DW_FRAME_FREG28 = 60, + DW_FRAME_FREG29 = 61, + DW_FRAME_FREG30 = 62, + DW_FRAME_FREG31 = 63, + DW_FRAME_RA_COL = 64, + DW_FRAME_STATIC_LINK = 65 + }; + +/* This is the number of columns in the Frame Table. */ +#define DW_FRAME_LAST_REG_NUM 66 + + + +#define DW_CHILDREN_no 0x00 +#define DW_CHILDREN_yes 0x01 + +#define DW_ADDR_none 0 + +/* Source language names and codes. */ + +enum dwarf_source_language + { + DW_LANG_C89 = 0x0001, + DW_LANG_C = 0x0002, + DW_LANG_Ada83 = 0x0003, + DW_LANG_C_plus_plus = 0x0004, + DW_LANG_Cobol74 = 0x0005, + DW_LANG_Cobol85 = 0x0006, + DW_LANG_Fortran77 = 0x0007, + DW_LANG_Fortran90 = 0x0008, + DW_LANG_Pascal83 = 0x0009, + DW_LANG_Modula2 = 0x000a, + DW_LANG_Mips_Assembler = 0x8001 + }; + + +#define DW_LANG_lo_user 0x8000 /* implementation-defined range start */ +#define DW_LANG_hi_user 0xffff /* implementation-defined range start */ + +/* Names and codes for GNU "macinfo" extension. */ + +enum dwarf_macinfo_record_type + { + DW_MACINFO_define = 1, + DW_MACINFO_undef = 2, + DW_MACINFO_start_file = 3, + DW_MACINFO_end_file = 4, + DW_MACINFO_vend_ext = 255 + }; + +#endif /* _ELF_DWARF2_H */ diff --git a/gnu/usr.bin/binutils/include/fopen-vms.h b/gnu/usr.bin/binutils/include/fopen-vms.h new file mode 100644 index 00000000000..da76b7fb59c --- /dev/null +++ b/gnu/usr.bin/binutils/include/fopen-vms.h @@ -0,0 +1,24 @@ +/* Macros for the 'type' part of an fopen, freopen or fdopen. + + [Update] + + This version is for VMS systems, where text and binary files are + different. + This file is designed for inclusion by host-dependent .h files. No + user application should include it directly, since that would make + the application unable to be configured for both "same" and "binary" + variant systems. */ + +#define FOPEN_RB "rb","rfm=var" +#define FOPEN_WB "wb","rfm=var" +#define FOPEN_AB "ab","rfm=var" +#define FOPEN_RUB "r+b","rfm=var" +#define FOPEN_WUB "w+b","rfm=var" +#define FOPEN_AUB "a+b","rfm=var" + +#define FOPEN_RT "r" +#define FOPEN_WT "w" +#define FOPEN_AT "a" +#define FOPEN_RUT "r+" +#define FOPEN_WUT "w+" +#define FOPEN_AUT "a+" diff --git a/gnu/usr.bin/binutils/include/opcode/alpha.h b/gnu/usr.bin/binutils/include/opcode/alpha.h new file mode 100644 index 00000000000..06ba20fdbca --- /dev/null +++ b/gnu/usr.bin/binutils/include/opcode/alpha.h @@ -0,0 +1,236 @@ +/* alpha.h -- Header file for Alpha opcode table + Copyright 1996 Free Software Foundation, Inc. + Contributed by Richard Henderson , + patterned after the PPC opcode table written by Ian Lance Taylor. + +This file is part of GDB, GAS, and the GNU binutils. + +GDB, GAS, and the GNU binutils are free software; you can redistribute +them and/or modify them under the terms of the GNU General Public +License as published by the Free Software Foundation; either version +1, or (at your option) any later version. + +GDB, GAS, and the GNU binutils are distributed in the hope that they +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 file; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef OPCODE_ALPHA_H +#define OPCODE_ALPHA_H + +#include "bfd.h" /* for bfd_reloc_code_real_type */ + +/* The opcode table is an array of struct alpha_opcode. */ + +struct alpha_opcode +{ + /* The opcode name. */ + const char *name; + + /* The opcode itself. Those bits which will be filled in with + operands are zeroes. */ + unsigned opcode; + + /* 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 mask; + + /* One bit flags for the opcode. These are primarily used to + indicate specific processors and environments support the + instructions. The defined values are listed below. */ + unsigned flags; + + /* 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[4]; +}; + +/* 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 alpha_opcode alpha_opcodes[]; +extern const int alpha_num_opcodes; + +/* Values defined for the flags field of a struct alpha_opcode. */ + +/* CPU Availability */ +#define AXP_OPCODE_ALL 00001 +#define AXP_OPCODE_EV4 00002 +/* EV45 is not programatically different */ +#define AXP_OPCODE_EV5 00004 +#define AXP_OPCODE_EV56 00010 + +/* A macro to extract the major opcode from an instruction. */ +#define AXP_OP(i) (((i) >> 26) & 0x3F) + +/* The total number of major opcodes. */ +#define AXP_NOPS 0x40 + + +/* The operands table is an array of struct alpha_operand. */ + +struct alpha_operand +{ + /* The number of bits in the operand. */ + int bits; + + /* How far the operand is left shifted in the instruction. */ + int shift; + + /* The default relocation type for this operand. */ + bfd_reloc_code_real_type default_reloc; + + /* Insertion function. This is used by the assembler. To insert an + operand value into an instruction, check this field. + + If it is NULL, execute + i |= (op & ((1 << o->bits) - 1)) << o->shift; + (i is the instruction which we are filling in, o is a pointer to + this structure, and op is the opcode value; this assumes twos + complement arithmetic). + + If this field is not NULL, then simply call it with the + instruction and the operand value. It will return the new value + of the instruction. If the ERRMSG argument is not NULL, then if + the operand value is illegal, *ERRMSG will be set to a warning + string (the operand will be inserted in any case). If the + operand value is legal, *ERRMSG will be unchanged (most operands + can accept any value). */ + unsigned (*insert) PARAMS ((unsigned instruction, int op, + const char **errmsg)); + + /* Extraction function. This is used by the disassembler. To + extract this operand type from an instruction, check this field. + + If it is NULL, compute + op = ((i) >> o->shift) & ((1 << o->bits) - 1); + if ((o->flags & AXP_OPERAND_SIGNED) != 0 + && (op & (1 << (o->bits - 1))) != 0) + op -= 1 << o->bits; + (i is the instruction, o is a pointer to this structure, and op + is the result; this assumes twos complement arithmetic). + + If this field is not NULL, then simply call it with the + instruction value. It will return the value of the operand. If + the INVALID argument is not NULL, *INVALID will be set to + non-zero if this operand type can not actually be extracted from + this operand (i.e., the instruction does not match). If the + operand is valid, *INVALID will not be changed. */ + int (*extract) PARAMS ((unsigned instruction, int *invalid)); + + /* One bit syntax flags. */ + unsigned flags; +}; + +/* Elements in the table are retrieved by indexing with values from + the operands field of the alpha_opcodes table. */ + +extern const struct alpha_operand alpha_operands[]; +extern const int alpha_num_operands; + +/* Values defined for the flags field of a struct alpha_operand. */ + +/* Mask for selecting the type for typecheck purposes */ +#define AXP_OPERAND_TYPECHECK_MASK \ + (AXP_OPERAND_PARENS | AXP_OPERAND_COMMA | AXP_OPERAND_IR | \ + AXP_OPERAND_FPR | AXP_OPERAND_RELATIVE | AXP_OPERAND_SIGNED | \ + AXP_OPERAND_UNSIGNED) + +/* This operand does not actually exist in the assembler input. This + is used to support extended mnemonics, for which two operands fields + are identical. The assembler should call the insert function with + any op value. The disassembler should call the extract function, + ignore the return value, and check the value placed in the invalid + argument. */ +#define AXP_OPERAND_FAKE 01 + +/* The operand should be wrapped in parentheses rather than separated + from the previous by a comma. This is used for the load and store + instructions which want their operands to look like "Ra,disp(Rb)". */ +#define AXP_OPERAND_PARENS 02 + +/* Used in combination with PARENS, this supresses the supression of + the comma. This is used for "jmp Ra,(Rb),hint". */ +#define AXP_OPERAND_COMMA 04 + +/* This operand names an integer register. */ +#define AXP_OPERAND_IR 010 + +/* This operand names a floating point register. */ +#define AXP_OPERAND_FPR 020 + +/* This operand is a relative branch displacement. The disassembler + prints these symbolically if possible. */ +#define AXP_OPERAND_RELATIVE 040 + +/* This operand takes signed values. */ +#define AXP_OPERAND_SIGNED 0100 + +/* This operand takes unsigned values. This exists primarily so that + a flags value of 0 can be treated as end-of-arguments. */ +#define AXP_OPERAND_UNSIGNED 0200 + +/* Supress overflow detection on this field. This is used for hints. */ +#define AXP_OPERAND_NOOVERFLOW 0400 + +/* Mask for optional argument default value. */ +#define AXP_OPERAND_OPTIONAL_MASK 07000 + +/* This operand defaults to zero. This is used for jump hints. */ +#define AXP_OPERAND_DEFAULT_ZERO 01000 + +/* This operand should default to the first (real) operand and is used + in conjunction with AXP_OPERAND_OPTIONAL. This allows + "and $0,3,$0" to be written as "and $0,3", etc. I don't like + it, but it's what DEC does. */ +#define AXP_OPERAND_DEFAULT_FIRST 02000 + +/* Similarly, this operand should default to the second (real) operand. + This allows "negl $0" instead of "negl $0,$0". */ +#define AXP_OPERAND_DEFAULT_SECOND 04000 + + +/* Register common names */ + +#define AXP_REG_V0 0 +#define AXP_REG_T0 1 +#define AXP_REG_T1 2 +#define AXP_REG_T2 3 +#define AXP_REG_T3 4 +#define AXP_REG_T4 5 +#define AXP_REG_T5 6 +#define AXP_REG_T6 7 +#define AXP_REG_T7 8 +#define AXP_REG_S0 9 +#define AXP_REG_S1 10 +#define AXP_REG_S2 11 +#define AXP_REG_S3 12 +#define AXP_REG_S4 13 +#define AXP_REG_S5 14 +#define AXP_REG_FP 15 +#define AXP_REG_A0 16 +#define AXP_REG_A1 17 +#define AXP_REG_A2 18 +#define AXP_REG_A3 19 +#define AXP_REG_A4 20 +#define AXP_REG_A5 21 +#define AXP_REG_T8 22 +#define AXP_REG_T9 23 +#define AXP_REG_T10 24 +#define AXP_REG_T11 25 +#define AXP_REG_RA 26 +#define AXP_REG_PV 27 +#define AXP_REG_T12 27 +#define AXP_REG_AT 28 +#define AXP_REG_GP 29 +#define AXP_REG_SP 30 +#define AXP_REG_ZERO 31 + +#endif /* OPCODE_ALPHA_H */ diff --git a/gnu/usr.bin/binutils/include/opcode/hppa.h b/gnu/usr.bin/binutils/include/opcode/hppa.h index 6f50e6bbea6..b55c59abd7b 100644 --- a/gnu/usr.bin/binutils/include/opcode/hppa.h +++ b/gnu/usr.bin/binutils/include/opcode/hppa.h @@ -344,30 +344,30 @@ static const struct pa_opcode pa_opcodes[] = { "lci", 0x04001300, 0xfc003fe0, "x(b),t", pa10}, { "pdtlb", 0x04001200, 0xfc003fdf, "Zx(s,b)", pa10}, { "pdtlb", 0x04001200, 0xfc003fdf, "Zx(b)", pa10}, -{ "pitlb", 0x04000200, 0xfc003fdf, "Zx(s,b)", pa10}, -{ "pitlb", 0x04000200, 0xfc003fdf, "Zx(b)", pa10}, +{ "pitlb", 0x04000200, 0xfc001fdf, "Zx(S,b)", pa10}, +{ "pitlb", 0x04000200, 0xfc001fdf, "Zx(b)", pa10}, { "pdtlbe", 0x04001240, 0xfc003fdf, "Zx(s,b)", pa10}, { "pdtlbe", 0x04001240, 0xfc003fdf, "Zx(b)", pa10}, -{ "pitlbe", 0x04000240, 0xfc003fdf, "Zx(s,b)", pa10}, -{ "pitlbe", 0x04000240, 0xfc003fdf, "Zx(b)", pa10}, +{ "pitlbe", 0x04000240, 0xfc001fdf, "Zx(S,b)", pa10}, +{ "pitlbe", 0x04000240, 0xfc001fdf, "Zx(b)", pa10}, { "idtlba", 0x04001040, 0xfc003fff, "x,(s,b)", pa10}, { "idtlba", 0x04001040, 0xfc003fff, "x,(b)", pa10}, -{ "iitlba", 0x04000040, 0xfc003fff, "x,(s,b)", pa10}, -{ "iitlba", 0x04000040, 0xfc003fff, "x,(b)", pa10}, +{ "iitlba", 0x04000040, 0xfc001fff, "x,(S,b)", pa10}, +{ "iitlba", 0x04000040, 0xfc001fff, "x,(b)", pa10}, { "idtlbp", 0x04001000, 0xfc003fff, "x,(s,b)", pa10}, { "idtlbp", 0x04001000, 0xfc003fff, "x,(b)", pa10}, -{ "iitlbp", 0x04000000, 0xfc003fff, "x,(s,b)", pa10}, -{ "iitlbp", 0x04000000, 0xfc003fff, "x,(b)", pa10}, +{ "iitlbp", 0x04000000, 0xfc001fff, "x,(S,b)", pa10}, +{ "iitlbp", 0x04000000, 0xfc001fff, "x,(b)", pa10}, { "pdc", 0x04001380, 0xfc003fdf, "Zx(s,b)", pa10}, { "pdc", 0x04001380, 0xfc003fdf, "Zx(b)", pa10}, { "fdc", 0x04001280, 0xfc003fdf, "Zx(s,b)", pa10}, { "fdc", 0x04001280, 0xfc003fdf, "Zx(b)", pa10}, -{ "fic", 0x04000280, 0xfc003fdf, "Zx(s,b)", pa10}, -{ "fic", 0x04000280, 0xfc003fdf, "Zx(b)", pa10}, +{ "fic", 0x04000280, 0xfc001fdf, "Zx(S,b)", pa10}, +{ "fic", 0x04000280, 0xfc001fdf, "Zx(b)", pa10}, { "fdce", 0x040012c0, 0xfc003fdf, "Zx(s,b)", pa10}, { "fdce", 0x040012c0, 0xfc003fdf, "Zx(b)", pa10}, -{ "fice", 0x040002c0, 0xfc003fdf, "Zx(s,b)", pa10}, -{ "fice", 0x040002c0, 0xfc003fdf, "Zx(b)", pa10}, +{ "fice", 0x040002c0, 0xfc001fdf, "Zx(S,b)", pa10}, +{ "fice", 0x040002c0, 0xfc001fdf, "Zx(b)", pa10}, { "diag", 0x14000000, 0xfc000000, "D", pa10}, /* gfw and gfr are not in the HP PA 1.1 manual, but they are in either diff --git a/gnu/usr.bin/binutils/include/opcode/m68k.h b/gnu/usr.bin/binutils/include/opcode/m68k.h index e0b371c92bb..d81967d16e2 100644 --- a/gnu/usr.bin/binutils/include/opcode/m68k.h +++ b/gnu/usr.bin/binutils/include/opcode/m68k.h @@ -35,6 +35,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #define m68882 m68881 /* synonym for -m68881. otherwise unused. */ #define m68851 0x080 #define cpu32 0x100 /* e.g., 68332 */ +#define mcf5200 0x200 /* handy aliases */ #define m68040up (m68040 | m68060) @@ -151,6 +152,10 @@ struct m68k_opcode_alias 0x806 URP User Root Pointer [60, 40] 0x807 SRP Supervisor Root Pointer [60, 40] 0x808 PCR Processor Configuration reg [60] + 0xC00 ROMBAR ROM Base Address Register [520X] + 0xC04 RAMBAR0 RAM Base Address Register 0 [520X] + 0xC05 RAMBAR1 RAM Base Address Register 0 [520X] + 0xC0F MBAR0 RAM Base Address Register 0 [520X] L Register list of the type d0-d7/a0-a7 etc. (New! Improved! Can also hold fp0-fp7, as well!) diff --git a/gnu/usr.bin/binutils/include/opcode/mips.h b/gnu/usr.bin/binutils/include/opcode/mips.h index 14ceec96119..9de3c32b99c 100644 --- a/gnu/usr.bin/binutils/include/opcode/mips.h +++ b/gnu/usr.bin/binutils/include/opcode/mips.h @@ -94,6 +94,26 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * #define OP_SH_FUNCT 0 #define OP_MASK_SPEC 0x3f #define OP_SH_SPEC 0 +#define OP_SH_LOCC 8 /* FP condition code */ +#define OP_SH_HICC 18 /* FP condition code */ +#define OP_MASK_CC 0x7 +#define OP_SH_COP1NORM 25 /* Normal COP1 encoding */ +#define OP_MASK_COP1NORM 0x1 /* a single bit */ +#define OP_SH_COP1SPEC 21 /* COP1 encodings */ +#define OP_MASK_COP1SPEC 0xf +#define OP_MASK_COP1SCLR 0x4 +#define OP_MASK_COP1CMP 0x3 +#define OP_SH_COP1CMP 4 +#define OP_SH_FORMAT 21 /* FP short format field */ +#define OP_MASK_FORMAT 0x7 +#define OP_SH_TRUE 16 +#define OP_MASK_TRUE 0x1 +#define OP_SH_GE 17 +#define OP_MASK_GE 0x01 +#define OP_SH_UNSIGNED 16 +#define OP_MASK_UNSIGNED 0x1 +#define OP_SH_HINT 16 +#define OP_MASK_HINT 0x1f /* This structure holds information for a particular instruction. */ diff --git a/gnu/usr.bin/binutils/ld/README b/gnu/usr.bin/binutils/ld/README index bb890e1fad5..248894ea294 100644 --- a/gnu/usr.bin/binutils/ld/README +++ b/gnu/usr.bin/binutils/ld/README @@ -24,10 +24,13 @@ Installation ============ See ../binutils/README. + If you want to make a cross-linker, you may want to specify a different search path of -lfoo libraries than the default. You can do this by setting the LIB_PATH variable in ./Makefile. +To build just the linker, make the target all-ld. + Porting to a new target ======================= diff --git a/gnu/usr.bin/binutils/ld/emulparams/elf32ebmip.sh b/gnu/usr.bin/binutils/ld/emulparams/elf32ebmip.sh new file mode 100644 index 00000000000..3bc284e6d0c --- /dev/null +++ b/gnu/usr.bin/binutils/ld/emulparams/elf32ebmip.sh @@ -0,0 +1,28 @@ +SCRIPT_NAME=elfmips +OUTPUT_FORMAT="elf32-bigmips" +BIG_OUTPUT_FORMAT="elf32-bigmips" +LITTLE_OUTPUT_FORMAT="elf32-littlemips" +TEXT_START_ADDR=0x0400000 +DATA_ADDR=0x10000000 +MAXPAGESIZE=0x40000 +NONPAGED_TEXT_START_ADDR=0x0400000 +SHLIB_TEXT_START_ADDR=0x5ffe0000 +OTHER_READONLY_SECTIONS='.reginfo : { *(.reginfo) }' +OTHER_GOT_SYMBOLS=' + _gp = ALIGN(16) + 0x7ff0; +' +OTHER_READWRITE_SECTIONS=' + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } +' +TEXT_START_SYMBOLS='_ftext = . ;' +DATA_START_SYMBOLS='_fdata = . ;' +OTHER_BSS_SYMBOLS='_fbss = .;' +OTHER_SECTIONS=' + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } +' +ARCH=mips +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +EMBEDDED=yes diff --git a/gnu/usr.bin/binutils/ld/emulparams/elf32elmip.sh b/gnu/usr.bin/binutils/ld/emulparams/elf32elmip.sh new file mode 100644 index 00000000000..c892dc17cbb --- /dev/null +++ b/gnu/usr.bin/binutils/ld/emulparams/elf32elmip.sh @@ -0,0 +1,28 @@ +SCRIPT_NAME=elfmips +OUTPUT_FORMAT="elf32-littlemips" +BIG_OUTPUT_FORMAT="elf32-bigmips" +LITTLE_OUTPUT_FORMAT="elf32-littlemips" +TEXT_START_ADDR=0x0400000 +DATA_ADDR=0x10000000 +MAXPAGESIZE=0x40000 +NONPAGED_TEXT_START_ADDR=0x0400000 +SHLIB_TEXT_START_ADDR=0x5ffe0000 +OTHER_READONLY_SECTIONS='.reginfo : { *(.reginfo) }' +OTHER_GOT_SYMBOLS=' + _gp = ALIGN(16) + 0x7ff0; +' +OTHER_READWRITE_SECTIONS=' + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } +' +TEXT_START_SYMBOLS='_ftext = . ;' +DATA_START_SYMBOLS='_fdata = . ;' +OTHER_BSS_SYMBOLS='_fbss = .;' +OTHER_SECTIONS=' + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } +' +ARCH=mips +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +EMBEDDED=yes diff --git a/gnu/usr.bin/binutils/ld/emulparams/elf64alpha.sh b/gnu/usr.bin/binutils/ld/emulparams/elf64alpha.sh new file mode 100644 index 00000000000..ca2d230ebdd --- /dev/null +++ b/gnu/usr.bin/binutils/ld/emulparams/elf64alpha.sh @@ -0,0 +1,14 @@ +ENTRY=__start +SCRIPT_NAME=elf +ELFSIZE=64 +TEMPLATE_NAME=elf32 +OUTPUT_FORMAT="elf64-alpha" +TEXT_START_ADDR="0x120000000" +MAXPAGESIZE=0x100000 +NONPAGED_TEXT_START_ADDR="0x120000000" +ARCH=alpha +GENERATE_SHLIB_SCRIPT=yes +DATA_PLT= +NOP=0x47ff041f + +OTHER_READONLY_SECTIONS='.reginfo : { *(.reginfo) }' diff --git a/gnu/usr.bin/binutils/ld/emulparams/h8300s.sh b/gnu/usr.bin/binutils/ld/emulparams/h8300s.sh new file mode 100644 index 00000000000..e27b4f523f1 --- /dev/null +++ b/gnu/usr.bin/binutils/ld/emulparams/h8300s.sh @@ -0,0 +1,5 @@ +SCRIPT_NAME=h8300s +OUTPUT_FORMAT="coff-h8300" +TEXT_START_ADDR=0x8000 +TARGET_PAGE_SIZE=128 +ARCH=h8300 diff --git a/gnu/usr.bin/binutils/ld/emulparams/pc532macha.sh b/gnu/usr.bin/binutils/ld/emulparams/pc532macha.sh new file mode 100644 index 00000000000..9c1d0791c8d --- /dev/null +++ b/gnu/usr.bin/binutils/ld/emulparams/pc532macha.sh @@ -0,0 +1,6 @@ +SCRIPT_NAME=aout +OUTPUT_FORMAT="a.out-pc532-mach" +TARGET_PAGE_SIZE=0x1000 +TEXT_START_ADDR="0x10020" +NONPAGED_TEXT_START_ADDR=0x10000 +ARCH=ns32k diff --git a/gnu/usr.bin/binutils/ld/emulparams/shelf.sh b/gnu/usr.bin/binutils/ld/emulparams/shelf.sh new file mode 100644 index 00000000000..a392e933c42 --- /dev/null +++ b/gnu/usr.bin/binutils/ld/emulparams/shelf.sh @@ -0,0 +1,16 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-sh" +TEXT_START_ADDR=0x1000 +MAXPAGESIZE=128 +ARCH=sh +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +EMBEDDED=yes + +# These are for compatibility with the COFF toolchain. +ENTRY=start +CTOR_START='___ctors = .;' +CTOR_END='___ctors_end = .;' +DTOR_START='___dtors = .;' +DTOR_END='___dtors_end = .;' +OTHER_RELOCATING_SECTIONS='.stack 0x30000 : { _stack = .; *(.stack) }' diff --git a/gnu/usr.bin/binutils/ld/emulparams/shlelf.sh b/gnu/usr.bin/binutils/ld/emulparams/shlelf.sh new file mode 100644 index 00000000000..93777f63de3 --- /dev/null +++ b/gnu/usr.bin/binutils/ld/emulparams/shlelf.sh @@ -0,0 +1,16 @@ +SCRIPT_NAME=elf +OUTPUT_FORMAT="elf32-shl" +TEXT_START_ADDR=0x1000 +MAXPAGESIZE=128 +ARCH=sh +TEMPLATE_NAME=elf32 +GENERATE_SHLIB_SCRIPT=yes +EMBEDDED=yes + +# These are for compatibility with the COFF toolchain. +ENTRY=start +CTOR_START='___ctors = .;' +CTOR_END='___ctors_end = .;' +DTOR_START='___dtors = .;' +DTOR_END='___dtors_end = .;' +OTHER_RELOCATING_SECTIONS='.stack 0x30000 : { _stack = .; *(.stack) }' diff --git a/gnu/usr.bin/binutils/ld/fnmatch.c b/gnu/usr.bin/binutils/ld/fnmatch.c new file mode 100644 index 00000000000..998c0c4582f --- /dev/null +++ b/gnu/usr.bin/binutils/ld/fnmatch.c @@ -0,0 +1,217 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + +NOTE: The canonical source of this file is maintained with the GNU C Library. +Bugs can be reported to bug-glibc@prep.ai.mit.edu. + +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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Modified for GNU ld to include sysdep.h. */ +#include "sysdep.h" + +#ifdef HAVE_CONFIG_H +#if defined (CONFIG_BROKETS) +/* We use instead of "config.h" so that a compilation + using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h + (which it would do because it found this file in $srcdir). */ +#include +#else +#include "config.h" +#endif +#endif + + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include +#include +#include + + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) +extern int errno; +#endif + +/* Match STRING against the filename pattern PATTERN, returning zero if + it matches, nonzero if not. */ +int +fnmatch (pattern, string, flags) + const char *pattern; + const char *string; + int flags; +{ + register const char *p = pattern, *n = string; + register char c; + +/* Note that this evalutes C many times. */ +#define FOLD(c) ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c)) + + while ((c = *p++) != '\0') + { + c = FOLD (c); + + switch (c) + { + case '?': + if (*n == '\0') + return FNM_NOMATCH; + else if ((flags & FNM_FILE_NAME) && *n == '/') + return FNM_NOMATCH; + else if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + break; + + case '\\': + if (!(flags & FNM_NOESCAPE)) + { + c = *p++; + c = FOLD (c); + } + if (FOLD (*n) != c) + return FNM_NOMATCH; + break; + + case '*': + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) + if (((flags & FNM_FILE_NAME) && *n == '/') || + (c == '?' && *n == '\0')) + return FNM_NOMATCH; + + if (c == '\0') + return 0; + + { + char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; + c1 = FOLD (c1); + for (--p; *n != '\0'; ++n) + if ((c == '[' || FOLD (*n) == c1) && + fnmatch (p, n, flags & ~FNM_PERIOD) == 0) + return 0; + return FNM_NOMATCH; + } + + case '[': + { + /* Nonzero if the sense of the character class is inverted. */ + register int not; + + if (*n == '\0') + return FNM_NOMATCH; + + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + not = (*p == '!' || *p == '^'); + if (not) + ++p; + + c = *p++; + for (;;) + { + register char cstart = c, cend = c; + + if (!(flags & FNM_NOESCAPE) && c == '\\') + cstart = cend = *p++; + + cstart = cend = FOLD (cstart); + + if (c == '\0') + /* [ (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + c = FOLD (c); + + if ((flags & FNM_FILE_NAME) && c == '/') + /* [/] can never match. */ + return FNM_NOMATCH; + + if (c == '-' && *p != ']') + { + cend = *p++; + if (!(flags & FNM_NOESCAPE) && cend == '\\') + cend = *p++; + if (cend == '\0') + return FNM_NOMATCH; + cend = FOLD (cend); + + c = *p++; + } + + if (FOLD (*n) >= cstart && FOLD (*n) <= cend) + goto matched; + + if (c == ']') + break; + } + if (!not) + return FNM_NOMATCH; + break; + + matched:; + /* Skip the rest of the [...] that already matched. */ + while (c != ']') + { + if (c == '\0') + /* [... (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + if (!(flags & FNM_NOESCAPE) && c == '\\') + /* XXX 1003.2d11 is unclear if this is right. */ + ++p; + } + if (not) + return FNM_NOMATCH; + } + break; + + default: + if (c != FOLD (*n)) + return FNM_NOMATCH; + } + + ++n; + } + + if (*n == '\0') + return 0; + + if ((flags & FNM_LEADING_DIR) && *n == '/') + /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ + return 0; + + return FNM_NOMATCH; +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ diff --git a/gnu/usr.bin/binutils/ld/fnmatch.h b/gnu/usr.bin/binutils/ld/fnmatch.h new file mode 100644 index 00000000000..1a653ab6314 --- /dev/null +++ b/gnu/usr.bin/binutils/ld/fnmatch.h @@ -0,0 +1,69 @@ +/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + +NOTE: The canonical source of this file is maintained with the GNU C Library. +Bugs can be reported to bug-glibc@prep.ai.mit.edu. + +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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _FNMATCH_H + +#define _FNMATCH_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) +#undef __P +#define __P(args) args +#else /* Not C++ or ANSI C. */ +#undef __P +#define __P(args) () +/* We can get away without defining `const' here only because in this file + it is used only inside the prototype for `fnmatch', which is elided in + non-ANSI C where `const' is problematical. */ +#endif /* C++ or ANSI C. */ + + +/* We #undef these before defining them because some losing systems + (HP-UX A.08.07 for example) define these in . */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD + +/* Bits set in the FLAGS argument to `fnmatch'. */ +#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ +#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ +#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ + +#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE) +#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ +#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ +#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ +#endif + +/* Value returned by `fnmatch' if STRING does not match PATTERN. */ +#define FNM_NOMATCH 1 + +/* Match STRING against the filename pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ +extern int fnmatch __P ((const char *__pattern, const char *__string, + int __flags)); + +#ifdef __cplusplus +} +#endif + +#endif /* fnmatch.h */ diff --git a/gnu/usr.bin/binutils/ld/ldcref.c b/gnu/usr.bin/binutils/ld/ldcref.c index bdce17d4fd0..d9e6ebb90e5 100644 --- a/gnu/usr.bin/binutils/ld/ldcref.c +++ b/gnu/usr.bin/binutils/ld/ldcref.c @@ -18,7 +18,9 @@ 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. */ -/* This file holds routines that manage the cross reference table. */ +/* This file holds routines that manage the cross reference table. + The table is used to generate cross reference reports. It is also + used to implement the NOCROSSREFS command in the linker script. */ #include "bfd.h" #include "sysdep.h" @@ -28,6 +30,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ld.h" #include "ldmain.h" #include "ldmisc.h" +#include "ldexp.h" +#include "ldlang.h" /* We keep an instance of this structure for each reference to a symbol from a given object. */ @@ -71,6 +75,11 @@ static struct bfd_hash_entry *cref_hash_newfunc static boolean cref_fill_array PARAMS ((struct cref_hash_entry *, PTR)); static int cref_sort_array PARAMS ((const PTR, const PTR)); static void output_one_cref PARAMS ((FILE *, struct cref_hash_entry *)); +static boolean check_nocrossref PARAMS ((struct cref_hash_entry *, PTR)); +static void check_refs + PARAMS ((struct cref_hash_entry *, struct bfd_link_hash_entry *, + struct lang_nocrossrefs *)); +static void check_reloc_refs PARAMS ((bfd *, asection *, PTR)); /* Look up an entry in the cref hash table. */ @@ -280,7 +289,8 @@ output_one_cref (fp, h) { if (hl->u.def.section->output_section == NULL) return; - if ((hl->u.def.section->owner->flags & DYNAMIC) != 0) + if (hl->u.def.section->owner != NULL + && (hl->u.def.section->owner->flags & DYNAMIC) != 0) { for (r = h->refs; r != NULL; r = r->next) if ((r->abfd->flags & DYNAMIC) == 0) @@ -324,3 +334,214 @@ output_one_cref (fp, h) ASSERT (len == 0); } + +/* Check for prohibited cross references. */ + +void +check_nocrossrefs () +{ + if (! cref_initialized) + return; + + cref_hash_traverse (&cref_table, check_nocrossref, (PTR) NULL); +} + +/* Check one symbol to see if it is a prohibited cross reference. */ + +/*ARGSUSED*/ +static boolean +check_nocrossref (h, ignore) + struct cref_hash_entry *h; + PTR ignore; +{ + struct bfd_link_hash_entry *hl; + asection *defsec; + const char *defsecname; + struct lang_nocrossrefs *ncrs; + struct lang_nocrossref *ncr; + + hl = bfd_link_hash_lookup (link_info.hash, h->root.string, false, + false, true); + if (hl == NULL) + { + einfo ("%P: symbol `%T' missing from main hash table\n", + h->root.string); + return true; + } + + if (hl->type != bfd_link_hash_defined + && hl->type != bfd_link_hash_defweak) + return true; + + defsec = hl->u.def.section->output_section; + if (defsec == NULL) + return true; + defsecname = bfd_get_section_name (defsec->owner, defsec); + + for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next) + for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next) + if (strcmp (ncr->name, defsecname) == 0) + check_refs (h, hl, ncrs); + + return true; +} + +/* The struct is used to pass information from check_refs to + check_reloc_refs through bfd_map_over_sections. */ + +struct check_refs_info +{ + struct cref_hash_entry *h; + asection *defsec; + struct lang_nocrossrefs *ncrs; + asymbol **asymbols; + boolean same; +}; + +/* This function is called for each symbol defined in a section which + prohibits cross references. We need to look through all references + to this symbol, and ensure that the references are not from + prohibited sections. */ + +static void +check_refs (h, hl, ncrs) + struct cref_hash_entry *h; + struct bfd_link_hash_entry *hl; + struct lang_nocrossrefs *ncrs; +{ + struct cref_ref *ref; + + for (ref = h->refs; ref != NULL; ref = ref->next) + { + lang_input_statement_type *li; + asymbol **asymbols; + struct check_refs_info info; + + /* We need to look through the relocations for this BFD, to see + if any of the relocations which refer to this symbol are from + a prohibited section. Note that we need to do this even for + the BFD in which the symbol is defined, since even a single + BFD might contain a prohibited cross reference; for this + case, we set the SAME field in INFO, which will cause + CHECK_RELOCS_REFS to check for relocations against the + section as well as against the symbol. */ + + li = (lang_input_statement_type *) ref->abfd->usrdata; + if (li != NULL && li->asymbols != NULL) + asymbols = li->asymbols; + else + { + long symsize; + long symbol_count; + + symsize = bfd_get_symtab_upper_bound (ref->abfd); + if (symsize < 0) + einfo ("%B%F: could not read symbols; %E\n", ref->abfd); + asymbols = (asymbol **) xmalloc (symsize); + symbol_count = bfd_canonicalize_symtab (ref->abfd, asymbols); + if (symbol_count < 0) + einfo ("%B%F: could not read symbols: %E\n", ref->abfd); + if (li != NULL) + { + li->asymbols = asymbols; + li->symbol_count = symbol_count; + } + } + + info.h = h; + info.defsec = hl->u.def.section; + info.ncrs = ncrs; + info.asymbols = asymbols; + if (ref->abfd == hl->u.def.section->owner) + info.same = true; + else + info.same = false; + bfd_map_over_sections (ref->abfd, check_reloc_refs, (PTR) &info); + + if (li == NULL) + free (asymbols); + } +} + +/* This is called via bfd_map_over_sections. INFO->H is a symbol + defined in INFO->DEFSECNAME. If this section maps into any of the + sections listed in INFO->NCRS, other than INFO->DEFSECNAME, then we + look through the relocations. If any of the relocations are to + INFO->H, then we report a prohibited cross reference error. */ + +static void +check_reloc_refs (abfd, sec, iarg) + bfd *abfd; + asection *sec; + PTR iarg; +{ + struct check_refs_info *info = (struct check_refs_info *) iarg; + asection *outsec; + const char *outsecname; + asection *outdefsec; + const char *outdefsecname; + struct lang_nocrossref *ncr; + const char *symname; + long relsize; + arelent **relpp; + long relcount; + arelent **p, **pend; + + outsec = sec->output_section; + outsecname = bfd_get_section_name (outsec->owner, outsec); + + outdefsec = info->defsec->output_section; + outdefsecname = bfd_get_section_name (outdefsec->owner, outdefsec); + + /* The section where the symbol is defined is permitted. */ + if (strcmp (outsecname, outdefsecname) == 0) + return; + + for (ncr = info->ncrs->list; ncr != NULL; ncr = ncr->next) + if (strcmp (outsecname, ncr->name) == 0) + break; + + if (ncr == NULL) + return; + + /* This section is one for which cross references are prohibited. + Look through the relocations, and see if any of them are to + INFO->H. */ + + symname = info->h->root.string; + + relsize = bfd_get_reloc_upper_bound (abfd, sec); + if (relsize < 0) + einfo ("%B%F: could not read relocs: %E\n", abfd); + if (relsize == 0) + return; + + relpp = (arelent **) xmalloc (relsize); + relcount = bfd_canonicalize_reloc (abfd, sec, relpp, info->asymbols); + if (relcount < 0) + einfo ("%B%F: could not read relocs: %E\n", abfd); + + p = relpp; + pend = p + relcount; + for (; p < pend && *p != NULL; p++) + { + arelent *q = *p; + + if (q->sym_ptr_ptr != NULL + && *q->sym_ptr_ptr != NULL + && (strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0 + || (info->same + && bfd_get_section (*q->sym_ptr_ptr) == info->defsec))) + { + /* We found a reloc for the symbol. The symbol is defined + in OUTSECNAME. This reloc is from a section which is + mapped into a section from which references to OUTSECNAME + are prohibited. We must report an error. */ + einfo ("%X%C: prohibited cross reference from %s to `%T' in %s\n", + abfd, sec, q->address, outsecname, + bfd_asymbol_name (*q->sym_ptr_ptr), outdefsecname); + } + } + + free (relpp); +} diff --git a/gnu/usr.bin/binutils/ld/mpw-eppcmac.c b/gnu/usr.bin/binutils/ld/mpw-eppcmac.c index 185f3d7c01a..007d2658a30 100644 --- a/gnu/usr.bin/binutils/ld/mpw-eppcmac.c +++ b/gnu/usr.bin/binutils/ld/mpw-eppcmac.c @@ -741,7 +741,7 @@ gldppcmacos_read_file (filename, import) (void) obstack_finish (o); keep = true; imppath = s; - impfile = NULL; + file = NULL; while (! isspace ((unsigned char) *s) && *s != '(' && *s != '\0') { if (*s == '/') diff --git a/gnu/usr.bin/binutils/ld/scripttempl/armcoff.sc b/gnu/usr.bin/binutils/ld/scripttempl/armcoff.sc index 3314d8141bb..e4bfd0db814 100644 --- a/gnu/usr.bin/binutils/ld/scripttempl/armcoff.sc +++ b/gnu/usr.bin/binutils/ld/scripttempl/armcoff.sc @@ -10,23 +10,35 @@ ENTRY(${ENTRY}) SECTIONS { /* We start at 0x8000 because gdb assumes it (see FRAME_CHAIN). - The bottom part of memory is reserved anyway (but 32k?). */ + This is an artifact of the ARM Demon monitor using the bottom 32k + as workspace (shared with the FP instruction emulator if + present): */ .text ${RELOCATING+ 0x8000} : { *(.init) *(.text) + ${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ; + LONG (-1); *(.ctors); *(.ctor); LONG (0); } + ${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ; + LONG (-1); *(.dtors); *(.dtor); LONG (0); } *(.fini) ${RELOCATING+ etext = .}; } .data ${RELOCATING+ 0x40000 + (. & 0xffc00fff)} : { + __data_start__ = . ; *(.data) + __data_end__ = . ; ${RELOCATING+ edata = .}; } .bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} : { + __bss_start__ = . ; *(.bss) *(COMMON) - ${RELOCATING+ end = .}; + __bss_end__ = . ; } + + ${RELOCATING+ __end__ = .}; + .stab 0 ${RELOCATING+(NOLOAD)} : { [ .stab ] diff --git a/gnu/usr.bin/binutils/ld/scripttempl/h8300s.sc b/gnu/usr.bin/binutils/ld/scripttempl/h8300s.sc new file mode 100644 index 00000000000..b43abdf55d9 --- /dev/null +++ b/gnu/usr.bin/binutils/ld/scripttempl/h8300s.sc @@ -0,0 +1,76 @@ +cat < vectors} +.text : { + *(.rodata) + *(.text) + *(.strings) + ${RELOCATING+ _etext = . ; } + } ${RELOCATING+ > ram} +.tors : { + ___ctors = . ; + *(.ctors) + ___ctors_end = . ; + ___dtors = . ; + *(.dtors) + ___dtors_end = . ; + } ${RELOCATING+ > ram} +.data : { + *(.data) + ${RELOCATING+ _edata = . ; } + } ${RELOCATING+ > ram} +.bss : { + ${RELOCATING+ _bss_start = . ;} + *(.bss) + *(COMMON) + ${RELOCATING+ _end = . ; } + } ${RELOCATING+ >ram} +.stack : { + ${RELOCATING+ _stack = . ; } + *(.stack) + } ${RELOCATING+ > topram} +.tiny : { + *(.tiny) + } ${RELOCATING+ > tiny} +.eight : { + *(.eight) + } ${RELOCATING+ > eight} +.stab 0 ${RELOCATING+(NOLOAD)} : { + [ .stab ] + } +.stabstr 0 ${RELOCATING+(NOLOAD)} : { + [ .stabstr ] + } +} +EOF diff --git a/gnu/usr.bin/binutils/ld/sysdep.h b/gnu/usr.bin/binutils/ld/sysdep.h index 427a9690726..bbeca6d8fae 100644 --- a/gnu/usr.bin/binutils/ld/sysdep.h +++ b/gnu/usr.bin/binutils/ld/sysdep.h @@ -37,7 +37,6 @@ #else extern char *strchr (); extern char *strrchr (); -extern char *strstr (); #endif #endif @@ -55,6 +54,10 @@ extern char *strstr (); #include "fopen-same.h" #endif +#ifdef NEED_DECLARATION_STRSTR +extern char *strstr (); +#endif + #ifdef NEED_DECLARATION_FREE extern void free (); #endif diff --git a/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross1.c b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross1.c new file mode 100644 index 00000000000..56789452a5b --- /dev/null +++ b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross1.c @@ -0,0 +1,6 @@ +extern int foo (); +int +func () +{ + return foo (); +} diff --git a/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross1.t b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross1.t new file mode 100644 index 00000000000..e1948c9e09f --- /dev/null +++ b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross1.t @@ -0,0 +1,6 @@ +NOCROSSREFS ( .text .data ) +SECTIONS +{ + .text : { tmpdir/cross1.o } + .data : { tmpdir/cross2.o } +} diff --git a/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross2.c b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross2.c new file mode 100644 index 00000000000..414317712d1 --- /dev/null +++ b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross2.c @@ -0,0 +1,5 @@ +int +foo () +{ + return 1; +} diff --git a/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross2.t b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross2.t new file mode 100644 index 00000000000..cf046f6c36b --- /dev/null +++ b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross2.t @@ -0,0 +1,6 @@ +NOCROSSREFS ( .text .data ) +SECTIONS +{ + .text : { *(.text) *(.pr) } + .data : { *(.data) *(.sdata) *(.rw) *(.tc0) *(.tc) } +} diff --git a/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross3.c b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross3.c new file mode 100644 index 00000000000..1848c32fd0b --- /dev/null +++ b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/cross3.c @@ -0,0 +1,7 @@ +int i = 4; + +int +foo () +{ + return i; +} diff --git a/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/crossref.exp b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/crossref.exp new file mode 100644 index 00000000000..04bb16ff61c --- /dev/null +++ b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/crossref.exp @@ -0,0 +1,72 @@ +# Test NOCROSSREFS in a linker script. +# By Ian Lance Taylor, Cygnus Support. + +set test1 "NOCROSSREFS 1" +set test2 "NOCROSSREFS 2" + +if { [which $CC] == 0 } { + untested $test1 + untested $test2 + return +} + +if { ![ld_compile $CC "$srcdir/$subdir/cross1.c" tmpdir/cross1.o] \ + || ![ld_compile $CC "$srcdir/$subdir/cross2.c" tmpdir/cross2.o] } { + unresolved $test1 + unresolved $test2 + return +} + +set flags "" + +# The a29k compiled code calls V_SPILL and V_FILL. Since we don't +# need to run this code, but we don't have definitions for those +# functions, we just define them out. +if [istarget a29k*-*-*] { + set flags "$flags --defsym V_SPILL=0 --defsym V_FILL=0" +} + +verbose -log "$ld $flags -o tmpdir/cross1 -T $srcdir/$subdir/cross1.t tmpdir/cross1.o tmpdir/cross2.o" + +catch "exec $ld $flags -o tmpdir/cross1 -T $srcdir/$subdir/cross1.t tmpdir/cross1.o tmpdir/cross2.o" exec_output + +set exec_output [prune_system_crud $host_triplet $exec_output] + +regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output + +if [string match "" $exec_output] then { + fail $test1 +} else { + verbose -log "$exec_output" + if [regexp "prohibited cross reference from .* to `foo' in" $exec_output] { + pass $test1 + } else { + fail $test1 + } +} + +# Check cross references within a single object. + +if { ![ld_compile $CC "$srcdir/$subdir/cross3.c" tmpdir/cross3.o] } { + unresolved $test2 + return +} + +verbose -log "$ld $flags -o tmpdir/cross2 -T $srcdir/$subdir/cross2.t tmpdir/cross3.o" + +catch "exec $ld $flags -o tmpdir/cross2 -T $srcdir/$subdir/cross2.t tmpdir/cross3.o" exec_output + +set exec_output [prune_system_crud $host_triplet $exec_output] + +regsub -all "(^|\n)($ld: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output + +if [string match "" $exec_output] then { + fail $test2 +} else { + verbose -log "$exec_output" + if [regexp "prohibited cross reference from .* to `.*' in" $exec_output] { + pass $test2 + } else { + fail $test2 + } +} diff --git a/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/phdrs.exp b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/phdrs.exp new file mode 100644 index 00000000000..3271252701c --- /dev/null +++ b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/phdrs.exp @@ -0,0 +1,50 @@ +# Test PHDRS in a linker script. +# By Ian Lance Taylor, Cygnus Support. + +# PHDRS is only meaningful for ELF. +if { ![istarget *-*-sysv4*] \ + && ![istarget *-*-unixware*] \ + && ![istarget *-*-elf*] \ + && ![istarget *-*-linux*] \ + && ![istarget *-*-irix5*] \ + && ![istarget *-*-irix6*] \ + && ![istarget *-*-solaris2*] } { + return +} + +if { [istarget *-*-linuxaout*] \ + || [istarget *-*-linuxoldld*] } { + return +} + +# This is a very simplistic test. + +set testname "PHDRS" + +if ![ld_assemble $as $srcdir/$subdir/phdrs.s tmpdir/phdrs.o] { + unresolved $testname + return +} + +set phdrs_regexp \ +".*Program Header:.*PHDR *off *0x00*34 *vaddr *0x00*80034 *paddr *0x00*80034.*filesz *0x0\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* flags r--.*LOAD *off *0x00* *vaddr *0x00*80000 *paddr *0x00*80000.*filesz *0x00*\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* *flags r-x.*LOAD *off *0x0\[0-9a-f\]* *vaddr *0x00*80*\[0-9a-f\]* *paddr *0x00*80*\[0-9a-f\]*.*filesz *0x0\[0-9a-f\]* *memsz *0x0\[0-9a-f\]* *flags *rw-.*" + +if ![ld_simple_link $ld tmpdir/phdrs "-T $srcdir/$subdir/phdrs.t tmpdir/phdrs.o"] { + fail $testname +} else { + if {[which $objdump] == 0} { + unresolved $testname + return + } + + verbose -log "$objdump --private tmpdir/phdrs" + catch "exec $objdump --private tmpdir/phdrs" exec_output + set exec_output [prune_system_crud $host_triplet $exec_output] + verbose -log $exec_output + + if [regexp $phdrs_regexp $exec_output] { + pass $testname + } else { + fail $testname + } +} diff --git a/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/phdrs.s b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/phdrs.s new file mode 100644 index 00000000000..ec1f0d17e6e --- /dev/null +++ b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/phdrs.s @@ -0,0 +1,8 @@ + .text + + .long 1 + + .data + + .long 2 + diff --git a/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/phdrs.t b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/phdrs.t new file mode 100644 index 00000000000..8f710e23fdc --- /dev/null +++ b/gnu/usr.bin/binutils/ld/testsuite/ld-scripts/phdrs.t @@ -0,0 +1,14 @@ +PHDRS +{ + header PT_PHDR PHDRS ; + text PT_LOAD FILEHDR PHDRS ; + data PT_LOAD ; +} + +SECTIONS +{ + . = 0x80000 + SIZEOF_HEADERS; + .text : { *(.text) } :text + .data : { *(.data) } :data + /DISCARD/ : { *(.reginfo) } +} diff --git a/gnu/usr.bin/binutils/ld/testsuite/ld-sh/sh1.s b/gnu/usr.bin/binutils/ld/testsuite/ld-sh/sh1.s index 13c2858f4aa..d18e4390dcc 100644 --- a/gnu/usr.bin/binutils/ld/testsuite/ld-sh/sh1.s +++ b/gnu/usr.bin/binutils/ld/testsuite/ld-sh/sh1.s @@ -10,4 +10,4 @@ L2: .long bar bar: rts - .align 2 + .align 4 diff --git a/gnu/usr.bin/binutils/ld/testsuite/lib/ld.exp b/gnu/usr.bin/binutils/ld/testsuite/lib/ld.exp index a6dfdb03d0b..820824d0721 100644 --- a/gnu/usr.bin/binutils/ld/testsuite/lib/ld.exp +++ b/gnu/usr.bin/binutils/ld/testsuite/lib/ld.exp @@ -32,16 +32,14 @@ proc default_ld_relocate { ld target objects } { return 0 } - send_log "$ld $HOSTING_EMU -o $target -r $objects\n" - verbose "$ld $HOSTING_EMU -o $target -r $objects" + verbose -log "$ld $HOSTING_EMU -o $target -r $objects" catch "exec $ld $HOSTING_EMU -o $target -r $objects" exec_output set exec_output [prune_system_crud $host_triplet $exec_output] if [string match "" $exec_output] then { return 1 } else { - send_log "$exec_output\n" - verbose "$exec_output" + verbose -log "$exec_output" return 0 } } @@ -65,16 +63,14 @@ proc default_ld_link { ld target objects } { return 0 } - send_log "$ld $HOSTING_EMU -o $target $objs $libs\n" - verbose "$ld $HOSTING_EMU -o $target $objs $libs" + verbose -log "$ld $HOSTING_EMU -o $target $objs $libs" catch "exec $ld $HOSTING_EMU -o $target $objs $libs" exec_output set exec_output [prune_system_crud $host_triplet $exec_output] if [string match "" $exec_output] then { return 1 } else { - send_log "$exec_output\n" - verbose "$exec_output" + verbose -log "$exec_output" return 0 } } @@ -91,8 +87,7 @@ proc default_ld_simple_link { ld target objects } { return 0 } - send_log "$ld -o $target $objects\n" - verbose "$ld -o $target $objects" + verbose -log "$ld -o $target $objects" catch "exec $ld -o $target $objects" exec_output set exec_output [prune_system_crud $host_triplet $exec_output] @@ -104,8 +99,7 @@ proc default_ld_simple_link { ld target objects } { if [string match "" $exec_output] then { return 1 } else { - send_log "$exec_output\n" - verbose "$exec_output" + verbose -log "$exec_output" return 0 } } @@ -131,8 +125,7 @@ proc default_ld_compile { cc source object } { catch "exec rm -f $object" exec_output - send_log "$cc -I$srcdir$subdir -c $CFLAGS $source -o $object\n" - verbose "$cc -I$srcdir$subdir -c $CFLAGS $source -o $object" + verbose -log "$cc -I$srcdir$subdir -c $CFLAGS $source -o $object" catch "exec $cc -I$srcdir$subdir -c $CFLAGS $source -o $object" exec_output set exec_output [prune_system_crud $host_triplet $exec_output] @@ -142,13 +135,11 @@ proc default_ld_compile { cc source object } { regsub "\\.c" $dobj ".o" realobj verbose "looking for $realobj" if {[file exists $realobj]} then { - send_log "mv $realobj $object\n" - verbose "mv $realobj $object" + verbose -log "mv $realobj $object" catch "exec mv $realobj $object" exec_output set exec_output [prune_system_crud $host_triplet $exec_output] if {![string match "" $exec_output]} then { - send_log "$exec_output\n" - verbose "$exec_output" + verbose -log "$exec_output" perror "could not move $realobj to $object" return 0 } @@ -159,8 +150,7 @@ proc default_ld_compile { cc source object } { } return 1 } else { - send_log "$exec_output\n" - verbose "$exec_output" + verbose -log "$exec_output" perror "$source: compilation failed" return 0 } @@ -181,16 +171,14 @@ proc default_ld_assemble { as source object } { if ![info exists ASFLAGS] { set ASFLAGS "" } - send_log "$as $ASFLAGS -o $object $source\n" - verbose "$as $ASFLAGS -o $object $source" + verbose -log "$as $ASFLAGS -o $object $source" catch "exec $as $ASFLAGS -o $object $source" exec_output set exec_output [prune_system_crud $host_triplet $exec_output] if [string match "" $exec_output] then { return 1 } else { - send_log "$exec_output\n" - verbose "$exec_output" + verbose -log "$exec_output" perror "$source: assembly failed" return 0 } @@ -212,8 +200,7 @@ proc default_ld_nm { nm object } { if ![info exists NMFLAGS] { set NMFLAGS "" } - send_log "$nm $NMFLAGS $object >tmpdir/nm.out\n" - verbose "$nm $NMFLAGS $object >tmpdir/nm.out" + verbose -log "$nm $NMFLAGS $object >tmpdir/nm.out" catch "exec $nm $NMFLAGS $object >tmpdir/nm.out" exec_output set exec_output [prune_system_crud $host_triplet $exec_output] @@ -229,8 +216,7 @@ proc default_ld_nm { nm object } { close $file return 1 } else { - send_log "$exec_output\n" - verbose $exec_output + verbose -log "$exec_output" perror "$object: nm failed" return 0 } @@ -289,11 +275,8 @@ proc simple_diff { file_1 file_2 } { verbose "\t$file_1: $i: $line_a\n" 3 verbose "\t$file_2: $i: $line_b\n" 3 if [string compare $line_a $line_b] then { - verbose "\t$file_1: $i: $line_a\n" 1 - verbose "\t$file_2: $i: $line_b\n" 1 - - send_log "\t$file_1: $i: $line_a\n" - send_log "\t$file_2: $i: $line_b\n" + verbose -log "\t$file_1: $i: $line_a\n" + verbose -log "\t$file_2: $i: $line_b\n" fail "Test: $target" return diff --git a/gnu/usr.bin/binutils/libiberty/argv.c b/gnu/usr.bin/binutils/libiberty/argv.c index 40582abe408..316400f32bb 100644 --- a/gnu/usr.bin/binutils/libiberty/argv.c +++ b/gnu/usr.bin/binutils/libiberty/argv.c @@ -41,12 +41,14 @@ extern char *strdup (const char *s); /* Non-ANSI */ #else /* !__STDC__ */ +#if !defined _WIN32 || defined __GNUC__ extern char *memcpy (); /* Copy memory region */ extern int strlen (); /* Count length of string */ extern char *malloc (); /* Standard memory allocater */ extern char *realloc (); /* Standard memory reallocator */ extern void free (); /* Free malloc'd memory */ extern char *strdup (); /* Duplicate a string */ +#endif #endif /* __STDC__ */ diff --git a/gnu/usr.bin/binutils/libiberty/choose-temp.c b/gnu/usr.bin/binutils/libiberty/choose-temp.c index b687729e2f6..9561bad9725 100644 --- a/gnu/usr.bin/binutils/libiberty/choose-temp.c +++ b/gnu/usr.bin/binutils/libiberty/choose-temp.c @@ -22,7 +22,7 @@ Boston, MA 02111-1307, USA. */ /* This file lives in at least two places: libiberty and gcc. Don't change one without the other. */ -#if ! defined (_WIN32) && ! defined (NO_SYS_FILE_H) +#ifndef NO_SYS_FILE_H #include #include /* May get R_OK, etc. on some systems. */ #endif @@ -42,7 +42,7 @@ extern char *xmalloc (); #else #include "ansidecl.h" #include "libiberty.h" -#if defined (__MSDOS__) || defined (_WIN32) +#if (defined (__MSDOS__) || defined (_WIN32)) && ! defined (__CYGWIN32__) #define DIR_SEPARATOR '\\' #endif #endif diff --git a/gnu/usr.bin/binutils/libiberty/config.h-vms b/gnu/usr.bin/binutils/libiberty/config.h-vms new file mode 100644 index 00000000000..ccac6a2bcc7 --- /dev/null +++ b/gnu/usr.bin/binutils/libiberty/config.h-vms @@ -0,0 +1,13 @@ +#ifndef NEED_strerror +#define NEED_strerror +#endif +#ifndef NEED_basename +#define NEED_basename +#endif +#ifndef NEED_psignal +#define NEED_psignal +#endif +#ifndef NEED_on_exit +#define NEED_on_exit +#endif + diff --git a/gnu/usr.bin/binutils/libiberty/getopt.c b/gnu/usr.bin/binutils/libiberty/getopt.c index 458dca22b44..79080aa54b3 100644 --- a/gnu/usr.bin/binutils/libiberty/getopt.c +++ b/gnu/usr.bin/binutils/libiberty/getopt.c @@ -389,6 +389,9 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only) if (optind == 0) optstring = _getopt_initialize (optstring); + if (argc == 0) + return EOF; + if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ diff --git a/gnu/usr.bin/binutils/libiberty/makefile.vms b/gnu/usr.bin/binutils/libiberty/makefile.vms new file mode 100644 index 00000000000..5f908e85056 --- /dev/null +++ b/gnu/usr.bin/binutils/libiberty/makefile.vms @@ -0,0 +1,31 @@ +# +# Makefile for libiberty under openVMS/AXP +# +# For use with gnu-make for vms +# +# Created by Klaus Kämpf, kkaempf@progis.de +# +# +CC=gcc + +OBJS=bcopy.obj,bcmp.obj,getopt.obj,obstack.obj,xexit.obj,xmalloc.obj,hex.obj,\ + getopt1.obj,cplus-dem.obj,strncasecmp.obj,strcasecmp.obj,strdup.obj,\ + concat.obj,getruntime.obj,getpagesize.obj,alloca.obj,xstrerror.obj,\ + xstrdup.obj,xatexit.obj + +ifeq ($(CC),gcc) +CFLAGS=/include=([],[-.include]) +else +CFLAGS=/noopt/debug/include=([],[-.include])/define=("const=")/warnings=disable=(missingreturn,implicitfunc) +endif + +libiberty.olb: config.h alloca-conf.h $(OBJS) + purge + lib/create libiberty *.obj + +alloca-conf.h: alloca-norm.h + $(CP) $< $@ + +config.h: config.h-vms + $(CP) $< $@ + diff --git a/gnu/usr.bin/binutils/libiberty/pexecute.c b/gnu/usr.bin/binutils/libiberty/pexecute.c new file mode 100644 index 00000000000..7ffe9caead5 --- /dev/null +++ b/gnu/usr.bin/binutils/libiberty/pexecute.c @@ -0,0 +1,573 @@ +/* Utilities to execute a program in a subprocess (possibly linked by pipes + with other subprocesses), and wait for it. + Copyright (C) 1996 Free Software Foundation, Inc. + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If not, +write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* This file exports two functions: pexecute and pwait. */ + +/* This file lives in at least two places: libiberty and gcc. + Don't change one without the other. */ + +#include +#include + +#ifdef IN_GCC +#include "config.h" +#include "gansidecl.h" +/* ??? Need to find a suitable header file. */ +#define PEXECUTE_FIRST 1 +#define PEXECUTE_LAST 2 +#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST) +#define PEXECUTE_SEARCH 4 +#define PEXECUTE_VERBOSE 8 +#else +#include "libiberty.h" +#endif + +/* stdin file number. */ +#define STDIN_FILE_NO 0 + +/* stdout file number. */ +#define STDOUT_FILE_NO 1 + +/* value of `pipe': port index for reading. */ +#define READ_PORT 0 + +/* value of `pipe': port index for writing. */ +#define WRITE_PORT 1 + +static char *install_error_msg = "installation problem, cannot exec `%s'"; + +/* pexecute: execute a program. + + PROGRAM and ARGV are the arguments to execv/execvp. + + THIS_PNAME is name of the calling program (i.e. argv[0]). + + TEMP_BASE is the path name, sans suffix, of a temporary file to use + if needed. This is currently only needed for MSDOS ports that don't use + GO32 (do any still exist?). Ports that don't need it can pass NULL. + + (FLAGS & PEXECUTE_SEARCH) is non-zero if $PATH should be searched + (??? It's not clear that GCC passes this flag correctly). + (FLAGS & PEXECUTE_FIRST) is nonzero for the first process in chain. + (FLAGS & PEXECUTE_FIRST) is nonzero for the last process in chain. + FIRST_LAST could be simplified to only mark the last of a chain of processes + but that requires the caller to always mark the last one (and not give up + early if some error occurs). It's more robust to require the caller to + mark both ends of the chain. + + The result is the pid on systems like Unix where we fork/exec and on systems + like WIN32 and OS2 where we use spawn. It is up to the caller to wait for + the child. + + The result is the WEXITSTATUS on systems like MSDOS where we spawn and wait + for the child here. + + Upon failure, ERRMSG_FMT and ERRMSG_ARG are set to the text of the error + message with an optional argument (if not needed, ERRMSG_ARG is set to + NULL), and -1 is returned. `errno' is available to the caller to use. + + pwait: cover function for wait. + + PID is the process id of the task to wait for. + STATUS is the `status' argument to wait. + FLAGS is currently unused (allows future enhancement without breaking + upward compatibility). Pass 0 for now. + + The result is the pid of the child reaped, + or -1 for failure (errno says why). + + On systems that don't support waiting for a particular child, PID is + ignored. On systems like MSDOS that don't really multitask pwait + is just a mechanism to provide a consistent interface for the caller. + + pfinish: finish generation of script + + pfinish is necessary for systems like MPW where a script is generated that + runs the requested programs. +*/ + +#ifdef __MSDOS__ + +/* MSDOS doesn't multitask, but for the sake of a consistent interface + the code behaves like it does. pexecute runs the program, tucks the + exit code away, and returns a "pid". pwait must be called to fetch the + exit code. */ + +#include + +/* For communicating information from pexecute to pwait. */ +static int last_pid = 0; +static int last_status = 0; +static int last_reaped = 0; + +int +pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) + const char *program; + char * const *argv; + const char *this_pname; + const char *temp_base; + char **errmsg_fmt, **errmsg_arg; + int flags; +{ + int rc; + + last_pid++; + if (last_pid < 0) + last_pid = 1; + + if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE) + abort (); + +#ifdef __GO32__ + /* ??? What are the possible return values from spawnv? */ + rc = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (1, program, argv); +#else + char *scmd, *rf; + FILE *argfile; + int i, el = flags & PEXECUTE_SEARCH ? 4 : 0; + + scmd = (char *) xmalloc (strlen (program) + strlen (temp_base) + 6 + el); + rf = scmd + strlen(program) + 2 + el; + sprintf (scmd, "%s%s @%s.gp", program, + (flags & PEXECUTE_SEARCH ? ".exe" : ""), temp_base); + argfile = fopen (rf, "w"); + if (argfile == 0) + { + int errno_save = errno; + free (scmd); + errno = errno_save; + *errmsg_fmt = "cannot open `%s.gp'"; + *errmsg_arg = temp_base; + return -1; + } + + for (i=1; argv[i]; i++) + { + char *cp; + for (cp = argv[i]; *cp; cp++) + { + if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp)) + fputc ('\\', argfile); + fputc (*cp, argfile); + } + fputc ('\n', argfile); + } + fclose (argfile); + + rc = system (scmd); + + { + int errno_save = errno; + remove (rf); + free (scmd); + errno = errno_save; + } +#endif + + if (rc == -1) + { + *errmsg_fmt = install_error_msg; + *errmsg_arg = program; + return -1; + } + + /* Tuck the status away for pwait, and return a "pid". */ + last_status = rc << 8; + return last_pid; +} + +int +pwait (pid, status, flags) + int pid; + int *status; + int flags; +{ + /* On MSDOS each pexecute must be followed by it's associated pwait. */ + if (pid != last_pid + /* Called twice for the same child? */ + || pid == last_reaped) + { + /* ??? ECHILD would be a better choice. Can we use it here? */ + errno = EINVAL; + return -1; + } + /* ??? Here's an opportunity to canonicalize the values in STATUS. + Needed? */ + *status = last_status; + last_reaped = last_pid; + return last_pid; +} + +#endif /* MSDOS */ + +#if defined (_WIN32) && !defined (__CYGWIN32__) + +#include +/* ??? Why are these __spawnv{,p} and not _spawnv{,p}? */ +extern int __spawnv (); +extern int __spawnvp (); + +int +pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) + const char *program; + char * const *argv; + const char *this_pname; + const char *temp_base; + char **errmsg_fmt, **errmsg_arg; + int flags; +{ + int pid; + + if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE) + abort (); + pid = (flags & PEXECUTE_SEARCH ? __spawnvp : __spawnv) (_P_NOWAIT, program, argv); + if (pid == -1) + { + *errmsg_fmt = install_error_msg; + *errmsg_arg = program; + return -1; + } + return pid; +} + +int +pwait (pid, status, flags) + int pid; + int *status; + int flags; +{ + /* ??? Here's an opportunity to canonicalize the values in STATUS. + Needed? */ + int pid = cwait (status, pid, WAIT_CHILD); + return pid; +} + +#endif /* WIN32 */ + +#ifdef OS2 + +/* ??? Does OS2 have process.h? */ +extern int spawnv (); +extern int spawnvp (); + +int +pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) + const char *program; + char * const *argv; + const char *this_pname; + const char *temp_base; + char **errmsg_fmt, **errmsg_arg; + int flags; +{ + int pid; + + if ((flags & PEXECUTE_ONE) != PEXECUTE_ONE) + abort (); + /* ??? Presumably 1 == _P_NOWAIT. */ + pid = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (1, program, argv); + if (pid == -1) + { + *errmsg_fmt = install_error_msg; + *errmsg_arg = program; + return -1; + } + return pid; +} + +int +pwait (pid, status, flags) + int pid; + int *status; + int flags; +{ + /* ??? Here's an opportunity to canonicalize the values in STATUS. + Needed? */ + int pid = wait (status); + return pid; +} + +#endif /* OS2 */ + +#ifdef MPW + +/* MPW pexecute doesn't actually run anything; instead, it writes out + script commands that, when run, will do the actual executing. + + For example, in GCC's case, GCC will write out several script commands: + + cpp ... + cc1 ... + as ... + ld ... + + and then exit. None of the above programs will have run yet. The task + that called GCC will then execute the script and cause cpp,etc. to run. + The caller must invoke pfinish before calling exit. This adds + the finishing touches to the generated script. */ + +static int first_time = 1; + +int +pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) + const char *program; + char **argv; + const char *this_pname; + const char *temp_base; + char **errmsg_fmt, **errmsg_arg; + int flags; +{ + char tmpprogram[255]; + char *cp, *tmpname; + int i; + + mpwify_filename (program, tmpprogram); + if (first_time) + { + printf ("Set Failed 0\n"); + first_time = 0; + } + + fputs ("If {Failed} == 0\n", stdout); + /* If being verbose, output a copy of the command. It should be + accurate enough and escaped enough to be "clickable". */ + if (flags & PEXECUTE_VERBOSE) + { + fputs ("\tEcho ", stdout); + fputc ('\'', stdout); + fputs (tmpprogram, stdout); + fputc ('\'', stdout); + fputc (' ', stdout); + for (i=1; argv[i]; i++) + { + /* We have to quote every arg, so that when the echo is + executed, the quotes are stripped and the original arg + is left. */ + fputc ('\'', stdout); + for (cp = argv[i]; *cp; cp++) + { + /* Write an Option-d esc char in front of special chars. */ + if (strchr ("\"'+", *cp)) + fputc ('\266', stdout); + fputc (*cp, stdout); + } + fputc ('\'', stdout); + fputc (' ', stdout); + } + fputs ("\n", stdout); + } + fputs ("\t", stdout); + fputs (tmpprogram, stdout); + fputc (' ', stdout); + + for (i=1; argv[i]; i++) + { + if (strchr (argv[i], ' ')) + fputc ('\'', stdout); + for (cp = argv[i]; *cp; cp++) + { + /* Write an Option-d esc char in front of special chars. */ + if (strchr ("\"'+", *cp)) + { + fputc ('\266', stdout); + } + fputc (*cp, stdout); + } + if (strchr (argv[i], ' ')) + fputc ('\'', stdout); + fputc (' ', stdout); + } + + fputs ("\n", stdout); + + /* Output commands that arrange to clean up and exit if a failure occurs. + We have to be careful to collect the status from the program that was + run, rather than some other script command. Also, we don't exit + immediately, since necessary cleanups are at the end of the script. */ + fputs ("\tSet TmpStatus {Status}\n", stdout); + fputs ("\tIf {TmpStatus} != 0\n", stdout); + fputs ("\t\tSet Failed {TmpStatus}\n", stdout); + fputs ("\tEnd\n", stdout); + fputs ("End\n", stdout); + + /* We're just composing a script, can't fail here. */ + return 0; +} + +int +pwait (pid, status, flags) + int pid; + int *status; + int flags; +{ + *status = 0; + return 0; +} + +/* Write out commands that will exit with the correct error code + if something in the script failed. */ + +void +pfinish () +{ + printf ("\tExit \"{Failed}\"\n"); +} + +#endif /* MPW */ + +/* include for Unix-like environments but not for Dos-like environments */ +#if ! defined (__MSDOS__) && ! defined (OS2) && ! defined (MPW) \ + && (defined (__CYGWIN32__) || ! defined (_WIN32)) + +#ifdef USG +#define vfork fork +#endif + +extern int execv (); +extern int execvp (); + +int +pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags) + const char *program; + char * const *argv; + const char *this_pname; + const char *temp_base; + char **errmsg_fmt, **errmsg_arg; + int flags; +{ + int (*func)() = (flags & PEXECUTE_SEARCH ? execvp : execv); + int pid; + int pdes[2]; + int input_desc, output_desc; + int retries, sleep_interval; + /* Pipe waiting from last process, to be used as input for the next one. + Value is STDIN_FILE_NO if no pipe is waiting + (i.e. the next command is the first of a group). */ + static int last_pipe_input; + + /* If this is the first process, initialize. */ + if (flags & PEXECUTE_FIRST) + last_pipe_input = STDIN_FILE_NO; + + input_desc = last_pipe_input; + + /* If this isn't the last process, make a pipe for its output, + and record it as waiting to be the input to the next process. */ + if (! (flags & PEXECUTE_LAST)) + { + if (pipe (pdes) < 0) + { + *errmsg_fmt = "pipe"; + *errmsg_arg = NULL; + return -1; + } + output_desc = pdes[WRITE_PORT]; + last_pipe_input = pdes[READ_PORT]; + } + else + { + /* Last process. */ + output_desc = STDOUT_FILE_NO; + last_pipe_input = STDIN_FILE_NO; + } + + /* Fork a subprocess; wait and retry if it fails. */ + sleep_interval = 1; + for (retries = 0; retries < 4; retries++) + { + pid = vfork (); + if (pid >= 0) + break; + sleep (sleep_interval); + sleep_interval *= 2; + } + + switch (pid) + { + case -1: + { +#ifdef vfork + *errmsg_fmt = "fork"; +#else + *errmsg_fmt = "vfork"; +#endif + *errmsg_arg = NULL; + return -1; + } + + case 0: /* child */ + /* Move the input and output pipes into place, if necessary. */ + if (input_desc != STDIN_FILE_NO) + { + close (STDIN_FILE_NO); + dup (input_desc); + close (input_desc); + } + if (output_desc != STDOUT_FILE_NO) + { + close (STDOUT_FILE_NO); + dup (output_desc); + close (output_desc); + } + + /* Close the parent's descs that aren't wanted here. */ + if (last_pipe_input != STDIN_FILE_NO) + close (last_pipe_input); + + /* Exec the program. */ + (*func) (program, argv); + + /* Note: Calling fprintf and exit here doesn't seem right for vfork. */ + fprintf (stderr, "%s: ", this_pname); + fprintf (stderr, install_error_msg, program); +#ifdef IN_GCC + fprintf (stderr, ": %s\n", my_strerror (errno)); +#else + fprintf (stderr, ": %s\n", xstrerror (errno)); +#endif + exit (-1); + /* NOTREACHED */ + return 0; + + default: + /* In the parent, after forking. + Close the descriptors that we made for this child. */ + if (input_desc != STDIN_FILE_NO) + close (input_desc); + if (output_desc != STDOUT_FILE_NO) + close (output_desc); + + /* Return child's process number. */ + return pid; + } +} + +int +pwait (pid, status, flags) + int pid; + int *status; + int flags; +{ + /* ??? Here's an opportunity to canonicalize the values in STATUS. + Needed? */ + pid = wait (status); + return pid; +} + +#endif /* ! __MSDOS__ && ! OS2 && ! MPW && (__CYGWIN32___ || ! _WIN32) */ diff --git a/gnu/usr.bin/binutils/libiberty/vmsbuild.com b/gnu/usr.bin/binutils/libiberty/vmsbuild.com index e1c203f9f47..9400b45723a 100644 --- a/gnu/usr.bin/binutils/libiberty/vmsbuild.com +++ b/gnu/usr.bin/binutils/libiberty/vmsbuild.com @@ -12,10 +12,10 @@ $ LIB_NAME = "liberty.olb" !this is what we're going to construct $ WORK_LIB = "new-lib.olb" !used to guard against an incomplete build $ $! manually copied from Makefile.in -$ REQUIRED_OFILES = "argv.o basename.o concat.o cplus-dem.o fdmatch.o "- - + "getopt.o getopt1.o getruntime.o hex.o "- +$ REQUIRED_OFILES = "argv.o basename.o choose-temp.o concat.o cplus-dem.o "- + + "fdmatch.o getopt.o getopt1.o getruntime.o hex.o "- + "floatformat.o obstack.o spaces.o strerror.o strsignal.o "- - + "vasprintf.o xatexit.o xexit.o xmalloc.o xstrerror.o" + + "vasprintf.o xatexit.o xexit.o xmalloc.o xstrdup.o xstrerror.o" $! anything not caught by link+search of dummy.* should be added here $ EXTRA_OFILES = "" $! @@ -36,6 +36,7 @@ $ LIBR 'WORK_LIB' /Create $ $! first pass: compile "required" modules $ ofiles = REQUIRED_OFILES + " " + EXTRA_OFILES +$ pass = 1 $ gosub do_ofiles $ $! second pass: process dummy.c, using the first pass' results @@ -71,8 +72,10 @@ $ ofiles = ofiles + " " + f$element(1," ",iline) + ".o" $ goto iloop $idone: close ifile$ $ DELETE dummy.list;* +$ on error then ABORT $ $! third pass: compile "missing" modules collected in pass 2 +$ pass = 3 $ gosub do_ofiles $ $! finish up @@ -103,15 +106,36 @@ $ f = f$element(i," ",ofiles) $ if f.eqs." " then goto odone $ f = f - ".o" !strip dummy suffix $ ECHO " ''f'" -$ 'CC' 'f'.c -$ LIBR 'WORK_LIB' 'f'.obj /Insert -$ DELETE 'f'.obj;* +$ skip_f = 0 +$ if pass.eq.3 .and. f$search("''f'.c").eqs."" then gosub chk_deffunc +$ if .not.skip_f +$ then +$ 'CC' 'f'.c +$ LIBR 'WORK_LIB' 'f'.obj /Insert +$ DELETE 'f'.obj;* +$ endif $ i = i + 1 $ goto oloop $odone: $ return $ $! +$! check functions.def for a DEFFUNC() entry corresponding to missing file 'f'.c +$! +$chk_deffunc: +$ define/User sys$output _NL: +$ define/User sys$error _NL: +$ SEARCH functions.def "DEFFUNC","''f'" /Match=AND +$ if (($status.and.%x7FFFFFFF) .eq. 1) +$ then +$ skip_f = 1 +$ open/Append config_h config.h +$ write config_h "#define NEED_''f'" +$ close config_h +$ endif +$ return +$ +$! $pass2_failure1: $! if we reach here, dummy.c failed to compile and we're really stuck $ type sys$input: diff --git a/gnu/usr.bin/binutils/mpw-config.in b/gnu/usr.bin/binutils/mpw-config.in index f27b0e5eec3..db622bb720d 100644 --- a/gnu/usr.bin/binutils/mpw-config.in +++ b/gnu/usr.bin/binutils/mpw-config.in @@ -10,15 +10,22 @@ Echo byacc is `Which byacc` Echo flex is `Which flex` Echo forward-include is `Which forward-include` Echo MoveIfChange is `Which MoveIfChange` +Echo mpw-touch is `Which mpw-touch` +Echo mpw-true is `Which mpw-true` +Echo null-command is `Which null-command` Echo open-brace is `Which open-brace` Echo sed is `Which sed` -Echo mpw-touch is `Which mpw-touch` Echo 'tr-7to8' is `Which tr-7to8` +Echo true is `Which true` Set Exit 1 -Set host_libs "libiberty opcodes bfd readline" +Set host_libs "mmalloc libiberty opcodes bfd readline gash tcl tk tclX" -Set host_tools "byacc flex binutils ld gas gcc gdb" +Set host_tools "texinfo byacc flex bison binutils ld gas gcc gdb make patch \Option-d + prms send-pr gprof gdbtest tgas etc expect dejagnu sim bash \Option-d + m4 autoconf ispell grep diff rcs cvs fileutils shellutils time \Option-d + textutils wdiff find emacs emacs19 uudecode hello tar gzip indent \Option-d + recode release sed utils guile perl apache inet gawk" Set target_libs "newlib" @@ -73,6 +80,7 @@ End If forward-include "{srcroot}"include:elf:common.h "{edir}"'elf/common.h' forward-include "{srcroot}"include:elf:dwarf.h "{edir}"'elf/dwarf.h' +forward-include "{srcroot}"include:elf:dwarf2.h "{edir}"'elf/dwarf2.h' forward-include "{srcroot}"include:elf:external.h "{edir}"'elf/external.h' forward-include "{srcroot}"include:elf:internal.h "{edir}"'elf/internal.h' diff --git a/gnu/usr.bin/binutils/opcodes/alpha-opc.c b/gnu/usr.bin/binutils/opcodes/alpha-opc.c new file mode 100644 index 00000000000..a64598e4e5e --- /dev/null +++ b/gnu/usr.bin/binutils/opcodes/alpha-opc.c @@ -0,0 +1,1356 @@ +/* alpha-opc.c -- Alpha AXP opcode list + Copyright 1996 Free Software Foundation, Inc. + Contributed by Richard Henderson , + patterned after the PPC opcode handling written by Ian Lance Taylor. + + This file is part of GDB, GAS, and the GNU binutils. + + GDB, GAS, and the GNU binutils are free software; you can redistribute + them and/or modify them 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. + + GDB, GAS, and the GNU binutils are distributed in the hope that they + 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 file; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#include +#include "ansidecl.h" +#include "opcode/alpha.h" + +/* This file holds the Alpha AXP 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. */ + +/* Local insertion and extraction functions */ + +static unsigned insert_rba PARAMS((unsigned, int, const char **)); +static unsigned insert_rca PARAMS((unsigned, int, const char **)); +static unsigned insert_za PARAMS((unsigned, int, const char **)); +static unsigned insert_zb PARAMS((unsigned, int, const char **)); +static unsigned insert_zc PARAMS((unsigned, int, const char **)); +static unsigned insert_bdisp PARAMS((unsigned, int, const char **)); +static unsigned insert_jhint PARAMS((unsigned, int, const char **)); + +static int extract_rba PARAMS((unsigned, int *)); +static int extract_rca PARAMS((unsigned, int *)); +static int extract_za PARAMS((unsigned, int *)); +static int extract_zb PARAMS((unsigned, int *)); +static int extract_zc PARAMS((unsigned, int *)); +static int extract_bdisp PARAMS((unsigned, int *)); +static int extract_jhint PARAMS((unsigned, int *)); + + +/* The operands table */ + +const struct alpha_operand alpha_operands[] = +{ + /* The fields are bits, shift, insert, extract, flags */ + /* The zero index is used to indicate end-of-list */ +#define UNUSED 0 + { 0, 0, BFD_RELOC_UNUSED, 0, 0 }, + + /* The plain integer register fields */ +#define RA (UNUSED + 1) + { 5, 21, BFD_RELOC_UNUSED, 0, 0, AXP_OPERAND_IR }, +#define RB (RA + 1) + { 5, 16, BFD_RELOC_UNUSED, 0, 0, AXP_OPERAND_IR }, +#define RC (RB + 1) + { 5, 0, BFD_RELOC_UNUSED, 0, 0, AXP_OPERAND_IR }, + + /* The plain fp register fields */ +#define FA (RC + 1) + { 5, 21, BFD_RELOC_UNUSED, 0, 0, AXP_OPERAND_FPR }, +#define FB (FA + 1) + { 5, 16, BFD_RELOC_UNUSED, 0, 0, AXP_OPERAND_FPR }, +#define FC (FB + 1) + { 5, 0, BFD_RELOC_UNUSED, 0, 0, AXP_OPERAND_FPR }, + + /* The integer registers when they are ZERO */ +#define ZA (FC + 1) + { 5, 21, BFD_RELOC_UNUSED, insert_za, extract_za, AXP_OPERAND_FAKE }, +#define ZB (ZA + 1) + { 5, 16, BFD_RELOC_UNUSED, insert_zb, extract_zb, AXP_OPERAND_FAKE }, +#define ZC (ZB + 1) + { 5, 0, BFD_RELOC_UNUSED, insert_zc, extract_zc, AXP_OPERAND_FAKE }, + + /* The RB field when it needs parentheses */ +#define PRB (ZC + 1) + { 5, 16, BFD_RELOC_UNUSED, 0, 0, AXP_OPERAND_IR|AXP_OPERAND_PARENS }, + + /* The RB field when it needs parentheses _and_ a preceding comma */ +#define CPRB (PRB + 1) + { 5, 16, BFD_RELOC_UNUSED, 0, 0, + AXP_OPERAND_IR|AXP_OPERAND_PARENS|AXP_OPERAND_COMMA }, + + /* The RB field when it must be the same as the RA field */ +#define RBA (CPRB + 1) + { 5, 16, BFD_RELOC_UNUSED, insert_rba, extract_rba, AXP_OPERAND_FAKE }, + + /* The RC field when it must be the same as the RB field */ +#define RCA (RBA + 1) + { 5, 0, BFD_RELOC_UNUSED, insert_rca, extract_rca, AXP_OPERAND_FAKE }, + + /* The RC field when it can *default* to RA */ +#define DRC1 (RCA + 1) + { 5, 0, BFD_RELOC_UNUSED, 0, 0, + AXP_OPERAND_IR|AXP_OPERAND_DEFAULT_FIRST }, + + /* The RC field when it can *default* to RB */ +#define DRC2 (DRC1 + 1) + { 5, 0, BFD_RELOC_UNUSED, 0, 0, + AXP_OPERAND_IR|AXP_OPERAND_DEFAULT_SECOND }, + + /* The FC field when it can *default* to RA */ +#define DFC1 (DRC2 + 1) + { 5, 0, BFD_RELOC_UNUSED, 0, 0, + AXP_OPERAND_FPR|AXP_OPERAND_DEFAULT_FIRST }, + + /* The FC field when it can *default* to RB */ +#define DFC2 (DFC1 + 1) + { 5, 0, BFD_RELOC_UNUSED, 0, 0, + AXP_OPERAND_FPR|AXP_OPERAND_DEFAULT_SECOND }, + + /* The unsigned 8-bit literal of Operate format insns */ +#define LIT (DFC2 + 1) + { 8, 13, BFD_RELOC_UNUSED+LIT, 0, 0, AXP_OPERAND_UNSIGNED }, + + /* The signed 16-bit displacement of Memory format insns. From here + we can't tell what relocation should be used, so don't use a default. */ +#define MDISP (LIT + 1) + { 16, 0, BFD_RELOC_UNUSED+MDISP, 0, 0, AXP_OPERAND_SIGNED }, + + /* The signed "23-bit" aligned displacement of Branch format insns */ +#define BDISP (MDISP + 1) + { 21, 0, BFD_RELOC_23_PCREL_S2, insert_bdisp, extract_bdisp, + AXP_OPERAND_RELATIVE }, + + /* The 26-bit PALcode function */ +#define PALFN (BDISP + 1) + { 26, 0, BFD_RELOC_UNUSED+PALFN, 0, 0, AXP_OPERAND_UNSIGNED }, + + /* The optional signed "16-bit" aligned displacement of the JMP/JSR hint */ +#define JMPHINT (PALFN + 1) + { 14, 0, BFD_RELOC_ALPHA_HINT, insert_jhint, extract_jhint, + AXP_OPERAND_RELATIVE|AXP_OPERAND_DEFAULT_ZERO|AXP_OPERAND_NOOVERFLOW }, + + /* The optional hint to RET/JSR_COROUTINE */ +#define RETHINT (JMPHINT + 1) + { 14, 0, BFD_RELOC_UNUSED+RETHINT, 0, 0, + AXP_OPERAND_UNSIGNED|AXP_OPERAND_DEFAULT_ZERO }, + + /* The 12-bit displacement for the ev4 hw_{ld,st} (pal1b/pal1f) insns */ +#define EV4HWDISP (RETHINT + 1) + { 12, 0, BFD_RELOC_UNUSED+EV4HWDISP, 0, 0, AXP_OPERAND_SIGNED }, + + /* The 5-bit index for the ev4 hw_m[ft]pr (pal19/pal1d) insns */ +#define EV4HWINDEX (EV4HWDISP + 1) + { 5, 0, BFD_RELOC_UNUSED+EV4HWINDEX, 0, 0, AXP_OPERAND_UNSIGNED }, + + /* The 8-bit index for the oddly unqualified hw_m[tf]pr insns + that occur in DEC PALcode. */ +#define EV4EXTHWINDEX (EV4HWINDEX + 1) + { 8, 0, BFD_RELOC_UNUSED+EV4EXTHWINDEX, 0, 0, AXP_OPERAND_UNSIGNED }, + + /* The 10-bit displacement for the ev5 hw_{ld,st} (pal1b/pal1f) insns */ +#define EV5HWDISP (EV4EXTHWINDEX + 1) + { 10, 0, BFD_RELOC_UNUSED+EV5HWDISP, 0, 0, AXP_OPERAND_SIGNED }, + + /* The 16-bit index for the ev5 hw_m[ft]pr (pal19/pal1d) insns */ +#define EV5HWINDEX (EV5HWDISP + 1) + { 16, 0, BFD_RELOC_UNUSED+EV5HWINDEX, 0, 0, AXP_OPERAND_UNSIGNED }, +}; + +const int alpha_num_operands = sizeof(alpha_operands)/sizeof(*alpha_operands); + +/* The RB field when it is the same as the RA field in the same insn. + This operand is marked fake. The insertion function just copies + the RA field into the RB field, and the extraction function just + checks that the fields are the same. */ + +/*ARGSUSED*/ +static unsigned +insert_rba(insn, value, errmsg) + unsigned insn; + int value; + const char **errmsg; +{ + return insn | (((insn >> 21) & 0x1f) << 16); +} + +static int +extract_rba(insn, invalid) + unsigned insn; + int *invalid; +{ + if (invalid != (int *) NULL + && ((insn >> 21) & 0x1f) != ((insn >> 16) & 0x1f)) + *invalid = 1; + return 0; +} + + +/* The same for the RC field */ + +/*ARGSUSED*/ +static unsigned +insert_rca(insn, value, errmsg) + unsigned insn; + int value; + const char **errmsg; +{ + return insn | ((insn >> 21) & 0x1f); +} + +static int +extract_rca(insn, invalid) + unsigned insn; + int *invalid; +{ + if (invalid != (int *) NULL + && ((insn >> 21) & 0x1f) != (insn & 0x1f)) + *invalid = 1; + return 0; +} + + +/* Fake arguments in which the registers must be set to ZERO */ + +/*ARGSUSED*/ +static unsigned +insert_za(insn, value, errmsg) + unsigned insn; + int value; + const char **errmsg; +{ + return insn | (31 << 21); +} + +static int +extract_za(insn, invalid) + unsigned insn; + int *invalid; +{ + if (invalid != (int *) NULL && ((insn >> 21) & 0x1f) != 31) + *invalid = 1; + return 0; +} + +/*ARGSUSED*/ +static unsigned +insert_zb(insn, value, errmsg) + unsigned insn; + int value; + const char **errmsg; +{ + return insn | (31 << 16); +} + +static int +extract_zb(insn, invalid) + unsigned insn; + int *invalid; +{ + if (invalid != (int *) NULL && ((insn >> 16) & 0x1f) != 31) + *invalid = 1; + return 0; +} + +/*ARGSUSED*/ +static unsigned +insert_zc(insn, value, errmsg) + unsigned insn; + int value; + const char **errmsg; +{ + return insn | 31; +} + +static int +extract_zc(insn, invalid) + unsigned insn; + int *invalid; +{ + if (invalid != (int *) NULL && (insn & 0x1f) != 31) + *invalid = 1; + return 0; +} + + +/* The displacement field of a Branch format insn. */ + +static unsigned +insert_bdisp(insn, value, errmsg) + unsigned insn; + int value; + const char **errmsg; +{ + if (errmsg != (const char **)NULL && (value & 3)) + *errmsg = "branch operand unaligned"; + return insn | ((value / 4) & 0x1FFFFF); +} + +/*ARGSUSED*/ +static int +extract_bdisp(insn, invalid) + unsigned insn; + int *invalid; +{ + return 4 * (((insn & 0x1FFFFF) ^ 0x100000) - 0x100000); +} + + +/* The hint field of a JMP/JSR insn. */ + +static unsigned +insert_jhint(insn, value, errmsg) + unsigned insn; + int value; + const char **errmsg; +{ + if (errmsg != (const char **)NULL && (value & 3)) + *errmsg = "jump hint unaligned"; + return insn | ((value / 4) & 0xFFFF); +} + +/*ARGSUSED*/ +static int +extract_jhint(insn, invalid) + unsigned insn; + int *invalid; +{ + return 4 * (((insn & 0x3FFF) ^ 0x2000) - 0x2000); +} + + +/* Macros used to form opcodes */ + +/* The main opcode */ +#define OP(x) (((x) & 0x3F) << 26) +#define OP_MASK 0xFC000000 + +/* Branch format instructions */ +#define BRA_(oo) OP(oo) +#define BRA_MASK OP_MASK +#define BRA(oo) BRA_(oo), BRA_MASK + +/* Floating point format instructions */ +#define FP_(oo,fff) (OP(oo) | (((fff) & 0x7FF) << 5)) +#define FP_MASK (OP_MASK | 0xFFE0) +#define FP(oo,fff) FP_(oo,fff), FP_MASK + +/* Memory format instructions */ +#define MEM_(oo) OP(oo) +#define MEM_MASK OP_MASK +#define MEM(oo) MEM_(oo), MEM_MASK + +/* Memory/Func Code format instructions */ +#define MFC_(oo,ffff) (OP(oo) | ((ffff) & 0xFFFF)) +#define MFC_MASK (OP_MASK | 0xFFFF) +#define MFC(oo,ffff) MFC_(oo,ffff), MFC_MASK + +/* Memory/Branch format instructions */ +#define MBR_(oo,h) (OP(oo) | (((h) & 3) << 14)) +#define MBR_MASK (OP_MASK | 0xC000) +#define MBR(oo,h) MBR_(oo,h), MBR_MASK + +/* Operate format instructions. The OPRL variant specifies a + literal second argument. */ +#define OPR_(oo,ff) (OP(oo) | (((ff) & 0x7F) << 5)) +#define OPRL_(oo,ff) (OPR_((oo),(ff)) | 0x1000) +#define OPR_MASK (OP_MASK | 0x1FE0) +#define OPR(oo,ff) OPR_(oo,ff), OPR_MASK +#define OPRL(oo,ff) OPRL_(oo,ff), OPR_MASK + +/* Generic PALcode format instructions */ +#define PCD_(oo) OP(oo) +#define PCD_MASK OP_MASK +#define PCD(oo) PCD_(oo), PCD_MASK + +/* Specific PALcode instructions */ +#define SPCD_(oo,ffff) (OP(oo) | ((ffff) & 0x3FFFFFF)) +#define SPCD_MASK 0xFFFFFFFF +#define SPCD(oo,ffff) SPCD_(oo,ffff), SPCD_MASK + +/* Hardware memory (hw_{ld,st}) instructions */ +#define EV4HWMEM_(oo,f) (OP(oo) | (((f) & 0xF) << 12)) +#define EV4HWMEM_MASK (OP_MASK | 0xF000) +#define EV4HWMEM(oo,f) EV4HWMEM_(oo,f), EV4HWMEM_MASK + +#define EV5HWMEM_(oo,f) (OP(oo) | (((f) & 0x3F) << 10)) +#define EV5HWMEM_MASK (OP_MASK | 0xF800) +#define EV5HWMEM(oo,f) EV5HWMEM_(oo,f), EV5HWMEM_MASK + +/* Common combinations of flags and arguments */ +#define ALL AXP_OPCODE_ALL +#define EV4 AXP_OPCODE_EV4 +#define EV5 AXP_OPCODE_EV5 +#define EV56 AXP_OPCODE_EV56 +#define EV5x EV5|EV56 + +#define ARG_NONE { 0 } +#define ARG_BRA { RA, BDISP } +#define ARG_FBRA { FA, BDISP } +#define ARG_FP { FA, FB, DFC1 } +#define ARG_FPZ1 { ZA, FB, DFC1 } +#define ARG_MEM { RA, MDISP, PRB } +#define ARG_FMEM { FA, MDISP, PRB } +#define ARG_OPR { RA, RB, DRC1 } +#define ARG_OPRL { RA, LIT, DRC1 } +#define ARG_OPRZ1 { ZA, RB, DRC1 } +#define ARG_OPRLZ1 { ZA, LIT, RC } +#define ARG_PCD { PALFN } +#define ARG_EV4HWMEM { RA, EV4HWDISP, PRB } +#define ARG_EV4HWMPR { RA, RBA, EV4HWINDEX } +#define ARG_EV5HWMEM { RA, EV5HWDISP, PRB } + + +/* The opcode table. + + The format of the opcode table is: + + NAME OPCODE MASK { OPERANDS } + + NAME is the name of the instruction. + + OPCODE is the instruction opcode. + + MASK is the opcode mask; this is used to tell the disassembler + which bits in the actual opcode must match OPCODE. + + OPERANDS is the list of operands. + + The preceding macros merge the text of the OPCODE and MASK fields. + + The disassembler reads the table in order and prints the first + instruction which matches, so this table is sorted to put more + specific instructions before more general instructions. + + Otherwise, it is sorted by major opcode and minor function code. + + There are three classes of not-really-instructions in this table: + + ALIAS is another name for another instruction. Some of + these come from the Architecture Handbook, some + come from the original gas opcode tables. In all + cases, the functionality of the opcode is unchanged. + + PSEUDO a stylized code form endorsed by Chapter A.4 of the + Architecture Handbook. + + EXTRA a stylized code form found in the original gas tables. + + XXX: Can anyone shed light on the pal{19,1b,1d,1e,1f} opcodes? + XXX: Do we want to conditionally compile complete sets of the + PALcodes described in the Architecture Handbook? +*/ + +const struct alpha_opcode alpha_opcodes[] = { + { "halt", SPCD(0x00,0x0000), ALL, ARG_NONE }, + { "draina", SPCD(0x00,0x0002), ALL, ARG_NONE }, + { "bpt", SPCD(0x00,0x0080), ALL, ARG_NONE }, + { "callsys", SPCD(0x00,0x0083), ALL, ARG_NONE }, + { "chmk", SPCD(0x00,0x0083), ALL, ARG_NONE }, + { "imb", SPCD(0x00,0x0086), ALL, ARG_NONE }, + { "call_pal", PCD(0x00), ALL, ARG_PCD }, + { "pal", PCD(0x00), ALL, ARG_PCD }, /* alias */ + + { "lda", MEM(0x08), ALL, ARG_MEM }, + { "ldah", MEM(0x09), ALL, ARG_MEM }, + { "unop", MEM(0x0B), ALL, { ZA } }, /* pseudo */ + { "ldq_u", MEM(0x0B), ALL, ARG_MEM }, + { "stq_u", MEM(0x0F), ALL, ARG_MEM }, + + { "sextl", OPR(0x10,0x00), ALL, ARG_OPRZ1 }, /* pseudo */ + { "sextl", OPRL(0x10,0x00), ALL, ARG_OPRLZ1 }, /* pseudo */ + { "addl", OPR(0x10,0x00), ALL, ARG_OPR }, + { "addl", OPRL(0x10,0x00), ALL, ARG_OPRL }, + { "s4addl", OPR(0x10,0x02), ALL, ARG_OPR }, + { "s4addl", OPRL(0x10,0x02), ALL, ARG_OPRL }, + { "negl", OPR(0x10,0x09), ALL, ARG_OPRZ1 }, /* pseudo */ + { "negl", OPRL(0x10,0x09), ALL, ARG_OPRLZ1 }, /* pseudo */ + { "subl", OPR(0x10,0x09), ALL, ARG_OPR }, + { "subl", OPRL(0x10,0x09), ALL, ARG_OPRL }, + { "s4subl", OPR(0x10,0x0B), ALL, ARG_OPR }, + { "s4subl", OPRL(0x10,0x0B), ALL, ARG_OPRL }, + { "cmpbge", OPR(0x10,0x0F), ALL, ARG_OPR }, + { "cmpbge", OPRL(0x10,0x0F), ALL, ARG_OPRL }, + { "s8addl", OPR(0x10,0x12), ALL, ARG_OPR }, + { "s8addl", OPRL(0x10,0x12), ALL, ARG_OPRL }, + { "s8subl", OPR(0x10,0x1B), ALL, ARG_OPR }, + { "s8subl", OPRL(0x10,0x1B), ALL, ARG_OPRL }, + { "cmpult", OPR(0x10,0x1D), ALL, ARG_OPR }, + { "cmpult", OPRL(0x10,0x1D), ALL, ARG_OPRL }, + { "addq", OPR(0x10,0x20), ALL, ARG_OPR }, + { "addq", OPRL(0x10,0x20), ALL, ARG_OPRL }, + { "s4addq", OPR(0x10,0x22), ALL, ARG_OPR }, + { "s4addq", OPRL(0x10,0x22), ALL, ARG_OPRL }, + { "negq", OPR(0x10,0x29), ALL, ARG_OPRZ1 }, /* pseudo */ + { "negq", OPRL(0x10,0x29), ALL, ARG_OPRLZ1 }, /* pseudo */ + { "subq", OPR(0x10,0x29), ALL, ARG_OPR }, + { "subq", OPRL(0x10,0x29), ALL, ARG_OPRL }, + { "s4subq", OPR(0x10,0x2B), ALL, ARG_OPR }, + { "s4subq", OPRL(0x10,0x2B), ALL, ARG_OPRL }, + { "cmpeq", OPR(0x10,0x2D), ALL, ARG_OPR }, + { "cmpeq", OPRL(0x10,0x2D), ALL, ARG_OPRL }, + { "s8addq", OPR(0x10,0x32), ALL, ARG_OPR }, + { "s8addq", OPRL(0x10,0x32), ALL, ARG_OPRL }, + { "s8subq", OPR(0x10,0x3B), ALL, ARG_OPR }, + { "s8subq", OPRL(0x10,0x3B), ALL, ARG_OPRL }, + { "cmpule", OPR(0x10,0x3D), ALL, ARG_OPR }, + { "cmpule", OPRL(0x10,0x3D), ALL, ARG_OPRL }, + { "addl/v", OPR(0x10,0x40), ALL, ARG_OPR }, + { "addl/v", OPRL(0x10,0x40), ALL, ARG_OPRL }, + { "negl/v", OPR(0x10,0x49), ALL, ARG_OPRZ1 }, /* pseudo */ + { "negl/v", OPRL(0x10,0x49), ALL, ARG_OPRLZ1 }, /* pseudo */ + { "subl/v", OPR(0x10,0x49), ALL, ARG_OPR }, + { "subl/v", OPRL(0x10,0x49), ALL, ARG_OPRL }, + { "cmplt", OPR(0x10,0x4D), ALL, ARG_OPR }, + { "cmplt", OPRL(0x10,0x4D), ALL, ARG_OPRL }, + { "addq/v", OPR(0x10,0x60), ALL, ARG_OPR }, + { "addq/v", OPRL(0x10,0x60), ALL, ARG_OPRL }, + { "negq/v", OPR(0x10,0x69), ALL, ARG_OPRZ1 }, /* pseudo */ + { "negq/v", OPRL(0x10,0x69), ALL, ARG_OPRLZ1 }, /* pseudo */ + { "subq/v", OPR(0x10,0x69), ALL, ARG_OPR }, + { "subq/v", OPRL(0x10,0x69), ALL, ARG_OPRL }, + { "cmple", OPR(0x10,0x6D), ALL, ARG_OPR }, + { "cmple", OPRL(0x10,0x6D), ALL, ARG_OPRL }, + + { "and", OPR(0x11,0x00), ALL, ARG_OPR }, + { "and", OPRL(0x11,0x00), ALL, ARG_OPRL }, + { "andnot", OPR(0x11,0x08), ALL, ARG_OPR }, /* alias */ + { "andnot", OPRL(0x11,0x08), ALL, ARG_OPRL }, /* alias */ + { "bic", OPR(0x11,0x08), ALL, ARG_OPR }, + { "bic", OPRL(0x11,0x08), ALL, ARG_OPRL }, + { "cmovlbs", OPR(0x11,0x14), ALL, ARG_OPR }, + { "cmovlbs", OPRL(0x11,0x14), ALL, ARG_OPRL }, + { "cmovlbc", OPR(0x11,0x16), ALL, ARG_OPR }, + { "cmovlbc", OPRL(0x11,0x16), ALL, ARG_OPRL }, + { "nop", OPR(0x11,0x20), ALL, { ZA, ZB, ZC } }, /* pseudo */ + { "clr", OPR(0x11,0x20), ALL, { ZA, ZB, RC } }, /* pseudo */ + { "mov", OPR(0x11,0x20), ALL, { ZA, RB, RC } }, /* pseudo */ + { "mov", OPR(0x11,0x20), ALL, { RA, RBA, RC } }, /* pseudo */ + { "mov", OPRL(0x11,0x20), ALL, { ZA, LIT, RC } }, /* pseudo */ + { "or", OPR(0x11,0x20), ALL, ARG_OPR }, /* alias */ + { "or", OPRL(0x11,0x20), ALL, ARG_OPRL }, /* alias */ + { "bis", OPR(0x11,0x20), ALL, ARG_OPR }, + { "bis", OPRL(0x11,0x20), ALL, ARG_OPRL }, + { "cmoveq", OPR(0x11,0x24), ALL, ARG_OPR }, + { "cmoveq", OPRL(0x11,0x24), ALL, ARG_OPRL }, + { "cmovne", OPR(0x11,0x26), ALL, ARG_OPR }, + { "cmovne", OPRL(0x11,0x26), ALL, ARG_OPRL }, + { "not", OPR(0x11,0x28), ALL, ARG_OPRZ1 }, /* pseudo */ + { "not", OPRL(0x11,0x28), ALL, ARG_OPRLZ1 }, /* pseudo */ + { "ornot", OPR(0x11,0x28), ALL, ARG_OPR }, + { "ornot", OPRL(0x11,0x28), ALL, ARG_OPRL }, + { "xor", OPR(0x11,0x40), ALL, ARG_OPR }, + { "xor", OPRL(0x11,0x40), ALL, ARG_OPRL }, + { "cmovlt", OPR(0x11,0x44), ALL, ARG_OPR }, + { "cmovlt", OPRL(0x11,0x44), ALL, ARG_OPRL }, + { "cmovge", OPR(0x11,0x46), ALL, ARG_OPR }, + { "cmovge", OPRL(0x11,0x46), ALL, ARG_OPRL }, + { "eqv", OPR(0x11,0x48), ALL, ARG_OPR }, + { "eqv", OPRL(0x11,0x48), ALL, ARG_OPRL }, + { "xornot", OPR(0x11,0x48), ALL, ARG_OPR }, /* alias */ + { "xornot", OPRL(0x11,0x48), ALL, ARG_OPRL }, /* alias */ + { "amask", OPR(0x11,0x61), EV56, ARG_OPRZ1 }, /* ev56 */ + { "amask", OPRL(0x11,0x61), EV56, ARG_OPRLZ1 }, /* ev56 */ + { "cmovle", OPR(0x11,0x64), ALL, ARG_OPR }, + { "cmovle", OPRL(0x11,0x64), ALL, ARG_OPRL }, + { "cmovgt", OPR(0x11,0x66), ALL, ARG_OPR }, + { "cmovgt", OPRL(0x11,0x66), ALL, ARG_OPRL }, + { "implver", OPR(0x11,0x6C), ALL, ARG_OPRZ1 }, /* ev56 */ + { "implver", OPRL(0x11,0x6C), ALL, ARG_OPRLZ1 }, /* ev56 */ + + { "mskbl", OPR(0x12,0x02), ALL, ARG_OPR }, + { "mskbl", OPRL(0x12,0x02), ALL, ARG_OPRL }, + { "extbl", OPR(0x12,0x06), ALL, ARG_OPR }, + { "extbl", OPRL(0x12,0x06), ALL, ARG_OPRL }, + { "insbl", OPR(0x12,0x0B), ALL, ARG_OPR }, + { "insbl", OPRL(0x12,0x0B), ALL, ARG_OPRL }, + { "mskwl", OPR(0x12,0x12), ALL, ARG_OPR }, + { "mskwl", OPRL(0x12,0x12), ALL, ARG_OPRL }, + { "extwl", OPR(0x12,0x16), ALL, ARG_OPR }, + { "extwl", OPRL(0x12,0x16), ALL, ARG_OPRL }, + { "inswl", OPR(0x12,0x1B), ALL, ARG_OPR }, + { "inswl", OPRL(0x12,0x1B), ALL, ARG_OPRL }, + { "mskll", OPR(0x12,0x22), ALL, ARG_OPR }, + { "mskll", OPRL(0x12,0x22), ALL, ARG_OPRL }, + { "extll", OPR(0x12,0x26), ALL, ARG_OPR }, + { "extll", OPRL(0x12,0x26), ALL, ARG_OPRL }, + { "insll", OPR(0x12,0x2B), ALL, ARG_OPR }, + { "insll", OPRL(0x12,0x2B), ALL, ARG_OPRL }, + { "zap", OPR(0x12,0x30), ALL, ARG_OPR }, + { "zap", OPRL(0x12,0x30), ALL, ARG_OPRL }, + { "zapnot", OPR(0x12,0x31), ALL, ARG_OPR }, + { "zapnot", OPRL(0x12,0x31), ALL, ARG_OPRL }, + { "mskql", OPR(0x12,0x32), ALL, ARG_OPR }, + { "mskql", OPRL(0x12,0x32), ALL, ARG_OPRL }, + { "srl", OPR(0x12,0x34), ALL, ARG_OPR }, + { "srl", OPRL(0x12,0x34), ALL, ARG_OPRL }, + { "extql", OPR(0x12,0x36), ALL, ARG_OPR }, + { "extql", OPRL(0x12,0x36), ALL, ARG_OPRL }, + { "sll", OPR(0x12,0x39), ALL, ARG_OPR }, + { "sll", OPRL(0x12,0x39), ALL, ARG_OPRL }, + { "insql", OPR(0x12,0x3B), ALL, ARG_OPR }, + { "insql", OPRL(0x12,0x3B), ALL, ARG_OPRL }, + { "sra", OPR(0x12,0x3C), ALL, ARG_OPR }, + { "sra", OPRL(0x12,0x3C), ALL, ARG_OPRL }, + { "mskwh", OPR(0x12,0x52), ALL, ARG_OPR }, + { "mskwh", OPRL(0x12,0x52), ALL, ARG_OPRL }, + { "inswh", OPR(0x12,0x57), ALL, ARG_OPR }, + { "inswh", OPRL(0x12,0x57), ALL, ARG_OPRL }, + { "extwh", OPR(0x12,0x5A), ALL, ARG_OPR }, + { "extwh", OPRL(0x12,0x5A), ALL, ARG_OPRL }, + { "msklh", OPR(0x12,0x62), ALL, ARG_OPR }, + { "msklh", OPRL(0x12,0x62), ALL, ARG_OPRL }, + { "inslh", OPR(0x12,0x67), ALL, ARG_OPR }, + { "inslh", OPRL(0x12,0x67), ALL, ARG_OPRL }, + { "extlh", OPR(0x12,0x6A), ALL, ARG_OPR }, + { "extlh", OPRL(0x12,0x6A), ALL, ARG_OPRL }, + { "mskqh", OPR(0x12,0x72), ALL, ARG_OPR }, + { "mskqh", OPRL(0x12,0x72), ALL, ARG_OPRL }, + { "insqh", OPR(0x12,0x77), ALL, ARG_OPR }, + { "insqh", OPRL(0x12,0x77), ALL, ARG_OPRL }, + { "extqh", OPR(0x12,0x7A), ALL, ARG_OPR }, + { "extqh", OPRL(0x12,0x7A), ALL, ARG_OPRL }, + + { "mull", OPR(0x13,0x00), ALL, ARG_OPR }, + { "mull", OPRL(0x13,0x00), ALL, ARG_OPRL }, + { "mulq", OPR(0x13,0x20), ALL, ARG_OPR }, + { "mulq", OPRL(0x13,0x20), ALL, ARG_OPRL }, + { "umulh", OPR(0x13,0x30), ALL, ARG_OPR }, + { "umulh", OPRL(0x13,0x30), ALL, ARG_OPRL }, + { "mull/v", OPR(0x13,0x40), ALL, ARG_OPR }, + { "mull/v", OPRL(0x13,0x40), ALL, ARG_OPRL }, + { "mulq/v", OPR(0x13,0x60), ALL, ARG_OPR }, + { "mulq/v", OPRL(0x13,0x60), ALL, ARG_OPRL }, + + { "addf/c", FP(0x15,0x000), ALL, ARG_FP }, + { "subf/c", FP(0x15,0x001), ALL, ARG_FP }, + { "mulf/c", FP(0x15,0x002), ALL, ARG_FP }, + { "divf/c", FP(0x15,0x003), ALL, ARG_FP }, + { "cvtdg/c", FP(0x15,0x01E), ALL, ARG_FPZ1 }, + { "addg/c", FP(0x15,0x020), ALL, ARG_FP }, + { "subg/c", FP(0x15,0x021), ALL, ARG_FP }, + { "mulg/c", FP(0x15,0x022), ALL, ARG_FP }, + { "divg/c", FP(0x15,0x023), ALL, ARG_FP }, + { "cvtgf/c", FP(0x15,0x02C), ALL, ARG_FPZ1 }, + { "cvtgd/c", FP(0x15,0x02D), ALL, ARG_FPZ1 }, + { "cvtgq/c", FP(0x15,0x02F), ALL, ARG_FPZ1 }, + { "cvtqf/c", FP(0x15,0x03C), ALL, ARG_FPZ1 }, + { "cvtqg/c", FP(0x15,0x03E), ALL, ARG_FPZ1 }, + { "addf", FP(0x15,0x080), ALL, ARG_FP }, + { "negf", FP(0x15,0x081), ALL, ARG_FPZ1 }, /* pseudo */ + { "subf", FP(0x15,0x081), ALL, ARG_FP }, + { "mulf", FP(0x15,0x082), ALL, ARG_FP }, + { "divf", FP(0x15,0x083), ALL, ARG_FP }, + { "cvtdg", FP(0x15,0x09E), ALL, ARG_FPZ1 }, + { "addg", FP(0x15,0x0A0), ALL, ARG_FP }, + { "negg", FP(0x15,0x0A1), ALL, ARG_FPZ1 }, /* pseudo */ + { "subg", FP(0x15,0x0A1), ALL, ARG_FP }, + { "mulg", FP(0x15,0x0A2), ALL, ARG_FP }, + { "divg", FP(0x15,0x0A3), ALL, ARG_FP }, + { "cmpgeq", FP(0x15,0x0A5), ALL, ARG_FP }, + { "cmpglt", FP(0x15,0x0A6), ALL, ARG_FP }, + { "cmpgle", FP(0x15,0x0A7), ALL, ARG_FP }, + { "cvtgf", FP(0x15,0x0AC), ALL, ARG_FPZ1 }, + { "cvtgd", FP(0x15,0x0AD), ALL, ARG_FPZ1 }, + { "cvtgq", FP(0x15,0x0AF), ALL, ARG_FPZ1 }, + { "cvtqf", FP(0x15,0x0BC), ALL, ARG_FPZ1 }, + { "cvtqg", FP(0x15,0x0BE), ALL, ARG_FPZ1 }, + { "addf/uc", FP(0x15,0x100), ALL, ARG_FP }, + { "subf/uc", FP(0x15,0x101), ALL, ARG_FP }, + { "mulf/uc", FP(0x15,0x102), ALL, ARG_FP }, + { "divf/uc", FP(0x15,0x103), ALL, ARG_FP }, + { "cvtdg/uc", FP(0x15,0x11E), ALL, ARG_FPZ1 }, + { "addg/uc", FP(0x15,0x120), ALL, ARG_FP }, + { "subg/uc", FP(0x15,0x121), ALL, ARG_FP }, + { "mulg/uc", FP(0x15,0x122), ALL, ARG_FP }, + { "divg/uc", FP(0x15,0x123), ALL, ARG_FP }, + { "cvtgf/uc", FP(0x15,0x12C), ALL, ARG_FPZ1 }, + { "cvtgd/uc", FP(0x15,0x12D), ALL, ARG_FPZ1 }, + { "cvtgq/vc", FP(0x15,0x12F), ALL, ARG_FPZ1 }, + { "addf/u", FP(0x15,0x180), ALL, ARG_FP }, + { "subf/u", FP(0x15,0x181), ALL, ARG_FP }, + { "mulf/u", FP(0x15,0x182), ALL, ARG_FP }, + { "divf/u", FP(0x15,0x183), ALL, ARG_FP }, + { "cvtdg/u", FP(0x15,0x19E), ALL, ARG_FPZ1 }, + { "addg/u", FP(0x15,0x1A0), ALL, ARG_FP }, + { "subg/u", FP(0x15,0x1A1), ALL, ARG_FP }, + { "mulg/u", FP(0x15,0x1A2), ALL, ARG_FP }, + { "divg/u", FP(0x15,0x1A3), ALL, ARG_FP }, + { "cvtgf/u", FP(0x15,0x1AC), ALL, ARG_FPZ1 }, + { "cvtgd/u", FP(0x15,0x1AD), ALL, ARG_FPZ1 }, + { "cvtgq/v", FP(0x15,0x1AF), ALL, ARG_FPZ1 }, + { "addf/sc", FP(0x15,0x400), ALL, ARG_FP }, + { "subf/sc", FP(0x15,0x401), ALL, ARG_FP }, + { "mulf/sc", FP(0x15,0x402), ALL, ARG_FP }, + { "divf/sc", FP(0x15,0x403), ALL, ARG_FP }, + { "cvtdg/sc", FP(0x15,0x41E), ALL, ARG_FPZ1 }, + { "addg/sc", FP(0x15,0x420), ALL, ARG_FP }, + { "subg/sc", FP(0x15,0x421), ALL, ARG_FP }, + { "mulg/sc", FP(0x15,0x422), ALL, ARG_FP }, + { "divg/sc", FP(0x15,0x423), ALL, ARG_FP }, + { "cvtgf/sc", FP(0x15,0x42C), ALL, ARG_FPZ1 }, + { "cvtgd/sc", FP(0x15,0x42D), ALL, ARG_FPZ1 }, + { "cvtgq/sc", FP(0x15,0x42F), ALL, ARG_FPZ1 }, + { "addf/s", FP(0x15,0x480), ALL, ARG_FP }, + { "negf/s", FP(0x15,0x481), ALL, ARG_FPZ1 }, /* pseudo */ + { "subf/s", FP(0x15,0x481), ALL, ARG_FP }, + { "mulf/s", FP(0x15,0x482), ALL, ARG_FP }, + { "divf/s", FP(0x15,0x483), ALL, ARG_FP }, + { "cvtdg/s", FP(0x15,0x49E), ALL, ARG_FPZ1 }, + { "addg/s", FP(0x15,0x4A0), ALL, ARG_FP }, + { "negg/s", FP(0x15,0x4A1), ALL, ARG_FPZ1 }, /* pseudo */ + { "subg/s", FP(0x15,0x4A1), ALL, ARG_FP }, + { "mulg/s", FP(0x15,0x4A2), ALL, ARG_FP }, + { "divg/s", FP(0x15,0x4A3), ALL, ARG_FP }, + { "cmpgeq/s", FP(0x15,0x4A5), ALL, ARG_FP }, + { "cmpglt/s", FP(0x15,0x4A6), ALL, ARG_FP }, + { "cmpgle/s", FP(0x15,0x4A7), ALL, ARG_FP }, + { "cvtgf/s", FP(0x15,0x4AC), ALL, ARG_FPZ1 }, + { "cvtgd/s", FP(0x15,0x4AD), ALL, ARG_FPZ1 }, + { "cvtgq/s", FP(0x15,0x4AF), ALL, ARG_FPZ1 }, + { "addf/suc", FP(0x15,0x500), ALL, ARG_FP }, + { "subf/suc", FP(0x15,0x501), ALL, ARG_FP }, + { "mulf/suc", FP(0x15,0x502), ALL, ARG_FP }, + { "divf/suc", FP(0x15,0x503), ALL, ARG_FP }, + { "cvtdg/suc", FP(0x15,0x51E), ALL, ARG_FPZ1 }, + { "addg/suc", FP(0x15,0x520), ALL, ARG_FP }, + { "subg/suc", FP(0x15,0x521), ALL, ARG_FP }, + { "mulg/suc", FP(0x15,0x522), ALL, ARG_FP }, + { "divg/suc", FP(0x15,0x523), ALL, ARG_FP }, + { "cvtgf/suc", FP(0x15,0x52C), ALL, ARG_FPZ1 }, + { "cvtgd/suc", FP(0x15,0x52D), ALL, ARG_FPZ1 }, + { "cvtgq/svc", FP(0x15,0x52F), ALL, ARG_FPZ1 }, + { "addf/su", FP(0x15,0x580), ALL, ARG_FP }, + { "subf/su", FP(0x15,0x581), ALL, ARG_FP }, + { "mulf/su", FP(0x15,0x582), ALL, ARG_FP }, + { "divf/su", FP(0x15,0x583), ALL, ARG_FP }, + { "cvtdg/su", FP(0x15,0x59E), ALL, ARG_FPZ1 }, + { "addg/su", FP(0x15,0x5A0), ALL, ARG_FP }, + { "subg/su", FP(0x15,0x5A1), ALL, ARG_FP }, + { "mulg/su", FP(0x15,0x5A2), ALL, ARG_FP }, + { "divg/su", FP(0x15,0x5A3), ALL, ARG_FP }, + { "cvtgf/su", FP(0x15,0x5AC), ALL, ARG_FPZ1 }, + { "cvtgd/su", FP(0x15,0x5AD), ALL, ARG_FPZ1 }, + { "cvtgq/sv", FP(0x15,0x5AF), ALL, ARG_FPZ1 }, + + { "adds/c", FP(0x16,0x000), ALL, ARG_FP }, + { "subs/c", FP(0x16,0x001), ALL, ARG_FP }, + { "muls/c", FP(0x16,0x002), ALL, ARG_FP }, + { "divs/c", FP(0x16,0x003), ALL, ARG_FP }, + { "addt/c", FP(0x16,0x020), ALL, ARG_FP }, + { "subt/c", FP(0x16,0x021), ALL, ARG_FP }, + { "mult/c", FP(0x16,0x022), ALL, ARG_FP }, + { "divt/c", FP(0x16,0x023), ALL, ARG_FP }, + { "cvtts/c", FP(0x16,0x02C), ALL, ARG_FPZ1 }, + { "cvttq/c", FP(0x16,0x02F), ALL, ARG_FPZ1 }, + { "cvtqs/c", FP(0x16,0x03C), ALL, ARG_FPZ1 }, + { "cvtqt/c", FP(0x16,0x03E), ALL, ARG_FPZ1 }, + { "adds/m", FP(0x16,0x040), ALL, ARG_FP }, + { "subs/m", FP(0x16,0x041), ALL, ARG_FP }, + { "muls/m", FP(0x16,0x042), ALL, ARG_FP }, + { "divs/m", FP(0x16,0x043), ALL, ARG_FP }, + { "addt/m", FP(0x16,0x060), ALL, ARG_FP }, + { "subt/m", FP(0x16,0x061), ALL, ARG_FP }, + { "mult/m", FP(0x16,0x062), ALL, ARG_FP }, + { "divt/m", FP(0x16,0x063), ALL, ARG_FP }, + { "cvtts/m", FP(0x16,0x06C), ALL, ARG_FPZ1 }, + { "cvttq/m", FP(0x16,0x06F), ALL, ARG_FPZ1 }, + { "cvtqs/m", FP(0x16,0x07C), ALL, ARG_FPZ1 }, + { "cvtqt/m", FP(0x16,0x07E), ALL, ARG_FPZ1 }, + { "adds", FP(0x16,0x080), ALL, ARG_FP }, + { "negs", FP(0x16,0x081), ALL, ARG_FPZ1 }, /* pseudo */ + { "subs", FP(0x16,0x081), ALL, ARG_FP }, + { "muls", FP(0x16,0x082), ALL, ARG_FP }, + { "divs", FP(0x16,0x083), ALL, ARG_FP }, + { "addt", FP(0x16,0x0A0), ALL, ARG_FP }, + { "negt", FP(0x16,0x0A1), ALL, ARG_FPZ1 }, /* pseudo */ + { "subt", FP(0x16,0x0A1), ALL, ARG_FP }, + { "mult", FP(0x16,0x0A2), ALL, ARG_FP }, + { "divt", FP(0x16,0x0A3), ALL, ARG_FP }, + { "cmptun", FP(0x16,0x0A4), ALL, ARG_FP }, + { "cmpteq", FP(0x16,0x0A5), ALL, ARG_FP }, + { "cmptlt", FP(0x16,0x0A6), ALL, ARG_FP }, + { "cmptle", FP(0x16,0x0A7), ALL, ARG_FP }, + { "cvtts", FP(0x16,0x0AC), ALL, ARG_FPZ1 }, + { "cvttq", FP(0x16,0x0AF), ALL, ARG_FPZ1 }, + { "cvtqs", FP(0x16,0x0BC), ALL, ARG_FPZ1 }, + { "cvtqt", FP(0x16,0x0BE), ALL, ARG_FPZ1 }, + { "adds/d", FP(0x16,0x0C0), ALL, ARG_FP }, + { "subs/d", FP(0x16,0x0C1), ALL, ARG_FP }, + { "muls/d", FP(0x16,0x0C2), ALL, ARG_FP }, + { "divs/d", FP(0x16,0x0C3), ALL, ARG_FP }, + { "addt/d", FP(0x16,0x0E0), ALL, ARG_FP }, + { "subt/d", FP(0x16,0x0E1), ALL, ARG_FP }, + { "mult/d", FP(0x16,0x0E2), ALL, ARG_FP }, + { "divt/d", FP(0x16,0x0E3), ALL, ARG_FP }, + { "cvtts/d", FP(0x16,0x0EC), ALL, ARG_FPZ1 }, + { "cvttq/d", FP(0x16,0x0EF), ALL, ARG_FPZ1 }, + { "cvtqs/d", FP(0x16,0x0FC), ALL, ARG_FPZ1 }, + { "cvtqt/d", FP(0x16,0x0FE), ALL, ARG_FPZ1 }, + { "adds/uc", FP(0x16,0x100), ALL, ARG_FP }, + { "subs/uc", FP(0x16,0x101), ALL, ARG_FP }, + { "muls/uc", FP(0x16,0x102), ALL, ARG_FP }, + { "divs/uc", FP(0x16,0x103), ALL, ARG_FP }, + { "addt/uc", FP(0x16,0x120), ALL, ARG_FP }, + { "subt/uc", FP(0x16,0x121), ALL, ARG_FP }, + { "mult/uc", FP(0x16,0x122), ALL, ARG_FP }, + { "divt/uc", FP(0x16,0x123), ALL, ARG_FP }, + { "cvtts/uc", FP(0x16,0x12C), ALL, ARG_FPZ1 }, + { "cvttq/vc", FP(0x16,0x12F), ALL, ARG_FPZ1 }, + { "adds/um", FP(0x16,0x140), ALL, ARG_FP }, + { "subs/um", FP(0x16,0x141), ALL, ARG_FP }, + { "muls/um", FP(0x16,0x142), ALL, ARG_FP }, + { "divs/um", FP(0x16,0x143), ALL, ARG_FP }, + { "addt/um", FP(0x16,0x160), ALL, ARG_FP }, + { "subt/um", FP(0x16,0x161), ALL, ARG_FP }, + { "mult/um", FP(0x16,0x162), ALL, ARG_FP }, + { "divt/um", FP(0x16,0x163), ALL, ARG_FP }, + { "cvtts/um", FP(0x16,0x16C), ALL, ARG_FPZ1 }, + { "cvttq/um", FP(0x16,0x16F), ALL, ARG_FPZ1 }, + { "cvtqs/um", FP(0x16,0x17C), ALL, ARG_FPZ1 }, + { "adds/u", FP(0x16,0x180), ALL, ARG_FP }, + { "subs/u", FP(0x16,0x181), ALL, ARG_FP }, + { "muls/u", FP(0x16,0x182), ALL, ARG_FP }, + { "divs/u", FP(0x16,0x183), ALL, ARG_FP }, + { "addt/u", FP(0x16,0x1A0), ALL, ARG_FP }, + { "subt/u", FP(0x16,0x1A1), ALL, ARG_FP }, + { "mult/u", FP(0x16,0x1A2), ALL, ARG_FP }, + { "divt/u", FP(0x16,0x1A3), ALL, ARG_FP }, + { "cvtts/u", FP(0x16,0x1AC), ALL, ARG_FPZ1 }, + { "cvttq/v", FP(0x16,0x1AF), ALL, ARG_FPZ1 }, + { "adds/ud", FP(0x16,0x1C0), ALL, ARG_FP }, + { "subs/ud", FP(0x16,0x1C1), ALL, ARG_FP }, + { "muls/ud", FP(0x16,0x1C2), ALL, ARG_FP }, + { "divs/ud", FP(0x16,0x1C3), ALL, ARG_FP }, + { "addt/ud", FP(0x16,0x1E0), ALL, ARG_FP }, + { "subt/ud", FP(0x16,0x1E1), ALL, ARG_FP }, + { "mult/ud", FP(0x16,0x1E2), ALL, ARG_FP }, + { "divt/ud", FP(0x16,0x1E3), ALL, ARG_FP }, + { "cvtts/ud", FP(0x16,0x1EC), ALL, ARG_FPZ1 }, + { "cvttq/ud", FP(0x16,0x1EF), ALL, ARG_FPZ1 }, + { "cvtst", FP(0x16,0x2AC), ALL, ARG_FPZ1 }, + { "adds/suc", FP(0x16,0x500), ALL, ARG_FP }, + { "subs/suc", FP(0x16,0x501), ALL, ARG_FP }, + { "muls/suc", FP(0x16,0x502), ALL, ARG_FP }, + { "divs/suc", FP(0x16,0x503), ALL, ARG_FP }, + { "addt/suc", FP(0x16,0x520), ALL, ARG_FP }, + { "subt/suc", FP(0x16,0x521), ALL, ARG_FP }, + { "mult/suc", FP(0x16,0x522), ALL, ARG_FP }, + { "divt/suc", FP(0x16,0x523), ALL, ARG_FP }, + { "cvtts/suc", FP(0x16,0x52C), ALL, ARG_FPZ1 }, + { "cvttq/svc", FP(0x16,0x52F), ALL, ARG_FPZ1 }, + { "adds/sum", FP(0x16,0x540), ALL, ARG_FP }, + { "subs/sum", FP(0x16,0x541), ALL, ARG_FP }, + { "muls/sum", FP(0x16,0x542), ALL, ARG_FP }, + { "divs/sum", FP(0x16,0x543), ALL, ARG_FP }, + { "addt/sum", FP(0x16,0x560), ALL, ARG_FP }, + { "subt/sum", FP(0x16,0x561), ALL, ARG_FP }, + { "mult/sum", FP(0x16,0x562), ALL, ARG_FP }, + { "divt/sum", FP(0x16,0x563), ALL, ARG_FP }, + { "cvtts/sum", FP(0x16,0x56C), ALL, ARG_FPZ1 }, + { "cvttq/sum", FP(0x16,0x56F), ALL, ARG_FPZ1 }, + { "cvtqs/sum", FP(0x16,0x57C), ALL, ARG_FPZ1 }, + { "adds/su", FP(0x16,0x580), ALL, ARG_FP }, + { "negs/su", FP(0x16,0x581), ALL, ARG_FPZ1 }, /* pseudo */ + { "subs/su", FP(0x16,0x581), ALL, ARG_FP }, + { "muls/su", FP(0x16,0x582), ALL, ARG_FP }, + { "divs/su", FP(0x16,0x583), ALL, ARG_FP }, + { "addt/su", FP(0x16,0x5A0), ALL, ARG_FP }, + { "negt/su", FP(0x16,0x5A1), ALL, ARG_FPZ1 }, /* pseudo */ + { "subt/su", FP(0x16,0x5A1), ALL, ARG_FP }, + { "mult/su", FP(0x16,0x5A2), ALL, ARG_FP }, + { "divt/su", FP(0x16,0x5A3), ALL, ARG_FP }, + { "cmptun/su", FP(0x16,0x5A4), ALL, ARG_FP }, + { "cmpteq/su", FP(0x16,0x5A5), ALL, ARG_FP }, + { "cmptlt/su", FP(0x16,0x5A6), ALL, ARG_FP }, + { "cmptle/su", FP(0x16,0x5A7), ALL, ARG_FP }, + { "cvtts/su", FP(0x16,0x5AC), ALL, ARG_FPZ1 }, + { "cvttq/sv", FP(0x16,0x5AF), ALL, ARG_FPZ1 }, + { "adds/sud", FP(0x16,0x5C0), ALL, ARG_FP }, + { "subs/sud", FP(0x16,0x5C1), ALL, ARG_FP }, + { "muls/sud", FP(0x16,0x5C2), ALL, ARG_FP }, + { "divs/sud", FP(0x16,0x5C3), ALL, ARG_FP }, + { "addt/sud", FP(0x16,0x5E0), ALL, ARG_FP }, + { "subt/sud", FP(0x16,0x5E1), ALL, ARG_FP }, + { "mult/sud", FP(0x16,0x5E2), ALL, ARG_FP }, + { "divt/sud", FP(0x16,0x5E3), ALL, ARG_FP }, + { "cvtts/sud", FP(0x16,0x5EC), ALL, ARG_FPZ1 }, + { "cvttq/sud", FP(0x16,0x5EF), ALL, ARG_FPZ1 }, + { "cvtst/s", FP(0x16,0x6AC), ALL, ARG_FPZ1 }, + { "adds/suic", FP(0x16,0x700), ALL, ARG_FP }, + { "subs/suic", FP(0x16,0x701), ALL, ARG_FP }, + { "muls/suic", FP(0x16,0x702), ALL, ARG_FP }, + { "divs/suic", FP(0x16,0x703), ALL, ARG_FP }, + { "addt/suic", FP(0x16,0x720), ALL, ARG_FP }, + { "subt/suic", FP(0x16,0x721), ALL, ARG_FP }, + { "mult/suic", FP(0x16,0x722), ALL, ARG_FP }, + { "divt/suic", FP(0x16,0x723), ALL, ARG_FP }, + { "cvtts/suic", FP(0x16,0x72C), ALL, ARG_FPZ1 }, + { "cvttq/svic", FP(0x16,0x72F), ALL, ARG_FPZ1 }, + { "cvtqs/suic", FP(0x16,0x73C), ALL, ARG_FPZ1 }, + { "cvtqt/suic", FP(0x16,0x73E), ALL, ARG_FPZ1 }, + { "adds/suim", FP(0x16,0x740), ALL, ARG_FP }, + { "subs/suim", FP(0x16,0x741), ALL, ARG_FP }, + { "muls/suim", FP(0x16,0x742), ALL, ARG_FP }, + { "divs/suim", FP(0x16,0x743), ALL, ARG_FP }, + { "addt/suim", FP(0x16,0x760), ALL, ARG_FP }, + { "subt/suim", FP(0x16,0x761), ALL, ARG_FP }, + { "mult/suim", FP(0x16,0x762), ALL, ARG_FP }, + { "divt/suim", FP(0x16,0x763), ALL, ARG_FP }, + { "cvtts/suim", FP(0x16,0x76C), ALL, ARG_FPZ1 }, + { "cvttq/suim", FP(0x16,0x76F), ALL, ARG_FPZ1 }, + { "cvtqs/suim", FP(0x16,0x77C), ALL, ARG_FPZ1 }, + { "cvtqt/suim", FP(0x16,0x77E), ALL, ARG_FPZ1 }, + { "adds/sui", FP(0x16,0x780), ALL, ARG_FP }, + { "negs/sui", FP(0x16,0x781), ALL, ARG_FPZ1 }, /* pseudo */ + { "subs/sui", FP(0x16,0x781), ALL, ARG_FP }, + { "muls/sui", FP(0x16,0x782), ALL, ARG_FP }, + { "divs/sui", FP(0x16,0x783), ALL, ARG_FP }, + { "addt/sui", FP(0x16,0x7A0), ALL, ARG_FP }, + { "negt/sui", FP(0x16,0x7A1), ALL, ARG_FPZ1 }, /* pseudo */ + { "subt/sui", FP(0x16,0x7A1), ALL, ARG_FP }, + { "mult/sui", FP(0x16,0x7A2), ALL, ARG_FP }, + { "divt/sui", FP(0x16,0x7A3), ALL, ARG_FP }, + { "cvtts/sui", FP(0x16,0x7AC), ALL, ARG_FPZ1 }, + { "cvttq/svi", FP(0x16,0x7AF), ALL, ARG_FPZ1 }, + { "cvtqs/sui", FP(0x16,0x7BC), ALL, ARG_FPZ1 }, + { "cvtqt/sui", FP(0x16,0x7BE), ALL, ARG_FPZ1 }, + { "adds/suid", FP(0x16,0x7C0), ALL, ARG_FP }, + { "subs/suid", FP(0x16,0x7C1), ALL, ARG_FP }, + { "muls/suid", FP(0x16,0x7C2), ALL, ARG_FP }, + { "divs/suid", FP(0x16,0x7C3), ALL, ARG_FP }, + { "addt/suid", FP(0x16,0x7E0), ALL, ARG_FP }, + { "subt/suid", FP(0x16,0x7E1), ALL, ARG_FP }, + { "mult/suid", FP(0x16,0x7E2), ALL, ARG_FP }, + { "divt/suid", FP(0x16,0x7E3), ALL, ARG_FP }, + { "cvtts/suid", FP(0x16,0x7EC), ALL, ARG_FPZ1 }, + { "cvttq/suid", FP(0x16,0x7EF), ALL, ARG_FPZ1 }, + { "cvtqs/suid", FP(0x16,0x7FC), ALL, ARG_FPZ1 }, + { "cvtqt/suid", FP(0x16,0x7FE), ALL, ARG_FPZ1 }, + + { "cvtlq", FP(0x17,0x010), ALL, ARG_FPZ1 }, + { "fnop", FP(0x17,0x020), ALL, { ZA, ZB, ZC } }, /* pseudo */ + { "fclr", FP(0x17,0x020), ALL, { ZA, ZB, FC } }, /* pseudo */ + { "fabs", FP(0x17,0x020), ALL, ARG_FPZ1 }, /* pseudo */ + { "fmov", FP(0x17,0x020), ALL, { FA, RBA, FC } }, /* pseudo */ + { "cpys", FP(0x17,0x020), ALL, ARG_FP }, + { "fneg", FP(0x17,0x021), ALL, { FA, RBA, FC } }, /* pseudo */ + { "cpysn", FP(0x17,0x021), ALL, ARG_FP }, + { "cpyse", FP(0x17,0x022), ALL, ARG_FP }, + { "mt_fpcr", FP(0x17,0x024), ALL, { FA, RBA, RCA } }, + { "mf_fpcr", FP(0x17,0x025), ALL, { FA, RBA, RCA } }, + { "fcmoveq", FP(0x17,0x02A), ALL, ARG_FP }, + { "fcmovne", FP(0x17,0x02B), ALL, ARG_FP }, + { "fcmovlt", FP(0x17,0x02C), ALL, ARG_FP }, + { "fcmovge", FP(0x17,0x02D), ALL, ARG_FP }, + { "fcmovle", FP(0x17,0x02E), ALL, ARG_FP }, + { "fcmovgt", FP(0x17,0x02F), ALL, ARG_FP }, + { "cvtql", FP(0x17,0x030), ALL, ARG_FPZ1 }, + { "cvtql/v", FP(0x17,0x130), ALL, ARG_FPZ1 }, + { "cvtql/sv", FP(0x17,0x530), ALL, ARG_FPZ1 }, + + { "trapb", MFC(0x18,0x0000), ALL, ARG_NONE }, + { "draint", MFC(0x18,0x0000), ALL, ARG_NONE }, /* alias */ + { "excb", MFC(0x18,0x0400), ALL, ARG_NONE }, + { "mb", MFC(0x18,0x4000), ALL, ARG_NONE }, + { "wmb", MFC(0x18,0x4400), ALL, ARG_NONE }, + { "fetch", MFC(0x18,0x8000), ALL, { MDISP, RB } }, + { "fetch_m", MFC(0x18,0xA000), ALL, { MDISP, RB } }, + { "rpcc", MFC(0x18,0xC000), ALL, { RA } }, + { "rc", MFC(0x18,0xE000), ALL, { RA } }, + { "rs", MFC(0x18,0xF000), ALL, { RA } }, + + { "hw_mfpr", OPR(0x19,0x00), EV4, { RA, RBA, EV4EXTHWINDEX } }, + { "hw_mfpr", OP(0x19), OP_MASK, EV5x, { RA, RBA, EV5HWINDEX } }, + { "hw_mfpr/i", OPR(0x19,0x01), EV4, ARG_EV4HWMPR }, + { "hw_mfpr/a", OPR(0x19,0x02), EV4, ARG_EV4HWMPR }, + { "hw_mfpr/ai", OPR(0x19,0x03), EV4, ARG_EV4HWMPR }, + { "hw_mfpr/p", OPR(0x19,0x04), EV4, ARG_EV4HWMPR }, + { "hw_mfpr/pi", OPR(0x19,0x05), EV4, ARG_EV4HWMPR }, + { "hw_mfpr/pa", OPR(0x19,0x06), EV4, ARG_EV4HWMPR }, + { "hw_mfpr/pai", OPR(0x19,0x07), EV4, ARG_EV4HWMPR }, + { "pal19", PCD(0x19), ALL, ARG_PCD }, + + { "jmp", MBR(0x1A,0), ALL, { RA, CPRB, JMPHINT } }, + { "jsr", MBR(0x1A,1), ALL, { RA, CPRB, JMPHINT } }, + { "ret", MBR(0x1A,2), ALL, { RA, CPRB, RETHINT } }, + { "jcr", MBR(0x1A,3), ALL, { RA, CPRB, RETHINT } }, /* alias */ + { "jsr_coroutine", MBR(0x1A,3), ALL, { RA, CPRB, RETHINT } }, + + { "hw_ldl", EV4HWMEM(0x1B,0x0), EV4, ARG_EV4HWMEM }, + { "hw_ldl", EV5HWMEM(0x1B,0x00), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/a", EV4HWMEM(0x1B,0x4), EV4, ARG_EV4HWMEM }, + { "hw_ldl/a", EV5HWMEM(0x1B,0x10), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/al", EV5HWMEM(0x1B,0x11), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/ar", EV4HWMEM(0x1B,0x6), EV4, ARG_EV4HWMEM }, + { "hw_ldl/av", EV5HWMEM(0x1B,0x12), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/avl", EV5HWMEM(0x1B,0x13), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/aw", EV5HWMEM(0x1B,0x18), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/awl", EV5HWMEM(0x1B,0x19), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/awv", EV5HWMEM(0x1B,0x1a), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/awvl", EV5HWMEM(0x1B,0x1b), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/l", EV5HWMEM(0x1B,0x01), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/p", EV4HWMEM(0x1B,0x8), EV4, ARG_EV4HWMEM }, + { "hw_ldl/p", EV5HWMEM(0x1B,0x20), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/pa", EV4HWMEM(0x1B,0xC), EV4, ARG_EV4HWMEM }, + { "hw_ldl/pa", EV5HWMEM(0x1B,0x30), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/pal", EV5HWMEM(0x1B,0x31), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/par", EV4HWMEM(0x1B,0xE), EV4, ARG_EV4HWMEM }, + { "hw_ldl/pav", EV5HWMEM(0x1B,0x32), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/pavl", EV5HWMEM(0x1B,0x33), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/paw", EV5HWMEM(0x1B,0x38), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/pawl", EV5HWMEM(0x1B,0x39), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/pawv", EV5HWMEM(0x1B,0x3a), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/pawvl", EV5HWMEM(0x1B,0x3b), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/pl", EV5HWMEM(0x1B,0x21), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/pr", EV4HWMEM(0x1B,0xA), EV4, ARG_EV4HWMEM }, + { "hw_ldl/pv", EV5HWMEM(0x1B,0x22), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/pvl", EV5HWMEM(0x1B,0x23), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/pw", EV5HWMEM(0x1B,0x28), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/pwl", EV5HWMEM(0x1B,0x29), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/pwv", EV5HWMEM(0x1B,0x2a), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/pwvl", EV5HWMEM(0x1B,0x2b), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/r", EV4HWMEM(0x1B,0x2), EV4, ARG_EV4HWMEM }, + { "hw_ldl/v", EV5HWMEM(0x1B,0x02), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/vl", EV5HWMEM(0x1B,0x03), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/w", EV5HWMEM(0x1B,0x08), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/wl", EV5HWMEM(0x1B,0x09), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/wv", EV5HWMEM(0x1B,0x0a), EV5x, ARG_EV5HWMEM }, + { "hw_ldl/wvl", EV5HWMEM(0x1B,0x0b), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l", EV5HWMEM(0x1B,0x01), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/a", EV5HWMEM(0x1B,0x11), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/av", EV5HWMEM(0x1B,0x13), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/aw", EV5HWMEM(0x1B,0x19), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/awv", EV5HWMEM(0x1B,0x1b), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/p", EV5HWMEM(0x1B,0x21), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/pa", EV5HWMEM(0x1B,0x31), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/pav", EV5HWMEM(0x1B,0x33), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/paw", EV5HWMEM(0x1B,0x39), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/pawv", EV5HWMEM(0x1B,0x3b), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/pv", EV5HWMEM(0x1B,0x23), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/pw", EV5HWMEM(0x1B,0x29), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/pwv", EV5HWMEM(0x1B,0x2b), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/v", EV5HWMEM(0x1B,0x03), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/w", EV5HWMEM(0x1B,0x09), EV5x, ARG_EV5HWMEM }, + { "hw_ldl_l/wv", EV5HWMEM(0x1B,0x0b), EV5x, ARG_EV5HWMEM }, + { "hw_ldq", EV4HWMEM(0x1B,0x1), EV4, ARG_EV4HWMEM }, + { "hw_ldq", EV5HWMEM(0x1B,0x04), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/a", EV4HWMEM(0x1B,0x5), EV4, ARG_EV4HWMEM }, + { "hw_ldq/a", EV5HWMEM(0x1B,0x14), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/al", EV5HWMEM(0x1B,0x15), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/ar", EV4HWMEM(0x1B,0x7), EV4, ARG_EV4HWMEM }, + { "hw_ldq/av", EV5HWMEM(0x1B,0x16), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/avl", EV5HWMEM(0x1B,0x17), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/aw", EV5HWMEM(0x1B,0x1c), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/awl", EV5HWMEM(0x1B,0x1d), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/awv", EV5HWMEM(0x1B,0x1e), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/awvl", EV5HWMEM(0x1B,0x1f), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/l", EV5HWMEM(0x1B,0x05), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/p", EV4HWMEM(0x1B,0x9), EV4, ARG_EV4HWMEM }, + { "hw_ldq/p", EV5HWMEM(0x1B,0x24), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/pa", EV4HWMEM(0x1B,0xD), EV4, ARG_EV4HWMEM }, + { "hw_ldq/pa", EV5HWMEM(0x1B,0x34), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/pal", EV5HWMEM(0x1B,0x35), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/par", EV4HWMEM(0x1B,0xF), EV4, ARG_EV4HWMEM }, + { "hw_ldq/pav", EV5HWMEM(0x1B,0x36), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/pavl", EV5HWMEM(0x1B,0x37), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/paw", EV5HWMEM(0x1B,0x3c), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/pawl", EV5HWMEM(0x1B,0x3d), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/pawv", EV5HWMEM(0x1B,0x3e), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/pawvl", EV5HWMEM(0x1B,0x3f), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/pl", EV5HWMEM(0x1B,0x25), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/pr", EV4HWMEM(0x1B,0xB), EV4, ARG_EV4HWMEM }, + { "hw_ldq/pv", EV5HWMEM(0x1B,0x26), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/pvl", EV5HWMEM(0x1B,0x27), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/pw", EV5HWMEM(0x1B,0x2c), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/pwl", EV5HWMEM(0x1B,0x2d), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/pwv", EV5HWMEM(0x1B,0x2e), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/pwvl", EV5HWMEM(0x1B,0x2f), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/r", EV4HWMEM(0x1B,0x3), EV4, ARG_EV4HWMEM }, + { "hw_ldq/v", EV5HWMEM(0x1B,0x06), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/vl", EV5HWMEM(0x1B,0x07), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/w", EV5HWMEM(0x1B,0x0c), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/wl", EV5HWMEM(0x1B,0x0d), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/wv", EV5HWMEM(0x1B,0x0e), EV5x, ARG_EV5HWMEM }, + { "hw_ldq/wvl", EV5HWMEM(0x1B,0x0f), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l", EV5HWMEM(0x1B,0x05), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/a", EV5HWMEM(0x1B,0x15), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/av", EV5HWMEM(0x1B,0x17), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/aw", EV5HWMEM(0x1B,0x1d), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/awv", EV5HWMEM(0x1B,0x1f), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/p", EV5HWMEM(0x1B,0x25), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/pa", EV5HWMEM(0x1B,0x35), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/pav", EV5HWMEM(0x1B,0x37), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/paw", EV5HWMEM(0x1B,0x3d), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/pawv", EV5HWMEM(0x1B,0x3f), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/pv", EV5HWMEM(0x1B,0x27), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/pw", EV5HWMEM(0x1B,0x2d), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/pwv", EV5HWMEM(0x1B,0x2f), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/v", EV5HWMEM(0x1B,0x07), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/w", EV5HWMEM(0x1B,0x0d), EV5x, ARG_EV5HWMEM }, + { "hw_ldq_l/wv", EV5HWMEM(0x1B,0x0f), EV5x, ARG_EV5HWMEM }, + { "hw_ld", EV4HWMEM(0x1B,0x0), EV4, ARG_EV4HWMEM }, + { "hw_ld", EV5HWMEM(0x1B,0x00), EV5x, ARG_EV5HWMEM }, + { "hw_ld/a", EV4HWMEM(0x1B,0x4), EV4, ARG_EV4HWMEM }, + { "hw_ld/a", EV5HWMEM(0x1B,0x10), EV5x, ARG_EV5HWMEM }, + { "hw_ld/al", EV5HWMEM(0x1B,0x11), EV5x, ARG_EV5HWMEM }, + { "hw_ld/aq", EV4HWMEM(0x1B,0x5), EV4, ARG_EV4HWMEM }, + { "hw_ld/aq", EV5HWMEM(0x1B,0x14), EV5x, ARG_EV5HWMEM }, + { "hw_ld/aql", EV5HWMEM(0x1B,0x15), EV5x, ARG_EV5HWMEM }, + { "hw_ld/aqv", EV5HWMEM(0x1B,0x16), EV5x, ARG_EV5HWMEM }, + { "hw_ld/aqvl", EV5HWMEM(0x1B,0x17), EV5x, ARG_EV5HWMEM }, + { "hw_ld/ar", EV4HWMEM(0x1B,0x6), EV4, ARG_EV4HWMEM }, + { "hw_ld/arq", EV4HWMEM(0x1B,0x7), EV4, ARG_EV4HWMEM }, + { "hw_ld/av", EV5HWMEM(0x1B,0x12), EV5x, ARG_EV5HWMEM }, + { "hw_ld/avl", EV5HWMEM(0x1B,0x13), EV5x, ARG_EV5HWMEM }, + { "hw_ld/aw", EV5HWMEM(0x1B,0x18), EV5x, ARG_EV5HWMEM }, + { "hw_ld/awl", EV5HWMEM(0x1B,0x19), EV5x, ARG_EV5HWMEM }, + { "hw_ld/awq", EV5HWMEM(0x1B,0x1c), EV5x, ARG_EV5HWMEM }, + { "hw_ld/awql", EV5HWMEM(0x1B,0x1d), EV5x, ARG_EV5HWMEM }, + { "hw_ld/awqv", EV5HWMEM(0x1B,0x1e), EV5x, ARG_EV5HWMEM }, + { "hw_ld/awqvl", EV5HWMEM(0x1B,0x1f), EV5x, ARG_EV5HWMEM }, + { "hw_ld/awv", EV5HWMEM(0x1B,0x1a), EV5x, ARG_EV5HWMEM }, + { "hw_ld/awvl", EV5HWMEM(0x1B,0x1b), EV5x, ARG_EV5HWMEM }, + { "hw_ld/l", EV5HWMEM(0x1B,0x01), EV5x, ARG_EV5HWMEM }, + { "hw_ld/p", EV4HWMEM(0x1B,0x8), EV4, ARG_EV4HWMEM }, + { "hw_ld/p", EV5HWMEM(0x1B,0x20), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pa", EV4HWMEM(0x1B,0xC), EV4, ARG_EV4HWMEM }, + { "hw_ld/pa", EV5HWMEM(0x1B,0x30), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pal", EV5HWMEM(0x1B,0x31), EV5x, ARG_EV5HWMEM }, + { "hw_ld/paq", EV4HWMEM(0x1B,0xD), EV4, ARG_EV4HWMEM }, + { "hw_ld/paq", EV5HWMEM(0x1B,0x34), EV5x, ARG_EV5HWMEM }, + { "hw_ld/paql", EV5HWMEM(0x1B,0x35), EV5x, ARG_EV5HWMEM }, + { "hw_ld/paqv", EV5HWMEM(0x1B,0x36), EV5x, ARG_EV5HWMEM }, + { "hw_ld/paqvl", EV5HWMEM(0x1B,0x37), EV5x, ARG_EV5HWMEM }, + { "hw_ld/par", EV4HWMEM(0x1B,0xE), EV4, ARG_EV4HWMEM }, + { "hw_ld/parq", EV4HWMEM(0x1B,0xF), EV4, ARG_EV4HWMEM }, + { "hw_ld/pav", EV5HWMEM(0x1B,0x32), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pavl", EV5HWMEM(0x1B,0x33), EV5x, ARG_EV5HWMEM }, + { "hw_ld/paw", EV5HWMEM(0x1B,0x38), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pawl", EV5HWMEM(0x1B,0x39), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pawq", EV5HWMEM(0x1B,0x3c), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pawql", EV5HWMEM(0x1B,0x3d), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pawqv", EV5HWMEM(0x1B,0x3e), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pawqvl", EV5HWMEM(0x1B,0x3f), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pawv", EV5HWMEM(0x1B,0x3a), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pawvl", EV5HWMEM(0x1B,0x3b), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pl", EV5HWMEM(0x1B,0x21), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pq", EV4HWMEM(0x1B,0x9), EV4, ARG_EV4HWMEM }, + { "hw_ld/pq", EV5HWMEM(0x1B,0x24), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pql", EV5HWMEM(0x1B,0x25), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pqv", EV5HWMEM(0x1B,0x26), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pqvl", EV5HWMEM(0x1B,0x27), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pr", EV4HWMEM(0x1B,0xA), EV4, ARG_EV4HWMEM }, + { "hw_ld/prq", EV4HWMEM(0x1B,0xB), EV4, ARG_EV4HWMEM }, + { "hw_ld/pv", EV5HWMEM(0x1B,0x22), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pvl", EV5HWMEM(0x1B,0x23), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pw", EV5HWMEM(0x1B,0x28), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pwl", EV5HWMEM(0x1B,0x29), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pwq", EV5HWMEM(0x1B,0x2c), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pwql", EV5HWMEM(0x1B,0x2d), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pwqv", EV5HWMEM(0x1B,0x2e), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pwqvl", EV5HWMEM(0x1B,0x2f), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pwv", EV5HWMEM(0x1B,0x2a), EV5x, ARG_EV5HWMEM }, + { "hw_ld/pwvl", EV5HWMEM(0x1B,0x2b), EV5x, ARG_EV5HWMEM }, + { "hw_ld/q", EV4HWMEM(0x1B,0x1), EV4, ARG_EV4HWMEM }, + { "hw_ld/q", EV5HWMEM(0x1B,0x04), EV5x, ARG_EV5HWMEM }, + { "hw_ld/ql", EV5HWMEM(0x1B,0x05), EV5x, ARG_EV5HWMEM }, + { "hw_ld/qv", EV5HWMEM(0x1B,0x06), EV5x, ARG_EV5HWMEM }, + { "hw_ld/qvl", EV5HWMEM(0x1B,0x07), EV5x, ARG_EV5HWMEM }, + { "hw_ld/r", EV4HWMEM(0x1B,0x2), EV4, ARG_EV4HWMEM }, + { "hw_ld/rq", EV4HWMEM(0x1B,0x3), EV4, ARG_EV4HWMEM }, + { "hw_ld/v", EV5HWMEM(0x1B,0x02), EV5x, ARG_EV5HWMEM }, + { "hw_ld/vl", EV5HWMEM(0x1B,0x03), EV5x, ARG_EV5HWMEM }, + { "hw_ld/w", EV5HWMEM(0x1B,0x08), EV5x, ARG_EV5HWMEM }, + { "hw_ld/wl", EV5HWMEM(0x1B,0x09), EV5x, ARG_EV5HWMEM }, + { "hw_ld/wq", EV5HWMEM(0x1B,0x0c), EV5x, ARG_EV5HWMEM }, + { "hw_ld/wql", EV5HWMEM(0x1B,0x0d), EV5x, ARG_EV5HWMEM }, + { "hw_ld/wqv", EV5HWMEM(0x1B,0x0e), EV5x, ARG_EV5HWMEM }, + { "hw_ld/wqvl", EV5HWMEM(0x1B,0x0f), EV5x, ARG_EV5HWMEM }, + { "hw_ld/wv", EV5HWMEM(0x1B,0x0a), EV5x, ARG_EV5HWMEM }, + { "hw_ld/wvl", EV5HWMEM(0x1B,0x0b), EV5x, ARG_EV5HWMEM }, + { "pal1b", PCD(0x1B), ALL, ARG_PCD }, + + { "hw_mtpr", OPR(0x1D,0x00), EV4, { RA, RBA, EV4EXTHWINDEX } }, + { "hw_mtpr", OP(0x1D), OP_MASK, EV5x, { RA, RBA, EV5HWINDEX } }, + { "hw_mtpr/i", OPR(0x1D,0x01), EV4, ARG_EV4HWMPR }, + { "hw_mtpr/a", OPR(0x1D,0x02), EV4, ARG_EV4HWMPR }, + { "hw_mtpr/ai", OPR(0x1D,0x03), EV4, ARG_EV4HWMPR }, + { "hw_mtpr/p", OPR(0x1D,0x04), EV4, ARG_EV4HWMPR }, + { "hw_mtpr/pi", OPR(0x1D,0x05), EV4, ARG_EV4HWMPR }, + { "hw_mtpr/pa", OPR(0x1D,0x06), EV4, ARG_EV4HWMPR }, + { "hw_mtpr/pai", OPR(0x1D,0x07), EV4, ARG_EV4HWMPR }, + { "pal1d", PCD(0x1D), ALL, ARG_PCD }, + + { "hw_rei", SPCD(0x1E,0x3FF8000), EV4|EV5x, ARG_NONE }, + { "hw_rei_stall", SPCD(0x1E,0x3FFC000), EV5x, ARG_NONE }, + { "pal1e", PCD(0x1E), ALL, ARG_PCD }, + + { "hw_stl", EV4HWMEM(0x1F,0x0), EV4, ARG_EV4HWMEM }, + { "hw_stl", EV5HWMEM(0x1F,0x00), EV5x, ARG_EV5HWMEM }, + { "hw_stl/a", EV4HWMEM(0x1F,0x4), EV4, ARG_EV4HWMEM }, + { "hw_stl/a", EV5HWMEM(0x1F,0x10), EV5x, ARG_EV5HWMEM }, + { "hw_stl/ac", EV5HWMEM(0x1F,0x11), EV5x, ARG_EV5HWMEM }, + { "hw_stl/ar", EV4HWMEM(0x1F,0x6), EV4, ARG_EV4HWMEM }, + { "hw_stl/av", EV5HWMEM(0x1F,0x12), EV5x, ARG_EV5HWMEM }, + { "hw_stl/avc", EV5HWMEM(0x1F,0x13), EV5x, ARG_EV5HWMEM }, + { "hw_stl/c", EV5HWMEM(0x1F,0x01), EV5x, ARG_EV5HWMEM }, + { "hw_stl/p", EV4HWMEM(0x1F,0x8), EV4, ARG_EV4HWMEM }, + { "hw_stl/p", EV5HWMEM(0x1F,0x20), EV5x, ARG_EV5HWMEM }, + { "hw_stl/pa", EV4HWMEM(0x1F,0xC), EV4, ARG_EV4HWMEM }, + { "hw_stl/pa", EV5HWMEM(0x1F,0x30), EV5x, ARG_EV5HWMEM }, + { "hw_stl/pac", EV5HWMEM(0x1F,0x31), EV5x, ARG_EV5HWMEM }, + { "hw_stl/pav", EV5HWMEM(0x1F,0x32), EV5x, ARG_EV5HWMEM }, + { "hw_stl/pavc", EV5HWMEM(0x1F,0x33), EV5x, ARG_EV5HWMEM }, + { "hw_stl/pc", EV5HWMEM(0x1F,0x21), EV5x, ARG_EV5HWMEM }, + { "hw_stl/pr", EV4HWMEM(0x1F,0xA), EV4, ARG_EV4HWMEM }, + { "hw_stl/pv", EV5HWMEM(0x1F,0x22), EV5x, ARG_EV5HWMEM }, + { "hw_stl/pvc", EV5HWMEM(0x1F,0x23), EV5x, ARG_EV5HWMEM }, + { "hw_stl/r", EV4HWMEM(0x1F,0x2), EV4, ARG_EV4HWMEM }, + { "hw_stl/v", EV5HWMEM(0x1F,0x02), EV5x, ARG_EV5HWMEM }, + { "hw_stl/vc", EV5HWMEM(0x1F,0x03), EV5x, ARG_EV5HWMEM }, + { "hw_stl_c", EV5HWMEM(0x1F,0x01), EV5x, ARG_EV5HWMEM }, + { "hw_stl_c/a", EV5HWMEM(0x1F,0x11), EV5x, ARG_EV5HWMEM }, + { "hw_stl_c/av", EV5HWMEM(0x1F,0x13), EV5x, ARG_EV5HWMEM }, + { "hw_stl_c/p", EV5HWMEM(0x1F,0x21), EV5x, ARG_EV5HWMEM }, + { "hw_stl_c/pa", EV5HWMEM(0x1F,0x31), EV5x, ARG_EV5HWMEM }, + { "hw_stl_c/pav", EV5HWMEM(0x1F,0x33), EV5x, ARG_EV5HWMEM }, + { "hw_stl_c/pv", EV5HWMEM(0x1F,0x23), EV5x, ARG_EV5HWMEM }, + { "hw_stl_c/v", EV5HWMEM(0x1F,0x03), EV5x, ARG_EV5HWMEM }, + { "hw_stq", EV4HWMEM(0x1F,0x1), EV4, ARG_EV4HWMEM }, + { "hw_stq", EV5HWMEM(0x1F,0x04), EV5x, ARG_EV5HWMEM }, + { "hw_stq/a", EV4HWMEM(0x1F,0x5), EV4, ARG_EV4HWMEM }, + { "hw_stq/a", EV5HWMEM(0x1F,0x14), EV5x, ARG_EV5HWMEM }, + { "hw_stq/ac", EV5HWMEM(0x1F,0x15), EV5x, ARG_EV5HWMEM }, + { "hw_stq/ar", EV4HWMEM(0x1F,0x7), EV4, ARG_EV4HWMEM }, + { "hw_stq/av", EV5HWMEM(0x1F,0x16), EV5x, ARG_EV5HWMEM }, + { "hw_stq/avc", EV5HWMEM(0x1F,0x17), EV5x, ARG_EV5HWMEM }, + { "hw_stq/c", EV5HWMEM(0x1F,0x05), EV5x, ARG_EV5HWMEM }, + { "hw_stq/p", EV4HWMEM(0x1F,0x9), EV4, ARG_EV4HWMEM }, + { "hw_stq/p", EV5HWMEM(0x1F,0x24), EV5x, ARG_EV5HWMEM }, + { "hw_stq/pa", EV4HWMEM(0x1F,0xD), EV4, ARG_EV4HWMEM }, + { "hw_stq/pa", EV5HWMEM(0x1F,0x34), EV5x, ARG_EV5HWMEM }, + { "hw_stq/pac", EV5HWMEM(0x1F,0x35), EV5x, ARG_EV5HWMEM }, + { "hw_stq/par", EV4HWMEM(0x1F,0xE), EV4, ARG_EV4HWMEM }, + { "hw_stq/par", EV4HWMEM(0x1F,0xF), EV4, ARG_EV4HWMEM }, + { "hw_stq/pav", EV5HWMEM(0x1F,0x36), EV5x, ARG_EV5HWMEM }, + { "hw_stq/pavc", EV5HWMEM(0x1F,0x37), EV5x, ARG_EV5HWMEM }, + { "hw_stq/pc", EV5HWMEM(0x1F,0x25), EV5x, ARG_EV5HWMEM }, + { "hw_stq/pr", EV4HWMEM(0x1F,0xB), EV4, ARG_EV4HWMEM }, + { "hw_stq/pv", EV5HWMEM(0x1F,0x26), EV5x, ARG_EV5HWMEM }, + { "hw_stq/pvc", EV5HWMEM(0x1F,0x27), EV5x, ARG_EV5HWMEM }, + { "hw_stq/r", EV4HWMEM(0x1F,0x3), EV4, ARG_EV4HWMEM }, + { "hw_stq/v", EV5HWMEM(0x1F,0x06), EV5x, ARG_EV5HWMEM }, + { "hw_stq/vc", EV5HWMEM(0x1F,0x07), EV5x, ARG_EV5HWMEM }, + { "hw_stq_c", EV5HWMEM(0x1F,0x05), EV5x, ARG_EV5HWMEM }, + { "hw_stq_c/a", EV5HWMEM(0x1F,0x15), EV5x, ARG_EV5HWMEM }, + { "hw_stq_c/av", EV5HWMEM(0x1F,0x17), EV5x, ARG_EV5HWMEM }, + { "hw_stq_c/p", EV5HWMEM(0x1F,0x25), EV5x, ARG_EV5HWMEM }, + { "hw_stq_c/pa", EV5HWMEM(0x1F,0x35), EV5x, ARG_EV5HWMEM }, + { "hw_stq_c/pav", EV5HWMEM(0x1F,0x37), EV5x, ARG_EV5HWMEM }, + { "hw_stq_c/pv", EV5HWMEM(0x1F,0x27), EV5x, ARG_EV5HWMEM }, + { "hw_stq_c/v", EV5HWMEM(0x1F,0x07), EV5x, ARG_EV5HWMEM }, + { "hw_st", EV4HWMEM(0x1F,0x0), EV4, ARG_EV4HWMEM }, + { "hw_st", EV5HWMEM(0x1F,0x00), EV5x, ARG_EV5HWMEM }, + { "hw_st/a", EV4HWMEM(0x1F,0x4), EV4, ARG_EV4HWMEM }, + { "hw_st/a", EV5HWMEM(0x1F,0x10), EV5x, ARG_EV5HWMEM }, + { "hw_st/ac", EV5HWMEM(0x1F,0x11), EV5x, ARG_EV5HWMEM }, + { "hw_st/aq", EV4HWMEM(0x1F,0x5), EV4, ARG_EV4HWMEM }, + { "hw_st/aq", EV5HWMEM(0x1F,0x14), EV5x, ARG_EV5HWMEM }, + { "hw_st/aqc", EV5HWMEM(0x1F,0x15), EV5x, ARG_EV5HWMEM }, + { "hw_st/aqv", EV5HWMEM(0x1F,0x16), EV5x, ARG_EV5HWMEM }, + { "hw_st/aqvc", EV5HWMEM(0x1F,0x17), EV5x, ARG_EV5HWMEM }, + { "hw_st/ar", EV4HWMEM(0x1F,0x6), EV4, ARG_EV4HWMEM }, + { "hw_st/arq", EV4HWMEM(0x1F,0x7), EV4, ARG_EV4HWMEM }, + { "hw_st/av", EV5HWMEM(0x1F,0x12), EV5x, ARG_EV5HWMEM }, + { "hw_st/avc", EV5HWMEM(0x1F,0x13), EV5x, ARG_EV5HWMEM }, + { "hw_st/c", EV5HWMEM(0x1F,0x01), EV5x, ARG_EV5HWMEM }, + { "hw_st/p", EV4HWMEM(0x1F,0x8), EV4, ARG_EV4HWMEM }, + { "hw_st/p", EV5HWMEM(0x1F,0x20), EV5x, ARG_EV5HWMEM }, + { "hw_st/pa", EV4HWMEM(0x1F,0xC), EV4, ARG_EV4HWMEM }, + { "hw_st/pa", EV5HWMEM(0x1F,0x30), EV5x, ARG_EV5HWMEM }, + { "hw_st/pac", EV5HWMEM(0x1F,0x31), EV5x, ARG_EV5HWMEM }, + { "hw_st/paq", EV4HWMEM(0x1F,0xD), EV4, ARG_EV4HWMEM }, + { "hw_st/paq", EV5HWMEM(0x1F,0x34), EV5x, ARG_EV5HWMEM }, + { "hw_st/paqc", EV5HWMEM(0x1F,0x35), EV5x, ARG_EV5HWMEM }, + { "hw_st/paqv", EV5HWMEM(0x1F,0x36), EV5x, ARG_EV5HWMEM }, + { "hw_st/paqvc", EV5HWMEM(0x1F,0x37), EV5x, ARG_EV5HWMEM }, + { "hw_st/par", EV4HWMEM(0x1F,0xE), EV4, ARG_EV4HWMEM }, + { "hw_st/parq", EV4HWMEM(0x1F,0xF), EV4, ARG_EV4HWMEM }, + { "hw_st/pav", EV5HWMEM(0x1F,0x32), EV5x, ARG_EV5HWMEM }, + { "hw_st/pavc", EV5HWMEM(0x1F,0x33), EV5x, ARG_EV5HWMEM }, + { "hw_st/pc", EV5HWMEM(0x1F,0x21), EV5x, ARG_EV5HWMEM }, + { "hw_st/pq", EV4HWMEM(0x1F,0x9), EV4, ARG_EV4HWMEM }, + { "hw_st/pq", EV5HWMEM(0x1F,0x24), EV5x, ARG_EV5HWMEM }, + { "hw_st/pqc", EV5HWMEM(0x1F,0x25), EV5x, ARG_EV5HWMEM }, + { "hw_st/pqv", EV5HWMEM(0x1F,0x26), EV5x, ARG_EV5HWMEM }, + { "hw_st/pqvc", EV5HWMEM(0x1F,0x27), EV5x, ARG_EV5HWMEM }, + { "hw_st/pr", EV4HWMEM(0x1F,0xA), EV4, ARG_EV4HWMEM }, + { "hw_st/prq", EV4HWMEM(0x1F,0xB), EV4, ARG_EV4HWMEM }, + { "hw_st/pv", EV5HWMEM(0x1F,0x22), EV5x, ARG_EV5HWMEM }, + { "hw_st/pvc", EV5HWMEM(0x1F,0x23), EV5x, ARG_EV5HWMEM }, + { "hw_st/q", EV4HWMEM(0x1F,0x1), EV4, ARG_EV4HWMEM }, + { "hw_st/q", EV5HWMEM(0x1F,0x04), EV5x, ARG_EV5HWMEM }, + { "hw_st/qc", EV5HWMEM(0x1F,0x05), EV5x, ARG_EV5HWMEM }, + { "hw_st/qv", EV5HWMEM(0x1F,0x06), EV5x, ARG_EV5HWMEM }, + { "hw_st/qvc", EV5HWMEM(0x1F,0x07), EV5x, ARG_EV5HWMEM }, + { "hw_st/r", EV4HWMEM(0x1F,0x2), EV4, ARG_EV4HWMEM }, + { "hw_st/v", EV5HWMEM(0x1F,0x02), EV5x, ARG_EV5HWMEM }, + { "hw_st/vc", EV5HWMEM(0x1F,0x03), EV5x, ARG_EV5HWMEM }, + { "pal1f", PCD(0x1F), ALL, ARG_PCD }, + + { "ldf", MEM(0x20), ALL, ARG_FMEM }, + { "ldg", MEM(0x21), ALL, ARG_FMEM }, + { "lds", MEM(0x22), ALL, ARG_FMEM }, + { "ldt", MEM(0x23), ALL, ARG_FMEM }, + { "stf", MEM(0x24), ALL, ARG_FMEM }, + { "stg", MEM(0x25), ALL, ARG_FMEM }, + { "sts", MEM(0x26), ALL, ARG_FMEM }, + { "stt", MEM(0x27), ALL, ARG_FMEM }, + + { "ldl", MEM(0x28), ALL, ARG_MEM }, + { "ldq", MEM(0x29), ALL, ARG_MEM }, + { "ldl_l", MEM(0x2A), ALL, ARG_MEM }, + { "ldq_l", MEM(0x2B), ALL, ARG_MEM }, + { "stl", MEM(0x2C), ALL, ARG_MEM }, + { "stq", MEM(0x2D), ALL, ARG_MEM }, + { "stl_c", MEM(0x2E), ALL, ARG_MEM }, + { "stq_c", MEM(0x2F), ALL, ARG_MEM }, + + { "br", BRA(0x30), ALL, { ZA, BDISP } }, /* pseudo */ + { "br", BRA(0x30), ALL, ARG_BRA }, + { "fbeq", BRA(0x31), ALL, ARG_FBRA }, + { "fblt", BRA(0x32), ALL, ARG_FBRA }, + { "fble", BRA(0x33), ALL, ARG_FBRA }, + { "bsr", BRA(0x34), ALL, ARG_BRA }, + { "fbne", BRA(0x35), ALL, ARG_FBRA }, + { "fbge", BRA(0x36), ALL, ARG_FBRA }, + { "fbgt", BRA(0x37), ALL, ARG_FBRA }, + { "blbc", BRA(0x38), ALL, ARG_BRA }, + { "beq", BRA(0x39), ALL, ARG_BRA }, + { "blt", BRA(0x3A), ALL, ARG_BRA }, + { "ble", BRA(0x3B), ALL, ARG_BRA }, + { "blbs", BRA(0x3C), ALL, ARG_BRA }, + { "bne", BRA(0x3D), ALL, ARG_BRA }, + { "bge", BRA(0x3E), ALL, ARG_BRA }, + { "bgt", BRA(0x3F), ALL, ARG_BRA }, +}; + +const int alpha_num_opcodes = sizeof(alpha_opcodes)/sizeof(*alpha_opcodes); diff --git a/gnu/usr.bin/binutils/opcodes/arm-dis.c b/gnu/usr.bin/binutils/opcodes/arm-dis.c index 32c7f8122f4..deeef731ddc 100644 --- a/gnu/usr.bin/binutils/opcodes/arm-dis.c +++ b/gnu/usr.bin/binutils/opcodes/arm-dis.c @@ -155,6 +155,70 @@ print_insn_arm (pc, info, given) } } break; + + case 's': + if ((given & 0x004f0000) == 0x004f0000) + { + /* PC relative with immediate offset */ + int offset = ((given & 0xf00) >> 4) | (given & 0xf); + if ((given & 0x00800000) == 0) + offset = -offset; + (*info->print_address_func) + (offset + pc + 8, info); + } + else + { + func (stream, "[%s", + arm_regnames[(given >> 16) & 0xf]); + if ((given & 0x01000000) != 0) + { + /* pre-indexed */ + if ((given & 0x00400000) == 0x00400000) + { + /* immediate */ + int offset = ((given & 0xf00) >> 4) | (given & 0xf); + if (offset) + func (stream, ", %s#%x", + (((given & 0x00800000) == 0) + ? "-" : ""), offset); + } + else + { + /* register */ + func (stream, ", %s%s", + (((given & 0x00800000) == 0) + ? "-" : ""), + arm_regnames[given & 0xf]); + } + + func (stream, "]%s", + ((given & 0x00200000) != 0) ? "!" : ""); + } + else + { + /* post-indexed */ + if ((given & 0x00400000) == 0x00400000) + { + /* immediate */ + int offset = ((given & 0xf00) >> 4) | (given & 0xf); + if (offset) + func (stream, "], %s#%x", + (((given & 0x00800000) == 0) + ? "-" : ""), offset); + else + func (stream, "]"); + } + else + { + /* register */ + func (stream, "], %s%s", + (((given & 0x00800000) == 0) + ? "-" : ""), + arm_regnames[given & 0xf]); + } + } + } + break; case 'b': (*info->print_address_func) @@ -207,6 +271,13 @@ print_insn_arm (pc, info, given) func (stream, "t"); break; + case 'h': + if ((given & 0x00000020) == 0x00000020) + func (stream, "h"); + else + func (stream, "b"); + break; + case 'A': func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]); if ((given & 0x01000000) != 0) diff --git a/gnu/usr.bin/binutils/opcodes/arm-opc.h b/gnu/usr.bin/binutils/opcodes/arm-opc.h index 33f5daa90d2..c1f544374b1 100644 --- a/gnu/usr.bin/binutils/opcodes/arm-opc.h +++ b/gnu/usr.bin/binutils/opcodes/arm-opc.h @@ -39,8 +39,10 @@ struct arm_opcode { %?ab print a if bit is one else print b %p print 'p' iff bits 12-15 are 15 %t print 't' iff bit 21 set and bit 24 clear + %h print 'h' iff bit 5 set, else print 'b' %o print operand2 (immediate or register + shift) %a print address for ldr/str instruction + %s print address for ldr/str halfword/signextend instruction %b print branch destination %A print address for ldc/stc/ldf/stf instruction %m print register mask for ldm/stm instruction @@ -53,11 +55,14 @@ struct arm_opcode { static struct arm_opcode arm_opcodes[] = { /* ARM instructions */ + {0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"}, {0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"}, {0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"}, {0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"}, {0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"}, {0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"}, + {0x00000090, 0x0e100090, "str%c%6's%h\t%12-15r, %s"}, + {0x00100090, 0x0e100090, "ldr%c%6's%h\t%12-15r, %s"}, {0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"}, {0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"}, {0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"}, diff --git a/gnu/usr.bin/binutils/opcodes/makefile.vms b/gnu/usr.bin/binutils/opcodes/makefile.vms new file mode 100644 index 00000000000..160319d5ce8 --- /dev/null +++ b/gnu/usr.bin/binutils/opcodes/makefile.vms @@ -0,0 +1,31 @@ +# +# Makefile for libopcodes under openVMS/AXP +# +# For use with gnu-make for vms +# +# Created by Klaus Kaempf, kkaempf@progis.de +# +# +CC=gcc + +OBJS=alpha-dis.obj,alpha-opc.obj,dis-buf.obj,disassemble.obj + +ifeq ($(CC),gcc) +DEFS=/define=(OBJ_EVAX) +CFLAGS=/include=([],[-.include],[-.bfd])$(DEFS) +else +DEFS=/define=(OBJ_EVAX,"const=") +CFLAGS=/noopt/debug/include=([],[-.include],[-.bfd])$(DEFS) +endif + +libopcodes.olb: sysdep.h $(OBJS) + purge + lib/create libopcodes *.obj + +disassemble.obj: disassemble.c + $(CC)$(CFLAGS)/define=("ARCH_alpha") $< + +alpha-dis.obj: alpha-dis.c + +sysdep.h: [-.bfd.hosts]alphavms.h + $(CP) $< $@ diff --git a/gnu/usr.bin/binutils/texinfo/texinfo.tex b/gnu/usr.bin/binutils/texinfo/texinfo.tex index 50db717ac71..e1548c3c158 100644 --- a/gnu/usr.bin/binutils/texinfo/texinfo.tex +++ b/gnu/usr.bin/binutils/texinfo/texinfo.tex @@ -1,6 +1,7 @@ %% TeX macros to handle texinfo files -% Copyright (C) 1985, 86, 88, 90, 91, 92, 1993 Free Software Foundation, Inc. +% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, +% 94, 95, 1996 Free Software Foundation, Inc. %This texinfo.tex file is free software; you can redistribute it and/or %modify it under the terms of the GNU General Public License as @@ -14,22 +15,38 @@ %You should have received a copy of the GNU General Public License %along with this texinfo.tex file; see the file COPYING. If not, write -%to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, -%USA. +%to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +%Boston, MA 02111-1307, USA. %In other words, you are welcome to use, share and improve this program. %You are forbidden to forbid anyone else to use, share and improve %what you give them. Help stamp out software-hoarding! -\def\texinfoversion{2.122} + +% Send bug reports to bug-texinfo@prep.ai.mit.edu. +% Please include a *precise* test case in each bug report. + + +% Make it possible to create a .fmt file just by loading this file: +% if the underlying format is not loaded, start by loading it now. +% Added by gildea November 1993. +\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi + +% This automatically updates the version number based on RCS. +\def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}} +\deftexinfoversion$Revision: 1.1.1.2 $ \message{Loading texinfo package [Version \texinfoversion]:} -% Print the version number if in a .fmt file. -\everyjob{\message{[Texinfo version \texinfoversion]}\message{}} +% If in a .fmt file, print the version number +% and turn on active characters that we couldn't do earlier because +% they might have appeared in the input file name. +\everyjob{\message{[Texinfo version \texinfoversion]}\message{} + \catcode`+=\active \catcode`\_=\active} % Save some parts of plain tex whose names we will redefine. +\let\ptextilde=\~ \let\ptexlbrace=\{ \let\ptexrbrace=\} \let\ptexdots=\dots @@ -44,7 +61,18 @@ \let\ptexl=\l \let\ptexL=\L -\def\tie{\penalty 10000\ } % Save plain tex definition of ~. +% Be sure we're in horizontal mode when doing a tie, since we make space +% equivalent to this in @example-like environments. Otherwise, a space +% at the beginning of a line will start with \penalty -- and +% since \penalty is valid in vertical mode, we'd end up putting the +% penalty on the vertical list instead of in the new paragraph. +{\catcode`@ = 11 + % Avoid using \@M directly, because that causes trouble + % if the definition is written into an index file. + \global\let\tiepenalty = \@M + \gdef\tie{\leavevmode\penalty\tiepenalty\ } +} +\let\~ = \tie % And make it available as @~. \message{Basics,} \chardef\other=12 @@ -157,9 +185,14 @@ % Do @cropmarks to get crop marks \def\cropmarks{\let\onepageout=\croppageout } +\newinsert\margin \dimen\margin=\maxdimen + \def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} {\catcode`\@ =11 \gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +% marginal hacks, juha@viisa.uucp (Juha Takala) +\ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi \dimen@=\dp#1 \unvbox#1 \ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi \ifr@ggedbottom \kern-\dimen@ \vfil \fi} @@ -310,13 +343,13 @@ % Single-spacing is done by various environments (specifically, in % \nonfillstart and \quotations). -\newskip\singlespaceskip \singlespaceskip = \baselineskip +\newskip\singlespaceskip \singlespaceskip = 12.5pt \def\singlespace{% -% Why was this kern here? It messes up equalizing space above and below -% environments. --karl, 6may93 -%{\advance \baselineskip by -\singlespaceskip -%\kern \baselineskip}% -\baselineskip=\singlespaceskip + % Why was this kern here? It messes up equalizing space above and below + % environments. --karl, 6may93 + %{\advance \baselineskip by -\singlespaceskip + %\kern \baselineskip}% + \setleading \singlespaceskip } %% Simple single-character @ commands @@ -348,6 +381,15 @@ % @. is an end-of-sentence period. \def\.{.\spacefactor=3000 } +% @enddots{} is an end-of-sentence ellipsis. +\gdef\enddots{$\mathinner{\ldotp\ldotp\ldotp\ldotp}$\spacefactor=3000} + +% @! is an end-of-sentence bang. +\gdef\!{!\spacefactor=3000 } + +% @? is an end-of-sentence query. +\gdef\?{?\spacefactor=3000 } + % @w prevents a word break. Without the \leavevmode, @w at the % beginning of a paragraph, when TeX is still in vertical mode, would % produce a whole line of output instead of starting the paragraph. @@ -402,8 +444,8 @@ \obeylines \fi % - % We do @comment here in case we are called inside an environment, - % such as @example, where each end-of-line in the input causes an + % Do @comment since we are called inside an environment such as + % @example, where each end-of-line in the input causes an % end-of-line in the output. We don't want the end-of-line after % the `@group' to put extra space in the output. Since @group % should appear on a line by itself (according to the Texinfo @@ -473,7 +515,7 @@ where each line of input produces a line of output.} % @dots{} output some dots -\def\dots{.$\,$.$\,$.\:} +\def\dots{$\ldots$} % @page forces the start of a new page @@ -495,17 +537,34 @@ where each line of input produces a line of output.} \def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount \leftline{\hskip\leftskip{\rm#1}}}} +% @inmargin{TEXT} puts TEXT in the margin next to the current paragraph. + +\def\inmargin#1{% +\strut\vadjust{\nobreak\kern-\strutdepth + \vtop to \strutdepth{\baselineskip\strutdepth\vss + \llap{\rightskip=\inmarginspacing \vbox{\noindent #1}}\null}}} +\newskip\inmarginspacing \inmarginspacing=1cm +\def\strutdepth{\dp\strutbox} + %\hbox{{\rm#1}}\hfil\break}} % @include file insert text of that file as input. - -\def\include{\parsearg\includezzz} -%Use \input\thisfile to avoid blank after \input, which may be an active -%char (in which case the blank would become the \input argument). -%The grouping keeps the value of \thisfile correct even when @include -%is nested. -\def\includezzz #1{\begingroup -\def\thisfile{#1}\input\thisfile +% Allow normal characters that we make active in the argument (a file name). +\def\include{\begingroup + \catcode`\\=12 + \catcode`~=12 + \catcode`^=12 + \catcode`_=12 + \catcode`|=12 + \catcode`<=12 + \catcode`>=12 + \catcode`+=12 + \parsearg\includezzz} +% Restore active chars for included file. +\def\includezzz#1{\endgroup\begingroup + % Read the included file in a group so nested @include's work. + \def\thisfile{#1}% + \input\thisfile \endgroup} \def\thisfile{} @@ -567,6 +626,7 @@ where each line of input produces a line of output.} % incorrectly. % \def\ignoremorecommands{% + \let\defcodeindex = \relax \let\defcv = \relax \let\deffn = \relax \let\deffnx = \relax @@ -590,6 +650,15 @@ where each line of input produces a line of output.} \let\printindex = \relax \let\pxref = \relax \let\settitle = \relax + \let\setchapternewpage = \relax + \let\setchapterstyle = \relax + \let\everyheading = \relax + \let\evenheading = \relax + \let\oddheading = \relax + \let\everyfooting = \relax + \let\evenfooting = \relax + \let\oddfooting = \relax + \let\headings = \relax \let\include = \relax \let\lowersections = \relax \let\down = \relax @@ -598,19 +667,25 @@ where each line of input produces a line of output.} \let\set = \relax \let\clear = \relax \let\item = \relax - \let\message = \relax } % Ignore @ignore ... @end ignore. % \def\ignore{\doignore{ignore}} -% Also ignore @ifinfo, @menu, and @direntry text. +% Also ignore @ifinfo, @ifhtml, @html, @menu, and @direntry text. % \def\ifinfo{\doignore{ifinfo}} +\def\ifhtml{\doignore{ifhtml}} +\def\html{\doignore{html}} \def\menu{\doignore{menu}} \def\direntry{\doignore{direntry}} +% @dircategory CATEGORY -- specify a category of the dir file +% which this file should belong to. Ignore this in TeX. + +\def\dircategory{\comment} + % Ignore text until a line `@end #1'. % \def\doignore#1{\begingroup @@ -646,7 +721,7 @@ where each line of input produces a line of output.} \immediate\write16{ script ``tex3patch'' from the Texinfo distribution} \immediate\write16{ to use a workaround.} \immediate\write16{} - \warnedobstrue + \global\warnedobstrue \fi } @@ -722,17 +797,22 @@ where each line of input produces a line of output.} % Since we want to separate VAR from REST-OF-LINE (which might be % empty), we can't just use \parsearg; we have to insert a space of our % own to delimit the rest of the line, and then take it out again if we -% didn't need it. +% didn't need it. Make sure the catcode of space is correct to avoid +% losing inside @example, for instance. % -\def\set{\parsearg\setxxx} +\def\set{\begingroup\catcode` =10 \parsearg\setxxx} \def\setxxx#1{\setyyy#1 \endsetyyy} \def\setyyy#1 #2\endsetyyy{% \def\temp{#2}% \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. \fi + \endgroup } -\def\setzzz#1#2 \endsetzzz{\expandafter\xdef\csname SET#1\endcsname{#2}} +% Can't use \xdef to pre-expand #2 and save some time, since \temp or +% \next or other control sequences that we've defined might get us into +% an infinite loop. Consider `@set foo @cite{bar}'. +\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}} % @clear VAR clears (i.e., unsets) the variable VAR. % @@ -834,15 +914,15 @@ where each line of input produces a line of output.} \def\donoderef{\ifx\lastnode\relax\else \expandafter\expandafter\expandafter\setref{\lastnode}\fi -\let\lastnode=\relax} +\global\let\lastnode=\relax} \def\unnumbnoderef{\ifx\lastnode\relax\else \expandafter\expandafter\expandafter\unnumbsetref{\lastnode}\fi -\let\lastnode=\relax} +\global\let\lastnode=\relax} \def\appendixnoderef{\ifx\lastnode\relax\else \expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi -\let\lastnode=\relax} +\global\let\lastnode=\relax} \let\refill=\relax @@ -864,6 +944,21 @@ where each line of input produces a line of output.} \def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, node \samp{\ignorespaces#1{}}} +\def\macro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\macroxxx} +\def\macroxxx#1#2 \end macro{% +\expandafter\gdef\macrotemp#1{#2}% +\endgroup} + +%\def\linemacro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\linemacroxxx} +%\def\linemacroxxx#1#2 \end linemacro{% +%\let\parsearg=\relax +%\edef\macrotempx{\csname M\butfirst\expandafter\string\macrotemp\endcsname}% +%\expandafter\xdef\macrotemp{\parsearg\macrotempx}% +%\expandafter\gdef\macrotempx#1{#2}% +%\endgroup} + +%\def\butfirst#1{} + \message{fonts,} % Font-change commands. @@ -874,31 +969,63 @@ where each line of input produces a line of output.} \def\sf{\fam=\sffam \tensf} \let\li = \sf % Sometimes we call it \li, not \sf. +% We don't need math for this one. +\def\ttsl{\tenttsl} + %% Try out Computer Modern fonts at \magstephalf \let\mainmagstep=\magstephalf +% Set the font macro #1 to the font named #2, adding on the +% specified font prefix (normally `cm'). +% #3 is the font's design size, #4 is a scale factor +\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4} + +% Use cm as the default font prefix. +% To specify the font prefix, you must define \fontprefix +% before you read in texinfo.tex. +\ifx\fontprefix\undefined +\def\fontprefix{cm} +\fi +% Support font families that don't use the same naming scheme as CM. +\def\rmshape{r} +\def\rmbshape{bx} %where the normal face is bold +\def\bfshape{b} +\def\bxshape{bx} +\def\ttshape{tt} +\def\ttbshape{tt} +\def\ttslshape{sltt} +\def\itshape{ti} +\def\itbshape{ti} +\def\slshape{sl} +\def\slbshape{sl} +\def\sfshape{ss} +\def\sfbshape{ss} +\def\scshape{csc} +\def\scbshape{csc} + \ifx\bigger\relax \let\mainmagstep=\magstep1 -\font\textrm=cmr12 -\font\texttt=cmtt12 +\setfont\textrm\rmshape{12}{1000} +\setfont\texttt\ttshape{12}{1000} \else -\font\textrm=cmr10 scaled \mainmagstep -\font\texttt=cmtt10 scaled \mainmagstep +\setfont\textrm\rmshape{10}{\mainmagstep} +\setfont\texttt\ttshape{10}{\mainmagstep} \fi % Instead of cmb10, you many want to use cmbx10. % cmbx10 is a prettier font on its own, but cmb10 % looks better when embedded in a line with cmr10. -\font\textbf=cmb10 scaled \mainmagstep -\font\textit=cmti10 scaled \mainmagstep -\font\textsl=cmsl10 scaled \mainmagstep -\font\textsf=cmss10 scaled \mainmagstep -\font\textsc=cmcsc10 scaled \mainmagstep +\setfont\textbf\bfshape{10}{\mainmagstep} +\setfont\textit\itshape{10}{\mainmagstep} +\setfont\textsl\slshape{10}{\mainmagstep} +\setfont\textsf\sfshape{10}{\mainmagstep} +\setfont\textsc\scshape{10}{\mainmagstep} +\setfont\textttsl\ttslshape{10}{\mainmagstep} \font\texti=cmmi10 scaled \mainmagstep \font\textsy=cmsy10 scaled \mainmagstep % A few fonts for @defun, etc. -\font\defbf=cmbx10 scaled \magstep1 %was 1314 -\font\deftt=cmtt10 scaled \magstep1 +\setfont\defbf\bxshape{10}{\magstep1} %was 1314 +\setfont\deftt\ttshape{10}{\magstep1} \def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf} % Fonts for indices and small examples. @@ -906,66 +1033,70 @@ where each line of input produces a line of output.} % because texinfo normally uses the slanted fonts for that. % Do not make many font distinctions in general in the index, since they % aren't very useful. -\font\ninett=cmtt9 -\font\indrm=cmr9 -\font\indit=cmsl9 +\setfont\ninett\ttshape{9}{1000} +\setfont\indrm\rmshape{9}{1000} +\setfont\indit\slshape{9}{1000} \let\indsl=\indit \let\indtt=\ninett +\let\indttsl=\ninett \let\indsf=\indrm \let\indbf=\indrm -\let\indsc=\indrm +\setfont\indsc\scshape{10}{900} \font\indi=cmmi9 \font\indsy=cmsy9 % Fonts for headings -\font\chaprm=cmbx12 scaled \magstep2 -\font\chapit=cmti12 scaled \magstep2 -\font\chapsl=cmsl12 scaled \magstep2 -\font\chaptt=cmtt12 scaled \magstep2 -\font\chapsf=cmss12 scaled \magstep2 +\setfont\chaprm\rmbshape{12}{\magstep2} +\setfont\chapit\itbshape{10}{\magstep3} +\setfont\chapsl\slbshape{10}{\magstep3} +\setfont\chaptt\ttbshape{12}{\magstep2} +\setfont\chapttsl\ttslshape{10}{\magstep3} +\setfont\chapsf\sfbshape{12}{\magstep2} \let\chapbf=\chaprm -\font\chapsc=cmcsc10 scaled\magstep3 +\setfont\chapsc\scbshape{10}{\magstep3} \font\chapi=cmmi12 scaled \magstep2 \font\chapsy=cmsy10 scaled \magstep3 -\font\secrm=cmbx12 scaled \magstep1 -\font\secit=cmti12 scaled \magstep1 -\font\secsl=cmsl12 scaled \magstep1 -\font\sectt=cmtt12 scaled \magstep1 -\font\secsf=cmss12 scaled \magstep1 -\font\secbf=cmbx12 scaled \magstep1 -\font\secsc=cmcsc10 scaled\magstep2 +\setfont\secrm\rmbshape{12}{\magstep1} +\setfont\secit\itbshape{10}{\magstep2} +\setfont\secsl\slbshape{10}{\magstep2} +\setfont\sectt\ttbshape{12}{\magstep1} +\setfont\secttsl\ttslshape{10}{\magstep2} +\setfont\secsf\sfbshape{12}{\magstep1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep2} \font\seci=cmmi12 scaled \magstep1 \font\secsy=cmsy10 scaled \magstep2 -% \font\ssecrm=cmbx10 scaled \magstep1 % This size an font looked bad. -% \font\ssecit=cmti10 scaled \magstep1 % The letters were too crowded. -% \font\ssecsl=cmsl10 scaled \magstep1 -% \font\ssectt=cmtt10 scaled \magstep1 -% \font\ssecsf=cmss10 scaled \magstep1 +% \setfont\ssecrm\bxshape{10}{\magstep1} % This size an font looked bad. +% \setfont\ssecit\itshape{10}{\magstep1} % The letters were too crowded. +% \setfont\ssecsl\slshape{10}{\magstep1} +% \setfont\ssectt\ttshape{10}{\magstep1} +% \setfont\ssecsf\sfshape{10}{\magstep1} -%\font\ssecrm=cmb10 scaled 1315 % Note the use of cmb rather than cmbx. -%\font\ssecit=cmti10 scaled 1315 % Also, the size is a little larger than -%\font\ssecsl=cmsl10 scaled 1315 % being scaled magstep1. -%\font\ssectt=cmtt10 scaled 1315 -%\font\ssecsf=cmss10 scaled 1315 +%\setfont\ssecrm\bfshape{10}{1315} % Note the use of cmb rather than cmbx. +%\setfont\ssecit\itshape{10}{1315} % Also, the size is a little larger than +%\setfont\ssecsl\slshape{10}{1315} % being scaled magstep1. +%\setfont\ssectt\ttshape{10}{1315} +%\setfont\ssecsf\sfshape{10}{1315} %\let\ssecbf=\ssecrm -\font\ssecrm=cmbx12 scaled \magstephalf -\font\ssecit=cmti12 scaled \magstephalf -\font\ssecsl=cmsl12 scaled \magstephalf -\font\ssectt=cmtt12 scaled \magstephalf -\font\ssecsf=cmss12 scaled \magstephalf -\font\ssecbf=cmbx12 scaled \magstephalf -\font\ssecsc=cmcsc10 scaled \magstep1 +\setfont\ssecrm\rmbshape{12}{\magstephalf} +\setfont\ssecit\itbshape{10}{1315} +\setfont\ssecsl\slbshape{10}{1315} +\setfont\ssectt\ttbshape{12}{\magstephalf} +\setfont\ssecttsl\ttslshape{10}{\magstep1} +\setfont\ssecsf\sfbshape{12}{\magstephalf} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{\magstep1} \font\sseci=cmmi12 scaled \magstephalf \font\ssecsy=cmsy10 scaled \magstep1 % The smallcaps and symbol fonts should actually be scaled \magstep1.5, % but that is not a standard magnification. % Fonts for title page: -\font\titlerm = cmbx12 scaled \magstep3 +\setfont\titlerm\rmbshape{12}{\magstep3} \let\authorrm = \secrm % In order for the font changes to affect most math symbols and letters, @@ -984,33 +1115,33 @@ where each line of input produces a line of output.} % The font-changing commands redefine the meanings of \tenSTYLE, instead % of just \STYLE. We do this so that font changes will continue to work % in math mode, where it is the current \fam that is relevant in most -% cases, not the current. Plain TeX does, for example, -% \def\bf{\fam=\bffam \tenbf} By redefining \tenbf, we obviate the need -% to redefine \bf itself. +% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam +% \tenbf}, for example. By redefining \tenbf, we obviate the need to +% redefine \bf itself. \def\textfonts{% \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc - \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy + \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl \resetmathfonts} \def\chapfonts{% \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc - \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy + \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl \resetmathfonts} \def\secfonts{% \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc - \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy + \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl \resetmathfonts} \def\subsecfonts{% \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc - \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy + \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl \resetmathfonts} \def\indexfonts{% \let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl \let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc - \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy + \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy \let\tenttsl=\indttsl \resetmathfonts} % Set up the default fonts, so we can use them for creating boxes. @@ -1021,9 +1152,9 @@ where each line of input produces a line of output.} \newcount\fontdepth \fontdepth=0 % Fonts for short table of contents. -\font\shortcontrm=cmr12 -\font\shortcontbf=cmbx12 -\font\shortcontsl=cmsl12 +\setfont\shortcontrm\rmshape{12}{1000} +\setfont\shortcontbf\bxshape{12}{1000} +\setfont\shortcontsl\slshape{12}{1000} %% Add scribe-like font environments, plus @l for inline lisp (usually sans %% serif) and @ii for TeX italic @@ -1050,16 +1181,16 @@ where each line of input produces a line of output.} \def\restorehyphenation{\hyphenchar\font = `- } \def\t#1{% - {\tt \nohyphenation \rawbackslash \frenchspacing #1}% + {\tt \rawbackslash \frenchspacing #1}% \null } -\let\ttfont = \t -%\def\samp #1{`{\tt \rawbackslash \frenchspacing #1}'\null} +\let\ttfont=\t \def\samp #1{`\tclose{#1}'\null} -\def\key #1{{\tt \nohyphenation \uppercase{#1}}\null} +\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null} \def\ctrl #1{{\tt \rawbackslash \hat}#1} \let\file=\samp +\let\url=\samp % perhaps include a hypertex \special eventually % @code is a modification of @t, % which makes spaces the same size as normal in the surrounding text. @@ -1085,7 +1216,7 @@ where each line of input produces a line of output.} } % We *must* turn on hyphenation at `-' and `_' in \code. -% Otherwise, it is too hard to avoid overful hboxes +% Otherwise, it is too hard to avoid overfull hboxes % in the Emacs manual, the Library manual, etc. % Unfortunately, TeX uses one parameter (\hyphenchar) to control @@ -1103,6 +1234,7 @@ where each line of input produces a line of output.} % ever called. -- mycroft \global\def\indexbreaks{\catcode`\-=\active \let-\realdash \catcode`\_=\active \let_\realunder} } + \def\realdash{-} \def\realunder{_} \def\codedash{-\discretionary{}{}{}} @@ -1113,12 +1245,19 @@ where each line of input produces a line of output.} % @kbd is like @code, except that if the argument is just one @key command, % then @kbd has no effect. - +% \def\xkey{\key} \def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% \ifx\one\xkey\ifx\threex\three \key{#2}% -\else\tclose{\look}\fi -\else\tclose{\look}\fi} +\else{\tclose{\ttsl\look}}\fi +\else{\tclose{\ttsl\look}}\fi} + +% Check if we are currently using a typewriter font. Since all the +% Computer Modern typewriter fonts have zero interword stretch (and +% shrink), and it is reasonable to expect all typewriter fonts to have +% this property, we can check that font parameter. +% +\def\ifmonospace{\ifdim\fontdimen3\font=0pt } % Typeset a dimension, e.g., `in' or `pt'. The only reason for the % argument is to make the input look right: @dmn{pt} instead of @@ -1383,7 +1522,7 @@ July\or August\or September\or October\or November\or December\fi \newif\ifitemxneedsnegativevskip -\def\itemxpar{\par\ifitemxneedsnegativevskip\vskip-\parskip\nobreak\fi} +\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} \def\internalBitem{\smallbreak \parsearg\itemzzz} \def\internalBitemx{\itemxpar \parsearg\itemzzz} @@ -1490,7 +1629,7 @@ July\or August\or September\or October\or November\or December\fi \def\tablez #1#2#3#4#5#6{% \aboveenvbreak % \begingroup % -\def\Edescription{\Etable}% Neccessary kludge. +\def\Edescription{\Etable}% Necessary kludge. \let\itemindex=#1% \ifnum 0#3>0 \advance \leftskip by #3\mil \fi % \ifnum 0#4>0 \tableindent=#4\mil \fi % @@ -1653,6 +1792,207 @@ July\or August\or September\or October\or November\or December\fi \vadjust{\penalty 1200}}% \flushcr} +% @multitable macros +% Amy Hendrickson, 8/18/94, 3/6/96 +% +% @multitable ... @end multitable will make as many columns as desired. +% Contents of each column will wrap at width given in preamble. Width +% can be specified either with sample text given in a template line, +% or in percent of \hsize, the current width of text on page. + +% Table can continue over pages but will only break between lines. + +% To make preamble: +% +% Either define widths of columns in terms of percent of \hsize: +% @multitable @columnfractions .25 .3 .45 +% @item ... +% +% Numbers following @columnfractions are the percent of the total +% current hsize to be used for each column. You may use as many +% columns as desired. + +% Or use a template: +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item ... +% using the widest term desired in each column. +% +% For those who want to use more than one line's worth of words in +% the preamble, break the line within one argument and it +% will parse correctly, i.e., +% +% @multitable {Column 1 template} {Column 2 template} {Column 3 +% template} +% Not: +% @multitable {Column 1 template} {Column 2 template} +% {Column 3 template} + +% Each new table line starts with @item, each subsequent new column +% starts with @tab. Empty columns may be produced by supplying @tab's +% with nothing between them for as many times as empty columns are needed, +% ie, @tab@tab@tab will produce two empty columns. + +% @item, @tab, @multicolumn or @endmulticolumn do not need to be on their +% own lines, but it will not hurt if they are. + +% Sample multitable: + +% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +% @item first col stuff @tab second col stuff @tab third col +% @item +% first col stuff +% @tab +% second col stuff +% @tab +% third col +% @item first col stuff @tab second col stuff +% @tab Many paragraphs of text may be used in any column. +% +% They will wrap at the width determined by the template. +% @item@tab@tab This will be in third column. +% @end multitable + +% Default dimensions may be reset by user. +% @multitableparskip is vertical space between paragraphs in table. +% @multitableparindent is paragraph indent in table. +% @multitablecolmargin is horizontal space to be left between columns. +% @multitablelinespace is space to leave between table items, baseline +% to baseline. +% 0pt means it depends on current normal line spacing. + +%%%% +% Dimensions + +\newskip\multitableparskip +\newskip\multitableparindent +\newdimen\multitablecolspace +\newskip\multitablelinespace +\multitableparskip=0pt +\multitableparindent=6pt +\multitablecolspace=12pt +\multitablelinespace=0pt + +%%%% +% Macros used to set up halign preamble: +\let\endsetuptable\relax +\def\xendsetuptable{\endsetuptable} +\let\columnfractions\relax +\def\xcolumnfractions{\columnfractions} +\newif\ifsetpercent + +%% 2/1/96, to allow fractions to be given with more than one digit. +\def\pickupwholefraction#1 {\global\advance\colcount by1 % +\expandafter\xdef\csname col\the\colcount\endcsname{.#1\hsize}% +\setuptable} + +\newcount\colcount +\def\setuptable#1{\def\firstarg{#1}% +\ifx\firstarg\xendsetuptable\let\go\relax% +\else + \ifx\firstarg\xcolumnfractions\global\setpercenttrue% + \else + \ifsetpercent + \let\go\pickupwholefraction % In this case arg of setuptable + % is the decimal point before the + % number given in percent of hsize. + % We don't need this so we don't use it. + \else + \global\advance\colcount by1 + \setbox0=\hbox{#1}% + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi% + \fi% +\ifx\go\pickupwholefraction\else\let\go\setuptable\fi% +\fi\go} + +%%%% +% multitable syntax +\def\tab{&\hskip1sp\relax} % 2/2/96 + % tiny skip here makes sure this column space is + % maintained, even if it is never used. + + +%%%% +% @multitable ... @end multitable definitions: + +\def\multitable{\parsearg\dotable} + +\def\dotable#1{\bgroup +\let\item\cr +\tolerance=9500 +\hbadness=9500 +\setmultitablespacing +\parskip=\multitableparskip +\parindent=\multitableparindent +\overfullrule=0pt +\global\colcount=0\relax% +\def\Emultitable{\global\setpercentfalse\global\everycr{}\cr\egroup\egroup}% + % To parse everything between @multitable and @item : +\setuptable#1 \endsetuptable + % Need to reset this to 0 after \setuptable. +\global\colcount=0\relax% + % + % This preamble sets up a generic column definition, which will + % be used as many times as user calls for columns. + % \vtop will set a single line and will also let text wrap and + % continue for many paragraphs if desired. +\halign\bgroup&\global\advance\colcount by 1\relax% +\multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % If user has set preamble in terms of percent of \hsize + % we will use that dimension as the width of the column, and + % the \leftskip will keep entries from bumping into each other. + % Table will start at left margin and final column will justify at + % right margin. +\ifnum\colcount=1 +\else + \ifsetpercent + \else + % If user has set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: +\leftskip=\multitablecolspace +\fi +\noindent##}\cr% + % \everycr will reset column counter, \colcount, at the end of + % each line. Every column entry will cause \colcount to advance by one. + % The table preamble + % looks at the current \colcount to find the correct column width. +\global\everycr{\noalign{% +\filbreak%% keeps underfull box messages off when table breaks over pages. +\global\colcount=0\relax}} +} + +\def\setmultitablespacing{% test to see if user has set \multitablelinespace. +% If so, do nothing. If not, give it an appropriate dimension based on +% current baselineskip. +\setbox0=\vbox{Xy} +\ifdim\multitablelinespace=0pt +%% strut to put in table in case some entry doesn't have descenders, +%% to keep lines equally spaced +\gdef\multistrut{\vrule height\ht0 depth\dp0 width0pt\relax} +%% Test to see if parskip is larger than space between lines of +%% table. If not, do nothing. +%% If so, set to same dimension as multitablelinespace. +\else +\gdef\multistrut{\vrule height\multitablelinespace depth\dp0 +width0pt\relax} \fi +\ifdim\multitableparskip>\multitablelinespace +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi% +\ifdim\multitableparskip=0pt +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller + %% than skip between lines in the table. +\fi} \message{indexing,} % Index generation facilities @@ -1781,8 +2121,15 @@ July\or August\or September\or October\or November\or December\fi \def\kbd##1{\realbackslash kbd {##1}}% \def\dfn##1{\realbackslash dfn {##1}}% \def\emph##1{\realbackslash emph {##1}}% +\unsepspaces } +% If an index command is used in an @example environment, any spaces +% therein should become regular spaces in the raw index file, not the +% expansion of \tie (\\leavevmode \penalty \@M \ ). +{\obeyspaces + \gdef\unsepspaces{\obeyspaces\let =\space}} + % \indexnofonts no-ops all font-change commands. % This is used when outputting the strings to sort the index by. \def\indexdummyfont#1{#1} @@ -1804,17 +2151,17 @@ July\or August\or September\or October\or November\or December\fi \let\v=\indexdummyfont \let\H=\indexdummyfont % Take care of the plain tex special European modified letters. -\def\oe{oe} -\def\ae{ae} -\def\aa{aa} -\def\OE{OE} -\def\AE{AE} -\def\AA{AA} -\def\o{o} -\def\O{O} -\def\l{l} -\def\L{L} -\def\ss{ss} +\def\oe{oe}% +\def\ae{ae}% +\def\aa{aa}% +\def\OE{OE}% +\def\AE{AE}% +\def\AA{AA}% +\def\o{o}% +\def\O{O}% +\def\l{l}% +\def\L{L}% +\def\ss{ss}% \let\w=\indexdummyfont \let\t=\indexdummyfont \let\r=\indexdummyfont @@ -1847,7 +2194,14 @@ July\or August\or September\or October\or November\or December\fi \let\indexbackslash=0 %overridden during \printindex. +\let\SETmarginindex=\relax %initialize! +% workhorse for all \fooindexes +% #1 is name of index, #2 is stuff to put there \def\doind #1#2{% +% Put the index entry in the margin if desired. +\ifx\SETmarginindex\relax\else% +\insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}% +\fi% {\count10=\lastpenalty % {\indexdummies % Must do this here, since \bf, etc expand at this stage \escapechar=`\\% @@ -2026,7 +2380,7 @@ July\or August\or September\or October\or November\or December\fi % % Insert the text of the index entry. TeX will do line-breaking on it. #1% - % The following is kluged to not output a line of dots in the index if + % The following is kludged to not output a line of dots in the index if % there are no page numbers. The next person who breaks this will be % cursed by a Unix daemon. \def\tempa{{\rm }}% @@ -2283,7 +2637,7 @@ July\or August\or September\or October\or November\or December\fi \def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz \def\chapterzzz #1{\seccheck{chapter}% \secno=0 \subsecno=0 \subsubsecno=0 -\global\advance \chapno by 1 \message{Chapter \the\chapno}% +\global\advance \chapno by 1 \message{\putwordChapter \the\chapno}% \chapmacro {#1}{\the\chapno}% \gdef\thissection{#1}% \gdef\thischaptername{#1}% @@ -2320,6 +2674,10 @@ July\or August\or September\or October\or November\or December\fi \global\let\subsubsection = \appendixsubsubsec }} +% @centerchap is like @unnumbered, but the heading is centered. +\outer\def\centerchap{\parsearg\centerchapyyy} +\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}} + \outer\def\top{\parsearg\unnumberedyyy} \outer\def\unnumbered{\parsearg\unnumberedyyy} \def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz @@ -2364,7 +2722,7 @@ July\or August\or September\or October\or November\or December\fi \penalty 10000 % }} -\outer\def\appenixsection{\parsearg\appendixsecyyy} +\outer\def\appendixsection{\parsearg\appendixsecyyy} \outer\def\appendixsec{\parsearg\appendixsecyyy} \def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz \def\appendixsectionzzz #1{\seccheck{appendixsection}% @@ -2570,7 +2928,8 @@ July\or August\or September\or October\or November\or December\fi \def\CHAPFplain{ \global\let\chapmacro=\chfplain -\global\let\unnumbchapmacro=\unnchfplain} +\global\let\unnumbchapmacro=\unnchfplain +\global\let\centerchapmacro=\centerchfplain} \def\chfplain #1#2{% \pchapsepmacro @@ -2589,6 +2948,14 @@ July\or August\or September\or October\or November\or December\fi \parindent=0pt\raggedright \rm #1\hfill}}\bigskip \par\penalty 10000 % } + +\def\centerchfplain #1{% +\pchapsepmacro % +{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt + {\rm #1}\hfill}}\bigskip \par\penalty 10000 % +} + \CHAPFplain % The default \def\unnchfopen #1{% @@ -2602,9 +2969,16 @@ July\or August\or September\or October\or November\or December\fi \par\penalty 5000 % } +\def\centerchfopen #1{% +\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 + \parindent=0pt + \hfill {\rm #1}\hfill}}\bigskip \par\penalty 10000 % +} + \def\CHAPFopen{ \global\let\chapmacro=\chfopen -\global\let\unnumbchapmacro=\unnchfopen} +\global\let\unnumbchapmacro=\unnchfopen +\global\let\centerchapmacro=\centerchfopen} % Parameter controlling skip before section headings. @@ -2670,6 +3044,7 @@ July\or August\or September\or October\or November\or December\fi \unnumbchapmacro{#1}\def\thischapter{}% \begingroup % Set up to handle contents files properly. \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11 + \catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi \raggedbottom % Worry more about breakpoints than the bottom. \advance\hsize by -\contentsrightmargin % Don't use the full line length. } @@ -2795,9 +3170,10 @@ July\or August\or September\or October\or November\or December\fi % can't do that in the \entry macro, since index entries might consist % of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.) % +% \turnoffactive is for the sake of @" used for umlauts. \def\tocentry#1#2{\begingroup \hyphenpenalty = 10000 - \entry{#1}{#2}% + \entry{\turnoffactive #1}{\turnoffactive #2}% \endgroup} % Space between chapter (or whatever) number and the title. @@ -2878,11 +3254,14 @@ July\or August\or September\or October\or November\or December\fi \catcode`\>=12 \escapechar=`\\ % +\let\~=\ptextilde \let\{=\ptexlbrace \let\}=\ptexrbrace \let\.=\ptexdot \let\*=\ptexstar \let\dots=\ptexdots +\def\endldots{\mathinner{\ldots\ldots\ldots\ldots}} +\def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi} \def\@{@}% \let\bullet=\ptexbullet \let\b=\ptexb \let\c=\ptexc \let\i=\ptexi \let\t=\ptext \let\l=\ptexl @@ -3052,9 +3431,9 @@ July\or August\or September\or October\or November\or December\fi \let\Esmallexample = \nonfillfinish % % Smaller interline space and fonts for small examples. - \baselineskip 10pt + \setleading{10pt}% \indexfonts \tt - \rawbackslash % output the \ character from the current font + \rawbackslash % make \ output the \ character from the current font (tt) \gobble } @@ -3090,23 +3469,26 @@ July\or August\or September\or October\or November\or December\fi \advance\leftskip by 0pt plus 1fill \gobble} -% @quotation does normal linebreaking and narrows the margins. +% @quotation does normal linebreaking (hence we can't use \nonfillstart) +% and narrows the margins. % \def\quotation{% -\begingroup\inENV %This group ends at the end of the @quotation body -{\parskip=0pt % because we will skip by \parskip too, later -\aboveenvbreak}% -\singlespace -\parindent=0pt -\let\Equotation = \nonfillfinish -% @cartouche defines \nonarrowing to inhibit narrowing -% at next level down. -\ifx\nonarrowing\relax -\advance \leftskip by \lispnarrowing -\advance \rightskip by \lispnarrowing -\exdentamount=\lispnarrowing -\let\nonarrowing=\relax -\fi} + \begingroup\inENV %This group ends at the end of the @quotation body + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \singlespace + \parindent=0pt + % We have retained a nonzero parskip for the environment, since we're + % doing normal filling. So to avoid extra space below the environment... + \def\Equotation{\parskip = 0pt \nonfillfinish}% + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \advance\rightskip by \lispnarrowing + \exdentamount = \lispnarrowing + \let\nonarrowing = \relax + \fi +} \message{defuns,} % Define formatter for defuns @@ -3138,6 +3520,9 @@ July\or August\or September\or October\or November\or December\fi \gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 } \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} +% This is used to turn on special parens +% but make & act ordinary (given that it's active). +\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr} % Definitions of (, ) and & used in args for functions. % This is the definition of ( outside of all parentheses. @@ -3346,7 +3731,8 @@ July\or August\or September\or October\or November\or December\fi \def\deftypefunargs #1{% % Expand, preventing hyphenation at `-' chars. % Note that groups don't affect changes in \hyphenchar. -\functionparens +% Use \boldbraxnoamp, not \functionparens, so that & is not special. +\boldbraxnoamp \tclose{#1}% avoid \code because of side effects on active chars \interlinepenalty=10000 \advance\rightskip by 0pt plus 1fil @@ -3383,7 +3769,7 @@ July\or August\or September\or October\or November\or December\fi % #1 is the data type, #2 the name, #3 the args. \def\deftypefunheaderx #1#2 #3\relax{% \doind {fn}{\code{#2}}% Make entry in function index -\begingroup\defname {\code{#1} #2}{Function}% +\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Function}% \deftypefunargs {#3}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } @@ -3392,6 +3778,10 @@ July\or August\or September\or October\or November\or December\fi \def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader} +% \defheaderxcond#1\relax$$$ +% puts #1 in @code, followed by a space, but does nothing if #1 is null. +\def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi} + % #1 is the classification. #2 is the data type. #3 is the name and args. \def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax} % #1 is the classification, #2 the data type, #3 the name, #4 the args. @@ -3400,7 +3790,7 @@ July\or August\or September\or October\or November\or December\fi \begingroup \normalparens % notably, turn off `&' magic, which prevents % at least some C++ text from working -\defname {\code{#2} #3}{#1}% +\defname {\defheaderxcond#2\relax$$$#3}{#1}% \deftypefunargs {#4}\endgroup % \catcode 61=\other % Turn off change made in \defparsebody } @@ -3528,7 +3918,7 @@ July\or August\or September\or October\or November\or December\fi % #1 is the data type. #2 is the name. \def\deftypevarheader #1#2{% \doind {vr}{\code{#2}}% Make entry in variables index -\begingroup\defname {\code{#1} #2}{Variable}% +\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Variable}% \interlinepenalty=10000 \endgraf\penalty 10000\vskip -\parskip\penalty 10000 \endgroup} @@ -3538,7 +3928,7 @@ July\or August\or September\or October\or November\or December\fi \def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader} \def\deftypevrheader #1#2#3{\doind {vr}{\code{#3}}% -\begingroup\defname {\code{#2} #3}{#1} +\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1} \interlinepenalty=10000 \endgraf\penalty 10000\vskip -\parskip\penalty 10000 \endgroup} @@ -3602,51 +3992,59 @@ July\or August\or September\or October\or November\or December\fi \def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} \def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} \def\ref#1{\xrefX[#1,,,,,,,]} -\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup% -\def\printedmanual{\ignorespaces #5}% -\def\printednodename{\ignorespaces #3}% -% -\setbox1=\hbox{\printedmanual}% -\setbox0=\hbox{\printednodename}% -\ifdim \wd0=0pt% -% No printed node name was explicitly given. -\ifx SETxref-automatic-section-title % -% This line should make the actual chapter or section title appear inside -% the square brackets. Use the real section title if we have it. -\ifdim \wd1>0pt% -% It is in another manual, so we don't have it. -\def\printednodename{\ignorespaces #1} \else% -% We know the real title if we have the xref values. -\ifhavexrefs \def\printednodename{\refx{#1-title}}% -% Otherwise just copy the Info node name. -\else \def\printednodename{\ignorespaces #1} \fi% -\fi\def\printednodename{#1-title}% -\else% This line just uses the node name. -\def\printednodename{\ignorespaces #1}% -\fi% ends \ifx SETxref-automatic-section-title -\fi% ends \ifdim \wd0 -% -% -% If we use \unhbox0 and \unhbox1 to print the node names, TeX does -% not insert empty discretionaries after hyphens, which means that it -% will not find a line break at a hyphen in a node names. Since some -% manuals are best written with fairly long node names, containing -% hyphens, this is a loss. Therefore, we simply give the text of -% the node name again, so it is as if TeX is seeing it for the first -% time. -\ifdim \wd1>0pt -\putwordsection{} ``\printednodename'' in \cite{\printedmanual}% -\else% -\turnoffactive% -\refx{#1-snt}{} [\printednodename], \putwordpage\tie\refx{#1-pg}{}% -\fi +\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \def\printedmanual{\ignorespaces #5}% + \def\printednodename{\ignorespaces #3}% + \setbox1=\hbox{\printedmanual}% + \setbox0=\hbox{\printednodename}% + \ifdim \wd0 = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax + % Use the node name inside the square brackets. + \def\printednodename{\ignorespaces #1}% + \else + % Use the actual chapter/section title appear inside + % the square brackets. Use the real section title if we have it. + \ifdim \wd1>0pt% + % It is in another manual, so we don't have it. + \def\printednodename{\ignorespaces #1}% + \else + \ifhavexrefs + % We know the real title if we have the xref values. + \def\printednodename{\refx{#1-title}{}}% + \else + % Otherwise just copy the Info node name. + \def\printednodename{\ignorespaces #1}% + \fi% + \fi + \fi + \fi + % + % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not + % insert empty discretionaries after hyphens, which means that it will + % not find a line break at a hyphen in a node names. Since some manuals + % are best written with fairly long node names, containing hyphens, this + % is a loss. Therefore, we give the text of the node name again, so it + % is as if TeX is seeing it for the first time. + \ifdim \wd1 > 0pt + \putwordsection{} ``\printednodename'' in \cite{\printedmanual}% + \else + % _ (for example) has to be the character _ for the purposes of the + % control sequence corresponding to the node, but it has to expand + % into the usual \leavevmode...\vrule stuff for purposes of + % printing. So we \turnoffactive for the \refx-snt, back on for the + % printing, back off for the \refx-pg. + {\turnoffactive \refx{#1-snt}{}}% + \space [\printednodename],\space + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + \fi \endgroup} % \dosetq is the interface for calls from other macros % Use \turnoffactive so that punctuation chars such as underscore % work in node names. -\def\dosetq #1#2{{\let\folio=0 \turnoffactive% +\def\dosetq #1#2{{\let\folio=0 \turnoffactive \auxhat% \edef\next{\write\auxfile{\internalsetq {#1}{#2}}}% \next}} @@ -3767,6 +4165,15 @@ July\or August\or September\or October\or November\or December\fi \catcode `\&=\other % `\+ does not work, so use 43. \catcode 43=\other +% Make the characters 128-255 be printing characters +{% + \count 1=128 + \def\loop{% + \catcode\count 1=\other + \advance\count 1 by 1 + \ifnum \count 1<256 \loop \fi + }% +}% % the aux file uses ' as the escape. % Turn off \ as an escape so we do not lose on % entries which were dumped with control sequences in their names. @@ -3776,6 +4183,7 @@ July\or August\or September\or October\or November\or December\fi \catcode `\{=1 \catcode `\}=2 \catcode `\%=\other \catcode `\'=0 +\catcode`\^=7 % to make ^^e4 etc usable in xref tags \catcode `\\=\other \openin 1 \jobname.aux \ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue @@ -3962,6 +4370,8 @@ July\or August\or September\or October\or November\or December\fi \global\tolerance=700 \global\hfuzz=1pt \global\contentsrightmargin=0pt +\global\deftypemargin=0pt +\global\defbodyindent=.5cm \global\pagewidth=\hsize \global\pageheight=\vsize @@ -3991,6 +4401,41 @@ July\or August\or September\or October\or November\or December\fi \global\pageheight=\vsize } +% Allow control of the text dimensions. Parameters in order: textheight; +% textwidth; voffset; hoffset; binding offset; topskip. +% All require a dimension; +% header is additional; added length extends the bottom of the page. + +\def\changepagesizes#1#2#3#4#5#6{ + \global\vsize= #1 + \global\topskip= #6 + \advance\vsize by \topskip + \global\voffset= #3 + \global\hsize= #2 + \global\outerhsize=\hsize + \global\advance\outerhsize by 0.5in + \global\outervsize=\vsize + \global\advance\outervsize by 0.6in + \global\pagewidth=\hsize + \global\pageheight=\vsize + \global\normaloffset= #4 + \global\bindingoffset= #5} + +% A specific text layout, 24x15cm overall, intended for A4 paper. Top margin +% 29mm, hence bottom margin 28mm, nominal side margin 3cm. +\def\afourlatex + {\global\tolerance=700 + \global\hfuzz=1pt + \setleading{12pt} + \global\parskip 15pt plus 1pt + \advance\baselineskip by 1.6pt + \changepagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm} + } + +% Use @afourwide to print on European A4 paper in wide format. +\def\afourwide{\afourpaper +\changepagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}} + % Define macros to output various characters with catcode for normal text. \catcode`\"=\other \catcode`\~=\other @@ -4032,19 +4477,13 @@ July\or August\or September\or October\or November\or December\fi \def~{{\tt \char '176}} \chardef\hat=`\^ \catcode`\^=\active +\def\auxhat{\def^{'hat}} \def^{{\tt \hat}} \catcode`\_=\active \def_{\ifusingtt\normalunderscore\_} % Subroutine for the previous macro. -\def\_{\lvvmode \kern.06em \vbox{\hrule width.3em height.1ex}} - -% \lvvmode is equivalent in function to \leavevmode. -% Using \leavevmode runs into trouble when written out to -% an index file due to the expansion of \leavevmode into ``\unhbox -% \voidb@x'' ---which looks to TeX like ``\unhbox \voidb\x'' due to our -% magic tricks with @. -\def\lvvmode{\vbox to 0pt{}} +\def\_{\leavevmode \kern.06em \vbox{\hrule width.3em height.1ex}} \catcode`\|=\active \def|{{\tt \char '174}} @@ -4059,21 +4498,19 @@ July\or August\or September\or October\or November\or December\fi %\catcode 27=\active %\def^^[{$\diamondsuit$} -% Used sometimes to turn off (effectively) the active characters -% even after parsing them. -\def\turnoffactive{\let"=\normaldoublequote -\let~=\normaltilde -\let^=\normalcaret -\let_=\normalunderscore -\let|=\normalverticalbar -\let<=\normalless -\let>=\normalgreater -\let+=\normalplus} - % Set up an active definition for =, but don't enable it most of the time. {\catcode`\==\active \global\def={{\tt \char 61}}} +\catcode`+=\active +\catcode`\_=\active + +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have \everyjob (or @setfilename) turn them on. +% \otherifyactive is called near the end of this file. +\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} + \catcode`\@=0 % \rawbackslashxx output one backslash character in current font @@ -4094,6 +4531,32 @@ July\or August\or September\or October\or November\or December\fi % \catcode 17=0 % Define control-q \catcode`\\=\active +% Used sometimes to turn off (effectively) the active characters +% even after parsing them. +@def@turnoffactive{@let"=@normaldoublequote +@let\=@realbackslash +@let~=@normaltilde +@let^=@normalcaret +@let_=@normalunderscore +@let|=@normalverticalbar +@let<=@normalless +@let>=@normalgreater +@let+=@normalplus} + +@def@normalturnoffactive{@let"=@normaldoublequote +@let\=@normalbackslash +@let~=@normaltilde +@let^=@normalcaret +@let_=@normalunderscore +@let|=@normalverticalbar +@let<=@normalless +@let>=@normalgreater +@let+=@normalplus} + +% Make _ and + \other characters, temporarily. +% This is canceled by @fixbackslash. +@otherifyactive + % If a .fmt file is being used, we don't want the `\input texinfo' to show up. % That is what \eatinput is for; after that, the `\' should revert to printing % a backslash. @@ -4104,8 +4567,11 @@ July\or August\or September\or October\or November\or December\fi % On the other hand, perhaps the file did not have a `\input texinfo'. Then % the first `\{ in the file would cause an error. This macro tries to fix % that, assuming it is called before the first `\' could plausibly occur. +% Also back turn on active characters that might appear in the input +% file name, in case not using a pre-dumped format. % -@gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi} +@gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi + @catcode`+=@active @catcode`@_=@active} %% These look ok in all fonts, so just make them not special. The @rm below %% makes sure that the current font starts out as the newly loaded cmr10