Home | History | Annotate | Line # | Download | only in bfd
      1       1.1  christos /* BFD semi-generic back-end for a.out binaries.
      2  1.1.1.10  christos    Copyright (C) 1990-2024 Free Software Foundation, Inc.
      3       1.1  christos    Written by Cygnus Support.
      4       1.1  christos 
      5       1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      6       1.1  christos 
      7       1.1  christos    This program is free software; you can redistribute it and/or modify
      8       1.1  christos    it under the terms of the GNU General Public License as published by
      9       1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10       1.1  christos    (at your option) any later version.
     11       1.1  christos 
     12       1.1  christos    This program is distributed in the hope that it will be useful,
     13       1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14       1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15       1.1  christos    GNU General Public License for more details.
     16       1.1  christos 
     17       1.1  christos    You should have received a copy of the GNU General Public License
     18       1.1  christos    along with this program; if not, write to the Free Software
     19       1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20       1.1  christos    MA 02110-1301, USA.  */
     21       1.1  christos 
     22       1.1  christos /*
     23       1.1  christos SECTION
     24       1.1  christos 	a.out backends
     25       1.1  christos 
     26       1.1  christos DESCRIPTION
     27       1.1  christos 
     28       1.1  christos 	BFD supports a number of different flavours of a.out format,
     29       1.1  christos 	though the major differences are only the sizes of the
     30       1.1  christos 	structures on disk, and the shape of the relocation
     31       1.1  christos 	information.
     32       1.1  christos 
     33       1.1  christos 	The support is split into a basic support file @file{aoutx.h}
     34       1.1  christos 	and other files which derive functions from the base. One
     35       1.1  christos 	derivation file is @file{aoutf1.h} (for a.out flavour 1), and
     36   1.1.1.7  christos 	adds to the basic a.out functions support for sun3, sun4, and
     37   1.1.1.7  christos 	386 a.out files, to create a target jump vector for a specific
     38   1.1.1.7  christos 	target.
     39       1.1  christos 
     40       1.1  christos 	This information is further split out into more specific files
     41       1.1  christos 	for each machine, including @file{sunos.c} for sun3 and sun4,
     42   1.1.1.7  christos 	and @file{demo64.c} for a demonstration of a 64 bit a.out format.
     43       1.1  christos 
     44       1.1  christos 	The base file @file{aoutx.h} defines general mechanisms for
     45       1.1  christos 	reading and writing records to and from disk and various
     46       1.1  christos 	other methods which BFD requires. It is included by
     47       1.1  christos 	@file{aout32.c} and @file{aout64.c} to form the names
     48       1.1  christos 	<<aout_32_swap_exec_header_in>>, <<aout_64_swap_exec_header_in>>, etc.
     49       1.1  christos 
     50       1.1  christos 	As an example, this is what goes on to make the back end for a
     51       1.1  christos 	sun4, from @file{aout32.c}:
     52       1.1  christos 
     53       1.1  christos |	#define ARCH_SIZE 32
     54       1.1  christos |	#include "aoutx.h"
     55       1.1  christos 
     56       1.1  christos 	Which exports names:
     57       1.1  christos 
     58       1.1  christos |	...
     59       1.1  christos |	aout_32_canonicalize_reloc
     60       1.1  christos |	aout_32_find_nearest_line
     61       1.1  christos |	aout_32_get_lineno
     62       1.1  christos |	aout_32_get_reloc_upper_bound
     63       1.1  christos |	...
     64       1.1  christos 
     65       1.1  christos 	from @file{sunos.c}:
     66       1.1  christos 
     67       1.1  christos |	#define TARGET_NAME "a.out-sunos-big"
     68   1.1.1.3  christos |	#define VECNAME    sparc_aout_sunos_be_vec
     69       1.1  christos |	#include "aoutf1.h"
     70       1.1  christos 
     71       1.1  christos 	requires all the names from @file{aout32.c}, and produces the jump vector
     72       1.1  christos 
     73   1.1.1.3  christos |	sparc_aout_sunos_be_vec
     74       1.1  christos 
     75       1.1  christos 	The file @file{host-aout.c} is a special case.  It is for a large set
     76       1.1  christos 	of hosts that use ``more or less standard'' a.out files, and
     77       1.1  christos 	for which cross-debugging is not interesting.  It uses the
     78       1.1  christos 	standard 32-bit a.out support routines, but determines the
     79       1.1  christos 	file offsets and addresses of the text, data, and BSS
     80       1.1  christos 	sections, the machine architecture and machine type, and the
     81       1.1  christos 	entry point address, in a host-dependent manner.  Once these
     82       1.1  christos 	values have been determined, generic code is used to handle
     83       1.1  christos 	the  object file.
     84       1.1  christos 
     85       1.1  christos 	When porting it to run on a new system, you must supply:
     86       1.1  christos 
     87       1.1  christos |        HOST_PAGE_SIZE
     88       1.1  christos |        HOST_SEGMENT_SIZE
     89       1.1  christos |        HOST_MACHINE_ARCH       (optional)
     90       1.1  christos |        HOST_MACHINE_MACHINE    (optional)
     91       1.1  christos |        HOST_TEXT_START_ADDR
     92       1.1  christos |        HOST_STACK_END_ADDR
     93       1.1  christos 
     94       1.1  christos 	in the file @file{../include/sys/h-@var{XXX}.h} (for your host).  These
     95       1.1  christos 	values, plus the structures and macros defined in @file{a.out.h} on
     96       1.1  christos 	your host system, will produce a BFD target that will access
     97       1.1  christos 	ordinary a.out files on your host. To configure a new machine
     98       1.1  christos 	to use @file{host-aout.c}, specify:
     99       1.1  christos 
    100       1.1  christos |	TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
    101       1.1  christos |	TDEPFILES= host-aout.o trad-core.o
    102       1.1  christos 
    103   1.1.1.3  christos 	in the @file{config/@var{XXX}.mt} file, and modify @file{configure.ac}
    104       1.1  christos 	to use the
    105       1.1  christos 	@file{@var{XXX}.mt} file (by setting "<<bfd_target=XXX>>") when your
    106       1.1  christos 	configuration is selected.  */
    107       1.1  christos 
    108       1.1  christos /* Some assumptions:
    109       1.1  christos    * Any BFD with D_PAGED set is ZMAGIC, and vice versa.
    110       1.1  christos      Doesn't matter what the setting of WP_TEXT is on output, but it'll
    111       1.1  christos      get set on input.
    112       1.1  christos    * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC.
    113       1.1  christos    * Any BFD with both flags clear is OMAGIC.
    114       1.1  christos    (Just want to make these explicit, so the conditions tested in this
    115       1.1  christos    file make sense if you're more familiar with a.out than with BFD.)  */
    116       1.1  christos 
    117       1.1  christos #define KEEPIT udata.i
    118       1.1  christos 
    119       1.1  christos #include "sysdep.h"
    120   1.1.1.7  christos #include <limits.h>
    121       1.1  christos #include "bfd.h"
    122       1.1  christos #include "safe-ctype.h"
    123       1.1  christos #include "bfdlink.h"
    124       1.1  christos 
    125       1.1  christos #include "libaout.h"
    126       1.1  christos #include "libbfd.h"
    127       1.1  christos #include "aout/aout64.h"
    128       1.1  christos #include "aout/stab_gnu.h"
    129       1.1  christos #include "aout/ar.h"
    130       1.1  christos 
    131   1.1.1.8  christos #ifdef BMAGIC
    132   1.1.1.8  christos #define N_IS_BMAGIC(x) (N_MAGIC (x) == BMAGIC)
    133   1.1.1.8  christos #else
    134   1.1.1.8  christos #define N_IS_BMAGIC(x) (0)
    135   1.1.1.8  christos #endif
    136   1.1.1.8  christos 
    137   1.1.1.8  christos #ifdef QMAGIC
    138   1.1.1.8  christos #define N_SET_QMAGIC(x) N_SET_MAGIC (x, QMAGIC)
    139   1.1.1.8  christos #else
    140   1.1.1.8  christos #define N_SET_QMAGIC(x) do { /**/ } while (0)
    141   1.1.1.8  christos #endif
    142   1.1.1.8  christos 
    143       1.1  christos /*
    144       1.1  christos SUBSECTION
    145       1.1  christos 	Relocations
    146       1.1  christos 
    147       1.1  christos DESCRIPTION
    148       1.1  christos 	The file @file{aoutx.h} provides for both the @emph{standard}
    149       1.1  christos 	and @emph{extended} forms of a.out relocation records.
    150       1.1  christos 
    151   1.1.1.7  christos 	The standard records contain only an address, a symbol index,
    152   1.1.1.7  christos 	and a type field.  The extended records also have a full
    153   1.1.1.7  christos 	integer for an addend.  */
    154       1.1  christos 
    155       1.1  christos #ifndef CTOR_TABLE_RELOC_HOWTO
    156       1.1  christos #define CTOR_TABLE_RELOC_IDX 2
    157       1.1  christos #define CTOR_TABLE_RELOC_HOWTO(BFD)					\
    158       1.1  christos   ((obj_reloc_entry_size (BFD) == RELOC_EXT_SIZE			\
    159       1.1  christos     ? howto_table_ext : howto_table_std)				\
    160       1.1  christos    + CTOR_TABLE_RELOC_IDX)
    161       1.1  christos #endif
    162       1.1  christos 
    163       1.1  christos #ifndef MY_swap_std_reloc_in
    164       1.1  christos #define MY_swap_std_reloc_in NAME (aout, swap_std_reloc_in)
    165       1.1  christos #endif
    166       1.1  christos 
    167       1.1  christos #ifndef MY_swap_ext_reloc_in
    168       1.1  christos #define MY_swap_ext_reloc_in NAME (aout, swap_ext_reloc_in)
    169       1.1  christos #endif
    170       1.1  christos 
    171       1.1  christos #ifndef MY_swap_std_reloc_out
    172       1.1  christos #define MY_swap_std_reloc_out NAME (aout, swap_std_reloc_out)
    173       1.1  christos #endif
    174       1.1  christos 
    175       1.1  christos #ifndef MY_swap_ext_reloc_out
    176       1.1  christos #define MY_swap_ext_reloc_out NAME (aout, swap_ext_reloc_out)
    177       1.1  christos #endif
    178       1.1  christos 
    179       1.1  christos #ifndef MY_final_link_relocate
    180       1.1  christos #define MY_final_link_relocate _bfd_final_link_relocate
    181       1.1  christos #endif
    182       1.1  christos 
    183       1.1  christos #ifndef MY_relocate_contents
    184       1.1  christos #define MY_relocate_contents _bfd_relocate_contents
    185       1.1  christos #endif
    186       1.1  christos 
    187       1.1  christos #define howto_table_ext NAME (aout, ext_howto_table)
    188       1.1  christos #define howto_table_std NAME (aout, std_howto_table)
    189       1.1  christos 
    190       1.1  christos reloc_howto_type howto_table_ext[] =
    191       1.1  christos {
    192   1.1.1.7  christos   /*	 Type	      rs   size bsz  pcrel bitpos ovrf			sf name		 part_inpl readmask setmask pcdone.  */
    193   1.1.1.9  christos   HOWTO (RELOC_8,	0,  1,	8,  false, 0, complain_overflow_bitfield, 0, "8",	    false, 0, 0x000000ff, false),
    194   1.1.1.9  christos   HOWTO (RELOC_16,	0,  2,	16, false, 0, complain_overflow_bitfield, 0, "16",	    false, 0, 0x0000ffff, false),
    195   1.1.1.9  christos   HOWTO (RELOC_32,	0,  4,	32, false, 0, complain_overflow_bitfield, 0, "32",	    false, 0, 0xffffffff, false),
    196   1.1.1.9  christos   HOWTO (RELOC_DISP8,	0,  1,	8,  true,  0, complain_overflow_signed,	  0, "DISP8",	    false, 0, 0x000000ff, false),
    197   1.1.1.9  christos   HOWTO (RELOC_DISP16,	0,  2,	16, true,  0, complain_overflow_signed,	  0, "DISP16",	    false, 0, 0x0000ffff, false),
    198   1.1.1.9  christos   HOWTO (RELOC_DISP32,	0,  4,	32, true,  0, complain_overflow_signed,	  0, "DISP32",	    false, 0, 0xffffffff, false),
    199   1.1.1.9  christos   HOWTO (RELOC_WDISP30, 2,  4,	30, true,  0, complain_overflow_signed,	  0, "WDISP30",	    false, 0, 0x3fffffff, false),
    200   1.1.1.9  christos   HOWTO (RELOC_WDISP22, 2,  4,	22, true,  0, complain_overflow_signed,	  0, "WDISP22",	    false, 0, 0x003fffff, false),
    201   1.1.1.9  christos   HOWTO (RELOC_HI22,   10,  4,	22, false, 0, complain_overflow_bitfield, 0, "HI22",	    false, 0, 0x003fffff, false),
    202   1.1.1.9  christos   HOWTO (RELOC_22,	0,  4,	22, false, 0, complain_overflow_bitfield, 0, "22",	    false, 0, 0x003fffff, false),
    203   1.1.1.9  christos   HOWTO (RELOC_13,	0,  4,	13, false, 0, complain_overflow_bitfield, 0, "13",	    false, 0, 0x00001fff, false),
    204   1.1.1.9  christos   HOWTO (RELOC_LO10,	0,  4,	10, false, 0, complain_overflow_dont,	  0, "LO10",	    false, 0, 0x000003ff, false),
    205   1.1.1.9  christos   HOWTO (RELOC_SFA_BASE,0,  4,	32, false, 0, complain_overflow_bitfield, 0, "SFA_BASE",    false, 0, 0xffffffff, false),
    206   1.1.1.9  christos   HOWTO (RELOC_SFA_OFF13,0, 4,	32, false, 0, complain_overflow_bitfield, 0, "SFA_OFF13",   false, 0, 0xffffffff, false),
    207   1.1.1.9  christos   HOWTO (RELOC_BASE10,	0,  4,	10, false, 0, complain_overflow_dont,	  0, "BASE10",	    false, 0, 0x000003ff, false),
    208   1.1.1.9  christos   HOWTO (RELOC_BASE13,	0,  4,	13, false, 0, complain_overflow_signed,	  0, "BASE13",	    false, 0, 0x00001fff, false),
    209   1.1.1.9  christos   HOWTO (RELOC_BASE22, 10,  4,	22, false, 0, complain_overflow_bitfield, 0, "BASE22",	    false, 0, 0x003fffff, false),
    210   1.1.1.9  christos   HOWTO (RELOC_PC10,	0,  4,	10, true,  0, complain_overflow_dont,	  0, "PC10",	    false, 0, 0x000003ff, true),
    211   1.1.1.9  christos   HOWTO (RELOC_PC22,   10,  4,	22, true,  0, complain_overflow_signed,	  0, "PC22",	    false, 0, 0x003fffff, true),
    212   1.1.1.9  christos   HOWTO (RELOC_JMP_TBL, 2,  4,	30, true,  0, complain_overflow_signed,	  0, "JMP_TBL",	    false, 0, 0x3fffffff, false),
    213   1.1.1.9  christos   HOWTO (RELOC_SEGOFF16,0,  4,	0,  false, 0, complain_overflow_bitfield, 0, "SEGOFF16",    false, 0, 0x00000000, false),
    214   1.1.1.9  christos   HOWTO (RELOC_GLOB_DAT,0,  4,	0,  false, 0, complain_overflow_bitfield, 0, "GLOB_DAT",    false, 0, 0x00000000, false),
    215   1.1.1.9  christos   HOWTO (RELOC_JMP_SLOT,0,  4,	0,  false, 0, complain_overflow_bitfield, 0, "JMP_SLOT",    false, 0, 0x00000000, false),
    216   1.1.1.9  christos   HOWTO (RELOC_RELATIVE,0,  4,	0,  false, 0, complain_overflow_bitfield, 0, "RELATIVE",    false, 0, 0x00000000, false),
    217   1.1.1.9  christos   HOWTO (0,		0,  0,	0,  false, 0, complain_overflow_dont,	  0, "R_SPARC_NONE",false, 0, 0x00000000, true),
    218   1.1.1.9  christos   HOWTO (0,		0,  0,	0,  false, 0, complain_overflow_dont,	  0, "R_SPARC_NONE",false, 0, 0x00000000, true),
    219       1.1  christos #define RELOC_SPARC_REV32 RELOC_WDISP19
    220   1.1.1.9  christos   HOWTO (RELOC_SPARC_REV32, 0, 4, 32, false, 0, complain_overflow_dont,	  0,"R_SPARC_REV32",false, 0, 0xffffffff, false),
    221       1.1  christos };
    222       1.1  christos 
    223       1.1  christos /* Convert standard reloc records to "arelent" format (incl byte swap).  */
    224       1.1  christos 
    225       1.1  christos reloc_howto_type howto_table_std[] =
    226       1.1  christos {
    227   1.1.1.7  christos   /* type	       rs size bsz  pcrel bitpos ovrf			  sf name     part_inpl readmask  setmask    pcdone.  */
    228   1.1.1.9  christos HOWTO ( 0,	       0,  1,	8,  false, 0, complain_overflow_bitfield,0,"8",		true, 0x000000ff,0x000000ff, false),
    229   1.1.1.9  christos HOWTO ( 1,	       0,  2,	16, false, 0, complain_overflow_bitfield,0,"16",	true, 0x0000ffff,0x0000ffff, false),
    230   1.1.1.9  christos HOWTO ( 2,	       0,  4,	32, false, 0, complain_overflow_bitfield,0,"32",	true, 0xffffffff,0xffffffff, false),
    231   1.1.1.9  christos HOWTO ( 3,	       0,  8,	64, false, 0, complain_overflow_bitfield,0,"64",	true, 0xdeaddead,0xdeaddead, false),
    232   1.1.1.9  christos HOWTO ( 4,	       0,  1,	8,  true,  0, complain_overflow_signed,	 0,"DISP8",	true, 0x000000ff,0x000000ff, false),
    233   1.1.1.9  christos HOWTO ( 5,	       0,  2,	16, true,  0, complain_overflow_signed,	 0,"DISP16",	true, 0x0000ffff,0x0000ffff, false),
    234   1.1.1.9  christos HOWTO ( 6,	       0,  4,	32, true,  0, complain_overflow_signed,	 0,"DISP32",	true, 0xffffffff,0xffffffff, false),
    235   1.1.1.9  christos HOWTO ( 7,	       0,  8,	64, true,  0, complain_overflow_signed,	 0,"DISP64",	true, 0xfeedface,0xfeedface, false),
    236   1.1.1.9  christos HOWTO ( 8,	       0,  4,	 0, false, 0, complain_overflow_bitfield,0,"GOT_REL",	false,	       0,0x00000000, false),
    237   1.1.1.9  christos HOWTO ( 9,	       0,  2,	16, false, 0, complain_overflow_bitfield,0,"BASE16",	false,0xffffffff,0xffffffff, false),
    238   1.1.1.9  christos HOWTO (10,	       0,  4,	32, false, 0, complain_overflow_bitfield,0,"BASE32",	false,0xffffffff,0xffffffff, false),
    239       1.1  christos EMPTY_HOWTO (-1),
    240       1.1  christos EMPTY_HOWTO (-1),
    241       1.1  christos EMPTY_HOWTO (-1),
    242       1.1  christos EMPTY_HOWTO (-1),
    243       1.1  christos EMPTY_HOWTO (-1),
    244   1.1.1.9  christos   HOWTO (16,	       0,  4,	 0, false, 0, complain_overflow_bitfield,0,"JMP_TABLE", false,	       0,0x00000000, false),
    245       1.1  christos EMPTY_HOWTO (-1),
    246       1.1  christos EMPTY_HOWTO (-1),
    247       1.1  christos EMPTY_HOWTO (-1),
    248       1.1  christos EMPTY_HOWTO (-1),
    249       1.1  christos EMPTY_HOWTO (-1),
    250       1.1  christos EMPTY_HOWTO (-1),
    251       1.1  christos EMPTY_HOWTO (-1),
    252       1.1  christos EMPTY_HOWTO (-1),
    253       1.1  christos EMPTY_HOWTO (-1),
    254       1.1  christos EMPTY_HOWTO (-1),
    255       1.1  christos EMPTY_HOWTO (-1),
    256       1.1  christos EMPTY_HOWTO (-1),
    257       1.1  christos EMPTY_HOWTO (-1),
    258       1.1  christos EMPTY_HOWTO (-1),
    259       1.1  christos EMPTY_HOWTO (-1),
    260   1.1.1.9  christos   HOWTO (32,	       0,  4,	 0, false, 0, complain_overflow_bitfield,0,"RELATIVE",	false,	       0,0x00000000, false),
    261       1.1  christos EMPTY_HOWTO (-1),
    262       1.1  christos EMPTY_HOWTO (-1),
    263       1.1  christos EMPTY_HOWTO (-1),
    264       1.1  christos EMPTY_HOWTO (-1),
    265       1.1  christos EMPTY_HOWTO (-1),
    266       1.1  christos EMPTY_HOWTO (-1),
    267       1.1  christos EMPTY_HOWTO (-1),
    268   1.1.1.9  christos   HOWTO (40,	       0,  4,	 0, false, 0, complain_overflow_bitfield,0,"BASEREL",	false,	       0,0x00000000, false),
    269       1.1  christos };
    270       1.1  christos 
    271       1.1  christos #define TABLE_SIZE(TABLE)	(sizeof (TABLE) / sizeof (TABLE[0]))
    272       1.1  christos 
    273       1.1  christos reloc_howto_type *
    274       1.1  christos NAME (aout, reloc_type_lookup) (bfd *abfd, bfd_reloc_code_real_type code)
    275       1.1  christos {
    276       1.1  christos #define EXT(i, j)	case i: return & howto_table_ext [j]
    277       1.1  christos #define STD(i, j)	case i: return & howto_table_std [j]
    278       1.1  christos   int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
    279       1.1  christos 
    280       1.1  christos   if (code == BFD_RELOC_CTOR)
    281       1.1  christos     switch (bfd_arch_bits_per_address (abfd))
    282       1.1  christos       {
    283       1.1  christos       case 32:
    284       1.1  christos 	code = BFD_RELOC_32;
    285       1.1  christos 	break;
    286       1.1  christos       case 64:
    287       1.1  christos 	code = BFD_RELOC_64;
    288       1.1  christos 	break;
    289       1.1  christos       }
    290       1.1  christos 
    291       1.1  christos   if (ext)
    292       1.1  christos     switch (code)
    293       1.1  christos       {
    294       1.1  christos 	EXT (BFD_RELOC_8, 0);
    295       1.1  christos 	EXT (BFD_RELOC_16, 1);
    296       1.1  christos 	EXT (BFD_RELOC_32, 2);
    297       1.1  christos 	EXT (BFD_RELOC_HI22, 8);
    298       1.1  christos 	EXT (BFD_RELOC_LO10, 11);
    299       1.1  christos 	EXT (BFD_RELOC_32_PCREL_S2, 6);
    300       1.1  christos 	EXT (BFD_RELOC_SPARC_WDISP22, 7);
    301       1.1  christos 	EXT (BFD_RELOC_SPARC13, 10);
    302       1.1  christos 	EXT (BFD_RELOC_SPARC_GOT10, 14);
    303       1.1  christos 	EXT (BFD_RELOC_SPARC_BASE13, 15);
    304       1.1  christos 	EXT (BFD_RELOC_SPARC_GOT13, 15);
    305       1.1  christos 	EXT (BFD_RELOC_SPARC_GOT22, 16);
    306       1.1  christos 	EXT (BFD_RELOC_SPARC_PC10, 17);
    307       1.1  christos 	EXT (BFD_RELOC_SPARC_PC22, 18);
    308       1.1  christos 	EXT (BFD_RELOC_SPARC_WPLT30, 19);
    309       1.1  christos 	EXT (BFD_RELOC_SPARC_REV32, 26);
    310       1.1  christos       default:
    311       1.1  christos 	return NULL;
    312       1.1  christos       }
    313       1.1  christos   else
    314       1.1  christos     /* std relocs.  */
    315       1.1  christos     switch (code)
    316       1.1  christos       {
    317       1.1  christos 	STD (BFD_RELOC_8, 0);
    318       1.1  christos 	STD (BFD_RELOC_16, 1);
    319       1.1  christos 	STD (BFD_RELOC_32, 2);
    320       1.1  christos 	STD (BFD_RELOC_8_PCREL, 4);
    321       1.1  christos 	STD (BFD_RELOC_16_PCREL, 5);
    322       1.1  christos 	STD (BFD_RELOC_32_PCREL, 6);
    323       1.1  christos 	STD (BFD_RELOC_16_BASEREL, 9);
    324       1.1  christos 	STD (BFD_RELOC_32_BASEREL, 10);
    325       1.1  christos       default:
    326       1.1  christos 	return NULL;
    327       1.1  christos       }
    328       1.1  christos }
    329       1.1  christos 
    330       1.1  christos reloc_howto_type *
    331       1.1  christos NAME (aout, reloc_name_lookup) (bfd *abfd, const char *r_name)
    332       1.1  christos {
    333       1.1  christos   unsigned int i, size;
    334       1.1  christos   reloc_howto_type *howto_table;
    335       1.1  christos 
    336       1.1  christos   if (obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE)
    337       1.1  christos     {
    338       1.1  christos       howto_table = howto_table_ext;
    339       1.1  christos       size = sizeof (howto_table_ext) / sizeof (howto_table_ext[0]);
    340       1.1  christos     }
    341       1.1  christos   else
    342       1.1  christos     {
    343       1.1  christos       howto_table = howto_table_std;
    344       1.1  christos       size = sizeof (howto_table_std) / sizeof (howto_table_std[0]);
    345       1.1  christos     }
    346       1.1  christos 
    347       1.1  christos   for (i = 0; i < size; i++)
    348       1.1  christos     if (howto_table[i].name != NULL
    349       1.1  christos 	&& strcasecmp (howto_table[i].name, r_name) == 0)
    350       1.1  christos       return &howto_table[i];
    351       1.1  christos 
    352       1.1  christos   return NULL;
    353       1.1  christos }
    354       1.1  christos 
    355       1.1  christos /*
    356       1.1  christos SUBSECTION
    357       1.1  christos 	Internal entry points
    358       1.1  christos 
    359       1.1  christos DESCRIPTION
    360       1.1  christos 	@file{aoutx.h} exports several routines for accessing the
    361       1.1  christos 	contents of an a.out file, which are gathered and exported in
    362       1.1  christos 	turn by various format specific files (eg sunos.c).
    363       1.1  christos */
    364       1.1  christos 
    365       1.1  christos /*
    366       1.1  christos FUNCTION
    367       1.1  christos 	 aout_@var{size}_swap_exec_header_in
    368       1.1  christos 
    369       1.1  christos SYNOPSIS
    370       1.1  christos 	void aout_@var{size}_swap_exec_header_in,
    371   1.1.1.7  christos 	   (bfd *abfd,
    372   1.1.1.7  christos 	    struct external_exec *bytes,
    373   1.1.1.7  christos 	    struct internal_exec *execp);
    374       1.1  christos 
    375       1.1  christos DESCRIPTION
    376       1.1  christos 	Swap the information in an executable header @var{raw_bytes} taken
    377       1.1  christos 	from a raw byte stream memory image into the internal exec header
    378       1.1  christos 	structure @var{execp}.
    379       1.1  christos */
    380       1.1  christos 
    381       1.1  christos #ifndef NAME_swap_exec_header_in
    382       1.1  christos void
    383       1.1  christos NAME (aout, swap_exec_header_in) (bfd *abfd,
    384       1.1  christos 				  struct external_exec *bytes,
    385       1.1  christos 				  struct internal_exec *execp)
    386       1.1  christos {
    387       1.1  christos   /* The internal_exec structure has some fields that are unused in this
    388       1.1  christos      configuration (IE for i960), so ensure that all such uninitialized
    389       1.1  christos      fields are zero'd out.  There are places where two of these structs
    390       1.1  christos      are memcmp'd, and thus the contents do matter.  */
    391       1.1  christos   memset ((void *) execp, 0, sizeof (struct internal_exec));
    392       1.1  christos   /* Now fill in fields in the execp, from the bytes in the raw data.  */
    393       1.1  christos   execp->a_info   = H_GET_32 (abfd, bytes->e_info);
    394       1.1  christos   execp->a_text   = GET_WORD (abfd, bytes->e_text);
    395       1.1  christos   execp->a_data   = GET_WORD (abfd, bytes->e_data);
    396       1.1  christos   execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
    397       1.1  christos   execp->a_syms   = GET_WORD (abfd, bytes->e_syms);
    398       1.1  christos   execp->a_entry  = GET_WORD (abfd, bytes->e_entry);
    399       1.1  christos   execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
    400       1.1  christos   execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
    401       1.1  christos }
    402       1.1  christos #define NAME_swap_exec_header_in NAME (aout, swap_exec_header_in)
    403       1.1  christos #endif
    404       1.1  christos 
    405       1.1  christos /*
    406       1.1  christos FUNCTION
    407       1.1  christos 	aout_@var{size}_swap_exec_header_out
    408       1.1  christos 
    409       1.1  christos SYNOPSIS
    410  1.1.1.10  christos 	bool aout_@var{size}_swap_exec_header_out
    411       1.1  christos 	  (bfd *abfd,
    412       1.1  christos 	   struct internal_exec *execp,
    413       1.1  christos 	   struct external_exec *raw_bytes);
    414       1.1  christos 
    415       1.1  christos DESCRIPTION
    416       1.1  christos 	Swap the information in an internal exec header structure
    417       1.1  christos 	@var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
    418       1.1  christos */
    419  1.1.1.10  christos bool
    420       1.1  christos NAME (aout, swap_exec_header_out) (bfd *abfd,
    421       1.1  christos 				   struct internal_exec *execp,
    422       1.1  christos 				   struct external_exec *bytes)
    423       1.1  christos {
    424  1.1.1.10  christos   const char *err = NULL;
    425  1.1.1.10  christos   uint64_t val;
    426  1.1.1.10  christos #define MAXVAL(x) ((UINT64_C (1) << (8 * sizeof (x) - 1) << 1) - 1)
    427  1.1.1.10  christos   if ((val = execp->a_text) > MAXVAL (bytes->e_text))
    428  1.1.1.10  christos     err = "e_text";
    429  1.1.1.10  christos   else if ((val = execp->a_data) > MAXVAL (bytes->e_data))
    430  1.1.1.10  christos     err = "e_data";
    431  1.1.1.10  christos   else if ((val = execp->a_bss) > MAXVAL (bytes->e_bss))
    432  1.1.1.10  christos     err = "e_bss";
    433  1.1.1.10  christos   else if ((val = execp->a_syms) > MAXVAL (bytes->e_syms))
    434  1.1.1.10  christos     err = "e_syms";
    435  1.1.1.10  christos   else if ((val = execp->a_entry) > MAXVAL (bytes->e_entry))
    436  1.1.1.10  christos     err = "e_entry";
    437  1.1.1.10  christos   else if ((val = execp->a_trsize) > MAXVAL (bytes->e_trsize))
    438  1.1.1.10  christos     err = "e_trsize";
    439  1.1.1.10  christos   else if ((val = execp->a_drsize) > MAXVAL (bytes->e_drsize))
    440  1.1.1.10  christos     err = "e_drsize";
    441  1.1.1.10  christos #undef MAXVAL
    442  1.1.1.10  christos   if (err)
    443  1.1.1.10  christos     {
    444  1.1.1.10  christos       _bfd_error_handler (_("%pB: %#" PRIx64 " overflows header %s field"),
    445  1.1.1.10  christos 			  abfd, val, err);
    446  1.1.1.10  christos       bfd_set_error (bfd_error_file_too_big);
    447  1.1.1.10  christos       return false;
    448  1.1.1.10  christos     }
    449  1.1.1.10  christos 
    450       1.1  christos   /* Now fill in fields in the raw data, from the fields in the exec struct.  */
    451       1.1  christos   H_PUT_32 (abfd, execp->a_info  , bytes->e_info);
    452       1.1  christos   PUT_WORD (abfd, execp->a_text  , bytes->e_text);
    453       1.1  christos   PUT_WORD (abfd, execp->a_data  , bytes->e_data);
    454       1.1  christos   PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
    455       1.1  christos   PUT_WORD (abfd, execp->a_syms  , bytes->e_syms);
    456       1.1  christos   PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
    457       1.1  christos   PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
    458       1.1  christos   PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
    459  1.1.1.10  christos   return true;
    460       1.1  christos }
    461       1.1  christos 
    462       1.1  christos /* Make all the section for an a.out file.  */
    463       1.1  christos 
    464   1.1.1.9  christos bool
    465       1.1  christos NAME (aout, make_sections) (bfd *abfd)
    466       1.1  christos {
    467       1.1  christos   if (obj_textsec (abfd) == NULL && bfd_make_section (abfd, ".text") == NULL)
    468   1.1.1.9  christos     return false;
    469       1.1  christos   if (obj_datasec (abfd) == NULL && bfd_make_section (abfd, ".data") == NULL)
    470   1.1.1.9  christos     return false;
    471       1.1  christos   if (obj_bsssec (abfd) == NULL && bfd_make_section (abfd, ".bss") == NULL)
    472   1.1.1.9  christos     return false;
    473   1.1.1.9  christos   return true;
    474       1.1  christos }
    475       1.1  christos 
    476       1.1  christos /*
    477       1.1  christos FUNCTION
    478       1.1  christos 	aout_@var{size}_some_aout_object_p
    479       1.1  christos 
    480       1.1  christos SYNOPSIS
    481   1.1.1.9  christos 	bfd_cleanup aout_@var{size}_some_aout_object_p
    482       1.1  christos 	 (bfd *abfd,
    483   1.1.1.7  christos 	  struct internal_exec *execp,
    484   1.1.1.9  christos 	  bfd_cleanup (*callback_to_real_object_p) (bfd *));
    485       1.1  christos 
    486       1.1  christos DESCRIPTION
    487       1.1  christos 	Some a.out variant thinks that the file open in @var{abfd}
    488       1.1  christos 	checking is an a.out file.  Do some more checking, and set up
    489       1.1  christos 	for access if it really is.  Call back to the calling
    490       1.1  christos 	environment's "finish up" function just before returning, to
    491       1.1  christos 	handle any last-minute setup.
    492       1.1  christos */
    493       1.1  christos 
    494   1.1.1.8  christos bfd_cleanup
    495       1.1  christos NAME (aout, some_aout_object_p) (bfd *abfd,
    496       1.1  christos 				 struct internal_exec *execp,
    497   1.1.1.8  christos 				 bfd_cleanup (*callback_to_real_object_p) (bfd *))
    498       1.1  christos {
    499  1.1.1.11  christos   struct aout_data_struct *rawptr;
    500   1.1.1.8  christos   bfd_cleanup result;
    501       1.1  christos 
    502  1.1.1.11  christos   rawptr = bfd_zalloc (abfd, sizeof (*rawptr));
    503       1.1  christos   if (rawptr == NULL)
    504       1.1  christos     return NULL;
    505       1.1  christos   abfd->tdata.aout_data = rawptr;
    506       1.1  christos 
    507       1.1  christos   abfd->tdata.aout_data->a.hdr = &rawptr->e;
    508       1.1  christos   /* Copy in the internal_exec struct.  */
    509       1.1  christos   *(abfd->tdata.aout_data->a.hdr) = *execp;
    510       1.1  christos   execp = abfd->tdata.aout_data->a.hdr;
    511       1.1  christos 
    512       1.1  christos   /* Set the file flags.  */
    513       1.1  christos   abfd->flags = BFD_NO_FLAGS;
    514       1.1  christos   if (execp->a_drsize || execp->a_trsize)
    515       1.1  christos     abfd->flags |= HAS_RELOC;
    516       1.1  christos   /* Setting of EXEC_P has been deferred to the bottom of this function.  */
    517       1.1  christos   if (execp->a_syms)
    518       1.1  christos     abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
    519   1.1.1.5  christos   if (N_DYNAMIC (execp))
    520       1.1  christos     abfd->flags |= DYNAMIC;
    521       1.1  christos 
    522   1.1.1.5  christos   if (N_MAGIC (execp) == ZMAGIC)
    523       1.1  christos     {
    524       1.1  christos       abfd->flags |= D_PAGED | WP_TEXT;
    525       1.1  christos       adata (abfd).magic = z_magic;
    526       1.1  christos     }
    527   1.1.1.8  christos   else if (N_IS_QMAGIC (execp))
    528       1.1  christos     {
    529       1.1  christos       abfd->flags |= D_PAGED | WP_TEXT;
    530       1.1  christos       adata (abfd).magic = z_magic;
    531       1.1  christos       adata (abfd).subformat = q_magic_format;
    532       1.1  christos     }
    533   1.1.1.5  christos   else if (N_MAGIC (execp) == NMAGIC)
    534       1.1  christos     {
    535       1.1  christos       abfd->flags |= WP_TEXT;
    536       1.1  christos       adata (abfd).magic = n_magic;
    537       1.1  christos     }
    538   1.1.1.8  christos   else if (N_MAGIC (execp) == OMAGIC || N_IS_BMAGIC (execp))
    539       1.1  christos     adata (abfd).magic = o_magic;
    540       1.1  christos   else
    541       1.1  christos     /* Should have been checked with N_BADMAG before this routine
    542       1.1  christos        was called.  */
    543       1.1  christos     abort ();
    544       1.1  christos 
    545   1.1.1.8  christos   abfd->start_address = execp->a_entry;
    546       1.1  christos 
    547   1.1.1.8  christos   abfd->symcount = execp->a_syms / sizeof (struct external_nlist);
    548       1.1  christos 
    549       1.1  christos   /* The default relocation entry size is that of traditional V7 Unix.  */
    550       1.1  christos   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
    551       1.1  christos 
    552       1.1  christos   /* The default symbol entry size is that of traditional Unix.  */
    553       1.1  christos   obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
    554       1.1  christos 
    555       1.1  christos   if (! NAME (aout, make_sections) (abfd))
    556       1.1  christos     goto error_ret;
    557       1.1  christos 
    558       1.1  christos   obj_datasec (abfd)->size = execp->a_data;
    559       1.1  christos   obj_bsssec (abfd)->size = execp->a_bss;
    560       1.1  christos 
    561       1.1  christos   obj_textsec (abfd)->flags =
    562       1.1  christos     (execp->a_trsize != 0
    563       1.1  christos      ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
    564       1.1  christos      : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
    565       1.1  christos   obj_datasec (abfd)->flags =
    566       1.1  christos     (execp->a_drsize != 0
    567       1.1  christos      ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
    568       1.1  christos      : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
    569       1.1  christos   obj_bsssec (abfd)->flags = SEC_ALLOC;
    570       1.1  christos 
    571       1.1  christos #ifdef THIS_IS_ONLY_DOCUMENTATION
    572       1.1  christos   /* The common code can't fill in these things because they depend
    573       1.1  christos      on either the start address of the text segment, the rounding
    574       1.1  christos      up of virtual addresses between segments, or the starting file
    575       1.1  christos      position of the text segment -- all of which varies among different
    576       1.1  christos      versions of a.out.  */
    577       1.1  christos 
    578       1.1  christos   /* Call back to the format-dependent code to fill in the rest of the
    579       1.1  christos      fields and do any further cleanup.  Things that should be filled
    580       1.1  christos      in by the callback:  */
    581       1.1  christos   struct exec *execp = exec_hdr (abfd);
    582       1.1  christos 
    583   1.1.1.5  christos   obj_textsec (abfd)->size = N_TXTSIZE (execp);
    584       1.1  christos   /* Data and bss are already filled in since they're so standard.  */
    585       1.1  christos 
    586       1.1  christos   /* The virtual memory addresses of the sections.  */
    587   1.1.1.5  christos   obj_textsec (abfd)->vma = N_TXTADDR (execp);
    588   1.1.1.5  christos   obj_datasec (abfd)->vma = N_DATADDR (execp);
    589   1.1.1.5  christos   obj_bsssec  (abfd)->vma = N_BSSADDR (execp);
    590       1.1  christos 
    591       1.1  christos   /* The file offsets of the sections.  */
    592   1.1.1.5  christos   obj_textsec (abfd)->filepos = N_TXTOFF (execp);
    593   1.1.1.5  christos   obj_datasec (abfd)->filepos = N_DATOFF (execp);
    594       1.1  christos 
    595       1.1  christos   /* The file offsets of the relocation info.  */
    596   1.1.1.5  christos   obj_textsec (abfd)->rel_filepos = N_TRELOFF (execp);
    597   1.1.1.5  christos   obj_datasec (abfd)->rel_filepos = N_DRELOFF (execp);
    598       1.1  christos 
    599       1.1  christos   /* The file offsets of the string table and symbol table.  */
    600   1.1.1.5  christos   obj_str_filepos (abfd) = N_STROFF (execp);
    601   1.1.1.5  christos   obj_sym_filepos (abfd) = N_SYMOFF (execp);
    602       1.1  christos 
    603       1.1  christos   /* Determine the architecture and machine type of the object file.  */
    604  1.1.1.10  christos   abfd->obj_arch = bfd_arch_obscure;
    605       1.1  christos 
    606       1.1  christos   adata (abfd)->page_size = TARGET_PAGE_SIZE;
    607       1.1  christos   adata (abfd)->segment_size = SEGMENT_SIZE;
    608       1.1  christos   adata (abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
    609       1.1  christos 
    610  1.1.1.10  christos   return _bfd_no_cleanup;
    611       1.1  christos 
    612       1.1  christos   /* The architecture is encoded in various ways in various a.out variants,
    613       1.1  christos      or is not encoded at all in some of them.  The relocation size depends
    614       1.1  christos      on the architecture and the a.out variant.  Finally, the return value
    615       1.1  christos      is the bfd_target vector in use.  If an error occurs, return zero and
    616       1.1  christos      set bfd_error to the appropriate error code.
    617       1.1  christos 
    618       1.1  christos      Formats such as b.out, which have additional fields in the a.out
    619       1.1  christos      header, should cope with them in this callback as well.  */
    620  1.1.1.10  christos #endif  /* DOCUMENTATION */
    621       1.1  christos 
    622       1.1  christos   result = (*callback_to_real_object_p) (abfd);
    623       1.1  christos 
    624       1.1  christos   /* Now that the segment addresses have been worked out, take a better
    625       1.1  christos      guess at whether the file is executable.  If the entry point
    626       1.1  christos      is within the text segment, assume it is.  (This makes files
    627       1.1  christos      executable even if their entry point address is 0, as long as
    628       1.1  christos      their text starts at zero.).
    629       1.1  christos 
    630       1.1  christos      This test had to be changed to deal with systems where the text segment
    631       1.1  christos      runs at a different location than the default.  The problem is that the
    632       1.1  christos      entry address can appear to be outside the text segment, thus causing an
    633       1.1  christos      erroneous conclusion that the file isn't executable.
    634       1.1  christos 
    635       1.1  christos      To fix this, we now accept any non-zero entry point as an indication of
    636       1.1  christos      executability.  This will work most of the time, since only the linker
    637       1.1  christos      sets the entry point, and that is likely to be non-zero for most systems.  */
    638       1.1  christos 
    639       1.1  christos   if (execp->a_entry != 0
    640       1.1  christos       || (execp->a_entry >= obj_textsec (abfd)->vma
    641       1.1  christos 	  && execp->a_entry < (obj_textsec (abfd)->vma
    642       1.1  christos 			       + obj_textsec (abfd)->size)
    643       1.1  christos 	  && execp->a_trsize == 0
    644       1.1  christos 	  && execp->a_drsize == 0))
    645       1.1  christos     abfd->flags |= EXEC_P;
    646       1.1  christos #ifdef STAT_FOR_EXEC
    647       1.1  christos   else
    648       1.1  christos     {
    649       1.1  christos       struct stat stat_buf;
    650       1.1  christos 
    651       1.1  christos       /* The original heuristic doesn't work in some important cases.
    652   1.1.1.7  christos 	The a.out file has no information about the text start
    653   1.1.1.7  christos 	address.  For files (like kernels) linked to non-standard
    654   1.1.1.7  christos 	addresses (ld -Ttext nnn) the entry point may not be between
    655   1.1.1.7  christos 	the default text start (obj_textsec(abfd)->vma) and
    656   1.1.1.7  christos 	(obj_textsec(abfd)->vma) + text size.  This is not just a mach
    657   1.1.1.7  christos 	issue.  Many kernels are loaded at non standard addresses.  */
    658       1.1  christos       if (abfd->iostream != NULL
    659       1.1  christos 	  && (abfd->flags & BFD_IN_MEMORY) == 0
    660       1.1  christos 	  && (fstat (fileno ((FILE *) (abfd->iostream)), &stat_buf) == 0)
    661       1.1  christos 	  && ((stat_buf.st_mode & 0111) != 0))
    662       1.1  christos 	abfd->flags |= EXEC_P;
    663       1.1  christos     }
    664       1.1  christos #endif /* STAT_FOR_EXEC */
    665       1.1  christos 
    666       1.1  christos   if (result)
    667       1.1  christos     return result;
    668       1.1  christos 
    669       1.1  christos  error_ret:
    670       1.1  christos   bfd_release (abfd, rawptr);
    671       1.1  christos   return NULL;
    672       1.1  christos }
    673       1.1  christos 
    674       1.1  christos /*
    675       1.1  christos FUNCTION
    676       1.1  christos 	aout_@var{size}_mkobject
    677       1.1  christos 
    678       1.1  christos SYNOPSIS
    679   1.1.1.9  christos 	bool aout_@var{size}_mkobject, (bfd *abfd);
    680       1.1  christos 
    681       1.1  christos DESCRIPTION
    682       1.1  christos 	Initialize BFD @var{abfd} for use with a.out files.
    683       1.1  christos */
    684       1.1  christos 
    685   1.1.1.9  christos bool
    686       1.1  christos NAME (aout, mkobject) (bfd *abfd)
    687       1.1  christos {
    688       1.1  christos   struct aout_data_struct *rawptr;
    689   1.1.1.8  christos   size_t amt = sizeof (* rawptr);
    690       1.1  christos 
    691       1.1  christos   bfd_set_error (bfd_error_system_call);
    692       1.1  christos 
    693       1.1  christos   rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
    694       1.1  christos   if (rawptr == NULL)
    695   1.1.1.9  christos     return false;
    696       1.1  christos 
    697       1.1  christos   abfd->tdata.aout_data = rawptr;
    698       1.1  christos   exec_hdr (abfd) = &(rawptr->e);
    699       1.1  christos 
    700       1.1  christos   obj_textsec (abfd) = NULL;
    701       1.1  christos   obj_datasec (abfd) = NULL;
    702       1.1  christos   obj_bsssec (abfd) = NULL;
    703       1.1  christos 
    704   1.1.1.9  christos   return true;
    705       1.1  christos }
    706       1.1  christos 
    707       1.1  christos /*
    708       1.1  christos FUNCTION
    709       1.1  christos 	aout_@var{size}_machine_type
    710       1.1  christos 
    711       1.1  christos SYNOPSIS
    712       1.1  christos 	enum machine_type  aout_@var{size}_machine_type
    713       1.1  christos 	 (enum bfd_architecture arch,
    714       1.1  christos 	  unsigned long machine,
    715   1.1.1.9  christos 	  bool *unknown);
    716       1.1  christos 
    717       1.1  christos DESCRIPTION
    718       1.1  christos 	Keep track of machine architecture and machine type for
    719       1.1  christos 	a.out's. Return the <<machine_type>> for a particular
    720       1.1  christos 	architecture and machine, or <<M_UNKNOWN>> if that exact architecture
    721       1.1  christos 	and machine can't be represented in a.out format.
    722       1.1  christos 
    723       1.1  christos 	If the architecture is understood, machine type 0 (default)
    724       1.1  christos 	is always understood.
    725       1.1  christos */
    726       1.1  christos 
    727       1.1  christos enum machine_type
    728       1.1  christos NAME (aout, machine_type) (enum bfd_architecture arch,
    729       1.1  christos 			   unsigned long machine,
    730   1.1.1.9  christos 			   bool *unknown)
    731       1.1  christos {
    732       1.1  christos   enum machine_type arch_flags;
    733       1.1  christos 
    734       1.1  christos   arch_flags = M_UNKNOWN;
    735   1.1.1.9  christos   *unknown = true;
    736       1.1  christos 
    737       1.1  christos   switch (arch)
    738       1.1  christos     {
    739       1.1  christos     case bfd_arch_sparc:
    740       1.1  christos       if (machine == 0
    741       1.1  christos 	  || machine == bfd_mach_sparc
    742       1.1  christos 	  || machine == bfd_mach_sparc_sparclite
    743       1.1  christos 	  || machine == bfd_mach_sparc_sparclite_le
    744       1.1  christos 	  || machine == bfd_mach_sparc_v8plus
    745       1.1  christos 	  || machine == bfd_mach_sparc_v8plusa
    746       1.1  christos 	  || machine == bfd_mach_sparc_v8plusb
    747   1.1.1.7  christos 	  || machine == bfd_mach_sparc_v8plusc
    748   1.1.1.7  christos 	  || machine == bfd_mach_sparc_v8plusd
    749   1.1.1.7  christos 	  || machine == bfd_mach_sparc_v8pluse
    750   1.1.1.7  christos 	  || machine == bfd_mach_sparc_v8plusv
    751   1.1.1.7  christos 	  || machine == bfd_mach_sparc_v8plusm
    752   1.1.1.7  christos 	  || machine == bfd_mach_sparc_v8plusm8
    753       1.1  christos 	  || machine == bfd_mach_sparc_v9
    754       1.1  christos 	  || machine == bfd_mach_sparc_v9a
    755   1.1.1.5  christos 	  || machine == bfd_mach_sparc_v9b
    756   1.1.1.7  christos 	  || machine == bfd_mach_sparc_v9c
    757   1.1.1.7  christos 	  || machine == bfd_mach_sparc_v9d
    758   1.1.1.7  christos 	  || machine == bfd_mach_sparc_v9e
    759   1.1.1.7  christos 	  || machine == bfd_mach_sparc_v9v
    760   1.1.1.7  christos 	  || machine == bfd_mach_sparc_v9m
    761   1.1.1.7  christos 	  || machine == bfd_mach_sparc_v9m8)
    762       1.1  christos 	arch_flags = M_SPARC;
    763       1.1  christos       else if (machine == bfd_mach_sparc_sparclet)
    764       1.1  christos 	arch_flags = M_SPARCLET;
    765       1.1  christos       break;
    766       1.1  christos 
    767       1.1  christos     case bfd_arch_i386:
    768       1.1  christos       if (machine == 0
    769       1.1  christos 	  || machine == bfd_mach_i386_i386
    770       1.1  christos 	  || machine == bfd_mach_i386_i386_intel_syntax)
    771       1.1  christos 	arch_flags = M_386;
    772       1.1  christos       break;
    773       1.1  christos 
    774       1.1  christos     case bfd_arch_arm:
    775       1.1  christos       if (machine == 0)
    776       1.1  christos 	arch_flags = M_ARM;
    777       1.1  christos       break;
    778       1.1  christos 
    779       1.1  christos     case bfd_arch_mips:
    780       1.1  christos       switch (machine)
    781       1.1  christos 	{
    782       1.1  christos 	case 0:
    783       1.1  christos 	case bfd_mach_mips3000:
    784       1.1  christos 	case bfd_mach_mips3900:
    785       1.1  christos 	  arch_flags = M_MIPS1;
    786       1.1  christos 	  break;
    787       1.1  christos 	case bfd_mach_mips6000:
    788       1.1  christos 	  arch_flags = M_MIPS2;
    789       1.1  christos 	  break;
    790       1.1  christos 	case bfd_mach_mips4000:
    791       1.1  christos 	case bfd_mach_mips4010:
    792       1.1  christos 	case bfd_mach_mips4100:
    793       1.1  christos 	case bfd_mach_mips4300:
    794       1.1  christos 	case bfd_mach_mips4400:
    795       1.1  christos 	case bfd_mach_mips4600:
    796       1.1  christos 	case bfd_mach_mips4650:
    797       1.1  christos 	case bfd_mach_mips8000:
    798       1.1  christos 	case bfd_mach_mips9000:
    799       1.1  christos 	case bfd_mach_mips10000:
    800       1.1  christos 	case bfd_mach_mips12000:
    801       1.1  christos 	case bfd_mach_mips14000:
    802       1.1  christos 	case bfd_mach_mips16000:
    803       1.1  christos 	case bfd_mach_mips16:
    804       1.1  christos 	case bfd_mach_mipsisa32:
    805       1.1  christos 	case bfd_mach_mipsisa32r2:
    806   1.1.1.3  christos 	case bfd_mach_mipsisa32r3:
    807   1.1.1.3  christos 	case bfd_mach_mipsisa32r5:
    808   1.1.1.3  christos 	case bfd_mach_mipsisa32r6:
    809       1.1  christos 	case bfd_mach_mips5:
    810       1.1  christos 	case bfd_mach_mipsisa64:
    811       1.1  christos 	case bfd_mach_mipsisa64r2:
    812   1.1.1.3  christos 	case bfd_mach_mipsisa64r3:
    813   1.1.1.3  christos 	case bfd_mach_mipsisa64r5:
    814   1.1.1.3  christos 	case bfd_mach_mipsisa64r6:
    815       1.1  christos 	case bfd_mach_mips_sb1:
    816       1.1  christos 	case bfd_mach_mips_xlr:
    817       1.1  christos 	  /* FIXME: These should be MIPS3, MIPS4, MIPS16, MIPS32, etc.  */
    818       1.1  christos 	  arch_flags = M_MIPS2;
    819       1.1  christos 	  break;
    820       1.1  christos 	default:
    821       1.1  christos 	  arch_flags = M_UNKNOWN;
    822       1.1  christos 	  break;
    823       1.1  christos 	}
    824       1.1  christos       break;
    825       1.1  christos 
    826       1.1  christos     case bfd_arch_ns32k:
    827       1.1  christos       switch (machine)
    828       1.1  christos 	{
    829   1.1.1.7  christos 	case 0:		arch_flags = M_NS32532; break;
    830       1.1  christos 	case 32032:	arch_flags = M_NS32032; break;
    831       1.1  christos 	case 32532:	arch_flags = M_NS32532; break;
    832       1.1  christos 	default:	arch_flags = M_UNKNOWN; break;
    833       1.1  christos 	}
    834       1.1  christos       break;
    835       1.1  christos 
    836       1.1  christos     case bfd_arch_vax:
    837   1.1.1.9  christos       *unknown = false;
    838       1.1  christos       break;
    839       1.1  christos 
    840       1.1  christos     case bfd_arch_cris:
    841       1.1  christos       if (machine == 0 || machine == 255)
    842       1.1  christos 	arch_flags = M_CRIS;
    843       1.1  christos       break;
    844       1.1  christos 
    845       1.1  christos     default:
    846       1.1  christos       arch_flags = M_UNKNOWN;
    847       1.1  christos     }
    848       1.1  christos 
    849       1.1  christos   if (arch_flags != M_UNKNOWN)
    850   1.1.1.9  christos     *unknown = false;
    851       1.1  christos 
    852       1.1  christos   return arch_flags;
    853       1.1  christos }
    854       1.1  christos 
    855       1.1  christos /*
    856       1.1  christos FUNCTION
    857       1.1  christos 	aout_@var{size}_set_arch_mach
    858       1.1  christos 
    859       1.1  christos SYNOPSIS
    860   1.1.1.9  christos 	bool aout_@var{size}_set_arch_mach,
    861       1.1  christos 	 (bfd *,
    862       1.1  christos 	  enum bfd_architecture arch,
    863       1.1  christos 	  unsigned long machine);
    864       1.1  christos 
    865       1.1  christos DESCRIPTION
    866       1.1  christos 	Set the architecture and the machine of the BFD @var{abfd} to the
    867       1.1  christos 	values @var{arch} and @var{machine}.  Verify that @var{abfd}'s format
    868       1.1  christos 	can support the architecture required.
    869       1.1  christos */
    870       1.1  christos 
    871   1.1.1.9  christos bool
    872       1.1  christos NAME (aout, set_arch_mach) (bfd *abfd,
    873       1.1  christos 			    enum bfd_architecture arch,
    874       1.1  christos 			    unsigned long machine)
    875       1.1  christos {
    876       1.1  christos   if (! bfd_default_set_arch_mach (abfd, arch, machine))
    877   1.1.1.9  christos     return false;
    878       1.1  christos 
    879       1.1  christos   if (arch != bfd_arch_unknown)
    880       1.1  christos     {
    881   1.1.1.9  christos       bool unknown;
    882       1.1  christos 
    883       1.1  christos       NAME (aout, machine_type) (arch, machine, &unknown);
    884       1.1  christos       if (unknown)
    885   1.1.1.9  christos 	return false;
    886       1.1  christos     }
    887       1.1  christos 
    888       1.1  christos   /* Determine the size of a relocation entry.  */
    889       1.1  christos   switch (arch)
    890       1.1  christos     {
    891       1.1  christos     case bfd_arch_sparc:
    892       1.1  christos     case bfd_arch_mips:
    893       1.1  christos       obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
    894       1.1  christos       break;
    895       1.1  christos     default:
    896       1.1  christos       obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
    897       1.1  christos       break;
    898       1.1  christos     }
    899       1.1  christos 
    900       1.1  christos   return (*aout_backend_info (abfd)->set_sizes) (abfd);
    901       1.1  christos }
    902       1.1  christos 
    903       1.1  christos static void
    904       1.1  christos adjust_o_magic (bfd *abfd, struct internal_exec *execp)
    905       1.1  christos {
    906       1.1  christos   file_ptr pos = adata (abfd).exec_bytes_size;
    907       1.1  christos   bfd_vma vma = 0;
    908       1.1  christos   int pad = 0;
    909   1.1.1.8  christos   asection *text = obj_textsec (abfd);
    910   1.1.1.8  christos   asection *data = obj_datasec (abfd);
    911   1.1.1.8  christos   asection *bss = obj_bsssec (abfd);
    912       1.1  christos 
    913       1.1  christos   /* Text.  */
    914   1.1.1.8  christos   text->filepos = pos;
    915   1.1.1.8  christos   if (!text->user_set_vma)
    916   1.1.1.8  christos     text->vma = vma;
    917       1.1  christos   else
    918   1.1.1.8  christos     vma = text->vma;
    919       1.1  christos 
    920   1.1.1.8  christos   pos += execp->a_text;
    921   1.1.1.8  christos   vma += execp->a_text;
    922       1.1  christos 
    923       1.1  christos   /* Data.  */
    924   1.1.1.8  christos   if (!data->user_set_vma)
    925       1.1  christos     {
    926       1.1  christos       pos += pad;
    927       1.1  christos       vma += pad;
    928   1.1.1.8  christos       data->vma = vma;
    929       1.1  christos     }
    930       1.1  christos   else
    931   1.1.1.8  christos     vma = data->vma;
    932   1.1.1.8  christos   execp->a_text += pad;
    933   1.1.1.8  christos 
    934   1.1.1.8  christos   data->filepos = pos;
    935   1.1.1.8  christos   pos += data->size;
    936   1.1.1.8  christos   vma += data->size;
    937       1.1  christos 
    938       1.1  christos   /* BSS.  */
    939   1.1.1.8  christos   if (!bss->user_set_vma)
    940       1.1  christos     {
    941       1.1  christos       pos += pad;
    942       1.1  christos       vma += pad;
    943   1.1.1.8  christos       bss->vma = vma;
    944       1.1  christos     }
    945       1.1  christos   else
    946       1.1  christos     {
    947       1.1  christos       /* The VMA of the .bss section is set by the VMA of the
    948   1.1.1.7  christos 	 .data section plus the size of the .data section.  We may
    949   1.1.1.7  christos 	 need to add padding bytes to make this true.  */
    950   1.1.1.8  christos       pad = bss->vma - vma;
    951   1.1.1.8  christos       if (pad < 0)
    952   1.1.1.8  christos 	pad = 0;
    953   1.1.1.8  christos       pos += pad;
    954       1.1  christos     }
    955   1.1.1.8  christos   execp->a_data = data->size + pad;
    956   1.1.1.8  christos   bss->filepos = pos;
    957   1.1.1.8  christos   execp->a_bss = bss->size;
    958       1.1  christos 
    959   1.1.1.5  christos   N_SET_MAGIC (execp, OMAGIC);
    960       1.1  christos }
    961       1.1  christos 
    962       1.1  christos static void
    963       1.1  christos adjust_z_magic (bfd *abfd, struct internal_exec *execp)
    964       1.1  christos {
    965       1.1  christos   bfd_size_type data_pad, text_pad;
    966       1.1  christos   file_ptr text_end;
    967       1.1  christos   const struct aout_backend_data *abdp;
    968       1.1  christos   /* TRUE if text includes exec header.  */
    969   1.1.1.9  christos   bool ztih;
    970   1.1.1.8  christos   asection *text = obj_textsec (abfd);
    971   1.1.1.8  christos   asection *data = obj_datasec (abfd);
    972   1.1.1.8  christos   asection *bss = obj_bsssec (abfd);
    973       1.1  christos 
    974       1.1  christos   abdp = aout_backend_info (abfd);
    975       1.1  christos 
    976       1.1  christos   /* Text.  */
    977       1.1  christos   ztih = (abdp != NULL
    978       1.1  christos 	  && (abdp->text_includes_header
    979       1.1  christos 	      || obj_aout_subformat (abfd) == q_magic_format));
    980   1.1.1.8  christos   text->filepos = (ztih
    981   1.1.1.8  christos 		   ? adata (abfd).exec_bytes_size
    982   1.1.1.8  christos 		   : adata (abfd).zmagic_disk_block_size);
    983   1.1.1.8  christos   if (!text->user_set_vma)
    984       1.1  christos     {
    985       1.1  christos       /* ?? Do we really need to check for relocs here?  */
    986   1.1.1.8  christos       text->vma = ((abfd->flags & HAS_RELOC)
    987   1.1.1.8  christos 		   ? 0
    988   1.1.1.8  christos 		   : (ztih
    989   1.1.1.8  christos 		      ? abdp->default_text_vma + adata (abfd).exec_bytes_size
    990   1.1.1.8  christos 		      : abdp->default_text_vma));
    991       1.1  christos       text_pad = 0;
    992       1.1  christos     }
    993       1.1  christos   else
    994       1.1  christos     {
    995       1.1  christos       /* The .text section is being loaded at an unusual address.  We
    996   1.1.1.7  christos 	 may need to pad it such that the .data section starts at a page
    997   1.1.1.7  christos 	 boundary.  */
    998       1.1  christos       if (ztih)
    999   1.1.1.8  christos 	text_pad = ((text->filepos - text->vma)
   1000       1.1  christos 		    & (adata (abfd).page_size - 1));
   1001       1.1  christos       else
   1002   1.1.1.8  christos 	text_pad = (-text->vma
   1003       1.1  christos 		    & (adata (abfd).page_size - 1));
   1004       1.1  christos     }
   1005       1.1  christos 
   1006       1.1  christos   /* Find start of data.  */
   1007       1.1  christos   if (ztih)
   1008       1.1  christos     {
   1009   1.1.1.8  christos       text_end = text->filepos + execp->a_text;
   1010       1.1  christos       text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
   1011       1.1  christos     }
   1012       1.1  christos   else
   1013       1.1  christos     {
   1014       1.1  christos       /* Note that if page_size == zmagic_disk_block_size, then
   1015       1.1  christos 	 filepos == page_size, and this case is the same as the ztih
   1016       1.1  christos 	 case.  */
   1017   1.1.1.8  christos       text_end = execp->a_text;
   1018       1.1  christos       text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
   1019   1.1.1.8  christos       text_end += text->filepos;
   1020       1.1  christos     }
   1021   1.1.1.8  christos   execp->a_text += text_pad;
   1022       1.1  christos 
   1023       1.1  christos   /* Data.  */
   1024   1.1.1.8  christos   if (!data->user_set_vma)
   1025       1.1  christos     {
   1026       1.1  christos       bfd_vma vma;
   1027   1.1.1.8  christos       vma = text->vma + execp->a_text;
   1028   1.1.1.8  christos       data->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
   1029       1.1  christos     }
   1030       1.1  christos   if (abdp && abdp->zmagic_mapped_contiguous)
   1031       1.1  christos     {
   1032   1.1.1.8  christos       text_pad = data->vma - (text->vma + execp->a_text);
   1033       1.1  christos       /* Only pad the text section if the data
   1034       1.1  christos 	 section is going to be placed after it.  */
   1035       1.1  christos       if (text_pad > 0)
   1036   1.1.1.8  christos 	execp->a_text += text_pad;
   1037       1.1  christos     }
   1038   1.1.1.8  christos   data->filepos = text->filepos + execp->a_text;
   1039       1.1  christos 
   1040       1.1  christos   /* Fix up exec header while we're at it.  */
   1041       1.1  christos   if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
   1042       1.1  christos     execp->a_text += adata (abfd).exec_bytes_size;
   1043       1.1  christos   if (obj_aout_subformat (abfd) == q_magic_format)
   1044   1.1.1.8  christos     N_SET_QMAGIC (execp);
   1045       1.1  christos   else
   1046   1.1.1.5  christos     N_SET_MAGIC (execp, ZMAGIC);
   1047       1.1  christos 
   1048       1.1  christos   /* Spec says data section should be rounded up to page boundary.  */
   1049   1.1.1.8  christos   execp->a_data = align_power (data->size, bss->alignment_power);
   1050   1.1.1.8  christos   execp->a_data = BFD_ALIGN (execp->a_data, adata (abfd).page_size);
   1051   1.1.1.8  christos   data_pad = execp->a_data - data->size;
   1052       1.1  christos 
   1053       1.1  christos   /* BSS.  */
   1054   1.1.1.8  christos   if (!bss->user_set_vma)
   1055   1.1.1.8  christos     bss->vma = data->vma + execp->a_data;
   1056       1.1  christos   /* If the BSS immediately follows the data section and extra space
   1057       1.1  christos      in the page is left after the data section, fudge data
   1058       1.1  christos      in the header so that the bss section looks smaller by that
   1059       1.1  christos      amount.  We'll start the bss section there, and lie to the OS.
   1060       1.1  christos      (Note that a linker script, as well as the above assignment,
   1061       1.1  christos      could have explicitly set the BSS vma to immediately follow
   1062       1.1  christos      the data section.)  */
   1063   1.1.1.8  christos   if (align_power (bss->vma, bss->alignment_power) == data->vma + execp->a_data)
   1064   1.1.1.8  christos     execp->a_bss = data_pad > bss->size ? 0 : bss->size - data_pad;
   1065       1.1  christos   else
   1066   1.1.1.8  christos     execp->a_bss = bss->size;
   1067       1.1  christos }
   1068       1.1  christos 
   1069       1.1  christos static void
   1070       1.1  christos adjust_n_magic (bfd *abfd, struct internal_exec *execp)
   1071       1.1  christos {
   1072       1.1  christos   file_ptr pos = adata (abfd).exec_bytes_size;
   1073       1.1  christos   bfd_vma vma = 0;
   1074       1.1  christos   int pad;
   1075   1.1.1.8  christos   asection *text = obj_textsec (abfd);
   1076   1.1.1.8  christos   asection *data = obj_datasec (abfd);
   1077   1.1.1.8  christos   asection *bss = obj_bsssec (abfd);
   1078       1.1  christos 
   1079       1.1  christos   /* Text.  */
   1080   1.1.1.8  christos   text->filepos = pos;
   1081   1.1.1.8  christos   if (!text->user_set_vma)
   1082   1.1.1.8  christos     text->vma = vma;
   1083       1.1  christos   else
   1084   1.1.1.8  christos     vma = text->vma;
   1085   1.1.1.8  christos   pos += execp->a_text;
   1086   1.1.1.8  christos   vma += execp->a_text;
   1087       1.1  christos 
   1088       1.1  christos   /* Data.  */
   1089   1.1.1.8  christos   data->filepos = pos;
   1090   1.1.1.8  christos   if (!data->user_set_vma)
   1091   1.1.1.8  christos     data->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
   1092   1.1.1.8  christos   vma = data->vma;
   1093       1.1  christos 
   1094       1.1  christos   /* Since BSS follows data immediately, see if it needs alignment.  */
   1095   1.1.1.8  christos   vma += data->size;
   1096   1.1.1.8  christos   pad = align_power (vma, bss->alignment_power) - vma;
   1097   1.1.1.8  christos   execp->a_data = data->size + pad;
   1098   1.1.1.8  christos   pos += execp->a_data;
   1099       1.1  christos 
   1100       1.1  christos   /* BSS.  */
   1101   1.1.1.8  christos   if (!bss->user_set_vma)
   1102   1.1.1.8  christos     bss->vma = vma;
   1103       1.1  christos   else
   1104   1.1.1.8  christos     vma = bss->vma;
   1105       1.1  christos 
   1106       1.1  christos   /* Fix up exec header.  */
   1107   1.1.1.8  christos   execp->a_bss = bss->size;
   1108   1.1.1.5  christos   N_SET_MAGIC (execp, NMAGIC);
   1109       1.1  christos }
   1110       1.1  christos 
   1111   1.1.1.9  christos bool
   1112   1.1.1.5  christos NAME (aout, adjust_sizes_and_vmas) (bfd *abfd)
   1113       1.1  christos {
   1114       1.1  christos   struct internal_exec *execp = exec_hdr (abfd);
   1115       1.1  christos 
   1116       1.1  christos   if (! NAME (aout, make_sections) (abfd))
   1117   1.1.1.9  christos     return false;
   1118       1.1  christos 
   1119       1.1  christos   if (adata (abfd).magic != undecided_magic)
   1120   1.1.1.9  christos     return true;
   1121       1.1  christos 
   1122   1.1.1.8  christos   execp->a_text = align_power (obj_textsec (abfd)->size,
   1123   1.1.1.8  christos 			       obj_textsec (abfd)->alignment_power);
   1124       1.1  christos 
   1125       1.1  christos   /* Rule (heuristic) for when to pad to a new page.  Note that there
   1126       1.1  christos      are (at least) two ways demand-paged (ZMAGIC) files have been
   1127       1.1  christos      handled.  Most Berkeley-based systems start the text segment at
   1128       1.1  christos      (TARGET_PAGE_SIZE).  However, newer versions of SUNOS start the text
   1129       1.1  christos      segment right after the exec header; the latter is counted in the
   1130       1.1  christos      text segment size, and is paged in by the kernel with the rest of
   1131       1.1  christos      the text.  */
   1132       1.1  christos 
   1133       1.1  christos   /* This perhaps isn't the right way to do this, but made it simpler for me
   1134       1.1  christos      to understand enough to implement it.  Better would probably be to go
   1135       1.1  christos      right from BFD flags to alignment/positioning characteristics.  But the
   1136       1.1  christos      old code was sloppy enough about handling the flags, and had enough
   1137       1.1  christos      other magic, that it was a little hard for me to understand.  I think
   1138       1.1  christos      I understand it better now, but I haven't time to do the cleanup this
   1139       1.1  christos      minute.  */
   1140       1.1  christos 
   1141       1.1  christos   if (abfd->flags & D_PAGED)
   1142       1.1  christos     /* Whether or not WP_TEXT is set -- let D_PAGED override.  */
   1143       1.1  christos     adata (abfd).magic = z_magic;
   1144       1.1  christos   else if (abfd->flags & WP_TEXT)
   1145       1.1  christos     adata (abfd).magic = n_magic;
   1146       1.1  christos   else
   1147       1.1  christos     adata (abfd).magic = o_magic;
   1148       1.1  christos 
   1149       1.1  christos #ifdef BFD_AOUT_DEBUG /* requires gcc2 */
   1150       1.1  christos #if __GNUC__ >= 2
   1151       1.1  christos   fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
   1152       1.1  christos 	   ({ char *str;
   1153       1.1  christos 	      switch (adata (abfd).magic)
   1154       1.1  christos 		{
   1155       1.1  christos 		case n_magic: str = "NMAGIC"; break;
   1156       1.1  christos 		case o_magic: str = "OMAGIC"; break;
   1157       1.1  christos 		case z_magic: str = "ZMAGIC"; break;
   1158       1.1  christos 		default: abort ();
   1159       1.1  christos 		}
   1160       1.1  christos 	      str;
   1161       1.1  christos 	    }),
   1162       1.1  christos 	   obj_textsec (abfd)->vma, obj_textsec (abfd)->size,
   1163   1.1.1.7  christos 		obj_textsec (abfd)->alignment_power,
   1164       1.1  christos 	   obj_datasec (abfd)->vma, obj_datasec (abfd)->size,
   1165   1.1.1.7  christos 		obj_datasec (abfd)->alignment_power,
   1166       1.1  christos 	   obj_bsssec (abfd)->vma, obj_bsssec (abfd)->size,
   1167   1.1.1.7  christos 		obj_bsssec (abfd)->alignment_power);
   1168       1.1  christos #endif
   1169       1.1  christos #endif
   1170       1.1  christos 
   1171       1.1  christos   switch (adata (abfd).magic)
   1172       1.1  christos     {
   1173       1.1  christos     case o_magic:
   1174       1.1  christos       adjust_o_magic (abfd, execp);
   1175       1.1  christos       break;
   1176       1.1  christos     case z_magic:
   1177       1.1  christos       adjust_z_magic (abfd, execp);
   1178       1.1  christos       break;
   1179       1.1  christos     case n_magic:
   1180       1.1  christos       adjust_n_magic (abfd, execp);
   1181       1.1  christos       break;
   1182       1.1  christos     default:
   1183       1.1  christos       abort ();
   1184       1.1  christos     }
   1185       1.1  christos 
   1186       1.1  christos #ifdef BFD_AOUT_DEBUG
   1187       1.1  christos   fprintf (stderr, "       text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
   1188   1.1.1.8  christos 	   obj_textsec (abfd)->vma, execp->a_text,
   1189   1.1.1.7  christos 		obj_textsec (abfd)->filepos,
   1190   1.1.1.8  christos 	   obj_datasec (abfd)->vma, execp->a_data,
   1191   1.1.1.7  christos 		obj_datasec (abfd)->filepos,
   1192   1.1.1.8  christos 	   obj_bsssec (abfd)->vma, execp->a_bss);
   1193       1.1  christos #endif
   1194       1.1  christos 
   1195   1.1.1.9  christos   return true;
   1196       1.1  christos }
   1197       1.1  christos 
   1198       1.1  christos /*
   1199       1.1  christos FUNCTION
   1200       1.1  christos 	aout_@var{size}_new_section_hook
   1201       1.1  christos 
   1202       1.1  christos SYNOPSIS
   1203   1.1.1.9  christos 	bool aout_@var{size}_new_section_hook,
   1204       1.1  christos 	   (bfd *abfd,
   1205       1.1  christos 	    asection *newsect);
   1206       1.1  christos 
   1207       1.1  christos DESCRIPTION
   1208       1.1  christos 	Called by the BFD in response to a @code{bfd_make_section}
   1209       1.1  christos 	request.
   1210       1.1  christos */
   1211   1.1.1.9  christos bool
   1212       1.1  christos NAME (aout, new_section_hook) (bfd *abfd, asection *newsect)
   1213       1.1  christos {
   1214       1.1  christos   /* Align to double at least.  */
   1215       1.1  christos   newsect->alignment_power = bfd_get_arch_info (abfd)->section_align_power;
   1216       1.1  christos 
   1217       1.1  christos   if (bfd_get_format (abfd) == bfd_object)
   1218       1.1  christos     {
   1219       1.1  christos       if (obj_textsec (abfd) == NULL && !strcmp (newsect->name, ".text"))
   1220       1.1  christos 	{
   1221       1.1  christos 	  obj_textsec (abfd)= newsect;
   1222       1.1  christos 	  newsect->target_index = N_TEXT;
   1223       1.1  christos 	}
   1224       1.1  christos       else if (obj_datasec (abfd) == NULL && !strcmp (newsect->name, ".data"))
   1225       1.1  christos 	{
   1226       1.1  christos 	  obj_datasec (abfd) = newsect;
   1227       1.1  christos 	  newsect->target_index = N_DATA;
   1228       1.1  christos 	}
   1229       1.1  christos       else if (obj_bsssec (abfd) == NULL && !strcmp (newsect->name, ".bss"))
   1230       1.1  christos 	{
   1231       1.1  christos 	  obj_bsssec (abfd) = newsect;
   1232       1.1  christos 	  newsect->target_index = N_BSS;
   1233       1.1  christos 	}
   1234       1.1  christos     }
   1235       1.1  christos 
   1236       1.1  christos   /* We allow more than three sections internally.  */
   1237       1.1  christos   return _bfd_generic_new_section_hook (abfd, newsect);
   1238       1.1  christos }
   1239       1.1  christos 
   1240   1.1.1.9  christos bool
   1241       1.1  christos NAME (aout, set_section_contents) (bfd *abfd,
   1242       1.1  christos 				   sec_ptr section,
   1243       1.1  christos 				   const void * location,
   1244       1.1  christos 				   file_ptr offset,
   1245       1.1  christos 				   bfd_size_type count)
   1246       1.1  christos {
   1247       1.1  christos   if (! abfd->output_has_begun)
   1248       1.1  christos     {
   1249   1.1.1.5  christos       if (! NAME (aout, adjust_sizes_and_vmas) (abfd))
   1250   1.1.1.9  christos 	return false;
   1251       1.1  christos     }
   1252       1.1  christos 
   1253       1.1  christos   if (section == obj_bsssec (abfd))
   1254       1.1  christos     {
   1255       1.1  christos       bfd_set_error (bfd_error_no_contents);
   1256   1.1.1.9  christos       return false;
   1257       1.1  christos     }
   1258       1.1  christos 
   1259       1.1  christos   if (section != obj_textsec (abfd)
   1260       1.1  christos       && section != obj_datasec (abfd))
   1261       1.1  christos     {
   1262       1.1  christos       if (aout_section_merge_with_text_p (abfd, section))
   1263       1.1  christos 	section->filepos = obj_textsec (abfd)->filepos +
   1264       1.1  christos 			   (section->vma - obj_textsec (abfd)->vma);
   1265       1.1  christos       else
   1266       1.1  christos 	{
   1267   1.1.1.6  christos 	  _bfd_error_handler
   1268   1.1.1.6  christos 	    /* xgettext:c-format */
   1269   1.1.1.7  christos 	   (_("%pB: can not represent section `%pA' in a.out object file format"),
   1270   1.1.1.6  christos 	     abfd, section);
   1271   1.1.1.7  christos 	  bfd_set_error (bfd_error_nonrepresentable_section);
   1272   1.1.1.9  christos 	  return false;
   1273       1.1  christos 	}
   1274       1.1  christos     }
   1275       1.1  christos 
   1276       1.1  christos   if (count != 0)
   1277       1.1  christos     {
   1278       1.1  christos       if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
   1279  1.1.1.10  christos 	  || bfd_write (location, count, abfd) != count)
   1280   1.1.1.9  christos 	return false;
   1281       1.1  christos     }
   1282       1.1  christos 
   1283   1.1.1.9  christos   return true;
   1284       1.1  christos }
   1285       1.1  christos 
   1286       1.1  christos /* Read the external symbols from an a.out file.  */
   1288   1.1.1.9  christos 
   1289       1.1  christos static bool
   1290       1.1  christos aout_get_external_symbols (bfd *abfd)
   1291       1.1  christos {
   1292       1.1  christos   if (obj_aout_external_syms (abfd) == NULL)
   1293       1.1  christos     {
   1294  1.1.1.10  christos       bfd_size_type count;
   1295   1.1.1.3  christos       struct external_nlist *syms = NULL;
   1296       1.1  christos       bfd_size_type amt = exec_hdr (abfd)->a_syms;
   1297   1.1.1.3  christos 
   1298       1.1  christos       count = amt / EXTERNAL_NLIST_SIZE;
   1299  1.1.1.10  christos       if (count == 0)
   1300       1.1  christos 	return true;
   1301       1.1  christos 
   1302       1.1  christos       /* We allocate using malloc to make the values easy to free
   1303       1.1  christos 	 later on.  If we put them on the objalloc it might not be
   1304   1.1.1.8  christos 	 possible to free them.  */
   1305   1.1.1.9  christos       if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
   1306  1.1.1.10  christos 	return false;
   1307       1.1  christos       syms = _bfd_malloc_and_read (abfd, amt, amt);
   1308   1.1.1.9  christos       if (syms == NULL)
   1309       1.1  christos 	return false;
   1310       1.1  christos 
   1311       1.1  christos       obj_aout_external_syms (abfd) = syms;
   1312       1.1  christos       obj_aout_external_sym_count (abfd) = count;
   1313       1.1  christos     }
   1314       1.1  christos 
   1315       1.1  christos   if (obj_aout_external_strings (abfd) == NULL
   1316       1.1  christos       && exec_hdr (abfd)->a_syms != 0)
   1317       1.1  christos     {
   1318       1.1  christos       unsigned char string_chars[BYTES_IN_WORD];
   1319       1.1  christos       bfd_size_type stringsize;
   1320       1.1  christos       char *strings;
   1321       1.1  christos       bfd_size_type amt = BYTES_IN_WORD;
   1322       1.1  christos 
   1323       1.1  christos       /* Get the size of the strings.  */
   1324  1.1.1.10  christos       if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
   1325   1.1.1.9  christos 	  || bfd_read (string_chars, amt, abfd) != amt)
   1326       1.1  christos 	return false;
   1327   1.1.1.7  christos       stringsize = GET_WORD (abfd, string_chars);
   1328   1.1.1.7  christos       if (stringsize == 0)
   1329  1.1.1.10  christos 	stringsize = 1;
   1330   1.1.1.7  christos       else if (stringsize + 1 < BYTES_IN_WORD + 1
   1331   1.1.1.7  christos 	       || (size_t) stringsize != stringsize)
   1332   1.1.1.7  christos 	{
   1333   1.1.1.9  christos 	  bfd_set_error (bfd_error_bad_value);
   1334   1.1.1.7  christos 	  return false;
   1335       1.1  christos 	}
   1336  1.1.1.10  christos 
   1337  1.1.1.10  christos       strings = (char *) bfd_malloc (stringsize + 1);
   1338  1.1.1.10  christos       if (strings == NULL)
   1339  1.1.1.10  christos 	return false;
   1340   1.1.1.7  christos 
   1341       1.1  christos       if (stringsize >= BYTES_IN_WORD)
   1342  1.1.1.10  christos 	{
   1343  1.1.1.10  christos 	  amt = stringsize - BYTES_IN_WORD;
   1344   1.1.1.7  christos 	  if (bfd_read (strings + BYTES_IN_WORD, amt, abfd) != amt)
   1345  1.1.1.10  christos 	    {
   1346  1.1.1.10  christos 	      free (strings);
   1347   1.1.1.7  christos 	      return false;
   1348   1.1.1.7  christos 	    }
   1349  1.1.1.10  christos 	}
   1350       1.1  christos 
   1351   1.1.1.9  christos       /* Ensure that a zero index yields an empty string.  */
   1352   1.1.1.9  christos       if (stringsize >= BYTES_IN_WORD)
   1353       1.1  christos 	memset (strings, 0, BYTES_IN_WORD);
   1354   1.1.1.7  christos 
   1355   1.1.1.7  christos       /* Ensure that the string buffer is NUL terminated.  */
   1356       1.1  christos       strings[stringsize] = 0;
   1357       1.1  christos 
   1358       1.1  christos       obj_aout_external_strings (abfd) = strings;
   1359       1.1  christos       obj_aout_external_string_size (abfd) = stringsize;
   1360       1.1  christos     }
   1361   1.1.1.9  christos 
   1362       1.1  christos   return true;
   1363       1.1  christos }
   1364       1.1  christos 
   1365       1.1  christos /* Translate an a.out symbol into a BFD symbol.  The desc, other, type
   1366       1.1  christos    and symbol->value fields of CACHE_PTR will be set from the a.out
   1367       1.1  christos    nlist structure.  This function is responsible for setting
   1368       1.1  christos    symbol->flags and symbol->section, and adjusting symbol->value.  */
   1369   1.1.1.9  christos 
   1370       1.1  christos static bool
   1371       1.1  christos translate_from_native_sym_flags (bfd *abfd, aout_symbol_type *cache_ptr)
   1372       1.1  christos {
   1373       1.1  christos   flagword visible;
   1374       1.1  christos 
   1375       1.1  christos   if ((cache_ptr->type & N_STAB) != 0
   1376       1.1  christos       || cache_ptr->type == N_FN)
   1377       1.1  christos     {
   1378       1.1  christos       asection *sec;
   1379       1.1  christos 
   1380       1.1  christos       /* This is a debugging symbol.  */
   1381       1.1  christos       cache_ptr->symbol.flags = BSF_DEBUGGING;
   1382       1.1  christos 
   1383       1.1  christos       /* Work out the symbol section.  */
   1384       1.1  christos       switch (cache_ptr->type & N_TYPE)
   1385       1.1  christos 	{
   1386       1.1  christos 	case N_TEXT:
   1387       1.1  christos 	case N_FN:
   1388       1.1  christos 	  sec = obj_textsec (abfd);
   1389       1.1  christos 	  break;
   1390       1.1  christos 	case N_DATA:
   1391       1.1  christos 	  sec = obj_datasec (abfd);
   1392       1.1  christos 	  break;
   1393       1.1  christos 	case N_BSS:
   1394       1.1  christos 	  sec = obj_bsssec (abfd);
   1395       1.1  christos 	  break;
   1396       1.1  christos 	default:
   1397       1.1  christos 	case N_ABS:
   1398       1.1  christos 	  sec = bfd_abs_section_ptr;
   1399       1.1  christos 	  break;
   1400       1.1  christos 	}
   1401       1.1  christos 
   1402       1.1  christos       cache_ptr->symbol.section = sec;
   1403       1.1  christos       cache_ptr->symbol.value -= sec->vma;
   1404   1.1.1.9  christos 
   1405       1.1  christos       return true;
   1406       1.1  christos     }
   1407       1.1  christos 
   1408       1.1  christos   /* Get the default visibility.  This does not apply to all types, so
   1409       1.1  christos      we just hold it in a local variable to use if wanted.  */
   1410       1.1  christos   if ((cache_ptr->type & N_EXT) == 0)
   1411       1.1  christos     visible = BSF_LOCAL;
   1412       1.1  christos   else
   1413       1.1  christos     visible = BSF_GLOBAL;
   1414       1.1  christos 
   1415       1.1  christos   switch (cache_ptr->type)
   1416       1.1  christos     {
   1417       1.1  christos     default:
   1418       1.1  christos     case N_ABS: case N_ABS | N_EXT:
   1419       1.1  christos       cache_ptr->symbol.section = bfd_abs_section_ptr;
   1420       1.1  christos       cache_ptr->symbol.flags = visible;
   1421       1.1  christos       break;
   1422       1.1  christos 
   1423       1.1  christos     case N_UNDF | N_EXT:
   1424       1.1  christos       if (cache_ptr->symbol.value != 0)
   1425       1.1  christos 	{
   1426       1.1  christos 	  /* This is a common symbol.  */
   1427       1.1  christos 	  cache_ptr->symbol.flags = BSF_GLOBAL;
   1428       1.1  christos 	  cache_ptr->symbol.section = bfd_com_section_ptr;
   1429       1.1  christos 	}
   1430       1.1  christos       else
   1431       1.1  christos 	{
   1432       1.1  christos 	  cache_ptr->symbol.flags = 0;
   1433       1.1  christos 	  cache_ptr->symbol.section = bfd_und_section_ptr;
   1434       1.1  christos 	}
   1435       1.1  christos       break;
   1436       1.1  christos 
   1437       1.1  christos     case N_TEXT: case N_TEXT | N_EXT:
   1438       1.1  christos       cache_ptr->symbol.section = obj_textsec (abfd);
   1439       1.1  christos       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
   1440       1.1  christos       cache_ptr->symbol.flags = visible;
   1441       1.1  christos       break;
   1442       1.1  christos 
   1443       1.1  christos       /* N_SETV symbols used to represent set vectors placed in the
   1444       1.1  christos 	 data section.  They are no longer generated.  Theoretically,
   1445       1.1  christos 	 it was possible to extract the entries and combine them with
   1446       1.1  christos 	 new ones, although I don't know if that was ever actually
   1447       1.1  christos 	 done.  Unless that feature is restored, treat them as data
   1448       1.1  christos 	 symbols.  */
   1449       1.1  christos     case N_SETV: case N_SETV | N_EXT:
   1450       1.1  christos     case N_DATA: case N_DATA | N_EXT:
   1451       1.1  christos       cache_ptr->symbol.section = obj_datasec (abfd);
   1452       1.1  christos       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
   1453       1.1  christos       cache_ptr->symbol.flags = visible;
   1454       1.1  christos       break;
   1455       1.1  christos 
   1456       1.1  christos     case N_BSS: case N_BSS | N_EXT:
   1457       1.1  christos       cache_ptr->symbol.section = obj_bsssec (abfd);
   1458       1.1  christos       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
   1459       1.1  christos       cache_ptr->symbol.flags = visible;
   1460       1.1  christos       break;
   1461       1.1  christos 
   1462       1.1  christos     case N_SETA: case N_SETA | N_EXT:
   1463       1.1  christos     case N_SETT: case N_SETT | N_EXT:
   1464       1.1  christos     case N_SETD: case N_SETD | N_EXT:
   1465       1.1  christos     case N_SETB: case N_SETB | N_EXT:
   1466       1.1  christos       {
   1467   1.1.1.7  christos 	/* This code is no longer needed.  It used to be used to make
   1468   1.1.1.7  christos 	   the linker handle set symbols, but they are now handled in
   1469       1.1  christos 	   the add_symbols routine instead.  */
   1470       1.1  christos 	switch (cache_ptr->type & N_TYPE)
   1471       1.1  christos 	  {
   1472       1.1  christos 	  case N_SETA:
   1473       1.1  christos 	    cache_ptr->symbol.section = bfd_abs_section_ptr;
   1474       1.1  christos 	    break;
   1475       1.1  christos 	  case N_SETT:
   1476       1.1  christos 	    cache_ptr->symbol.section = obj_textsec (abfd);
   1477       1.1  christos 	    break;
   1478       1.1  christos 	  case N_SETD:
   1479       1.1  christos 	    cache_ptr->symbol.section = obj_datasec (abfd);
   1480       1.1  christos 	    break;
   1481       1.1  christos 	  case N_SETB:
   1482       1.1  christos 	    cache_ptr->symbol.section = obj_bsssec (abfd);
   1483       1.1  christos 	    break;
   1484       1.1  christos 	  }
   1485       1.1  christos 
   1486       1.1  christos 	cache_ptr->symbol.flags |= BSF_CONSTRUCTOR;
   1487       1.1  christos       }
   1488       1.1  christos       break;
   1489       1.1  christos 
   1490       1.1  christos     case N_WARNING:
   1491       1.1  christos       /* This symbol is the text of a warning message.  The next
   1492       1.1  christos 	 symbol is the symbol to associate the warning with.  If a
   1493       1.1  christos 	 reference is made to that symbol, a warning is issued.  */
   1494       1.1  christos       cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
   1495       1.1  christos       cache_ptr->symbol.section = bfd_abs_section_ptr;
   1496       1.1  christos       break;
   1497       1.1  christos 
   1498       1.1  christos     case N_INDR: case N_INDR | N_EXT:
   1499       1.1  christos       /* An indirect symbol.  This consists of two symbols in a row.
   1500       1.1  christos 	 The first symbol is the name of the indirection.  The second
   1501       1.1  christos 	 symbol is the name of the target.  A reference to the first
   1502       1.1  christos 	 symbol becomes a reference to the second.  */
   1503       1.1  christos       cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT | visible;
   1504       1.1  christos       cache_ptr->symbol.section = bfd_ind_section_ptr;
   1505       1.1  christos       break;
   1506       1.1  christos 
   1507       1.1  christos     case N_WEAKU:
   1508       1.1  christos       cache_ptr->symbol.section = bfd_und_section_ptr;
   1509       1.1  christos       cache_ptr->symbol.flags = BSF_WEAK;
   1510       1.1  christos       break;
   1511       1.1  christos 
   1512       1.1  christos     case N_WEAKA:
   1513       1.1  christos       cache_ptr->symbol.section = bfd_abs_section_ptr;
   1514       1.1  christos       cache_ptr->symbol.flags = BSF_WEAK;
   1515       1.1  christos       break;
   1516       1.1  christos 
   1517       1.1  christos     case N_WEAKT:
   1518       1.1  christos       cache_ptr->symbol.section = obj_textsec (abfd);
   1519       1.1  christos       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
   1520       1.1  christos       cache_ptr->symbol.flags = BSF_WEAK;
   1521       1.1  christos       break;
   1522       1.1  christos 
   1523       1.1  christos     case N_WEAKD:
   1524       1.1  christos       cache_ptr->symbol.section = obj_datasec (abfd);
   1525       1.1  christos       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
   1526       1.1  christos       cache_ptr->symbol.flags = BSF_WEAK;
   1527       1.1  christos       break;
   1528       1.1  christos 
   1529       1.1  christos     case N_WEAKB:
   1530       1.1  christos       cache_ptr->symbol.section = obj_bsssec (abfd);
   1531       1.1  christos       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
   1532       1.1  christos       cache_ptr->symbol.flags = BSF_WEAK;
   1533       1.1  christos       break;
   1534       1.1  christos     }
   1535   1.1.1.9  christos 
   1536       1.1  christos   return true;
   1537       1.1  christos }
   1538       1.1  christos 
   1539       1.1  christos /* Set the fields of SYM_POINTER according to CACHE_PTR.  */
   1540   1.1.1.9  christos 
   1541       1.1  christos static bool
   1542       1.1  christos translate_to_native_sym_flags (bfd *abfd,
   1543       1.1  christos 			       asymbol *cache_ptr,
   1544       1.1  christos 			       struct external_nlist *sym_pointer)
   1545       1.1  christos {
   1546       1.1  christos   bfd_vma value = cache_ptr->value;
   1547       1.1  christos   asection *sec;
   1548       1.1  christos   bfd_vma off;
   1549       1.1  christos 
   1550       1.1  christos   /* Mask out any existing type bits in case copying from one section
   1551       1.1  christos      to another.  */
   1552       1.1  christos   sym_pointer->e_type[0] &= ~N_TYPE;
   1553   1.1.1.8  christos 
   1554       1.1  christos   sec = bfd_asymbol_section (cache_ptr);
   1555       1.1  christos   off = 0;
   1556       1.1  christos 
   1557       1.1  christos   if (sec == NULL)
   1558       1.1  christos     {
   1559       1.1  christos       /* This case occurs, e.g., for the *DEBUG* section of a COFF
   1560   1.1.1.6  christos 	 file.  */
   1561   1.1.1.6  christos       _bfd_error_handler
   1562   1.1.1.7  christos 	/* xgettext:c-format */
   1563   1.1.1.6  christos 	(_("%pB: can not represent section for symbol `%s' in a.out "
   1564   1.1.1.6  christos 	   "object file format"),
   1565       1.1  christos 	 abfd,
   1566       1.1  christos 	 cache_ptr->name != NULL ? cache_ptr->name : _("*unknown*"));
   1567   1.1.1.9  christos       bfd_set_error (bfd_error_nonrepresentable_section);
   1568       1.1  christos       return false;
   1569       1.1  christos     }
   1570       1.1  christos 
   1571       1.1  christos   if (sec->output_section != NULL)
   1572       1.1  christos     {
   1573       1.1  christos       off = sec->output_offset;
   1574       1.1  christos       sec = sec->output_section;
   1575       1.1  christos     }
   1576       1.1  christos 
   1577       1.1  christos   if (bfd_is_abs_section (sec))
   1578       1.1  christos     sym_pointer->e_type[0] |= N_ABS;
   1579       1.1  christos   else if (sec == obj_textsec (abfd))
   1580       1.1  christos     sym_pointer->e_type[0] |= N_TEXT;
   1581       1.1  christos   else if (sec == obj_datasec (abfd))
   1582       1.1  christos     sym_pointer->e_type[0] |= N_DATA;
   1583       1.1  christos   else if (sec == obj_bsssec (abfd))
   1584       1.1  christos     sym_pointer->e_type[0] |= N_BSS;
   1585       1.1  christos   else if (bfd_is_und_section (sec))
   1586       1.1  christos     sym_pointer->e_type[0] = N_UNDF | N_EXT;
   1587       1.1  christos   else if (bfd_is_ind_section (sec))
   1588       1.1  christos     sym_pointer->e_type[0] = N_INDR;
   1589       1.1  christos   else if (bfd_is_com_section (sec))
   1590       1.1  christos     sym_pointer->e_type[0] = N_UNDF | N_EXT;
   1591       1.1  christos   else
   1592       1.1  christos     {
   1593       1.1  christos       if (aout_section_merge_with_text_p (abfd, sec))
   1594       1.1  christos 	sym_pointer->e_type[0] |= N_TEXT;
   1595       1.1  christos       else
   1596   1.1.1.6  christos 	{
   1597   1.1.1.6  christos 	  _bfd_error_handler
   1598   1.1.1.7  christos 	    /* xgettext:c-format */
   1599   1.1.1.6  christos 	   (_("%pB: can not represent section `%pA' in a.out object file format"),
   1600   1.1.1.7  christos 	     abfd, sec);
   1601   1.1.1.9  christos 	  bfd_set_error (bfd_error_nonrepresentable_section);
   1602       1.1  christos 	  return false;
   1603       1.1  christos 	}
   1604       1.1  christos     }
   1605       1.1  christos 
   1606       1.1  christos   /* Turn the symbol from section relative to absolute again.  */
   1607       1.1  christos   value += sec->vma + off;
   1608       1.1  christos 
   1609       1.1  christos   if ((cache_ptr->flags & BSF_WARNING) != 0)
   1610       1.1  christos     sym_pointer->e_type[0] = N_WARNING;
   1611       1.1  christos 
   1612       1.1  christos   if ((cache_ptr->flags & BSF_DEBUGGING) != 0)
   1613       1.1  christos     sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
   1614       1.1  christos   else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
   1615       1.1  christos     sym_pointer->e_type[0] |= N_EXT;
   1616       1.1  christos   else if ((cache_ptr->flags & BSF_LOCAL) != 0)
   1617       1.1  christos     sym_pointer->e_type[0] &= ~N_EXT;
   1618       1.1  christos 
   1619       1.1  christos   if ((cache_ptr->flags & BSF_CONSTRUCTOR) != 0)
   1620       1.1  christos     {
   1621       1.1  christos       int type = ((aout_symbol_type *) cache_ptr)->type;
   1622       1.1  christos 
   1623       1.1  christos       switch (type)
   1624       1.1  christos 	{
   1625       1.1  christos 	case N_ABS:	type = N_SETA; break;
   1626       1.1  christos 	case N_TEXT:	type = N_SETT; break;
   1627       1.1  christos 	case N_DATA:	type = N_SETD; break;
   1628       1.1  christos 	case N_BSS:	type = N_SETB; break;
   1629       1.1  christos 	}
   1630       1.1  christos       sym_pointer->e_type[0] = type;
   1631       1.1  christos     }
   1632       1.1  christos 
   1633       1.1  christos   if ((cache_ptr->flags & BSF_WEAK) != 0)
   1634       1.1  christos     {
   1635       1.1  christos       int type;
   1636       1.1  christos 
   1637       1.1  christos       switch (sym_pointer->e_type[0] & N_TYPE)
   1638       1.1  christos 	{
   1639       1.1  christos 	default:
   1640       1.1  christos 	case N_ABS:	type = N_WEAKA; break;
   1641       1.1  christos 	case N_TEXT:	type = N_WEAKT; break;
   1642       1.1  christos 	case N_DATA:	type = N_WEAKD; break;
   1643       1.1  christos 	case N_BSS:	type = N_WEAKB; break;
   1644       1.1  christos 	case N_UNDF:	type = N_WEAKU; break;
   1645       1.1  christos 	}
   1646       1.1  christos       sym_pointer->e_type[0] = type;
   1647       1.1  christos     }
   1648       1.1  christos 
   1649       1.1  christos   PUT_WORD (abfd, value, sym_pointer->e_value);
   1650   1.1.1.9  christos 
   1651       1.1  christos   return true;
   1652       1.1  christos }
   1653       1.1  christos 
   1654       1.1  christos /* Native-level interface to symbols.  */
   1656       1.1  christos 
   1657       1.1  christos asymbol *
   1658   1.1.1.8  christos NAME (aout, make_empty_symbol) (bfd *abfd)
   1659       1.1  christos {
   1660       1.1  christos   size_t amt = sizeof (aout_symbol_type);
   1661       1.1  christos 
   1662       1.1  christos   aout_symbol_type *new_symbol = (aout_symbol_type *) bfd_zalloc (abfd, amt);
   1663       1.1  christos   if (!new_symbol)
   1664       1.1  christos     return NULL;
   1665       1.1  christos   new_symbol->symbol.the_bfd = abfd;
   1666       1.1  christos 
   1667       1.1  christos   return &new_symbol->symbol;
   1668   1.1.1.8  christos }
   1669       1.1  christos 
   1670   1.1.1.9  christos /* Translate a set of external symbols into internal symbols.  */
   1671       1.1  christos 
   1672       1.1  christos bool
   1673       1.1  christos NAME (aout, translate_symbol_table) (bfd *abfd,
   1674       1.1  christos 				     aout_symbol_type *in,
   1675       1.1  christos 				     struct external_nlist *ext,
   1676       1.1  christos 				     bfd_size_type count,
   1677   1.1.1.9  christos 				     char *str,
   1678       1.1  christos 				     bfd_size_type strsize,
   1679       1.1  christos 				     bool dynamic)
   1680       1.1  christos {
   1681       1.1  christos   struct external_nlist *ext_end;
   1682       1.1  christos 
   1683       1.1  christos   ext_end = ext + count;
   1684       1.1  christos   for (; ext < ext_end; ext++, in++)
   1685       1.1  christos     {
   1686       1.1  christos       bfd_vma x;
   1687       1.1  christos 
   1688       1.1  christos       x = GET_WORD (abfd, ext->e_strx);
   1689       1.1  christos       in->symbol.the_bfd = abfd;
   1690       1.1  christos 
   1691       1.1  christos       /* For the normal symbols, the zero index points at the number
   1692       1.1  christos 	 of bytes in the string table but is to be interpreted as the
   1693       1.1  christos 	 null string.  For the dynamic symbols, the number of bytes in
   1694       1.1  christos 	 the string table is stored in the __DYNAMIC structure and the
   1695       1.1  christos 	 zero index points at an actual string.  */
   1696       1.1  christos       if (x == 0 && ! dynamic)
   1697       1.1  christos 	in->symbol.name = "";
   1698       1.1  christos       else if (x < strsize)
   1699   1.1.1.7  christos 	in->symbol.name = str + x;
   1700   1.1.1.7  christos       else
   1701   1.1.1.7  christos 	{
   1702   1.1.1.7  christos 	  _bfd_error_handler
   1703   1.1.1.7  christos 	    (_("%pB: invalid string offset %" PRIu64 " >= %" PRIu64),
   1704   1.1.1.9  christos 	     abfd, (uint64_t) x, (uint64_t) strsize);
   1705   1.1.1.7  christos 	  bfd_set_error (bfd_error_bad_value);
   1706       1.1  christos 	  return false;
   1707       1.1  christos 	}
   1708       1.1  christos 
   1709       1.1  christos       in->symbol.value = GET_SWORD (abfd,  ext->e_value);
   1710       1.1  christos       in->desc = H_GET_16 (abfd, ext->e_desc);
   1711       1.1  christos       in->other = H_GET_8 (abfd, ext->e_other);
   1712       1.1  christos       in->type = H_GET_8 (abfd,  ext->e_type);
   1713       1.1  christos       in->symbol.udata.p = NULL;
   1714   1.1.1.9  christos 
   1715       1.1  christos       if (! translate_from_native_sym_flags (abfd, in))
   1716       1.1  christos 	return false;
   1717       1.1  christos 
   1718       1.1  christos       if (dynamic)
   1719       1.1  christos 	in->symbol.flags |= BSF_DYNAMIC;
   1720   1.1.1.9  christos     }
   1721       1.1  christos 
   1722       1.1  christos   return true;
   1723       1.1  christos }
   1724       1.1  christos 
   1725       1.1  christos /* We read the symbols into a buffer, which is discarded when this
   1726       1.1  christos    function exits.  We read the strings into a buffer large enough to
   1727   1.1.1.9  christos    hold them all plus all the cached symbol entries.  */
   1728       1.1  christos 
   1729       1.1  christos bool
   1730       1.1  christos NAME (aout, slurp_symbol_table) (bfd *abfd)
   1731       1.1  christos {
   1732       1.1  christos   struct external_nlist *old_external_syms;
   1733       1.1  christos   aout_symbol_type *cached;
   1734       1.1  christos   bfd_size_type cached_size;
   1735       1.1  christos 
   1736   1.1.1.9  christos   /* If there's no work to be done, don't do any.  */
   1737       1.1  christos   if (obj_aout_symbols (abfd) != NULL)
   1738       1.1  christos     return true;
   1739       1.1  christos 
   1740       1.1  christos   old_external_syms = obj_aout_external_syms (abfd);
   1741   1.1.1.9  christos 
   1742       1.1  christos   if (! aout_get_external_symbols (abfd))
   1743       1.1  christos     return false;
   1744       1.1  christos 
   1745   1.1.1.9  christos   cached_size = obj_aout_external_sym_count (abfd);
   1746       1.1  christos   if (cached_size == 0)
   1747       1.1  christos     return true;		/* Nothing to do.  */
   1748       1.1  christos 
   1749       1.1  christos   cached_size *= sizeof (aout_symbol_type);
   1750   1.1.1.9  christos   cached = (aout_symbol_type *) bfd_zmalloc (cached_size);
   1751       1.1  christos   if (cached == NULL)
   1752       1.1  christos     return false;
   1753       1.1  christos 
   1754       1.1  christos   /* Convert from external symbol information to internal.  */
   1755       1.1  christos   if (! (NAME (aout, translate_symbol_table)
   1756       1.1  christos 	 (abfd, cached,
   1757       1.1  christos 	  obj_aout_external_syms (abfd),
   1758       1.1  christos 	  obj_aout_external_sym_count (abfd),
   1759   1.1.1.9  christos 	  obj_aout_external_strings (abfd),
   1760       1.1  christos 	  obj_aout_external_string_size (abfd),
   1761       1.1  christos 	  false)))
   1762   1.1.1.9  christos     {
   1763       1.1  christos       free (cached);
   1764       1.1  christos       return false;
   1765   1.1.1.8  christos     }
   1766       1.1  christos 
   1767       1.1  christos   abfd->symcount = obj_aout_external_sym_count (abfd);
   1768       1.1  christos 
   1769       1.1  christos   obj_aout_symbols (abfd) = cached;
   1770       1.1  christos 
   1771       1.1  christos   /* It is very likely that anybody who calls this function will not
   1772       1.1  christos      want the external symbol information, so if it was allocated
   1773       1.1  christos      because of our call to aout_get_external_symbols, we free it up
   1774       1.1  christos      right away to save space.  */
   1775       1.1  christos   if (old_external_syms == NULL
   1776       1.1  christos       && obj_aout_external_syms (abfd) != NULL)
   1777       1.1  christos     {
   1778       1.1  christos       free (obj_aout_external_syms (abfd));
   1779       1.1  christos       obj_aout_external_syms (abfd) = NULL;
   1780   1.1.1.9  christos     }
   1781       1.1  christos 
   1782       1.1  christos   return true;
   1783       1.1  christos }
   1784       1.1  christos 
   1785       1.1  christos /* We use a hash table when writing out symbols so that we only write
   1787       1.1  christos    out a particular string once.  This helps particularly when the
   1788       1.1  christos    linker writes out stabs debugging entries, because each different
   1789       1.1  christos    contributing object file tends to have many duplicate stabs
   1790       1.1  christos    strings.
   1791       1.1  christos 
   1792       1.1  christos    This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
   1793       1.1  christos    if BFD_TRADITIONAL_FORMAT is set.  */
   1794       1.1  christos 
   1795       1.1  christos /* Get the index of a string in a strtab, adding it if it is not
   1796       1.1  christos    already present.  */
   1797       1.1  christos 
   1798       1.1  christos static inline bfd_size_type
   1799   1.1.1.9  christos add_to_stringtab (bfd *abfd,
   1800       1.1  christos 		  struct bfd_strtab_hash *tab,
   1801   1.1.1.9  christos 		  const char *str,
   1802       1.1  christos 		  bool copy)
   1803       1.1  christos {
   1804       1.1  christos   bool hash;
   1805       1.1  christos   bfd_size_type str_index;
   1806       1.1  christos 
   1807       1.1  christos   /* An index of 0 always means the empty string.  */
   1808       1.1  christos   if (str == 0 || *str == '\0')
   1809       1.1  christos     return 0;
   1810   1.1.1.9  christos 
   1811       1.1  christos   /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
   1812   1.1.1.9  christos      doesn't understand a hashed string table.  */
   1813       1.1  christos   hash = true;
   1814       1.1  christos   if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
   1815       1.1  christos     hash = false;
   1816       1.1  christos 
   1817       1.1  christos   str_index = _bfd_stringtab_add (tab, str, hash, copy);
   1818       1.1  christos 
   1819       1.1  christos   if (str_index != (bfd_size_type) -1)
   1820       1.1  christos     /* Add BYTES_IN_WORD to the return value to account for the
   1821       1.1  christos        space taken up by the string table size.  */
   1822       1.1  christos     str_index += BYTES_IN_WORD;
   1823       1.1  christos 
   1824       1.1  christos   return str_index;
   1825       1.1  christos }
   1826       1.1  christos 
   1827   1.1.1.9  christos /* Write out a strtab.  ABFD is already at the right location in the
   1828       1.1  christos    file.  */
   1829       1.1  christos 
   1830       1.1  christos static bool
   1831   1.1.1.8  christos emit_stringtab (bfd *abfd, struct bfd_strtab_hash *tab)
   1832       1.1  christos {
   1833       1.1  christos   bfd_byte buffer[BYTES_IN_WORD];
   1834       1.1  christos   size_t amt = BYTES_IN_WORD;
   1835  1.1.1.10  christos 
   1836   1.1.1.9  christos   /* The string table starts with the size.  */
   1837       1.1  christos   PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer);
   1838       1.1  christos   if (bfd_write (buffer, amt, abfd) != amt)
   1839       1.1  christos     return false;
   1840       1.1  christos 
   1841   1.1.1.9  christos   return _bfd_stringtab_emit (abfd, tab);
   1842       1.1  christos }
   1843       1.1  christos 
   1844       1.1  christos bool
   1846       1.1  christos NAME (aout, write_syms) (bfd *abfd)
   1847       1.1  christos {
   1848       1.1  christos   unsigned int count ;
   1849       1.1  christos   asymbol **generic = bfd_get_outsymbols (abfd);
   1850   1.1.1.9  christos   struct bfd_strtab_hash *strtab;
   1851       1.1  christos 
   1852       1.1  christos   strtab = _bfd_stringtab_init ();
   1853       1.1  christos   if (strtab == NULL)
   1854       1.1  christos     return false;
   1855       1.1  christos 
   1856       1.1  christos   for (count = 0; count < bfd_get_symcount (abfd); count++)
   1857   1.1.1.8  christos     {
   1858       1.1  christos       asymbol *g = generic[count];
   1859   1.1.1.9  christos       bfd_size_type indx;
   1860       1.1  christos       struct external_nlist nsp;
   1861       1.1  christos       size_t amt;
   1862       1.1  christos 
   1863       1.1  christos       indx = add_to_stringtab (abfd, strtab, g->name, false);
   1864       1.1  christos       if (indx == (bfd_size_type) -1)
   1865       1.1  christos 	goto error_return;
   1866       1.1  christos       PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx);
   1867       1.1  christos 
   1868       1.1  christos       if (bfd_asymbol_flavour (g) == abfd->xvec->flavour)
   1869       1.1  christos 	{
   1870       1.1  christos 	  H_PUT_16 (abfd, aout_symbol (g)->desc,  nsp.e_desc);
   1871       1.1  christos 	  H_PUT_8  (abfd, aout_symbol (g)->other, nsp.e_other);
   1872       1.1  christos 	  H_PUT_8  (abfd, aout_symbol (g)->type,  nsp.e_type);
   1873       1.1  christos 	}
   1874       1.1  christos       else
   1875       1.1  christos 	{
   1876       1.1  christos 	  H_PUT_16 (abfd, 0, nsp.e_desc);
   1877       1.1  christos 	  H_PUT_8  (abfd, 0, nsp.e_other);
   1878       1.1  christos 	  H_PUT_8  (abfd, 0, nsp.e_type);
   1879       1.1  christos 	}
   1880       1.1  christos 
   1881  1.1.1.10  christos       if (! translate_to_native_sym_flags (abfd, g, &nsp))
   1882       1.1  christos 	goto error_return;
   1883       1.1  christos 
   1884       1.1  christos       amt = EXTERNAL_NLIST_SIZE;
   1885       1.1  christos       if (bfd_write (&nsp, amt, abfd) != amt)
   1886       1.1  christos 	goto error_return;
   1887       1.1  christos 
   1888       1.1  christos       /* NB: `KEEPIT' currently overlays `udata.p', so set this only
   1889       1.1  christos 	 here, at the end.  */
   1890       1.1  christos       g->KEEPIT = count;
   1891       1.1  christos     }
   1892       1.1  christos 
   1893       1.1  christos   if (! emit_stringtab (abfd, strtab))
   1894   1.1.1.9  christos     goto error_return;
   1895       1.1  christos 
   1896   1.1.1.8  christos   _bfd_stringtab_free (strtab);
   1897       1.1  christos 
   1898   1.1.1.9  christos   return true;
   1899       1.1  christos 
   1900       1.1  christos  error_return:
   1901       1.1  christos   _bfd_stringtab_free (strtab);
   1902       1.1  christos   return false;
   1903       1.1  christos }
   1904       1.1  christos 
   1905       1.1  christos long
   1907       1.1  christos NAME (aout, canonicalize_symtab) (bfd *abfd, asymbol **location)
   1908       1.1  christos {
   1909       1.1  christos   unsigned int counter = 0;
   1910       1.1  christos   aout_symbol_type *symbase;
   1911       1.1  christos 
   1912       1.1  christos   if (!NAME (aout, slurp_symbol_table) (abfd))
   1913       1.1  christos     return -1;
   1914       1.1  christos 
   1915       1.1  christos   for (symbase = obj_aout_symbols (abfd);
   1916       1.1  christos        counter++ < bfd_get_symcount (abfd);
   1917       1.1  christos        )
   1918       1.1  christos     *(location++) = (asymbol *) (symbase++);
   1919       1.1  christos   *location++ =0;
   1920       1.1  christos   return bfd_get_symcount (abfd);
   1921       1.1  christos }
   1922       1.1  christos 
   1923       1.1  christos /* Standard reloc stuff.  */
   1925       1.1  christos /* Output standard relocation information to a file in target byte order.  */
   1926       1.1  christos 
   1927       1.1  christos extern void  NAME (aout, swap_std_reloc_out)
   1928       1.1  christos   (bfd *, arelent *, struct reloc_std_external *);
   1929       1.1  christos 
   1930       1.1  christos void
   1931       1.1  christos NAME (aout, swap_std_reloc_out) (bfd *abfd,
   1932   1.1.1.9  christos 				 arelent *g,
   1933       1.1  christos 				 struct reloc_std_external *natptr)
   1934       1.1  christos {
   1935       1.1  christos   int r_index;
   1936       1.1  christos   asymbol *sym = *(g->sym_ptr_ptr);
   1937       1.1  christos   int r_extern;
   1938       1.1  christos   unsigned int r_length, r_size;
   1939   1.1.1.6  christos   int r_pcrel;
   1940   1.1.1.8  christos   int r_baserel, r_jmptable, r_relative;
   1941   1.1.1.9  christos   asection *output_section = sym->section->output_section;
   1942   1.1.1.9  christos 
   1943   1.1.1.9  christos   PUT_WORD (abfd, g->address, natptr->r_address);
   1944   1.1.1.8  christos 
   1945   1.1.1.8  christos   BFD_ASSERT (g->howto != NULL);
   1946   1.1.1.9  christos 
   1947   1.1.1.8  christos   r_size = bfd_get_reloc_size (g->howto);
   1948   1.1.1.8  christos   r_length = bfd_log2 (r_size);
   1949   1.1.1.8  christos   if (1u << r_length != r_size)
   1950   1.1.1.8  christos     {
   1951       1.1  christos       _bfd_error_handler (_("%pB: unsupported AOUT relocation size: %d"),
   1952       1.1  christos 			  abfd, r_size);
   1953       1.1  christos       bfd_set_error (bfd_error_bad_value);
   1954       1.1  christos       return;
   1955       1.1  christos     }
   1956       1.1  christos 
   1957       1.1  christos   r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC?  */
   1958       1.1  christos   /* XXX This relies on relocs coming from a.out files.  */
   1959       1.1  christos   r_baserel = (g->howto->type & 8) != 0;
   1960       1.1  christos   r_jmptable = (g->howto->type & 16) != 0;
   1961       1.1  christos   r_relative = (g->howto->type & 32) != 0;
   1962       1.1  christos 
   1963       1.1  christos   /* Name was clobbered by aout_write_syms to be symbol index.  */
   1964       1.1  christos 
   1965       1.1  christos   /* If this relocation is relative to a symbol then set the
   1966       1.1  christos      r_index to the symbols index, and the r_extern bit.
   1967       1.1  christos 
   1968       1.1  christos      Absolute symbols can come in in two ways, either as an offset
   1969       1.1  christos      from the abs section, or as a symbol which has an abs value.
   1970       1.1  christos      check for that here.  */
   1971       1.1  christos 
   1972       1.1  christos   if (bfd_is_com_section (output_section)
   1973       1.1  christos       || bfd_is_abs_section (output_section)
   1974       1.1  christos       || bfd_is_und_section (output_section)
   1975       1.1  christos       /* PR gas/3041  a.out relocs against weak symbols
   1976       1.1  christos 	 must be treated as if they were against externs.  */
   1977       1.1  christos       || (sym->flags & BSF_WEAK))
   1978       1.1  christos     {
   1979       1.1  christos       if (bfd_abs_section_ptr->symbol == sym)
   1980       1.1  christos 	{
   1981       1.1  christos 	  /* Whoops, looked like an abs symbol, but is
   1982       1.1  christos 	     really an offset from the abs section.  */
   1983       1.1  christos 	  r_index = N_ABS;
   1984       1.1  christos 	  r_extern = 0;
   1985       1.1  christos 	}
   1986       1.1  christos       else
   1987       1.1  christos 	{
   1988       1.1  christos 	  /* Fill in symbol.  */
   1989       1.1  christos 	  r_extern = 1;
   1990       1.1  christos 	  r_index = (*(g->sym_ptr_ptr))->KEEPIT;
   1991       1.1  christos 	}
   1992       1.1  christos     }
   1993       1.1  christos   else
   1994       1.1  christos     {
   1995       1.1  christos       /* Just an ordinary section.  */
   1996       1.1  christos       r_extern = 0;
   1997       1.1  christos       r_index  = output_section->target_index;
   1998       1.1  christos     }
   1999       1.1  christos 
   2000       1.1  christos   /* Now the fun stuff.  */
   2001       1.1  christos   if (bfd_header_big_endian (abfd))
   2002       1.1  christos     {
   2003       1.1  christos       natptr->r_index[0] = r_index >> 16;
   2004       1.1  christos       natptr->r_index[1] = r_index >> 8;
   2005       1.1  christos       natptr->r_index[2] = r_index;
   2006       1.1  christos       natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
   2007       1.1  christos 			   | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
   2008       1.1  christos 			   | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
   2009       1.1  christos 			   | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
   2010       1.1  christos 			   | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
   2011       1.1  christos 			   | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
   2012       1.1  christos     }
   2013       1.1  christos   else
   2014       1.1  christos     {
   2015       1.1  christos       natptr->r_index[2] = r_index >> 16;
   2016       1.1  christos       natptr->r_index[1] = r_index >> 8;
   2017       1.1  christos       natptr->r_index[0] = r_index;
   2018       1.1  christos       natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
   2019       1.1  christos 			   | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
   2020       1.1  christos 			   | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
   2021       1.1  christos 			   | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
   2022       1.1  christos 			   | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
   2023       1.1  christos 			   | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
   2024       1.1  christos     }
   2025       1.1  christos }
   2026       1.1  christos 
   2027       1.1  christos /* Extended stuff.  */
   2028       1.1  christos /* Output extended relocation information to a file in target byte order.  */
   2029       1.1  christos 
   2030       1.1  christos extern void NAME (aout, swap_ext_reloc_out)
   2031       1.1  christos   (bfd *, arelent *, struct reloc_ext_external *);
   2032       1.1  christos 
   2033       1.1  christos void
   2034       1.1  christos NAME (aout, swap_ext_reloc_out) (bfd *abfd,
   2035       1.1  christos 				 arelent *g,
   2036       1.1  christos 				 struct reloc_ext_external *natptr)
   2037       1.1  christos {
   2038       1.1  christos   int r_index;
   2039       1.1  christos   int r_extern;
   2040       1.1  christos   unsigned int r_type;
   2041       1.1  christos   bfd_vma r_addend;
   2042       1.1  christos   asymbol *sym = *(g->sym_ptr_ptr);
   2043       1.1  christos   asection *output_section = sym->section->output_section;
   2044       1.1  christos 
   2045       1.1  christos   PUT_WORD (abfd, g->address, natptr->r_address);
   2046       1.1  christos 
   2047       1.1  christos   r_type = (unsigned int) g->howto->type;
   2048       1.1  christos 
   2049       1.1  christos   r_addend = g->addend;
   2050       1.1  christos   if ((sym->flags & BSF_SECTION_SYM) != 0)
   2051       1.1  christos     r_addend += (*(g->sym_ptr_ptr))->section->output_section->vma;
   2052       1.1  christos 
   2053   1.1.1.8  christos   /* If this relocation is relative to a symbol then set the
   2054       1.1  christos      r_index to the symbols index, and the r_extern bit.
   2055       1.1  christos 
   2056       1.1  christos      Absolute symbols can come in in two ways, either as an offset
   2057       1.1  christos      from the abs section, or as a symbol which has an abs value.
   2058       1.1  christos      check for that here.  */
   2059       1.1  christos   if (bfd_is_abs_section (bfd_asymbol_section (sym)))
   2060   1.1.1.8  christos     {
   2061       1.1  christos       r_extern = 0;
   2062       1.1  christos       r_index = N_ABS;
   2063       1.1  christos     }
   2064       1.1  christos   else if ((sym->flags & BSF_SECTION_SYM) == 0)
   2065       1.1  christos     {
   2066       1.1  christos       if (bfd_is_und_section (bfd_asymbol_section (sym))
   2067       1.1  christos 	  || (sym->flags & BSF_GLOBAL) != 0)
   2068       1.1  christos 	r_extern = 1;
   2069       1.1  christos       else
   2070       1.1  christos 	r_extern = 0;
   2071       1.1  christos       r_index = (*(g->sym_ptr_ptr))->KEEPIT;
   2072       1.1  christos     }
   2073       1.1  christos   else
   2074       1.1  christos     {
   2075       1.1  christos       /* Just an ordinary section.  */
   2076       1.1  christos       r_extern = 0;
   2077       1.1  christos       r_index = output_section->target_index;
   2078       1.1  christos     }
   2079       1.1  christos 
   2080       1.1  christos   /* Now the fun stuff.  */
   2081       1.1  christos   if (bfd_header_big_endian (abfd))
   2082       1.1  christos     {
   2083       1.1  christos       natptr->r_index[0] = r_index >> 16;
   2084       1.1  christos       natptr->r_index[1] = r_index >> 8;
   2085       1.1  christos       natptr->r_index[2] = r_index;
   2086       1.1  christos       natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
   2087       1.1  christos 			   | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
   2088       1.1  christos     }
   2089       1.1  christos   else
   2090       1.1  christos     {
   2091       1.1  christos       natptr->r_index[2] = r_index >> 16;
   2092       1.1  christos       natptr->r_index[1] = r_index >> 8;
   2093       1.1  christos       natptr->r_index[0] = r_index;
   2094       1.1  christos       natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
   2095       1.1  christos 			   | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE));
   2096       1.1  christos     }
   2097       1.1  christos 
   2098       1.1  christos   PUT_WORD (abfd, r_addend, natptr->r_addend);
   2099       1.1  christos }
   2100       1.1  christos 
   2101       1.1  christos /* BFD deals internally with all things based from the section they're
   2102       1.1  christos    in. so, something in 10 bytes into a text section  with a base of
   2103       1.1  christos    50 would have a symbol (.text+10) and know .text vma was 50.
   2104       1.1  christos 
   2105       1.1  christos    Aout keeps all it's symbols based from zero, so the symbol would
   2106       1.1  christos    contain 60. This macro subs the base of each section from the value
   2107   1.1.1.9  christos    to give the true offset from the section.  */
   2108   1.1.1.9  christos 
   2109   1.1.1.9  christos #define MOVE_ADDRESS(ad)						\
   2110  1.1.1.11  christos   if (r_extern)								\
   2111       1.1  christos     {									\
   2112       1.1  christos       /* Undefined symbol.  */						\
   2113       1.1  christos       if (symbols != NULL && r_index < bfd_get_symcount (abfd))		\
   2114       1.1  christos 	cache_ptr->sym_ptr_ptr = symbols + r_index;			\
   2115       1.1  christos       else								\
   2116       1.1  christos 	cache_ptr->sym_ptr_ptr = &bfd_abs_section_ptr->symbol;		\
   2117       1.1  christos       cache_ptr->addend = ad;						\
   2118       1.1  christos     }									\
   2119       1.1  christos    else									\
   2120       1.1  christos     {									\
   2121  1.1.1.11  christos       /* Defined, section relative.  Replace symbol with pointer to	\
   2122       1.1  christos 	 symbol which points to section.  */				\
   2123       1.1  christos       switch (r_index)							\
   2124       1.1  christos 	{								\
   2125       1.1  christos 	case N_TEXT:							\
   2126  1.1.1.11  christos 	case N_TEXT | N_EXT:						\
   2127       1.1  christos 	  cache_ptr->sym_ptr_ptr = &obj_textsec (abfd)->symbol;		\
   2128       1.1  christos 	  cache_ptr->addend = ad - su->textsec->vma;			\
   2129       1.1  christos 	  break;							\
   2130       1.1  christos 	case N_DATA:							\
   2131  1.1.1.11  christos 	case N_DATA | N_EXT:						\
   2132       1.1  christos 	  cache_ptr->sym_ptr_ptr = &obj_datasec (abfd)->symbol;		\
   2133       1.1  christos 	  cache_ptr->addend = ad - su->datasec->vma;			\
   2134       1.1  christos 	  break;							\
   2135       1.1  christos 	case N_BSS:							\
   2136       1.1  christos 	case N_BSS | N_EXT:						\
   2137  1.1.1.11  christos 	  cache_ptr->sym_ptr_ptr = &obj_bsssec (abfd)->symbol;		\
   2138       1.1  christos 	  cache_ptr->addend = ad - su->bsssec->vma;			\
   2139       1.1  christos 	  break;							\
   2140       1.1  christos 	default:							\
   2141       1.1  christos 	case N_ABS:							\
   2142       1.1  christos 	case N_ABS | N_EXT:						\
   2143       1.1  christos 	  cache_ptr->sym_ptr_ptr = &bfd_abs_section_ptr->symbol;	\
   2144       1.1  christos 	  cache_ptr->addend = ad;					\
   2145       1.1  christos 	  break;							\
   2146       1.1  christos 	}								\
   2147       1.1  christos     }
   2148       1.1  christos 
   2149       1.1  christos void
   2150       1.1  christos NAME (aout, swap_ext_reloc_in) (bfd *abfd,
   2151       1.1  christos 				struct reloc_ext_external *bytes,
   2152       1.1  christos 				arelent *cache_ptr,
   2153       1.1  christos 				asymbol **symbols,
   2154       1.1  christos 				bfd_size_type symcount)
   2155       1.1  christos {
   2156       1.1  christos   unsigned int r_index;
   2157       1.1  christos   int r_extern;
   2158       1.1  christos   unsigned int r_type;
   2159       1.1  christos   struct aoutdata *su = &(abfd->tdata.aout_data->a);
   2160       1.1  christos 
   2161       1.1  christos   cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
   2162       1.1  christos 
   2163       1.1  christos   /* Now the fun stuff.  */
   2164       1.1  christos   if (bfd_header_big_endian (abfd))
   2165       1.1  christos     {
   2166       1.1  christos       r_index = (((unsigned int) bytes->r_index[0] << 16)
   2167       1.1  christos 		 | ((unsigned int) bytes->r_index[1] << 8)
   2168       1.1  christos 		 | bytes->r_index[2]);
   2169       1.1  christos       r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
   2170       1.1  christos       r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
   2171       1.1  christos 		>> RELOC_EXT_BITS_TYPE_SH_BIG);
   2172       1.1  christos     }
   2173       1.1  christos   else
   2174       1.1  christos     {
   2175       1.1  christos       r_index =  (((unsigned int) bytes->r_index[2] << 16)
   2176       1.1  christos 		  | ((unsigned int) bytes->r_index[1] << 8)
   2177       1.1  christos 		  | bytes->r_index[0]);
   2178       1.1  christos       r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
   2179       1.1  christos       r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
   2180       1.1  christos 		>> RELOC_EXT_BITS_TYPE_SH_LITTLE);
   2181       1.1  christos     }
   2182       1.1  christos 
   2183       1.1  christos   if (r_type < TABLE_SIZE (howto_table_ext))
   2184       1.1  christos     cache_ptr->howto = howto_table_ext + r_type;
   2185       1.1  christos   else
   2186       1.1  christos     cache_ptr->howto = NULL;
   2187       1.1  christos 
   2188       1.1  christos   /* Base relative relocs are always against the symbol table,
   2189       1.1  christos      regardless of the setting of r_extern.  r_extern just reflects
   2190       1.1  christos      whether the symbol the reloc is against is local or global.  */
   2191       1.1  christos   if (r_type == (unsigned int) RELOC_BASE10
   2192       1.1  christos       || r_type == (unsigned int) RELOC_BASE13
   2193   1.1.1.7  christos       || r_type == (unsigned int) RELOC_BASE22)
   2194       1.1  christos     r_extern = 1;
   2195       1.1  christos 
   2196       1.1  christos   if (r_extern && r_index > symcount)
   2197       1.1  christos     {
   2198       1.1  christos       /* We could arrange to return an error, but it might be useful
   2199       1.1  christos 	 to see the file even if it is bad.  */
   2200       1.1  christos       r_extern = 0;
   2201       1.1  christos       r_index = N_ABS;
   2202       1.1  christos     }
   2203       1.1  christos 
   2204       1.1  christos   MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
   2205       1.1  christos }
   2206       1.1  christos 
   2207       1.1  christos void
   2208       1.1  christos NAME (aout, swap_std_reloc_in) (bfd *abfd,
   2209       1.1  christos 				struct reloc_std_external *bytes,
   2210       1.1  christos 				arelent *cache_ptr,
   2211       1.1  christos 				asymbol **symbols,
   2212       1.1  christos 				bfd_size_type symcount)
   2213       1.1  christos {
   2214       1.1  christos   unsigned int r_index;
   2215       1.1  christos   int r_extern;
   2216       1.1  christos   unsigned int r_length;
   2217       1.1  christos   int r_pcrel;
   2218       1.1  christos   int r_baserel, r_jmptable, r_relative;
   2219       1.1  christos   struct aoutdata  *su = &(abfd->tdata.aout_data->a);
   2220       1.1  christos   unsigned int howto_idx;
   2221       1.1  christos 
   2222       1.1  christos   cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
   2223       1.1  christos 
   2224       1.1  christos   /* Now the fun stuff.  */
   2225       1.1  christos   if (bfd_header_big_endian (abfd))
   2226       1.1  christos     {
   2227       1.1  christos       r_index = (((unsigned int) bytes->r_index[0] << 16)
   2228       1.1  christos 		 | ((unsigned int) bytes->r_index[1] << 8)
   2229       1.1  christos 		 | bytes->r_index[2]);
   2230       1.1  christos       r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
   2231       1.1  christos       r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
   2232       1.1  christos       r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
   2233       1.1  christos       r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
   2234       1.1  christos       r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
   2235       1.1  christos       r_length  = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
   2236       1.1  christos 		   >> RELOC_STD_BITS_LENGTH_SH_BIG);
   2237       1.1  christos     }
   2238       1.1  christos   else
   2239       1.1  christos     {
   2240       1.1  christos       r_index = (((unsigned int) bytes->r_index[2] << 16)
   2241       1.1  christos 		 | ((unsigned int) bytes->r_index[1] << 8)
   2242       1.1  christos 		 | bytes->r_index[0]);
   2243       1.1  christos       r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
   2244       1.1  christos       r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
   2245       1.1  christos       r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
   2246       1.1  christos       r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
   2247       1.1  christos       r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
   2248       1.1  christos       r_length  = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
   2249       1.1  christos 		   >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
   2250       1.1  christos     }
   2251       1.1  christos 
   2252       1.1  christos   howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
   2253       1.1  christos 	       + 16 * r_jmptable + 32 * r_relative);
   2254       1.1  christos   if (howto_idx < TABLE_SIZE (howto_table_std))
   2255       1.1  christos     {
   2256       1.1  christos       cache_ptr->howto = howto_table_std + howto_idx;
   2257       1.1  christos       if (cache_ptr->howto->type == (unsigned int) -1)
   2258       1.1  christos 	cache_ptr->howto = NULL;
   2259       1.1  christos     }
   2260       1.1  christos   else
   2261       1.1  christos     cache_ptr->howto = NULL;
   2262       1.1  christos 
   2263   1.1.1.7  christos   /* Base relative relocs are always against the symbol table,
   2264       1.1  christos      regardless of the setting of r_extern.  r_extern just reflects
   2265       1.1  christos      whether the symbol the reloc is against is local or global.  */
   2266   1.1.1.7  christos   if (r_baserel)
   2267   1.1.1.7  christos     r_extern = 1;
   2268   1.1.1.7  christos 
   2269       1.1  christos   if (r_extern && r_index >= symcount)
   2270       1.1  christos     {
   2271       1.1  christos       /* We could arrange to return an error, but it might be useful
   2272       1.1  christos 	 to see the file even if it is bad.  FIXME: Of course this
   2273       1.1  christos 	 means that objdump -r *doesn't* see the actual reloc, and
   2274       1.1  christos 	 objcopy silently writes a different reloc.  */
   2275       1.1  christos       r_extern = 0;
   2276       1.1  christos       r_index = N_ABS;
   2277       1.1  christos     }
   2278   1.1.1.9  christos 
   2279       1.1  christos   MOVE_ADDRESS (0);
   2280       1.1  christos }
   2281       1.1  christos 
   2282       1.1  christos /* Read and swap the relocs for a section.  */
   2283       1.1  christos 
   2284       1.1  christos bool
   2285       1.1  christos NAME (aout, slurp_reloc_table) (bfd *abfd, sec_ptr asect, asymbol **symbols)
   2286       1.1  christos {
   2287       1.1  christos   bfd_size_type count;
   2288       1.1  christos   bfd_size_type reloc_size;
   2289       1.1  christos   void * relocs;
   2290       1.1  christos   arelent *reloc_cache;
   2291   1.1.1.9  christos   size_t each_size;
   2292       1.1  christos   unsigned int counter = 0;
   2293       1.1  christos   arelent *cache_ptr;
   2294   1.1.1.9  christos   bfd_size_type amt;
   2295       1.1  christos 
   2296       1.1  christos   if (asect->relocation)
   2297       1.1  christos     return true;
   2298       1.1  christos 
   2299       1.1  christos   if (asect->flags & SEC_CONSTRUCTOR)
   2300       1.1  christos     return true;
   2301       1.1  christos 
   2302       1.1  christos   if (asect == obj_datasec (abfd))
   2303       1.1  christos     reloc_size = exec_hdr (abfd)->a_drsize;
   2304       1.1  christos   else if (asect == obj_textsec (abfd))
   2305   1.1.1.9  christos     reloc_size = exec_hdr (abfd)->a_trsize;
   2306       1.1  christos   else if (asect == obj_bsssec (abfd))
   2307       1.1  christos     reloc_size = 0;
   2308       1.1  christos   else
   2309       1.1  christos     {
   2310       1.1  christos       bfd_set_error (bfd_error_invalid_operation);
   2311   1.1.1.9  christos       return false;
   2312       1.1  christos     }
   2313   1.1.1.8  christos 
   2314   1.1.1.9  christos   each_size = obj_reloc_entry_size (abfd);
   2315   1.1.1.8  christos   count = reloc_size / each_size;
   2316       1.1  christos   if (count == 0)
   2317   1.1.1.9  christos     return true;		/* Nothing to be done.  */
   2318       1.1  christos 
   2319   1.1.1.8  christos   if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
   2320   1.1.1.8  christos     return false;
   2321   1.1.1.8  christos   relocs = _bfd_malloc_and_read (abfd, reloc_size, reloc_size);
   2322       1.1  christos   if (relocs == NULL)
   2323       1.1  christos     return false;
   2324   1.1.1.9  christos 
   2325       1.1  christos   amt = count * sizeof (arelent);
   2326       1.1  christos   reloc_cache = (arelent *) bfd_zmalloc (amt);
   2327       1.1  christos   if (reloc_cache == NULL)
   2328       1.1  christos     {
   2329       1.1  christos       free (relocs);
   2330       1.1  christos       return false;
   2331       1.1  christos     }
   2332       1.1  christos 
   2333       1.1  christos   cache_ptr = reloc_cache;
   2334       1.1  christos   if (each_size == RELOC_EXT_SIZE)
   2335       1.1  christos     {
   2336       1.1  christos       struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
   2337       1.1  christos 
   2338       1.1  christos       for (; counter < count; counter++, rptr++, cache_ptr++)
   2339       1.1  christos 	MY_swap_ext_reloc_in (abfd, rptr, cache_ptr, symbols,
   2340       1.1  christos 			      (bfd_size_type) bfd_get_symcount (abfd));
   2341       1.1  christos     }
   2342       1.1  christos   else
   2343       1.1  christos     {
   2344       1.1  christos       struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
   2345       1.1  christos 
   2346       1.1  christos       for (; counter < count; counter++, rptr++, cache_ptr++)
   2347       1.1  christos 	MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols,
   2348       1.1  christos 			      (bfd_size_type) bfd_get_symcount (abfd));
   2349       1.1  christos     }
   2350   1.1.1.9  christos 
   2351       1.1  christos   free (relocs);
   2352       1.1  christos 
   2353       1.1  christos   asect->relocation = reloc_cache;
   2354       1.1  christos   asect->reloc_count = cache_ptr - reloc_cache;
   2355   1.1.1.9  christos 
   2356       1.1  christos   return true;
   2357       1.1  christos }
   2358       1.1  christos 
   2359       1.1  christos /* Write out a relocation section into an object file.  */
   2360       1.1  christos 
   2361       1.1  christos bool
   2362       1.1  christos NAME (aout, squirt_out_relocs) (bfd *abfd, asection *section)
   2363       1.1  christos {
   2364       1.1  christos   arelent **generic;
   2365       1.1  christos   unsigned char *native, *natptr;
   2366   1.1.1.9  christos   size_t each_size;
   2367       1.1  christos 
   2368       1.1  christos   unsigned int count = section->reloc_count;
   2369       1.1  christos   bfd_size_type natsize;
   2370       1.1  christos 
   2371       1.1  christos   if (count == 0 || section->orelocation == NULL)
   2372   1.1.1.9  christos     return true;
   2373       1.1  christos 
   2374       1.1  christos   each_size = obj_reloc_entry_size (abfd);
   2375       1.1  christos   natsize = (bfd_size_type) each_size * count;
   2376       1.1  christos   native = (unsigned char *) bfd_zalloc (abfd, natsize);
   2377       1.1  christos   if (!native)
   2378       1.1  christos     return false;
   2379       1.1  christos 
   2380       1.1  christos   generic = section->orelocation;
   2381   1.1.1.6  christos 
   2382   1.1.1.6  christos   if (each_size == RELOC_EXT_SIZE)
   2383   1.1.1.6  christos     {
   2384   1.1.1.6  christos       for (natptr = native;
   2385   1.1.1.6  christos 	   count != 0;
   2386   1.1.1.6  christos 	   --count, natptr += each_size, ++generic)
   2387   1.1.1.6  christos 	{
   2388   1.1.1.6  christos 	  /* PR 20921: If the howto field has not been initialised then skip
   2389   1.1.1.8  christos 	     this reloc.
   2390   1.1.1.8  christos 	     PR 20929: Similarly for the symbol field.  */
   2391   1.1.1.9  christos 	  if ((*generic)->howto == NULL
   2392   1.1.1.6  christos 	      || (*generic)->sym_ptr_ptr == NULL)
   2393   1.1.1.6  christos 	    {
   2394   1.1.1.6  christos 	      bfd_set_error (bfd_error_invalid_operation);
   2395   1.1.1.6  christos 	      _bfd_error_handler (_("%pB: attempt to write out "
   2396       1.1  christos 				    "unknown reloc type"), abfd);
   2397       1.1  christos 	      return false;
   2398       1.1  christos 	    }
   2399       1.1  christos 	  MY_swap_ext_reloc_out (abfd, *generic,
   2400       1.1  christos 				 (struct reloc_ext_external *) natptr);
   2401       1.1  christos 	}
   2402   1.1.1.6  christos     }
   2403   1.1.1.6  christos   else
   2404   1.1.1.6  christos     {
   2405   1.1.1.6  christos       for (natptr = native;
   2406   1.1.1.6  christos 	   count != 0;
   2407   1.1.1.8  christos 	   --count, natptr += each_size, ++generic)
   2408   1.1.1.8  christos 	{
   2409   1.1.1.9  christos 	  if ((*generic)->howto == NULL
   2410   1.1.1.6  christos 	      || (*generic)->sym_ptr_ptr == NULL)
   2411   1.1.1.6  christos 	    {
   2412   1.1.1.6  christos 	      bfd_set_error (bfd_error_invalid_operation);
   2413   1.1.1.6  christos 	      _bfd_error_handler (_("%pB: attempt to write out "
   2414       1.1  christos 				    "unknown reloc type"), abfd);
   2415       1.1  christos 	      return false;
   2416  1.1.1.10  christos 	    }
   2417       1.1  christos 	  MY_swap_std_reloc_out (abfd, *generic,
   2418       1.1  christos 				 (struct reloc_std_external *) natptr);
   2419   1.1.1.9  christos 	}
   2420       1.1  christos     }
   2421       1.1  christos 
   2422       1.1  christos   if (bfd_write (native, natsize, abfd) != natsize)
   2423   1.1.1.9  christos     {
   2424       1.1  christos       bfd_release (abfd, native);
   2425       1.1  christos       return false;
   2426       1.1  christos     }
   2427       1.1  christos   bfd_release (abfd, native);
   2428       1.1  christos 
   2429       1.1  christos   return true;
   2430       1.1  christos }
   2431       1.1  christos 
   2432       1.1  christos /* This is stupid.  This function should be a boolean predicate.  */
   2433       1.1  christos 
   2434       1.1  christos long
   2435       1.1  christos NAME (aout, canonicalize_reloc) (bfd *abfd,
   2436       1.1  christos 				 sec_ptr section,
   2437       1.1  christos 				 arelent **relptr,
   2438       1.1  christos 				 asymbol **symbols)
   2439       1.1  christos {
   2440       1.1  christos   arelent *tblptr = section->relocation;
   2441       1.1  christos   unsigned int count;
   2442       1.1  christos 
   2443       1.1  christos   if (section == obj_bsssec (abfd))
   2444       1.1  christos     {
   2445       1.1  christos       *relptr = NULL;
   2446       1.1  christos       return 0;
   2447       1.1  christos     }
   2448       1.1  christos 
   2449       1.1  christos   if (!(tblptr || NAME (aout, slurp_reloc_table) (abfd, section, symbols)))
   2450       1.1  christos     return -1;
   2451       1.1  christos 
   2452       1.1  christos   if (section->flags & SEC_CONSTRUCTOR)
   2453       1.1  christos     {
   2454       1.1  christos       arelent_chain *chain = section->constructor_chain;
   2455       1.1  christos       for (count = 0; count < section->reloc_count; count ++)
   2456       1.1  christos 	{
   2457       1.1  christos 	  *relptr ++ = &chain->relent;
   2458       1.1  christos 	  chain = chain->next;
   2459       1.1  christos 	}
   2460       1.1  christos     }
   2461       1.1  christos   else
   2462       1.1  christos     {
   2463       1.1  christos       tblptr = section->relocation;
   2464       1.1  christos 
   2465       1.1  christos       for (count = 0; count++ < section->reloc_count; )
   2466       1.1  christos 	{
   2467       1.1  christos 	  *relptr++ = tblptr++;
   2468       1.1  christos 	}
   2469       1.1  christos     }
   2470       1.1  christos   *relptr = 0;
   2471       1.1  christos 
   2472   1.1.1.9  christos   return section->reloc_count;
   2473       1.1  christos }
   2474       1.1  christos 
   2475   1.1.1.7  christos long
   2476   1.1.1.7  christos NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect)
   2477   1.1.1.7  christos {
   2478   1.1.1.7  christos   size_t count, raw;
   2479   1.1.1.7  christos 
   2480   1.1.1.7  christos   if (asect->flags & SEC_CONSTRUCTOR)
   2481   1.1.1.7  christos     count = asect->reloc_count;
   2482   1.1.1.7  christos   else if (asect == obj_datasec (abfd))
   2483   1.1.1.7  christos     count = exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
   2484   1.1.1.7  christos   else if (asect == obj_textsec (abfd))
   2485   1.1.1.7  christos     count = exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
   2486   1.1.1.7  christos   else if (asect == obj_bsssec (abfd))
   2487       1.1  christos     count = 0;
   2488   1.1.1.9  christos   else
   2489   1.1.1.9  christos     {
   2490   1.1.1.7  christos       bfd_set_error (bfd_error_invalid_operation);
   2491   1.1.1.7  christos       return -1;
   2492   1.1.1.7  christos     }
   2493   1.1.1.7  christos 
   2494   1.1.1.9  christos   if (count >= LONG_MAX / sizeof (arelent *)
   2495   1.1.1.9  christos       || _bfd_mul_overflow (count, obj_reloc_entry_size (abfd), &raw))
   2496   1.1.1.9  christos     {
   2497   1.1.1.9  christos       bfd_set_error (bfd_error_file_too_big);
   2498   1.1.1.9  christos       return -1;
   2499   1.1.1.9  christos     }
   2500   1.1.1.9  christos   if (!bfd_write_p (abfd))
   2501   1.1.1.9  christos     {
   2502   1.1.1.9  christos       ufile_ptr filesize = bfd_get_file_size (abfd);
   2503   1.1.1.7  christos       if (filesize != 0 && raw > filesize)
   2504       1.1  christos 	{
   2505       1.1  christos 	  bfd_set_error (bfd_error_file_truncated);
   2506       1.1  christos 	  return -1;
   2507       1.1  christos 	}
   2508       1.1  christos     }
   2509       1.1  christos   return (count + 1) * sizeof (arelent *);
   2510       1.1  christos }
   2511       1.1  christos 
   2512       1.1  christos long
   2514       1.1  christos NAME (aout, get_symtab_upper_bound) (bfd *abfd)
   2515       1.1  christos {
   2516       1.1  christos   if (!NAME (aout, slurp_symbol_table) (abfd))
   2517       1.1  christos     return -1;
   2518       1.1  christos 
   2519       1.1  christos   return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
   2520       1.1  christos }
   2521       1.1  christos 
   2522       1.1  christos alent *
   2523       1.1  christos NAME (aout, get_lineno) (bfd *ignore_abfd ATTRIBUTE_UNUSED,
   2524       1.1  christos 			 asymbol *ignore_symbol ATTRIBUTE_UNUSED)
   2525       1.1  christos {
   2526       1.1  christos   return NULL;
   2527       1.1  christos }
   2528       1.1  christos 
   2529       1.1  christos void
   2530       1.1  christos NAME (aout, get_symbol_info) (bfd *ignore_abfd ATTRIBUTE_UNUSED,
   2531       1.1  christos 			      asymbol *symbol,
   2532       1.1  christos 			      symbol_info *ret)
   2533       1.1  christos {
   2534       1.1  christos   bfd_symbol_info (symbol, ret);
   2535       1.1  christos 
   2536       1.1  christos   if (ret->type == '?')
   2537       1.1  christos     {
   2538       1.1  christos       int type_code = aout_symbol (symbol)->type & 0xff;
   2539       1.1  christos       const char *stab_name = bfd_get_stab_name (type_code);
   2540       1.1  christos       static char buf[10];
   2541       1.1  christos 
   2542       1.1  christos       if (stab_name == NULL)
   2543       1.1  christos 	{
   2544       1.1  christos 	  sprintf (buf, "(%d)", type_code);
   2545       1.1  christos 	  stab_name = buf;
   2546       1.1  christos 	}
   2547       1.1  christos       ret->type = '-';
   2548       1.1  christos       ret->stab_type = type_code;
   2549       1.1  christos       ret->stab_other = (unsigned) (aout_symbol (symbol)->other & 0xff);
   2550       1.1  christos       ret->stab_desc = (unsigned) (aout_symbol (symbol)->desc & 0xffff);
   2551       1.1  christos       ret->stab_name = stab_name;
   2552       1.1  christos     }
   2553       1.1  christos }
   2554       1.1  christos 
   2555       1.1  christos void
   2556       1.1  christos NAME (aout, print_symbol) (bfd *abfd,
   2557       1.1  christos 			   void * afile,
   2558       1.1  christos 			   asymbol *symbol,
   2559       1.1  christos 			   bfd_print_symbol_type how)
   2560       1.1  christos {
   2561       1.1  christos   FILE *file = (FILE *)afile;
   2562       1.1  christos 
   2563       1.1  christos   switch (how)
   2564       1.1  christos     {
   2565       1.1  christos     case bfd_print_symbol_name:
   2566       1.1  christos       if (symbol->name)
   2567       1.1  christos 	fprintf (file,"%s", symbol->name);
   2568       1.1  christos       break;
   2569       1.1  christos     case bfd_print_symbol_more:
   2570       1.1  christos       fprintf (file,"%4x %2x %2x",
   2571       1.1  christos 	       (unsigned) (aout_symbol (symbol)->desc & 0xffff),
   2572       1.1  christos 	       (unsigned) (aout_symbol (symbol)->other & 0xff),
   2573       1.1  christos 	       (unsigned) (aout_symbol (symbol)->type));
   2574       1.1  christos       break;
   2575       1.1  christos     case bfd_print_symbol_all:
   2576       1.1  christos       {
   2577       1.1  christos 	const char *section_name = symbol->section->name;
   2578       1.1  christos 
   2579       1.1  christos 	bfd_print_symbol_vandf (abfd, (void *)file, symbol);
   2580       1.1  christos 
   2581       1.1  christos 	fprintf (file," %-5s %04x %02x %02x",
   2582       1.1  christos 		 section_name,
   2583       1.1  christos 		 (unsigned) (aout_symbol (symbol)->desc & 0xffff),
   2584       1.1  christos 		 (unsigned) (aout_symbol (symbol)->other & 0xff),
   2585       1.1  christos 		 (unsigned) (aout_symbol (symbol)->type & 0xff));
   2586       1.1  christos 	if (symbol->name)
   2587       1.1  christos 	  fprintf (file," %s", symbol->name);
   2588       1.1  christos       }
   2589       1.1  christos       break;
   2590       1.1  christos     }
   2591       1.1  christos }
   2592       1.1  christos 
   2593       1.1  christos /* If we don't have to allocate more than 1MB to hold the generic
   2594       1.1  christos    symbols, we use the generic minisymbol methord: it's faster, since
   2595       1.1  christos    it only translates the symbols once, not multiple times.  */
   2596       1.1  christos #define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
   2597   1.1.1.9  christos 
   2598       1.1  christos /* Read minisymbols.  For minisymbols, we use the unmodified a.out
   2599       1.1  christos    symbols.  The minisymbol_to_symbol function translates these into
   2600       1.1  christos    BFD asymbol structures.  */
   2601       1.1  christos 
   2602       1.1  christos long
   2603       1.1  christos NAME (aout, read_minisymbols) (bfd *abfd,
   2604       1.1  christos 			       bool dynamic,
   2605       1.1  christos 			       void * *minisymsp,
   2606       1.1  christos 			       unsigned int *sizep)
   2607       1.1  christos {
   2608       1.1  christos   if (dynamic)
   2609       1.1  christos     /* We could handle the dynamic symbols here as well, but it's
   2610       1.1  christos        easier to hand them off.  */
   2611       1.1  christos     return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
   2612       1.1  christos 
   2613       1.1  christos   if (! aout_get_external_symbols (abfd))
   2614       1.1  christos     return -1;
   2615       1.1  christos 
   2616       1.1  christos   if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
   2617       1.1  christos     return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
   2618       1.1  christos 
   2619       1.1  christos   *minisymsp = (void *) obj_aout_external_syms (abfd);
   2620       1.1  christos 
   2621       1.1  christos   /* By passing the external symbols back from this routine, we are
   2622       1.1  christos      giving up control over the memory block.  Clear
   2623       1.1  christos      obj_aout_external_syms, so that we do not try to free it
   2624       1.1  christos      ourselves.  */
   2625       1.1  christos   obj_aout_external_syms (abfd) = NULL;
   2626       1.1  christos 
   2627       1.1  christos   *sizep = EXTERNAL_NLIST_SIZE;
   2628       1.1  christos   return obj_aout_external_sym_count (abfd);
   2629       1.1  christos }
   2630   1.1.1.9  christos 
   2631       1.1  christos /* Convert a minisymbol to a BFD asymbol.  A minisymbol is just an
   2632       1.1  christos    unmodified a.out symbol.  The SYM argument is a structure returned
   2633       1.1  christos    by bfd_make_empty_symbol, which we fill in here.  */
   2634       1.1  christos 
   2635       1.1  christos asymbol *
   2636       1.1  christos NAME (aout, minisymbol_to_symbol) (bfd *abfd,
   2637       1.1  christos 				   bool dynamic,
   2638       1.1  christos 				   const void * minisym,
   2639       1.1  christos 				   asymbol *sym)
   2640       1.1  christos {
   2641       1.1  christos   if (dynamic
   2642       1.1  christos       || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
   2643       1.1  christos     return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
   2644       1.1  christos 
   2645       1.1  christos   memset (sym, 0, sizeof (aout_symbol_type));
   2646       1.1  christos 
   2647       1.1  christos   /* We call translate_symbol_table to translate a single symbol.  */
   2648   1.1.1.9  christos   if (! (NAME (aout, translate_symbol_table)
   2649       1.1  christos 	 (abfd,
   2650       1.1  christos 	  (aout_symbol_type *) sym,
   2651       1.1  christos 	  (struct external_nlist *) minisym,
   2652       1.1  christos 	  (bfd_size_type) 1,
   2653       1.1  christos 	  obj_aout_external_strings (abfd),
   2654       1.1  christos 	  obj_aout_external_string_size (abfd),
   2655       1.1  christos 	  false)))
   2656       1.1  christos     return NULL;
   2657       1.1  christos 
   2658   1.1.1.9  christos   return sym;
   2659       1.1  christos }
   2660       1.1  christos 
   2661   1.1.1.3  christos /* Provided a BFD, a section and an offset into the section, calculate
   2662       1.1  christos    and return the name of the source file and the line nearest to the
   2663       1.1  christos    wanted location.  */
   2664       1.1  christos 
   2665   1.1.1.3  christos bool
   2666   1.1.1.3  christos NAME (aout, find_nearest_line) (bfd *abfd,
   2667       1.1  christos 				asymbol **symbols,
   2668       1.1  christos 				asection *section,
   2669       1.1  christos 				bfd_vma offset,
   2670       1.1  christos 				const char **filename_ptr,
   2671       1.1  christos 				const char **functionname_ptr,
   2672       1.1  christos 				unsigned int *line_ptr,
   2673       1.1  christos 				unsigned int *disriminator_ptr)
   2674       1.1  christos {
   2675       1.1  christos   /* Run down the file looking for the filename, function and linenumber.  */
   2676       1.1  christos   asymbol **p;
   2677       1.1  christos   const char *directory_name = NULL;
   2678       1.1  christos   const char *main_file_name = NULL;
   2679       1.1  christos   const char *current_file_name = NULL;
   2680       1.1  christos   const char *line_file_name = NULL;      /* Value of current_file_name at line number.  */
   2681   1.1.1.8  christos   const char *line_directory_name = NULL; /* Value of directory_name at line number.  */
   2682   1.1.1.6  christos   bfd_vma low_line_vma = 0;
   2683       1.1  christos   bfd_vma low_func_vma = 0;
   2684   1.1.1.3  christos   asymbol *func = 0;
   2685   1.1.1.3  christos   bfd_size_type filelen, funclen;
   2686       1.1  christos   char *buf;
   2687       1.1  christos 
   2688       1.1  christos   *filename_ptr = bfd_get_filename (abfd);
   2689       1.1  christos   *functionname_ptr = NULL;
   2690       1.1  christos   *line_ptr = 0;
   2691       1.1  christos   if (disriminator_ptr)
   2692       1.1  christos     *disriminator_ptr = 0;
   2693       1.1  christos 
   2694       1.1  christos   if (symbols != NULL)
   2695       1.1  christos     {
   2696       1.1  christos       for (p = symbols; *p; p++)
   2697       1.1  christos 	{
   2698       1.1  christos 	  aout_symbol_type  *q = (aout_symbol_type *) (*p);
   2699       1.1  christos 	next:
   2700       1.1  christos 	  switch (q->type)
   2701       1.1  christos 	    {
   2702       1.1  christos 	    case N_TEXT:
   2703       1.1  christos 	      /* If this looks like a file name symbol, and it comes after
   2704       1.1  christos 		 the line number we have found so far, but before the
   2705       1.1  christos 		 offset, then we have probably not found the right line
   2706       1.1  christos 		 number.  */
   2707       1.1  christos 	      if (q->symbol.value <= offset
   2708       1.1  christos 		  && ((q->symbol.value > low_line_vma
   2709       1.1  christos 		       && (line_file_name != NULL
   2710   1.1.1.7  christos 			   || *line_ptr != 0))
   2711   1.1.1.7  christos 		      || (q->symbol.value > low_func_vma
   2712   1.1.1.7  christos 			  && func != NULL)))
   2713   1.1.1.7  christos 		{
   2714       1.1  christos 		  const char *symname;
   2715       1.1  christos 
   2716       1.1  christos 		  symname = q->symbol.name;
   2717       1.1  christos 
   2718       1.1  christos 		  if (symname != NULL
   2719       1.1  christos 		      && strlen (symname) > 2
   2720       1.1  christos 		      && strcmp (symname + strlen (symname) - 2, ".o") == 0)
   2721       1.1  christos 		    {
   2722       1.1  christos 		      if (q->symbol.value > low_line_vma)
   2723       1.1  christos 			{
   2724       1.1  christos 			  *line_ptr = 0;
   2725       1.1  christos 			  line_file_name = NULL;
   2726       1.1  christos 			}
   2727       1.1  christos 		      if (q->symbol.value > low_func_vma)
   2728       1.1  christos 			func = NULL;
   2729       1.1  christos 		    }
   2730       1.1  christos 		}
   2731       1.1  christos 	      break;
   2732       1.1  christos 
   2733       1.1  christos 	    case N_SO:
   2734       1.1  christos 	      /* If this symbol is less than the offset, but greater than
   2735       1.1  christos 		 the line number we have found so far, then we have not
   2736       1.1  christos 		 found the right line number.  */
   2737       1.1  christos 	      if (q->symbol.value <= offset)
   2738       1.1  christos 		{
   2739       1.1  christos 		  if (q->symbol.value > low_line_vma)
   2740       1.1  christos 		    {
   2741       1.1  christos 		      *line_ptr = 0;
   2742       1.1  christos 		      line_file_name = NULL;
   2743       1.1  christos 		    }
   2744       1.1  christos 		  if (q->symbol.value > low_func_vma)
   2745       1.1  christos 		    func = NULL;
   2746       1.1  christos 		}
   2747       1.1  christos 
   2748       1.1  christos 	      main_file_name = current_file_name = q->symbol.name;
   2749       1.1  christos 	      /* Look ahead to next symbol to check if that too is an N_SO.  */
   2750       1.1  christos 	      p++;
   2751       1.1  christos 	      if (*p == NULL)
   2752       1.1  christos 		goto done;
   2753       1.1  christos 	      q = (aout_symbol_type *) (*p);
   2754       1.1  christos 	      if (q->type != (int)N_SO)
   2755       1.1  christos 		goto next;
   2756       1.1  christos 
   2757       1.1  christos 	      /* Found a second N_SO  First is directory; second is filename.  */
   2758       1.1  christos 	      directory_name = current_file_name;
   2759       1.1  christos 	      main_file_name = current_file_name = q->symbol.name;
   2760       1.1  christos 	      if (obj_textsec (abfd) != section)
   2761       1.1  christos 		goto done;
   2762       1.1  christos 	      break;
   2763       1.1  christos 	    case N_SOL:
   2764       1.1  christos 	      current_file_name = q->symbol.name;
   2765       1.1  christos 	      break;
   2766       1.1  christos 
   2767       1.1  christos 	    case N_SLINE:
   2768       1.1  christos 
   2769       1.1  christos 	    case N_DSLINE:
   2770       1.1  christos 	    case N_BSLINE:
   2771       1.1  christos 	      /* We'll keep this if it resolves nearer than the one we have
   2772       1.1  christos 		 already.  */
   2773       1.1  christos 	      if (q->symbol.value >= low_line_vma
   2774       1.1  christos 		  && q->symbol.value <= offset)
   2775       1.1  christos 		{
   2776       1.1  christos 		  *line_ptr = q->desc;
   2777       1.1  christos 		  low_line_vma = q->symbol.value;
   2778   1.1.1.7  christos 		  line_file_name = current_file_name;
   2779   1.1.1.7  christos 		  line_directory_name = directory_name;
   2780       1.1  christos 		}
   2781       1.1  christos 	      break;
   2782       1.1  christos 	    case N_FUN:
   2783       1.1  christos 	      {
   2784       1.1  christos 		/* We'll keep this if it is nearer than the one we have already.  */
   2785       1.1  christos 		if (q->symbol.value >= low_func_vma
   2786       1.1  christos 		    && q->symbol.value <= offset)
   2787       1.1  christos 		  {
   2788       1.1  christos 		    low_func_vma = q->symbol.value;
   2789       1.1  christos 		    func = (asymbol *)q;
   2790       1.1  christos 		  }
   2791       1.1  christos 		else if (q->symbol.value > offset)
   2792       1.1  christos 		  goto done;
   2793       1.1  christos 	      }
   2794       1.1  christos 	      break;
   2795       1.1  christos 	    }
   2796       1.1  christos 	}
   2797       1.1  christos     }
   2798       1.1  christos 
   2799       1.1  christos  done:
   2800       1.1  christos   if (*line_ptr != 0)
   2801       1.1  christos     {
   2802       1.1  christos       main_file_name = line_file_name;
   2803       1.1  christos       directory_name = line_directory_name;
   2804       1.1  christos     }
   2805       1.1  christos 
   2806       1.1  christos   if (main_file_name == NULL
   2807       1.1  christos       || IS_ABSOLUTE_PATH (main_file_name)
   2808       1.1  christos       || directory_name == NULL)
   2809       1.1  christos     filelen = 0;
   2810       1.1  christos   else
   2811   1.1.1.8  christos     filelen = strlen (directory_name) + strlen (main_file_name);
   2812       1.1  christos 
   2813       1.1  christos   if (func == NULL)
   2814       1.1  christos     funclen = 0;
   2815       1.1  christos   else
   2816       1.1  christos     funclen = strlen (bfd_asymbol_name (func));
   2817       1.1  christos 
   2818       1.1  christos   free (adata (abfd).line_buf);
   2819       1.1  christos 
   2820   1.1.1.9  christos   if (filelen + funclen == 0)
   2821       1.1  christos     adata (abfd).line_buf = buf = NULL;
   2822       1.1  christos   else
   2823       1.1  christos     {
   2824       1.1  christos       buf = (char *) bfd_malloc (filelen + funclen + 3);
   2825       1.1  christos       adata (abfd).line_buf = buf;
   2826       1.1  christos       if (buf == NULL)
   2827       1.1  christos 	return false;
   2828       1.1  christos     }
   2829   1.1.1.6  christos 
   2830   1.1.1.6  christos   if (main_file_name != NULL)
   2831   1.1.1.6  christos     {
   2832   1.1.1.6  christos       if (IS_ABSOLUTE_PATH (main_file_name) || directory_name == NULL)
   2833   1.1.1.6  christos 	*filename_ptr = main_file_name;
   2834   1.1.1.6  christos       else
   2835   1.1.1.6  christos 	{
   2836   1.1.1.6  christos 	  if (buf == NULL)
   2837   1.1.1.6  christos 	    /* PR binutils/20891: In a corrupt input file both
   2838   1.1.1.6  christos 	       main_file_name and directory_name can be empty...  */
   2839   1.1.1.6  christos 	    * filename_ptr = NULL;
   2840       1.1  christos 	  else
   2841       1.1  christos 	    {
   2842       1.1  christos 	      snprintf (buf, filelen + 1, "%s%s", directory_name,
   2843       1.1  christos 			main_file_name);
   2844       1.1  christos 	      *filename_ptr = buf;
   2845       1.1  christos 	      buf += filelen + 1;
   2846       1.1  christos 	    }
   2847       1.1  christos 	}
   2848   1.1.1.6  christos     }
   2849   1.1.1.6  christos 
   2850   1.1.1.6  christos   if (func)
   2851   1.1.1.6  christos     {
   2852   1.1.1.9  christos       const char *function = func->name;
   2853   1.1.1.6  christos       char *colon;
   2854       1.1  christos 
   2855       1.1  christos       if (buf == NULL)
   2856       1.1  christos 	{
   2857       1.1  christos 	  /* PR binutils/20892: In a corrupt input file func can be empty.  */
   2858       1.1  christos 	  * functionname_ptr = NULL;
   2859       1.1  christos 	  return true;
   2860       1.1  christos 	}
   2861       1.1  christos       /* The caller expects a symbol name.  We actually have a
   2862       1.1  christos 	 function name, without the leading underscore.  Put the
   2863       1.1  christos 	 underscore back in, so that the caller gets a symbol name.  */
   2864       1.1  christos       if (bfd_get_symbol_leading_char (abfd) == '\0')
   2865       1.1  christos 	strcpy (buf, function);
   2866       1.1  christos       else
   2867       1.1  christos 	{
   2868       1.1  christos 	  buf[0] = bfd_get_symbol_leading_char (abfd);
   2869       1.1  christos 	  strcpy (buf + 1, function);
   2870       1.1  christos 	}
   2871   1.1.1.9  christos       /* Have to remove : stuff.  */
   2872       1.1  christos       colon = strchr (buf, ':');
   2873       1.1  christos       if (colon != NULL)
   2874       1.1  christos 	*colon = '\0';
   2875       1.1  christos       *functionname_ptr = buf;
   2876       1.1  christos     }
   2877       1.1  christos 
   2878       1.1  christos   return true;
   2879       1.1  christos }
   2880       1.1  christos 
   2881  1.1.1.10  christos int
   2882       1.1  christos NAME (aout, sizeof_headers) (bfd *abfd,
   2883   1.1.1.9  christos 			     struct bfd_link_info *info ATTRIBUTE_UNUSED)
   2884       1.1  christos {
   2885       1.1  christos   return adata (abfd).exec_bytes_size;
   2886  1.1.1.10  christos }
   2887  1.1.1.10  christos 
   2888  1.1.1.10  christos /* Throw away most malloc'd and alloc'd information for this BFD.  */
   2889  1.1.1.10  christos 
   2890   1.1.1.8  christos bool
   2891  1.1.1.10  christos NAME (aout, bfd_free_cached_info) (bfd *abfd)
   2892  1.1.1.10  christos {
   2893  1.1.1.10  christos   if ((bfd_get_format (abfd) == bfd_object
   2894  1.1.1.10  christos        || bfd_get_format (abfd) == bfd_core)
   2895  1.1.1.10  christos       && abfd->tdata.aout_data != NULL)
   2896  1.1.1.10  christos     {
   2897       1.1  christos #define BFCI_FREE(x) do { free (x); x = NULL; } while (0)
   2898  1.1.1.10  christos       BFCI_FREE (adata (abfd).line_buf);
   2899       1.1  christos       BFCI_FREE (obj_aout_symbols (abfd));
   2900  1.1.1.10  christos       BFCI_FREE (obj_aout_external_syms (abfd));
   2901       1.1  christos       BFCI_FREE (obj_aout_external_strings (abfd));
   2902       1.1  christos       for (asection *o = abfd->sections; o != NULL; o = o->next)
   2903       1.1  christos 	BFCI_FREE (o->relocation);
   2904       1.1  christos #undef BFCI_FREE
   2905       1.1  christos     }
   2906       1.1  christos 
   2907       1.1  christos   return _bfd_generic_bfd_free_cached_info (abfd);
   2908       1.1  christos }
   2909       1.1  christos 
   2910       1.1  christos /* a.out link code.  */
   2912       1.1  christos 
   2913       1.1  christos /* Routine to create an entry in an a.out link hash table.  */
   2914       1.1  christos 
   2915       1.1  christos struct bfd_hash_entry *
   2916       1.1  christos NAME (aout, link_hash_newfunc) (struct bfd_hash_entry *entry,
   2917       1.1  christos 				struct bfd_hash_table *table,
   2918   1.1.1.7  christos 				const char *string)
   2919       1.1  christos {
   2920       1.1  christos   struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
   2921       1.1  christos 
   2922       1.1  christos   /* Allocate the structure if it has not already been allocated by a
   2923       1.1  christos      subclass.  */
   2924       1.1  christos   if (ret == NULL)
   2925       1.1  christos     ret = (struct aout_link_hash_entry *) bfd_hash_allocate (table,
   2926       1.1  christos 							     sizeof (* ret));
   2927       1.1  christos   if (ret == NULL)
   2928       1.1  christos     return NULL;
   2929   1.1.1.9  christos 
   2930       1.1  christos   /* Call the allocation method of the superclass.  */
   2931       1.1  christos   ret = ((struct aout_link_hash_entry *)
   2932       1.1  christos 	 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
   2933       1.1  christos 				 table, string));
   2934       1.1  christos   if (ret)
   2935       1.1  christos     {
   2936       1.1  christos       /* Set local fields.  */
   2937       1.1  christos       ret->written = false;
   2938   1.1.1.9  christos       ret->indx = -1;
   2939       1.1  christos     }
   2940       1.1  christos 
   2941       1.1  christos   return (struct bfd_hash_entry *) ret;
   2942       1.1  christos }
   2943       1.1  christos 
   2944       1.1  christos /* Initialize an a.out link hash table.  */
   2945       1.1  christos 
   2946       1.1  christos bool
   2947       1.1  christos NAME (aout, link_hash_table_init) (struct aout_link_hash_table *table,
   2948       1.1  christos 				   bfd *abfd,
   2949       1.1  christos 				   struct bfd_hash_entry *(*newfunc)
   2950       1.1  christos 				   (struct bfd_hash_entry *, struct bfd_hash_table *,
   2951       1.1  christos 				    const char *),
   2952       1.1  christos 				   unsigned int entsize)
   2953       1.1  christos {
   2954       1.1  christos   return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
   2955   1.1.1.8  christos }
   2956       1.1  christos 
   2957       1.1  christos /* Create an a.out link hash table.  */
   2958       1.1  christos 
   2959       1.1  christos struct bfd_link_hash_table *
   2960       1.1  christos NAME (aout, link_hash_table_create) (bfd *abfd)
   2961       1.1  christos {
   2962       1.1  christos   struct aout_link_hash_table *ret;
   2963       1.1  christos   size_t amt = sizeof (* ret);
   2964       1.1  christos 
   2965       1.1  christos   ret = (struct aout_link_hash_table *) bfd_malloc (amt);
   2966       1.1  christos   if (ret == NULL)
   2967       1.1  christos     return NULL;
   2968       1.1  christos 
   2969       1.1  christos   if (!NAME (aout, link_hash_table_init) (ret, abfd,
   2970       1.1  christos 					  NAME (aout, link_hash_newfunc),
   2971       1.1  christos 					  sizeof (struct aout_link_hash_entry)))
   2972       1.1  christos     {
   2973   1.1.1.9  christos       free (ret);
   2974       1.1  christos       return NULL;
   2975       1.1  christos     }
   2976   1.1.1.9  christos   return &ret->root;
   2977       1.1  christos }
   2978   1.1.1.9  christos 
   2979       1.1  christos /* Add all symbols from an object file to the hash table.  */
   2980       1.1  christos 
   2981       1.1  christos static bool
   2982   1.1.1.9  christos aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
   2983       1.1  christos {
   2984       1.1  christos   bool (*add_one_symbol)
   2985       1.1  christos     (struct bfd_link_info *, bfd *, const char *, flagword, asection *,
   2986       1.1  christos      bfd_vma, const char *, bool, bool, struct bfd_link_hash_entry **);
   2987       1.1  christos   struct external_nlist *syms;
   2988       1.1  christos   bfd_size_type sym_count;
   2989       1.1  christos   char *strings;
   2990       1.1  christos   bool copy;
   2991       1.1  christos   struct aout_link_hash_entry **sym_hash;
   2992   1.1.1.9  christos   struct external_nlist *p;
   2993       1.1  christos   struct external_nlist *pend;
   2994   1.1.1.9  christos   bfd_size_type amt;
   2995       1.1  christos 
   2996       1.1  christos   syms = obj_aout_external_syms (abfd);
   2997       1.1  christos   sym_count = obj_aout_external_sym_count (abfd);
   2998       1.1  christos   strings = obj_aout_external_strings (abfd);
   2999       1.1  christos   if (info->keep_memory)
   3000   1.1.1.9  christos     copy = false;
   3001       1.1  christos   else
   3002       1.1  christos     copy = true;
   3003       1.1  christos 
   3004   1.1.1.9  christos   if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
   3005       1.1  christos     {
   3006       1.1  christos       if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
   3007       1.1  christos 	     (abfd, info, &syms, &sym_count, &strings)))
   3008       1.1  christos 	return false;
   3009       1.1  christos     }
   3010       1.1  christos 
   3011       1.1  christos   if (sym_count == 0)
   3012       1.1  christos     return true;		/* Nothing to do.  */
   3013   1.1.1.9  christos 
   3014       1.1  christos   /* We keep a list of the linker hash table entries that correspond
   3015       1.1  christos      to particular symbols.  We could just look them up in the hash
   3016       1.1  christos      table, but keeping the list is more efficient.  Perhaps this
   3017       1.1  christos      should be conditional on info->keep_memory.  */
   3018       1.1  christos   amt = sym_count * sizeof (struct aout_link_hash_entry *);
   3019       1.1  christos   sym_hash = (struct aout_link_hash_entry **) bfd_alloc (abfd, amt);
   3020       1.1  christos   if (sym_hash == NULL)
   3021       1.1  christos     return false;
   3022       1.1  christos   obj_aout_sym_hashes (abfd) = sym_hash;
   3023       1.1  christos 
   3024       1.1  christos   add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
   3025       1.1  christos   if (add_one_symbol == NULL)
   3026       1.1  christos     add_one_symbol = _bfd_generic_link_add_one_symbol;
   3027       1.1  christos 
   3028       1.1  christos   p = syms;
   3029       1.1  christos   pend = p + sym_count;
   3030       1.1  christos   for (; p < pend; p++, sym_hash++)
   3031       1.1  christos     {
   3032       1.1  christos       int type;
   3033       1.1  christos       const char *name;
   3034       1.1  christos       bfd_vma value;
   3035       1.1  christos       asection *section;
   3036       1.1  christos       flagword flags;
   3037       1.1  christos       const char *string;
   3038       1.1  christos 
   3039   1.1.1.5  christos       *sym_hash = NULL;
   3040   1.1.1.6  christos 
   3041   1.1.1.9  christos       type = H_GET_8 (abfd, p->e_type);
   3042       1.1  christos 
   3043       1.1  christos       /* Ignore debugging symbols.  */
   3044       1.1  christos       if ((type & N_STAB) != 0)
   3045       1.1  christos 	continue;
   3046       1.1  christos 
   3047       1.1  christos       /* PR 19629: Corrupt binaries can contain illegal string offsets.  */
   3048       1.1  christos       if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd))
   3049       1.1  christos 	return false;
   3050       1.1  christos       name = strings + GET_WORD (abfd, p->e_strx);
   3051       1.1  christos       value = GET_WORD (abfd, p->e_value);
   3052       1.1  christos       flags = BSF_GLOBAL;
   3053       1.1  christos       string = NULL;
   3054       1.1  christos       switch (type)
   3055       1.1  christos 	{
   3056       1.1  christos 	default:
   3057       1.1  christos 	  abort ();
   3058       1.1  christos 
   3059       1.1  christos 	case N_UNDF:
   3060       1.1  christos 	case N_ABS:
   3061       1.1  christos 	case N_TEXT:
   3062       1.1  christos 	case N_DATA:
   3063       1.1  christos 	case N_BSS:
   3064       1.1  christos 	case N_FN_SEQ:
   3065       1.1  christos 	case N_COMM:
   3066       1.1  christos 	case N_SETV:
   3067       1.1  christos 	case N_FN:
   3068       1.1  christos 	  /* Ignore symbols that are not externally visible.  */
   3069       1.1  christos 	  continue;
   3070       1.1  christos 	case N_INDR:
   3071       1.1  christos 	  /* Ignore local indirect symbol.  */
   3072       1.1  christos 	  ++p;
   3073       1.1  christos 	  ++sym_hash;
   3074       1.1  christos 	  continue;
   3075       1.1  christos 
   3076       1.1  christos 	case N_UNDF | N_EXT:
   3077       1.1  christos 	  if (value == 0)
   3078       1.1  christos 	    {
   3079       1.1  christos 	      section = bfd_und_section_ptr;
   3080       1.1  christos 	      flags = 0;
   3081       1.1  christos 	    }
   3082   1.1.1.8  christos 	  else
   3083       1.1  christos 	    section = bfd_com_section_ptr;
   3084       1.1  christos 	  break;
   3085       1.1  christos 	case N_ABS | N_EXT:
   3086       1.1  christos 	  section = bfd_abs_section_ptr;
   3087       1.1  christos 	  break;
   3088       1.1  christos 	case N_TEXT | N_EXT:
   3089   1.1.1.8  christos 	  section = obj_textsec (abfd);
   3090       1.1  christos 	  value -= bfd_section_vma (section);
   3091       1.1  christos 	  break;
   3092       1.1  christos 	case N_DATA | N_EXT:
   3093   1.1.1.8  christos 	case N_SETV | N_EXT:
   3094       1.1  christos 	  /* Treat N_SETV symbols as N_DATA symbol; see comment in
   3095       1.1  christos 	     translate_from_native_sym_flags.  */
   3096       1.1  christos 	  section = obj_datasec (abfd);
   3097       1.1  christos 	  value -= bfd_section_vma (section);
   3098   1.1.1.6  christos 	  break;
   3099   1.1.1.6  christos 	case N_BSS | N_EXT:
   3100   1.1.1.9  christos 	  section = obj_bsssec (abfd);
   3101       1.1  christos 	  value -= bfd_section_vma (section);
   3102   1.1.1.5  christos 	  break;
   3103   1.1.1.6  christos 	case N_INDR | N_EXT:
   3104   1.1.1.9  christos 	  /* An indirect symbol.  The next symbol is the symbol
   3105       1.1  christos 	     which this one really is.  */
   3106       1.1  christos 	  /* See PR 20925 for a reproducer.  */
   3107       1.1  christos 	  if (p + 1 >= pend)
   3108       1.1  christos 	    return false;
   3109       1.1  christos 	  ++p;
   3110       1.1  christos 	  /* PR 19629: Corrupt binaries can contain illegal string offsets.  */
   3111       1.1  christos 	  if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd))
   3112       1.1  christos 	    return false;
   3113       1.1  christos 	  string = strings + GET_WORD (abfd, p->e_strx);
   3114       1.1  christos 	  section = bfd_ind_section_ptr;
   3115       1.1  christos 	  flags |= BSF_INDIRECT;
   3116       1.1  christos 	  break;
   3117       1.1  christos 	case N_COMM | N_EXT:
   3118       1.1  christos 	  section = bfd_com_section_ptr;
   3119   1.1.1.8  christos 	  break;
   3120       1.1  christos 	case N_SETA: case N_SETA | N_EXT:
   3121       1.1  christos 	  section = bfd_abs_section_ptr;
   3122       1.1  christos 	  flags |= BSF_CONSTRUCTOR;
   3123       1.1  christos 	  break;
   3124   1.1.1.8  christos 	case N_SETT: case N_SETT | N_EXT:
   3125       1.1  christos 	  section = obj_textsec (abfd);
   3126       1.1  christos 	  flags |= BSF_CONSTRUCTOR;
   3127       1.1  christos 	  value -= bfd_section_vma (section);
   3128       1.1  christos 	  break;
   3129   1.1.1.8  christos 	case N_SETD: case N_SETD | N_EXT:
   3130       1.1  christos 	  section = obj_datasec (abfd);
   3131       1.1  christos 	  flags |= BSF_CONSTRUCTOR;
   3132       1.1  christos 	  value -= bfd_section_vma (section);
   3133       1.1  christos 	  break;
   3134       1.1  christos 	case N_SETB: case N_SETB | N_EXT:
   3135   1.1.1.9  christos 	  section = obj_bsssec (abfd);
   3136       1.1  christos 	  flags |= BSF_CONSTRUCTOR;
   3137       1.1  christos 	  value -= bfd_section_vma (section);
   3138   1.1.1.5  christos 	  break;
   3139   1.1.1.6  christos 	case N_WARNING:
   3140   1.1.1.9  christos 	  /* A warning symbol.  The next symbol is the one to warn
   3141       1.1  christos 	     about.  If there is no next symbol, just look away.  */
   3142       1.1  christos 	  if (p + 1 >= pend)
   3143       1.1  christos 	    return true;
   3144       1.1  christos 	  ++p;
   3145       1.1  christos 	  string = name;
   3146       1.1  christos 	  /* PR 19629: Corrupt binaries can contain illegal string offsets.  */
   3147       1.1  christos 	  if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd))
   3148       1.1  christos 	    return false;
   3149       1.1  christos 	  name = strings + GET_WORD (abfd, p->e_strx);
   3150       1.1  christos 	  section = bfd_und_section_ptr;
   3151       1.1  christos 	  flags |= BSF_WARNING;
   3152       1.1  christos 	  break;
   3153       1.1  christos 	case N_WEAKU:
   3154       1.1  christos 	  section = bfd_und_section_ptr;
   3155   1.1.1.8  christos 	  flags = BSF_WEAK;
   3156       1.1  christos 	  break;
   3157       1.1  christos 	case N_WEAKA:
   3158       1.1  christos 	  section = bfd_abs_section_ptr;
   3159       1.1  christos 	  flags = BSF_WEAK;
   3160   1.1.1.8  christos 	  break;
   3161       1.1  christos 	case N_WEAKT:
   3162       1.1  christos 	  section = obj_textsec (abfd);
   3163       1.1  christos 	  value -= bfd_section_vma (section);
   3164       1.1  christos 	  flags = BSF_WEAK;
   3165   1.1.1.8  christos 	  break;
   3166       1.1  christos 	case N_WEAKD:
   3167       1.1  christos 	  section = obj_datasec (abfd);
   3168       1.1  christos 	  value -= bfd_section_vma (section);
   3169       1.1  christos 	  flags = BSF_WEAK;
   3170       1.1  christos 	  break;
   3171   1.1.1.9  christos 	case N_WEAKB:
   3172       1.1  christos 	  section = obj_bsssec (abfd);
   3173   1.1.1.9  christos 	  value -= bfd_section_vma (section);
   3174       1.1  christos 	  flags = BSF_WEAK;
   3175       1.1  christos 	  break;
   3176       1.1  christos 	}
   3177       1.1  christos 
   3178       1.1  christos       if (! ((*add_one_symbol)
   3179       1.1  christos 	     (info, abfd, name, flags, section, value, string, copy, false,
   3180       1.1  christos 	      (struct bfd_link_hash_entry **) sym_hash)))
   3181       1.1  christos 	return false;
   3182       1.1  christos 
   3183       1.1  christos       /* Restrict the maximum alignment of a common symbol based on
   3184       1.1  christos 	 the architecture, since a.out has no way to represent
   3185       1.1  christos 	 alignment requirements of a section in a .o file.  FIXME:
   3186       1.1  christos 	 This isn't quite right: it should use the architecture of the
   3187       1.1  christos 	 output file, not the input files.  */
   3188       1.1  christos       if ((*sym_hash)->root.type == bfd_link_hash_common
   3189       1.1  christos 	  && ((*sym_hash)->root.u.c.p->alignment_power >
   3190       1.1  christos 	      bfd_get_arch_info (abfd)->section_align_power))
   3191       1.1  christos 	(*sym_hash)->root.u.c.p->alignment_power =
   3192       1.1  christos 	  bfd_get_arch_info (abfd)->section_align_power;
   3193       1.1  christos 
   3194       1.1  christos       /* If this is a set symbol, and we are not building sets, then
   3195       1.1  christos 	 it is possible for the hash entry to not have been set.  In
   3196       1.1  christos 	 such a case, treat the symbol as not globally defined.  */
   3197       1.1  christos       if ((*sym_hash)->root.type == bfd_link_hash_new)
   3198       1.1  christos 	{
   3199   1.1.1.9  christos 	  BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
   3200       1.1  christos 	  *sym_hash = NULL;
   3201       1.1  christos 	}
   3202       1.1  christos 
   3203       1.1  christos       if (type == (N_INDR | N_EXT) || type == N_WARNING)
   3204   1.1.1.9  christos 	++sym_hash;
   3205       1.1  christos     }
   3206       1.1  christos 
   3207       1.1  christos   return true;
   3208       1.1  christos }
   3209       1.1  christos 
   3210       1.1  christos /* Free up the internal symbols read from an a.out file.  */
   3211       1.1  christos 
   3212       1.1  christos static bool
   3213       1.1  christos aout_link_free_symbols (bfd *abfd)
   3214       1.1  christos {
   3215       1.1  christos   if (obj_aout_external_syms (abfd) != NULL)
   3216       1.1  christos     {
   3217   1.1.1.9  christos       free ((void *) obj_aout_external_syms (abfd));
   3218       1.1  christos       obj_aout_external_syms (abfd) = NULL;
   3219       1.1  christos     }
   3220       1.1  christos   if (obj_aout_external_strings (abfd) != NULL)
   3221       1.1  christos     {
   3222   1.1.1.9  christos       free ((void *) obj_aout_external_strings (abfd));
   3223       1.1  christos       obj_aout_external_strings (abfd) = NULL;
   3224       1.1  christos     }
   3225       1.1  christos   return true;
   3226   1.1.1.9  christos }
   3227       1.1  christos 
   3228   1.1.1.9  christos /* Add symbols from an a.out object file.  */
   3229       1.1  christos 
   3230       1.1  christos static bool
   3231       1.1  christos aout_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
   3232   1.1.1.9  christos {
   3233       1.1  christos   if (! aout_get_external_symbols (abfd))
   3234   1.1.1.9  christos     return false;
   3235       1.1  christos   if (! aout_link_add_symbols (abfd, info))
   3236       1.1  christos     return false;
   3237       1.1  christos   if (! info->keep_memory)
   3238       1.1  christos     {
   3239       1.1  christos       if (! aout_link_free_symbols (abfd))
   3240       1.1  christos 	return false;
   3241       1.1  christos     }
   3242       1.1  christos   return true;
   3243       1.1  christos }
   3244   1.1.1.9  christos 
   3245       1.1  christos /* Look through the internal symbols to see if this object file should
   3246       1.1  christos    be included in the link.  We should include this object file if it
   3247   1.1.1.9  christos    defines any symbols which are currently undefined.  If this object
   3248       1.1  christos    file defines a common symbol, then we may adjust the size of the
   3249       1.1  christos    known symbol but we do not include the object file in the link
   3250       1.1  christos    (unless there is some other reason to include it).  */
   3251       1.1  christos 
   3252       1.1  christos static bool
   3253       1.1  christos aout_link_check_ar_symbols (bfd *abfd,
   3254   1.1.1.9  christos 			    struct bfd_link_info *info,
   3255       1.1  christos 			    bool *pneeded,
   3256       1.1  christos 			    bfd **subsbfd)
   3257       1.1  christos {
   3258       1.1  christos   struct external_nlist *p;
   3259       1.1  christos   struct external_nlist *pend;
   3260       1.1  christos   char *strings;
   3261       1.1  christos 
   3262       1.1  christos   *pneeded = false;
   3263       1.1  christos 
   3264       1.1  christos   /* Look through all the symbols.  */
   3265       1.1  christos   p = obj_aout_external_syms (abfd);
   3266       1.1  christos   pend = p + obj_aout_external_sym_count (abfd);
   3267       1.1  christos   strings = obj_aout_external_strings (abfd);
   3268       1.1  christos   for (; p < pend; p++)
   3269       1.1  christos     {
   3270       1.1  christos       int type = H_GET_8 (abfd, p->e_type);
   3271       1.1  christos       const char *name;
   3272       1.1  christos       struct bfd_link_hash_entry *h;
   3273       1.1  christos 
   3274       1.1  christos       /* Ignore symbols that are not externally visible.  This is an
   3275       1.1  christos 	 optimization only, as we check the type more thoroughly
   3276       1.1  christos 	 below.  */
   3277       1.1  christos       if (((type & N_EXT) == 0
   3278       1.1  christos 	   || (type & N_STAB) != 0
   3279       1.1  christos 	   || type == N_FN)
   3280       1.1  christos 	  && type != N_WEAKA
   3281       1.1  christos 	  && type != N_WEAKT
   3282       1.1  christos 	  && type != N_WEAKD
   3283       1.1  christos 	  && type != N_WEAKB)
   3284   1.1.1.9  christos 	{
   3285       1.1  christos 	  if (type == N_WARNING
   3286       1.1  christos 	      || type == N_INDR)
   3287       1.1  christos 	    ++p;
   3288       1.1  christos 	  continue;
   3289       1.1  christos 	}
   3290       1.1  christos 
   3291       1.1  christos       name = strings + GET_WORD (abfd, p->e_strx);
   3292       1.1  christos       h = bfd_link_hash_lookup (info->hash, name, false, false, true);
   3293       1.1  christos 
   3294       1.1  christos       /* We are only interested in symbols that are currently
   3295       1.1  christos 	 undefined or common.  */
   3296       1.1  christos       if (h == NULL
   3297       1.1  christos 	  || (h->type != bfd_link_hash_undefined
   3298       1.1  christos 	      && h->type != bfd_link_hash_common))
   3299       1.1  christos 	{
   3300       1.1  christos 	  if (type == (N_INDR | N_EXT))
   3301       1.1  christos 	    ++p;
   3302       1.1  christos 	  continue;
   3303       1.1  christos 	}
   3304       1.1  christos 
   3305       1.1  christos       if (type == (N_TEXT | N_EXT)
   3306       1.1  christos 	  || type == (N_DATA | N_EXT)
   3307   1.1.1.7  christos 	  || type == (N_BSS | N_EXT)
   3308       1.1  christos 	  || type == (N_ABS | N_EXT)
   3309   1.1.1.7  christos 	  || type == (N_INDR | N_EXT))
   3310       1.1  christos 	{
   3311   1.1.1.7  christos 	  /* This object file defines this symbol.  We must link it
   3312       1.1  christos 	     in.  This is true regardless of whether the current
   3313   1.1.1.7  christos 	     definition of the symbol is undefined or common.
   3314       1.1  christos 
   3315       1.1  christos 	     If the current definition is common, we have a case in
   3316       1.1  christos 	     which we have already seen an object file including:
   3317       1.1  christos 		 int a;
   3318       1.1  christos 	     and this object file from the archive includes:
   3319       1.1  christos 		 int a = 5;
   3320       1.1  christos 	     In such a case, whether to include this object is target
   3321       1.1  christos 	     dependant for backward compatibility.
   3322       1.1  christos 
   3323       1.1  christos 	     FIXME: The SunOS 4.1.3 linker will pull in the archive
   3324       1.1  christos 	     element if the symbol is defined in the .data section,
   3325       1.1  christos 	     but not if it is defined in the .text section.  That
   3326   1.1.1.7  christos 	     seems a bit crazy to me, and it has not been implemented
   3327   1.1.1.7  christos 	     yet.  However, it might be correct.  */
   3328       1.1  christos 	  if (h->type == bfd_link_hash_common)
   3329       1.1  christos 	    {
   3330       1.1  christos 	      int skip = 0;
   3331       1.1  christos 
   3332       1.1  christos 	      switch (info->common_skip_ar_symbols)
   3333       1.1  christos 		{
   3334       1.1  christos 		case bfd_link_common_skip_none:
   3335       1.1  christos 		  break;
   3336       1.1  christos 		case bfd_link_common_skip_text:
   3337       1.1  christos 		  skip = (type == (N_TEXT | N_EXT));
   3338       1.1  christos 		  break;
   3339       1.1  christos 		case bfd_link_common_skip_data:
   3340       1.1  christos 		  skip = (type == (N_DATA | N_EXT));
   3341       1.1  christos 		  break;
   3342       1.1  christos 		case bfd_link_common_skip_all:
   3343       1.1  christos 		  skip = 1;
   3344       1.1  christos 		  break;
   3345   1.1.1.9  christos 		}
   3346   1.1.1.9  christos 
   3347   1.1.1.9  christos 	      if (skip)
   3348       1.1  christos 		continue;
   3349       1.1  christos 	    }
   3350       1.1  christos 
   3351       1.1  christos 	  if (!(*info->callbacks
   3352       1.1  christos 		->add_archive_element) (info, abfd, name, subsbfd))
   3353       1.1  christos 	    return false;
   3354       1.1  christos 	  *pneeded = true;
   3355       1.1  christos 	  return true;
   3356       1.1  christos 	}
   3357       1.1  christos 
   3358       1.1  christos       if (type == (N_UNDF | N_EXT))
   3359       1.1  christos 	{
   3360       1.1  christos 	  bfd_vma value;
   3361       1.1  christos 
   3362       1.1  christos 	  value = GET_WORD (abfd, p->e_value);
   3363       1.1  christos 	  if (value != 0)
   3364       1.1  christos 	    {
   3365       1.1  christos 	      /* This symbol is common in the object from the archive
   3366       1.1  christos 		 file.  */
   3367       1.1  christos 	      if (h->type == bfd_link_hash_undefined)
   3368       1.1  christos 		{
   3369       1.1  christos 		  bfd *symbfd;
   3370       1.1  christos 		  unsigned int power;
   3371       1.1  christos 
   3372       1.1  christos 		  symbfd = h->u.undef.abfd;
   3373   1.1.1.9  christos 		  if (symbfd == NULL)
   3374   1.1.1.9  christos 		    {
   3375   1.1.1.9  christos 		      /* This symbol was created as undefined from
   3376       1.1  christos 			 outside BFD.  We assume that we should link
   3377       1.1  christos 			 in the object file.  This is done for the -u
   3378       1.1  christos 			 option in the linker.  */
   3379       1.1  christos 		      if (!(*info->callbacks
   3380       1.1  christos 			    ->add_archive_element) (info, abfd, name, subsbfd))
   3381       1.1  christos 			return false;
   3382       1.1  christos 		      *pneeded = true;
   3383       1.1  christos 		      return true;
   3384   1.1.1.9  christos 		    }
   3385       1.1  christos 		  /* Turn the current link symbol into a common
   3386       1.1  christos 		     symbol.  It is already on the undefs list.  */
   3387       1.1  christos 		  h->type = bfd_link_hash_common;
   3388       1.1  christos 		  h->u.c.p = (struct bfd_link_hash_common_entry *)
   3389       1.1  christos 		    bfd_hash_allocate (&info->hash->table,
   3390       1.1  christos 				       sizeof (struct bfd_link_hash_common_entry));
   3391       1.1  christos 		  if (h->u.c.p == NULL)
   3392       1.1  christos 		    return false;
   3393       1.1  christos 
   3394       1.1  christos 		  h->u.c.size = value;
   3395       1.1  christos 
   3396       1.1  christos 		  /* FIXME: This isn't quite right.  The maximum
   3397       1.1  christos 		     alignment of a common symbol should be set by the
   3398       1.1  christos 		     architecture of the output file, not of the input
   3399       1.1  christos 		     file.  */
   3400       1.1  christos 		  power = bfd_log2 (value);
   3401       1.1  christos 		  if (power > bfd_get_arch_info (abfd)->section_align_power)
   3402       1.1  christos 		    power = bfd_get_arch_info (abfd)->section_align_power;
   3403       1.1  christos 		  h->u.c.p->alignment_power = power;
   3404       1.1  christos 
   3405       1.1  christos 		  h->u.c.p->section = bfd_make_section_old_way (symbfd,
   3406       1.1  christos 								"COMMON");
   3407       1.1  christos 		}
   3408       1.1  christos 	      else
   3409       1.1  christos 		{
   3410       1.1  christos 		  /* Adjust the size of the common symbol if
   3411       1.1  christos 		     necessary.  */
   3412       1.1  christos 		  if (value > h->u.c.size)
   3413       1.1  christos 		    h->u.c.size = value;
   3414       1.1  christos 		}
   3415       1.1  christos 	    }
   3416       1.1  christos 	}
   3417       1.1  christos 
   3418       1.1  christos       if (type == N_WEAKA
   3419       1.1  christos 	  || type == N_WEAKT
   3420       1.1  christos 	  || type == N_WEAKD
   3421       1.1  christos 	  || type == N_WEAKB)
   3422   1.1.1.9  christos 	{
   3423   1.1.1.9  christos 	  /* This symbol is weak but defined.  We must pull it in if
   3424   1.1.1.9  christos 	     the current link symbol is undefined, but we don't want
   3425       1.1  christos 	     it if the current link symbol is common.  */
   3426       1.1  christos 	  if (h->type == bfd_link_hash_undefined)
   3427       1.1  christos 	    {
   3428       1.1  christos 	      if (!(*info->callbacks
   3429       1.1  christos 		    ->add_archive_element) (info, abfd, name, subsbfd))
   3430   1.1.1.9  christos 		return false;
   3431       1.1  christos 	      *pneeded = true;
   3432       1.1  christos 	      return true;
   3433       1.1  christos 	    }
   3434       1.1  christos 	}
   3435       1.1  christos     }
   3436       1.1  christos 
   3437   1.1.1.9  christos   /* We do not need this object file.  */
   3438       1.1  christos   return true;
   3439       1.1  christos }
   3440   1.1.1.3  christos /* Check a single archive element to see if we need to include it in
   3441   1.1.1.3  christos    the link.  *PNEEDED is set according to whether this element is
   3442   1.1.1.9  christos    needed in the link or not.  This is called from
   3443       1.1  christos    _bfd_generic_link_add_archive_symbols.  */
   3444       1.1  christos 
   3445   1.1.1.9  christos static bool
   3446       1.1  christos aout_link_check_archive_element (bfd *abfd,
   3447       1.1  christos 				 struct bfd_link_info *info,
   3448   1.1.1.9  christos 				 struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
   3449       1.1  christos 				 const char *name ATTRIBUTE_UNUSED,
   3450       1.1  christos 				 bool *pneeded)
   3451       1.1  christos {
   3452   1.1.1.9  christos   bfd *oldbfd;
   3453       1.1  christos   bool needed;
   3454       1.1  christos 
   3455       1.1  christos   if (!aout_get_external_symbols (abfd))
   3456       1.1  christos     return false;
   3457       1.1  christos 
   3458       1.1  christos   oldbfd = abfd;
   3459       1.1  christos   if (!aout_link_check_ar_symbols (abfd, info, pneeded, &abfd))
   3460       1.1  christos     return false;
   3461       1.1  christos 
   3462       1.1  christos   needed = *pneeded;
   3463   1.1.1.9  christos   if (needed)
   3464       1.1  christos     {
   3465   1.1.1.9  christos       /* Potentially, the add_archive_element hook may have set a
   3466       1.1  christos 	 substitute BFD for us.  */
   3467       1.1  christos       if (abfd != oldbfd)
   3468   1.1.1.9  christos 	{
   3469       1.1  christos 	  if (!info->keep_memory
   3470       1.1  christos 	      && !aout_link_free_symbols (oldbfd))
   3471       1.1  christos 	    return false;
   3472       1.1  christos 	  if (!aout_get_external_symbols (abfd))
   3473       1.1  christos 	    return false;
   3474   1.1.1.9  christos 	}
   3475       1.1  christos       if (!aout_link_add_symbols (abfd, info))
   3476       1.1  christos 	return false;
   3477   1.1.1.9  christos     }
   3478       1.1  christos 
   3479       1.1  christos   if (!info->keep_memory || !needed)
   3480       1.1  christos     {
   3481       1.1  christos       if (!aout_link_free_symbols (abfd))
   3482       1.1  christos 	return false;
   3483   1.1.1.9  christos     }
   3484       1.1  christos 
   3485       1.1  christos   return true;
   3486       1.1  christos }
   3487       1.1  christos 
   3488       1.1  christos /* Given an a.out BFD, add symbols to the global hash table as
   3489       1.1  christos    appropriate.  */
   3490       1.1  christos 
   3491       1.1  christos bool
   3492       1.1  christos NAME (aout, link_add_symbols) (bfd *abfd, struct bfd_link_info *info)
   3493       1.1  christos {
   3494       1.1  christos   switch (bfd_get_format (abfd))
   3495   1.1.1.9  christos     {
   3496       1.1  christos     case bfd_object:
   3497       1.1  christos       return aout_link_add_object_symbols (abfd, info);
   3498       1.1  christos     case bfd_archive:
   3499       1.1  christos       return _bfd_generic_link_add_archive_symbols
   3500       1.1  christos 	(abfd, info, aout_link_check_archive_element);
   3501       1.1  christos     default:
   3502       1.1  christos       bfd_set_error (bfd_error_wrong_format);
   3503       1.1  christos       return false;
   3504       1.1  christos     }
   3505       1.1  christos }
   3506       1.1  christos 
   3507       1.1  christos /* A hash table used for header files with N_BINCL entries.  */
   3509       1.1  christos 
   3510       1.1  christos struct aout_link_includes_table
   3511       1.1  christos {
   3512       1.1  christos   struct bfd_hash_table root;
   3513       1.1  christos };
   3514       1.1  christos 
   3515       1.1  christos /* A linked list of totals that we have found for a particular header
   3516       1.1  christos    file.  */
   3517       1.1  christos 
   3518       1.1  christos struct aout_link_includes_totals
   3519       1.1  christos {
   3520       1.1  christos   struct aout_link_includes_totals *next;
   3521       1.1  christos   bfd_vma total;
   3522       1.1  christos };
   3523       1.1  christos 
   3524       1.1  christos /* An entry in the header file hash table.  */
   3525       1.1  christos 
   3526       1.1  christos struct aout_link_includes_entry
   3527       1.1  christos {
   3528       1.1  christos   struct bfd_hash_entry root;
   3529       1.1  christos   /* List of totals we have found for this file.  */
   3530       1.1  christos   struct aout_link_includes_totals *totals;
   3531       1.1  christos };
   3532       1.1  christos 
   3533       1.1  christos /* Look up an entry in an the header file hash table.  */
   3534       1.1  christos 
   3535       1.1  christos #define aout_link_includes_lookup(table, string, create, copy)		\
   3536       1.1  christos   ((struct aout_link_includes_entry *)					\
   3537       1.1  christos    bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
   3538       1.1  christos 
   3539       1.1  christos /* During the final link step we need to pass around a bunch of
   3540       1.1  christos    information, so we do it in an instance of this structure.  */
   3541       1.1  christos 
   3542       1.1  christos struct aout_final_link_info
   3543       1.1  christos {
   3544       1.1  christos   /* General link information.  */
   3545       1.1  christos   struct bfd_link_info *info;
   3546       1.1  christos   /* Output bfd.  */
   3547       1.1  christos   bfd *output_bfd;
   3548       1.1  christos   /* Reloc file positions.  */
   3549       1.1  christos   file_ptr treloff, dreloff;
   3550       1.1  christos   /* File position of symbols.  */
   3551       1.1  christos   file_ptr symoff;
   3552       1.1  christos   /* String table.  */
   3553       1.1  christos   struct bfd_strtab_hash *strtab;
   3554       1.1  christos   /* Header file hash table.  */
   3555       1.1  christos   struct aout_link_includes_table includes;
   3556       1.1  christos   /* A buffer large enough to hold the contents of any section.  */
   3557       1.1  christos   bfd_byte *contents;
   3558       1.1  christos   /* A buffer large enough to hold the relocs of any section.  */
   3559       1.1  christos   void * relocs;
   3560       1.1  christos   /* A buffer large enough to hold the symbol map of any input BFD.  */
   3561       1.1  christos   int *symbol_map;
   3562       1.1  christos   /* A buffer large enough to hold output symbols of any input BFD.  */
   3563       1.1  christos   struct external_nlist *output_syms;
   3564       1.1  christos };
   3565       1.1  christos 
   3566       1.1  christos /* The function to create a new entry in the header file hash table.  */
   3567       1.1  christos 
   3568       1.1  christos static struct bfd_hash_entry *
   3569       1.1  christos aout_link_includes_newfunc (struct bfd_hash_entry *entry,
   3570       1.1  christos 			    struct bfd_hash_table *table,
   3571   1.1.1.7  christos 			    const char *string)
   3572       1.1  christos {
   3573       1.1  christos   struct aout_link_includes_entry *ret =
   3574       1.1  christos     (struct aout_link_includes_entry *) entry;
   3575       1.1  christos 
   3576       1.1  christos   /* Allocate the structure if it has not already been allocated by a
   3577       1.1  christos      subclass.  */
   3578       1.1  christos   if (ret == NULL)
   3579       1.1  christos     ret = (struct aout_link_includes_entry *)
   3580       1.1  christos 	bfd_hash_allocate (table, sizeof (* ret));
   3581       1.1  christos   if (ret == NULL)
   3582       1.1  christos     return NULL;
   3583       1.1  christos 
   3584       1.1  christos   /* Call the allocation method of the superclass.  */
   3585       1.1  christos   ret = ((struct aout_link_includes_entry *)
   3586       1.1  christos 	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
   3587       1.1  christos   if (ret)
   3588       1.1  christos     {
   3589       1.1  christos       /* Set local fields.  */
   3590   1.1.1.9  christos       ret->totals = NULL;
   3591   1.1.1.2  christos     }
   3592       1.1  christos 
   3593   1.1.1.2  christos   return (struct bfd_hash_entry *) ret;
   3594   1.1.1.2  christos }
   3595       1.1  christos 
   3596       1.1  christos /* Write out a symbol that was not associated with an a.out input
   3597       1.1  christos    object.  */
   3598       1.1  christos 
   3599       1.1  christos static bool
   3600   1.1.1.8  christos aout_link_write_other_symbol (struct bfd_hash_entry *bh, void *data)
   3601       1.1  christos {
   3602       1.1  christos   struct aout_link_hash_entry *h = (struct aout_link_hash_entry *) bh;
   3603       1.1  christos   struct aout_final_link_info *flaginfo = (struct aout_final_link_info *) data;
   3604       1.1  christos   bfd *output_bfd;
   3605       1.1  christos   int type;
   3606   1.1.1.9  christos   bfd_vma val;
   3607       1.1  christos   struct external_nlist outsym;
   3608       1.1  christos   bfd_size_type indx;
   3609   1.1.1.2  christos   size_t amt;
   3610       1.1  christos 
   3611       1.1  christos   if (h->root.type == bfd_link_hash_warning)
   3612       1.1  christos     {
   3613       1.1  christos       h = (struct aout_link_hash_entry *) h->root.u.i.link;
   3614   1.1.1.2  christos       if (h->root.type == bfd_link_hash_new)
   3615       1.1  christos 	return true;
   3616       1.1  christos     }
   3617       1.1  christos 
   3618       1.1  christos   output_bfd = flaginfo->output_bfd;
   3619       1.1  christos 
   3620       1.1  christos   if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
   3621       1.1  christos     {
   3622   1.1.1.9  christos       if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
   3623       1.1  christos 	     (output_bfd, flaginfo->info, h)))
   3624   1.1.1.9  christos 	{
   3625       1.1  christos 	  /* FIXME: No way to handle errors.  */
   3626       1.1  christos 	  abort ();
   3627       1.1  christos 	}
   3628   1.1.1.2  christos     }
   3629   1.1.1.2  christos 
   3630   1.1.1.2  christos   if (h->written)
   3631   1.1.1.9  christos     return true;
   3632   1.1.1.9  christos 
   3633       1.1  christos   h->written = true;
   3634       1.1  christos 
   3635       1.1  christos   /* An indx of -2 means the symbol must be written.  */
   3636       1.1  christos   if (h->indx != -2
   3637       1.1  christos       && (flaginfo->info->strip == strip_all
   3638       1.1  christos 	  || (flaginfo->info->strip == strip_some
   3639       1.1  christos 	      && bfd_hash_lookup (flaginfo->info->keep_hash, h->root.root.string,
   3640   1.1.1.9  christos 				  false, false) == NULL)))
   3641       1.1  christos     return true;
   3642       1.1  christos 
   3643   1.1.1.7  christos   switch (h->root.type)
   3644   1.1.1.9  christos     {
   3645       1.1  christos     default:
   3646       1.1  christos     case bfd_link_hash_warning:
   3647       1.1  christos       abort ();
   3648       1.1  christos       /* Avoid variable not initialized warnings.  */
   3649       1.1  christos       return true;
   3650       1.1  christos     case bfd_link_hash_new:
   3651       1.1  christos       /* This can happen for set symbols when sets are not being
   3652       1.1  christos 	 built.  */
   3653       1.1  christos       return true;
   3654       1.1  christos     case bfd_link_hash_undefined:
   3655       1.1  christos       type = N_UNDF | N_EXT;
   3656       1.1  christos       val = 0;
   3657       1.1  christos       break;
   3658       1.1  christos     case bfd_link_hash_defined:
   3659       1.1  christos     case bfd_link_hash_defweak:
   3660       1.1  christos       {
   3661       1.1  christos 	asection *sec;
   3662       1.1  christos 
   3663       1.1  christos 	sec = h->root.u.def.section->output_section;
   3664       1.1  christos 	BFD_ASSERT (bfd_is_abs_section (sec)
   3665       1.1  christos 		    || sec->owner == output_bfd);
   3666       1.1  christos 	if (sec == obj_textsec (output_bfd))
   3667       1.1  christos 	  type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
   3668       1.1  christos 	else if (sec == obj_datasec (output_bfd))
   3669       1.1  christos 	  type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
   3670       1.1  christos 	else if (sec == obj_bsssec (output_bfd))
   3671       1.1  christos 	  type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
   3672       1.1  christos 	else
   3673       1.1  christos 	  type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
   3674       1.1  christos 	type |= N_EXT;
   3675       1.1  christos 	val = (h->root.u.def.value
   3676       1.1  christos 	       + sec->vma
   3677       1.1  christos 	       + h->root.u.def.section->output_offset);
   3678       1.1  christos       }
   3679       1.1  christos       break;
   3680       1.1  christos     case bfd_link_hash_common:
   3681       1.1  christos       type = N_UNDF | N_EXT;
   3682   1.1.1.9  christos       val = h->root.u.c.size;
   3683       1.1  christos       break;
   3684       1.1  christos     case bfd_link_hash_undefweak:
   3685       1.1  christos       type = N_WEAKU;
   3686       1.1  christos       val = 0;
   3687       1.1  christos       break;
   3688   1.1.1.2  christos     case bfd_link_hash_indirect:
   3689   1.1.1.9  christos       /* We ignore these symbols, since the indirected symbol is
   3690       1.1  christos 	 already in the hash table.  */
   3691       1.1  christos       return true;
   3692       1.1  christos     }
   3693       1.1  christos 
   3694       1.1  christos   H_PUT_8 (output_bfd, type, outsym.e_type);
   3695       1.1  christos   H_PUT_8 (output_bfd, 0, outsym.e_other);
   3696       1.1  christos   H_PUT_16 (output_bfd, 0, outsym.e_desc);
   3697       1.1  christos   indx = add_to_stringtab (output_bfd, flaginfo->strtab, h->root.root.string,
   3698   1.1.1.2  christos 			   false);
   3699  1.1.1.10  christos   if (indx == - (bfd_size_type) 1)
   3700       1.1  christos     /* FIXME: No way to handle errors.  */
   3701       1.1  christos     abort ();
   3702       1.1  christos 
   3703   1.1.1.2  christos   PUT_WORD (output_bfd, indx, outsym.e_strx);
   3704       1.1  christos   PUT_WORD (output_bfd, val, outsym.e_value);
   3705       1.1  christos 
   3706       1.1  christos   amt = EXTERNAL_NLIST_SIZE;
   3707   1.1.1.9  christos   if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0
   3708       1.1  christos       || bfd_write (&outsym, amt, output_bfd) != amt)
   3709       1.1  christos     /* FIXME: No way to handle errors.  */
   3710       1.1  christos     abort ();
   3711       1.1  christos 
   3712   1.1.1.9  christos   flaginfo->symoff += EXTERNAL_NLIST_SIZE;
   3713   1.1.1.2  christos   h->indx = obj_aout_external_sym_count (output_bfd);
   3714       1.1  christos   ++obj_aout_external_sym_count (output_bfd);
   3715       1.1  christos 
   3716       1.1  christos   return true;
   3717       1.1  christos }
   3718       1.1  christos 
   3719       1.1  christos /* Handle a link order which is supposed to generate a reloc.  */
   3720       1.1  christos 
   3721       1.1  christos static bool
   3722       1.1  christos aout_link_reloc_link_order (struct aout_final_link_info *flaginfo,
   3723       1.1  christos 			    asection *o,
   3724       1.1  christos 			    struct bfd_link_order *p)
   3725   1.1.1.8  christos {
   3726       1.1  christos   struct bfd_link_order_reloc *pr;
   3727       1.1  christos   int r_index;
   3728       1.1  christos   int r_extern;
   3729       1.1  christos   reloc_howto_type *howto;
   3730       1.1  christos   file_ptr *reloff_ptr = NULL;
   3731       1.1  christos   struct reloc_std_external srel;
   3732       1.1  christos   struct reloc_ext_external erel;
   3733       1.1  christos   void * rel_ptr;
   3734       1.1  christos   size_t amt;
   3735       1.1  christos 
   3736   1.1.1.2  christos   pr = p->u.reloc.p;
   3737       1.1  christos 
   3738       1.1  christos   if (p->type == bfd_section_reloc_link_order)
   3739       1.1  christos     {
   3740       1.1  christos       r_extern = 0;
   3741       1.1  christos       if (bfd_is_abs_section (pr->u.section))
   3742       1.1  christos 	r_index = N_ABS | N_EXT;
   3743       1.1  christos       else
   3744       1.1  christos 	{
   3745       1.1  christos 	  BFD_ASSERT (pr->u.section->owner == flaginfo->output_bfd);
   3746       1.1  christos 	  r_index = pr->u.section->target_index;
   3747   1.1.1.2  christos 	}
   3748   1.1.1.9  christos     }
   3749       1.1  christos   else
   3750       1.1  christos     {
   3751       1.1  christos       struct aout_link_hash_entry *h;
   3752       1.1  christos 
   3753       1.1  christos       BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
   3754       1.1  christos       r_extern = 1;
   3755       1.1  christos       h = ((struct aout_link_hash_entry *)
   3756       1.1  christos 	   bfd_wrapped_link_hash_lookup (flaginfo->output_bfd, flaginfo->info,
   3757       1.1  christos 					 pr->u.name, false, false, true));
   3758       1.1  christos       if (h != NULL
   3759   1.1.1.9  christos 	  && h->indx >= 0)
   3760   1.1.1.2  christos 	r_index = h->indx;
   3761   1.1.1.9  christos       else if (h != NULL)
   3762       1.1  christos 	{
   3763       1.1  christos 	  /* We decided to strip this symbol, but it turns out that we
   3764       1.1  christos 	     can't.  Note that we lose the other and desc information
   3765       1.1  christos 	     here.  I don't think that will ever matter for a global
   3766   1.1.1.5  christos 	     symbol.  */
   3767   1.1.1.5  christos 	  h->indx = -2;
   3768       1.1  christos 	  h->written = false;
   3769       1.1  christos 	  if (!aout_link_write_other_symbol (&h->root.root, flaginfo))
   3770       1.1  christos 	    return false;
   3771       1.1  christos 	  r_index = h->indx;
   3772   1.1.1.2  christos 	}
   3773       1.1  christos       else
   3774       1.1  christos 	{
   3775       1.1  christos 	  (*flaginfo->info->callbacks->unattached_reloc)
   3776   1.1.1.9  christos 	    (flaginfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0);
   3777       1.1  christos 	  r_index = 0;
   3778       1.1  christos 	}
   3779   1.1.1.2  christos     }
   3780   1.1.1.2  christos 
   3781   1.1.1.2  christos   howto = bfd_reloc_type_lookup (flaginfo->output_bfd, pr->reloc);
   3782   1.1.1.2  christos   if (howto == 0)
   3783       1.1  christos     {
   3784       1.1  christos       bfd_set_error (bfd_error_bad_value);
   3785       1.1  christos       return false;
   3786   1.1.1.2  christos     }
   3787       1.1  christos 
   3788       1.1  christos   if (o == obj_textsec (flaginfo->output_bfd))
   3789   1.1.1.2  christos     reloff_ptr = &flaginfo->treloff;
   3790       1.1  christos   else if (o == obj_datasec (flaginfo->output_bfd))
   3791       1.1  christos     reloff_ptr = &flaginfo->dreloff;
   3792       1.1  christos   else
   3793       1.1  christos     abort ();
   3794       1.1  christos 
   3795       1.1  christos   if (obj_reloc_entry_size (flaginfo->output_bfd) == RELOC_STD_SIZE)
   3796       1.1  christos     {
   3797   1.1.1.8  christos #ifdef MY_put_reloc
   3798       1.1  christos       MY_put_reloc (flaginfo->output_bfd, r_extern, r_index, p->offset, howto,
   3799       1.1  christos 		    &srel);
   3800       1.1  christos #else
   3801       1.1  christos       {
   3802       1.1  christos 	int r_pcrel;
   3803   1.1.1.9  christos 	int r_baserel;
   3804       1.1  christos 	int r_jmptable;
   3805   1.1.1.2  christos 	int r_relative;
   3806   1.1.1.2  christos 	unsigned int r_length;
   3807       1.1  christos 
   3808       1.1  christos 	r_pcrel = (int) howto->pc_relative;
   3809       1.1  christos 	r_baserel = (howto->type & 8) != 0;
   3810       1.1  christos 	r_jmptable = (howto->type & 16) != 0;
   3811       1.1  christos 	r_relative = (howto->type & 32) != 0;
   3812       1.1  christos 	r_length = bfd_log2 (bfd_get_reloc_size (howto));
   3813       1.1  christos 
   3814       1.1  christos 	PUT_WORD (flaginfo->output_bfd, p->offset, srel.r_address);
   3815       1.1  christos 	if (bfd_header_big_endian (flaginfo->output_bfd))
   3816       1.1  christos 	  {
   3817       1.1  christos 	    srel.r_index[0] = r_index >> 16;
   3818       1.1  christos 	    srel.r_index[1] = r_index >> 8;
   3819       1.1  christos 	    srel.r_index[2] = r_index;
   3820       1.1  christos 	    srel.r_type[0] =
   3821       1.1  christos 	      ((r_extern ?     RELOC_STD_BITS_EXTERN_BIG : 0)
   3822       1.1  christos 	       | (r_pcrel ?    RELOC_STD_BITS_PCREL_BIG : 0)
   3823       1.1  christos 	       | (r_baserel ?  RELOC_STD_BITS_BASEREL_BIG : 0)
   3824       1.1  christos 	       | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
   3825       1.1  christos 	       | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
   3826       1.1  christos 	       | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
   3827       1.1  christos 	  }
   3828       1.1  christos 	else
   3829       1.1  christos 	  {
   3830       1.1  christos 	    srel.r_index[2] = r_index >> 16;
   3831       1.1  christos 	    srel.r_index[1] = r_index >> 8;
   3832       1.1  christos 	    srel.r_index[0] = r_index;
   3833       1.1  christos 	    srel.r_type[0] =
   3834       1.1  christos 	      ((r_extern ?     RELOC_STD_BITS_EXTERN_LITTLE : 0)
   3835       1.1  christos 	       | (r_pcrel ?    RELOC_STD_BITS_PCREL_LITTLE : 0)
   3836       1.1  christos 	       | (r_baserel ?  RELOC_STD_BITS_BASEREL_LITTLE : 0)
   3837       1.1  christos 	       | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
   3838       1.1  christos 	       | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
   3839       1.1  christos 	       | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
   3840       1.1  christos 	  }
   3841       1.1  christos       }
   3842       1.1  christos #endif
   3843       1.1  christos       rel_ptr = (void *) &srel;
   3844       1.1  christos 
   3845       1.1  christos       /* We have to write the addend into the object file, since
   3846   1.1.1.9  christos 	 standard a.out relocs are in place.  It would be more
   3847       1.1  christos 	 reliable if we had the current contents of the file here,
   3848       1.1  christos 	 rather than assuming zeroes, but we can't read the file since
   3849       1.1  christos 	 it was opened using bfd_openw.  */
   3850   1.1.1.4  christos       if (pr->addend != 0)
   3851   1.1.1.9  christos 	{
   3852   1.1.1.2  christos 	  bfd_size_type size;
   3853       1.1  christos 	  bfd_reloc_status_type r;
   3854       1.1  christos 	  bfd_byte *buf;
   3855       1.1  christos 	  bool ok;
   3856       1.1  christos 
   3857       1.1  christos 	  size = bfd_get_reloc_size (howto);
   3858       1.1  christos 	  buf = (bfd_byte *) bfd_zmalloc (size);
   3859       1.1  christos 	  if (buf == NULL && size != 0)
   3860       1.1  christos 	    return false;
   3861       1.1  christos 	  r = MY_relocate_contents (howto, flaginfo->output_bfd,
   3862   1.1.1.5  christos 				    (bfd_vma) pr->addend, buf);
   3863   1.1.1.5  christos 	  switch (r)
   3864   1.1.1.5  christos 	    {
   3865   1.1.1.8  christos 	    case bfd_reloc_ok:
   3866   1.1.1.5  christos 	      break;
   3867   1.1.1.5  christos 	    default:
   3868       1.1  christos 	    case bfd_reloc_outofrange:
   3869       1.1  christos 	      abort ();
   3870   1.1.1.2  christos 	    case bfd_reloc_overflow:
   3871       1.1  christos 	      (*flaginfo->info->callbacks->reloc_overflow)
   3872       1.1  christos 		(flaginfo->info, NULL,
   3873       1.1  christos 		 (p->type == bfd_section_reloc_link_order
   3874   1.1.1.9  christos 		  ? bfd_section_name (pr->u.section)
   3875       1.1  christos 		  : pr->u.name),
   3876       1.1  christos 		 howto->name, pr->addend, NULL, NULL, (bfd_vma) 0);
   3877       1.1  christos 	      break;
   3878       1.1  christos 	    }
   3879       1.1  christos 	  ok = bfd_set_section_contents (flaginfo->output_bfd, o, (void *) buf,
   3880   1.1.1.2  christos 					 (file_ptr) p->offset, size);
   3881       1.1  christos 	  free (buf);
   3882       1.1  christos 	  if (! ok)
   3883   1.1.1.2  christos 	    return false;
   3884       1.1  christos 	}
   3885   1.1.1.2  christos     }
   3886       1.1  christos   else
   3887       1.1  christos     {
   3888       1.1  christos #ifdef MY_put_ext_reloc
   3889       1.1  christos       MY_put_ext_reloc (flaginfo->output_bfd, r_extern, r_index, p->offset,
   3890       1.1  christos 			howto, &erel, pr->addend);
   3891       1.1  christos #else
   3892       1.1  christos       PUT_WORD (flaginfo->output_bfd, p->offset, erel.r_address);
   3893       1.1  christos 
   3894       1.1  christos       if (bfd_header_big_endian (flaginfo->output_bfd))
   3895       1.1  christos 	{
   3896       1.1  christos 	  erel.r_index[0] = r_index >> 16;
   3897       1.1  christos 	  erel.r_index[1] = r_index >> 8;
   3898       1.1  christos 	  erel.r_index[2] = r_index;
   3899       1.1  christos 	  erel.r_type[0] =
   3900       1.1  christos 	    ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
   3901       1.1  christos 	     | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
   3902       1.1  christos 	}
   3903       1.1  christos       else
   3904   1.1.1.2  christos 	{
   3905       1.1  christos 	  erel.r_index[2] = r_index >> 16;
   3906       1.1  christos 	  erel.r_index[1] = r_index >> 8;
   3907       1.1  christos 	  erel.r_index[0] = r_index;
   3908       1.1  christos 	  erel.r_type[0] =
   3909       1.1  christos 	    (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
   3910   1.1.1.2  christos 	      | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
   3911   1.1.1.2  christos 	}
   3912  1.1.1.10  christos 
   3913   1.1.1.9  christos       PUT_WORD (flaginfo->output_bfd, (bfd_vma) pr->addend, erel.r_addend);
   3914       1.1  christos #endif /* MY_put_ext_reloc */
   3915   1.1.1.2  christos 
   3916       1.1  christos       rel_ptr = (void *) &erel;
   3917       1.1  christos     }
   3918       1.1  christos 
   3919   1.1.1.2  christos   amt = obj_reloc_entry_size (flaginfo->output_bfd);
   3920   1.1.1.2  christos   if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
   3921       1.1  christos       || bfd_write (rel_ptr, amt, flaginfo->output_bfd) != amt)
   3922   1.1.1.2  christos     return false;
   3923       1.1  christos 
   3924   1.1.1.9  christos   *reloff_ptr += obj_reloc_entry_size (flaginfo->output_bfd);
   3925       1.1  christos 
   3926       1.1  christos   /* Assert that the relocs have not run into the symbols, and that n
   3927       1.1  christos      the text relocs have not run into the data relocs.  */
   3928       1.1  christos   BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd)
   3929   1.1.1.9  christos 	      && (reloff_ptr != &flaginfo->treloff
   3930       1.1  christos 		  || (*reloff_ptr
   3931       1.1  christos 		      <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
   3932       1.1  christos 
   3933       1.1  christos   return true;
   3934       1.1  christos }
   3935       1.1  christos 
   3936       1.1  christos /* Get the section corresponding to a reloc index.  */
   3937       1.1  christos 
   3938       1.1  christos static inline asection *
   3939       1.1  christos aout_reloc_index_to_section (bfd *abfd, int indx)
   3940       1.1  christos {
   3941       1.1  christos   switch (indx & N_TYPE)
   3942       1.1  christos     {
   3943       1.1  christos     case N_TEXT:   return obj_textsec (abfd);
   3944       1.1  christos     case N_DATA:   return obj_datasec (abfd);
   3945       1.1  christos     case N_BSS:    return obj_bsssec (abfd);
   3946   1.1.1.9  christos     case N_ABS:
   3947   1.1.1.2  christos     case N_UNDF:   return bfd_abs_section_ptr;
   3948       1.1  christos     default:       abort ();
   3949       1.1  christos     }
   3950       1.1  christos   return NULL;
   3951       1.1  christos }
   3952       1.1  christos 
   3953       1.1  christos /* Relocate an a.out section using standard a.out relocs.  */
   3954   1.1.1.9  christos 
   3955       1.1  christos static bool
   3956   1.1.1.9  christos aout_link_input_section_std (struct aout_final_link_info *flaginfo,
   3957       1.1  christos 			     bfd *input_bfd,
   3958   1.1.1.9  christos 			     asection *input_section,
   3959       1.1  christos 			     struct reloc_std_external *relocs,
   3960       1.1  christos 			     bfd_size_type rel_size,
   3961       1.1  christos 			     bfd_byte *contents)
   3962       1.1  christos {
   3963       1.1  christos   bool (*check_dynamic_reloc)
   3964       1.1  christos     (struct bfd_link_info *, bfd *, asection *,
   3965       1.1  christos      struct aout_link_hash_entry *, void *, bfd_byte *, bool *, bfd_vma *);
   3966       1.1  christos   bfd *output_bfd;
   3967   1.1.1.2  christos   bool relocatable;
   3968       1.1  christos   struct external_nlist *syms;
   3969       1.1  christos   char *strings;
   3970       1.1  christos   struct aout_link_hash_entry **sym_hashes;
   3971       1.1  christos   int *symbol_map;
   3972       1.1  christos   bfd_size_type reloc_count;
   3973       1.1  christos   struct reloc_std_external *rel;
   3974   1.1.1.5  christos   struct reloc_std_external *rel_end;
   3975       1.1  christos 
   3976       1.1  christos   output_bfd = flaginfo->output_bfd;
   3977       1.1  christos   check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
   3978   1.1.1.2  christos 
   3979       1.1  christos   BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
   3980       1.1  christos   BFD_ASSERT (input_bfd->xvec->header_byteorder
   3981       1.1  christos 	      == output_bfd->xvec->header_byteorder);
   3982       1.1  christos 
   3983       1.1  christos   relocatable = bfd_link_relocatable (flaginfo->info);
   3984       1.1  christos   syms = obj_aout_external_syms (input_bfd);
   3985       1.1  christos   strings = obj_aout_external_strings (input_bfd);
   3986   1.1.1.9  christos   sym_hashes = obj_aout_sym_hashes (input_bfd);
   3987       1.1  christos   symbol_map = flaginfo->symbol_map;
   3988       1.1  christos 
   3989       1.1  christos   reloc_count = rel_size / RELOC_STD_SIZE;
   3990       1.1  christos   rel = relocs;
   3991       1.1  christos   rel_end = rel + reloc_count;
   3992       1.1  christos   for (; rel < rel_end; rel++)
   3993       1.1  christos     {
   3994       1.1  christos       bfd_vma r_addr;
   3995       1.1  christos       unsigned int r_index;
   3996       1.1  christos       int r_extern;
   3997       1.1  christos       int r_pcrel;
   3998       1.1  christos       int r_baserel = 0;
   3999       1.1  christos       reloc_howto_type *howto;
   4000       1.1  christos       struct aout_link_hash_entry *h = NULL;
   4001       1.1  christos       bfd_vma relocation;
   4002       1.1  christos       bfd_reloc_status_type r;
   4003       1.1  christos 
   4004       1.1  christos       r_addr = GET_SWORD (input_bfd, rel->r_address);
   4005       1.1  christos 
   4006       1.1  christos #ifdef MY_reloc_howto
   4007       1.1  christos       howto = MY_reloc_howto (input_bfd, rel, r_index, r_extern, r_pcrel);
   4008       1.1  christos #else
   4009       1.1  christos       {
   4010       1.1  christos 	int r_jmptable;
   4011       1.1  christos 	int r_relative;
   4012       1.1  christos 	int r_length;
   4013       1.1  christos 	unsigned int howto_idx;
   4014       1.1  christos 
   4015       1.1  christos 	if (bfd_header_big_endian (input_bfd))
   4016       1.1  christos 	  {
   4017       1.1  christos 	    r_index   =  (((unsigned int) rel->r_index[0] << 16)
   4018       1.1  christos 			  | ((unsigned int) rel->r_index[1] << 8)
   4019       1.1  christos 			  | rel->r_index[2]);
   4020       1.1  christos 	    r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
   4021       1.1  christos 	    r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
   4022       1.1  christos 	    r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
   4023       1.1  christos 	    r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
   4024       1.1  christos 	    r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
   4025       1.1  christos 	    r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
   4026       1.1  christos 			 >> RELOC_STD_BITS_LENGTH_SH_BIG);
   4027       1.1  christos 	  }
   4028       1.1  christos 	else
   4029       1.1  christos 	  {
   4030       1.1  christos 	    r_index   = (((unsigned int) rel->r_index[2] << 16)
   4031       1.1  christos 			 | ((unsigned int) rel->r_index[1] << 8)
   4032       1.1  christos 			 | rel->r_index[0]);
   4033       1.1  christos 	    r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
   4034       1.1  christos 	    r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
   4035       1.1  christos 	    r_baserel = (0 != (rel->r_type[0]
   4036       1.1  christos 			       & RELOC_STD_BITS_BASEREL_LITTLE));
   4037       1.1  christos 	    r_jmptable= (0 != (rel->r_type[0]
   4038       1.1  christos 			       & RELOC_STD_BITS_JMPTABLE_LITTLE));
   4039       1.1  christos 	    r_relative= (0 != (rel->r_type[0]
   4040       1.1  christos 			       & RELOC_STD_BITS_RELATIVE_LITTLE));
   4041       1.1  christos 	    r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
   4042       1.1  christos 			 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
   4043       1.1  christos 	  }
   4044       1.1  christos 
   4045       1.1  christos 	howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
   4046       1.1  christos 		     + 16 * r_jmptable + 32 * r_relative);
   4047   1.1.1.7  christos 	if (howto_idx < TABLE_SIZE (howto_table_std))
   4048   1.1.1.7  christos 	  howto = howto_table_std + howto_idx;
   4049       1.1  christos 	else
   4050   1.1.1.9  christos 	  howto = NULL;
   4051       1.1  christos       }
   4052       1.1  christos #endif
   4053       1.1  christos 
   4054       1.1  christos       if (howto == NULL)
   4055       1.1  christos 	{
   4056       1.1  christos 	  _bfd_error_handler (_("%pB: unsupported relocation type"),
   4057       1.1  christos 			      input_bfd);
   4058       1.1  christos 	  bfd_set_error (bfd_error_bad_value);
   4059       1.1  christos 	  return false;
   4060       1.1  christos 	}
   4061       1.1  christos 
   4062       1.1  christos       if (relocatable)
   4063       1.1  christos 	{
   4064       1.1  christos 	  /* We are generating a relocatable output file, and must
   4065       1.1  christos 	     modify the reloc accordingly.  */
   4066       1.1  christos 	  if (r_extern)
   4067       1.1  christos 	    {
   4068       1.1  christos 	      /* If we know the symbol this relocation is against,
   4069       1.1  christos 		 convert it into a relocation against a section.  This
   4070       1.1  christos 		 is what the native linker does.  */
   4071       1.1  christos 	      h = sym_hashes[r_index];
   4072       1.1  christos 	      if (h != NULL
   4073       1.1  christos 		  && (h->root.type == bfd_link_hash_defined
   4074       1.1  christos 		      || h->root.type == bfd_link_hash_defweak))
   4075       1.1  christos 		{
   4076       1.1  christos 		  asection *output_section;
   4077       1.1  christos 
   4078       1.1  christos 		  /* Change the r_extern value.  */
   4079       1.1  christos 		  if (bfd_header_big_endian (output_bfd))
   4080       1.1  christos 		    rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
   4081       1.1  christos 		  else
   4082       1.1  christos 		    rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
   4083       1.1  christos 
   4084       1.1  christos 		  /* Compute a new r_index.  */
   4085       1.1  christos 		  output_section = h->root.u.def.section->output_section;
   4086       1.1  christos 		  if (output_section == obj_textsec (output_bfd))
   4087       1.1  christos 		    r_index = N_TEXT;
   4088       1.1  christos 		  else if (output_section == obj_datasec (output_bfd))
   4089       1.1  christos 		    r_index = N_DATA;
   4090       1.1  christos 		  else if (output_section == obj_bsssec (output_bfd))
   4091       1.1  christos 		    r_index = N_BSS;
   4092       1.1  christos 		  else
   4093       1.1  christos 		    r_index = N_ABS;
   4094       1.1  christos 
   4095       1.1  christos 		  /* Add the symbol value and the section VMA to the
   4096       1.1  christos 		     addend stored in the contents.  */
   4097       1.1  christos 		  relocation = (h->root.u.def.value
   4098   1.1.1.9  christos 				+ output_section->vma
   4099       1.1  christos 				+ h->root.u.def.section->output_offset);
   4100       1.1  christos 		}
   4101       1.1  christos 	      else
   4102       1.1  christos 		{
   4103   1.1.1.7  christos 		  /* We must change r_index according to the symbol
   4104   1.1.1.7  christos 		     map.  */
   4105   1.1.1.7  christos 		  r_index = symbol_map[r_index];
   4106   1.1.1.7  christos 
   4107       1.1  christos 		  if (r_index == -1u)
   4108       1.1  christos 		    {
   4109       1.1  christos 		      if (h != NULL)
   4110   1.1.1.9  christos 			{
   4111   1.1.1.2  christos 			  /* We decided to strip this symbol, but it
   4112   1.1.1.2  christos 			     turns out that we can't.  Note that we
   4113   1.1.1.9  christos 			     lose the other and desc information here.
   4114       1.1  christos 			     I don't think that will ever matter for a
   4115       1.1  christos 			     global symbol.  */
   4116       1.1  christos 			  if (h->indx < 0)
   4117       1.1  christos 			    {
   4118       1.1  christos 			      h->indx = -2;
   4119       1.1  christos 			      h->written = false;
   4120       1.1  christos 			      if (!aout_link_write_other_symbol (&h->root.root,
   4121       1.1  christos 								 flaginfo))
   4122       1.1  christos 				return false;
   4123   1.1.1.5  christos 			    }
   4124   1.1.1.5  christos 			  r_index = h->indx;
   4125   1.1.1.5  christos 			}
   4126       1.1  christos 		      else
   4127       1.1  christos 			{
   4128       1.1  christos 			  const char *name;
   4129       1.1  christos 
   4130       1.1  christos 			  name = strings + GET_WORD (input_bfd,
   4131       1.1  christos 						     syms[r_index].e_strx);
   4132       1.1  christos 			  (*flaginfo->info->callbacks->unattached_reloc)
   4133       1.1  christos 			    (flaginfo->info, name,
   4134       1.1  christos 			     input_bfd, input_section, r_addr);
   4135       1.1  christos 			  r_index = 0;
   4136       1.1  christos 			}
   4137       1.1  christos 		    }
   4138       1.1  christos 
   4139       1.1  christos 		  relocation = 0;
   4140       1.1  christos 		}
   4141       1.1  christos 
   4142       1.1  christos 	      /* Write out the new r_index value.  */
   4143       1.1  christos 	      if (bfd_header_big_endian (output_bfd))
   4144       1.1  christos 		{
   4145       1.1  christos 		  rel->r_index[0] = r_index >> 16;
   4146       1.1  christos 		  rel->r_index[1] = r_index >> 8;
   4147       1.1  christos 		  rel->r_index[2] = r_index;
   4148       1.1  christos 		}
   4149       1.1  christos 	      else
   4150       1.1  christos 		{
   4151       1.1  christos 		  rel->r_index[2] = r_index >> 16;
   4152       1.1  christos 		  rel->r_index[1] = r_index >> 8;
   4153       1.1  christos 		  rel->r_index[0] = r_index;
   4154       1.1  christos 		}
   4155       1.1  christos 	    }
   4156       1.1  christos 	  else
   4157       1.1  christos 	    {
   4158       1.1  christos 	      asection *section;
   4159       1.1  christos 
   4160       1.1  christos 	      /* This is a relocation against a section.  We must
   4161       1.1  christos 		 adjust by the amount that the section moved.  */
   4162       1.1  christos 	      section = aout_reloc_index_to_section (input_bfd, r_index);
   4163       1.1  christos 	      relocation = (section->output_section->vma
   4164       1.1  christos 			    + section->output_offset
   4165       1.1  christos 			    - section->vma);
   4166       1.1  christos 	    }
   4167       1.1  christos 
   4168       1.1  christos 	  /* Change the address of the relocation.  */
   4169       1.1  christos 	  PUT_WORD (output_bfd,
   4170       1.1  christos 		    r_addr + input_section->output_offset,
   4171       1.1  christos 		    rel->r_address);
   4172       1.1  christos 
   4173       1.1  christos 	  /* Adjust a PC relative relocation by removing the reference
   4174       1.1  christos 	     to the original address in the section and including the
   4175       1.1  christos 	     reference to the new address.  */
   4176       1.1  christos 	  if (r_pcrel)
   4177       1.1  christos 	    relocation -= (input_section->output_section->vma
   4178       1.1  christos 			   + input_section->output_offset
   4179       1.1  christos 			   - input_section->vma);
   4180       1.1  christos 
   4181       1.1  christos #ifdef MY_relocatable_reloc
   4182       1.1  christos 	  MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
   4183       1.1  christos #endif
   4184       1.1  christos 
   4185   1.1.1.9  christos 	  if (relocation == 0)
   4186       1.1  christos 	    r = bfd_reloc_ok;
   4187       1.1  christos 	  else
   4188       1.1  christos 	    r = MY_relocate_contents (howto,
   4189   1.1.1.9  christos 					input_bfd, relocation,
   4190       1.1  christos 					contents + r_addr);
   4191       1.1  christos 	}
   4192       1.1  christos       else
   4193       1.1  christos 	{
   4194       1.1  christos 	  bool hundef;
   4195       1.1  christos 
   4196       1.1  christos 	  /* We are generating an executable, and must do a full
   4197       1.1  christos 	     relocation.  */
   4198       1.1  christos 	  hundef = false;
   4199       1.1  christos 
   4200       1.1  christos 	  if (r_extern)
   4201       1.1  christos 	    {
   4202       1.1  christos 	      h = sym_hashes[r_index];
   4203       1.1  christos 
   4204       1.1  christos 	      if (h != NULL
   4205       1.1  christos 		  && (h->root.type == bfd_link_hash_defined
   4206       1.1  christos 		      || h->root.type == bfd_link_hash_defweak))
   4207       1.1  christos 		{
   4208   1.1.1.9  christos 		  relocation = (h->root.u.def.value
   4209       1.1  christos 				+ h->root.u.def.section->output_section->vma
   4210       1.1  christos 				+ h->root.u.def.section->output_offset);
   4211       1.1  christos 		}
   4212       1.1  christos 	      else if (h != NULL
   4213       1.1  christos 		       && h->root.type == bfd_link_hash_undefweak)
   4214       1.1  christos 		relocation = 0;
   4215       1.1  christos 	      else
   4216       1.1  christos 		{
   4217       1.1  christos 		  hundef = true;
   4218       1.1  christos 		  relocation = 0;
   4219       1.1  christos 		}
   4220       1.1  christos 	    }
   4221       1.1  christos 	  else
   4222       1.1  christos 	    {
   4223       1.1  christos 	      asection *section;
   4224       1.1  christos 
   4225       1.1  christos 	      section = aout_reloc_index_to_section (input_bfd, r_index);
   4226   1.1.1.9  christos 	      relocation = (section->output_section->vma
   4227       1.1  christos 			    + section->output_offset
   4228       1.1  christos 			    - section->vma);
   4229   1.1.1.2  christos 	      if (r_pcrel)
   4230       1.1  christos 		relocation += input_section->vma;
   4231   1.1.1.9  christos 	    }
   4232       1.1  christos 
   4233       1.1  christos 	  if (check_dynamic_reloc != NULL)
   4234       1.1  christos 	    {
   4235       1.1  christos 	      bool skip;
   4236       1.1  christos 
   4237   1.1.1.7  christos 	      if (! ((*check_dynamic_reloc)
   4238   1.1.1.7  christos 		     (flaginfo->info, input_bfd, input_section, h,
   4239   1.1.1.5  christos 		      (void *) rel, contents, &skip, &relocation)))
   4240       1.1  christos 		return false;
   4241       1.1  christos 	      if (skip)
   4242       1.1  christos 		continue;
   4243       1.1  christos 	    }
   4244       1.1  christos 
   4245       1.1  christos 	  /* Now warn if a global symbol is undefined.  We could not
   4246       1.1  christos 	     do this earlier, because check_dynamic_reloc might want
   4247   1.1.1.5  christos 	     to skip this reloc.  */
   4248   1.1.1.9  christos 	  if (hundef && ! bfd_link_pic (flaginfo->info) && ! r_baserel)
   4249       1.1  christos 	    {
   4250       1.1  christos 	      const char *name;
   4251       1.1  christos 
   4252       1.1  christos 	      if (h != NULL)
   4253       1.1  christos 		name = h->root.root.string;
   4254       1.1  christos 	      else
   4255       1.1  christos 		name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
   4256       1.1  christos 	      (*flaginfo->info->callbacks->undefined_symbol)
   4257       1.1  christos 		(flaginfo->info, name, input_bfd, input_section, r_addr, true);
   4258       1.1  christos 	    }
   4259       1.1  christos 
   4260       1.1  christos 	  r = MY_final_link_relocate (howto,
   4261       1.1  christos 				      input_bfd, input_section,
   4262       1.1  christos 				      contents, r_addr, relocation,
   4263       1.1  christos 				      (bfd_vma) 0);
   4264       1.1  christos 	}
   4265       1.1  christos 
   4266       1.1  christos       if (r != bfd_reloc_ok)
   4267       1.1  christos 	{
   4268       1.1  christos 	  switch (r)
   4269       1.1  christos 	    {
   4270       1.1  christos 	    default:
   4271       1.1  christos 	    case bfd_reloc_outofrange:
   4272       1.1  christos 	      abort ();
   4273       1.1  christos 	    case bfd_reloc_overflow:
   4274       1.1  christos 	      {
   4275       1.1  christos 		const char *name;
   4276       1.1  christos 
   4277       1.1  christos 		if (h != NULL)
   4278   1.1.1.8  christos 		  name = NULL;
   4279       1.1  christos 		else if (r_extern)
   4280   1.1.1.5  christos 		  name = strings + GET_WORD (input_bfd,
   4281   1.1.1.5  christos 					     syms[r_index].e_strx);
   4282   1.1.1.5  christos 		else
   4283       1.1  christos 		  {
   4284       1.1  christos 		    asection *s;
   4285       1.1  christos 
   4286       1.1  christos 		    s = aout_reloc_index_to_section (input_bfd, r_index);
   4287       1.1  christos 		    name = bfd_section_name (s);
   4288       1.1  christos 		  }
   4289   1.1.1.9  christos 		(*flaginfo->info->callbacks->reloc_overflow)
   4290       1.1  christos 		  (flaginfo->info, (h ? &h->root : NULL), name, howto->name,
   4291       1.1  christos 		   (bfd_vma) 0, input_bfd, input_section, r_addr);
   4292       1.1  christos 	      }
   4293       1.1  christos 	      break;
   4294   1.1.1.9  christos 	    }
   4295   1.1.1.2  christos 	}
   4296       1.1  christos     }
   4297       1.1  christos 
   4298       1.1  christos   return true;
   4299       1.1  christos }
   4300       1.1  christos 
   4301       1.1  christos /* Relocate an a.out section using extended a.out relocs.  */
   4302   1.1.1.9  christos 
   4303       1.1  christos static bool
   4304   1.1.1.9  christos aout_link_input_section_ext (struct aout_final_link_info *flaginfo,
   4305       1.1  christos 			     bfd *input_bfd,
   4306   1.1.1.9  christos 			     asection *input_section,
   4307       1.1  christos 			     struct reloc_ext_external *relocs,
   4308       1.1  christos 			     bfd_size_type rel_size,
   4309       1.1  christos 			     bfd_byte *contents)
   4310       1.1  christos {
   4311       1.1  christos   bool (*check_dynamic_reloc)
   4312       1.1  christos     (struct bfd_link_info *, bfd *, asection *,
   4313       1.1  christos      struct aout_link_hash_entry *, void *, bfd_byte *, bool *, bfd_vma *);
   4314       1.1  christos   bfd *output_bfd;
   4315   1.1.1.2  christos   bool relocatable;
   4316       1.1  christos   struct external_nlist *syms;
   4317       1.1  christos   char *strings;
   4318       1.1  christos   struct aout_link_hash_entry **sym_hashes;
   4319       1.1  christos   int *symbol_map;
   4320       1.1  christos   bfd_size_type reloc_count;
   4321       1.1  christos   struct reloc_ext_external *rel;
   4322   1.1.1.5  christos   struct reloc_ext_external *rel_end;
   4323       1.1  christos 
   4324       1.1  christos   output_bfd = flaginfo->output_bfd;
   4325       1.1  christos   check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
   4326   1.1.1.2  christos 
   4327       1.1  christos   BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
   4328       1.1  christos   BFD_ASSERT (input_bfd->xvec->header_byteorder
   4329       1.1  christos 	      == output_bfd->xvec->header_byteorder);
   4330       1.1  christos 
   4331       1.1  christos   relocatable = bfd_link_relocatable (flaginfo->info);
   4332       1.1  christos   syms = obj_aout_external_syms (input_bfd);
   4333       1.1  christos   strings = obj_aout_external_strings (input_bfd);
   4334   1.1.1.9  christos   sym_hashes = obj_aout_sym_hashes (input_bfd);
   4335       1.1  christos   symbol_map = flaginfo->symbol_map;
   4336       1.1  christos 
   4337       1.1  christos   reloc_count = rel_size / RELOC_EXT_SIZE;
   4338       1.1  christos   rel = relocs;
   4339       1.1  christos   rel_end = rel + reloc_count;
   4340       1.1  christos   for (; rel < rel_end; rel++)
   4341       1.1  christos     {
   4342       1.1  christos       bfd_vma r_addr;
   4343       1.1  christos       unsigned int r_index;
   4344       1.1  christos       int r_extern;
   4345       1.1  christos       unsigned int r_type;
   4346       1.1  christos       bfd_vma r_addend;
   4347       1.1  christos       struct aout_link_hash_entry *h = NULL;
   4348       1.1  christos       asection *r_section = NULL;
   4349       1.1  christos       bfd_vma relocation;
   4350       1.1  christos 
   4351       1.1  christos       r_addr = GET_SWORD (input_bfd, rel->r_address);
   4352       1.1  christos 
   4353       1.1  christos       if (bfd_header_big_endian (input_bfd))
   4354       1.1  christos 	{
   4355       1.1  christos 	  r_index  = (((unsigned int) rel->r_index[0] << 16)
   4356       1.1  christos 		      | ((unsigned int) rel->r_index[1] << 8)
   4357       1.1  christos 		      | rel->r_index[2]);
   4358       1.1  christos 	  r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
   4359       1.1  christos 	  r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
   4360       1.1  christos 		      >> RELOC_EXT_BITS_TYPE_SH_BIG);
   4361       1.1  christos 	}
   4362       1.1  christos       else
   4363       1.1  christos 	{
   4364       1.1  christos 	  r_index  = (((unsigned int) rel->r_index[2] << 16)
   4365       1.1  christos 		      | ((unsigned int) rel->r_index[1] << 8)
   4366       1.1  christos 		      | rel->r_index[0]);
   4367   1.1.1.7  christos 	  r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
   4368   1.1.1.7  christos 	  r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
   4369       1.1  christos 		      >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
   4370   1.1.1.9  christos 	}
   4371       1.1  christos 
   4372       1.1  christos       r_addend = GET_SWORD (input_bfd, rel->r_addend);
   4373       1.1  christos 
   4374       1.1  christos       if (r_type >= TABLE_SIZE (howto_table_ext))
   4375       1.1  christos 	{
   4376       1.1  christos 	  _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
   4377       1.1  christos 			      input_bfd, r_type);
   4378       1.1  christos 	  bfd_set_error (bfd_error_bad_value);
   4379       1.1  christos 	  return false;
   4380       1.1  christos 	}
   4381       1.1  christos 
   4382       1.1  christos       if (relocatable)
   4383       1.1  christos 	{
   4384       1.1  christos 	  /* We are generating a relocatable output file, and must
   4385       1.1  christos 	     modify the reloc accordingly.  */
   4386       1.1  christos 	  if (r_extern
   4387       1.1  christos 	      || r_type == (unsigned int) RELOC_BASE10
   4388       1.1  christos 	      || r_type == (unsigned int) RELOC_BASE13
   4389       1.1  christos 	      || r_type == (unsigned int) RELOC_BASE22)
   4390       1.1  christos 	    {
   4391       1.1  christos 	      /* If we know the symbol this relocation is against,
   4392       1.1  christos 		 convert it into a relocation against a section.  This
   4393       1.1  christos 		 is what the native linker does.  */
   4394       1.1  christos 	      if (r_type == (unsigned int) RELOC_BASE10
   4395       1.1  christos 		  || r_type == (unsigned int) RELOC_BASE13
   4396       1.1  christos 		  || r_type == (unsigned int) RELOC_BASE22)
   4397       1.1  christos 		h = NULL;
   4398       1.1  christos 	      else
   4399       1.1  christos 		h = sym_hashes[r_index];
   4400       1.1  christos 	      if (h != NULL
   4401       1.1  christos 		  && (h->root.type == bfd_link_hash_defined
   4402       1.1  christos 		      || h->root.type == bfd_link_hash_defweak))
   4403       1.1  christos 		{
   4404       1.1  christos 		  asection *output_section;
   4405       1.1  christos 
   4406       1.1  christos 		  /* Change the r_extern value.  */
   4407       1.1  christos 		  if (bfd_header_big_endian (output_bfd))
   4408       1.1  christos 		    rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
   4409       1.1  christos 		  else
   4410       1.1  christos 		    rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
   4411       1.1  christos 
   4412       1.1  christos 		  /* Compute a new r_index.  */
   4413       1.1  christos 		  output_section = h->root.u.def.section->output_section;
   4414       1.1  christos 		  if (output_section == obj_textsec (output_bfd))
   4415       1.1  christos 		    r_index = N_TEXT;
   4416       1.1  christos 		  else if (output_section == obj_datasec (output_bfd))
   4417       1.1  christos 		    r_index = N_DATA;
   4418       1.1  christos 		  else if (output_section == obj_bsssec (output_bfd))
   4419       1.1  christos 		    r_index = N_BSS;
   4420       1.1  christos 		  else
   4421       1.1  christos 		    r_index = N_ABS;
   4422       1.1  christos 
   4423       1.1  christos 		  /* Add the symbol value and the section VMA to the
   4424       1.1  christos 		     addend.  */
   4425       1.1  christos 		  relocation = (h->root.u.def.value
   4426       1.1  christos 				+ output_section->vma
   4427       1.1  christos 				+ h->root.u.def.section->output_offset);
   4428       1.1  christos 
   4429       1.1  christos 		  /* Now RELOCATION is the VMA of the final
   4430       1.1  christos 		     destination.  If this is a PC relative reloc,
   4431       1.1  christos 		     then ADDEND is the negative of the source VMA.
   4432       1.1  christos 		     We want to set ADDEND to the difference between
   4433       1.1  christos 		     the destination VMA and the source VMA, which
   4434   1.1.1.9  christos 		     means we must adjust RELOCATION by the change in
   4435       1.1  christos 		     the source VMA.  This is done below.  */
   4436       1.1  christos 		}
   4437       1.1  christos 	      else
   4438       1.1  christos 		{
   4439   1.1.1.7  christos 		  /* We must change r_index according to the symbol
   4440   1.1.1.7  christos 		     map.  */
   4441   1.1.1.7  christos 		  r_index = symbol_map[r_index];
   4442   1.1.1.7  christos 
   4443       1.1  christos 		  if (r_index == -1u)
   4444       1.1  christos 		    {
   4445       1.1  christos 		      if (h != NULL)
   4446   1.1.1.9  christos 			{
   4447   1.1.1.2  christos 			  /* We decided to strip this symbol, but it
   4448   1.1.1.2  christos 			     turns out that we can't.  Note that we
   4449   1.1.1.9  christos 			     lose the other and desc information here.
   4450       1.1  christos 			     I don't think that will ever matter for a
   4451       1.1  christos 			     global symbol.  */
   4452       1.1  christos 			  if (h->indx < 0)
   4453       1.1  christos 			    {
   4454       1.1  christos 			      h->indx = -2;
   4455       1.1  christos 			      h->written = false;
   4456       1.1  christos 			      if (!aout_link_write_other_symbol (&h->root.root,
   4457       1.1  christos 								 flaginfo))
   4458       1.1  christos 				return false;
   4459   1.1.1.5  christos 			    }
   4460   1.1.1.5  christos 			  r_index = h->indx;
   4461   1.1.1.5  christos 			}
   4462       1.1  christos 		      else
   4463       1.1  christos 			{
   4464       1.1  christos 			  const char *name;
   4465       1.1  christos 
   4466       1.1  christos 			  name = strings + GET_WORD (input_bfd,
   4467       1.1  christos 						     syms[r_index].e_strx);
   4468       1.1  christos 			  (*flaginfo->info->callbacks->unattached_reloc)
   4469       1.1  christos 			    (flaginfo->info, name,
   4470       1.1  christos 			     input_bfd, input_section, r_addr);
   4471       1.1  christos 			  r_index = 0;
   4472       1.1  christos 			}
   4473       1.1  christos 		    }
   4474       1.1  christos 
   4475       1.1  christos 		  relocation = 0;
   4476       1.1  christos 
   4477       1.1  christos 		  /* If this is a PC relative reloc, then the addend
   4478       1.1  christos 		     is the negative of the source VMA.  We must
   4479       1.1  christos 		     adjust it by the change in the source VMA.  This
   4480       1.1  christos 		     is done below.  */
   4481       1.1  christos 		}
   4482       1.1  christos 
   4483       1.1  christos 	      /* Write out the new r_index value.  */
   4484       1.1  christos 	      if (bfd_header_big_endian (output_bfd))
   4485       1.1  christos 		{
   4486       1.1  christos 		  rel->r_index[0] = r_index >> 16;
   4487       1.1  christos 		  rel->r_index[1] = r_index >> 8;
   4488       1.1  christos 		  rel->r_index[2] = r_index;
   4489       1.1  christos 		}
   4490       1.1  christos 	      else
   4491       1.1  christos 		{
   4492       1.1  christos 		  rel->r_index[2] = r_index >> 16;
   4493       1.1  christos 		  rel->r_index[1] = r_index >> 8;
   4494       1.1  christos 		  rel->r_index[0] = r_index;
   4495       1.1  christos 		}
   4496       1.1  christos 	    }
   4497       1.1  christos 	  else
   4498       1.1  christos 	    {
   4499       1.1  christos 	      /* This is a relocation against a section.  We must
   4500       1.1  christos 		 adjust by the amount that the section moved.  */
   4501       1.1  christos 	      r_section = aout_reloc_index_to_section (input_bfd, r_index);
   4502       1.1  christos 	      relocation = (r_section->output_section->vma
   4503       1.1  christos 			    + r_section->output_offset
   4504       1.1  christos 			    - r_section->vma);
   4505       1.1  christos 
   4506       1.1  christos 	      /* If this is a PC relative reloc, then the addend is
   4507       1.1  christos 		 the difference in VMA between the destination and the
   4508       1.1  christos 		 source.  We have just adjusted for the change in VMA
   4509       1.1  christos 		 of the destination, so we must also adjust by the
   4510       1.1  christos 		 change in VMA of the source.  This is done below.  */
   4511       1.1  christos 	    }
   4512       1.1  christos 
   4513       1.1  christos 	  /* As described above, we must always adjust a PC relative
   4514       1.1  christos 	     reloc by the change in VMA of the source.  However, if
   4515       1.1  christos 	     pcrel_offset is set, then the addend does not include the
   4516       1.1  christos 	     location within the section, in which case we don't need
   4517       1.1  christos 	     to adjust anything.  */
   4518       1.1  christos 	  if (howto_table_ext[r_type].pc_relative
   4519       1.1  christos 	      && ! howto_table_ext[r_type].pcrel_offset)
   4520       1.1  christos 	    relocation -= (input_section->output_section->vma
   4521       1.1  christos 			   + input_section->output_offset
   4522       1.1  christos 			   - input_section->vma);
   4523       1.1  christos 
   4524       1.1  christos 	  /* Change the addend if necessary.  */
   4525       1.1  christos 	  if (relocation != 0)
   4526   1.1.1.9  christos 	    PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
   4527       1.1  christos 
   4528       1.1  christos 	  /* Change the address of the relocation.  */
   4529       1.1  christos 	  PUT_WORD (output_bfd,
   4530       1.1  christos 		    r_addr + input_section->output_offset,
   4531   1.1.1.9  christos 		    rel->r_address);
   4532       1.1  christos 	}
   4533       1.1  christos       else
   4534       1.1  christos 	{
   4535       1.1  christos 	  bool hundef;
   4536       1.1  christos 	  bfd_reloc_status_type r;
   4537       1.1  christos 
   4538       1.1  christos 	  /* We are generating an executable, and must do a full
   4539       1.1  christos 	     relocation.  */
   4540       1.1  christos 	  hundef = false;
   4541       1.1  christos 
   4542       1.1  christos 	  if (r_extern)
   4543       1.1  christos 	    {
   4544       1.1  christos 	      h = sym_hashes[r_index];
   4545       1.1  christos 
   4546       1.1  christos 	      if (h != NULL
   4547       1.1  christos 		  && (h->root.type == bfd_link_hash_defined
   4548       1.1  christos 		      || h->root.type == bfd_link_hash_defweak))
   4549       1.1  christos 		{
   4550   1.1.1.9  christos 		  relocation = (h->root.u.def.value
   4551       1.1  christos 				+ h->root.u.def.section->output_section->vma
   4552       1.1  christos 				+ h->root.u.def.section->output_offset);
   4553       1.1  christos 		}
   4554       1.1  christos 	      else if (h != NULL
   4555       1.1  christos 		       && h->root.type == bfd_link_hash_undefweak)
   4556       1.1  christos 		relocation = 0;
   4557       1.1  christos 	      else
   4558       1.1  christos 		{
   4559       1.1  christos 		  hundef = true;
   4560       1.1  christos 		  relocation = 0;
   4561       1.1  christos 		}
   4562   1.1.1.7  christos 	    }
   4563       1.1  christos 	  else if (r_type == (unsigned int) RELOC_BASE10
   4564       1.1  christos 		   || r_type == (unsigned int) RELOC_BASE13
   4565       1.1  christos 		   || r_type == (unsigned int) RELOC_BASE22)
   4566       1.1  christos 	    {
   4567       1.1  christos 	      struct external_nlist *sym;
   4568       1.1  christos 	      int type;
   4569       1.1  christos 
   4570       1.1  christos 	      /* For base relative relocs, r_index is always an index
   4571       1.1  christos 		 into the symbol table, even if r_extern is 0.  */
   4572       1.1  christos 	      sym = syms + r_index;
   4573       1.1  christos 	      type = H_GET_8 (input_bfd, sym->e_type);
   4574       1.1  christos 	      if ((type & N_TYPE) == N_TEXT
   4575       1.1  christos 		  || type == N_WEAKT)
   4576       1.1  christos 		r_section = obj_textsec (input_bfd);
   4577       1.1  christos 	      else if ((type & N_TYPE) == N_DATA
   4578       1.1  christos 		       || type == N_WEAKD)
   4579       1.1  christos 		r_section = obj_datasec (input_bfd);
   4580       1.1  christos 	      else if ((type & N_TYPE) == N_BSS
   4581       1.1  christos 		       || type == N_WEAKB)
   4582       1.1  christos 		r_section = obj_bsssec (input_bfd);
   4583       1.1  christos 	      else if ((type & N_TYPE) == N_ABS
   4584       1.1  christos 		       || type == N_WEAKA)
   4585       1.1  christos 		r_section = bfd_abs_section_ptr;
   4586       1.1  christos 	      else
   4587       1.1  christos 		abort ();
   4588       1.1  christos 	      relocation = (r_section->output_section->vma
   4589       1.1  christos 			    + r_section->output_offset
   4590       1.1  christos 			    + (GET_WORD (input_bfd, sym->e_value)
   4591       1.1  christos 			       - r_section->vma));
   4592       1.1  christos 	    }
   4593       1.1  christos 	  else
   4594       1.1  christos 	    {
   4595       1.1  christos 	      r_section = aout_reloc_index_to_section (input_bfd, r_index);
   4596       1.1  christos 
   4597       1.1  christos 	      /* If this is a PC relative reloc, then R_ADDEND is the
   4598       1.1  christos 		 difference between the two vmas, or
   4599       1.1  christos 		   old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
   4600       1.1  christos 		 where
   4601       1.1  christos 		   old_dest_sec == section->vma
   4602       1.1  christos 		 and
   4603       1.1  christos 		   old_src_sec == input_section->vma
   4604       1.1  christos 		 and
   4605       1.1  christos 		   old_src_off == r_addr
   4606       1.1  christos 
   4607       1.1  christos 		 _bfd_final_link_relocate expects RELOCATION +
   4608       1.1  christos 		 R_ADDEND to be the VMA of the destination minus
   4609       1.1  christos 		 r_addr (the minus r_addr is because this relocation
   4610       1.1  christos 		 is not pcrel_offset, which is a bit confusing and
   4611       1.1  christos 		 should, perhaps, be changed), or
   4612       1.1  christos 		   new_dest_sec
   4613       1.1  christos 		 where
   4614       1.1  christos 		   new_dest_sec == output_section->vma + output_offset
   4615       1.1  christos 		 We arrange for this to happen by setting RELOCATION to
   4616       1.1  christos 		   new_dest_sec + old_src_sec - old_dest_sec
   4617       1.1  christos 
   4618       1.1  christos 		 If this is not a PC relative reloc, then R_ADDEND is
   4619       1.1  christos 		 simply the VMA of the destination, so we set
   4620       1.1  christos 		 RELOCATION to the change in the destination VMA, or
   4621       1.1  christos 		   new_dest_sec - old_dest_sec
   4622       1.1  christos 		 */
   4623   1.1.1.9  christos 	      relocation = (r_section->output_section->vma
   4624       1.1  christos 			    + r_section->output_offset
   4625       1.1  christos 			    - r_section->vma);
   4626   1.1.1.2  christos 	      if (howto_table_ext[r_type].pc_relative)
   4627       1.1  christos 		relocation += input_section->vma;
   4628   1.1.1.9  christos 	    }
   4629       1.1  christos 
   4630       1.1  christos 	  if (check_dynamic_reloc != NULL)
   4631       1.1  christos 	    {
   4632       1.1  christos 	      bool skip;
   4633       1.1  christos 
   4634   1.1.1.7  christos 	      if (! ((*check_dynamic_reloc)
   4635   1.1.1.7  christos 		     (flaginfo->info, input_bfd, input_section, h,
   4636       1.1  christos 		      (void *) rel, contents, &skip, &relocation)))
   4637   1.1.1.5  christos 		return false;
   4638       1.1  christos 	      if (skip)
   4639       1.1  christos 		continue;
   4640       1.1  christos 	    }
   4641       1.1  christos 
   4642       1.1  christos 	  /* Now warn if a global symbol is undefined.  We could not
   4643       1.1  christos 	     do this earlier, because check_dynamic_reloc might want
   4644       1.1  christos 	     to skip this reloc.  */
   4645       1.1  christos 	  if (hundef
   4646       1.1  christos 	      && ! bfd_link_pic (flaginfo->info)
   4647       1.1  christos 	      && r_type != (unsigned int) RELOC_BASE10
   4648   1.1.1.5  christos 	      && r_type != (unsigned int) RELOC_BASE13
   4649   1.1.1.9  christos 	      && r_type != (unsigned int) RELOC_BASE22)
   4650       1.1  christos 	    {
   4651       1.1  christos 	      const char *name;
   4652       1.1  christos 
   4653       1.1  christos 	      if (h != NULL)
   4654       1.1  christos 		name = h->root.root.string;
   4655       1.1  christos 	      else
   4656       1.1  christos 		name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
   4657       1.1  christos 	      (*flaginfo->info->callbacks->undefined_symbol)
   4658       1.1  christos 		(flaginfo->info, name, input_bfd, input_section, r_addr, true);
   4659       1.1  christos 	    }
   4660       1.1  christos 
   4661       1.1  christos 	  if (r_type != (unsigned int) RELOC_SPARC_REV32)
   4662       1.1  christos 	    r = MY_final_link_relocate (howto_table_ext + r_type,
   4663       1.1  christos 					input_bfd, input_section,
   4664       1.1  christos 					contents, r_addr, relocation,
   4665       1.1  christos 					r_addend);
   4666       1.1  christos 	  else
   4667       1.1  christos 	    {
   4668       1.1  christos 	      bfd_vma x;
   4669       1.1  christos 
   4670       1.1  christos 	      x = bfd_get_32 (input_bfd, contents + r_addr);
   4671       1.1  christos 	      x = x + relocation + r_addend;
   4672       1.1  christos 	      bfd_putl32 (/*input_bfd,*/ x, contents + r_addr);
   4673       1.1  christos 	      r = bfd_reloc_ok;
   4674       1.1  christos 	    }
   4675       1.1  christos 
   4676       1.1  christos 	  if (r != bfd_reloc_ok)
   4677       1.1  christos 	    {
   4678       1.1  christos 	      switch (r)
   4679       1.1  christos 		{
   4680       1.1  christos 		default:
   4681       1.1  christos 		case bfd_reloc_outofrange:
   4682       1.1  christos 		  abort ();
   4683       1.1  christos 		case bfd_reloc_overflow:
   4684       1.1  christos 		  {
   4685       1.1  christos 		    const char *name;
   4686       1.1  christos 
   4687       1.1  christos 		    if (h != NULL)
   4688       1.1  christos 		      name = NULL;
   4689       1.1  christos 		    else if (r_extern
   4690       1.1  christos 			     || r_type == (unsigned int) RELOC_BASE10
   4691   1.1.1.8  christos 			     || r_type == (unsigned int) RELOC_BASE13
   4692       1.1  christos 			     || r_type == (unsigned int) RELOC_BASE22)
   4693   1.1.1.5  christos 		      name = strings + GET_WORD (input_bfd,
   4694   1.1.1.5  christos 						 syms[r_index].e_strx);
   4695   1.1.1.5  christos 		    else
   4696   1.1.1.5  christos 		      {
   4697       1.1  christos 			asection *s;
   4698       1.1  christos 
   4699       1.1  christos 			s = aout_reloc_index_to_section (input_bfd, r_index);
   4700       1.1  christos 			name = bfd_section_name (s);
   4701       1.1  christos 		      }
   4702       1.1  christos 		    (*flaginfo->info->callbacks->reloc_overflow)
   4703       1.1  christos 		      (flaginfo->info, (h ? &h->root : NULL), name,
   4704   1.1.1.9  christos 		       howto_table_ext[r_type].name,
   4705       1.1  christos 		       r_addend, input_bfd, input_section, r_addr);
   4706       1.1  christos 		  }
   4707       1.1  christos 		  break;
   4708       1.1  christos 		}
   4709   1.1.1.9  christos 	    }
   4710   1.1.1.2  christos 	}
   4711       1.1  christos     }
   4712       1.1  christos 
   4713       1.1  christos   return true;
   4714       1.1  christos }
   4715       1.1  christos 
   4716       1.1  christos /* Link an a.out section into the output file.  */
   4717       1.1  christos 
   4718       1.1  christos static bool
   4719       1.1  christos aout_link_input_section (struct aout_final_link_info *flaginfo,
   4720       1.1  christos 			 bfd *input_bfd,
   4721       1.1  christos 			 asection *input_section,
   4722   1.1.1.2  christos 			 file_ptr *reloff_ptr,
   4723       1.1  christos 			 bfd_size_type rel_size)
   4724   1.1.1.9  christos {
   4725       1.1  christos   bfd_size_type input_size;
   4726  1.1.1.11  christos   void * relocs;
   4727  1.1.1.11  christos 
   4728       1.1  christos   /* Get the section contents.  */
   4729  1.1.1.11  christos   input_size = input_section->size;
   4730  1.1.1.11  christos   if (! bfd_get_section_contents (input_bfd, input_section,
   4731  1.1.1.11  christos 				  (void *) flaginfo->contents,
   4732       1.1  christos 				  (file_ptr) 0, input_size))
   4733       1.1  christos     return false;
   4734       1.1  christos 
   4735       1.1  christos   relocs = flaginfo->relocs;
   4736       1.1  christos   if (rel_size > 0)
   4737   1.1.1.2  christos     {
   4738       1.1  christos       if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
   4739   1.1.1.2  christos 	  || bfd_read (relocs, rel_size, input_bfd) != rel_size)
   4740   1.1.1.9  christos 	return false;
   4741       1.1  christos     }
   4742       1.1  christos 
   4743       1.1  christos   /* Relocate the section contents.  */
   4744   1.1.1.2  christos   if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
   4745       1.1  christos     {
   4746   1.1.1.2  christos       if (! aout_link_input_section_std (flaginfo, input_bfd, input_section,
   4747   1.1.1.9  christos 					 (struct reloc_std_external *) relocs,
   4748       1.1  christos 					 rel_size, flaginfo->contents))
   4749       1.1  christos 	return false;
   4750       1.1  christos     }
   4751   1.1.1.2  christos   else
   4752       1.1  christos     {
   4753   1.1.1.2  christos       if (! aout_link_input_section_ext (flaginfo, input_bfd, input_section,
   4754       1.1  christos 					 (struct reloc_ext_external *) relocs,
   4755       1.1  christos 					 rel_size, flaginfo->contents))
   4756   1.1.1.9  christos 	return false;
   4757       1.1  christos     }
   4758       1.1  christos 
   4759       1.1  christos   /* Write out the section contents.  */
   4760   1.1.1.5  christos   if (! bfd_set_section_contents (flaginfo->output_bfd,
   4761       1.1  christos 				  input_section->output_section,
   4762   1.1.1.2  christos 				  (void *) flaginfo->contents,
   4763   1.1.1.9  christos 				  (file_ptr) input_section->output_offset,
   4764  1.1.1.10  christos 				  input_size))
   4765   1.1.1.9  christos     return false;
   4766       1.1  christos 
   4767       1.1  christos   /* If we are producing relocatable output, the relocs were
   4768       1.1  christos      modified, and we now write them out.  */
   4769       1.1  christos   if (bfd_link_relocatable (flaginfo->info) && rel_size > 0)
   4770       1.1  christos     {
   4771   1.1.1.2  christos       if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
   4772   1.1.1.2  christos 	return false;
   4773       1.1  christos       if (bfd_write (relocs, rel_size, flaginfo->output_bfd) != rel_size)
   4774   1.1.1.2  christos 	return false;
   4775       1.1  christos       *reloff_ptr += rel_size;
   4776       1.1  christos 
   4777   1.1.1.9  christos       /* Assert that the relocs have not run into the symbols, and
   4778       1.1  christos 	 that if these are the text relocs they have not run into the
   4779       1.1  christos 	 data relocs.  */
   4780       1.1  christos       BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd)
   4781       1.1  christos 		  && (reloff_ptr != &flaginfo->treloff
   4782       1.1  christos 		      || (*reloff_ptr
   4783   1.1.1.9  christos 			  <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
   4784   1.1.1.2  christos     }
   4785       1.1  christos 
   4786       1.1  christos   return true;
   4787       1.1  christos }
   4788       1.1  christos 
   4789       1.1  christos /* Adjust and write out the symbols for an a.out file.  Set the new
   4790       1.1  christos    symbol indices into a symbol_map.  */
   4791       1.1  christos 
   4792       1.1  christos static bool
   4793       1.1  christos aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd)
   4794       1.1  christos {
   4795       1.1  christos   bfd *output_bfd;
   4796       1.1  christos   bfd_size_type sym_count;
   4797   1.1.1.9  christos   char *strings;
   4798   1.1.1.9  christos   enum bfd_link_strip strip;
   4799       1.1  christos   enum bfd_link_discard discard;
   4800   1.1.1.2  christos   struct external_nlist *outsym;
   4801       1.1  christos   bfd_size_type strtab_index;
   4802       1.1  christos   struct external_nlist *sym;
   4803   1.1.1.2  christos   struct external_nlist *sym_end;
   4804   1.1.1.2  christos   struct aout_link_hash_entry **sym_hash;
   4805   1.1.1.2  christos   int *symbol_map;
   4806       1.1  christos   bool pass;
   4807       1.1  christos   bool skip_next;
   4808       1.1  christos 
   4809       1.1  christos   output_bfd = flaginfo->output_bfd;
   4810       1.1  christos   sym_count = obj_aout_external_sym_count (input_bfd);
   4811   1.1.1.8  christos   strings = obj_aout_external_strings (input_bfd);
   4812   1.1.1.8  christos   strip = flaginfo->info->strip;
   4813   1.1.1.9  christos   discard = flaginfo->info->discard;
   4814       1.1  christos   outsym = flaginfo->output_syms;
   4815       1.1  christos 
   4816       1.1  christos   /* First write out a symbol for this object file, unless we are
   4817       1.1  christos      discarding such symbols.  */
   4818       1.1  christos   if (strip != strip_all
   4819   1.1.1.2  christos       && (strip != strip_some
   4820   1.1.1.9  christos 	  || bfd_hash_lookup (flaginfo->info->keep_hash,
   4821       1.1  christos 			      bfd_get_filename (input_bfd),
   4822   1.1.1.9  christos 			      false, false) != NULL)
   4823       1.1  christos       && discard != discard_all)
   4824       1.1  christos     {
   4825   1.1.1.8  christos       H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
   4826       1.1  christos       H_PUT_8 (output_bfd, 0, outsym->e_other);
   4827       1.1  christos       H_PUT_16 (output_bfd, 0, outsym->e_desc);
   4828       1.1  christos       strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
   4829       1.1  christos 				       bfd_get_filename (input_bfd), false);
   4830       1.1  christos       if (strtab_index == (bfd_size_type) -1)
   4831       1.1  christos 	return false;
   4832   1.1.1.9  christos       PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
   4833   1.1.1.9  christos       PUT_WORD (output_bfd,
   4834       1.1  christos 		(bfd_section_vma (obj_textsec (input_bfd)->output_section)
   4835       1.1  christos 		 + obj_textsec (input_bfd)->output_offset),
   4836       1.1  christos 		outsym->e_value);
   4837   1.1.1.2  christos       ++obj_aout_external_sym_count (output_bfd);
   4838       1.1  christos       ++outsym;
   4839       1.1  christos     }
   4840       1.1  christos 
   4841       1.1  christos   pass = false;
   4842       1.1  christos   skip_next = false;
   4843       1.1  christos   sym = obj_aout_external_syms (input_bfd);
   4844   1.1.1.9  christos   sym_end = sym + sym_count;
   4845       1.1  christos   sym_hash = obj_aout_sym_hashes (input_bfd);
   4846       1.1  christos   symbol_map = flaginfo->symbol_map;
   4847   1.1.1.9  christos   memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
   4848       1.1  christos   for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
   4849       1.1  christos     {
   4850   1.1.1.7  christos       const char *name;
   4851   1.1.1.7  christos       int type;
   4852   1.1.1.7  christos       struct aout_link_hash_entry *h;
   4853       1.1  christos       bool skip;
   4854       1.1  christos       asection *symsec;
   4855       1.1  christos       bfd_vma val = 0;
   4856       1.1  christos       bool copy;
   4857   1.1.1.7  christos 
   4858   1.1.1.7  christos       /* We set *symbol_map to 0 above for all symbols.  If it has
   4859       1.1  christos 	 already been set to -1 for this symbol, it means that we are
   4860       1.1  christos 	 discarding it because it appears in a duplicate header file.
   4861       1.1  christos 	 See the N_BINCL code below.  */
   4862       1.1  christos       if (*symbol_map == -1)
   4863       1.1  christos 	continue;
   4864       1.1  christos 
   4865       1.1  christos       /* Initialize *symbol_map to -1, which means that the symbol was
   4866       1.1  christos 	 not copied into the output file.  We will change it later if
   4867       1.1  christos 	 we do copy the symbol over.  */
   4868       1.1  christos       *symbol_map = -1;
   4869       1.1  christos 
   4870       1.1  christos       type = H_GET_8 (input_bfd, sym->e_type);
   4871   1.1.1.9  christos       name = strings + GET_WORD (input_bfd, sym->e_strx);
   4872       1.1  christos 
   4873       1.1  christos       h = NULL;
   4874       1.1  christos 
   4875       1.1  christos       if (pass)
   4876       1.1  christos 	{
   4877       1.1  christos 	  /* Pass this symbol through.  It is the target of an
   4878   1.1.1.9  christos 	     indirect or warning symbol.  */
   4879       1.1  christos 	  val = GET_WORD (input_bfd, sym->e_value);
   4880       1.1  christos 	  pass = false;
   4881       1.1  christos 	}
   4882       1.1  christos       else if (skip_next)
   4883       1.1  christos 	{
   4884       1.1  christos 	  /* Skip this symbol, which is the target of an indirect
   4885       1.1  christos 	     symbol that we have changed to no longer be an indirect
   4886       1.1  christos 	     symbol.  */
   4887       1.1  christos 	  skip_next = false;
   4888       1.1  christos 	  continue;
   4889       1.1  christos 	}
   4890       1.1  christos       else
   4891       1.1  christos 	{
   4892   1.1.1.7  christos 	  struct aout_link_hash_entry *hresolve;
   4893       1.1  christos 
   4894       1.1  christos 	  /* We have saved the hash table entry for this symbol, if
   4895       1.1  christos 	     there is one.  Note that we could just look it up again
   4896       1.1  christos 	     in the hash table, provided we first check that it is an
   4897       1.1  christos 	     external symbol.  */
   4898       1.1  christos 	  h = *sym_hash;
   4899       1.1  christos 
   4900       1.1  christos 	  /* Use the name from the hash table, in case the symbol was
   4901       1.1  christos 	     wrapped.  */
   4902       1.1  christos 	  if (h != NULL
   4903       1.1  christos 	      && h->root.type != bfd_link_hash_warning)
   4904       1.1  christos 	    name = h->root.root.string;
   4905       1.1  christos 
   4906       1.1  christos 	  /* If this is an indirect or warning symbol, then change
   4907       1.1  christos 	     hresolve to the base symbol.  We also change *sym_hash so
   4908       1.1  christos 	     that the relocation routines relocate against the real
   4909       1.1  christos 	     symbol.  */
   4910       1.1  christos 	  hresolve = h;
   4911       1.1  christos 	  if (h != (struct aout_link_hash_entry *) NULL
   4912       1.1  christos 	      && (h->root.type == bfd_link_hash_indirect
   4913       1.1  christos 		  || h->root.type == bfd_link_hash_warning))
   4914       1.1  christos 	    {
   4915       1.1  christos 	      hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
   4916       1.1  christos 	      while (hresolve->root.type == bfd_link_hash_indirect
   4917       1.1  christos 		     || hresolve->root.type == bfd_link_hash_warning)
   4918       1.1  christos 		hresolve = ((struct aout_link_hash_entry *)
   4919       1.1  christos 			    hresolve->root.u.i.link);
   4920   1.1.1.9  christos 	      *sym_hash = hresolve;
   4921       1.1  christos 	    }
   4922       1.1  christos 
   4923       1.1  christos 	  /* If the symbol has already been written out, skip it.  */
   4924       1.1  christos 	  if (h != NULL
   4925       1.1  christos 	      && h->written)
   4926   1.1.1.9  christos 	    {
   4927       1.1  christos 	      if ((type & N_TYPE) == N_INDR
   4928       1.1  christos 		  || type == N_WARNING)
   4929       1.1  christos 		skip_next = true;
   4930       1.1  christos 	      *symbol_map = h->indx;
   4931       1.1  christos 	      continue;
   4932       1.1  christos 	    }
   4933   1.1.1.9  christos 
   4934       1.1  christos 	  /* See if we are stripping this symbol.  */
   4935       1.1  christos 	  skip = false;
   4936   1.1.1.9  christos 	  switch (strip)
   4937       1.1  christos 	    {
   4938   1.1.1.9  christos 	    case strip_none:
   4939       1.1  christos 	      break;
   4940       1.1  christos 	    case strip_debugger:
   4941   1.1.1.9  christos 	      if ((type & N_STAB) != 0)
   4942       1.1  christos 		skip = true;
   4943       1.1  christos 	      break;
   4944       1.1  christos 	    case strip_some:
   4945       1.1  christos 	      if (bfd_hash_lookup (flaginfo->info->keep_hash, name, false, false)
   4946       1.1  christos 		  == NULL)
   4947   1.1.1.9  christos 		skip = true;
   4948       1.1  christos 	      break;
   4949       1.1  christos 	    case strip_all:
   4950       1.1  christos 	      skip = true;
   4951       1.1  christos 	      break;
   4952       1.1  christos 	    }
   4953       1.1  christos 	  if (skip)
   4954       1.1  christos 	    {
   4955       1.1  christos 	      if (h != NULL)
   4956       1.1  christos 		h->written = true;
   4957       1.1  christos 	      continue;
   4958       1.1  christos 	    }
   4959       1.1  christos 
   4960       1.1  christos 	  /* Get the value of the symbol.  */
   4961       1.1  christos 	  if ((type & N_TYPE) == N_TEXT
   4962       1.1  christos 	      || type == N_WEAKT)
   4963       1.1  christos 	    symsec = obj_textsec (input_bfd);
   4964       1.1  christos 	  else if ((type & N_TYPE) == N_DATA
   4965       1.1  christos 		   || type == N_WEAKD)
   4966       1.1  christos 	    symsec = obj_datasec (input_bfd);
   4967       1.1  christos 	  else if ((type & N_TYPE) == N_BSS
   4968       1.1  christos 		   || type == N_WEAKB)
   4969       1.1  christos 	    symsec = obj_bsssec (input_bfd);
   4970       1.1  christos 	  else if ((type & N_TYPE) == N_ABS
   4971       1.1  christos 		   || type == N_WEAKA)
   4972       1.1  christos 	    symsec = bfd_abs_section_ptr;
   4973       1.1  christos 	  else if (((type & N_TYPE) == N_INDR
   4974       1.1  christos 		    && (hresolve == NULL
   4975       1.1  christos 			|| (hresolve->root.type != bfd_link_hash_defined
   4976   1.1.1.9  christos 			    && hresolve->root.type != bfd_link_hash_defweak
   4977       1.1  christos 			    && hresolve->root.type != bfd_link_hash_common)))
   4978       1.1  christos 		   || type == N_WARNING)
   4979       1.1  christos 	    {
   4980       1.1  christos 	      /* Pass the next symbol through unchanged.  The
   4981       1.1  christos 		 condition above for indirect symbols is so that if
   4982       1.1  christos 		 the indirect symbol was defined, we output it with
   4983       1.1  christos 		 the correct definition so the debugger will
   4984       1.1  christos 		 understand it.  */
   4985       1.1  christos 	      pass = true;
   4986       1.1  christos 	      val = GET_WORD (input_bfd, sym->e_value);
   4987       1.1  christos 	      symsec = NULL;
   4988       1.1  christos 	    }
   4989       1.1  christos 	  else if ((type & N_STAB) != 0)
   4990       1.1  christos 	    {
   4991       1.1  christos 	      val = GET_WORD (input_bfd, sym->e_value);
   4992   1.1.1.9  christos 	      symsec = NULL;
   4993       1.1  christos 	    }
   4994       1.1  christos 	  else
   4995       1.1  christos 	    {
   4996       1.1  christos 	      /* If we get here with an indirect symbol, it means that
   4997       1.1  christos 		 we are outputting it with a real definition.  In such
   4998       1.1  christos 		 a case we do not want to output the next symbol,
   4999       1.1  christos 		 which is the target of the indirection.  */
   5000       1.1  christos 	      if ((type & N_TYPE) == N_INDR)
   5001       1.1  christos 		skip_next = true;
   5002       1.1  christos 
   5003       1.1  christos 	      symsec = NULL;
   5004       1.1  christos 
   5005       1.1  christos 	      /* We need to get the value from the hash table.  We use
   5006       1.1  christos 		 hresolve so that if we have defined an indirect
   5007       1.1  christos 		 symbol we output the final definition.  */
   5008       1.1  christos 	      if (h == NULL)
   5009       1.1  christos 		{
   5010       1.1  christos 		  switch (type & N_TYPE)
   5011       1.1  christos 		    {
   5012       1.1  christos 		    case N_SETT:
   5013       1.1  christos 		      symsec = obj_textsec (input_bfd);
   5014       1.1  christos 		      break;
   5015       1.1  christos 		    case N_SETD:
   5016       1.1  christos 		      symsec = obj_datasec (input_bfd);
   5017       1.1  christos 		      break;
   5018       1.1  christos 		    case N_SETB:
   5019       1.1  christos 		      symsec = obj_bsssec (input_bfd);
   5020       1.1  christos 		      break;
   5021       1.1  christos 		    case N_SETA:
   5022       1.1  christos 		      symsec = bfd_abs_section_ptr;
   5023       1.1  christos 		      break;
   5024       1.1  christos 		    default:
   5025       1.1  christos 		      val = 0;
   5026       1.1  christos 		      break;
   5027       1.1  christos 		    }
   5028       1.1  christos 		}
   5029       1.1  christos 	      else if (hresolve->root.type == bfd_link_hash_defined
   5030       1.1  christos 		       || hresolve->root.type == bfd_link_hash_defweak)
   5031       1.1  christos 		{
   5032       1.1  christos 		  asection *input_section;
   5033   1.1.1.8  christos 		  asection *output_section;
   5034       1.1  christos 
   5035       1.1  christos 		  /* This case usually means a common symbol which was
   5036       1.1  christos 		     turned into a defined symbol.  */
   5037       1.1  christos 		  input_section = hresolve->root.u.def.section;
   5038       1.1  christos 		  output_section = input_section->output_section;
   5039       1.1  christos 		  BFD_ASSERT (bfd_is_abs_section (output_section)
   5040       1.1  christos 			      || output_section->owner == output_bfd);
   5041       1.1  christos 		  val = (hresolve->root.u.def.value
   5042       1.1  christos 			 + bfd_section_vma (output_section)
   5043       1.1  christos 			 + input_section->output_offset);
   5044       1.1  christos 
   5045       1.1  christos 		  /* Get the correct type based on the section.  If
   5046       1.1  christos 		     this is a constructed set, force it to be
   5047       1.1  christos 		     globally visible.  */
   5048       1.1  christos 		  if (type == N_SETT
   5049       1.1  christos 		      || type == N_SETD
   5050       1.1  christos 		      || type == N_SETB
   5051       1.1  christos 		      || type == N_SETA)
   5052       1.1  christos 		    type |= N_EXT;
   5053       1.1  christos 
   5054       1.1  christos 		  type &=~ N_TYPE;
   5055       1.1  christos 
   5056       1.1  christos 		  if (output_section == obj_textsec (output_bfd))
   5057       1.1  christos 		    type |= (hresolve->root.type == bfd_link_hash_defined
   5058       1.1  christos 			     ? N_TEXT
   5059       1.1  christos 			     : N_WEAKT);
   5060       1.1  christos 		  else if (output_section == obj_datasec (output_bfd))
   5061       1.1  christos 		    type |= (hresolve->root.type == bfd_link_hash_defined
   5062       1.1  christos 			     ? N_DATA
   5063       1.1  christos 			     : N_WEAKD);
   5064       1.1  christos 		  else if (output_section == obj_bsssec (output_bfd))
   5065       1.1  christos 		    type |= (hresolve->root.type == bfd_link_hash_defined
   5066       1.1  christos 			     ? N_BSS
   5067       1.1  christos 			     : N_WEAKB);
   5068       1.1  christos 		  else
   5069       1.1  christos 		    type |= (hresolve->root.type == bfd_link_hash_defined
   5070       1.1  christos 			     ? N_ABS
   5071       1.1  christos 			     : N_WEAKA);
   5072       1.1  christos 		}
   5073       1.1  christos 	      else if (hresolve->root.type == bfd_link_hash_common)
   5074       1.1  christos 		val = hresolve->root.u.c.size;
   5075       1.1  christos 	      else if (hresolve->root.type == bfd_link_hash_undefweak)
   5076       1.1  christos 		{
   5077       1.1  christos 		  val = 0;
   5078       1.1  christos 		  type = N_WEAKU;
   5079       1.1  christos 		}
   5080       1.1  christos 	      else
   5081       1.1  christos 		val = 0;
   5082       1.1  christos 	    }
   5083       1.1  christos 	  if (symsec != NULL)
   5084   1.1.1.9  christos 	    val = (symsec->output_section->vma
   5085       1.1  christos 		   + symsec->output_offset
   5086       1.1  christos 		   + (GET_WORD (input_bfd, sym->e_value)
   5087       1.1  christos 		      - symsec->vma));
   5088       1.1  christos 
   5089       1.1  christos 	  /* If this is a global symbol set the written flag, and if
   5090       1.1  christos 	     it is a local symbol see if we should discard it.  */
   5091       1.1  christos 	  if (h != NULL)
   5092       1.1  christos 	    {
   5093       1.1  christos 	      h->written = true;
   5094       1.1  christos 	      h->indx = obj_aout_external_sym_count (output_bfd);
   5095       1.1  christos 	    }
   5096       1.1  christos 	  else if ((type & N_TYPE) != N_SETT
   5097       1.1  christos 		   && (type & N_TYPE) != N_SETD
   5098       1.1  christos 		   && (type & N_TYPE) != N_SETB
   5099       1.1  christos 		   && (type & N_TYPE) != N_SETA)
   5100   1.1.1.9  christos 	    {
   5101       1.1  christos 	      switch (discard)
   5102       1.1  christos 		{
   5103   1.1.1.9  christos 		case discard_none:
   5104       1.1  christos 		case discard_sec_merge:
   5105       1.1  christos 		  break;
   5106       1.1  christos 		case discard_l:
   5107       1.1  christos 		  if ((type & N_STAB) == 0
   5108   1.1.1.9  christos 		      && bfd_is_local_label_name (input_bfd, name))
   5109       1.1  christos 		    skip = true;
   5110       1.1  christos 		  break;
   5111       1.1  christos 		case discard_all:
   5112       1.1  christos 		  skip = true;
   5113       1.1  christos 		  break;
   5114       1.1  christos 		}
   5115       1.1  christos 	      if (skip)
   5116       1.1  christos 		{
   5117       1.1  christos 		  pass = false;
   5118       1.1  christos 		  continue;
   5119       1.1  christos 		}
   5120       1.1  christos 	    }
   5121       1.1  christos 
   5122       1.1  christos 	  /* An N_BINCL symbol indicates the start of the stabs
   5123       1.1  christos 	     entries for a header file.  We need to scan ahead to the
   5124       1.1  christos 	     next N_EINCL symbol, ignoring nesting, adding up all the
   5125       1.1  christos 	     characters in the symbol names, not including the file
   5126       1.1  christos 	     numbers in types (the first number after an open
   5127       1.1  christos 	     parenthesis).  */
   5128       1.1  christos 	  if (type == (int) N_BINCL)
   5129       1.1  christos 	    {
   5130       1.1  christos 	      struct external_nlist *incl_sym;
   5131       1.1  christos 	      int nest;
   5132       1.1  christos 	      struct aout_link_includes_entry *incl_entry;
   5133       1.1  christos 	      struct aout_link_includes_totals *t;
   5134       1.1  christos 
   5135       1.1  christos 	      val = 0;
   5136       1.1  christos 	      nest = 0;
   5137       1.1  christos 	      for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
   5138       1.1  christos 		{
   5139       1.1  christos 		  int incl_type;
   5140       1.1  christos 
   5141       1.1  christos 		  incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
   5142       1.1  christos 		  if (incl_type == (int) N_EINCL)
   5143       1.1  christos 		    {
   5144       1.1  christos 		      if (nest == 0)
   5145       1.1  christos 			break;
   5146       1.1  christos 		      --nest;
   5147       1.1  christos 		    }
   5148       1.1  christos 		  else if (incl_type == (int) N_BINCL)
   5149       1.1  christos 		    ++nest;
   5150       1.1  christos 		  else if (nest == 0)
   5151       1.1  christos 		    {
   5152       1.1  christos 		      const char *s;
   5153       1.1  christos 
   5154       1.1  christos 		      s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
   5155       1.1  christos 		      for (; *s != '\0'; s++)
   5156       1.1  christos 			{
   5157       1.1  christos 			  val += *s;
   5158       1.1  christos 			  if (*s == '(')
   5159       1.1  christos 			    {
   5160       1.1  christos 			      /* Skip the file number.  */
   5161       1.1  christos 			      ++s;
   5162   1.1.1.7  christos 			      while (ISDIGIT (*s))
   5163   1.1.1.7  christos 				++s;
   5164   1.1.1.9  christos 			      --s;
   5165   1.1.1.2  christos 			    }
   5166   1.1.1.9  christos 			}
   5167       1.1  christos 		    }
   5168   1.1.1.9  christos 		}
   5169       1.1  christos 
   5170       1.1  christos 	      /* If we have already included a header file with the
   5171       1.1  christos 		 same value, then replace this one with an N_EXCL
   5172       1.1  christos 		 symbol.  */
   5173       1.1  christos 	      copy = !flaginfo->info->keep_memory;
   5174       1.1  christos 	      incl_entry = aout_link_includes_lookup (&flaginfo->includes,
   5175   1.1.1.7  christos 						      name, true, copy);
   5176       1.1  christos 	      if (incl_entry == NULL)
   5177   1.1.1.7  christos 		return false;
   5178       1.1  christos 	      for (t = incl_entry->totals; t != NULL; t = t->next)
   5179       1.1  christos 		if (t->total == val)
   5180   1.1.1.9  christos 		  break;
   5181       1.1  christos 	      if (t == NULL)
   5182       1.1  christos 		{
   5183       1.1  christos 		  /* This is the first time we have seen this header
   5184       1.1  christos 		     file with this set of stabs strings.  */
   5185       1.1  christos 		  t = (struct aout_link_includes_totals *)
   5186       1.1  christos 		      bfd_hash_allocate (&flaginfo->includes.root,
   5187       1.1  christos 					 sizeof *t);
   5188       1.1  christos 		  if (t == NULL)
   5189       1.1  christos 		    return false;
   5190   1.1.1.7  christos 		  t->total = val;
   5191   1.1.1.7  christos 		  t->next = incl_entry->totals;
   5192       1.1  christos 		  incl_entry->totals = t;
   5193       1.1  christos 		}
   5194       1.1  christos 	      else
   5195       1.1  christos 		{
   5196       1.1  christos 		  int *incl_map;
   5197       1.1  christos 
   5198       1.1  christos 		  /* This is a duplicate header file.  We must change
   5199       1.1  christos 		     it to be an N_EXCL entry, and mark all the
   5200       1.1  christos 		     included symbols to prevent outputting them.  */
   5201       1.1  christos 		  type = (int) N_EXCL;
   5202       1.1  christos 
   5203       1.1  christos 		  nest = 0;
   5204       1.1  christos 		  for (incl_sym = sym + 1, incl_map = symbol_map + 1;
   5205       1.1  christos 		       incl_sym < sym_end;
   5206       1.1  christos 		       incl_sym++, incl_map++)
   5207       1.1  christos 		    {
   5208       1.1  christos 		      int incl_type;
   5209       1.1  christos 
   5210       1.1  christos 		      incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
   5211       1.1  christos 		      if (incl_type == (int) N_EINCL)
   5212       1.1  christos 			{
   5213       1.1  christos 			  if (nest == 0)
   5214       1.1  christos 			    {
   5215       1.1  christos 			      *incl_map = -1;
   5216       1.1  christos 			      break;
   5217       1.1  christos 			    }
   5218       1.1  christos 			  --nest;
   5219       1.1  christos 			}
   5220       1.1  christos 		      else if (incl_type == (int) N_BINCL)
   5221       1.1  christos 			++nest;
   5222       1.1  christos 		      else if (nest == 0)
   5223       1.1  christos 			*incl_map = -1;
   5224       1.1  christos 		    }
   5225   1.1.1.9  christos 		}
   5226   1.1.1.2  christos 	    }
   5227       1.1  christos 	}
   5228       1.1  christos 
   5229       1.1  christos       /* Copy this symbol into the list of symbols we are going to
   5230       1.1  christos 	 write out.  */
   5231       1.1  christos       H_PUT_8 (output_bfd, type, outsym->e_type);
   5232       1.1  christos       H_PUT_8 (output_bfd, H_GET_8 (input_bfd, sym->e_other), outsym->e_other);
   5233       1.1  christos       H_PUT_16 (output_bfd, H_GET_16 (input_bfd, sym->e_desc), outsym->e_desc);
   5234   1.1.1.9  christos       copy = false;
   5235       1.1  christos       if (! flaginfo->info->keep_memory)
   5236   1.1.1.2  christos 	{
   5237       1.1  christos 	  /* name points into a string table which we are going to
   5238       1.1  christos 	     free.  If there is a hash table entry, use that string.
   5239   1.1.1.9  christos 	     Otherwise, copy name into memory.  */
   5240       1.1  christos 	  if (h != NULL)
   5241       1.1  christos 	    name = h->root.root.string;
   5242       1.1  christos 	  else
   5243       1.1  christos 	    copy = true;
   5244       1.1  christos 	}
   5245       1.1  christos       strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
   5246       1.1  christos 				       name, copy);
   5247       1.1  christos       if (strtab_index == (bfd_size_type) -1)
   5248   1.1.1.2  christos 	return false;
   5249       1.1  christos       PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
   5250       1.1  christos       PUT_WORD (output_bfd, val, outsym->e_value);
   5251       1.1  christos       *symbol_map = obj_aout_external_sym_count (output_bfd);
   5252   1.1.1.2  christos       ++obj_aout_external_sym_count (output_bfd);
   5253   1.1.1.9  christos       ++outsym;
   5254   1.1.1.2  christos     }
   5255       1.1  christos 
   5256  1.1.1.10  christos   /* Write out the output symbols we have just constructed.  */
   5257       1.1  christos   if (outsym > flaginfo->output_syms)
   5258   1.1.1.9  christos     {
   5259   1.1.1.2  christos       bfd_size_type outsym_size;
   5260       1.1  christos 
   5261       1.1  christos       if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0)
   5262   1.1.1.9  christos 	return false;
   5263       1.1  christos       outsym_size = outsym - flaginfo->output_syms;
   5264       1.1  christos       outsym_size *= EXTERNAL_NLIST_SIZE;
   5265       1.1  christos       if (bfd_write (flaginfo->output_syms, outsym_size, output_bfd)
   5266       1.1  christos 	  != outsym_size)
   5267   1.1.1.9  christos 	return false;
   5268   1.1.1.2  christos       flaginfo->symoff += outsym_size;
   5269       1.1  christos     }
   5270       1.1  christos 
   5271       1.1  christos   return true;
   5272       1.1  christos }
   5273       1.1  christos 
   5274       1.1  christos /* Link an a.out input BFD into the output file.  */
   5275       1.1  christos 
   5276   1.1.1.2  christos static bool
   5277       1.1  christos aout_link_input_bfd (struct aout_final_link_info *flaginfo, bfd *input_bfd)
   5278       1.1  christos {
   5279   1.1.1.2  christos   BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
   5280       1.1  christos 
   5281   1.1.1.9  christos   /* If this is a dynamic object, it may need special handling.  */
   5282       1.1  christos   if ((input_bfd->flags & DYNAMIC) != 0
   5283       1.1  christos       && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
   5284   1.1.1.2  christos     return ((*aout_backend_info (input_bfd)->link_dynamic_object)
   5285   1.1.1.2  christos 	    (flaginfo->info, input_bfd));
   5286   1.1.1.9  christos 
   5287       1.1  christos   /* Get the symbols.  We probably have them already, unless
   5288       1.1  christos      flaginfo->info->keep_memory is FALSE.  */
   5289       1.1  christos   if (! aout_get_external_symbols (input_bfd))
   5290       1.1  christos     return false;
   5291       1.1  christos 
   5292       1.1  christos   /* Write out the symbols and get a map of the new indices.  The map
   5293       1.1  christos      is placed into flaginfo->symbol_map.  */
   5294   1.1.1.2  christos   if (! aout_link_write_symbols (flaginfo, input_bfd))
   5295       1.1  christos     return false;
   5296   1.1.1.2  christos 
   5297       1.1  christos   /* Relocate and write out the sections.  These functions use the
   5298   1.1.1.9  christos      symbol map created by aout_link_write_symbols.  The linker_mark
   5299       1.1  christos      field will be set if these sections are to be included in the
   5300       1.1  christos      link, which will normally be the case.  */
   5301       1.1  christos   if (obj_textsec (input_bfd)->linker_mark)
   5302   1.1.1.2  christos     {
   5303       1.1  christos       if (! aout_link_input_section (flaginfo, input_bfd,
   5304   1.1.1.2  christos 				     obj_textsec (input_bfd),
   5305       1.1  christos 				     &flaginfo->treloff,
   5306   1.1.1.9  christos 				     exec_hdr (input_bfd)->a_trsize))
   5307       1.1  christos 	return false;
   5308       1.1  christos     }
   5309       1.1  christos   if (obj_datasec (input_bfd)->linker_mark)
   5310       1.1  christos     {
   5311       1.1  christos       if (! aout_link_input_section (flaginfo, input_bfd,
   5312   1.1.1.2  christos 				     obj_datasec (input_bfd),
   5313       1.1  christos 				     &flaginfo->dreloff,
   5314       1.1  christos 				     exec_hdr (input_bfd)->a_drsize))
   5315   1.1.1.9  christos 	return false;
   5316       1.1  christos     }
   5317       1.1  christos 
   5318   1.1.1.9  christos   /* If we are not keeping memory, we don't need the symbols any
   5319       1.1  christos      longer.  We still need them if we are keeping memory, because the
   5320       1.1  christos      strings in the hash table point into them.  */
   5321       1.1  christos   if (! flaginfo->info->keep_memory)
   5322       1.1  christos     {
   5323   1.1.1.3  christos       if (! aout_link_free_symbols (input_bfd))
   5324       1.1  christos 	return false;
   5325       1.1  christos     }
   5326       1.1  christos 
   5327       1.1  christos   return true;
   5328   1.1.1.9  christos }
   5329       1.1  christos 
   5330       1.1  christos /* Do the final link step.  This is called on the output BFD.  The
   5331       1.1  christos    INFO structure should point to a list of BFDs linked through the
   5332       1.1  christos    link.next field which can be used to find each BFD which takes part
   5333       1.1  christos    in the output.  Also, each section in ABFD should point to a list
   5334   1.1.1.9  christos    of bfd_link_order structures which list all the input sections for
   5335       1.1  christos    the output section.  */
   5336       1.1  christos 
   5337       1.1  christos bool
   5338       1.1  christos NAME (aout, final_link) (bfd *abfd,
   5339       1.1  christos 			 struct bfd_link_info *info,
   5340       1.1  christos 			 void (*callback) (bfd *, file_ptr *, file_ptr *, file_ptr *))
   5341       1.1  christos {
   5342   1.1.1.9  christos   struct aout_final_link_info aout_info;
   5343       1.1  christos   bool includes_hash_initialized = false;
   5344   1.1.1.5  christos   bfd *sub;
   5345       1.1  christos   bfd_size_type trsize, drsize;
   5346       1.1  christos   bfd_size_type max_contents_size;
   5347       1.1  christos   bfd_size_type max_relocs_size;
   5348       1.1  christos   bfd_size_type max_sym_count;
   5349       1.1  christos   struct bfd_link_order *p;
   5350       1.1  christos   asection *o;
   5351       1.1  christos   bool have_link_order_relocs;
   5352       1.1  christos 
   5353       1.1  christos   if (bfd_link_pic (info))
   5354       1.1  christos     abfd->flags |= DYNAMIC;
   5355       1.1  christos 
   5356       1.1  christos   aout_info.info = info;
   5357       1.1  christos   aout_info.output_bfd = abfd;
   5358       1.1  christos   aout_info.contents = NULL;
   5359   1.1.1.9  christos   aout_info.relocs = NULL;
   5360       1.1  christos   aout_info.symbol_map = NULL;
   5361       1.1  christos   aout_info.output_syms = NULL;
   5362       1.1  christos 
   5363       1.1  christos   if (!bfd_hash_table_init_n (&aout_info.includes.root,
   5364       1.1  christos 			      aout_link_includes_newfunc,
   5365       1.1  christos 			      sizeof (struct aout_link_includes_entry),
   5366       1.1  christos 			      251))
   5367       1.1  christos     goto error_return;
   5368   1.1.1.3  christos   includes_hash_initialized = true;
   5369       1.1  christos 
   5370       1.1  christos   /* Figure out the largest section size.  Also, if generating
   5371       1.1  christos      relocatable output, count the relocs.  */
   5372   1.1.1.5  christos   trsize = 0;
   5373       1.1  christos   drsize = 0;
   5374       1.1  christos   max_contents_size = 0;
   5375       1.1  christos   max_relocs_size = 0;
   5376       1.1  christos   max_sym_count = 0;
   5377       1.1  christos   for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
   5378       1.1  christos     {
   5379       1.1  christos       bfd_size_type sz;
   5380       1.1  christos 
   5381       1.1  christos       if (bfd_link_relocatable (info))
   5382       1.1  christos 	{
   5383       1.1  christos 	  if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
   5384       1.1  christos 	    {
   5385   1.1.1.6  christos 	      trsize += exec_hdr (sub)->a_trsize;
   5386   1.1.1.6  christos 	      drsize += exec_hdr (sub)->a_drsize;
   5387   1.1.1.7  christos 	    }
   5388   1.1.1.6  christos 	  else
   5389       1.1  christos 	    {
   5390       1.1  christos 	      /* FIXME: We need to identify the .text and .data sections
   5391       1.1  christos 		 and call get_reloc_upper_bound and canonicalize_reloc to
   5392       1.1  christos 		 work out the number of relocs needed, and then multiply
   5393       1.1  christos 		 by the reloc size.  */
   5394       1.1  christos 	      _bfd_error_handler
   5395       1.1  christos 		/* xgettext:c-format */
   5396       1.1  christos 		(_("%pB: relocatable link from %s to %s not supported"),
   5397       1.1  christos 		 abfd, sub->xvec->name, abfd->xvec->name);
   5398       1.1  christos 	      bfd_set_error (bfd_error_invalid_operation);
   5399       1.1  christos 	      goto error_return;
   5400       1.1  christos 	    }
   5401       1.1  christos 	}
   5402       1.1  christos 
   5403       1.1  christos       if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
   5404       1.1  christos 	{
   5405       1.1  christos 	  sz = obj_textsec (sub)->size;
   5406       1.1  christos 	  if (sz > max_contents_size)
   5407       1.1  christos 	    max_contents_size = sz;
   5408       1.1  christos 	  sz = obj_datasec (sub)->size;
   5409       1.1  christos 	  if (sz > max_contents_size)
   5410       1.1  christos 	    max_contents_size = sz;
   5411       1.1  christos 
   5412       1.1  christos 	  sz = exec_hdr (sub)->a_trsize;
   5413       1.1  christos 	  if (sz > max_relocs_size)
   5414       1.1  christos 	    max_relocs_size = sz;
   5415       1.1  christos 	  sz = exec_hdr (sub)->a_drsize;
   5416   1.1.1.5  christos 	  if (sz > max_relocs_size)
   5417       1.1  christos 	    max_relocs_size = sz;
   5418       1.1  christos 
   5419       1.1  christos 	  sz = obj_aout_external_sym_count (sub);
   5420       1.1  christos 	  if (sz > max_sym_count)
   5421       1.1  christos 	    max_sym_count = sz;
   5422       1.1  christos 	}
   5423       1.1  christos     }
   5424       1.1  christos 
   5425       1.1  christos   if (bfd_link_relocatable (info))
   5426       1.1  christos     {
   5427       1.1  christos       if (obj_textsec (abfd) != NULL)
   5428       1.1  christos 	trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
   5429       1.1  christos 						 ->map_head.link_order)
   5430       1.1  christos 		   * obj_reloc_entry_size (abfd));
   5431       1.1  christos       if (obj_datasec (abfd) != NULL)
   5432       1.1  christos 	drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
   5433       1.1  christos 						 ->map_head.link_order)
   5434       1.1  christos 		   * obj_reloc_entry_size (abfd));
   5435       1.1  christos     }
   5436   1.1.1.5  christos 
   5437       1.1  christos   exec_hdr (abfd)->a_trsize = trsize;
   5438       1.1  christos   exec_hdr (abfd)->a_drsize = drsize;
   5439       1.1  christos 
   5440       1.1  christos   exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
   5441       1.1  christos 
   5442       1.1  christos   /* Adjust the section sizes and vmas according to the magic number.
   5443       1.1  christos      This sets a_text, a_data and a_bss in the exec_hdr and sets the
   5444       1.1  christos      filepos for each section.  */
   5445   1.1.1.7  christos   if (! NAME (aout, adjust_sizes_and_vmas) (abfd))
   5446       1.1  christos     goto error_return;
   5447       1.1  christos 
   5448       1.1  christos   /* The relocation and symbol file positions differ among a.out
   5449       1.1  christos      targets.  We are passed a callback routine from the backend
   5450       1.1  christos      specific code to handle this.
   5451       1.1  christos      FIXME: At this point we do not know how much space the symbol
   5452       1.1  christos      table will require.  This will not work for any (nonstandard)
   5453       1.1  christos      a.out target that needs to know the symbol table size before it
   5454       1.1  christos      can compute the relocation file positions.  */
   5455       1.1  christos   (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
   5456       1.1  christos 	       &aout_info.symoff);
   5457       1.1  christos   obj_textsec (abfd)->rel_filepos = aout_info.treloff;
   5458       1.1  christos   obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
   5459       1.1  christos   obj_sym_filepos (abfd) = aout_info.symoff;
   5460       1.1  christos 
   5461       1.1  christos   /* We keep a count of the symbols as we output them.  */
   5462       1.1  christos   obj_aout_external_sym_count (abfd) = 0;
   5463       1.1  christos 
   5464       1.1  christos   /* We accumulate the string table as we write out the symbols.  */
   5465       1.1  christos   aout_info.strtab = _bfd_stringtab_init ();
   5466       1.1  christos   if (aout_info.strtab == NULL)
   5467       1.1  christos     goto error_return;
   5468       1.1  christos 
   5469       1.1  christos   /* Allocate buffers to hold section contents and relocs.  */
   5470       1.1  christos   aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
   5471       1.1  christos   aout_info.relocs = bfd_malloc (max_relocs_size);
   5472       1.1  christos   aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int));
   5473       1.1  christos   aout_info.output_syms = (struct external_nlist *)
   5474       1.1  christos       bfd_malloc ((max_sym_count + 1) * sizeof (struct external_nlist));
   5475       1.1  christos   if ((aout_info.contents == NULL && max_contents_size != 0)
   5476       1.1  christos       || (aout_info.relocs == NULL && max_relocs_size != 0)
   5477       1.1  christos       || (aout_info.symbol_map == NULL && max_sym_count != 0)
   5478       1.1  christos       || aout_info.output_syms == NULL)
   5479       1.1  christos     goto error_return;
   5480   1.1.1.9  christos 
   5481       1.1  christos   /* If we have a symbol named __DYNAMIC, force it out now.  This is
   5482   1.1.1.2  christos      required by SunOS.  Doing this here rather than in sunos.c is a
   5483       1.1  christos      hack, but it's easier than exporting everything which would be
   5484       1.1  christos      needed.  */
   5485       1.1  christos   {
   5486       1.1  christos     struct aout_link_hash_entry *h;
   5487       1.1  christos 
   5488       1.1  christos     h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
   5489       1.1  christos 			       false, false, false);
   5490       1.1  christos     if (h != NULL)
   5491       1.1  christos       aout_link_write_other_symbol (&h->root.root, &aout_info);
   5492       1.1  christos   }
   5493       1.1  christos 
   5494       1.1  christos   /* The most time efficient way to do the link would be to read all
   5495       1.1  christos      the input object files into memory and then sort out the
   5496       1.1  christos      information into the output file.  Unfortunately, that will
   5497       1.1  christos      probably use too much memory.  Another method would be to step
   5498       1.1  christos      through everything that composes the text section and write it
   5499       1.1  christos      out, and then everything that composes the data section and write
   5500       1.1  christos      it out, and then write out the relocs, and then write out the
   5501       1.1  christos      symbols.  Unfortunately, that requires reading stuff from each
   5502       1.1  christos      input file several times, and we will not be able to keep all the
   5503       1.1  christos      input files open simultaneously, and reopening them will be slow.
   5504       1.1  christos 
   5505       1.1  christos      What we do is basically process one input file at a time.  We do
   5506   1.1.1.3  christos      everything we need to do with an input file once--copy over the
   5507   1.1.1.9  christos      section contents, handle the relocation information, and write
   5508       1.1  christos      out the symbols--and then we throw away the information we read
   5509       1.1  christos      from it.  This approach requires a lot of lseeks of the output
   5510       1.1  christos      file, which is unfortunate but still faster than reopening a lot
   5511       1.1  christos      of files.
   5512       1.1  christos 
   5513       1.1  christos      We use the output_has_begun field of the input BFDs to see
   5514       1.1  christos      whether we have already handled it.  */
   5515       1.1  christos   for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
   5516       1.1  christos     sub->output_has_begun = false;
   5517   1.1.1.9  christos 
   5518       1.1  christos   /* Mark all sections which are to be included in the link.  This
   5519       1.1  christos      will normally be every section.  We need to do this so that we
   5520   1.1.1.9  christos      can identify any sections which the linker has decided to not
   5521       1.1  christos      include.  */
   5522       1.1  christos   for (o = abfd->sections; o != NULL; o = o->next)
   5523       1.1  christos     {
   5524       1.1  christos       for (p = o->map_head.link_order; p != NULL; p = p->next)
   5525       1.1  christos 	if (p->type == bfd_indirect_link_order)
   5526       1.1  christos 	  p->u.indirect.section->linker_mark = true;
   5527       1.1  christos     }
   5528       1.1  christos 
   5529       1.1  christos   have_link_order_relocs = false;
   5530       1.1  christos   for (o = abfd->sections; o != NULL; o = o->next)
   5531       1.1  christos     {
   5532       1.1  christos       for (p = o->map_head.link_order;
   5533       1.1  christos 	   p != NULL;
   5534       1.1  christos 	   p = p->next)
   5535       1.1  christos 	{
   5536       1.1  christos 	  if (p->type == bfd_indirect_link_order
   5537       1.1  christos 	      && (bfd_get_flavour (p->u.indirect.section->owner)
   5538   1.1.1.9  christos 		  == bfd_target_aout_flavour))
   5539       1.1  christos 	    {
   5540       1.1  christos 	      bfd *input_bfd;
   5541       1.1  christos 
   5542       1.1  christos 	      input_bfd = p->u.indirect.section->owner;
   5543       1.1  christos 	      if (! input_bfd->output_has_begun)
   5544       1.1  christos 		{
   5545   1.1.1.9  christos 		  if (! aout_link_input_bfd (&aout_info, input_bfd))
   5546       1.1  christos 		    goto error_return;
   5547       1.1  christos 		  input_bfd->output_has_begun = true;
   5548       1.1  christos 		}
   5549       1.1  christos 	    }
   5550       1.1  christos 	  else if (p->type == bfd_section_reloc_link_order
   5551       1.1  christos 		   || p->type == bfd_symbol_reloc_link_order)
   5552       1.1  christos 	    {
   5553       1.1  christos 	      /* These are handled below.  */
   5554       1.1  christos 	      have_link_order_relocs = true;
   5555       1.1  christos 	    }
   5556   1.1.1.2  christos 	  else
   5557   1.1.1.2  christos 	    {
   5558   1.1.1.2  christos 	      if (! _bfd_default_link_order (abfd, info, o, p))
   5559       1.1  christos 		goto error_return;
   5560       1.1  christos 	    }
   5561       1.1  christos 	}
   5562       1.1  christos     }
   5563       1.1  christos 
   5564       1.1  christos   /* Write out any symbols that we have not already written out.  */
   5565       1.1  christos   bfd_hash_traverse (&info->hash->table,
   5566       1.1  christos 		     aout_link_write_other_symbol,
   5567       1.1  christos 		     &aout_info);
   5568       1.1  christos 
   5569       1.1  christos   /* Now handle any relocs we were asked to create by the linker.
   5570       1.1  christos      These did not come from any input file.  We must do these after
   5571       1.1  christos      we have written out all the symbols, so that we know the symbol
   5572       1.1  christos      indices to use.  */
   5573       1.1  christos   if (have_link_order_relocs)
   5574       1.1  christos     {
   5575       1.1  christos       for (o = abfd->sections; o != NULL; o = o->next)
   5576       1.1  christos 	{
   5577       1.1  christos 	  for (p = o->map_head.link_order;
   5578       1.1  christos 	       p != NULL;
   5579       1.1  christos 	       p = p->next)
   5580       1.1  christos 	    {
   5581       1.1  christos 	      if (p->type == bfd_section_reloc_link_order
   5582   1.1.1.8  christos 		  || p->type == bfd_symbol_reloc_link_order)
   5583   1.1.1.8  christos 		{
   5584   1.1.1.8  christos 		  if (! aout_link_reloc_link_order (&aout_info, o, p))
   5585   1.1.1.8  christos 		    goto error_return;
   5586   1.1.1.8  christos 		}
   5587   1.1.1.8  christos 	    }
   5588   1.1.1.8  christos 	}
   5589   1.1.1.8  christos     }
   5590   1.1.1.8  christos 
   5591       1.1  christos   free (aout_info.contents);
   5592       1.1  christos   aout_info.contents = NULL;
   5593       1.1  christos   free (aout_info.relocs);
   5594   1.1.1.9  christos   aout_info.relocs = NULL;
   5595       1.1  christos   free (aout_info.symbol_map);
   5596       1.1  christos   aout_info.symbol_map = NULL;
   5597       1.1  christos   free (aout_info.output_syms);
   5598       1.1  christos   aout_info.output_syms = NULL;
   5599       1.1  christos 
   5600       1.1  christos   if (includes_hash_initialized)
   5601       1.1  christos     {
   5602       1.1  christos       bfd_hash_table_free (&aout_info.includes.root);
   5603       1.1  christos       includes_hash_initialized = false;
   5604       1.1  christos     }
   5605       1.1  christos 
   5606       1.1  christos   /* Finish up any dynamic linking we may be doing.  */
   5607       1.1  christos   if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
   5608       1.1  christos     {
   5609       1.1  christos       if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
   5610       1.1  christos 	goto error_return;
   5611       1.1  christos     }
   5612       1.1  christos 
   5613       1.1  christos   /* Update the header information.  */
   5614       1.1  christos   abfd->symcount = obj_aout_external_sym_count (abfd);
   5615       1.1  christos   exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
   5616       1.1  christos   obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
   5617       1.1  christos   obj_textsec (abfd)->reloc_count =
   5618       1.1  christos     exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
   5619       1.1  christos   obj_datasec (abfd)->reloc_count =
   5620       1.1  christos     exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
   5621       1.1  christos 
   5622       1.1  christos   /* Write out the string table, unless there are no symbols.  */
   5623       1.1  christos   if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
   5624       1.1  christos     goto error_return;
   5625       1.1  christos   if (abfd->symcount > 0)
   5626  1.1.1.10  christos     {
   5627       1.1  christos       if (!emit_stringtab (abfd, aout_info.strtab))
   5628       1.1  christos 	goto error_return;
   5629       1.1  christos     }
   5630   1.1.1.9  christos   else
   5631       1.1  christos     {
   5632       1.1  christos       bfd_byte b[BYTES_IN_WORD];
   5633   1.1.1.8  christos 
   5634   1.1.1.8  christos       memset (b, 0, BYTES_IN_WORD);
   5635   1.1.1.8  christos       if (bfd_write (b, BYTES_IN_WORD, abfd) != BYTES_IN_WORD)
   5636   1.1.1.8  christos 	goto error_return;
   5637       1.1  christos     }
   5638       1.1  christos 
   5639   1.1.1.9  christos   return true;
   5640       1.1  christos 
   5641                      error_return:
   5642                       free (aout_info.contents);
   5643                       free (aout_info.relocs);
   5644                       free (aout_info.symbol_map);
   5645                       free (aout_info.output_syms);
   5646                       if (includes_hash_initialized)
   5647                         bfd_hash_table_free (&aout_info.includes.root);
   5648                       return false;
   5649                     }
   5650