Home | History | Annotate | Line # | Download | only in bfd
      1       1.1     skrll /* BFD back-end for PDP-11 a.out binaries.
      2  1.1.1.12  christos    Copyright (C) 2001-2026 Free Software Foundation, Inc.
      3       1.1     skrll 
      4       1.1     skrll    This file is part of BFD, the Binary File Descriptor library.
      5       1.1     skrll 
      6       1.1     skrll    This program is free software; you can redistribute it and/or modify
      7       1.1     skrll    it under the terms of the GNU General Public License as published by
      8       1.1     skrll    the Free Software Foundation; either version 3 of the License, or
      9       1.1     skrll    (at your option) any later version.
     10       1.1     skrll 
     11       1.1     skrll    This program is distributed in the hope that it will be useful,
     12       1.1     skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13       1.1     skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14       1.1     skrll    GNU General Public License for more details.
     15       1.1     skrll 
     16       1.1     skrll    You should have received a copy of the GNU General Public License
     17       1.1     skrll    along with this program; if not, write to the Free Software
     18       1.1     skrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19       1.1     skrll    MA 02110-1301, USA. */
     20       1.1     skrll 
     21       1.1     skrll 
     22       1.1     skrll /* BFD backend for PDP-11, running 2.11BSD in particular.
     23       1.1     skrll 
     24       1.1     skrll    This file was hacked up by looking hard at the existing vaxnetbsd
     25   1.1.1.9  christos    back end and the header files in 2.11BSD.  The symbol table format
     26   1.1.1.9  christos    of 2.11BSD has been extended to accommodate .stab symbols.  See
     27   1.1.1.9  christos    struct pdp11_external_nlist below for details.
     28       1.1     skrll 
     29       1.1     skrll    TODO
     30       1.1     skrll    * support for V7 file formats
     31       1.1     skrll    * support for overlay object files (see 2.11 a.out(5))
     32       1.1     skrll    * support for old and very old archives
     33       1.1     skrll    (see 2.11 ar(5), historical section)
     34       1.1     skrll 
     35       1.1     skrll    Search for TODO to find other areas needing more work.  */
     36       1.1     skrll 
     37       1.1     skrll #define	BYTES_IN_WORD	2
     38       1.1     skrll #define	BYTES_IN_LONG	4
     39       1.1     skrll #define ARCH_SIZE	16
     40       1.1     skrll #undef TARGET_IS_BIG_ENDIAN_P
     41       1.1     skrll 
     42   1.1.1.8  christos #define	TARGET_PAGE_SIZE	8192
     43       1.1     skrll #define	SEGMENT__SIZE	TARGET_PAGE_SIZE
     44       1.1     skrll 
     45       1.1     skrll #define	DEFAULT_ARCH	bfd_arch_pdp11
     46   1.1.1.6  christos #define	DEFAULT_MID	M_PDP11
     47       1.1     skrll 
     48       1.1     skrll /* Do not "beautify" the CONCAT* macro args.  Traditional C will not
     49       1.1     skrll    remove whitespace added here, and thus will fail to concatenate
     50       1.1     skrll    the tokens.  */
     51       1.1     skrll #define MY(OP) CONCAT2 (pdp11_aout_,OP)
     52       1.1     skrll 
     53       1.1     skrll /* This needs to start with a.out so GDB knows it is an a.out variant.  */
     54       1.1     skrll #define TARGETNAME "a.out-pdp11"
     55       1.1     skrll 
     56       1.1     skrll /* This is the normal load address for executables.  */
     57       1.1     skrll #define TEXT_START_ADDR		0
     58       1.1     skrll 
     59       1.1     skrll /* The header is not included in the text segment.  */
     60       1.1     skrll #define N_HEADER_IN_TEXT(x)	0
     61       1.1     skrll 
     62       1.1     skrll /* There is no flags field.  */
     63   1.1.1.5  christos #define N_FLAGS(execp)		0
     64       1.1     skrll 
     65   1.1.1.5  christos #define N_SET_FLAGS(execp, flags) do { } while (0)
     66   1.1.1.2  christos #define N_BADMAG(x) (N_MAGIC(x) != OMAGIC	\
     67   1.1.1.2  christos 		     && N_MAGIC(x) != NMAGIC	\
     68   1.1.1.9  christos 		     && N_MAGIC(x) != IMAGIC	\
     69   1.1.1.2  christos 		     && N_MAGIC(x) != ZMAGIC)
     70       1.1     skrll 
     71       1.1     skrll #include "sysdep.h"
     72   1.1.1.8  christos #include <limits.h>
     73       1.1     skrll #include "bfd.h"
     74       1.1     skrll 
     75       1.1     skrll #define external_exec pdp11_external_exec
     76       1.1     skrll struct pdp11_external_exec
     77       1.1     skrll {
     78       1.1     skrll   bfd_byte e_info[2];		/* Magic number.  */
     79       1.1     skrll   bfd_byte e_text[2];		/* Length of text section in bytes.  */
     80       1.1     skrll   bfd_byte e_data[2];		/* Length of data section in bytes.  */
     81       1.1     skrll   bfd_byte e_bss[2];		/* Length of bss area in bytes.  */
     82       1.1     skrll   bfd_byte e_syms[2];		/* Length of symbol table in bytes.  */
     83       1.1     skrll   bfd_byte e_entry[2];		/* Start address.  */
     84       1.1     skrll   bfd_byte e_unused[2];		/* Not used.  */
     85       1.1     skrll   bfd_byte e_flag[2];		/* Relocation info stripped.  */
     86   1.1.1.6  christos   bfd_byte e_relocatable;	/* Ugly hack.  */
     87       1.1     skrll };
     88       1.1     skrll 
     89       1.1     skrll #define	EXEC_BYTES_SIZE	(8 * 2)
     90       1.1     skrll 
     91       1.1     skrll #define	A_MAGIC1	OMAGIC
     92       1.1     skrll #define OMAGIC		0407	/* ...object file or impure executable.  */
     93       1.1     skrll #define	A_MAGIC2	NMAGIC
     94       1.1     skrll #define NMAGIC		0410	/* Pure executable.  */
     95       1.1     skrll #define ZMAGIC		0413	/* Demand-paged executable.  */
     96   1.1.1.9  christos #define	IMAGIC		0411	/* Separated I&D.  */
     97   1.1.1.9  christos #define	A_MAGIC3	IMAGIC
     98       1.1     skrll #define	A_MAGIC4	0405	/* Overlay.  */
     99       1.1     skrll #define	A_MAGIC5	0430	/* Auto-overlay (nonseparate).  */
    100       1.1     skrll #define	A_MAGIC6	0431	/* Auto-overlay (separate).  */
    101       1.1     skrll #define QMAGIC		0
    102       1.1     skrll #define BMAGIC		0
    103       1.1     skrll 
    104       1.1     skrll #define A_FLAG_RELOC_STRIPPED	0x0001
    105       1.1     skrll 
    106   1.1.1.9  christos /* The following struct defines the format of an entry in the object file
    107   1.1.1.9  christos    symbol table.  In the original 2.11BSD struct the index into the string
    108   1.1.1.9  christos    table is stored as a long, but the PDP11 C convention for storing a long in
    109   1.1.1.9  christos    memory placed the most significant word first even though the bytes within a
    110   1.1.1.9  christos    word are stored least significant first.  So here the string table index is
    111   1.1.1.9  christos    considered to be just 16 bits and the first two bytes of the struct were
    112   1.1.1.9  christos    previously named e_unused.  To extend the symbol table format to accommodate
    113   1.1.1.9  christos    .stab symbols, the e_unused bytes are renamed e_desc to store the desc field
    114   1.1.1.9  christos    of the .stab symbol.  The GDP Project's STABS document says that the "other"
    115   1.1.1.9  christos    field is almost always unused and can be set to zero; the only nonzero cases
    116   1.1.1.9  christos    identified were for stabs in their own sections, which does not apply for
    117   1.1.1.9  christos    pdp11 a.out format, and for a special case of GNU Modula2 which is not
    118   1.1.1.9  christos    supported for the PDP11.  */
    119       1.1     skrll #define external_nlist pdp11_external_nlist
    120       1.1     skrll struct pdp11_external_nlist
    121       1.1     skrll {
    122   1.1.1.9  christos   bfd_byte e_desc[2];		/* The desc field for .stab symbols, else 0.  */
    123       1.1     skrll   bfd_byte e_strx[2];		/* Index into string table of name.  */
    124       1.1     skrll   bfd_byte e_type[1];		/* Type of symbol.  */
    125       1.1     skrll   bfd_byte e_ovly[1];		/* Overlay number.  */
    126       1.1     skrll   bfd_byte e_value[2];		/* Value of symbol.  */
    127       1.1     skrll };
    128       1.1     skrll 
    129       1.1     skrll #define	EXTERNAL_NLIST_SIZE	8
    130       1.1     skrll 
    131       1.1     skrll #define N_TXTOFF(x)	(EXEC_BYTES_SIZE)
    132   1.1.1.5  christos #define N_DATOFF(x)	(N_TXTOFF(x) + (x)->a_text)
    133   1.1.1.5  christos #define N_TRELOFF(x)	(N_DATOFF(x) + (x)->a_data)
    134   1.1.1.5  christos #define N_DRELOFF(x)	(N_TRELOFF(x) + (x)->a_trsize)
    135   1.1.1.5  christos #define N_SYMOFF(x)	(N_DRELOFF(x) + (x)->a_drsize)
    136   1.1.1.5  christos #define N_STROFF(x)	(N_SYMOFF(x) + (x)->a_syms)
    137       1.1     skrll 
    138       1.1     skrll #define WRITE_HEADERS(abfd, execp) pdp11_aout_write_headers (abfd, execp)
    139       1.1     skrll 
    140       1.1     skrll #include "libbfd.h"
    141       1.1     skrll #include "libaout.h"
    142       1.1     skrll 
    143       1.1     skrll #define SWAP_MAGIC(ext) bfd_getl16 (ext)
    144       1.1     skrll 
    145       1.1     skrll #define MY_entry_is_text_address 1
    146       1.1     skrll 
    147       1.1     skrll #define MY_write_object_contents MY(write_object_contents)
    148   1.1.1.9  christos static bool MY(write_object_contents) (bfd *);
    149       1.1     skrll #define MY_text_includes_header 1
    150       1.1     skrll 
    151       1.1     skrll #define MY_BFD_TARGET
    152       1.1     skrll 
    153       1.1     skrll #include "aout-target.h"
    154       1.1     skrll 
    155       1.1     skrll /* Start of modified aoutx.h.  */
    156       1.1     skrll #define KEEPIT udata.i
    157       1.1     skrll 
    158       1.1     skrll #include <string.h>		/* For strchr and friends.  */
    159       1.1     skrll #include "bfd.h"
    160       1.1     skrll #include "sysdep.h"
    161       1.1     skrll #include "safe-ctype.h"
    162       1.1     skrll #include "bfdlink.h"
    163       1.1     skrll 
    164       1.1     skrll #include "libaout.h"
    165       1.1     skrll #include "aout/aout64.h"
    166       1.1     skrll #include "aout/stab_gnu.h"
    167       1.1     skrll #include "aout/ar.h"
    168       1.1     skrll 
    169   1.1.1.9  christos /* The symbol type numbers for the 16-bit a.out format from 2.11BSD differ from
    170   1.1.1.9  christos    those defined in aout64.h so we must redefine them here.  N_EXT changes from
    171   1.1.1.9  christos    0x01 to 0x20 which creates a conflict with some .stab values, in particular
    172   1.1.1.9  christos    between undefined externals (N_UNDF+N_EXT) vs. global variables (N_GYSM) and
    173   1.1.1.9  christos    between external bss symbols (N_BSS+N_EXT) vs. function names (N_FUN).  We
    174   1.1.1.9  christos    disambiguate those conflicts with a hack in is_stab() to look for the ':' in
    175   1.1.1.9  christos    the global variable or function name string.  */
    176       1.1     skrll #undef N_TYPE
    177       1.1     skrll #undef N_UNDF
    178       1.1     skrll #undef N_ABS
    179       1.1     skrll #undef N_TEXT
    180       1.1     skrll #undef N_DATA
    181       1.1     skrll #undef N_BSS
    182       1.1     skrll #undef N_REG
    183       1.1     skrll #undef N_FN
    184       1.1     skrll #undef N_EXT
    185   1.1.1.9  christos #undef N_STAB
    186       1.1     skrll #define N_TYPE		0x1f	/* Type mask.  */
    187       1.1     skrll #define N_UNDF		0x00	/* Undefined.  */
    188       1.1     skrll #define N_ABS		0x01	/* Absolute.  */
    189       1.1     skrll #define N_TEXT		0x02	/* Text segment.  */
    190       1.1     skrll #define N_DATA		0x03	/* Data segment.  */
    191       1.1     skrll #define N_BSS		0x04	/* Bss segment.  */
    192       1.1     skrll #define N_REG		0x14	/* Register symbol.  */
    193       1.1     skrll #define N_FN		0x1f	/* File name.  */
    194       1.1     skrll #define N_EXT		0x20	/* External flag.  */
    195   1.1.1.9  christos /* Type numbers from .stab entries that could conflict:
    196   1.1.1.9  christos 	N_GSYM		0x20	   Global variable [conflict with external undef]
    197   1.1.1.9  christos 	N_FNAME		0x22	   Function name (for BSD Fortran) [ignored]
    198   1.1.1.9  christos 	N_FUN		0x24	   Function name [conflict with external BSS]
    199   1.1.1.9  christos 	N_NOMAP		0x34	   No DST map for sym. [ext. reg. doesn't exist]
    200   1.1.1.9  christos */
    201       1.1     skrll 
    202       1.1     skrll #define RELOC_SIZE 2
    203       1.1     skrll 
    204       1.1     skrll #define RELFLG		0x0001	/* PC-relative flag.  */
    205       1.1     skrll #define RTYPE		0x000e	/* Type mask.  */
    206       1.1     skrll #define RIDXMASK	0xfff0	/* Index mask.  */
    207       1.1     skrll 
    208       1.1     skrll #define RABS		0x00	/* Absolute.  */
    209       1.1     skrll #define RTEXT		0x02	/* Text.  */
    210       1.1     skrll #define RDATA		0x04	/* Data.  */
    211       1.1     skrll #define RBSS		0x06	/* Bss.  */
    212       1.1     skrll #define REXT		0x08	/* External.  */
    213       1.1     skrll 
    214       1.1     skrll #define RINDEX(x)	(((x) & 0xfff0) >> 4)
    215       1.1     skrll 
    216       1.1     skrll #ifndef MY_final_link_relocate
    217       1.1     skrll #define MY_final_link_relocate _bfd_final_link_relocate
    218       1.1     skrll #endif
    219       1.1     skrll 
    220       1.1     skrll #ifndef MY_relocate_contents
    221       1.1     skrll #define MY_relocate_contents _bfd_relocate_contents
    222       1.1     skrll #endif
    223       1.1     skrll 
    224       1.1     skrll /* A hash table used for header files with N_BINCL entries.  */
    225       1.1     skrll 
    226       1.1     skrll struct aout_link_includes_table
    227       1.1     skrll {
    228       1.1     skrll   struct bfd_hash_table root;
    229       1.1     skrll };
    230       1.1     skrll 
    231       1.1     skrll /* A linked list of totals that we have found for a particular header
    232       1.1     skrll    file.  */
    233       1.1     skrll 
    234       1.1     skrll struct aout_link_includes_totals
    235       1.1     skrll {
    236       1.1     skrll   struct aout_link_includes_totals *next;
    237       1.1     skrll   bfd_vma total;
    238       1.1     skrll };
    239       1.1     skrll 
    240       1.1     skrll /* An entry in the header file hash table.  */
    241       1.1     skrll 
    242       1.1     skrll struct aout_link_includes_entry
    243       1.1     skrll {
    244       1.1     skrll   struct bfd_hash_entry root;
    245       1.1     skrll   /* List of totals we have found for this file.  */
    246       1.1     skrll   struct aout_link_includes_totals *totals;
    247       1.1     skrll };
    248       1.1     skrll 
    249       1.1     skrll /* During the final link step we need to pass around a bunch of
    250       1.1     skrll    information, so we do it in an instance of this structure.  */
    251       1.1     skrll 
    252       1.1     skrll struct aout_final_link_info
    253       1.1     skrll {
    254       1.1     skrll   /* General link information.  */
    255       1.1     skrll   struct bfd_link_info *info;
    256       1.1     skrll   /* Output bfd.  */
    257       1.1     skrll   bfd *output_bfd;
    258       1.1     skrll   /* Reloc file positions.  */
    259       1.1     skrll   file_ptr treloff, dreloff;
    260       1.1     skrll   /* File position of symbols.  */
    261       1.1     skrll   file_ptr symoff;
    262       1.1     skrll   /* String table.  */
    263       1.1     skrll   struct bfd_strtab_hash *strtab;
    264       1.1     skrll   /* Header file hash table.  */
    265       1.1     skrll   struct aout_link_includes_table includes;
    266       1.1     skrll   /* A buffer large enough to hold the contents of any section.  */
    267       1.1     skrll   bfd_byte *contents;
    268       1.1     skrll   /* A buffer large enough to hold the relocs of any section.  */
    269       1.1     skrll   void * relocs;
    270       1.1     skrll   /* A buffer large enough to hold the symbol map of any input BFD.  */
    271       1.1     skrll   int *symbol_map;
    272       1.1     skrll   /* A buffer large enough to hold output symbols of any input BFD.  */
    273       1.1     skrll   struct external_nlist *output_syms;
    274       1.1     skrll };
    275       1.1     skrll 
    276   1.1.1.9  christos /* Copy of the link_info.separate_code boolean to select the output format with
    277   1.1.1.9  christos    separate instruction and data spaces selected by --imagic */
    278   1.1.1.9  christos static bool separate_i_d = false;
    279   1.1.1.9  christos 
    280       1.1     skrll reloc_howto_type howto_table_pdp11[] =
    281       1.1     skrll {
    282   1.1.1.6  christos   /* type	       rs size bsz  pcrel bitpos ovrf			  sf name     part_inpl readmask  setmask    pcdone */
    283  1.1.1.10  christos HOWTO( 0,	       0,  2,  16,  false, 0, complain_overflow_dont,0,"16",	true, 0x0000ffff,0x0000ffff, false),
    284  1.1.1.10  christos HOWTO( 1,	       0,  2,  16,  true,  0, complain_overflow_dont,0,"DISP16",	true, 0x0000ffff,0x0000ffff, false),
    285  1.1.1.10  christos HOWTO( 2,	       0,  4,  32,  false, 0, complain_overflow_dont,0,"32",	true, 0x0000ffff,0x0000ffff, false),
    286       1.1     skrll };
    287       1.1     skrll 
    288       1.1     skrll #define TABLE_SIZE(TABLE)	(sizeof(TABLE)/sizeof(TABLE[0]))
    289       1.1     skrll 
    290       1.1     skrll 
    291   1.1.1.9  christos static bool aout_link_check_archive_element (bfd *, struct bfd_link_info *,
    292   1.1.1.9  christos 					     struct bfd_link_hash_entry *,
    293   1.1.1.9  christos 					     const char *, bool *);
    294   1.1.1.9  christos static bool aout_link_add_object_symbols (bfd *, struct bfd_link_info *);
    295   1.1.1.9  christos static bool aout_link_add_symbols (bfd *, struct bfd_link_info *);
    296   1.1.1.9  christos static bool aout_link_write_symbols (struct aout_final_link_info *, bfd *);
    297       1.1     skrll 
    298       1.1     skrll 
    299       1.1     skrll reloc_howto_type *
    300       1.1     skrll NAME (aout, reloc_type_lookup) (bfd * abfd ATTRIBUTE_UNUSED,
    301       1.1     skrll 				bfd_reloc_code_real_type code)
    302       1.1     skrll {
    303       1.1     skrll   switch (code)
    304       1.1     skrll     {
    305       1.1     skrll     case BFD_RELOC_16:
    306       1.1     skrll       return &howto_table_pdp11[0];
    307       1.1     skrll     case BFD_RELOC_16_PCREL:
    308       1.1     skrll       return &howto_table_pdp11[1];
    309   1.1.1.9  christos     case BFD_RELOC_32:
    310   1.1.1.9  christos       return &howto_table_pdp11[2];
    311       1.1     skrll     default:
    312       1.1     skrll       return NULL;
    313       1.1     skrll     }
    314       1.1     skrll }
    315       1.1     skrll 
    316       1.1     skrll reloc_howto_type *
    317       1.1     skrll NAME (aout, reloc_name_lookup) (bfd *abfd ATTRIBUTE_UNUSED,
    318       1.1     skrll 				      const char *r_name)
    319       1.1     skrll {
    320       1.1     skrll   unsigned int i;
    321       1.1     skrll 
    322       1.1     skrll   for (i = 0;
    323       1.1     skrll        i < sizeof (howto_table_pdp11) / sizeof (howto_table_pdp11[0]);
    324       1.1     skrll        i++)
    325       1.1     skrll     if (howto_table_pdp11[i].name != NULL
    326       1.1     skrll 	&& strcasecmp (howto_table_pdp11[i].name, r_name) == 0)
    327       1.1     skrll       return &howto_table_pdp11[i];
    328       1.1     skrll 
    329       1.1     skrll   return NULL;
    330       1.1     skrll }
    331       1.1     skrll 
    332   1.1.1.9  christos /* Disambiguate conflicts between normal symbol types and .stab symbol types
    333   1.1.1.9  christos    (undefined externals N_UNDF+N_EXT vs. global variables N_GYSM and external
    334   1.1.1.9  christos    bss symbols N_BSS+N_EXT vs. function names N_FUN) with a hack to look for
    335   1.1.1.9  christos    the ':' in the global variable or function name string.  */
    336   1.1.1.9  christos 
    337   1.1.1.9  christos static int
    338   1.1.1.9  christos is_stab (int type, const char *name)
    339   1.1.1.9  christos {
    340   1.1.1.9  christos   if (type == N_GSYM || type == N_FUN)
    341   1.1.1.9  christos     return strchr (name, ':') != NULL;
    342   1.1.1.9  christos   return type > N_FUN;
    343   1.1.1.9  christos }
    344   1.1.1.9  christos 
    345       1.1     skrll static int
    346       1.1     skrll pdp11_aout_write_headers (bfd *abfd, struct internal_exec *execp)
    347       1.1     skrll {
    348       1.1     skrll   struct external_exec exec_bytes;
    349       1.1     skrll 
    350       1.1     skrll   if (adata(abfd).magic == undecided_magic)
    351   1.1.1.5  christos     NAME (aout, adjust_sizes_and_vmas) (abfd);
    352       1.1     skrll 
    353       1.1     skrll   execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;
    354       1.1     skrll   execp->a_entry = bfd_get_start_address (abfd);
    355       1.1     skrll 
    356       1.1     skrll   if (obj_textsec (abfd)->reloc_count > 0
    357       1.1     skrll       || obj_datasec (abfd)->reloc_count > 0)
    358       1.1     skrll     {
    359       1.1     skrll       execp->a_trsize = execp->a_text;
    360       1.1     skrll       execp->a_drsize = execp->a_data;
    361       1.1     skrll     }
    362       1.1     skrll   else
    363       1.1     skrll     {
    364       1.1     skrll       execp->a_trsize = 0;
    365       1.1     skrll       execp->a_drsize = 0;
    366       1.1     skrll     }
    367       1.1     skrll 
    368  1.1.1.11  christos   if (!NAME (aout, swap_exec_header_out) (abfd, execp, & exec_bytes))
    369  1.1.1.11  christos     return false;
    370       1.1     skrll 
    371  1.1.1.10  christos   if (bfd_seek (abfd, 0, SEEK_SET) != 0)
    372   1.1.1.9  christos     return false;
    373       1.1     skrll 
    374  1.1.1.10  christos   if (bfd_write (&exec_bytes, EXEC_BYTES_SIZE, abfd) != EXEC_BYTES_SIZE)
    375   1.1.1.9  christos     return false;
    376       1.1     skrll 
    377       1.1     skrll   /* Now write out reloc info, followed by syms and strings.  */
    378       1.1     skrll   if (bfd_get_outsymbols (abfd) != NULL
    379       1.1     skrll       && bfd_get_symcount (abfd) != 0)
    380       1.1     skrll     {
    381  1.1.1.10  christos       if (bfd_seek (abfd, N_SYMOFF (execp), SEEK_SET) != 0)
    382   1.1.1.9  christos 	return false;
    383       1.1     skrll 
    384       1.1     skrll       if (! NAME (aout, write_syms) (abfd))
    385   1.1.1.9  christos 	return false;
    386       1.1     skrll     }
    387       1.1     skrll 
    388       1.1     skrll   if (obj_textsec (abfd)->reloc_count > 0
    389       1.1     skrll       || obj_datasec (abfd)->reloc_count > 0)
    390       1.1     skrll     {
    391  1.1.1.10  christos       if (bfd_seek (abfd, N_TRELOFF (execp), SEEK_SET) != 0
    392       1.1     skrll 	  || !NAME (aout, squirt_out_relocs) (abfd, obj_textsec (abfd))
    393  1.1.1.10  christos 	  || bfd_seek (abfd, N_DRELOFF (execp), SEEK_SET) != 0
    394   1.1.1.4  christos 	  || !NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd)))
    395   1.1.1.9  christos 	return false;
    396       1.1     skrll     }
    397       1.1     skrll 
    398   1.1.1.9  christos   return true;
    399       1.1     skrll }
    400       1.1     skrll 
    401       1.1     skrll /* Write an object file.
    402       1.1     skrll    Section contents have already been written.  We write the
    403       1.1     skrll    file header, symbols, and relocation.  */
    404       1.1     skrll 
    405   1.1.1.9  christos static bool
    406       1.1     skrll MY(write_object_contents) (bfd *abfd)
    407       1.1     skrll {
    408       1.1     skrll   struct internal_exec *execp = exec_hdr (abfd);
    409       1.1     skrll 
    410       1.1     skrll   /* We must make certain that the magic number has been set.  This
    411       1.1     skrll      will normally have been done by set_section_contents, but only if
    412       1.1     skrll      there actually are some section contents.  */
    413       1.1     skrll   if (! abfd->output_has_begun)
    414   1.1.1.5  christos     NAME (aout, adjust_sizes_and_vmas) (abfd);
    415       1.1     skrll 
    416       1.1     skrll   obj_reloc_entry_size (abfd) = RELOC_SIZE;
    417       1.1     skrll 
    418       1.1     skrll   return WRITE_HEADERS (abfd, execp);
    419       1.1     skrll }
    420       1.1     skrll 
    421       1.1     skrll /* Swap the information in an executable header @var{raw_bytes} taken
    422       1.1     skrll    from a raw byte stream memory image into the internal exec header
    423       1.1     skrll    structure "execp".  */
    424       1.1     skrll 
    425       1.1     skrll #ifndef NAME_swap_exec_header_in
    426       1.1     skrll void
    427       1.1     skrll NAME (aout, swap_exec_header_in) (bfd *abfd,
    428       1.1     skrll 				  struct external_exec *bytes,
    429       1.1     skrll 				  struct internal_exec *execp)
    430       1.1     skrll {
    431       1.1     skrll   /* The internal_exec structure has some fields that are unused in this
    432       1.1     skrll      configuration (IE for i960), so ensure that all such uninitialized
    433       1.1     skrll      fields are zero'd out.  There are places where two of these structs
    434       1.1     skrll      are memcmp'd, and thus the contents do matter.  */
    435       1.1     skrll   memset ((void *) execp, 0, sizeof (struct internal_exec));
    436       1.1     skrll   /* Now fill in fields in the execp, from the bytes in the raw data.  */
    437       1.1     skrll   execp->a_info   = GET_MAGIC (abfd, bytes->e_info);
    438       1.1     skrll   execp->a_text   = GET_WORD (abfd, bytes->e_text);
    439       1.1     skrll   execp->a_data   = GET_WORD (abfd, bytes->e_data);
    440       1.1     skrll   execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
    441       1.1     skrll   execp->a_syms   = GET_WORD (abfd, bytes->e_syms);
    442       1.1     skrll   execp->a_entry  = GET_WORD (abfd, bytes->e_entry);
    443       1.1     skrll 
    444       1.1     skrll   if (GET_WORD (abfd, bytes->e_flag) & A_FLAG_RELOC_STRIPPED)
    445       1.1     skrll     {
    446       1.1     skrll       execp->a_trsize = 0;
    447       1.1     skrll       execp->a_drsize = 0;
    448       1.1     skrll     }
    449       1.1     skrll   else
    450       1.1     skrll     {
    451       1.1     skrll       execp->a_trsize = execp->a_text;
    452       1.1     skrll       execp->a_drsize = execp->a_data;
    453       1.1     skrll     }
    454       1.1     skrll }
    455       1.1     skrll #define NAME_swap_exec_header_in NAME (aout, swap_exec_header_in)
    456       1.1     skrll #endif
    457       1.1     skrll 
    458       1.1     skrll /*  Swap the information in an internal exec header structure
    459       1.1     skrll     "execp" into the buffer "bytes" ready for writing to disk.  */
    460  1.1.1.11  christos bool
    461       1.1     skrll NAME (aout, swap_exec_header_out) (bfd *abfd,
    462       1.1     skrll 				   struct internal_exec *execp,
    463       1.1     skrll 				   struct external_exec *bytes)
    464       1.1     skrll {
    465  1.1.1.11  christos   const char *err = NULL;
    466  1.1.1.11  christos   uint64_t val;
    467  1.1.1.11  christos #define MAXVAL(x) ((UINT64_C (1) << (8 * sizeof (x) - 1) << 1) - 1)
    468  1.1.1.11  christos   if ((val = execp->a_text) > MAXVAL (bytes->e_text))
    469  1.1.1.11  christos     err = "e_text";
    470  1.1.1.11  christos   else if ((val = execp->a_data) > MAXVAL (bytes->e_data))
    471  1.1.1.11  christos     err = "e_data";
    472  1.1.1.11  christos   else if ((val = execp->a_bss) > MAXVAL (bytes->e_bss))
    473  1.1.1.11  christos     err = "e_bss";
    474  1.1.1.11  christos   else if ((val = execp->a_syms) > MAXVAL (bytes->e_syms))
    475  1.1.1.11  christos     err = "e_syms";
    476  1.1.1.11  christos   else if ((val = execp->a_entry) > MAXVAL (bytes->e_entry))
    477  1.1.1.11  christos     err = "e_entry";
    478  1.1.1.11  christos #undef MAXVAL
    479  1.1.1.11  christos   if (err)
    480  1.1.1.11  christos     {
    481  1.1.1.11  christos       _bfd_error_handler (_("%pB: %#" PRIx64 " overflows header %s field"),
    482  1.1.1.11  christos 			  abfd, val, err);
    483  1.1.1.11  christos       bfd_set_error (bfd_error_file_too_big);
    484  1.1.1.11  christos       return false;
    485  1.1.1.11  christos     }
    486  1.1.1.11  christos 
    487       1.1     skrll   /* Now fill in fields in the raw data, from the fields in the exec struct.  */
    488       1.1     skrll   PUT_MAGIC (abfd, execp->a_info,		bytes->e_info);
    489       1.1     skrll   PUT_WORD (abfd, execp->a_text,		bytes->e_text);
    490       1.1     skrll   PUT_WORD (abfd, execp->a_data,		bytes->e_data);
    491       1.1     skrll   PUT_WORD (abfd, execp->a_bss,			bytes->e_bss);
    492       1.1     skrll   PUT_WORD (abfd, execp->a_syms,		bytes->e_syms);
    493       1.1     skrll   PUT_WORD (abfd, execp->a_entry,		bytes->e_entry);
    494       1.1     skrll   PUT_WORD (abfd, 0,				bytes->e_unused);
    495       1.1     skrll 
    496       1.1     skrll   if ((execp->a_trsize == 0 || execp->a_text == 0)
    497       1.1     skrll       && (execp->a_drsize == 0 || execp->a_data == 0))
    498       1.1     skrll     PUT_WORD (abfd, A_FLAG_RELOC_STRIPPED, bytes->e_flag);
    499       1.1     skrll   else if (execp->a_trsize == execp->a_text
    500       1.1     skrll 	   && execp->a_drsize == execp->a_data)
    501       1.1     skrll     PUT_WORD (abfd, 0, bytes->e_flag);
    502       1.1     skrll   else
    503       1.1     skrll     {
    504       1.1     skrll       /* TODO: print a proper warning message.  */
    505       1.1     skrll       fprintf (stderr, "BFD:%s:%d: internal error\n", __FILE__, __LINE__);
    506       1.1     skrll       PUT_WORD (abfd, 0,			bytes->e_flag);
    507       1.1     skrll     }
    508  1.1.1.11  christos   return true;
    509       1.1     skrll }
    510       1.1     skrll 
    511       1.1     skrll /* Make all the section for an a.out file.  */
    512       1.1     skrll 
    513   1.1.1.9  christos bool
    514       1.1     skrll NAME (aout, make_sections) (bfd *abfd)
    515       1.1     skrll {
    516       1.1     skrll   if (obj_textsec (abfd) == NULL && bfd_make_section (abfd, ".text") == NULL)
    517   1.1.1.9  christos     return false;
    518       1.1     skrll   if (obj_datasec (abfd) == NULL && bfd_make_section (abfd, ".data") == NULL)
    519   1.1.1.9  christos     return false;
    520       1.1     skrll   if (obj_bsssec (abfd) == NULL  && bfd_make_section (abfd, ".bss") == NULL)
    521   1.1.1.9  christos     return false;
    522   1.1.1.9  christos   return true;
    523       1.1     skrll }
    524       1.1     skrll 
    525       1.1     skrll /* Some a.out variant thinks that the file open in ABFD
    526       1.1     skrll    checking is an a.out file.  Do some more checking, and set up
    527       1.1     skrll    for access if it really is.  Call back to the calling
    528       1.1     skrll    environment's "finish up" function just before returning, to
    529       1.1     skrll    handle any last-minute setup.  */
    530       1.1     skrll 
    531   1.1.1.9  christos bfd_cleanup
    532       1.1     skrll NAME (aout, some_aout_object_p) (bfd *abfd,
    533       1.1     skrll 				 struct internal_exec *execp,
    534   1.1.1.9  christos 				 bfd_cleanup (*callback_to_real_object_p) (bfd *))
    535       1.1     skrll {
    536  1.1.1.11  christos   struct aout_data_struct *rawptr;
    537  1.1.1.11  christos   bfd_cleanup result;
    538  1.1.1.11  christos   size_t amt = sizeof (*rawptr);
    539       1.1     skrll 
    540       1.1     skrll   rawptr = bfd_zalloc (abfd, amt);
    541       1.1     skrll   if (rawptr == NULL)
    542  1.1.1.11  christos     return NULL;
    543       1.1     skrll   abfd->tdata.aout_data = rawptr;
    544       1.1     skrll 
    545       1.1     skrll   abfd->tdata.aout_data->a.hdr = &rawptr->e;
    546  1.1.1.11  christos   /* Copy in the internal_exec struct.  */
    547  1.1.1.11  christos   *(abfd->tdata.aout_data->a.hdr) = *execp;
    548       1.1     skrll   execp = abfd->tdata.aout_data->a.hdr;
    549       1.1     skrll 
    550       1.1     skrll   /* Set the file flags.  */
    551       1.1     skrll   abfd->flags = BFD_NO_FLAGS;
    552       1.1     skrll   if (execp->a_drsize || execp->a_trsize)
    553       1.1     skrll     abfd->flags |= HAS_RELOC;
    554       1.1     skrll   /* Setting of EXEC_P has been deferred to the bottom of this function.  */
    555       1.1     skrll   if (execp->a_syms)
    556       1.1     skrll     abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
    557   1.1.1.5  christos   if (N_DYNAMIC (execp))
    558       1.1     skrll     abfd->flags |= DYNAMIC;
    559       1.1     skrll 
    560   1.1.1.5  christos   if (N_MAGIC (execp) == ZMAGIC)
    561       1.1     skrll     {
    562       1.1     skrll       abfd->flags |= D_PAGED | WP_TEXT;
    563       1.1     skrll       adata (abfd).magic = z_magic;
    564       1.1     skrll     }
    565   1.1.1.5  christos   else if (N_MAGIC (execp) == NMAGIC)
    566       1.1     skrll     {
    567       1.1     skrll       abfd->flags |= WP_TEXT;
    568       1.1     skrll       adata (abfd).magic = n_magic;
    569       1.1     skrll     }
    570   1.1.1.5  christos   else if (N_MAGIC (execp) == OMAGIC)
    571       1.1     skrll     adata (abfd).magic = o_magic;
    572   1.1.1.9  christos   else if (N_MAGIC (execp) == IMAGIC)
    573   1.1.1.9  christos     adata (abfd).magic = i_magic;
    574       1.1     skrll   else
    575       1.1     skrll     {
    576       1.1     skrll       /* Should have been checked with N_BADMAG before this routine
    577       1.1     skrll 	 was called.  */
    578       1.1     skrll       abort ();
    579       1.1     skrll     }
    580       1.1     skrll 
    581   1.1.1.8  christos   abfd->start_address = execp->a_entry;
    582       1.1     skrll 
    583   1.1.1.8  christos   abfd->symcount = execp->a_syms / sizeof (struct external_nlist);
    584       1.1     skrll 
    585       1.1     skrll   /* The default relocation entry size is that of traditional V7 Unix.  */
    586       1.1     skrll   obj_reloc_entry_size (abfd) = RELOC_SIZE;
    587       1.1     skrll 
    588       1.1     skrll   /* The default symbol entry size is that of traditional Unix.  */
    589       1.1     skrll   obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
    590       1.1     skrll 
    591       1.1     skrll   if (! NAME (aout, make_sections) (abfd))
    592  1.1.1.11  christos     goto error_ret;
    593       1.1     skrll 
    594       1.1     skrll   obj_datasec (abfd)->size = execp->a_data;
    595       1.1     skrll   obj_bsssec (abfd)->size = execp->a_bss;
    596       1.1     skrll 
    597       1.1     skrll   obj_textsec (abfd)->flags =
    598       1.1     skrll     (execp->a_trsize != 0
    599       1.1     skrll      ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
    600       1.1     skrll      : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
    601       1.1     skrll   obj_datasec (abfd)->flags =
    602       1.1     skrll     (execp->a_drsize != 0
    603       1.1     skrll      ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
    604       1.1     skrll      : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
    605       1.1     skrll   obj_bsssec (abfd)->flags = SEC_ALLOC;
    606       1.1     skrll 
    607       1.1     skrll #ifdef THIS_IS_ONLY_DOCUMENTATION
    608       1.1     skrll   /* The common code can't fill in these things because they depend
    609       1.1     skrll      on either the start address of the text segment, the rounding
    610       1.1     skrll      up of virtual addresses between segments, or the starting file
    611       1.1     skrll      position of the text segment -- all of which varies among different
    612       1.1     skrll      versions of a.out.  */
    613       1.1     skrll 
    614       1.1     skrll   /* Call back to the format-dependent code to fill in the rest of the
    615       1.1     skrll      fields and do any further cleanup.  Things that should be filled
    616       1.1     skrll      in by the callback:  */
    617       1.1     skrll   struct exec *execp = exec_hdr (abfd);
    618       1.1     skrll 
    619   1.1.1.5  christos   obj_textsec (abfd)->size = N_TXTSIZE (execp);
    620       1.1     skrll   /* Data and bss are already filled in since they're so standard.  */
    621       1.1     skrll 
    622       1.1     skrll   /* The virtual memory addresses of the sections.  */
    623   1.1.1.5  christos   obj_textsec (abfd)->vma = N_TXTADDR (execp);
    624   1.1.1.5  christos   obj_datasec (abfd)->vma = N_DATADDR (execp);
    625   1.1.1.5  christos   obj_bsssec  (abfd)->vma = N_BSSADDR (execp);
    626       1.1     skrll 
    627       1.1     skrll   /* The file offsets of the sections.  */
    628   1.1.1.5  christos   obj_textsec (abfd)->filepos = N_TXTOFF (execp);
    629   1.1.1.5  christos   obj_datasec (abfd)->filepos = N_DATOFF (execp);
    630       1.1     skrll 
    631       1.1     skrll   /* The file offsets of the relocation info.  */
    632   1.1.1.5  christos   obj_textsec (abfd)->rel_filepos = N_TRELOFF (execp);
    633   1.1.1.5  christos   obj_datasec (abfd)->rel_filepos = N_DRELOFF (execp);
    634       1.1     skrll 
    635       1.1     skrll   /* The file offsets of the string table and symbol table.  */
    636   1.1.1.5  christos   obj_str_filepos (abfd) = N_STROFF (execp);
    637   1.1.1.5  christos   obj_sym_filepos (abfd) = N_SYMOFF (execp);
    638       1.1     skrll 
    639       1.1     skrll   /* Determine the architecture and machine type of the object file.  */
    640       1.1     skrll   abfd->obj_arch = bfd_arch_obscure;
    641       1.1     skrll 
    642  1.1.1.11  christos   adata (abfd)->page_size = TARGET_PAGE_SIZE;
    643  1.1.1.11  christos   adata (abfd)->segment_size = SEGMENT_SIZE;
    644  1.1.1.11  christos   adata (abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
    645       1.1     skrll 
    646   1.1.1.9  christos   return _bfd_no_cleanup;
    647       1.1     skrll 
    648       1.1     skrll   /* The architecture is encoded in various ways in various a.out variants,
    649       1.1     skrll      or is not encoded at all in some of them.  The relocation size depends
    650       1.1     skrll      on the architecture and the a.out variant.  Finally, the return value
    651       1.1     skrll      is the bfd_target vector in use.  If an error occurs, return zero and
    652       1.1     skrll      set bfd_error to the appropriate error code.
    653       1.1     skrll 
    654       1.1     skrll      Formats such as b.out, which have additional fields in the a.out
    655       1.1     skrll      header, should cope with them in this callback as well.  */
    656       1.1     skrll #endif	/* DOCUMENTATION */
    657       1.1     skrll 
    658  1.1.1.11  christos   result = (*callback_to_real_object_p) (abfd);
    659       1.1     skrll 
    660       1.1     skrll   /* Now that the segment addresses have been worked out, take a better
    661       1.1     skrll      guess at whether the file is executable.  If the entry point
    662       1.1     skrll      is within the text segment, assume it is.  (This makes files
    663       1.1     skrll      executable even if their entry point address is 0, as long as
    664       1.1     skrll      their text starts at zero.).
    665       1.1     skrll 
    666       1.1     skrll      This test had to be changed to deal with systems where the text segment
    667       1.1     skrll      runs at a different location than the default.  The problem is that the
    668       1.1     skrll      entry address can appear to be outside the text segment, thus causing an
    669       1.1     skrll      erroneous conclusion that the file isn't executable.
    670       1.1     skrll 
    671       1.1     skrll      To fix this, we now accept any non-zero entry point as an indication of
    672       1.1     skrll      executability.  This will work most of the time, since only the linker
    673  1.1.1.11  christos      sets the entry point, and that is likely to be non-zero for most systems.  */
    674       1.1     skrll 
    675       1.1     skrll   if (execp->a_entry != 0
    676   1.1.1.9  christos       || (execp->a_entry >= obj_textsec (abfd)->vma
    677   1.1.1.9  christos 	  && execp->a_entry < (obj_textsec (abfd)->vma
    678   1.1.1.9  christos 			       + obj_textsec (abfd)->size)
    679   1.1.1.9  christos 	  && execp->a_trsize == 0
    680   1.1.1.9  christos 	  && execp->a_drsize == 0))
    681       1.1     skrll     abfd->flags |= EXEC_P;
    682       1.1     skrll #ifdef STAT_FOR_EXEC
    683       1.1     skrll   else
    684       1.1     skrll     {
    685       1.1     skrll       struct stat stat_buf;
    686       1.1     skrll 
    687       1.1     skrll       /* The original heuristic doesn't work in some important cases.
    688   1.1.1.6  christos 	The a.out file has no information about the text start
    689   1.1.1.6  christos 	address.  For files (like kernels) linked to non-standard
    690   1.1.1.6  christos 	addresses (ld -Ttext nnn) the entry point may not be between
    691   1.1.1.6  christos 	the default text start (obj_textsec(abfd)->vma) and
    692   1.1.1.6  christos 	(obj_textsec(abfd)->vma) + text size.  This is not just a mach
    693   1.1.1.6  christos 	issue.  Many kernels are loaded at non standard addresses.  */
    694       1.1     skrll       if (abfd->iostream != NULL
    695       1.1     skrll 	  && (abfd->flags & BFD_IN_MEMORY) == 0
    696  1.1.1.11  christos 	  && (fstat (fileno ((FILE *) (abfd->iostream)), &stat_buf) == 0)
    697       1.1     skrll 	  && ((stat_buf.st_mode & 0111) != 0))
    698       1.1     skrll 	abfd->flags |= EXEC_P;
    699       1.1     skrll     }
    700       1.1     skrll #endif /* STAT_FOR_EXEC */
    701       1.1     skrll 
    702  1.1.1.11  christos   if (result)
    703  1.1.1.11  christos     return result;
    704  1.1.1.11  christos 
    705  1.1.1.11  christos  error_ret:
    706  1.1.1.11  christos   bfd_release (abfd, rawptr);
    707  1.1.1.11  christos   return NULL;
    708       1.1     skrll }
    709       1.1     skrll 
    710       1.1     skrll /* Initialize ABFD for use with a.out files.  */
    711       1.1     skrll 
    712   1.1.1.9  christos bool
    713       1.1     skrll NAME (aout, mkobject) (bfd *abfd)
    714       1.1     skrll {
    715       1.1     skrll   struct aout_data_struct  *rawptr;
    716   1.1.1.9  christos   size_t amt = sizeof (struct aout_data_struct);
    717       1.1     skrll 
    718       1.1     skrll   bfd_set_error (bfd_error_system_call);
    719       1.1     skrll 
    720       1.1     skrll   /* Use an intermediate variable for clarity.  */
    721       1.1     skrll   rawptr = bfd_zalloc (abfd, amt);
    722       1.1     skrll 
    723       1.1     skrll   if (rawptr == NULL)
    724   1.1.1.9  christos     return false;
    725       1.1     skrll 
    726       1.1     skrll   abfd->tdata.aout_data = rawptr;
    727       1.1     skrll   exec_hdr (abfd) = &(rawptr->e);
    728       1.1     skrll 
    729       1.1     skrll   obj_textsec (abfd) = NULL;
    730       1.1     skrll   obj_datasec (abfd) = NULL;
    731       1.1     skrll   obj_bsssec (abfd)  = NULL;
    732       1.1     skrll 
    733   1.1.1.9  christos   return true;
    734       1.1     skrll }
    735       1.1     skrll 
    736       1.1     skrll /* Keep track of machine architecture and machine type for
    737       1.1     skrll    a.out's. Return the <<machine_type>> for a particular
    738       1.1     skrll    architecture and machine, or <<M_UNKNOWN>> if that exact architecture
    739       1.1     skrll    and machine can't be represented in a.out format.
    740       1.1     skrll 
    741       1.1     skrll    If the architecture is understood, machine type 0 (default)
    742       1.1     skrll    is always understood.  */
    743       1.1     skrll 
    744       1.1     skrll enum machine_type
    745       1.1     skrll NAME (aout, machine_type) (enum bfd_architecture arch,
    746       1.1     skrll 			   unsigned long machine,
    747   1.1.1.9  christos 			   bool *unknown)
    748       1.1     skrll {
    749       1.1     skrll   enum machine_type arch_flags;
    750       1.1     skrll 
    751       1.1     skrll   arch_flags = M_UNKNOWN;
    752   1.1.1.9  christos   *unknown = true;
    753       1.1     skrll 
    754       1.1     skrll   switch (arch)
    755       1.1     skrll     {
    756       1.1     skrll     case bfd_arch_sparc:
    757       1.1     skrll       if (machine == 0
    758       1.1     skrll 	  || machine == bfd_mach_sparc
    759       1.1     skrll 	  || machine == bfd_mach_sparc_sparclite
    760       1.1     skrll 	  || machine == bfd_mach_sparc_v9)
    761       1.1     skrll 	arch_flags = M_SPARC;
    762       1.1     skrll       else if (machine == bfd_mach_sparc_sparclet)
    763       1.1     skrll 	arch_flags = M_SPARCLET;
    764       1.1     skrll       break;
    765       1.1     skrll 
    766       1.1     skrll     case bfd_arch_i386:
    767       1.1     skrll       if (machine == 0
    768       1.1     skrll 	  || machine == bfd_mach_i386_i386
    769       1.1     skrll 	  || machine == bfd_mach_i386_i386_intel_syntax)
    770       1.1     skrll 	arch_flags = M_386;
    771       1.1     skrll       break;
    772       1.1     skrll 
    773       1.1     skrll     case bfd_arch_arm:
    774       1.1     skrll       if (machine == 0)	arch_flags = M_ARM;
    775       1.1     skrll       break;
    776       1.1     skrll 
    777       1.1     skrll     case bfd_arch_mips:
    778       1.1     skrll       switch (machine)
    779       1.1     skrll 	{
    780       1.1     skrll 	case 0:
    781       1.1     skrll 	case 2000:
    782       1.1     skrll 	case bfd_mach_mips3000:
    783   1.1.1.6  christos 	  arch_flags = M_MIPS1;
    784       1.1     skrll 	  break;
    785       1.1     skrll 	case bfd_mach_mips4000: /* MIPS3 */
    786       1.1     skrll 	case bfd_mach_mips4400:
    787       1.1     skrll 	case bfd_mach_mips8000: /* MIPS4 */
    788       1.1     skrll 	case bfd_mach_mips6000: /* Real MIPS2: */
    789   1.1.1.6  christos 	  arch_flags = M_MIPS2;
    790       1.1     skrll 	  break;
    791       1.1     skrll 	default:
    792       1.1     skrll 	  arch_flags = M_UNKNOWN;
    793       1.1     skrll 	  break;
    794       1.1     skrll 	}
    795       1.1     skrll       break;
    796       1.1     skrll 
    797       1.1     skrll     case bfd_arch_ns32k:
    798       1.1     skrll       switch (machine)
    799       1.1     skrll 	{
    800   1.1.1.6  christos 	case 0:			arch_flags = M_NS32532; break;
    801       1.1     skrll 	case 32032:		arch_flags = M_NS32032; break;
    802       1.1     skrll 	case 32532:		arch_flags = M_NS32532; break;
    803       1.1     skrll 	default:		arch_flags = M_UNKNOWN; break;
    804       1.1     skrll 	}
    805       1.1     skrll       break;
    806       1.1     skrll 
    807       1.1     skrll     case bfd_arch_pdp11:
    808       1.1     skrll       /* TODO: arch_flags = M_PDP11; */
    809   1.1.1.9  christos       *unknown = false;
    810       1.1     skrll       break;
    811       1.1     skrll 
    812       1.1     skrll     case bfd_arch_vax:
    813   1.1.1.9  christos       *unknown = false;
    814       1.1     skrll       break;
    815       1.1     skrll 
    816       1.1     skrll     default:
    817       1.1     skrll       arch_flags = M_UNKNOWN;
    818       1.1     skrll     }
    819       1.1     skrll 
    820       1.1     skrll   if (arch_flags != M_UNKNOWN)
    821   1.1.1.9  christos     *unknown = false;
    822       1.1     skrll 
    823       1.1     skrll   return arch_flags;
    824       1.1     skrll }
    825       1.1     skrll 
    826       1.1     skrll /* Set the architecture and the machine of the ABFD to the
    827       1.1     skrll    values ARCH and MACHINE.  Verify that @ABFD's format
    828       1.1     skrll    can support the architecture required.  */
    829       1.1     skrll 
    830   1.1.1.9  christos bool
    831       1.1     skrll NAME (aout, set_arch_mach) (bfd *abfd,
    832       1.1     skrll 			    enum bfd_architecture arch,
    833       1.1     skrll 			    unsigned long machine)
    834       1.1     skrll {
    835       1.1     skrll   if (! bfd_default_set_arch_mach (abfd, arch, machine))
    836   1.1.1.9  christos     return false;
    837       1.1     skrll 
    838       1.1     skrll   if (arch != bfd_arch_unknown)
    839       1.1     skrll     {
    840   1.1.1.9  christos       bool unknown;
    841       1.1     skrll 
    842       1.1     skrll       NAME (aout, machine_type) (arch, machine, &unknown);
    843       1.1     skrll       if (unknown)
    844   1.1.1.9  christos 	return false;
    845       1.1     skrll     }
    846       1.1     skrll 
    847       1.1     skrll   obj_reloc_entry_size (abfd) = RELOC_SIZE;
    848       1.1     skrll 
    849       1.1     skrll   return (*aout_backend_info(abfd)->set_sizes) (abfd);
    850       1.1     skrll }
    851       1.1     skrll 
    852       1.1     skrll static void
    853       1.1     skrll adjust_o_magic (bfd *abfd, struct internal_exec *execp)
    854       1.1     skrll {
    855       1.1     skrll   file_ptr pos = adata (abfd).exec_bytes_size;
    856       1.1     skrll   bfd_vma vma = 0;
    857       1.1     skrll   int pad = 0;
    858   1.1.1.9  christos   asection *text = obj_textsec (abfd);
    859   1.1.1.9  christos   asection *data = obj_datasec (abfd);
    860   1.1.1.9  christos   asection *bss = obj_bsssec (abfd);
    861       1.1     skrll 
    862       1.1     skrll   /* Text.  */
    863   1.1.1.9  christos   text->filepos = pos;
    864   1.1.1.9  christos   if (!text->user_set_vma)
    865   1.1.1.9  christos     text->vma = vma;
    866       1.1     skrll   else
    867   1.1.1.9  christos     vma = text->vma;
    868       1.1     skrll 
    869   1.1.1.9  christos   pos += execp->a_text;
    870   1.1.1.9  christos   vma += execp->a_text;
    871       1.1     skrll 
    872       1.1     skrll   /* Data.  */
    873   1.1.1.9  christos   if (!data->user_set_vma)
    874       1.1     skrll     {
    875       1.1     skrll       pos += pad;
    876       1.1     skrll       vma += pad;
    877   1.1.1.9  christos       data->vma = vma;
    878       1.1     skrll     }
    879       1.1     skrll   else
    880   1.1.1.9  christos     vma = data->vma;
    881   1.1.1.9  christos   execp->a_text += pad;
    882   1.1.1.9  christos 
    883   1.1.1.9  christos   data->filepos = pos;
    884   1.1.1.9  christos   pos += data->size;
    885   1.1.1.9  christos   vma += data->size;
    886       1.1     skrll 
    887       1.1     skrll   /* BSS.  */
    888   1.1.1.9  christos   if (!bss->user_set_vma)
    889       1.1     skrll     {
    890       1.1     skrll       pos += pad;
    891       1.1     skrll       vma += pad;
    892   1.1.1.9  christos       bss->vma = vma;
    893       1.1     skrll     }
    894   1.1.1.9  christos   else if (data->size > 0 || bss->size > 0) /* PR25677: for objcopy --extract-symbol */
    895       1.1     skrll     {
    896       1.1     skrll       /* The VMA of the .bss section is set by the VMA of the
    897   1.1.1.6  christos 	 .data section plus the size of the .data section.  We may
    898   1.1.1.6  christos 	 need to add padding bytes to make this true.  */
    899   1.1.1.9  christos       pad = bss->vma - vma;
    900   1.1.1.9  christos       if (pad < 0)
    901   1.1.1.9  christos 	pad = 0;
    902   1.1.1.9  christos       pos += pad;
    903       1.1     skrll     }
    904   1.1.1.9  christos   execp->a_data = data->size + pad;
    905   1.1.1.9  christos   bss->filepos = pos;
    906   1.1.1.9  christos   execp->a_bss = bss->size;
    907       1.1     skrll 
    908   1.1.1.5  christos   N_SET_MAGIC (execp, OMAGIC);
    909       1.1     skrll }
    910       1.1     skrll 
    911       1.1     skrll static void
    912       1.1     skrll adjust_z_magic (bfd *abfd, struct internal_exec *execp)
    913       1.1     skrll {
    914       1.1     skrll   bfd_size_type data_pad, text_pad;
    915       1.1     skrll   file_ptr text_end;
    916       1.1     skrll   const struct aout_backend_data *abdp;
    917   1.1.1.9  christos   /* TRUE if text includes exec header.  */
    918   1.1.1.9  christos   bool ztih;
    919   1.1.1.9  christos   asection *text = obj_textsec (abfd);
    920   1.1.1.9  christos   asection *data = obj_datasec (abfd);
    921   1.1.1.9  christos   asection *bss = obj_bsssec (abfd);
    922       1.1     skrll 
    923       1.1     skrll   abdp = aout_backend_info (abfd);
    924       1.1     skrll 
    925       1.1     skrll   /* Text.  */
    926       1.1     skrll   ztih = (abdp != NULL
    927       1.1     skrll 	  && (abdp->text_includes_header
    928       1.1     skrll 	      || obj_aout_subformat (abfd) == q_magic_format));
    929   1.1.1.9  christos   text->filepos = (ztih
    930   1.1.1.9  christos 		   ? adata (abfd).exec_bytes_size
    931   1.1.1.9  christos 		   : adata (abfd).zmagic_disk_block_size);
    932   1.1.1.9  christos   if (!text->user_set_vma)
    933       1.1     skrll     {
    934       1.1     skrll       /* ?? Do we really need to check for relocs here?  */
    935   1.1.1.9  christos       text->vma = ((abfd->flags & HAS_RELOC)
    936   1.1.1.9  christos 		   ? 0
    937   1.1.1.9  christos 		   : (ztih
    938   1.1.1.9  christos 		      ? abdp->default_text_vma + adata (abfd).exec_bytes_size
    939   1.1.1.9  christos 		      : abdp->default_text_vma));
    940       1.1     skrll       text_pad = 0;
    941       1.1     skrll     }
    942       1.1     skrll   else
    943       1.1     skrll     {
    944       1.1     skrll       /* The .text section is being loaded at an unusual address.  We
    945   1.1.1.6  christos 	 may need to pad it such that the .data section starts at a page
    946   1.1.1.6  christos 	 boundary.  */
    947       1.1     skrll       if (ztih)
    948   1.1.1.9  christos 	text_pad = ((text->filepos - text->vma)
    949       1.1     skrll 		    & (adata (abfd).page_size - 1));
    950       1.1     skrll       else
    951   1.1.1.9  christos 	text_pad = (-text->vma
    952       1.1     skrll 		    & (adata (abfd).page_size - 1));
    953       1.1     skrll     }
    954       1.1     skrll 
    955       1.1     skrll   /* Find start of data.  */
    956       1.1     skrll   if (ztih)
    957       1.1     skrll     {
    958   1.1.1.9  christos       text_end = text->filepos + execp->a_text;
    959       1.1     skrll       text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
    960       1.1     skrll     }
    961       1.1     skrll   else
    962       1.1     skrll     {
    963       1.1     skrll       /* Note that if page_size == zmagic_disk_block_size, then
    964       1.1     skrll 	 filepos == page_size, and this case is the same as the ztih
    965       1.1     skrll 	 case.  */
    966   1.1.1.9  christos       text_end = execp->a_text;
    967       1.1     skrll       text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
    968   1.1.1.9  christos       text_end += text->filepos;
    969       1.1     skrll     }
    970   1.1.1.9  christos   execp->a_text += text_pad;
    971       1.1     skrll 
    972       1.1     skrll   /* Data.  */
    973   1.1.1.9  christos   if (!data->user_set_vma)
    974       1.1     skrll     {
    975       1.1     skrll       bfd_vma vma;
    976   1.1.1.9  christos       vma = text->vma + execp->a_text;
    977   1.1.1.9  christos       data->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
    978       1.1     skrll     }
    979       1.1     skrll   if (abdp && abdp->zmagic_mapped_contiguous)
    980       1.1     skrll     {
    981   1.1.1.9  christos       text_pad = data->vma - (text->vma + execp->a_text);
    982   1.1.1.9  christos       /* Only pad the text section if the data
    983   1.1.1.9  christos 	 section is going to be placed after it.  */
    984   1.1.1.9  christos       if (text_pad > 0)
    985   1.1.1.9  christos 	execp->a_text += text_pad;
    986       1.1     skrll     }
    987   1.1.1.9  christos   data->filepos = text->filepos + execp->a_text;
    988       1.1     skrll 
    989       1.1     skrll   /* Fix up exec header while we're at it.  */
    990       1.1     skrll   if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
    991   1.1.1.9  christos     execp->a_text += adata (abfd).exec_bytes_size;
    992   1.1.1.5  christos   N_SET_MAGIC (execp, ZMAGIC);
    993       1.1     skrll 
    994       1.1     skrll   /* Spec says data section should be rounded up to page boundary.  */
    995   1.1.1.9  christos   execp->a_data = align_power (data->size, bss->alignment_power);
    996   1.1.1.9  christos   execp->a_data = BFD_ALIGN (execp->a_data, adata (abfd).page_size);
    997   1.1.1.9  christos   data_pad = execp->a_data - data->size;
    998       1.1     skrll 
    999       1.1     skrll   /* BSS.  */
   1000   1.1.1.9  christos   if (!bss->user_set_vma)
   1001   1.1.1.9  christos     bss->vma = data->vma + execp->a_data;
   1002       1.1     skrll   /* If the BSS immediately follows the data section and extra space
   1003       1.1     skrll      in the page is left after the data section, fudge data
   1004       1.1     skrll      in the header so that the bss section looks smaller by that
   1005       1.1     skrll      amount.  We'll start the bss section there, and lie to the OS.
   1006       1.1     skrll      (Note that a linker script, as well as the above assignment,
   1007       1.1     skrll      could have explicitly set the BSS vma to immediately follow
   1008       1.1     skrll      the data section.)  */
   1009   1.1.1.9  christos   if (align_power (bss->vma, bss->alignment_power) == data->vma + execp->a_data)
   1010   1.1.1.9  christos     execp->a_bss = data_pad > bss->size ? 0 : bss->size - data_pad;
   1011       1.1     skrll   else
   1012   1.1.1.9  christos     execp->a_bss = bss->size;
   1013       1.1     skrll }
   1014       1.1     skrll 
   1015       1.1     skrll static void
   1016       1.1     skrll adjust_n_magic (bfd *abfd, struct internal_exec *execp)
   1017       1.1     skrll {
   1018   1.1.1.9  christos   file_ptr pos = adata (abfd).exec_bytes_size;
   1019       1.1     skrll   bfd_vma vma = 0;
   1020       1.1     skrll   int pad;
   1021   1.1.1.9  christos   asection *text = obj_textsec (abfd);
   1022   1.1.1.9  christos   asection *data = obj_datasec (abfd);
   1023   1.1.1.9  christos   asection *bss = obj_bsssec (abfd);
   1024       1.1     skrll 
   1025       1.1     skrll   /* Text.  */
   1026   1.1.1.9  christos   text->filepos = pos;
   1027   1.1.1.9  christos   if (!text->user_set_vma)
   1028   1.1.1.9  christos     text->vma = vma;
   1029       1.1     skrll   else
   1030   1.1.1.9  christos     vma = text->vma;
   1031   1.1.1.9  christos   pos += execp->a_text;
   1032   1.1.1.9  christos   vma += execp->a_text;
   1033       1.1     skrll 
   1034       1.1     skrll   /* Data.  */
   1035   1.1.1.9  christos   data->filepos = pos;
   1036   1.1.1.9  christos   if (!data->user_set_vma)
   1037   1.1.1.9  christos     data->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
   1038   1.1.1.9  christos   vma = data->vma;
   1039       1.1     skrll 
   1040       1.1     skrll   /* Since BSS follows data immediately, see if it needs alignment.  */
   1041   1.1.1.9  christos   vma += data->size;
   1042   1.1.1.9  christos   pad = align_power (vma, bss->alignment_power) - vma;
   1043   1.1.1.9  christos   execp->a_data = data->size + pad;
   1044   1.1.1.9  christos   pos += execp->a_data;
   1045       1.1     skrll 
   1046       1.1     skrll   /* BSS.  */
   1047   1.1.1.9  christos   if (!bss->user_set_vma)
   1048   1.1.1.9  christos     bss->vma = vma;
   1049       1.1     skrll   else
   1050   1.1.1.9  christos     vma = bss->vma;
   1051       1.1     skrll 
   1052       1.1     skrll   /* Fix up exec header.  */
   1053   1.1.1.9  christos   execp->a_bss = bss->size;
   1054   1.1.1.5  christos   N_SET_MAGIC (execp, NMAGIC);
   1055       1.1     skrll }
   1056       1.1     skrll 
   1057   1.1.1.9  christos static void
   1058   1.1.1.9  christos adjust_i_magic (bfd *abfd, struct internal_exec *execp)
   1059   1.1.1.9  christos {
   1060   1.1.1.9  christos   file_ptr pos = adata (abfd).exec_bytes_size;
   1061   1.1.1.9  christos   bfd_vma vma = 0;
   1062   1.1.1.9  christos   int pad;
   1063   1.1.1.9  christos   asection *text = obj_textsec (abfd);
   1064   1.1.1.9  christos   asection *data = obj_datasec (abfd);
   1065   1.1.1.9  christos   asection *bss = obj_bsssec (abfd);
   1066   1.1.1.9  christos 
   1067   1.1.1.9  christos   /* Text.  */
   1068   1.1.1.9  christos   text->filepos = pos;
   1069   1.1.1.9  christos   if (!text->user_set_vma)
   1070   1.1.1.9  christos     text->vma = vma;
   1071   1.1.1.9  christos   else
   1072   1.1.1.9  christos     vma = text->vma;
   1073   1.1.1.9  christos   pos += execp->a_text;
   1074   1.1.1.9  christos 
   1075   1.1.1.9  christos   /* Data.  */
   1076   1.1.1.9  christos   data->filepos = pos;
   1077   1.1.1.9  christos   if (!data->user_set_vma)
   1078   1.1.1.9  christos     data->vma = 0;
   1079   1.1.1.9  christos   vma = data->vma;
   1080   1.1.1.9  christos 
   1081   1.1.1.9  christos   /* Since BSS follows data immediately, see if it needs alignment.  */
   1082   1.1.1.9  christos   vma += data->size;
   1083   1.1.1.9  christos   pad = align_power (vma, bss->alignment_power) - vma;
   1084   1.1.1.9  christos   execp->a_data = data->size + pad;
   1085   1.1.1.9  christos   pos += execp->a_data;
   1086   1.1.1.9  christos 
   1087   1.1.1.9  christos   /* BSS.  */
   1088   1.1.1.9  christos   if (!bss->user_set_vma)
   1089   1.1.1.9  christos     bss->vma = vma;
   1090   1.1.1.9  christos   else
   1091   1.1.1.9  christos     vma = bss->vma;
   1092   1.1.1.9  christos 
   1093   1.1.1.9  christos   /* Fix up exec header.  */
   1094   1.1.1.9  christos   execp->a_bss = bss->size;
   1095   1.1.1.9  christos   N_SET_MAGIC (execp, IMAGIC);
   1096   1.1.1.9  christos }
   1097   1.1.1.9  christos 
   1098   1.1.1.9  christos bool
   1099   1.1.1.5  christos NAME (aout, adjust_sizes_and_vmas) (bfd *abfd)
   1100       1.1     skrll {
   1101       1.1     skrll   struct internal_exec *execp = exec_hdr (abfd);
   1102       1.1     skrll 
   1103       1.1     skrll   if (! NAME (aout, make_sections) (abfd))
   1104   1.1.1.9  christos     return false;
   1105       1.1     skrll 
   1106   1.1.1.9  christos   if (adata (abfd).magic != undecided_magic)
   1107   1.1.1.9  christos     return true;
   1108       1.1     skrll 
   1109   1.1.1.9  christos   execp->a_text = align_power (obj_textsec (abfd)->size,
   1110   1.1.1.9  christos 			       obj_textsec (abfd)->alignment_power);
   1111       1.1     skrll 
   1112       1.1     skrll   /* Rule (heuristic) for when to pad to a new page.  Note that there
   1113       1.1     skrll      are (at least) two ways demand-paged (ZMAGIC) files have been
   1114       1.1     skrll      handled.  Most Berkeley-based systems start the text segment at
   1115       1.1     skrll      (TARGET_PAGE_SIZE).  However, newer versions of SUNOS start the text
   1116       1.1     skrll      segment right after the exec header; the latter is counted in the
   1117       1.1     skrll      text segment size, and is paged in by the kernel with the rest of
   1118   1.1.1.9  christos      the text.  */
   1119       1.1     skrll 
   1120       1.1     skrll   /* This perhaps isn't the right way to do this, but made it simpler for me
   1121       1.1     skrll      to understand enough to implement it.  Better would probably be to go
   1122       1.1     skrll      right from BFD flags to alignment/positioning characteristics.  But the
   1123       1.1     skrll      old code was sloppy enough about handling the flags, and had enough
   1124       1.1     skrll      other magic, that it was a little hard for me to understand.  I think
   1125       1.1     skrll      I understand it better now, but I haven't time to do the cleanup this
   1126       1.1     skrll      minute.  */
   1127       1.1     skrll 
   1128   1.1.1.9  christos   if (separate_i_d)
   1129   1.1.1.9  christos     adata (abfd).magic = i_magic;
   1130   1.1.1.9  christos   else if (abfd->flags & WP_TEXT)
   1131   1.1.1.9  christos     adata (abfd).magic = n_magic;
   1132       1.1     skrll   else
   1133   1.1.1.9  christos     adata (abfd).magic = o_magic;
   1134       1.1     skrll 
   1135       1.1     skrll #ifdef BFD_AOUT_DEBUG /* requires gcc2 */
   1136       1.1     skrll #if __GNUC__ >= 2
   1137       1.1     skrll   fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
   1138       1.1     skrll 	   ({ char *str;
   1139   1.1.1.9  christos 	      switch (adata (abfd).magic)
   1140   1.1.1.9  christos 		{
   1141   1.1.1.9  christos 		case n_magic: str = "NMAGIC"; break;
   1142   1.1.1.9  christos 		case o_magic: str = "OMAGIC"; break;
   1143   1.1.1.9  christos 		case i_magic: str = "IMAGIC"; break;
   1144   1.1.1.9  christos 		case z_magic: str = "ZMAGIC"; break;
   1145   1.1.1.9  christos 		default: abort ();
   1146   1.1.1.9  christos 		}
   1147       1.1     skrll 	      str;
   1148       1.1     skrll 	    }),
   1149   1.1.1.9  christos 	   obj_textsec (abfd)->vma, obj_textsec (abfd)->size,
   1150   1.1.1.9  christos 		obj_textsec (abfd)->alignment_power,
   1151   1.1.1.9  christos 	   obj_datasec (abfd)->vma, obj_datasec (abfd)->size,
   1152   1.1.1.9  christos 		obj_datasec (abfd)->alignment_power,
   1153   1.1.1.9  christos 	   obj_bsssec (abfd)->vma, obj_bsssec (abfd)->size,
   1154   1.1.1.9  christos 		obj_bsssec (abfd)->alignment_power);
   1155       1.1     skrll #endif
   1156       1.1     skrll #endif
   1157       1.1     skrll 
   1158   1.1.1.9  christos   switch (adata (abfd).magic)
   1159       1.1     skrll     {
   1160       1.1     skrll     case o_magic:
   1161       1.1     skrll       adjust_o_magic (abfd, execp);
   1162       1.1     skrll       break;
   1163       1.1     skrll     case z_magic:
   1164       1.1     skrll       adjust_z_magic (abfd, execp);
   1165       1.1     skrll       break;
   1166       1.1     skrll     case n_magic:
   1167       1.1     skrll       adjust_n_magic (abfd, execp);
   1168       1.1     skrll       break;
   1169   1.1.1.9  christos     case i_magic:
   1170   1.1.1.9  christos       adjust_i_magic (abfd, execp);
   1171   1.1.1.9  christos       break;
   1172       1.1     skrll     default:
   1173       1.1     skrll       abort ();
   1174       1.1     skrll     }
   1175       1.1     skrll 
   1176       1.1     skrll #ifdef BFD_AOUT_DEBUG
   1177       1.1     skrll   fprintf (stderr, "       text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
   1178   1.1.1.9  christos 	   obj_textsec (abfd)->vma, execp->a_text,
   1179   1.1.1.9  christos 		obj_textsec (abfd)->filepos,
   1180   1.1.1.9  christos 	   obj_datasec (abfd)->vma, execp->a_data,
   1181   1.1.1.9  christos 		obj_datasec (abfd)->filepos,
   1182   1.1.1.9  christos 	   obj_bsssec (abfd)->vma, execp->a_bss);
   1183       1.1     skrll #endif
   1184       1.1     skrll 
   1185   1.1.1.9  christos   return true;
   1186       1.1     skrll }
   1187       1.1     skrll 
   1188       1.1     skrll /* Called by the BFD in response to a bfd_make_section request.  */
   1189       1.1     skrll 
   1190   1.1.1.9  christos bool
   1191       1.1     skrll NAME (aout, new_section_hook) (bfd *abfd, asection *newsect)
   1192       1.1     skrll {
   1193       1.1     skrll   /* Align to double at least.  */
   1194       1.1     skrll   newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
   1195       1.1     skrll 
   1196       1.1     skrll   if (bfd_get_format (abfd) == bfd_object)
   1197       1.1     skrll     {
   1198       1.1     skrll       if (obj_textsec (abfd) == NULL
   1199       1.1     skrll 	  && !strcmp (newsect->name, ".text"))
   1200       1.1     skrll 	{
   1201       1.1     skrll 	  obj_textsec(abfd)= newsect;
   1202       1.1     skrll 	  newsect->target_index = N_TEXT;
   1203       1.1     skrll 	}
   1204       1.1     skrll       else if (obj_datasec (abfd) == NULL
   1205       1.1     skrll 	       && !strcmp (newsect->name, ".data"))
   1206       1.1     skrll 	{
   1207       1.1     skrll 	  obj_datasec (abfd) = newsect;
   1208       1.1     skrll 	  newsect->target_index = N_DATA;
   1209       1.1     skrll 	}
   1210       1.1     skrll       else if (obj_bsssec (abfd) == NULL
   1211       1.1     skrll 	       && !strcmp (newsect->name, ".bss"))
   1212       1.1     skrll 	{
   1213       1.1     skrll 	  obj_bsssec (abfd) = newsect;
   1214       1.1     skrll 	  newsect->target_index = N_BSS;
   1215       1.1     skrll 	}
   1216       1.1     skrll     }
   1217       1.1     skrll 
   1218       1.1     skrll   /* We allow more than three sections internally.  */
   1219       1.1     skrll   return _bfd_generic_new_section_hook (abfd, newsect);
   1220       1.1     skrll }
   1221       1.1     skrll 
   1222   1.1.1.9  christos bool
   1223       1.1     skrll NAME (aout, set_section_contents) (bfd *abfd,
   1224       1.1     skrll 				   sec_ptr section,
   1225       1.1     skrll 				   const void * location,
   1226       1.1     skrll 				   file_ptr offset,
   1227       1.1     skrll 				   bfd_size_type count)
   1228       1.1     skrll {
   1229       1.1     skrll   if (! abfd->output_has_begun)
   1230       1.1     skrll     {
   1231   1.1.1.5  christos       if (! NAME (aout, adjust_sizes_and_vmas) (abfd))
   1232   1.1.1.9  christos 	return false;
   1233       1.1     skrll     }
   1234       1.1     skrll 
   1235       1.1     skrll   if (section == obj_bsssec (abfd))
   1236       1.1     skrll     {
   1237       1.1     skrll       bfd_set_error (bfd_error_no_contents);
   1238   1.1.1.9  christos       return false;
   1239       1.1     skrll     }
   1240       1.1     skrll 
   1241       1.1     skrll   if (section != obj_textsec (abfd)
   1242       1.1     skrll       && section != obj_datasec (abfd))
   1243       1.1     skrll     {
   1244   1.1.1.6  christos       _bfd_error_handler
   1245   1.1.1.6  christos 	/* xgettext:c-format */
   1246   1.1.1.7  christos 	(_("%pB: can not represent section `%pA' in a.out object file format"),
   1247   1.1.1.6  christos 	 abfd, section);
   1248       1.1     skrll       bfd_set_error (bfd_error_nonrepresentable_section);
   1249   1.1.1.9  christos       return false;
   1250       1.1     skrll     }
   1251       1.1     skrll 
   1252       1.1     skrll   if (count != 0)
   1253       1.1     skrll     {
   1254       1.1     skrll       if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
   1255  1.1.1.10  christos 	  || bfd_write (location, count, abfd) != count)
   1256   1.1.1.9  christos 	return false;
   1257       1.1     skrll     }
   1258       1.1     skrll 
   1259   1.1.1.9  christos   return true;
   1260       1.1     skrll }
   1261       1.1     skrll 
   1262       1.1     skrll /* Read the external symbols from an a.out file.  */
   1264   1.1.1.9  christos 
   1265       1.1     skrll static bool
   1266       1.1     skrll aout_get_external_symbols (bfd *abfd)
   1267       1.1     skrll {
   1268       1.1     skrll   if (obj_aout_external_syms (abfd) == NULL)
   1269       1.1     skrll     {
   1270  1.1.1.11  christos       bfd_size_type count;
   1271  1.1.1.11  christos       struct external_nlist *syms = NULL;
   1272       1.1     skrll       bfd_size_type amt = exec_hdr (abfd)->a_syms;
   1273  1.1.1.11  christos 
   1274       1.1     skrll       count = amt / EXTERNAL_NLIST_SIZE;
   1275   1.1.1.4  christos 
   1276   1.1.1.4  christos       /* PR 17512: file: 011f5a08.  */
   1277  1.1.1.11  christos       if (count == 0)
   1278   1.1.1.4  christos 	return true;
   1279       1.1     skrll 
   1280       1.1     skrll       /* We allocate using malloc to make the values easy to free
   1281       1.1     skrll 	 later on.  If we put them on the objalloc it might not be
   1282   1.1.1.9  christos 	 possible to free them.  */
   1283   1.1.1.9  christos       if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
   1284  1.1.1.11  christos 	return false;
   1285   1.1.1.9  christos       syms = _bfd_malloc_and_read (abfd, amt, amt);
   1286   1.1.1.9  christos       if (syms == NULL)
   1287       1.1     skrll 	return false;
   1288       1.1     skrll 
   1289       1.1     skrll       obj_aout_external_syms (abfd) = syms;
   1290       1.1     skrll       obj_aout_external_sym_count (abfd) = count;
   1291       1.1     skrll     }
   1292       1.1     skrll 
   1293       1.1     skrll   if (obj_aout_external_strings (abfd) == NULL
   1294       1.1     skrll       && exec_hdr (abfd)->a_syms != 0)
   1295       1.1     skrll     {
   1296       1.1     skrll       unsigned char string_chars[BYTES_IN_LONG];
   1297       1.1     skrll       bfd_size_type stringsize;
   1298   1.1.1.9  christos       char *strings;
   1299       1.1     skrll       bfd_size_type amt = BYTES_IN_LONG;
   1300       1.1     skrll 
   1301       1.1     skrll       /* Get the size of the strings.  */
   1302  1.1.1.10  christos       if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
   1303   1.1.1.9  christos 	  || bfd_read (string_chars, amt, abfd) != amt)
   1304       1.1     skrll 	return false;
   1305   1.1.1.9  christos       stringsize = H_GET_32 (abfd, string_chars);
   1306   1.1.1.9  christos       if (stringsize == 0)
   1307  1.1.1.11  christos 	stringsize = 1;
   1308   1.1.1.9  christos       else if (stringsize + 1 < BYTES_IN_LONG + 1
   1309   1.1.1.9  christos 	       || (size_t) stringsize != stringsize)
   1310   1.1.1.9  christos 	{
   1311   1.1.1.9  christos 	  bfd_set_error (bfd_error_bad_value);
   1312   1.1.1.9  christos 	  return false;
   1313       1.1     skrll 	}
   1314  1.1.1.11  christos 
   1315  1.1.1.11  christos       strings = (char *) bfd_malloc (stringsize + 1);
   1316  1.1.1.11  christos       if (strings == NULL)
   1317  1.1.1.11  christos 	return false;
   1318   1.1.1.9  christos 
   1319       1.1     skrll       if (stringsize >= BYTES_IN_LONG)
   1320  1.1.1.11  christos 	{
   1321  1.1.1.11  christos 	  amt = stringsize - BYTES_IN_LONG;
   1322   1.1.1.9  christos 	  if (bfd_read (strings + BYTES_IN_LONG, amt, abfd) != amt)
   1323  1.1.1.11  christos 	    {
   1324  1.1.1.11  christos 	      free (strings);
   1325   1.1.1.9  christos 	      return false;
   1326   1.1.1.9  christos 	    }
   1327  1.1.1.11  christos 	}
   1328       1.1     skrll 
   1329   1.1.1.9  christos       /* Ensure that a zero index yields an empty string.  */
   1330   1.1.1.9  christos       if (stringsize >= BYTES_IN_WORD)
   1331       1.1     skrll 	memset (strings, 0, BYTES_IN_LONG);
   1332   1.1.1.9  christos 
   1333   1.1.1.9  christos       /* Ensure that the string buffer is NUL terminated.  */
   1334       1.1     skrll       strings[stringsize] = 0;
   1335       1.1     skrll 
   1336       1.1     skrll       obj_aout_external_strings (abfd) = strings;
   1337       1.1     skrll       obj_aout_external_string_size (abfd) = stringsize;
   1338       1.1     skrll     }
   1339   1.1.1.9  christos 
   1340       1.1     skrll   return true;
   1341       1.1     skrll }
   1342       1.1     skrll 
   1343       1.1     skrll /* Translate an a.out symbol into a BFD symbol.  The desc, other, type
   1344       1.1     skrll    and symbol->value fields of CACHE_PTR will be set from the a.out
   1345       1.1     skrll    nlist structure.  This function is responsible for setting
   1346       1.1     skrll    symbol->flags and symbol->section, and adjusting symbol->value.  */
   1347   1.1.1.9  christos 
   1348       1.1     skrll static bool
   1349       1.1     skrll translate_from_native_sym_flags (bfd *abfd,
   1350       1.1     skrll 				 aout_symbol_type *cache_ptr)
   1351       1.1     skrll {
   1352       1.1     skrll   flagword visible;
   1353   1.1.1.9  christos 
   1354       1.1     skrll   if (is_stab (cache_ptr->type, cache_ptr->symbol.name))
   1355       1.1     skrll     {
   1356       1.1     skrll       asection *sec;
   1357       1.1     skrll 
   1358       1.1     skrll       /* This is a debugging symbol.  */
   1359       1.1     skrll       cache_ptr->symbol.flags = BSF_DEBUGGING;
   1360       1.1     skrll 
   1361   1.1.1.9  christos       /* Work out the symbol section.  */
   1362       1.1     skrll       switch (cache_ptr->type)
   1363   1.1.1.9  christos 	{
   1364   1.1.1.9  christos 	case N_SO:
   1365   1.1.1.9  christos 	case N_SOL:
   1366   1.1.1.9  christos 	case N_FUN:
   1367   1.1.1.9  christos 	case N_ENTRY:
   1368       1.1     skrll 	case N_SLINE:
   1369       1.1     skrll 	case N_FN:
   1370       1.1     skrll 	  sec = obj_textsec (abfd);
   1371   1.1.1.9  christos 	  break;
   1372   1.1.1.9  christos 	case N_STSYM:
   1373       1.1     skrll 	case N_DSLINE:
   1374       1.1     skrll 	  sec = obj_datasec (abfd);
   1375   1.1.1.9  christos 	  break;
   1376   1.1.1.9  christos 	case N_LCSYM:
   1377       1.1     skrll 	case N_BSLINE:
   1378       1.1     skrll 	  sec = obj_bsssec (abfd);
   1379       1.1     skrll 	  break;
   1380       1.1     skrll 	default:
   1381       1.1     skrll 	  sec = bfd_abs_section_ptr;
   1382       1.1     skrll 	  break;
   1383       1.1     skrll 	}
   1384       1.1     skrll 
   1385       1.1     skrll       cache_ptr->symbol.section = sec;
   1386       1.1     skrll       cache_ptr->symbol.value -= sec->vma;
   1387   1.1.1.9  christos 
   1388       1.1     skrll       return true;
   1389       1.1     skrll     }
   1390       1.1     skrll 
   1391       1.1     skrll   /* Get the default visibility.  This does not apply to all types, so
   1392       1.1     skrll      we just hold it in a local variable to use if wanted.  */
   1393       1.1     skrll   if ((cache_ptr->type & N_EXT) == 0)
   1394       1.1     skrll     visible = BSF_LOCAL;
   1395       1.1     skrll   else
   1396       1.1     skrll     visible = BSF_GLOBAL;
   1397       1.1     skrll 
   1398       1.1     skrll   switch (cache_ptr->type)
   1399       1.1     skrll     {
   1400       1.1     skrll     default:
   1401       1.1     skrll     case N_ABS: case N_ABS | N_EXT:
   1402       1.1     skrll       cache_ptr->symbol.section = bfd_abs_section_ptr;
   1403       1.1     skrll       cache_ptr->symbol.flags = visible;
   1404       1.1     skrll       break;
   1405       1.1     skrll 
   1406       1.1     skrll     case N_UNDF | N_EXT:
   1407       1.1     skrll       if (cache_ptr->symbol.value != 0)
   1408       1.1     skrll 	{
   1409       1.1     skrll 	  /* This is a common symbol.  */
   1410       1.1     skrll 	  cache_ptr->symbol.flags = BSF_GLOBAL;
   1411       1.1     skrll 	  cache_ptr->symbol.section = bfd_com_section_ptr;
   1412       1.1     skrll 	}
   1413       1.1     skrll       else
   1414       1.1     skrll 	{
   1415       1.1     skrll 	  cache_ptr->symbol.flags = 0;
   1416       1.1     skrll 	  cache_ptr->symbol.section = bfd_und_section_ptr;
   1417       1.1     skrll 	}
   1418       1.1     skrll       break;
   1419       1.1     skrll 
   1420       1.1     skrll     case N_TEXT: case N_TEXT | N_EXT:
   1421       1.1     skrll       cache_ptr->symbol.section = obj_textsec (abfd);
   1422       1.1     skrll       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
   1423       1.1     skrll       cache_ptr->symbol.flags = visible;
   1424       1.1     skrll       break;
   1425       1.1     skrll 
   1426       1.1     skrll     case N_DATA: case N_DATA | N_EXT:
   1427       1.1     skrll       cache_ptr->symbol.section = obj_datasec (abfd);
   1428       1.1     skrll       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
   1429       1.1     skrll       cache_ptr->symbol.flags = visible;
   1430       1.1     skrll       break;
   1431       1.1     skrll 
   1432       1.1     skrll     case N_BSS: case N_BSS | N_EXT:
   1433       1.1     skrll       cache_ptr->symbol.section = obj_bsssec (abfd);
   1434       1.1     skrll       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
   1435       1.1     skrll       cache_ptr->symbol.flags = visible;
   1436       1.1     skrll       break;
   1437       1.1     skrll     }
   1438   1.1.1.9  christos 
   1439       1.1     skrll   return true;
   1440       1.1     skrll }
   1441       1.1     skrll 
   1442       1.1     skrll /* Set the fields of SYM_POINTER according to CACHE_PTR.  */
   1443   1.1.1.9  christos 
   1444       1.1     skrll static bool
   1445       1.1     skrll translate_to_native_sym_flags (bfd *abfd,
   1446       1.1     skrll 			       asymbol *cache_ptr,
   1447       1.1     skrll 			       struct external_nlist *sym_pointer)
   1448       1.1     skrll {
   1449       1.1     skrll   bfd_vma value = cache_ptr->value;
   1450       1.1     skrll   asection *sec;
   1451   1.1.1.9  christos   bfd_vma off;
   1452       1.1     skrll   const char *name = cache_ptr->name != NULL ? cache_ptr->name : "*unknown*";
   1453       1.1     skrll 
   1454       1.1     skrll   /* Mask out any existing type bits in case copying from one section
   1455   1.1.1.9  christos      to another.  */
   1456   1.1.1.9  christos   if (!is_stab (sym_pointer->e_type[0], name))
   1457       1.1     skrll     sym_pointer->e_type[0] &= ~N_TYPE;
   1458   1.1.1.8  christos 
   1459       1.1     skrll   sec = bfd_asymbol_section (cache_ptr);
   1460       1.1     skrll   off = 0;
   1461       1.1     skrll 
   1462       1.1     skrll   if (sec == NULL)
   1463       1.1     skrll     {
   1464       1.1     skrll       /* This case occurs, e.g., for the *DEBUG* section of a COFF
   1465   1.1.1.6  christos 	 file.  */
   1466   1.1.1.6  christos       _bfd_error_handler
   1467   1.1.1.7  christos 	/* xgettext:c-format */
   1468   1.1.1.9  christos 	(_("%pB: can not represent section for symbol `%s' in a.out object file format"),
   1469       1.1     skrll 	 abfd, name);
   1470   1.1.1.9  christos       bfd_set_error (bfd_error_nonrepresentable_section);
   1471       1.1     skrll       return false;
   1472       1.1     skrll     }
   1473       1.1     skrll 
   1474       1.1     skrll   if (sec->output_section != NULL)
   1475       1.1     skrll     {
   1476       1.1     skrll       off = sec->output_offset;
   1477       1.1     skrll       sec = sec->output_section;
   1478       1.1     skrll     }
   1479       1.1     skrll 
   1480       1.1     skrll   if (bfd_is_abs_section (sec))
   1481       1.1     skrll     sym_pointer->e_type[0] |= N_ABS;
   1482       1.1     skrll   else if (sec == obj_textsec (abfd))
   1483       1.1     skrll     sym_pointer->e_type[0] |= N_TEXT;
   1484       1.1     skrll   else if (sec == obj_datasec (abfd))
   1485       1.1     skrll     sym_pointer->e_type[0] |= N_DATA;
   1486       1.1     skrll   else if (sec == obj_bsssec (abfd))
   1487       1.1     skrll     sym_pointer->e_type[0] |= N_BSS;
   1488       1.1     skrll   else if (bfd_is_und_section (sec))
   1489       1.1     skrll     sym_pointer->e_type[0] = N_UNDF | N_EXT;
   1490       1.1     skrll   else if (bfd_is_com_section (sec))
   1491       1.1     skrll     sym_pointer->e_type[0] = N_UNDF | N_EXT;
   1492       1.1     skrll   else
   1493   1.1.1.6  christos     {
   1494   1.1.1.6  christos       _bfd_error_handler
   1495   1.1.1.7  christos 	/* xgettext:c-format */
   1496       1.1     skrll 	(_("%pB: can not represent section `%pA' in a.out object file format"),
   1497       1.1     skrll 	 abfd, sec);
   1498   1.1.1.9  christos       bfd_set_error (bfd_error_nonrepresentable_section);
   1499       1.1     skrll       return false;
   1500       1.1     skrll     }
   1501       1.1     skrll 
   1502       1.1     skrll   /* Turn the symbol from section relative to absolute again */
   1503       1.1     skrll   value += sec->vma + off;
   1504       1.1     skrll 
   1505       1.1     skrll   if ((cache_ptr->flags & BSF_DEBUGGING) != 0)
   1506       1.1     skrll     sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
   1507       1.1     skrll   else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
   1508       1.1     skrll     sym_pointer->e_type[0] |= N_EXT;
   1509       1.1     skrll 
   1510       1.1     skrll   PUT_WORD(abfd, value, sym_pointer->e_value);
   1511   1.1.1.9  christos 
   1512       1.1     skrll   return true;
   1513       1.1     skrll }
   1514       1.1     skrll 
   1515       1.1     skrll /* Native-level interface to symbols. */
   1517       1.1     skrll 
   1518       1.1     skrll asymbol *
   1519   1.1.1.9  christos NAME (aout, make_empty_symbol) (bfd *abfd)
   1520   1.1.1.2  christos {
   1521       1.1     skrll   size_t amt = sizeof (aout_symbol_type);
   1522   1.1.1.2  christos   aout_symbol_type *new_symbol_type = bfd_zalloc (abfd, amt);
   1523       1.1     skrll 
   1524   1.1.1.2  christos   if (!new_symbol_type)
   1525       1.1     skrll     return NULL;
   1526   1.1.1.2  christos   new_symbol_type->symbol.the_bfd = abfd;
   1527       1.1     skrll 
   1528       1.1     skrll   return &new_symbol_type->symbol;
   1529   1.1.1.9  christos }
   1530       1.1     skrll 
   1531   1.1.1.9  christos /* Translate a set of external symbols into internal symbols.  */
   1532       1.1     skrll 
   1533       1.1     skrll bool
   1534       1.1     skrll NAME (aout, translate_symbol_table) (bfd *abfd,
   1535       1.1     skrll 				     aout_symbol_type *in,
   1536       1.1     skrll 				     struct external_nlist *ext,
   1537       1.1     skrll 				     bfd_size_type count,
   1538   1.1.1.9  christos 				     char *str,
   1539       1.1     skrll 				     bfd_size_type strsize,
   1540       1.1     skrll 				     bool dynamic)
   1541       1.1     skrll {
   1542       1.1     skrll   struct external_nlist *ext_end;
   1543       1.1     skrll 
   1544       1.1     skrll   ext_end = ext + count;
   1545       1.1     skrll   for (; ext < ext_end; ext++, in++)
   1546   1.1.1.9  christos     {
   1547       1.1     skrll       bfd_vma x;
   1548       1.1     skrll       int ovly;
   1549       1.1     skrll 
   1550       1.1     skrll       x = GET_WORD (abfd, ext->e_strx);
   1551       1.1     skrll       in->symbol.the_bfd = abfd;
   1552       1.1     skrll 
   1553       1.1     skrll       /* For the normal symbols, the zero index points at the number
   1554       1.1     skrll 	 of bytes in the string table but is to be interpreted as the
   1555       1.1     skrll 	 null string.  For the dynamic symbols, the number of bytes in
   1556       1.1     skrll 	 the string table is stored in the __DYNAMIC structure and the
   1557       1.1     skrll 	 zero index points at an actual string.  */
   1558       1.1     skrll       if (x == 0 && ! dynamic)
   1559       1.1     skrll 	in->symbol.name = "";
   1560       1.1     skrll       else if (x < strsize)
   1561   1.1.1.9  christos 	in->symbol.name = str + x;
   1562   1.1.1.9  christos       else
   1563   1.1.1.9  christos 	{
   1564   1.1.1.9  christos 	  _bfd_error_handler
   1565   1.1.1.9  christos 	    (_("%pB: invalid string offset %" PRIu64 " >= %" PRIu64),
   1566   1.1.1.9  christos 	     abfd, (uint64_t) x, (uint64_t) strsize);
   1567   1.1.1.9  christos 	  bfd_set_error (bfd_error_bad_value);
   1568   1.1.1.9  christos 	  return false;
   1569   1.1.1.9  christos 	}
   1570   1.1.1.9  christos 
   1571   1.1.1.9  christos       ovly = H_GET_8 (abfd, ext->e_ovly);
   1572   1.1.1.9  christos       if (ovly != 0)
   1573   1.1.1.9  christos 	{
   1574   1.1.1.9  christos 	  _bfd_error_handler
   1575   1.1.1.9  christos 	    (_("%pB: symbol indicates overlay (not supported)"), abfd);
   1576   1.1.1.9  christos 	  bfd_set_error (bfd_error_bad_value);
   1577   1.1.1.9  christos 	  return false;
   1578   1.1.1.9  christos 	}
   1579   1.1.1.9  christos 
   1580   1.1.1.9  christos       in->symbol.value = GET_WORD (abfd,  ext->e_value);
   1581   1.1.1.9  christos       /* e_desc is zero for normal symbols but for .stab symbols it
   1582       1.1     skrll 	 carries the desc field in our extended 2.11BSD format. */
   1583       1.1     skrll       in->desc = H_GET_16 (abfd, ext->e_desc);
   1584       1.1     skrll       in->other = 0;
   1585       1.1     skrll       in->type = H_GET_8 (abfd,  ext->e_type);
   1586       1.1     skrll       in->symbol.udata.p = NULL;
   1587   1.1.1.9  christos 
   1588       1.1     skrll       if (! translate_from_native_sym_flags (abfd, in))
   1589       1.1     skrll 	return false;
   1590       1.1     skrll 
   1591       1.1     skrll       if (dynamic)
   1592       1.1     skrll 	in->symbol.flags |= BSF_DYNAMIC;
   1593   1.1.1.9  christos     }
   1594       1.1     skrll 
   1595       1.1     skrll   return true;
   1596       1.1     skrll }
   1597       1.1     skrll 
   1598       1.1     skrll /* We read the symbols into a buffer, which is discarded when this
   1599       1.1     skrll    function exits.  We read the strings into a buffer large enough to
   1600   1.1.1.9  christos    hold them all plus all the cached symbol entries.  */
   1601       1.1     skrll 
   1602       1.1     skrll bool
   1603       1.1     skrll NAME (aout, slurp_symbol_table) (bfd *abfd)
   1604       1.1     skrll {
   1605       1.1     skrll   struct external_nlist *old_external_syms;
   1606       1.1     skrll   aout_symbol_type *cached;
   1607       1.1     skrll   bfd_size_type cached_size;
   1608       1.1     skrll 
   1609   1.1.1.9  christos   /* If there's no work to be done, don't do any.  */
   1610       1.1     skrll   if (obj_aout_symbols (abfd) != NULL)
   1611       1.1     skrll     return true;
   1612       1.1     skrll 
   1613       1.1     skrll   old_external_syms = obj_aout_external_syms (abfd);
   1614   1.1.1.9  christos 
   1615       1.1     skrll   if (! aout_get_external_symbols (abfd))
   1616       1.1     skrll     return false;
   1617       1.1     skrll 
   1618       1.1     skrll   cached_size = obj_aout_external_sym_count (abfd);
   1619       1.1     skrll   cached_size *= sizeof (aout_symbol_type);
   1620   1.1.1.9  christos   cached = bfd_zmalloc (cached_size);
   1621       1.1     skrll   if (cached == NULL && cached_size != 0)
   1622       1.1     skrll     return false;
   1623       1.1     skrll 
   1624       1.1     skrll   /* Convert from external symbol information to internal.  */
   1625       1.1     skrll   if (! (NAME (aout, translate_symbol_table)
   1626       1.1     skrll 	 (abfd, cached,
   1627       1.1     skrll 	  obj_aout_external_syms (abfd),
   1628       1.1     skrll 	  obj_aout_external_sym_count (abfd),
   1629   1.1.1.9  christos 	  obj_aout_external_strings (abfd),
   1630       1.1     skrll 	  obj_aout_external_string_size (abfd),
   1631       1.1     skrll 	  false)))
   1632   1.1.1.9  christos     {
   1633       1.1     skrll       free (cached);
   1634       1.1     skrll       return false;
   1635   1.1.1.8  christos     }
   1636       1.1     skrll 
   1637       1.1     skrll   abfd->symcount = obj_aout_external_sym_count (abfd);
   1638       1.1     skrll 
   1639       1.1     skrll   obj_aout_symbols (abfd) = cached;
   1640       1.1     skrll 
   1641       1.1     skrll   /* It is very likely that anybody who calls this function will not
   1642       1.1     skrll      want the external symbol information, so if it was allocated
   1643       1.1     skrll      because of our call to aout_get_external_symbols, we free it up
   1644       1.1     skrll      right away to save space.  */
   1645       1.1     skrll   if (old_external_syms == NULL
   1646       1.1     skrll       && obj_aout_external_syms (abfd) != NULL)
   1647       1.1     skrll     {
   1648       1.1     skrll       free (obj_aout_external_syms (abfd));
   1649       1.1     skrll       obj_aout_external_syms (abfd) = NULL;
   1650   1.1.1.9  christos     }
   1651       1.1     skrll 
   1652       1.1     skrll   return true;
   1653       1.1     skrll }
   1654       1.1     skrll 
   1655       1.1     skrll /* We use a hash table when writing out symbols so that we only write
   1657       1.1     skrll    out a particular string once.  This helps particularly when the
   1658       1.1     skrll    linker writes out stabs debugging entries, because each different
   1659       1.1     skrll    contributing object file tends to have many duplicate stabs
   1660       1.1     skrll    strings.
   1661       1.1     skrll 
   1662       1.1     skrll    This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
   1663       1.1     skrll    if BFD_TRADITIONAL_FORMAT is set.  */
   1664       1.1     skrll 
   1665   1.1.1.9  christos /* Get the index of a string in a strtab, adding it if it is not
   1666       1.1     skrll    already present.  */
   1667       1.1     skrll 
   1668       1.1     skrll static inline bfd_size_type
   1669   1.1.1.9  christos add_to_stringtab (bfd *abfd,
   1670       1.1     skrll 		  struct bfd_strtab_hash *tab,
   1671   1.1.1.9  christos 		  const char *str,
   1672   1.1.1.2  christos 		  bool copy)
   1673       1.1     skrll {
   1674       1.1     skrll   bool hash;
   1675       1.1     skrll   bfd_size_type str_index;
   1676       1.1     skrll 
   1677       1.1     skrll   /* An index of 0 always means the empty string.  */
   1678       1.1     skrll   if (str == 0 || *str == '\0')
   1679       1.1     skrll     return 0;
   1680   1.1.1.9  christos 
   1681       1.1     skrll   /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
   1682   1.1.1.9  christos      doesn't understand a hashed string table.  */
   1683       1.1     skrll   hash = true;
   1684   1.1.1.2  christos   if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
   1685       1.1     skrll     hash = false;
   1686   1.1.1.2  christos 
   1687       1.1     skrll   str_index = _bfd_stringtab_add (tab, str, hash, copy);
   1688       1.1     skrll 
   1689   1.1.1.2  christos   if (str_index != (bfd_size_type) -1)
   1690       1.1     skrll     /* Add BYTES_IN_LONG to the return value to account for the
   1691   1.1.1.2  christos        space taken up by the string table size.  */
   1692       1.1     skrll     str_index += BYTES_IN_LONG;
   1693       1.1     skrll 
   1694       1.1     skrll   return str_index;
   1695       1.1     skrll }
   1696       1.1     skrll 
   1697   1.1.1.9  christos /* Write out a strtab.  ABFD is already at the right location in the
   1698       1.1     skrll    file.  */
   1699       1.1     skrll 
   1700       1.1     skrll static bool
   1701       1.1     skrll emit_stringtab (bfd *abfd, struct bfd_strtab_hash *tab)
   1702       1.1     skrll {
   1703       1.1     skrll   bfd_byte buffer[BYTES_IN_LONG];
   1704  1.1.1.10  christos 
   1705   1.1.1.9  christos   /* The string table starts with the size.  */
   1706       1.1     skrll   H_PUT_32 (abfd, _bfd_stringtab_size (tab) + BYTES_IN_LONG, buffer);
   1707       1.1     skrll   if (bfd_write (buffer, BYTES_IN_LONG, abfd) != BYTES_IN_LONG)
   1708       1.1     skrll     return false;
   1709       1.1     skrll 
   1710   1.1.1.9  christos   return _bfd_stringtab_emit (abfd, tab);
   1711       1.1     skrll }
   1712       1.1     skrll 
   1713       1.1     skrll bool
   1715       1.1     skrll NAME (aout, write_syms) (bfd *abfd)
   1716       1.1     skrll {
   1717       1.1     skrll   unsigned int count ;
   1718       1.1     skrll   asymbol **generic = bfd_get_outsymbols (abfd);
   1719   1.1.1.9  christos   struct bfd_strtab_hash *strtab;
   1720       1.1     skrll 
   1721       1.1     skrll   strtab = _bfd_stringtab_init ();
   1722       1.1     skrll   if (strtab == NULL)
   1723       1.1     skrll     return false;
   1724       1.1     skrll 
   1725       1.1     skrll   for (count = 0; count < bfd_get_symcount (abfd); count++)
   1726       1.1     skrll     {
   1727   1.1.1.9  christos       asymbol *g = generic[count];
   1728       1.1     skrll       bfd_size_type indx;
   1729       1.1     skrll       struct external_nlist nsp;
   1730       1.1     skrll 
   1731       1.1     skrll       indx = add_to_stringtab (abfd, strtab, g->name, false);
   1732       1.1     skrll       if (indx == (bfd_size_type) -1)
   1733   1.1.1.9  christos 	goto error_return;
   1734   1.1.1.9  christos       PUT_WORD (abfd, indx, nsp.e_strx);
   1735   1.1.1.9  christos 
   1736   1.1.1.9  christos       if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
   1737   1.1.1.9  christos 	{
   1738       1.1     skrll 	  H_PUT_16 (abfd, aout_symbol (g)->desc,  nsp.e_desc);
   1739   1.1.1.9  christos 	  H_PUT_8 (abfd, 0, nsp.e_ovly);
   1740   1.1.1.9  christos 	  H_PUT_8 (abfd, aout_symbol (g)->type,  nsp.e_type);
   1741   1.1.1.9  christos 	}
   1742   1.1.1.9  christos       else
   1743   1.1.1.9  christos 	{
   1744       1.1     skrll 	  H_PUT_16 (abfd, 0, nsp.e_desc);
   1745       1.1     skrll 	  H_PUT_8 (abfd, 0, nsp.e_ovly);
   1746       1.1     skrll 	  H_PUT_8 (abfd, 0, nsp.e_type);
   1747       1.1     skrll 	}
   1748  1.1.1.10  christos 
   1749       1.1     skrll       if (! translate_to_native_sym_flags (abfd, g, &nsp))
   1750       1.1     skrll 	goto error_return;
   1751       1.1     skrll 
   1752       1.1     skrll       if (bfd_write (&nsp, EXTERNAL_NLIST_SIZE, abfd) != EXTERNAL_NLIST_SIZE)
   1753       1.1     skrll 	goto error_return;
   1754       1.1     skrll 
   1755       1.1     skrll       /* NB: `KEEPIT' currently overlays `udata.p', so set this only
   1756       1.1     skrll 	 here, at the end.  */
   1757       1.1     skrll       g->KEEPIT = count;
   1758       1.1     skrll     }
   1759       1.1     skrll 
   1760       1.1     skrll   if (! emit_stringtab (abfd, strtab))
   1761   1.1.1.9  christos     goto error_return;
   1762       1.1     skrll 
   1763   1.1.1.9  christos   _bfd_stringtab_free (strtab);
   1764       1.1     skrll 
   1765   1.1.1.9  christos   return true;
   1766       1.1     skrll 
   1767       1.1     skrll  error_return:
   1768       1.1     skrll   _bfd_stringtab_free (strtab);
   1769       1.1     skrll   return false;
   1770       1.1     skrll }
   1771       1.1     skrll 
   1772       1.1     skrll 
   1773       1.1     skrll long
   1775       1.1     skrll NAME (aout, canonicalize_symtab) (bfd *abfd, asymbol **location)
   1776       1.1     skrll {
   1777       1.1     skrll   unsigned int counter = 0;
   1778       1.1     skrll   aout_symbol_type *symbase;
   1779       1.1     skrll 
   1780       1.1     skrll   if (!NAME (aout, slurp_symbol_table) (abfd))
   1781       1.1     skrll     return -1;
   1782       1.1     skrll 
   1783       1.1     skrll   for (symbase = obj_aout_symbols (abfd); counter++ < bfd_get_symcount (abfd);)
   1784       1.1     skrll     *(location++) = (asymbol *)(symbase++);
   1785       1.1     skrll   *location++ =0;
   1786       1.1     skrll   return bfd_get_symcount (abfd);
   1787       1.1     skrll }
   1788       1.1     skrll 
   1789       1.1     skrll 
   1790       1.1     skrll /* Output extended relocation information to a file in target byte order.  */
   1792       1.1     skrll 
   1793       1.1     skrll static void
   1794       1.1     skrll pdp11_aout_swap_reloc_out (bfd *abfd, arelent *g, bfd_byte *natptr)
   1795       1.1     skrll {
   1796       1.1     skrll   int r_index;
   1797       1.1     skrll   int r_pcrel;
   1798       1.1     skrll   int reloc_entry;
   1799       1.1     skrll   int r_type;
   1800       1.1     skrll   asymbol *sym = *(g->sym_ptr_ptr);
   1801       1.1     skrll   asection *output_section = sym->section->output_section;
   1802       1.1     skrll 
   1803       1.1     skrll   if (g->addend != 0)
   1804       1.1     skrll     fprintf (stderr, "BFD: can't do this reloc addend stuff\n");
   1805       1.1     skrll 
   1806       1.1     skrll   r_pcrel = g->howto->pc_relative;
   1807       1.1     skrll 
   1808       1.1     skrll   if (bfd_is_abs_section (output_section))
   1809       1.1     skrll     r_type = RABS;
   1810       1.1     skrll   else if (output_section == obj_textsec (abfd))
   1811       1.1     skrll     r_type = RTEXT;
   1812       1.1     skrll   else if (output_section == obj_datasec (abfd))
   1813       1.1     skrll     r_type = RDATA;
   1814       1.1     skrll   else if (output_section == obj_bsssec (abfd))
   1815       1.1     skrll     r_type = RBSS;
   1816       1.1     skrll   else if (bfd_is_und_section (output_section))
   1817       1.1     skrll     r_type = REXT;
   1818       1.1     skrll   else if (bfd_is_com_section (output_section))
   1819       1.1     skrll     r_type = REXT;
   1820       1.1     skrll   else
   1821       1.1     skrll     r_type = -1;
   1822       1.1     skrll 
   1823       1.1     skrll   BFD_ASSERT (r_type != -1);
   1824       1.1     skrll 
   1825       1.1     skrll   if (r_type == RABS)
   1826       1.1     skrll     r_index = 0;
   1827       1.1     skrll   else
   1828       1.1     skrll     r_index = (*(g->sym_ptr_ptr))->KEEPIT;
   1829       1.1     skrll 
   1830       1.1     skrll   reloc_entry = r_index << 4 | r_type | r_pcrel;
   1831       1.1     skrll 
   1832       1.1     skrll   PUT_WORD (abfd, reloc_entry, natptr);
   1833       1.1     skrll }
   1834       1.1     skrll 
   1835       1.1     skrll /* BFD deals internally with all things based from the section they're
   1836       1.1     skrll    in. so, something in 10 bytes into a text section  with a base of
   1837       1.1     skrll    50 would have a symbol (.text+10) and know .text vma was 50.
   1838   1.1.1.6  christos 
   1839   1.1.1.6  christos    Aout keeps all it's symbols based from zero, so the symbol would
   1840       1.1     skrll    contain 60. This macro subs the base of each section from the value
   1841       1.1     skrll    to give the true offset from the section */
   1842  1.1.1.10  christos 
   1843   1.1.1.9  christos 
   1844  1.1.1.10  christos #define MOVE_ADDRESS(ad)						\
   1845  1.1.1.11  christos   if (r_extern)								\
   1846       1.1     skrll     {									\
   1847       1.1     skrll       /* Undefined symbol.  */						\
   1848       1.1     skrll       if (symbols != NULL && r_index < bfd_get_symcount (abfd))		\
   1849       1.1     skrll 	cache_ptr->sym_ptr_ptr = symbols + r_index;			\
   1850   1.1.1.6  christos       else								\
   1851       1.1     skrll 	cache_ptr->sym_ptr_ptr = &bfd_abs_section_ptr->symbol;		\
   1852       1.1     skrll       cache_ptr->addend = ad;						\
   1853       1.1     skrll     }									\
   1854       1.1     skrll   else									\
   1855       1.1     skrll     {									\
   1856  1.1.1.11  christos       /* Defined, section relative. replace symbol with pointer to	\
   1857       1.1     skrll 	 symbol which points to section.  */				\
   1858       1.1     skrll       switch (r_index)							\
   1859       1.1     skrll 	{								\
   1860       1.1     skrll 	case N_TEXT:							\
   1861  1.1.1.11  christos 	case N_TEXT | N_EXT:						\
   1862       1.1     skrll 	  cache_ptr->sym_ptr_ptr  = &obj_textsec (abfd)->symbol;	\
   1863       1.1     skrll 	  cache_ptr->addend = ad  - su->textsec->vma;			\
   1864       1.1     skrll 	  break;							\
   1865       1.1     skrll 	case N_DATA:							\
   1866  1.1.1.11  christos 	case N_DATA | N_EXT:						\
   1867       1.1     skrll 	  cache_ptr->sym_ptr_ptr  = &obj_datasec (abfd)->symbol;	\
   1868       1.1     skrll 	  cache_ptr->addend = ad - su->datasec->vma;			\
   1869       1.1     skrll 	  break;							\
   1870       1.1     skrll 	case N_BSS:							\
   1871       1.1     skrll 	case N_BSS | N_EXT:						\
   1872  1.1.1.11  christos 	  cache_ptr->sym_ptr_ptr  = &obj_bsssec (abfd)->symbol;		\
   1873       1.1     skrll 	  cache_ptr->addend = ad - su->bsssec->vma;			\
   1874       1.1     skrll 	  break;							\
   1875       1.1     skrll 	default:							\
   1876       1.1     skrll 	case N_ABS:							\
   1877       1.1     skrll 	case N_ABS | N_EXT:						\
   1878       1.1     skrll 	  cache_ptr->sym_ptr_ptr = &bfd_abs_section_ptr->symbol;	\
   1879   1.1.1.6  christos 	  cache_ptr->addend = ad;					\
   1880   1.1.1.6  christos 	  break;							\
   1881   1.1.1.6  christos 	}								\
   1882   1.1.1.6  christos     }
   1883   1.1.1.6  christos 
   1884   1.1.1.6  christos static void
   1885       1.1     skrll pdp11_aout_swap_reloc_in (bfd *		 abfd,
   1886       1.1     skrll 			  bfd_byte *	 bytes,
   1887       1.1     skrll 			  arelent *	 cache_ptr,
   1888       1.1     skrll 			  bfd_size_type	 offset,
   1889       1.1     skrll 			  asymbol **	 symbols,
   1890       1.1     skrll 			  bfd_size_type	 symcount)
   1891       1.1     skrll {
   1892       1.1     skrll   struct aoutdata *su = &(abfd->tdata.aout_data->a);
   1893       1.1     skrll   unsigned int r_index;
   1894       1.1     skrll   int reloc_entry;
   1895       1.1     skrll   int r_extern;
   1896       1.1     skrll   int r_pcrel;
   1897       1.1     skrll 
   1898       1.1     skrll   reloc_entry = GET_WORD (abfd, (void *) bytes);
   1899       1.1     skrll 
   1900       1.1     skrll   r_pcrel = reloc_entry & RELFLG;
   1901       1.1     skrll 
   1902       1.1     skrll   cache_ptr->address = offset;
   1903       1.1     skrll   cache_ptr->howto = howto_table_pdp11 + (r_pcrel ? 1 : 0);
   1904       1.1     skrll 
   1905       1.1     skrll   if ((reloc_entry & RTYPE) == RABS)
   1906       1.1     skrll     r_index = N_ABS;
   1907       1.1     skrll   else
   1908   1.1.1.9  christos     r_index = RINDEX (reloc_entry);
   1909       1.1     skrll 
   1910       1.1     skrll   /* r_extern reflects whether the symbol the reloc is against is
   1911   1.1.1.9  christos      local or global.  */
   1912   1.1.1.9  christos   r_extern = (reloc_entry & RTYPE) == REXT;
   1913   1.1.1.9  christos 
   1914       1.1     skrll   if (r_extern && r_index >= symcount)
   1915       1.1     skrll     {
   1916       1.1     skrll       /* We could arrange to return an error, but it might be useful
   1917       1.1     skrll 	 to see the file even if it is bad.  FIXME: Of course this
   1918       1.1     skrll 	 means that objdump -r *doesn't* see the actual reloc, and
   1919       1.1     skrll 	 objcopy silently writes a different reloc.  */
   1920       1.1     skrll       r_extern = 0;
   1921       1.1     skrll       r_index = N_ABS;
   1922       1.1     skrll     }
   1923   1.1.1.9  christos 
   1924       1.1     skrll   MOVE_ADDRESS(0);
   1925       1.1     skrll }
   1926       1.1     skrll 
   1927       1.1     skrll /* Read and swap the relocs for a section.  */
   1928       1.1     skrll 
   1929       1.1     skrll bool
   1930       1.1     skrll NAME (aout, slurp_reloc_table) (bfd *abfd, sec_ptr asect, asymbol **symbols)
   1931       1.1     skrll {
   1932       1.1     skrll   bfd_byte *rptr;
   1933       1.1     skrll   bfd_size_type count;
   1934       1.1     skrll   bfd_size_type reloc_size;
   1935       1.1     skrll   void * relocs;
   1936   1.1.1.9  christos   arelent *reloc_cache;
   1937       1.1     skrll   size_t each_size;
   1938       1.1     skrll   unsigned int counter = 0;
   1939   1.1.1.9  christos   arelent *cache_ptr;
   1940       1.1     skrll 
   1941       1.1     skrll   if (asect->relocation)
   1942       1.1     skrll     return true;
   1943       1.1     skrll 
   1944       1.1     skrll   if (asect->flags & SEC_CONSTRUCTOR)
   1945       1.1     skrll     return true;
   1946       1.1     skrll 
   1947       1.1     skrll   if (asect == obj_datasec (abfd))
   1948       1.1     skrll     reloc_size = exec_hdr(abfd)->a_drsize;
   1949       1.1     skrll   else if (asect == obj_textsec (abfd))
   1950   1.1.1.9  christos     reloc_size = exec_hdr(abfd)->a_trsize;
   1951       1.1     skrll   else if (asect == obj_bsssec (abfd))
   1952       1.1     skrll     reloc_size = 0;
   1953       1.1     skrll   else
   1954   1.1.1.9  christos     {
   1955   1.1.1.9  christos       bfd_set_error (bfd_error_invalid_operation);
   1956       1.1     skrll       return false;
   1957   1.1.1.9  christos     }
   1958       1.1     skrll 
   1959   1.1.1.9  christos   if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
   1960       1.1     skrll     return false;
   1961       1.1     skrll   relocs = _bfd_malloc_and_read (abfd, reloc_size, reloc_size);
   1962       1.1     skrll   if (relocs == NULL && reloc_size != 0)
   1963       1.1     skrll     return false;
   1964       1.1     skrll 
   1965       1.1     skrll   each_size = obj_reloc_entry_size (abfd);
   1966       1.1     skrll   count = reloc_size / each_size;
   1967       1.1     skrll 
   1968       1.1     skrll   /* Count the number of NON-ZERO relocs, this is the count we want.  */
   1969       1.1     skrll   {
   1970       1.1     skrll     unsigned int real_count = 0;
   1971       1.1     skrll 
   1972       1.1     skrll     for (counter = 0; counter < count; counter++)
   1973       1.1     skrll       {
   1974       1.1     skrll 	int x;
   1975       1.1     skrll 
   1976       1.1     skrll 	x = GET_WORD (abfd, (char *) relocs + each_size * counter);
   1977       1.1     skrll 	if (x != 0)
   1978       1.1     skrll 	  real_count++;
   1979       1.1     skrll       }
   1980   1.1.1.9  christos 
   1981       1.1     skrll     count = real_count;
   1982       1.1     skrll   }
   1983       1.1     skrll 
   1984       1.1     skrll   reloc_cache = bfd_zmalloc (count * sizeof (arelent));
   1985       1.1     skrll   if (reloc_cache == NULL && count != 0)
   1986       1.1     skrll     return false;
   1987       1.1     skrll 
   1988       1.1     skrll   cache_ptr = reloc_cache;
   1989       1.1     skrll 
   1990       1.1     skrll   rptr = relocs;
   1991       1.1     skrll   for (counter = 0;
   1992       1.1     skrll        counter < count;
   1993       1.1     skrll        counter++, rptr += RELOC_SIZE, cache_ptr++)
   1994       1.1     skrll     {
   1995       1.1     skrll       while (GET_WORD (abfd, (void *) rptr) == 0)
   1996       1.1     skrll 	{
   1997       1.1     skrll 	  rptr += RELOC_SIZE;
   1998       1.1     skrll 	  if ((char *) rptr >= (char *) relocs + reloc_size)
   1999       1.1     skrll 	    goto done;
   2000       1.1     skrll 	}
   2001       1.1     skrll 
   2002       1.1     skrll       pdp11_aout_swap_reloc_in (abfd, rptr, cache_ptr,
   2003       1.1     skrll 				(bfd_size_type) ((char *) rptr - (char *) relocs),
   2004       1.1     skrll 				symbols,
   2005       1.1     skrll 				(bfd_size_type) bfd_get_symcount (abfd));
   2006       1.1     skrll     }
   2007       1.1     skrll  done:
   2008       1.1     skrll   /* Just in case, if rptr >= relocs + reloc_size should happen
   2009       1.1     skrll      too early.  */
   2010       1.1     skrll   BFD_ASSERT (counter == count);
   2011   1.1.1.9  christos 
   2012       1.1     skrll   free (relocs);
   2013       1.1     skrll 
   2014       1.1     skrll   asect->relocation = reloc_cache;
   2015       1.1     skrll   asect->reloc_count = cache_ptr - reloc_cache;
   2016   1.1.1.9  christos 
   2017       1.1     skrll   return true;
   2018       1.1     skrll }
   2019       1.1     skrll 
   2020       1.1     skrll /* Write out a relocation section into an object file.  */
   2021       1.1     skrll 
   2022       1.1     skrll bool
   2023       1.1     skrll NAME (aout, squirt_out_relocs) (bfd *abfd, asection *section)
   2024       1.1     skrll {
   2025       1.1     skrll   arelent **generic;
   2026       1.1     skrll   unsigned char *native;
   2027   1.1.1.9  christos   unsigned int count = section->reloc_count;
   2028       1.1     skrll   bfd_size_type natsize;
   2029       1.1     skrll 
   2030       1.1     skrll   natsize = section->size;
   2031       1.1     skrll   native = bfd_zalloc (abfd, natsize);
   2032       1.1     skrll   if (!native)
   2033       1.1     skrll     return false;
   2034       1.1     skrll 
   2035       1.1     skrll   generic = section->orelocation;
   2036   1.1.1.9  christos   if (generic != NULL)
   2037   1.1.1.9  christos     {
   2038   1.1.1.9  christos       while (count > 0)
   2039   1.1.1.9  christos 	{
   2040   1.1.1.9  christos 	  bfd_byte *r;
   2041   1.1.1.9  christos 
   2042   1.1.1.9  christos 	  if ((*generic)->howto == NULL
   2043   1.1.1.9  christos 	      || (*generic)->sym_ptr_ptr == NULL)
   2044   1.1.1.9  christos 	    {
   2045       1.1     skrll 	      bfd_set_error (bfd_error_invalid_operation);
   2046       1.1     skrll 	      _bfd_error_handler (_("%pB: attempt to write out "
   2047       1.1     skrll 				    "unknown reloc type"), abfd);
   2048       1.1     skrll 	      bfd_release (abfd, native);
   2049       1.1     skrll 	      return false;
   2050       1.1     skrll 	    }
   2051       1.1     skrll 	  r = native + (*generic)->address;
   2052  1.1.1.10  christos 	  pdp11_aout_swap_reloc_out (abfd, *generic, r);
   2053       1.1     skrll 	  count--;
   2054       1.1     skrll 	  generic++;
   2055   1.1.1.9  christos 	}
   2056       1.1     skrll     }
   2057       1.1     skrll 
   2058       1.1     skrll   if (bfd_write (native, natsize, abfd) != natsize)
   2059   1.1.1.9  christos     {
   2060       1.1     skrll       bfd_release (abfd, native);
   2061       1.1     skrll       return false;
   2062       1.1     skrll     }
   2063       1.1     skrll 
   2064       1.1     skrll   bfd_release (abfd, native);
   2065       1.1     skrll   return true;
   2066       1.1     skrll }
   2067       1.1     skrll 
   2068       1.1     skrll /* This is stupid.  This function should be a boolean predicate.  */
   2069       1.1     skrll 
   2070       1.1     skrll long
   2071       1.1     skrll NAME (aout, canonicalize_reloc) (bfd *abfd,
   2072       1.1     skrll 				 sec_ptr section,
   2073       1.1     skrll 				 arelent **relptr,
   2074       1.1     skrll 				 asymbol **symbols)
   2075       1.1     skrll {
   2076       1.1     skrll   arelent *tblptr = section->relocation;
   2077       1.1     skrll   unsigned int count;
   2078       1.1     skrll 
   2079       1.1     skrll   if (section == obj_bsssec (abfd))
   2080       1.1     skrll     {
   2081       1.1     skrll       *relptr = NULL;
   2082       1.1     skrll       return 0;
   2083       1.1     skrll     }
   2084       1.1     skrll 
   2085       1.1     skrll   if (!(tblptr || NAME (aout, slurp_reloc_table)(abfd, section, symbols)))
   2086       1.1     skrll     return -1;
   2087       1.1     skrll 
   2088       1.1     skrll   if (section->flags & SEC_CONSTRUCTOR)
   2089       1.1     skrll     {
   2090       1.1     skrll       arelent_chain *chain = section->constructor_chain;
   2091       1.1     skrll 
   2092       1.1     skrll       for (count = 0; count < section->reloc_count; count ++)
   2093       1.1     skrll 	{
   2094       1.1     skrll 	  *relptr ++ = &chain->relent;
   2095       1.1     skrll 	  chain = chain->next;
   2096       1.1     skrll 	}
   2097       1.1     skrll     }
   2098       1.1     skrll   else
   2099       1.1     skrll     {
   2100       1.1     skrll       tblptr = section->relocation;
   2101       1.1     skrll 
   2102       1.1     skrll       for (count = 0; count++ < section->reloc_count;)
   2103       1.1     skrll 	*relptr++ = tblptr++;
   2104       1.1     skrll     }
   2105       1.1     skrll 
   2106       1.1     skrll   *relptr = 0;
   2107       1.1     skrll 
   2108  1.1.1.10  christos   return section->reloc_count;
   2109       1.1     skrll }
   2110       1.1     skrll 
   2111   1.1.1.8  christos long
   2112   1.1.1.8  christos NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect)
   2113   1.1.1.8  christos {
   2114   1.1.1.8  christos   size_t count, raw;
   2115   1.1.1.8  christos 
   2116   1.1.1.8  christos   if (asect->flags & SEC_CONSTRUCTOR)
   2117   1.1.1.8  christos     count = asect->reloc_count;
   2118   1.1.1.8  christos   else if (asect == obj_datasec (abfd))
   2119   1.1.1.8  christos     count = exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
   2120   1.1.1.8  christos   else if (asect == obj_textsec (abfd))
   2121   1.1.1.8  christos     count = exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
   2122   1.1.1.8  christos   else if (asect == obj_bsssec (abfd))
   2123       1.1     skrll     count = 0;
   2124  1.1.1.10  christos   else
   2125  1.1.1.10  christos     {
   2126   1.1.1.8  christos       bfd_set_error (bfd_error_invalid_operation);
   2127   1.1.1.8  christos       return -1;
   2128   1.1.1.8  christos     }
   2129   1.1.1.8  christos 
   2130  1.1.1.10  christos   if (count >= LONG_MAX / sizeof (arelent *)
   2131  1.1.1.10  christos       || _bfd_mul_overflow (count, obj_reloc_entry_size (abfd), &raw))
   2132  1.1.1.10  christos     {
   2133  1.1.1.10  christos       bfd_set_error (bfd_error_file_too_big);
   2134  1.1.1.10  christos       return -1;
   2135  1.1.1.10  christos     }
   2136  1.1.1.10  christos   if (!bfd_write_p (abfd))
   2137  1.1.1.10  christos     {
   2138  1.1.1.10  christos       ufile_ptr filesize = bfd_get_file_size (abfd);
   2139   1.1.1.8  christos       if (filesize != 0 && raw > filesize)
   2140       1.1     skrll 	{
   2141       1.1     skrll 	  bfd_set_error (bfd_error_file_truncated);
   2142       1.1     skrll 	  return -1;
   2143       1.1     skrll 	}
   2144       1.1     skrll     }
   2145       1.1     skrll   return (count + 1) * sizeof (arelent *);
   2146       1.1     skrll }
   2147       1.1     skrll 
   2148       1.1     skrll 
   2149       1.1     skrll long
   2151       1.1     skrll NAME (aout, get_symtab_upper_bound) (bfd *abfd)
   2152       1.1     skrll {
   2153       1.1     skrll   if (!NAME (aout, slurp_symbol_table) (abfd))
   2154       1.1     skrll     return -1;
   2155       1.1     skrll 
   2156       1.1     skrll   return (bfd_get_symcount (abfd) + 1) * (sizeof (aout_symbol_type *));
   2157       1.1     skrll }
   2158       1.1     skrll 
   2159       1.1     skrll alent *
   2160       1.1     skrll NAME (aout, get_lineno) (bfd * abfd ATTRIBUTE_UNUSED,
   2161       1.1     skrll 			 asymbol * symbol ATTRIBUTE_UNUSED)
   2162       1.1     skrll {
   2163       1.1     skrll   return NULL;
   2164       1.1     skrll }
   2165       1.1     skrll 
   2166       1.1     skrll void
   2167       1.1     skrll NAME (aout, get_symbol_info) (bfd * abfd ATTRIBUTE_UNUSED,
   2168       1.1     skrll 			      asymbol *symbol,
   2169       1.1     skrll 			      symbol_info *ret)
   2170       1.1     skrll {
   2171       1.1     skrll   bfd_symbol_info (symbol, ret);
   2172       1.1     skrll 
   2173       1.1     skrll   if (ret->type == '?')
   2174       1.1     skrll     {
   2175       1.1     skrll       int type_code = aout_symbol(symbol)->type & 0xff;
   2176       1.1     skrll       const char *stab_name = bfd_get_stab_name (type_code);
   2177       1.1     skrll       static char buf[10];
   2178       1.1     skrll 
   2179       1.1     skrll       if (stab_name == NULL)
   2180       1.1     skrll 	{
   2181       1.1     skrll 	  sprintf(buf, "(%d)", type_code);
   2182       1.1     skrll 	  stab_name = buf;
   2183       1.1     skrll 	}
   2184       1.1     skrll       ret->type = '-';
   2185       1.1     skrll       ret->stab_type  = type_code;
   2186       1.1     skrll       ret->stab_other = (unsigned) (aout_symbol(symbol)->other & 0xff);
   2187       1.1     skrll       ret->stab_desc  = (unsigned) (aout_symbol(symbol)->desc & 0xffff);
   2188       1.1     skrll       ret->stab_name  = stab_name;
   2189       1.1     skrll     }
   2190       1.1     skrll }
   2191       1.1     skrll 
   2192       1.1     skrll void
   2193       1.1     skrll NAME (aout, print_symbol) (bfd * abfd,
   2194       1.1     skrll 			   void * afile,
   2195       1.1     skrll 			   asymbol *symbol,
   2196       1.1     skrll 			   bfd_print_symbol_type how)
   2197       1.1     skrll {
   2198       1.1     skrll   FILE *file = (FILE *) afile;
   2199       1.1     skrll 
   2200       1.1     skrll   switch (how)
   2201       1.1     skrll     {
   2202       1.1     skrll     case bfd_print_symbol_name:
   2203       1.1     skrll       if (symbol->name)
   2204       1.1     skrll 	fprintf(file,"%s", symbol->name);
   2205       1.1     skrll       break;
   2206       1.1     skrll     case bfd_print_symbol_more:
   2207       1.1     skrll       fprintf(file,"%4x %2x %2x",
   2208       1.1     skrll 	      (unsigned) (aout_symbol (symbol)->desc & 0xffff),
   2209       1.1     skrll 	      (unsigned) (aout_symbol (symbol)->other & 0xff),
   2210       1.1     skrll 	      (unsigned) (aout_symbol (symbol)->type));
   2211       1.1     skrll       break;
   2212       1.1     skrll     case bfd_print_symbol_all:
   2213       1.1     skrll       {
   2214       1.1     skrll 	const char *section_name = symbol->section->name;
   2215       1.1     skrll 
   2216       1.1     skrll 	bfd_print_symbol_vandf (abfd, (void *) file, symbol);
   2217       1.1     skrll 
   2218       1.1     skrll 	fprintf (file," %-5s %04x %02x %02x",
   2219       1.1     skrll 		 section_name,
   2220       1.1     skrll 		 (unsigned) (aout_symbol (symbol)->desc & 0xffff),
   2221       1.1     skrll 		 (unsigned) (aout_symbol (symbol)->other & 0xff),
   2222       1.1     skrll 		 (unsigned) (aout_symbol (symbol)->type  & 0xff));
   2223       1.1     skrll 	if (symbol->name)
   2224       1.1     skrll 	  fprintf(file," %s", symbol->name);
   2225       1.1     skrll       }
   2226       1.1     skrll       break;
   2227       1.1     skrll     }
   2228       1.1     skrll }
   2229       1.1     skrll 
   2230       1.1     skrll /* If we don't have to allocate more than 1MB to hold the generic
   2231       1.1     skrll    symbols, we use the generic minisymbol method: it's faster, since
   2232       1.1     skrll    it only translates the symbols once, not multiple times.  */
   2233       1.1     skrll #define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
   2234   1.1.1.9  christos 
   2235       1.1     skrll /* Read minisymbols.  For minisymbols, we use the unmodified a.out
   2236       1.1     skrll    symbols.  The minisymbol_to_symbol function translates these into
   2237       1.1     skrll    BFD asymbol structures.  */
   2238       1.1     skrll 
   2239       1.1     skrll long
   2240       1.1     skrll NAME (aout, read_minisymbols) (bfd *abfd,
   2241       1.1     skrll 			       bool dynamic,
   2242       1.1     skrll 			       void * *minisymsp,
   2243       1.1     skrll 			       unsigned int *sizep)
   2244       1.1     skrll {
   2245       1.1     skrll   if (dynamic)
   2246       1.1     skrll     /* We could handle the dynamic symbols here as well, but it's
   2247       1.1     skrll        easier to hand them off.  */
   2248       1.1     skrll     return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
   2249       1.1     skrll 
   2250       1.1     skrll   if (! aout_get_external_symbols (abfd))
   2251       1.1     skrll     return -1;
   2252       1.1     skrll 
   2253       1.1     skrll   if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
   2254       1.1     skrll     return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
   2255       1.1     skrll 
   2256       1.1     skrll   *minisymsp = (void *) obj_aout_external_syms (abfd);
   2257       1.1     skrll 
   2258       1.1     skrll   /* By passing the external symbols back from this routine, we are
   2259       1.1     skrll      giving up control over the memory block.  Clear
   2260       1.1     skrll      obj_aout_external_syms, so that we do not try to free it
   2261       1.1     skrll      ourselves.  */
   2262       1.1     skrll   obj_aout_external_syms (abfd) = NULL;
   2263       1.1     skrll 
   2264       1.1     skrll   *sizep = EXTERNAL_NLIST_SIZE;
   2265       1.1     skrll   return obj_aout_external_sym_count (abfd);
   2266       1.1     skrll }
   2267   1.1.1.9  christos 
   2268       1.1     skrll /* Convert a minisymbol to a BFD asymbol.  A minisymbol is just an
   2269       1.1     skrll    unmodified a.out symbol.  The SYM argument is a structure returned
   2270       1.1     skrll    by bfd_make_empty_symbol, which we fill in here.  */
   2271       1.1     skrll 
   2272       1.1     skrll asymbol *
   2273       1.1     skrll NAME (aout, minisymbol_to_symbol) (bfd *abfd,
   2274       1.1     skrll 				   bool dynamic,
   2275       1.1     skrll 				   const void * minisym,
   2276       1.1     skrll 				   asymbol *sym)
   2277       1.1     skrll {
   2278       1.1     skrll   if (dynamic
   2279       1.1     skrll       || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
   2280       1.1     skrll     return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
   2281       1.1     skrll 
   2282       1.1     skrll   memset (sym, 0, sizeof (aout_symbol_type));
   2283       1.1     skrll 
   2284       1.1     skrll   /* We call translate_symbol_table to translate a single symbol.  */
   2285   1.1.1.9  christos   if (! (NAME (aout, translate_symbol_table)
   2286       1.1     skrll 	 (abfd,
   2287       1.1     skrll 	  (aout_symbol_type *) sym,
   2288       1.1     skrll 	  (struct external_nlist *) minisym,
   2289       1.1     skrll 	  (bfd_size_type) 1,
   2290       1.1     skrll 	  obj_aout_external_strings (abfd),
   2291       1.1     skrll 	  obj_aout_external_string_size (abfd),
   2292       1.1     skrll 	  false)))
   2293       1.1     skrll     return NULL;
   2294       1.1     skrll 
   2295   1.1.1.9  christos   return sym;
   2296       1.1     skrll }
   2297       1.1     skrll 
   2298   1.1.1.4  christos /* Provided a BFD, a section and an offset into the section, calculate
   2299       1.1     skrll    and return the name of the source file and the line nearest to the
   2300       1.1     skrll    wanted location.  */
   2301       1.1     skrll 
   2302   1.1.1.4  christos bool
   2303   1.1.1.4  christos NAME (aout, find_nearest_line) (bfd *abfd,
   2304       1.1     skrll 				asymbol **symbols,
   2305       1.1     skrll 				asection *section,
   2306       1.1     skrll 				bfd_vma offset,
   2307       1.1     skrll 				const char **filename_ptr,
   2308       1.1     skrll 				const char **functionname_ptr,
   2309       1.1     skrll 				unsigned int *line_ptr,
   2310       1.1     skrll 				unsigned int *discriminator_ptr)
   2311       1.1     skrll {
   2312       1.1     skrll   /* Run down the file looking for the filename, function and linenumber.  */
   2313       1.1     skrll   asymbol **p;
   2314       1.1     skrll   const char *directory_name = NULL;
   2315       1.1     skrll   const char *main_file_name = NULL;
   2316       1.1     skrll   const char *current_file_name = NULL;
   2317   1.1.1.9  christos   const char *line_file_name = NULL; /* Value of current_file_name at line number.  */
   2318   1.1.1.9  christos   bfd_vma low_line_vma = 0;
   2319       1.1     skrll   bfd_vma low_func_vma = 0;
   2320   1.1.1.4  christos   asymbol *func = 0;
   2321   1.1.1.4  christos   size_t filelen, funclen;
   2322       1.1     skrll   char *buf;
   2323       1.1     skrll 
   2324       1.1     skrll   *filename_ptr = bfd_get_filename (abfd);
   2325       1.1     skrll   *functionname_ptr = NULL;
   2326       1.1     skrll   *line_ptr = 0;
   2327       1.1     skrll   if (discriminator_ptr)
   2328       1.1     skrll     *discriminator_ptr = 0;
   2329       1.1     skrll 
   2330       1.1     skrll   if (symbols != NULL)
   2331       1.1     skrll     {
   2332       1.1     skrll       for (p = symbols; *p; p++)
   2333       1.1     skrll 	{
   2334       1.1     skrll 	  aout_symbol_type  *q = (aout_symbol_type *)(*p);
   2335       1.1     skrll 	next:
   2336       1.1     skrll 	  switch (q->type)
   2337       1.1     skrll 	    {
   2338       1.1     skrll 	    case N_TEXT:
   2339       1.1     skrll 	      /* If this looks like a file name symbol, and it comes after
   2340       1.1     skrll 		 the line number we have found so far, but before the
   2341       1.1     skrll 		 offset, then we have probably not found the right line
   2342       1.1     skrll 		 number.  */
   2343       1.1     skrll 	      if (q->symbol.value <= offset
   2344       1.1     skrll 		  && ((q->symbol.value > low_line_vma
   2345       1.1     skrll 		       && (line_file_name != NULL
   2346   1.1.1.9  christos 			   || *line_ptr != 0))
   2347   1.1.1.9  christos 		      || (q->symbol.value > low_func_vma
   2348   1.1.1.9  christos 			  && func != NULL)))
   2349   1.1.1.9  christos 		{
   2350       1.1     skrll 		  const char * symname;
   2351       1.1     skrll 
   2352       1.1     skrll 		  symname = q->symbol.name;
   2353       1.1     skrll 
   2354       1.1     skrll 		  if (symname != NULL
   2355       1.1     skrll 		      && strlen (symname) > 2
   2356       1.1     skrll 		      && strcmp (symname + strlen (symname) - 2, ".o") == 0)
   2357       1.1     skrll 		    {
   2358       1.1     skrll 		      if (q->symbol.value > low_line_vma)
   2359       1.1     skrll 			{
   2360       1.1     skrll 			  *line_ptr = 0;
   2361       1.1     skrll 			  line_file_name = NULL;
   2362       1.1     skrll 			}
   2363       1.1     skrll 		      if (q->symbol.value > low_func_vma)
   2364       1.1     skrll 			func = NULL;
   2365       1.1     skrll 		    }
   2366       1.1     skrll 		}
   2367       1.1     skrll 	      break;
   2368       1.1     skrll 
   2369       1.1     skrll 	    case N_SO:
   2370       1.1     skrll 	      /* If this symbol is less than the offset, but greater than
   2371       1.1     skrll 		 the line number we have found so far, then we have not
   2372       1.1     skrll 		 found the right line number.  */
   2373       1.1     skrll 	      if (q->symbol.value <= offset)
   2374       1.1     skrll 		{
   2375       1.1     skrll 		  if (q->symbol.value > low_line_vma)
   2376       1.1     skrll 		    {
   2377       1.1     skrll 		      *line_ptr = 0;
   2378       1.1     skrll 		      line_file_name = NULL;
   2379       1.1     skrll 		    }
   2380       1.1     skrll 		  if (q->symbol.value > low_func_vma)
   2381   1.1.1.9  christos 		    func = NULL;
   2382       1.1     skrll 		}
   2383       1.1     skrll 
   2384       1.1     skrll 	      main_file_name = current_file_name = q->symbol.name;
   2385       1.1     skrll 	      /* Look ahead to next symbol to check if that too is an N_SO.  */
   2386       1.1     skrll 	      p++;
   2387       1.1     skrll 	      if (*p == NULL)
   2388       1.1     skrll 		goto done;
   2389       1.1     skrll 	      q = (aout_symbol_type *)(*p);
   2390       1.1     skrll 	      if (q->type != (int) N_SO)
   2391       1.1     skrll 		goto next;
   2392       1.1     skrll 
   2393       1.1     skrll 	      /* Found a second N_SO  First is directory; second is filename.  */
   2394       1.1     skrll 	      directory_name = current_file_name;
   2395       1.1     skrll 	      main_file_name = current_file_name = q->symbol.name;
   2396       1.1     skrll 	      if (obj_textsec(abfd) != section)
   2397       1.1     skrll 		goto done;
   2398       1.1     skrll 	      break;
   2399       1.1     skrll 	    case N_SOL:
   2400       1.1     skrll 	      current_file_name = q->symbol.name;
   2401       1.1     skrll 	      break;
   2402       1.1     skrll 
   2403       1.1     skrll 	    case N_SLINE:
   2404       1.1     skrll 	    case N_DSLINE:
   2405       1.1     skrll 	    case N_BSLINE:
   2406       1.1     skrll 	      /* We'll keep this if it resolves nearer than the one we have
   2407       1.1     skrll 		 already.  */
   2408       1.1     skrll 	      if (q->symbol.value >= low_line_vma
   2409       1.1     skrll 		  && q->symbol.value <= offset)
   2410       1.1     skrll 		{
   2411       1.1     skrll 		  *line_ptr = q->desc;
   2412       1.1     skrll 		  low_line_vma = q->symbol.value;
   2413       1.1     skrll 		  line_file_name = current_file_name;
   2414       1.1     skrll 		}
   2415       1.1     skrll 	      break;
   2416       1.1     skrll 
   2417       1.1     skrll 	    case N_FUN:
   2418       1.1     skrll 	      {
   2419       1.1     skrll 		/* We'll keep this if it is nearer than the one we have already.  */
   2420       1.1     skrll 		if (q->symbol.value >= low_func_vma &&
   2421       1.1     skrll 		    q->symbol.value <= offset)
   2422       1.1     skrll 		  {
   2423       1.1     skrll 		    low_func_vma = q->symbol.value;
   2424       1.1     skrll 		    func = (asymbol *) q;
   2425       1.1     skrll 		  }
   2426       1.1     skrll 		else if (q->symbol.value > offset)
   2427       1.1     skrll 		  goto done;
   2428       1.1     skrll 	      }
   2429       1.1     skrll 	      break;
   2430       1.1     skrll 	    }
   2431       1.1     skrll 	}
   2432       1.1     skrll     }
   2433       1.1     skrll 
   2434       1.1     skrll  done:
   2435       1.1     skrll   if (*line_ptr != 0)
   2436       1.1     skrll     main_file_name = line_file_name;
   2437       1.1     skrll 
   2438       1.1     skrll   if (main_file_name == NULL
   2439       1.1     skrll       || main_file_name[0] == '/'
   2440       1.1     skrll       || directory_name == NULL)
   2441       1.1     skrll     filelen = 0;
   2442   1.1.1.9  christos   else
   2443       1.1     skrll     filelen = strlen (directory_name) + strlen (main_file_name);
   2444       1.1     skrll   if (func == NULL)
   2445       1.1     skrll     funclen = 0;
   2446       1.1     skrll   else
   2447       1.1     skrll     funclen = strlen (bfd_asymbol_name (func));
   2448       1.1     skrll 
   2449       1.1     skrll   free (adata (abfd).line_buf);
   2450   1.1.1.9  christos   if (filelen + funclen == 0)
   2451       1.1     skrll     adata (abfd).line_buf = buf = NULL;
   2452       1.1     skrll   else
   2453       1.1     skrll     {
   2454       1.1     skrll       buf = bfd_malloc ((bfd_size_type) filelen + funclen + 3);
   2455       1.1     skrll       adata (abfd).line_buf = buf;
   2456       1.1     skrll       if (buf == NULL)
   2457       1.1     skrll 	return false;
   2458       1.1     skrll     }
   2459   1.1.1.9  christos 
   2460   1.1.1.9  christos   if (main_file_name != NULL)
   2461   1.1.1.9  christos     {
   2462   1.1.1.9  christos       if (main_file_name[0] == '/' || directory_name == NULL)
   2463   1.1.1.9  christos 	*filename_ptr = main_file_name;
   2464   1.1.1.9  christos       else
   2465   1.1.1.9  christos 	{
   2466   1.1.1.9  christos 	  if (buf == NULL)
   2467   1.1.1.9  christos 	    /* PR binutils/20891: In a corrupt input file both
   2468   1.1.1.9  christos 	       main_file_name and directory_name can be empty...  */
   2469   1.1.1.9  christos 	    * filename_ptr = NULL;
   2470       1.1     skrll 	  else
   2471       1.1     skrll 	    {
   2472       1.1     skrll 	      snprintf (buf, filelen + 1, "%s%s", directory_name,
   2473       1.1     skrll 			main_file_name);
   2474       1.1     skrll 	      *filename_ptr = buf;
   2475       1.1     skrll 	      buf += filelen + 1;
   2476       1.1     skrll 	    }
   2477       1.1     skrll 	}
   2478   1.1.1.9  christos     }
   2479   1.1.1.9  christos 
   2480   1.1.1.9  christos   if (func)
   2481   1.1.1.9  christos     {
   2482   1.1.1.9  christos       const char *function = func->name;
   2483   1.1.1.9  christos       char *colon;
   2484       1.1     skrll 
   2485       1.1     skrll       if (buf == NULL)
   2486       1.1     skrll 	{
   2487       1.1     skrll 	  /* PR binutils/20892: In a corrupt input file func can be empty.  */
   2488       1.1     skrll 	  * functionname_ptr = NULL;
   2489       1.1     skrll 	  return true;
   2490       1.1     skrll 	}
   2491       1.1     skrll       /* The caller expects a symbol name.  We actually have a
   2492       1.1     skrll 	 function name, without the leading underscore.  Put the
   2493       1.1     skrll 	 underscore back in, so that the caller gets a symbol name.  */
   2494       1.1     skrll       if (bfd_get_symbol_leading_char (abfd) == '\0')
   2495       1.1     skrll 	strcpy (buf, function);
   2496       1.1     skrll       else
   2497       1.1     skrll 	{
   2498       1.1     skrll 	  buf[0] = bfd_get_symbol_leading_char (abfd);
   2499       1.1     skrll 	  strcpy (buf + 1, function);
   2500       1.1     skrll 	}
   2501       1.1     skrll 
   2502   1.1.1.9  christos       /* Have to remove : stuff.  */
   2503       1.1     skrll       colon = strchr (buf, ':');
   2504       1.1     skrll       if (colon != NULL)
   2505       1.1     skrll 	*colon = '\0';
   2506       1.1     skrll       *functionname_ptr = buf;
   2507       1.1     skrll     }
   2508       1.1     skrll 
   2509       1.1     skrll   return true;
   2510       1.1     skrll }
   2511       1.1     skrll 
   2512  1.1.1.10  christos int
   2513       1.1     skrll NAME (aout, sizeof_headers) (bfd *abfd,
   2514   1.1.1.9  christos 			     struct bfd_link_info *info ATTRIBUTE_UNUSED)
   2515       1.1     skrll {
   2516       1.1     skrll   return adata (abfd).exec_bytes_size;
   2517  1.1.1.10  christos }
   2518  1.1.1.10  christos 
   2519  1.1.1.10  christos /* Throw away most malloc'd and alloc'd information for this BFD.  */
   2520  1.1.1.10  christos 
   2521   1.1.1.9  christos bool
   2522  1.1.1.10  christos NAME (aout, bfd_free_cached_info) (bfd *abfd)
   2523  1.1.1.10  christos {
   2524  1.1.1.10  christos   if ((bfd_get_format (abfd) == bfd_object
   2525  1.1.1.10  christos        || bfd_get_format (abfd) == bfd_core)
   2526  1.1.1.10  christos       && abfd->tdata.aout_data != NULL)
   2527  1.1.1.10  christos     {
   2528       1.1     skrll #define BFCI_FREE(x) do { free (x); x = NULL; } while (0)
   2529  1.1.1.10  christos       BFCI_FREE (adata (abfd).line_buf);
   2530       1.1     skrll       BFCI_FREE (obj_aout_symbols (abfd));
   2531  1.1.1.10  christos       BFCI_FREE (obj_aout_external_syms (abfd));
   2532       1.1     skrll       BFCI_FREE (obj_aout_external_strings (abfd));
   2533       1.1     skrll       for (asection *o = abfd->sections; o != NULL; o = o->next)
   2534       1.1     skrll 	BFCI_FREE (o->relocation);
   2535       1.1     skrll #undef BFCI_FREE
   2536       1.1     skrll     }
   2537       1.1     skrll 
   2538       1.1     skrll   return _bfd_generic_bfd_free_cached_info (abfd);
   2539       1.1     skrll }
   2540       1.1     skrll 
   2541       1.1     skrll /* Routine to create an entry in an a.out link hash table.  */
   2543       1.1     skrll 
   2544       1.1     skrll struct bfd_hash_entry *
   2545       1.1     skrll NAME (aout, link_hash_newfunc) (struct bfd_hash_entry *entry,
   2546       1.1     skrll 				struct bfd_hash_table *table,
   2547       1.1     skrll 				const char *string)
   2548       1.1     skrll {
   2549       1.1     skrll   struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
   2550       1.1     skrll 
   2551       1.1     skrll   /* Allocate the structure if it has not already been allocated by a
   2552       1.1     skrll      subclass.  */
   2553       1.1     skrll   if (ret == NULL)
   2554       1.1     skrll     ret = bfd_hash_allocate (table, sizeof (* ret));
   2555       1.1     skrll   if (ret == NULL)
   2556   1.1.1.9  christos     return NULL;
   2557       1.1     skrll 
   2558       1.1     skrll   /* Call the allocation method of the superclass.  */
   2559       1.1     skrll   ret = (struct aout_link_hash_entry *)
   2560       1.1     skrll 	 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string);
   2561       1.1     skrll   if (ret)
   2562       1.1     skrll     {
   2563       1.1     skrll       /* Set local fields.  */
   2564       1.1     skrll       ret->written = false;
   2565   1.1.1.9  christos       ret->indx = -1;
   2566       1.1     skrll     }
   2567       1.1     skrll 
   2568       1.1     skrll   return (struct bfd_hash_entry *) ret;
   2569       1.1     skrll }
   2570       1.1     skrll 
   2571       1.1     skrll /* Initialize an a.out link hash table.  */
   2572       1.1     skrll 
   2573       1.1     skrll bool
   2574       1.1     skrll NAME (aout, link_hash_table_init) (struct aout_link_hash_table *table,
   2575       1.1     skrll 				   bfd *abfd,
   2576       1.1     skrll 				   struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
   2577       1.1     skrll 								     struct bfd_hash_table *,
   2578       1.1     skrll 								     const char *),
   2579       1.1     skrll 				   unsigned int entsize)
   2580       1.1     skrll {
   2581       1.1     skrll   return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
   2582   1.1.1.9  christos }
   2583       1.1     skrll 
   2584   1.1.1.4  christos /* Create an a.out link hash table.  */
   2585       1.1     skrll 
   2586       1.1     skrll struct bfd_link_hash_table *
   2587       1.1     skrll NAME (aout, link_hash_table_create) (bfd *abfd)
   2588       1.1     skrll {
   2589       1.1     skrll   struct aout_link_hash_table *ret;
   2590       1.1     skrll   size_t amt = sizeof (struct aout_link_hash_table);
   2591       1.1     skrll 
   2592       1.1     skrll   ret = bfd_malloc (amt);
   2593       1.1     skrll   if (ret == NULL)
   2594       1.1     skrll     return NULL;
   2595       1.1     skrll   if (! NAME (aout, link_hash_table_init) (ret, abfd,
   2596       1.1     skrll 					   NAME (aout, link_hash_newfunc),
   2597       1.1     skrll 					   sizeof (struct aout_link_hash_entry)))
   2598       1.1     skrll     {
   2599   1.1.1.9  christos       free (ret);
   2600       1.1     skrll       return NULL;
   2601       1.1     skrll     }
   2602       1.1     skrll   return &ret->root;
   2603       1.1     skrll }
   2604       1.1     skrll 
   2605       1.1     skrll /* Free up the internal symbols read from an a.out file.  */
   2606       1.1     skrll 
   2607       1.1     skrll static bool
   2608       1.1     skrll aout_link_free_symbols (bfd *abfd)
   2609       1.1     skrll {
   2610       1.1     skrll   if (obj_aout_external_syms (abfd) != NULL)
   2611       1.1     skrll     {
   2612       1.1     skrll       free ((void *) obj_aout_external_syms (abfd));
   2613   1.1.1.9  christos       obj_aout_external_syms (abfd) = NULL;
   2614       1.1     skrll     }
   2615       1.1     skrll 
   2616       1.1     skrll   if (obj_aout_external_strings (abfd) != NULL)
   2617       1.1     skrll     {
   2618       1.1     skrll       free ((void *) obj_aout_external_strings (abfd));
   2619   1.1.1.9  christos       obj_aout_external_strings (abfd) = NULL;
   2620       1.1     skrll     }
   2621       1.1     skrll   return true;
   2622       1.1     skrll }
   2623       1.1     skrll 
   2624       1.1     skrll /* Given an a.out BFD, add symbols to the global hash table as
   2625       1.1     skrll    appropriate.  */
   2626       1.1     skrll 
   2627       1.1     skrll bool
   2628       1.1     skrll NAME (aout, link_add_symbols) (bfd *abfd, struct bfd_link_info *info)
   2629       1.1     skrll {
   2630       1.1     skrll   switch (bfd_get_format (abfd))
   2631   1.1.1.9  christos     {
   2632       1.1     skrll     case bfd_object:
   2633       1.1     skrll       return aout_link_add_object_symbols (abfd, info);
   2634       1.1     skrll     case bfd_archive:
   2635       1.1     skrll       return _bfd_generic_link_add_archive_symbols
   2636       1.1     skrll 	(abfd, info, aout_link_check_archive_element);
   2637   1.1.1.9  christos     default:
   2638       1.1     skrll       bfd_set_error (bfd_error_wrong_format);
   2639       1.1     skrll       return false;
   2640       1.1     skrll     }
   2641   1.1.1.9  christos }
   2642       1.1     skrll 
   2643   1.1.1.9  christos /* Add symbols from an a.out object file.  */
   2644       1.1     skrll 
   2645       1.1     skrll static bool
   2646       1.1     skrll aout_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
   2647   1.1.1.9  christos {
   2648       1.1     skrll   if (! aout_get_external_symbols (abfd))
   2649   1.1.1.9  christos     return false;
   2650       1.1     skrll   if (! aout_link_add_symbols (abfd, info))
   2651       1.1     skrll     return false;
   2652       1.1     skrll   if (! info->keep_memory)
   2653       1.1     skrll     {
   2654       1.1     skrll       if (! aout_link_free_symbols (abfd))
   2655       1.1     skrll 	return false;
   2656       1.1     skrll     }
   2657       1.1     skrll   return true;
   2658       1.1     skrll }
   2659   1.1.1.9  christos 
   2660       1.1     skrll /* Look through the internal symbols to see if this object file should
   2661       1.1     skrll    be included in the link.  We should include this object file if it
   2662   1.1.1.9  christos    defines any symbols which are currently undefined.  If this object
   2663   1.1.1.2  christos    file defines a common symbol, then we may adjust the size of the
   2664       1.1     skrll    known symbol but we do not include the object file in the link
   2665       1.1     skrll    (unless there is some other reason to include it).  */
   2666       1.1     skrll 
   2667       1.1     skrll static bool
   2668       1.1     skrll aout_link_check_ar_symbols (bfd *abfd,
   2669   1.1.1.9  christos 			    struct bfd_link_info *info,
   2670       1.1     skrll 			    bool *pneeded,
   2671       1.1     skrll 			    bfd **subsbfd)
   2672       1.1     skrll {
   2673       1.1     skrll   struct external_nlist *p;
   2674       1.1     skrll   struct external_nlist *pend;
   2675       1.1     skrll   char *strings;
   2676       1.1     skrll 
   2677       1.1     skrll   *pneeded = false;
   2678   1.1.1.9  christos 
   2679       1.1     skrll   /* Look through all the symbols.  */
   2680       1.1     skrll   p = obj_aout_external_syms (abfd);
   2681       1.1     skrll   pend = p + obj_aout_external_sym_count (abfd);
   2682       1.1     skrll   strings = obj_aout_external_strings (abfd);
   2683       1.1     skrll   for (; p < pend; p++)
   2684       1.1     skrll     {
   2685   1.1.1.9  christos       int type = H_GET_8 (abfd, p->e_type);
   2686       1.1     skrll       const char *name = strings + GET_WORD (abfd, p->e_strx);
   2687       1.1     skrll       struct bfd_link_hash_entry *h;
   2688       1.1     skrll 
   2689   1.1.1.9  christos       /* Ignore symbols that are not externally visible.  This is an
   2690       1.1     skrll 	 optimization only, as we check the type more thoroughly
   2691       1.1     skrll 	 below.  */
   2692       1.1     skrll       if ((type & N_EXT) == 0
   2693       1.1     skrll 	  || is_stab(type, name)
   2694       1.1     skrll 	  || type == N_FN)
   2695       1.1     skrll 	continue;
   2696       1.1     skrll 
   2697       1.1     skrll       h = bfd_link_hash_lookup (info->hash, name, false, false, true);
   2698       1.1     skrll 
   2699       1.1     skrll       /* We are only interested in symbols that are currently
   2700       1.1     skrll 	 undefined or common.  */
   2701       1.1     skrll       if (h == NULL
   2702       1.1     skrll 	  || (h->type != bfd_link_hash_undefined
   2703       1.1     skrll 	      && h->type != bfd_link_hash_common))
   2704       1.1     skrll 	continue;
   2705       1.1     skrll 
   2706       1.1     skrll       if (type == (N_TEXT | N_EXT)
   2707       1.1     skrll 	  || type == (N_DATA | N_EXT)
   2708   1.1.1.6  christos 	  || type == (N_BSS | N_EXT)
   2709       1.1     skrll 	  || type == (N_ABS | N_EXT))
   2710   1.1.1.6  christos 	{
   2711       1.1     skrll 	  /* This object file defines this symbol.  We must link it
   2712       1.1     skrll 	     in.  This is true regardless of whether the current
   2713       1.1     skrll 	     definition of the symbol is undefined or common.  If the
   2714       1.1     skrll 	     current definition is common, we have a case in which we
   2715       1.1     skrll 	     have already seen an object file including
   2716       1.1     skrll 		 int a;
   2717       1.1     skrll 	     and this object file from the archive includes
   2718   1.1.1.2  christos 		 int a = 5;
   2719   1.1.1.2  christos 	     In such a case we must include this object file.
   2720   1.1.1.5  christos 
   2721   1.1.1.9  christos 	     FIXME: The SunOS 4.1.3 linker will pull in the archive
   2722   1.1.1.9  christos 	     element if the symbol is defined in the .data section,
   2723       1.1     skrll 	     but not if it is defined in the .text section.  That
   2724       1.1     skrll 	     seems a bit crazy to me, and I haven't implemented it.
   2725       1.1     skrll 	     However, it might be correct.  */
   2726       1.1     skrll 	  if (!(*info->callbacks
   2727       1.1     skrll 		->add_archive_element) (info, abfd, name, subsbfd))
   2728       1.1     skrll 	    continue;
   2729       1.1     skrll 	  *pneeded = true;
   2730       1.1     skrll 	  return true;
   2731       1.1     skrll 	}
   2732       1.1     skrll 
   2733       1.1     skrll       if (type == (N_UNDF | N_EXT))
   2734       1.1     skrll 	{
   2735       1.1     skrll 	  bfd_vma value;
   2736       1.1     skrll 
   2737       1.1     skrll 	  value = GET_WORD (abfd, p->e_value);
   2738       1.1     skrll 	  if (value != 0)
   2739       1.1     skrll 	    {
   2740       1.1     skrll 	      /* This symbol is common in the object from the archive
   2741       1.1     skrll 		 file.  */
   2742       1.1     skrll 	      if (h->type == bfd_link_hash_undefined)
   2743       1.1     skrll 		{
   2744       1.1     skrll 		  bfd *symbfd;
   2745       1.1     skrll 		  unsigned int power;
   2746   1.1.1.2  christos 
   2747   1.1.1.2  christos 		  symbfd = h->u.undef.abfd;
   2748   1.1.1.9  christos 		  if (symbfd == NULL)
   2749   1.1.1.9  christos 		    {
   2750   1.1.1.9  christos 		      /* This symbol was created as undefined from
   2751       1.1     skrll 			 outside BFD.  We assume that we should link
   2752       1.1     skrll 			 in the object file.  This is done for the -u
   2753       1.1     skrll 			 option in the linker.  */
   2754       1.1     skrll 		      if (!(*info->callbacks
   2755       1.1     skrll 			    ->add_archive_element) (info, abfd, name, subsbfd))
   2756       1.1     skrll 			return false;
   2757       1.1     skrll 		      *pneeded = true;
   2758   1.1.1.9  christos 		      return true;
   2759       1.1     skrll 		    }
   2760       1.1     skrll 		  /* Turn the current link symbol into a common
   2761       1.1     skrll 		     symbol.  It is already on the undefs list.  */
   2762       1.1     skrll 		  h->type = bfd_link_hash_common;
   2763       1.1     skrll 		  h->u.c.p = bfd_hash_allocate (&info->hash->table,
   2764       1.1     skrll 						sizeof (struct bfd_link_hash_common_entry));
   2765       1.1     skrll 		  if (h->u.c.p == NULL)
   2766       1.1     skrll 		    return false;
   2767       1.1     skrll 
   2768       1.1     skrll 		  h->u.c.size = value;
   2769       1.1     skrll 
   2770       1.1     skrll 		  /* FIXME: This isn't quite right.  The maximum
   2771       1.1     skrll 		     alignment of a common symbol should be set by the
   2772       1.1     skrll 		     architecture of the output file, not of the input
   2773       1.1     skrll 		     file.  */
   2774       1.1     skrll 		  power = bfd_log2 (value);
   2775       1.1     skrll 		  if (power > bfd_get_arch_info (abfd)->section_align_power)
   2776       1.1     skrll 		    power = bfd_get_arch_info (abfd)->section_align_power;
   2777       1.1     skrll 		  h->u.c.p->alignment_power = power;
   2778       1.1     skrll 
   2779       1.1     skrll 		  h->u.c.p->section = bfd_make_section_old_way (symbfd,
   2780       1.1     skrll 								"COMMON");
   2781       1.1     skrll 		}
   2782       1.1     skrll 	      else
   2783       1.1     skrll 		{
   2784       1.1     skrll 		  /* Adjust the size of the common symbol if
   2785       1.1     skrll 		     necessary.  */
   2786   1.1.1.9  christos 		  if (value > h->u.c.size)
   2787       1.1     skrll 		    h->u.c.size = value;
   2788       1.1     skrll 		}
   2789       1.1     skrll 	    }
   2790       1.1     skrll 	}
   2791       1.1     skrll     }
   2792       1.1     skrll 
   2793       1.1     skrll   /* We do not need this object file.  */
   2794   1.1.1.9  christos   return true;
   2795       1.1     skrll }
   2796       1.1     skrll 
   2797   1.1.1.4  christos /* Check a single archive element to see if we need to include it in
   2798   1.1.1.4  christos    the link.  *PNEEDED is set according to whether this element is
   2799   1.1.1.9  christos    needed in the link or not.  This is called from
   2800       1.1     skrll    _bfd_generic_link_add_archive_symbols.  */
   2801   1.1.1.2  christos 
   2802   1.1.1.9  christos static bool
   2803   1.1.1.2  christos aout_link_check_archive_element (bfd *abfd,
   2804   1.1.1.2  christos 				 struct bfd_link_info *info,
   2805   1.1.1.9  christos 				 struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
   2806       1.1     skrll 				 const char *name ATTRIBUTE_UNUSED,
   2807   1.1.1.2  christos 				 bool *pneeded)
   2808   1.1.1.2  christos {
   2809   1.1.1.9  christos   bfd *oldbfd;
   2810       1.1     skrll   bool needed;
   2811   1.1.1.2  christos 
   2812   1.1.1.2  christos   if (!aout_get_external_symbols (abfd))
   2813       1.1     skrll     return false;
   2814   1.1.1.2  christos 
   2815   1.1.1.2  christos   oldbfd = abfd;
   2816   1.1.1.2  christos   if (!aout_link_check_ar_symbols (abfd, info, pneeded, &abfd))
   2817   1.1.1.2  christos     return false;
   2818   1.1.1.2  christos 
   2819   1.1.1.2  christos   needed = *pneeded;
   2820   1.1.1.9  christos   if (needed)
   2821   1.1.1.2  christos     {
   2822   1.1.1.9  christos       /* Potentially, the add_archive_element hook may have set a
   2823   1.1.1.2  christos 	 substitute BFD for us.  */
   2824   1.1.1.2  christos       if (abfd != oldbfd)
   2825   1.1.1.9  christos 	{
   2826       1.1     skrll 	  if (!info->keep_memory
   2827       1.1     skrll 	      && !aout_link_free_symbols (oldbfd))
   2828   1.1.1.2  christos 	    return false;
   2829       1.1     skrll 	  if (!aout_get_external_symbols (abfd))
   2830   1.1.1.2  christos 	    return false;
   2831   1.1.1.9  christos 	}
   2832       1.1     skrll       if (!aout_link_add_symbols (abfd, info))
   2833       1.1     skrll 	return false;
   2834   1.1.1.9  christos     }
   2835       1.1     skrll 
   2836       1.1     skrll   if (!info->keep_memory || !needed)
   2837       1.1     skrll     {
   2838       1.1     skrll       if (!aout_link_free_symbols (abfd))
   2839   1.1.1.9  christos 	return false;
   2840       1.1     skrll     }
   2841       1.1     skrll 
   2842       1.1     skrll   return true;
   2843       1.1     skrll }
   2844       1.1     skrll 
   2845   1.1.1.9  christos /* Add all symbols from an object file to the hash table.  */
   2846       1.1     skrll 
   2847       1.1     skrll static bool
   2848       1.1     skrll aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
   2849       1.1     skrll {
   2850       1.1     skrll   struct external_nlist *syms;
   2851       1.1     skrll   bfd_size_type sym_count;
   2852       1.1     skrll   char *strings;
   2853       1.1     skrll   bool copy;
   2854   1.1.1.9  christos   struct aout_link_hash_entry **sym_hash;
   2855       1.1     skrll   struct external_nlist *p;
   2856   1.1.1.9  christos   struct external_nlist *pend;
   2857       1.1     skrll 
   2858       1.1     skrll   syms = obj_aout_external_syms (abfd);
   2859       1.1     skrll   sym_count = obj_aout_external_sym_count (abfd);
   2860       1.1     skrll   strings = obj_aout_external_strings (abfd);
   2861       1.1     skrll   if (info->keep_memory)
   2862   1.1.1.9  christos     copy = false;
   2863       1.1     skrll   else
   2864       1.1     skrll     copy = true;
   2865       1.1     skrll 
   2866       1.1     skrll   if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
   2867       1.1     skrll     {
   2868       1.1     skrll       if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
   2869       1.1     skrll 	     (abfd, info, &syms, &sym_count, &strings)))
   2870       1.1     skrll 	return false;
   2871       1.1     skrll     }
   2872   1.1.1.9  christos 
   2873       1.1     skrll   /* We keep a list of the linker hash table entries that correspond
   2874       1.1     skrll      to particular symbols.  We could just look them up in the hash
   2875       1.1     skrll      table, but keeping the list is more efficient.  Perhaps this
   2876       1.1     skrll      should be conditional on info->keep_memory.  */
   2877       1.1     skrll   sym_hash = bfd_alloc (abfd,
   2878       1.1     skrll 			sym_count * sizeof (struct aout_link_hash_entry *));
   2879       1.1     skrll   if (sym_hash == NULL && sym_count != 0)
   2880       1.1     skrll     return false;
   2881       1.1     skrll   obj_aout_sym_hashes (abfd) = sym_hash;
   2882       1.1     skrll 
   2883       1.1     skrll   p = syms;
   2884       1.1     skrll   pend = p + sym_count;
   2885       1.1     skrll   for (; p < pend; p++, sym_hash++)
   2886       1.1     skrll     {
   2887       1.1     skrll       int type;
   2888       1.1     skrll       const char *name;
   2889       1.1     skrll       bfd_vma value;
   2890   1.1.1.9  christos       asection *section;
   2891   1.1.1.9  christos       flagword flags;
   2892   1.1.1.9  christos       const char *string;
   2893       1.1     skrll 
   2894   1.1.1.9  christos       *sym_hash = NULL;
   2895   1.1.1.9  christos 
   2896   1.1.1.9  christos       type = H_GET_8 (abfd, p->e_type);
   2897   1.1.1.9  christos 
   2898   1.1.1.9  christos       /* PR 19629: Corrupt binaries can contain illegal string offsets.  */
   2899       1.1     skrll       if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd))
   2900       1.1     skrll 	return false;
   2901       1.1     skrll       name = strings + GET_WORD (abfd, p->e_strx);
   2902       1.1     skrll 
   2903       1.1     skrll       /* Ignore debugging symbols.  */
   2904       1.1     skrll       if (is_stab (type, name))
   2905   1.1.1.9  christos 	continue;
   2906   1.1.1.9  christos 
   2907   1.1.1.3  christos       value = GET_WORD (abfd, p->e_value);
   2908       1.1     skrll       flags = BSF_GLOBAL;
   2909       1.1     skrll       string = NULL;
   2910       1.1     skrll       switch (type)
   2911       1.1     skrll 	{
   2912       1.1     skrll 	default:
   2913       1.1     skrll 	  /* Shouldn't be any types not covered.  */
   2914       1.1     skrll 	  BFD_ASSERT (0);
   2915       1.1     skrll 	  continue;
   2916       1.1     skrll 
   2917       1.1     skrll 	case N_UNDF:
   2918       1.1     skrll 	case N_ABS:
   2919       1.1     skrll 	case N_TEXT:
   2920       1.1     skrll 	case N_DATA:
   2921       1.1     skrll 	case N_BSS:
   2922       1.1     skrll 	case N_REG:
   2923       1.1     skrll 	case N_FN:
   2924       1.1     skrll 	  /* Ignore symbols that are not externally visible.  */
   2925       1.1     skrll 	  continue;
   2926       1.1     skrll 
   2927       1.1     skrll 	case N_UNDF | N_EXT:
   2928       1.1     skrll 	  if (value == 0)
   2929       1.1     skrll 	    {
   2930       1.1     skrll 	      section = bfd_und_section_ptr;
   2931       1.1     skrll 	      flags = 0;
   2932       1.1     skrll 	    }
   2933   1.1.1.8  christos 	  else
   2934       1.1     skrll 	    section = bfd_com_section_ptr;
   2935       1.1     skrll 	  break;
   2936       1.1     skrll 	case N_ABS | N_EXT:
   2937       1.1     skrll 	  section = bfd_abs_section_ptr;
   2938       1.1     skrll 	  break;
   2939   1.1.1.8  christos 	case N_TEXT | N_EXT:
   2940       1.1     skrll 	  section = obj_textsec (abfd);
   2941       1.1     skrll 	  value -= bfd_section_vma (section);
   2942       1.1     skrll 	  break;
   2943   1.1.1.8  christos 	case N_DATA | N_EXT:
   2944       1.1     skrll 	  /* Treat N_SETV symbols as N_DATA symbol; see comment in
   2945       1.1     skrll 	     translate_from_native_sym_flags.  */
   2946       1.1     skrll 	  section = obj_datasec (abfd);
   2947  1.1.1.11  christos 	  value -= bfd_section_vma (section);
   2948   1.1.1.9  christos 	  break;
   2949       1.1     skrll 	case N_BSS | N_EXT:
   2950   1.1.1.9  christos 	  section = obj_bsssec (abfd);
   2951       1.1     skrll 	  value -= bfd_section_vma (section);
   2952       1.1     skrll 	  break;
   2953       1.1     skrll 	}
   2954       1.1     skrll 
   2955       1.1     skrll       if (! (_bfd_generic_link_add_one_symbol
   2956       1.1     skrll 	     (info, abfd, name, flags, section, value, string, copy, false,
   2957       1.1     skrll 	      (struct bfd_link_hash_entry **) sym_hash)))
   2958       1.1     skrll 	return false;
   2959       1.1     skrll 
   2960       1.1     skrll       /* Restrict the maximum alignment of a common symbol based on
   2961       1.1     skrll 	 the architecture, since a.out has no way to represent
   2962       1.1     skrll 	 alignment requirements of a section in a .o file.  FIXME:
   2963       1.1     skrll 	 This isn't quite right: it should use the architecture of the
   2964       1.1     skrll 	 output file, not the input files.  */
   2965       1.1     skrll       if ((*sym_hash)->root.type == bfd_link_hash_common
   2966       1.1     skrll 	  && ((*sym_hash)->root.u.c.p->alignment_power >
   2967       1.1     skrll 	      bfd_get_arch_info (abfd)->section_align_power))
   2968       1.1     skrll 	(*sym_hash)->root.u.c.p->alignment_power =
   2969       1.1     skrll 	  bfd_get_arch_info (abfd)->section_align_power;
   2970       1.1     skrll 
   2971       1.1     skrll       /* If this is a set symbol, and we are not building sets, then
   2972       1.1     skrll 	 it is possible for the hash entry to not have been set.  In
   2973   1.1.1.9  christos 	 such a case, treat the symbol as not globally defined.  */
   2974       1.1     skrll       if ((*sym_hash)->root.type == bfd_link_hash_new)
   2975       1.1     skrll 	{
   2976       1.1     skrll 	  BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
   2977       1.1     skrll 	  *sym_hash = NULL;
   2978       1.1     skrll 	}
   2979       1.1     skrll     }
   2980       1.1     skrll 
   2981       1.1     skrll   return true;
   2982       1.1     skrll }
   2983       1.1     skrll 
   2984       1.1     skrll /* Look up an entry in an the header file hash table.  */
   2986       1.1     skrll 
   2987       1.1     skrll #define aout_link_includes_lookup(table, string, create, copy) \
   2988       1.1     skrll   ((struct aout_link_includes_entry *) \
   2989       1.1     skrll    bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
   2990       1.1     skrll 
   2991       1.1     skrll /* The function to create a new entry in the header file hash table.  */
   2992       1.1     skrll 
   2993       1.1     skrll static struct bfd_hash_entry *
   2994       1.1     skrll aout_link_includes_newfunc (struct bfd_hash_entry *entry,
   2995       1.1     skrll 			    struct bfd_hash_table *table,
   2996       1.1     skrll 			    const char *string)
   2997       1.1     skrll {
   2998       1.1     skrll   struct aout_link_includes_entry * ret =
   2999       1.1     skrll     (struct aout_link_includes_entry *) entry;
   3000       1.1     skrll 
   3001       1.1     skrll   /* Allocate the structure if it has not already been allocated by a
   3002       1.1     skrll      subclass.  */
   3003       1.1     skrll   if (ret == NULL)
   3004       1.1     skrll     ret = bfd_hash_allocate (table,
   3005       1.1     skrll 			     sizeof (struct aout_link_includes_entry));
   3006       1.1     skrll   if (ret == NULL)
   3007       1.1     skrll     return NULL;
   3008       1.1     skrll 
   3009       1.1     skrll   /* Call the allocation method of the superclass.  */
   3010   1.1.1.9  christos   ret = ((struct aout_link_includes_entry *)
   3011   1.1.1.9  christos 	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
   3012   1.1.1.9  christos   if (ret)
   3013   1.1.1.9  christos     /* Set local fields.  */
   3014   1.1.1.3  christos     ret->totals = NULL;
   3015       1.1     skrll 
   3016   1.1.1.3  christos   return (struct bfd_hash_entry *) ret;
   3017   1.1.1.3  christos }
   3018       1.1     skrll 
   3019       1.1     skrll /* Write out a symbol that was not associated with an a.out input
   3020       1.1     skrll    object.  */
   3021       1.1     skrll 
   3022       1.1     skrll static bool
   3023   1.1.1.9  christos aout_link_write_other_symbol (struct bfd_hash_entry *bh, void *data)
   3024       1.1     skrll {
   3025       1.1     skrll   struct aout_link_hash_entry *h = (struct aout_link_hash_entry *) bh;
   3026       1.1     skrll   struct aout_final_link_info *flaginfo = (struct aout_final_link_info *) data;
   3027       1.1     skrll   bfd *output_bfd;
   3028       1.1     skrll   int type;
   3029   1.1.1.9  christos   bfd_vma val;
   3030       1.1     skrll   struct external_nlist outsym;
   3031       1.1     skrll   bfd_size_type indx;
   3032   1.1.1.3  christos   size_t amt;
   3033       1.1     skrll 
   3034       1.1     skrll   if (h->root.type == bfd_link_hash_warning)
   3035       1.1     skrll     {
   3036       1.1     skrll       h = (struct aout_link_hash_entry *) h->root.u.i.link;
   3037   1.1.1.3  christos       if (h->root.type == bfd_link_hash_new)
   3038       1.1     skrll 	return true;
   3039       1.1     skrll     }
   3040       1.1     skrll 
   3041       1.1     skrll   output_bfd = flaginfo->output_bfd;
   3042       1.1     skrll 
   3043       1.1     skrll   if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
   3044       1.1     skrll     {
   3045   1.1.1.9  christos       if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
   3046       1.1     skrll 	     (output_bfd, flaginfo->info, h)))
   3047   1.1.1.9  christos 	{
   3048       1.1     skrll 	  /* FIXME: No way to handle errors.  */
   3049       1.1     skrll 	  abort ();
   3050       1.1     skrll 	}
   3051   1.1.1.3  christos     }
   3052   1.1.1.3  christos 
   3053   1.1.1.3  christos   if (h->written)
   3054   1.1.1.9  christos     return true;
   3055   1.1.1.9  christos 
   3056       1.1     skrll   h->written = true;
   3057       1.1     skrll 
   3058       1.1     skrll   /* An indx of -2 means the symbol must be written.  */
   3059       1.1     skrll   if (h->indx != -2
   3060       1.1     skrll       && (flaginfo->info->strip == strip_all
   3061       1.1     skrll 	  || (flaginfo->info->strip == strip_some
   3062   1.1.1.9  christos 	      && bfd_hash_lookup (flaginfo->info->keep_hash, h->root.root.string,
   3063       1.1     skrll 				  false, false) == NULL)))
   3064       1.1     skrll     return true;
   3065   1.1.1.6  christos 
   3066   1.1.1.9  christos   switch (h->root.type)
   3067       1.1     skrll     {
   3068       1.1     skrll     default:
   3069       1.1     skrll       abort ();
   3070       1.1     skrll       /* Avoid variable not initialized warnings.  */
   3071       1.1     skrll       return true;
   3072       1.1     skrll     case bfd_link_hash_new:
   3073       1.1     skrll       /* This can happen for set symbols when sets are not being
   3074       1.1     skrll 	 built.  */
   3075       1.1     skrll       return true;
   3076       1.1     skrll     case bfd_link_hash_undefined:
   3077       1.1     skrll       type = N_UNDF | N_EXT;
   3078       1.1     skrll       val = 0;
   3079       1.1     skrll       break;
   3080       1.1     skrll     case bfd_link_hash_defined:
   3081       1.1     skrll     case bfd_link_hash_defweak:
   3082       1.1     skrll       {
   3083       1.1     skrll 	asection *sec;
   3084       1.1     skrll 
   3085       1.1     skrll 	sec = h->root.u.def.section->output_section;
   3086       1.1     skrll 	BFD_ASSERT (bfd_is_abs_section (sec)
   3087       1.1     skrll 		    || sec->owner == output_bfd);
   3088       1.1     skrll 	if (sec == obj_textsec (output_bfd))
   3089       1.1     skrll 	  type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
   3090       1.1     skrll 	else if (sec == obj_datasec (output_bfd))
   3091       1.1     skrll 	  type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
   3092       1.1     skrll 	else if (sec == obj_bsssec (output_bfd))
   3093       1.1     skrll 	  type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
   3094       1.1     skrll 	else
   3095       1.1     skrll 	  type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
   3096       1.1     skrll 	type |= N_EXT;
   3097       1.1     skrll 	val = (h->root.u.def.value
   3098       1.1     skrll 	       + sec->vma
   3099       1.1     skrll 	       + h->root.u.def.section->output_offset);
   3100   1.1.1.6  christos       }
   3101       1.1     skrll       break;
   3102       1.1     skrll     case bfd_link_hash_common:
   3103       1.1     skrll       type = N_UNDF | N_EXT;
   3104       1.1     skrll       val = h->root.u.c.size;
   3105   1.1.1.9  christos       break;
   3106       1.1     skrll     case bfd_link_hash_undefweak:
   3107       1.1     skrll       type = N_WEAKU;
   3108       1.1     skrll       val = 0;
   3109   1.1.1.9  christos       /* Fall through.  */
   3110   1.1.1.3  christos     case bfd_link_hash_indirect:
   3111   1.1.1.9  christos     case bfd_link_hash_warning:
   3112       1.1     skrll       /* FIXME: Ignore these for now.  The circumstances under which
   3113       1.1     skrll 	 they should be written out are not clear to me.  */
   3114       1.1     skrll       return true;
   3115       1.1     skrll     }
   3116   1.1.1.9  christos 
   3117       1.1     skrll   H_PUT_8 (output_bfd, type, outsym.e_type);
   3118       1.1     skrll   H_PUT_8 (output_bfd, 0, outsym.e_ovly);
   3119       1.1     skrll   indx = add_to_stringtab (output_bfd, flaginfo->strtab, h->root.root.string,
   3120       1.1     skrll 			   false);
   3121   1.1.1.3  christos   if (indx == (bfd_size_type) -1)
   3122  1.1.1.10  christos     /* FIXME: No way to handle errors.  */
   3123       1.1     skrll     abort ();
   3124       1.1     skrll 
   3125       1.1     skrll   PUT_WORD (output_bfd, 0, outsym.e_desc);
   3126   1.1.1.3  christos   PUT_WORD (output_bfd, indx, outsym.e_strx);
   3127       1.1     skrll   PUT_WORD (output_bfd, val, outsym.e_value);
   3128       1.1     skrll 
   3129       1.1     skrll   amt = EXTERNAL_NLIST_SIZE;
   3130   1.1.1.9  christos   if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0
   3131       1.1     skrll       || bfd_write (&outsym, amt, output_bfd) != amt)
   3132       1.1     skrll     /* FIXME: No way to handle errors.  */
   3133       1.1     skrll     abort ();
   3134       1.1     skrll 
   3135   1.1.1.9  christos   flaginfo->symoff += amt;
   3136   1.1.1.3  christos   h->indx = obj_aout_external_sym_count (output_bfd);
   3137       1.1     skrll   ++obj_aout_external_sym_count (output_bfd);
   3138       1.1     skrll 
   3139       1.1     skrll   return true;
   3140       1.1     skrll }
   3141       1.1     skrll 
   3142       1.1     skrll /* Handle a link order which is supposed to generate a reloc.  */
   3143       1.1     skrll 
   3144       1.1     skrll static bool
   3145       1.1     skrll aout_link_reloc_link_order (struct aout_final_link_info *flaginfo,
   3146       1.1     skrll 			    asection *o,
   3147       1.1     skrll 			    struct bfd_link_order *p)
   3148       1.1     skrll {
   3149       1.1     skrll   struct bfd_link_order_reloc *pr;
   3150       1.1     skrll   int r_index;
   3151       1.1     skrll   int r_extern;
   3152       1.1     skrll   reloc_howto_type *howto;
   3153       1.1     skrll   file_ptr *reloff_ptr;
   3154       1.1     skrll   struct reloc_std_external srel;
   3155       1.1     skrll   void * rel_ptr;
   3156       1.1     skrll   bfd_size_type rel_size;
   3157       1.1     skrll 
   3158   1.1.1.3  christos   pr = p->u.reloc.p;
   3159       1.1     skrll 
   3160       1.1     skrll   if (p->type == bfd_section_reloc_link_order)
   3161       1.1     skrll     {
   3162       1.1     skrll       r_extern = 0;
   3163       1.1     skrll       if (bfd_is_abs_section (pr->u.section))
   3164       1.1     skrll 	r_index = N_ABS | N_EXT;
   3165       1.1     skrll       else
   3166       1.1     skrll 	{
   3167       1.1     skrll 	  BFD_ASSERT (pr->u.section->owner == flaginfo->output_bfd);
   3168       1.1     skrll 	  r_index = pr->u.section->target_index;
   3169   1.1.1.3  christos 	}
   3170   1.1.1.9  christos     }
   3171       1.1     skrll   else
   3172       1.1     skrll     {
   3173       1.1     skrll       struct aout_link_hash_entry *h;
   3174       1.1     skrll 
   3175       1.1     skrll       BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
   3176       1.1     skrll       r_extern = 1;
   3177       1.1     skrll       h = ((struct aout_link_hash_entry *)
   3178       1.1     skrll 	   bfd_wrapped_link_hash_lookup (flaginfo->output_bfd, flaginfo->info,
   3179       1.1     skrll 					 pr->u.name, false, false, true));
   3180       1.1     skrll       if (h != NULL
   3181   1.1.1.9  christos 	  && h->indx >= 0)
   3182   1.1.1.3  christos 	r_index = h->indx;
   3183   1.1.1.9  christos       else if (h != NULL)
   3184       1.1     skrll 	{
   3185       1.1     skrll 	  /* We decided to strip this symbol, but it turns out that we
   3186       1.1     skrll 	     can't.  Note that we lose the other and desc information
   3187       1.1     skrll 	     here.  I don't think that will ever matter for a global
   3188   1.1.1.5  christos 	     symbol.  */
   3189   1.1.1.5  christos 	  h->indx = -2;
   3190       1.1     skrll 	  h->written = false;
   3191       1.1     skrll 	  if (!aout_link_write_other_symbol (&h->root.root, flaginfo))
   3192       1.1     skrll 	    return false;
   3193       1.1     skrll 	  r_index = h->indx;
   3194   1.1.1.3  christos 	}
   3195       1.1     skrll       else
   3196       1.1     skrll 	{
   3197       1.1     skrll 	  (*flaginfo->info->callbacks->unattached_reloc)
   3198   1.1.1.9  christos 	    (flaginfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0);
   3199       1.1     skrll 	  r_index = 0;
   3200       1.1     skrll 	}
   3201   1.1.1.3  christos     }
   3202   1.1.1.3  christos 
   3203   1.1.1.3  christos   howto = bfd_reloc_type_lookup (flaginfo->output_bfd, pr->reloc);
   3204   1.1.1.3  christos   if (howto == 0)
   3205       1.1     skrll     {
   3206       1.1     skrll       bfd_set_error (bfd_error_bad_value);
   3207       1.1     skrll       return false;
   3208       1.1     skrll     }
   3209   1.1.1.3  christos 
   3210       1.1     skrll   if (o == obj_textsec (flaginfo->output_bfd))
   3211       1.1     skrll     reloff_ptr = &flaginfo->treloff;
   3212       1.1     skrll   else if (o == obj_datasec (flaginfo->output_bfd))
   3213       1.1     skrll     reloff_ptr = &flaginfo->dreloff;
   3214       1.1     skrll   else
   3215       1.1     skrll     abort ();
   3216       1.1     skrll 
   3217       1.1     skrll #ifdef MY_put_reloc
   3218       1.1     skrll   MY_put_reloc(flaginfo->output_bfd, r_extern, r_index, p->offset, howto,
   3219       1.1     skrll 	       &srel);
   3220       1.1     skrll #else
   3221       1.1     skrll   {
   3222       1.1     skrll     int r_pcrel;
   3223       1.1     skrll     int r_baserel;
   3224       1.1     skrll     int r_jmptable;
   3225   1.1.1.9  christos     int r_relative;
   3226       1.1     skrll     int r_length;
   3227   1.1.1.3  christos 
   3228   1.1.1.3  christos     fprintf (stderr, "TODO: line %d in bfd/pdp11.c\n", __LINE__);
   3229       1.1     skrll 
   3230       1.1     skrll     r_pcrel = howto->pc_relative;
   3231       1.1     skrll     r_baserel = (howto->type & 8) != 0;
   3232       1.1     skrll     r_jmptable = (howto->type & 16) != 0;
   3233       1.1     skrll     r_relative = (howto->type & 32) != 0;
   3234       1.1     skrll     r_length = bfd_log2 (bfd_get_reloc_size (howto));
   3235       1.1     skrll 
   3236       1.1     skrll     PUT_WORD (flaginfo->output_bfd, p->offset, srel.r_address);
   3237       1.1     skrll     if (bfd_header_big_endian (flaginfo->output_bfd))
   3238       1.1     skrll       {
   3239       1.1     skrll 	srel.r_index[0] = r_index >> 16;
   3240       1.1     skrll 	srel.r_index[1] = r_index >> 8;
   3241       1.1     skrll 	srel.r_index[2] = r_index;
   3242       1.1     skrll 	srel.r_type[0] =
   3243       1.1     skrll 	  ((r_extern ?     RELOC_STD_BITS_EXTERN_BIG : 0)
   3244       1.1     skrll 	   | (r_pcrel ?    RELOC_STD_BITS_PCREL_BIG : 0)
   3245       1.1     skrll 	   | (r_baserel ?  RELOC_STD_BITS_BASEREL_BIG : 0)
   3246       1.1     skrll 	   | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
   3247       1.1     skrll 	   | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
   3248       1.1     skrll 	   | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
   3249       1.1     skrll       }
   3250       1.1     skrll     else
   3251       1.1     skrll       {
   3252       1.1     skrll 	srel.r_index[2] = r_index >> 16;
   3253       1.1     skrll 	srel.r_index[1] = r_index >> 8;
   3254       1.1     skrll 	srel.r_index[0] = r_index;
   3255       1.1     skrll 	srel.r_type[0] =
   3256       1.1     skrll 	  ((r_extern ?     RELOC_STD_BITS_EXTERN_LITTLE : 0)
   3257       1.1     skrll 	   | (r_pcrel ?    RELOC_STD_BITS_PCREL_LITTLE : 0)
   3258       1.1     skrll 	   | (r_baserel ?  RELOC_STD_BITS_BASEREL_LITTLE : 0)
   3259       1.1     skrll 	   | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
   3260       1.1     skrll 	   | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
   3261       1.1     skrll 	   | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
   3262       1.1     skrll       }
   3263       1.1     skrll   }
   3264       1.1     skrll #endif
   3265       1.1     skrll   rel_ptr = (void *) &srel;
   3266       1.1     skrll 
   3267       1.1     skrll   /* We have to write the addend into the object file, since
   3268   1.1.1.9  christos      standard a.out relocs are in place.  It would be more
   3269       1.1     skrll      reliable if we had the current contents of the file here,
   3270       1.1     skrll      rather than assuming zeroes, but we can't read the file since
   3271       1.1     skrll      it was opened using bfd_openw.  */
   3272   1.1.1.4  christos   if (pr->addend != 0)
   3273   1.1.1.9  christos     {
   3274   1.1.1.3  christos       bfd_size_type size;
   3275       1.1     skrll       bfd_reloc_status_type r;
   3276       1.1     skrll       bfd_byte *buf;
   3277       1.1     skrll       bool ok;
   3278       1.1     skrll 
   3279       1.1     skrll       size = bfd_get_reloc_size (howto);
   3280       1.1     skrll       buf = bfd_zmalloc (size);
   3281       1.1     skrll       if (buf == NULL && size != 0)
   3282       1.1     skrll 	return false;
   3283       1.1     skrll       r = MY_relocate_contents (howto, flaginfo->output_bfd,
   3284   1.1.1.5  christos 				pr->addend, buf);
   3285   1.1.1.5  christos       switch (r)
   3286   1.1.1.5  christos 	{
   3287   1.1.1.8  christos 	case bfd_reloc_ok:
   3288   1.1.1.5  christos 	  break;
   3289   1.1.1.5  christos 	default:
   3290   1.1.1.5  christos 	case bfd_reloc_outofrange:
   3291       1.1     skrll 	  abort ();
   3292       1.1     skrll 	case bfd_reloc_overflow:
   3293   1.1.1.3  christos 	  (*flaginfo->info->callbacks->reloc_overflow)
   3294       1.1     skrll 	    (flaginfo->info, NULL,
   3295       1.1     skrll 	     (p->type == bfd_section_reloc_link_order
   3296       1.1     skrll 	      ? bfd_section_name (pr->u.section)
   3297       1.1     skrll 	      : pr->u.name),
   3298       1.1     skrll 	     howto->name, pr->addend, NULL,
   3299   1.1.1.9  christos 	     (asection *) NULL, (bfd_vma) 0);
   3300       1.1     skrll 	  break;
   3301       1.1     skrll 	}
   3302   1.1.1.3  christos       ok = bfd_set_section_contents (flaginfo->output_bfd, o,
   3303   1.1.1.3  christos 				     (void *) buf,
   3304  1.1.1.10  christos 				     (file_ptr) p->offset,
   3305   1.1.1.9  christos 				     size);
   3306       1.1     skrll       free (buf);
   3307       1.1     skrll       if (! ok)
   3308       1.1     skrll 	return false;
   3309       1.1     skrll     }
   3310       1.1     skrll 
   3311   1.1.1.3  christos   rel_size = obj_reloc_entry_size (flaginfo->output_bfd);
   3312   1.1.1.3  christos   if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
   3313       1.1     skrll       || bfd_write (rel_ptr, rel_size, flaginfo->output_bfd) != rel_size)
   3314   1.1.1.3  christos     return false;
   3315       1.1     skrll 
   3316   1.1.1.9  christos   *reloff_ptr += rel_size;
   3317       1.1     skrll 
   3318       1.1     skrll   /* Assert that the relocs have not run into the symbols, and that n
   3319       1.1     skrll      the text relocs have not run into the data relocs.  */
   3320       1.1     skrll   BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd)
   3321       1.1     skrll 	      && (reloff_ptr != &flaginfo->treloff
   3322       1.1     skrll 		  || (*reloff_ptr
   3323       1.1     skrll 		      <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
   3324       1.1     skrll 
   3325       1.1     skrll   return true;
   3326       1.1     skrll }
   3327       1.1     skrll 
   3328       1.1     skrll /* Get the section corresponding to a reloc index.  */
   3329       1.1     skrll 
   3330       1.1     skrll static inline asection *
   3331       1.1     skrll aout_reloc_type_to_section (bfd *abfd, int type)
   3332       1.1     skrll {
   3333       1.1     skrll   switch (type)
   3334       1.1     skrll     {
   3335   1.1.1.9  christos     case RTEXT:	return obj_textsec (abfd);
   3336   1.1.1.3  christos     case RDATA: return obj_datasec (abfd);
   3337       1.1     skrll     case RBSS:  return obj_bsssec (abfd);
   3338       1.1     skrll     case RABS:  return bfd_abs_section_ptr;
   3339       1.1     skrll     case REXT:  return bfd_und_section_ptr;
   3340       1.1     skrll     default:    abort ();
   3341       1.1     skrll     }
   3342       1.1     skrll }
   3343   1.1.1.9  christos 
   3344       1.1     skrll static bool
   3345   1.1.1.9  christos pdp11_aout_link_input_section (struct aout_final_link_info *flaginfo,
   3346       1.1     skrll 			       bfd *input_bfd,
   3347   1.1.1.9  christos 			       asection *input_section,
   3348       1.1     skrll 			       bfd_byte *relocs,
   3349       1.1     skrll 			       bfd_size_type rel_size,
   3350       1.1     skrll 			       bfd_byte *contents)
   3351       1.1     skrll {
   3352       1.1     skrll   bool (*check_dynamic_reloc)
   3353       1.1     skrll     (struct bfd_link_info *, bfd *, asection *,
   3354       1.1     skrll      struct aout_link_hash_entry *, void *, bfd_byte *, bool *, bfd_vma *);
   3355   1.1.1.3  christos   bfd *output_bfd;
   3356       1.1     skrll   bool relocatable;
   3357       1.1     skrll   struct external_nlist *syms;
   3358       1.1     skrll   char *strings;
   3359       1.1     skrll   struct aout_link_hash_entry **sym_hashes;
   3360       1.1     skrll   int *symbol_map;
   3361       1.1     skrll   bfd_byte *rel;
   3362   1.1.1.4  christos   bfd_byte *rel_end;
   3363       1.1     skrll 
   3364       1.1     skrll   output_bfd = flaginfo->output_bfd;
   3365       1.1     skrll   check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
   3366   1.1.1.3  christos 
   3367       1.1     skrll   BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_SIZE);
   3368       1.1     skrll   BFD_ASSERT (input_bfd->xvec->header_byteorder
   3369       1.1     skrll 	      == output_bfd->xvec->header_byteorder);
   3370       1.1     skrll 
   3371       1.1     skrll   relocatable = bfd_link_relocatable (flaginfo->info);
   3372       1.1     skrll   syms = obj_aout_external_syms (input_bfd);
   3373       1.1     skrll   strings = obj_aout_external_strings (input_bfd);
   3374       1.1     skrll   sym_hashes = obj_aout_sym_hashes (input_bfd);
   3375       1.1     skrll   symbol_map = flaginfo->symbol_map;
   3376       1.1     skrll 
   3377       1.1     skrll   rel = relocs;
   3378       1.1     skrll   rel_end = rel + rel_size;
   3379       1.1     skrll   for (; rel < rel_end; rel += RELOC_SIZE)
   3380       1.1     skrll     {
   3381       1.1     skrll       bfd_vma r_addr;
   3382       1.1     skrll       int r_index;
   3383       1.1     skrll       int r_type;
   3384       1.1     skrll       int r_pcrel;
   3385       1.1     skrll       int r_extern;
   3386       1.1     skrll       reloc_howto_type *howto;
   3387       1.1     skrll       struct aout_link_hash_entry *h = NULL;
   3388       1.1     skrll       bfd_vma relocation;
   3389       1.1     skrll       bfd_reloc_status_type r;
   3390       1.1     skrll       int reloc_entry;
   3391       1.1     skrll 
   3392       1.1     skrll       reloc_entry = GET_WORD (input_bfd, (void *) rel);
   3393       1.1     skrll       if (reloc_entry == 0)
   3394       1.1     skrll 	continue;
   3395       1.1     skrll 
   3396       1.1     skrll       {
   3397       1.1     skrll 	unsigned int howto_idx;
   3398   1.1.1.9  christos 
   3399   1.1.1.9  christos 	r_index = (reloc_entry & RIDXMASK) >> 4;
   3400   1.1.1.9  christos 	r_type = reloc_entry & RTYPE;
   3401   1.1.1.9  christos 	r_pcrel = reloc_entry & RELFLG;
   3402   1.1.1.9  christos 	r_addr = (char *) rel - (char *) relocs;
   3403   1.1.1.9  christos 
   3404   1.1.1.9  christos 	r_extern = (r_type == REXT);
   3405   1.1.1.9  christos 
   3406   1.1.1.9  christos 	howto_idx = r_pcrel;
   3407       1.1     skrll 	if (howto_idx < TABLE_SIZE (howto_table_pdp11))
   3408       1.1     skrll 	  howto = howto_table_pdp11 + howto_idx;
   3409       1.1     skrll 	else
   3410       1.1     skrll 	  {
   3411       1.1     skrll 	    _bfd_error_handler (_("%pB: unsupported relocation type"),
   3412       1.1     skrll 				input_bfd);
   3413       1.1     skrll 	    bfd_set_error (bfd_error_bad_value);
   3414       1.1     skrll 	    return false;
   3415       1.1     skrll 	  }
   3416       1.1     skrll       }
   3417       1.1     skrll 
   3418       1.1     skrll       if (relocatable)
   3419       1.1     skrll 	{
   3420       1.1     skrll 	  /* We are generating a relocatable output file, and must
   3421       1.1     skrll 	     modify the reloc accordingly.  */
   3422       1.1     skrll 	  if (r_extern)
   3423       1.1     skrll 	    {
   3424       1.1     skrll 	      /* If we know the symbol this relocation is against,
   3425       1.1     skrll 		 convert it into a relocation against a section.  This
   3426       1.1     skrll 		 is what the native linker does.  */
   3427       1.1     skrll 	      h = sym_hashes[r_index];
   3428       1.1     skrll 	      if (h != NULL
   3429       1.1     skrll 		  && (h->root.type == bfd_link_hash_defined
   3430       1.1     skrll 		      || h->root.type == bfd_link_hash_defweak))
   3431       1.1     skrll 		{
   3432       1.1     skrll 		  asection *output_section;
   3433       1.1     skrll 
   3434       1.1     skrll 		  /* Compute a new r_index.  */
   3435       1.1     skrll 		  output_section = h->root.u.def.section->output_section;
   3436       1.1     skrll 		  if (output_section == obj_textsec (output_bfd))
   3437       1.1     skrll 		    r_type = N_TEXT;
   3438       1.1     skrll 		  else if (output_section == obj_datasec (output_bfd))
   3439       1.1     skrll 		    r_type = N_DATA;
   3440       1.1     skrll 		  else if (output_section == obj_bsssec (output_bfd))
   3441       1.1     skrll 		    r_type = N_BSS;
   3442       1.1     skrll 		  else
   3443       1.1     skrll 		    r_type = N_ABS;
   3444       1.1     skrll 
   3445       1.1     skrll 		  /* Add the symbol value and the section VMA to the
   3446       1.1     skrll 		     addend stored in the contents.  */
   3447       1.1     skrll 		  relocation = (h->root.u.def.value
   3448       1.1     skrll 				+ output_section->vma
   3449       1.1     skrll 				+ h->root.u.def.section->output_offset);
   3450       1.1     skrll 		}
   3451       1.1     skrll 	      else
   3452       1.1     skrll 		{
   3453   1.1.1.6  christos 		  /* We must change r_index according to the symbol
   3454   1.1.1.6  christos 		     map.  */
   3455   1.1.1.6  christos 		  r_index = symbol_map[r_index];
   3456   1.1.1.6  christos 
   3457       1.1     skrll 		  if (r_index == -1)
   3458       1.1     skrll 		    {
   3459       1.1     skrll 		      if (h != NULL)
   3460   1.1.1.9  christos 			{
   3461   1.1.1.3  christos 			  /* We decided to strip this symbol, but it
   3462   1.1.1.3  christos 			     turns out that we can't.  Note that we
   3463   1.1.1.9  christos 			     lose the other and desc information here.
   3464       1.1     skrll 			     I don't think that will ever matter for a
   3465       1.1     skrll 			     global symbol.  */
   3466       1.1     skrll 			  if (h->indx < 0)
   3467       1.1     skrll 			    {
   3468       1.1     skrll 			      h->indx = -2;
   3469       1.1     skrll 			      h->written = false;
   3470       1.1     skrll 			      if (!aout_link_write_other_symbol (&h->root.root,
   3471       1.1     skrll 								 flaginfo))
   3472       1.1     skrll 				return false;
   3473   1.1.1.5  christos 			    }
   3474   1.1.1.5  christos 			  r_index = h->indx;
   3475   1.1.1.5  christos 			}
   3476       1.1     skrll 		      else
   3477       1.1     skrll 			{
   3478       1.1     skrll 			  const char *name;
   3479       1.1     skrll 
   3480       1.1     skrll 			  name = strings + GET_WORD (input_bfd,
   3481       1.1     skrll 						     syms[r_index].e_strx);
   3482       1.1     skrll 			  (*flaginfo->info->callbacks->unattached_reloc)
   3483       1.1     skrll 			    (flaginfo->info, name, input_bfd, input_section,
   3484       1.1     skrll 			     r_addr);
   3485       1.1     skrll 			  r_index = 0;
   3486       1.1     skrll 			}
   3487       1.1     skrll 		    }
   3488       1.1     skrll 
   3489       1.1     skrll 		  relocation = 0;
   3490       1.1     skrll 		}
   3491       1.1     skrll 
   3492       1.1     skrll 	      /* Write out the new r_index value.  */
   3493       1.1     skrll 	      reloc_entry = GET_WORD (input_bfd, rel);
   3494       1.1     skrll 	      reloc_entry &= RIDXMASK;
   3495       1.1     skrll 	      reloc_entry |= r_index << 4;
   3496       1.1     skrll 	      PUT_WORD (input_bfd, reloc_entry, rel);
   3497       1.1     skrll 	    }
   3498       1.1     skrll 	  else
   3499       1.1     skrll 	    {
   3500       1.1     skrll 	      asection *section;
   3501       1.1     skrll 
   3502       1.1     skrll 	      /* This is a relocation against a section.  We must
   3503       1.1     skrll 		 adjust by the amount that the section moved.  */
   3504       1.1     skrll 	      section = aout_reloc_type_to_section (input_bfd, r_type);
   3505       1.1     skrll 	      relocation = (section->output_section->vma
   3506       1.1     skrll 			    + section->output_offset
   3507       1.1     skrll 			    - section->vma);
   3508       1.1     skrll 	    }
   3509       1.1     skrll 
   3510       1.1     skrll 	  /* Change the address of the relocation.  */
   3511       1.1     skrll 	  fprintf (stderr, "TODO: change the address of the relocation\n");
   3512       1.1     skrll 
   3513       1.1     skrll 	  /* Adjust a PC relative relocation by removing the reference
   3514       1.1     skrll 	     to the original address in the section and including the
   3515       1.1     skrll 	     reference to the new address.  */
   3516       1.1     skrll 	  if (r_pcrel)
   3517       1.1     skrll 	    relocation -= (input_section->output_section->vma
   3518       1.1     skrll 			   + input_section->output_offset
   3519       1.1     skrll 			   - input_section->vma);
   3520       1.1     skrll 
   3521       1.1     skrll #ifdef MY_relocatable_reloc
   3522       1.1     skrll 	  MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
   3523       1.1     skrll #endif
   3524       1.1     skrll 
   3525   1.1.1.9  christos 	  if (relocation == 0)
   3526       1.1     skrll 	    r = bfd_reloc_ok;
   3527       1.1     skrll 	  else
   3528       1.1     skrll 	    r = MY_relocate_contents (howto,
   3529   1.1.1.9  christos 				      input_bfd, relocation,
   3530       1.1     skrll 				      contents + r_addr);
   3531       1.1     skrll 	}
   3532       1.1     skrll       else
   3533       1.1     skrll 	{
   3534       1.1     skrll 	  bool hundef;
   3535       1.1     skrll 
   3536       1.1     skrll 	  /* We are generating an executable, and must do a full
   3537       1.1     skrll 	     relocation.  */
   3538       1.1     skrll 	  hundef = false;
   3539       1.1     skrll 	  if (r_extern)
   3540       1.1     skrll 	    {
   3541       1.1     skrll 	      h = sym_hashes[r_index];
   3542       1.1     skrll 
   3543       1.1     skrll 	      if (h != NULL
   3544       1.1     skrll 		  && (h->root.type == bfd_link_hash_defined
   3545       1.1     skrll 		      || h->root.type == bfd_link_hash_defweak))
   3546       1.1     skrll 		{
   3547   1.1.1.9  christos 		  relocation = (h->root.u.def.value
   3548       1.1     skrll 				+ h->root.u.def.section->output_section->vma
   3549       1.1     skrll 				+ h->root.u.def.section->output_offset);
   3550       1.1     skrll 		}
   3551       1.1     skrll 	      else if (h != NULL
   3552       1.1     skrll 		       && h->root.type == bfd_link_hash_undefweak)
   3553       1.1     skrll 		relocation = 0;
   3554       1.1     skrll 	      else
   3555       1.1     skrll 		{
   3556       1.1     skrll 		  hundef = true;
   3557       1.1     skrll 		  relocation = 0;
   3558       1.1     skrll 		}
   3559       1.1     skrll 	    }
   3560       1.1     skrll 	  else
   3561       1.1     skrll 	    {
   3562       1.1     skrll 	      asection *section;
   3563       1.1     skrll 
   3564       1.1     skrll 	      section = aout_reloc_type_to_section (input_bfd, r_type);
   3565   1.1.1.9  christos 	      relocation = (section->output_section->vma
   3566       1.1     skrll 			    + section->output_offset
   3567       1.1     skrll 			    - section->vma);
   3568   1.1.1.3  christos 	      if (r_pcrel)
   3569       1.1     skrll 		relocation += input_section->vma;
   3570   1.1.1.9  christos 	    }
   3571       1.1     skrll 
   3572       1.1     skrll 	  if (check_dynamic_reloc != NULL)
   3573       1.1     skrll 	    {
   3574       1.1     skrll 	      bool skip;
   3575       1.1     skrll 
   3576   1.1.1.6  christos 	      if (! ((*check_dynamic_reloc)
   3577   1.1.1.6  christos 		     (flaginfo->info, input_bfd, input_section, h,
   3578   1.1.1.4  christos 		      (void *) rel, contents, &skip, &relocation)))
   3579       1.1     skrll 		return false;
   3580       1.1     skrll 	      if (skip)
   3581       1.1     skrll 		continue;
   3582       1.1     skrll 	    }
   3583       1.1     skrll 
   3584       1.1     skrll 	  /* Now warn if a global symbol is undefined.  We could not
   3585       1.1     skrll 	     do this earlier, because check_dynamic_reloc might want
   3586   1.1.1.5  christos 	     to skip this reloc.  */
   3587   1.1.1.5  christos 	  if (hundef && ! bfd_link_pic (flaginfo->info))
   3588   1.1.1.9  christos 	    {
   3589       1.1     skrll 	      const char *name;
   3590       1.1     skrll 
   3591       1.1     skrll 	      if (h != NULL)
   3592       1.1     skrll 		name = h->root.root.string;
   3593       1.1     skrll 	      else
   3594       1.1     skrll 		name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
   3595       1.1     skrll 	      (*flaginfo->info->callbacks->undefined_symbol)
   3596       1.1     skrll 		(flaginfo->info, name, input_bfd, input_section,
   3597       1.1     skrll 		 r_addr, true);
   3598       1.1     skrll 	    }
   3599       1.1     skrll 
   3600       1.1     skrll 	  r = MY_final_link_relocate (howto,
   3601       1.1     skrll 				      input_bfd, input_section,
   3602       1.1     skrll 				      contents, r_addr, relocation,
   3603       1.1     skrll 				      (bfd_vma) 0);
   3604       1.1     skrll 	}
   3605       1.1     skrll 
   3606       1.1     skrll       if (r != bfd_reloc_ok)
   3607       1.1     skrll 	{
   3608       1.1     skrll 	  switch (r)
   3609       1.1     skrll 	    {
   3610       1.1     skrll 	    default:
   3611       1.1     skrll 	    case bfd_reloc_outofrange:
   3612       1.1     skrll 	      abort ();
   3613       1.1     skrll 	    case bfd_reloc_overflow:
   3614       1.1     skrll 	      {
   3615       1.1     skrll 		const char *name;
   3616       1.1     skrll 
   3617       1.1     skrll 		if (h != NULL)
   3618   1.1.1.8  christos 		  name = NULL;
   3619       1.1     skrll 		else if (r_extern)
   3620   1.1.1.5  christos 		  name = strings + GET_WORD (input_bfd,
   3621   1.1.1.5  christos 					     syms[r_index].e_strx);
   3622   1.1.1.5  christos 		else
   3623       1.1     skrll 		  {
   3624       1.1     skrll 		    asection *s;
   3625       1.1     skrll 
   3626       1.1     skrll 		    s = aout_reloc_type_to_section (input_bfd, r_type);
   3627       1.1     skrll 		    name = bfd_section_name (s);
   3628       1.1     skrll 		  }
   3629   1.1.1.9  christos 		(*flaginfo->info->callbacks->reloc_overflow)
   3630       1.1     skrll 		  (flaginfo->info, (h ? &h->root : NULL), name, howto->name,
   3631       1.1     skrll 		   (bfd_vma) 0, input_bfd, input_section, r_addr);
   3632       1.1     skrll 	      }
   3633       1.1     skrll 	      break;
   3634   1.1.1.9  christos 	    }
   3635   1.1.1.3  christos 	}
   3636       1.1     skrll     }
   3637       1.1     skrll 
   3638       1.1     skrll   return true;
   3639       1.1     skrll }
   3640       1.1     skrll 
   3641       1.1     skrll /* Link an a.out section into the output file.  */
   3642       1.1     skrll 
   3643       1.1     skrll static bool
   3644       1.1     skrll aout_link_input_section (struct aout_final_link_info *flaginfo,
   3645       1.1     skrll 			 bfd *input_bfd,
   3646       1.1     skrll 			 asection *input_section,
   3647   1.1.1.3  christos 			 file_ptr *reloff_ptr,
   3648       1.1     skrll 			 bfd_size_type rel_size)
   3649   1.1.1.9  christos {
   3650       1.1     skrll   bfd_size_type input_size;
   3651  1.1.1.11  christos   void * relocs;
   3652  1.1.1.11  christos 
   3653       1.1     skrll   /* Get the section contents.  */
   3654  1.1.1.11  christos   input_size = input_section->size;
   3655  1.1.1.11  christos   if (! bfd_get_section_contents (input_bfd, input_section,
   3656  1.1.1.11  christos 				  (void *) flaginfo->contents,
   3657       1.1     skrll 				  (file_ptr) 0, input_size))
   3658       1.1     skrll     return false;
   3659       1.1     skrll 
   3660   1.1.1.3  christos   relocs = flaginfo->relocs;
   3661       1.1     skrll   if (rel_size > 0)
   3662   1.1.1.3  christos     {
   3663   1.1.1.9  christos       if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
   3664       1.1     skrll 	  || bfd_read (relocs, rel_size, input_bfd) != rel_size)
   3665       1.1     skrll 	return false;
   3666   1.1.1.3  christos     }
   3667       1.1     skrll 
   3668   1.1.1.3  christos   /* Relocate the section contents.  */
   3669       1.1     skrll   if (! pdp11_aout_link_input_section (flaginfo, input_bfd, input_section,
   3670       1.1     skrll 				       (bfd_byte *) relocs,
   3671   1.1.1.9  christos 				       rel_size, flaginfo->contents))
   3672       1.1     skrll     return false;
   3673       1.1     skrll 
   3674       1.1     skrll   /* Write out the section contents.  */
   3675   1.1.1.4  christos   if (! bfd_set_section_contents (flaginfo->output_bfd,
   3676       1.1     skrll 				  input_section->output_section,
   3677   1.1.1.3  christos 				  (void *) flaginfo->contents,
   3678   1.1.1.9  christos 				  (file_ptr) input_section->output_offset,
   3679  1.1.1.10  christos 				  input_size))
   3680   1.1.1.9  christos     return false;
   3681       1.1     skrll 
   3682       1.1     skrll   /* If we are producing relocatable output, the relocs were
   3683       1.1     skrll      modified, and we now write them out.  */
   3684       1.1     skrll   if (bfd_link_relocatable (flaginfo->info) && rel_size > 0)
   3685       1.1     skrll     {
   3686   1.1.1.3  christos       if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
   3687   1.1.1.3  christos 	return false;
   3688       1.1     skrll       if (bfd_write (relocs, rel_size, flaginfo->output_bfd) != rel_size)
   3689   1.1.1.3  christos 	return false;
   3690       1.1     skrll       *reloff_ptr += rel_size;
   3691       1.1     skrll 
   3692   1.1.1.9  christos       /* Assert that the relocs have not run into the symbols, and
   3693       1.1     skrll 	 that if these are the text relocs they have not run into the
   3694       1.1     skrll 	 data relocs.  */
   3695       1.1     skrll       BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd)
   3696       1.1     skrll 		  && (reloff_ptr != &flaginfo->treloff
   3697   1.1.1.9  christos 		      || (*reloff_ptr
   3698   1.1.1.3  christos 			  <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
   3699       1.1     skrll     }
   3700       1.1     skrll 
   3701       1.1     skrll   return true;
   3702       1.1     skrll }
   3703       1.1     skrll 
   3704       1.1     skrll /* Link an a.out input BFD into the output file.  */
   3705       1.1     skrll 
   3706   1.1.1.3  christos static bool
   3707       1.1     skrll aout_link_input_bfd (struct aout_final_link_info *flaginfo, bfd *input_bfd)
   3708       1.1     skrll {
   3709   1.1.1.3  christos   BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
   3710       1.1     skrll 
   3711   1.1.1.9  christos   /* If this is a dynamic object, it may need special handling.  */
   3712       1.1     skrll   if ((input_bfd->flags & DYNAMIC) != 0
   3713       1.1     skrll       && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
   3714   1.1.1.3  christos     return ((*aout_backend_info (input_bfd)->link_dynamic_object)
   3715   1.1.1.3  christos 	    (flaginfo->info, input_bfd));
   3716   1.1.1.9  christos 
   3717       1.1     skrll   /* Get the symbols.  We probably have them already, unless
   3718       1.1     skrll      flaginfo->info->keep_memory is FALSE.  */
   3719       1.1     skrll   if (! aout_get_external_symbols (input_bfd))
   3720       1.1     skrll     return false;
   3721       1.1     skrll 
   3722       1.1     skrll   /* Write out the symbols and get a map of the new indices.  The map
   3723       1.1     skrll      is placed into flaginfo->symbol_map.  */
   3724   1.1.1.3  christos   if (! aout_link_write_symbols (flaginfo, input_bfd))
   3725       1.1     skrll     return false;
   3726   1.1.1.3  christos 
   3727       1.1     skrll   /* Relocate and write out the sections.  These functions use the
   3728   1.1.1.9  christos      symbol map created by aout_link_write_symbols.  The linker_mark
   3729       1.1     skrll      field will be set if these sections are to be included in the
   3730       1.1     skrll      link, which will normally be the case.  */
   3731       1.1     skrll   if (obj_textsec (input_bfd)->linker_mark)
   3732   1.1.1.3  christos     {
   3733       1.1     skrll       if (! aout_link_input_section (flaginfo, input_bfd,
   3734   1.1.1.3  christos 				     obj_textsec (input_bfd),
   3735       1.1     skrll 				     &flaginfo->treloff,
   3736   1.1.1.9  christos 				     exec_hdr (input_bfd)->a_trsize))
   3737       1.1     skrll 	return false;
   3738       1.1     skrll     }
   3739       1.1     skrll   if (obj_datasec (input_bfd)->linker_mark)
   3740       1.1     skrll     {
   3741       1.1     skrll       if (! aout_link_input_section (flaginfo, input_bfd,
   3742   1.1.1.3  christos 				     obj_datasec (input_bfd),
   3743       1.1     skrll 				     &flaginfo->dreloff,
   3744       1.1     skrll 				     exec_hdr (input_bfd)->a_drsize))
   3745   1.1.1.9  christos 	return false;
   3746       1.1     skrll     }
   3747       1.1     skrll 
   3748   1.1.1.9  christos   /* If we are not keeping memory, we don't need the symbols any
   3749       1.1     skrll      longer.  We still need them if we are keeping memory, because the
   3750       1.1     skrll      strings in the hash table point into them.  */
   3751       1.1     skrll   if (! flaginfo->info->keep_memory)
   3752       1.1     skrll     {
   3753   1.1.1.4  christos       if (! aout_link_free_symbols (input_bfd))
   3754       1.1     skrll 	return false;
   3755       1.1     skrll     }
   3756       1.1     skrll 
   3757       1.1     skrll   return true;
   3758   1.1.1.9  christos }
   3759       1.1     skrll 
   3760       1.1     skrll /* Do the final link step.  This is called on the output BFD.  The
   3761       1.1     skrll    INFO structure should point to a list of BFDs linked through the
   3762       1.1     skrll    link.next field which can be used to find each BFD which takes part
   3763       1.1     skrll    in the output.  Also, each section in ABFD should point to a list
   3764   1.1.1.9  christos    of bfd_link_order structures which list all the input sections for
   3765       1.1     skrll    the output section.  */
   3766       1.1     skrll 
   3767       1.1     skrll bool
   3768       1.1     skrll NAME (aout, final_link) (bfd *abfd,
   3769       1.1     skrll 			 struct bfd_link_info *info,
   3770       1.1     skrll 			 void (*callback) (bfd *, file_ptr *, file_ptr *, file_ptr *))
   3771       1.1     skrll {
   3772   1.1.1.9  christos   struct aout_final_link_info aout_info;
   3773       1.1     skrll   bool includes_hash_initialized = false;
   3774   1.1.1.4  christos   bfd *sub;
   3775       1.1     skrll   bfd_size_type trsize, drsize;
   3776       1.1     skrll   bfd_size_type max_contents_size;
   3777   1.1.1.9  christos   bfd_size_type max_relocs_size;
   3778       1.1     skrll   bfd_size_type max_sym_count;
   3779       1.1     skrll   struct bfd_link_order *p;
   3780       1.1     skrll   asection *o;
   3781       1.1     skrll   bool have_link_order_relocs;
   3782       1.1     skrll 
   3783       1.1     skrll   if (bfd_link_pic (info))
   3784       1.1     skrll     abfd->flags |= DYNAMIC;
   3785       1.1     skrll 
   3786       1.1     skrll   separate_i_d = info->separate_code;
   3787       1.1     skrll   aout_info.info = info;
   3788       1.1     skrll   aout_info.output_bfd = abfd;
   3789       1.1     skrll   aout_info.contents = NULL;
   3790   1.1.1.9  christos   aout_info.relocs = NULL;
   3791       1.1     skrll   aout_info.symbol_map = NULL;
   3792       1.1     skrll   aout_info.output_syms = NULL;
   3793       1.1     skrll 
   3794       1.1     skrll   if (!bfd_hash_table_init_n (&aout_info.includes.root,
   3795       1.1     skrll 			      aout_link_includes_newfunc,
   3796       1.1     skrll 			      sizeof (struct aout_link_includes_entry),
   3797       1.1     skrll 			      251))
   3798       1.1     skrll     goto error_return;
   3799   1.1.1.4  christos   includes_hash_initialized = true;
   3800       1.1     skrll 
   3801       1.1     skrll   /* Figure out the largest section size.  Also, if generating
   3802       1.1     skrll      relocatable output, count the relocs.  */
   3803   1.1.1.4  christos   trsize = 0;
   3804       1.1     skrll   drsize = 0;
   3805       1.1     skrll   max_contents_size = 0;
   3806       1.1     skrll   max_relocs_size = 0;
   3807       1.1     skrll   max_sym_count = 0;
   3808       1.1     skrll   for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
   3809       1.1     skrll     {
   3810       1.1     skrll       size_t sz;
   3811       1.1     skrll 
   3812       1.1     skrll       if (bfd_link_relocatable (info))
   3813       1.1     skrll 	{
   3814       1.1     skrll 	  if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
   3815       1.1     skrll 	    {
   3816   1.1.1.6  christos 	      trsize += exec_hdr (sub)->a_trsize;
   3817   1.1.1.6  christos 	      drsize += exec_hdr (sub)->a_drsize;
   3818   1.1.1.7  christos 	    }
   3819   1.1.1.6  christos 	  else
   3820       1.1     skrll 	    {
   3821       1.1     skrll 	      /* FIXME: We need to identify the .text and .data sections
   3822       1.1     skrll 		 and call get_reloc_upper_bound and canonicalize_reloc to
   3823       1.1     skrll 		 work out the number of relocs needed, and then multiply
   3824       1.1     skrll 		 by the reloc size.  */
   3825       1.1     skrll 	      _bfd_error_handler
   3826       1.1     skrll 		/* xgettext:c-format */
   3827       1.1     skrll 		(_("%pB: relocatable link from %s to %s not supported"),
   3828       1.1     skrll 		 abfd, sub->xvec->name, abfd->xvec->name);
   3829       1.1     skrll 	      bfd_set_error (bfd_error_invalid_operation);
   3830       1.1     skrll 	      goto error_return;
   3831       1.1     skrll 	    }
   3832       1.1     skrll 	}
   3833       1.1     skrll 
   3834       1.1     skrll       if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
   3835       1.1     skrll 	{
   3836       1.1     skrll 	  sz = obj_textsec (sub)->size;
   3837       1.1     skrll 	  if (sz > max_contents_size)
   3838       1.1     skrll 	    max_contents_size = sz;
   3839       1.1     skrll 	  sz = obj_datasec (sub)->size;
   3840       1.1     skrll 	  if (sz > max_contents_size)
   3841       1.1     skrll 	    max_contents_size = sz;
   3842       1.1     skrll 
   3843       1.1     skrll 	  sz = exec_hdr (sub)->a_trsize;
   3844       1.1     skrll 	  if (sz > max_relocs_size)
   3845       1.1     skrll 	    max_relocs_size = sz;
   3846       1.1     skrll 	  sz = exec_hdr (sub)->a_drsize;
   3847   1.1.1.4  christos 	  if (sz > max_relocs_size)
   3848       1.1     skrll 	    max_relocs_size = sz;
   3849       1.1     skrll 
   3850       1.1     skrll 	  sz = obj_aout_external_sym_count (sub);
   3851       1.1     skrll 	  if (sz > max_sym_count)
   3852       1.1     skrll 	    max_sym_count = sz;
   3853       1.1     skrll 	}
   3854       1.1     skrll     }
   3855       1.1     skrll 
   3856       1.1     skrll   if (bfd_link_relocatable (info))
   3857       1.1     skrll     {
   3858       1.1     skrll       if (obj_textsec (abfd) != NULL)
   3859       1.1     skrll 	trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
   3860       1.1     skrll 						 ->map_head.link_order)
   3861       1.1     skrll 		   * obj_reloc_entry_size (abfd));
   3862       1.1     skrll       if (obj_datasec (abfd) != NULL)
   3863       1.1     skrll 	drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
   3864       1.1     skrll 						 ->map_head.link_order)
   3865       1.1     skrll 		   * obj_reloc_entry_size (abfd));
   3866   1.1.1.5  christos     }
   3867       1.1     skrll 
   3868       1.1     skrll   exec_hdr (abfd)->a_trsize = trsize;
   3869       1.1     skrll   exec_hdr (abfd)->a_drsize = drsize;
   3870       1.1     skrll   exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
   3871       1.1     skrll 
   3872       1.1     skrll   /* Adjust the section sizes and vmas according to the magic number.
   3873       1.1     skrll      This sets a_text, a_data and a_bss in the exec_hdr and sets the
   3874       1.1     skrll      filepos for each section.  */
   3875   1.1.1.7  christos   if (! NAME (aout, adjust_sizes_and_vmas) (abfd))
   3876       1.1     skrll     goto error_return;
   3877       1.1     skrll 
   3878       1.1     skrll   /* The relocation and symbol file positions differ among a.out
   3879       1.1     skrll      targets.  We are passed a callback routine from the backend
   3880       1.1     skrll      specific code to handle this.
   3881       1.1     skrll      FIXME: At this point we do not know how much space the symbol
   3882       1.1     skrll      table will require.  This will not work for any (nonstandard)
   3883       1.1     skrll      a.out target that needs to know the symbol table size before it
   3884       1.1     skrll      can compute the relocation file positions.  */
   3885       1.1     skrll   (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
   3886       1.1     skrll 	       &aout_info.symoff);
   3887       1.1     skrll   obj_textsec (abfd)->rel_filepos = aout_info.treloff;
   3888       1.1     skrll   obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
   3889       1.1     skrll   obj_sym_filepos (abfd) = aout_info.symoff;
   3890       1.1     skrll 
   3891       1.1     skrll   /* We keep a count of the symbols as we output them.  */
   3892       1.1     skrll   obj_aout_external_sym_count (abfd) = 0;
   3893       1.1     skrll 
   3894       1.1     skrll   /* We accumulate the string table as we write out the symbols.  */
   3895       1.1     skrll   aout_info.strtab = _bfd_stringtab_init ();
   3896       1.1     skrll   if (aout_info.strtab == NULL)
   3897       1.1     skrll     goto error_return;
   3898       1.1     skrll 
   3899       1.1     skrll   /* Allocate buffers to hold section contents and relocs.  */
   3900       1.1     skrll   aout_info.contents = bfd_malloc (max_contents_size);
   3901       1.1     skrll   aout_info.relocs = bfd_malloc (max_relocs_size);
   3902       1.1     skrll   aout_info.symbol_map = bfd_malloc (max_sym_count * sizeof (int *));
   3903       1.1     skrll   aout_info.output_syms = bfd_malloc ((max_sym_count + 1)
   3904       1.1     skrll 				      * sizeof (struct external_nlist));
   3905       1.1     skrll   if ((aout_info.contents == NULL && max_contents_size != 0)
   3906       1.1     skrll       || (aout_info.relocs == NULL && max_relocs_size != 0)
   3907       1.1     skrll       || (aout_info.symbol_map == NULL && max_sym_count != 0)
   3908       1.1     skrll       || aout_info.output_syms == NULL)
   3909       1.1     skrll     goto error_return;
   3910   1.1.1.9  christos 
   3911       1.1     skrll   /* If we have a symbol named __DYNAMIC, force it out now.  This is
   3912   1.1.1.3  christos      required by SunOS.  Doing this here rather than in sunos.c is a
   3913       1.1     skrll      hack, but it's easier than exporting everything which would be
   3914       1.1     skrll      needed.  */
   3915       1.1     skrll   {
   3916       1.1     skrll     struct aout_link_hash_entry *h;
   3917       1.1     skrll 
   3918       1.1     skrll     h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
   3919       1.1     skrll 			       false, false, false);
   3920       1.1     skrll     if (h != NULL)
   3921       1.1     skrll       aout_link_write_other_symbol (&h->root.root, &aout_info);
   3922       1.1     skrll   }
   3923       1.1     skrll 
   3924       1.1     skrll   /* The most time efficient way to do the link would be to read all
   3925       1.1     skrll      the input object files into memory and then sort out the
   3926       1.1     skrll      information into the output file.  Unfortunately, that will
   3927       1.1     skrll      probably use too much memory.  Another method would be to step
   3928       1.1     skrll      through everything that composes the text section and write it
   3929       1.1     skrll      out, and then everything that composes the data section and write
   3930       1.1     skrll      it out, and then write out the relocs, and then write out the
   3931       1.1     skrll      symbols.  Unfortunately, that requires reading stuff from each
   3932       1.1     skrll      input file several times, and we will not be able to keep all the
   3933       1.1     skrll      input files open simultaneously, and reopening them will be slow.
   3934       1.1     skrll 
   3935       1.1     skrll      What we do is basically process one input file at a time.  We do
   3936   1.1.1.4  christos      everything we need to do with an input file once--copy over the
   3937   1.1.1.9  christos      section contents, handle the relocation information, and write
   3938       1.1     skrll      out the symbols--and then we throw away the information we read
   3939       1.1     skrll      from it.  This approach requires a lot of lseeks of the output
   3940       1.1     skrll      file, which is unfortunate but still faster than reopening a lot
   3941       1.1     skrll      of files.
   3942       1.1     skrll 
   3943       1.1     skrll      We use the output_has_begun field of the input BFDs to see
   3944       1.1     skrll      whether we have already handled it.  */
   3945       1.1     skrll   for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
   3946       1.1     skrll     sub->output_has_begun = false;
   3947   1.1.1.9  christos 
   3948       1.1     skrll   /* Mark all sections which are to be included in the link.  This
   3949       1.1     skrll      will normally be every section.  We need to do this so that we
   3950   1.1.1.9  christos      can identify any sections which the linker has decided to not
   3951       1.1     skrll      include.  */
   3952       1.1     skrll   for (o = abfd->sections; o != NULL; o = o->next)
   3953       1.1     skrll     {
   3954       1.1     skrll       for (p = o->map_head.link_order; p != NULL; p = p->next)
   3955       1.1     skrll 	if (p->type == bfd_indirect_link_order)
   3956       1.1     skrll 	  p->u.indirect.section->linker_mark = true;
   3957       1.1     skrll     }
   3958       1.1     skrll 
   3959       1.1     skrll   have_link_order_relocs = false;
   3960       1.1     skrll   for (o = abfd->sections; o != NULL; o = o->next)
   3961       1.1     skrll     {
   3962       1.1     skrll       for (p = o->map_head.link_order;
   3963       1.1     skrll 	   p != NULL;
   3964       1.1     skrll 	   p = p->next)
   3965       1.1     skrll 	{
   3966       1.1     skrll 	  if (p->type == bfd_indirect_link_order
   3967       1.1     skrll 	      && (bfd_get_flavour (p->u.indirect.section->owner)
   3968   1.1.1.9  christos 		  == bfd_target_aout_flavour))
   3969       1.1     skrll 	    {
   3970       1.1     skrll 	      bfd *input_bfd;
   3971       1.1     skrll 
   3972       1.1     skrll 	      input_bfd = p->u.indirect.section->owner;
   3973       1.1     skrll 	      if (! input_bfd->output_has_begun)
   3974   1.1.1.9  christos 		{
   3975       1.1     skrll 		  if (! aout_link_input_bfd (&aout_info, input_bfd))
   3976       1.1     skrll 		    goto error_return;
   3977       1.1     skrll 		  input_bfd->output_has_begun = true;
   3978       1.1     skrll 		}
   3979       1.1     skrll 	    }
   3980       1.1     skrll 	  else if (p->type == bfd_section_reloc_link_order
   3981       1.1     skrll 		   || p->type == bfd_symbol_reloc_link_order)
   3982       1.1     skrll 	    /* These are handled below.  */
   3983       1.1     skrll 	    have_link_order_relocs = true;
   3984   1.1.1.3  christos 	  else
   3985   1.1.1.3  christos 	    {
   3986   1.1.1.3  christos 	      if (! _bfd_default_link_order (abfd, info, o, p))
   3987       1.1     skrll 		goto error_return;
   3988       1.1     skrll 	    }
   3989       1.1     skrll 	}
   3990       1.1     skrll     }
   3991       1.1     skrll 
   3992       1.1     skrll   /* Write out any symbols that we have not already written out.  */
   3993       1.1     skrll   bfd_hash_traverse (&info->hash->table,
   3994       1.1     skrll 		     aout_link_write_other_symbol,
   3995       1.1     skrll 		     &aout_info);
   3996       1.1     skrll 
   3997       1.1     skrll   /* Now handle any relocs we were asked to create by the linker.
   3998       1.1     skrll      These did not come from any input file.  We must do these after
   3999       1.1     skrll      we have written out all the symbols, so that we know the symbol
   4000       1.1     skrll      indices to use.  */
   4001       1.1     skrll   if (have_link_order_relocs)
   4002       1.1     skrll     {
   4003       1.1     skrll       for (o = abfd->sections; o != NULL; o = o->next)
   4004       1.1     skrll 	{
   4005       1.1     skrll 	  for (p = o->map_head.link_order;
   4006       1.1     skrll 	       p != NULL;
   4007       1.1     skrll 	       p = p->next)
   4008       1.1     skrll 	    {
   4009       1.1     skrll 	      if (p->type == bfd_section_reloc_link_order
   4010   1.1.1.9  christos 		  || p->type == bfd_symbol_reloc_link_order)
   4011   1.1.1.9  christos 		{
   4012   1.1.1.9  christos 		  if (! aout_link_reloc_link_order (&aout_info, o, p))
   4013   1.1.1.9  christos 		    goto error_return;
   4014   1.1.1.9  christos 		}
   4015   1.1.1.9  christos 	    }
   4016   1.1.1.9  christos 	}
   4017   1.1.1.9  christos     }
   4018       1.1     skrll 
   4019       1.1     skrll   free (aout_info.contents);
   4020       1.1     skrll   aout_info.contents = NULL;
   4021   1.1.1.9  christos   free (aout_info.relocs);
   4022       1.1     skrll   aout_info.relocs = NULL;
   4023       1.1     skrll   free (aout_info.symbol_map);
   4024       1.1     skrll   aout_info.symbol_map = NULL;
   4025       1.1     skrll   free (aout_info.output_syms);
   4026       1.1     skrll   aout_info.output_syms = NULL;
   4027       1.1     skrll   if (includes_hash_initialized)
   4028       1.1     skrll     {
   4029       1.1     skrll       bfd_hash_table_free (&aout_info.includes.root);
   4030       1.1     skrll       includes_hash_initialized = false;
   4031       1.1     skrll     }
   4032       1.1     skrll 
   4033       1.1     skrll   /* Finish up any dynamic linking we may be doing.  */
   4034       1.1     skrll   if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
   4035       1.1     skrll     {
   4036       1.1     skrll       if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
   4037       1.1     skrll 	goto error_return;
   4038       1.1     skrll     }
   4039       1.1     skrll 
   4040       1.1     skrll   /* Update the header information.  */
   4041       1.1     skrll   abfd->symcount = obj_aout_external_sym_count (abfd);
   4042       1.1     skrll   exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
   4043       1.1     skrll   obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
   4044       1.1     skrll   obj_textsec (abfd)->reloc_count =
   4045       1.1     skrll     exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
   4046       1.1     skrll   obj_datasec (abfd)->reloc_count =
   4047       1.1     skrll     exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
   4048       1.1     skrll 
   4049       1.1     skrll   /* Write out the string table, unless there are no symbols.  */
   4050   1.1.1.9  christos   if (abfd->symcount > 0)
   4051   1.1.1.9  christos     {
   4052   1.1.1.9  christos       if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
   4053   1.1.1.9  christos 	  || ! emit_stringtab (abfd, aout_info.strtab))
   4054   1.1.1.9  christos 	goto error_return;
   4055   1.1.1.9  christos     }
   4056   1.1.1.9  christos   else if (obj_textsec (abfd)->reloc_count == 0
   4057   1.1.1.9  christos 	   && obj_datasec (abfd)->reloc_count == 0)
   4058   1.1.1.9  christos     {
   4059   1.1.1.9  christos       /* The layout of a typical a.out file is header, text, data,
   4060   1.1.1.9  christos 	 relocs, symbols, string table.  When there are no relocs,
   4061   1.1.1.9  christos 	 symbols or string table, the last thing in the file is data
   4062   1.1.1.9  christos 	 and a_data may be rounded up.  However we may have a smaller
   4063   1.1.1.9  christos 	 sized .data section and thus not written final padding.  The
   4064   1.1.1.9  christos 	 same thing can happen with text if there is no data.  Write
   4065   1.1.1.9  christos 	 final padding here to extend the file.  */
   4066   1.1.1.9  christos       file_ptr pos = 0;
   4067   1.1.1.9  christos 
   4068   1.1.1.9  christos       if (exec_hdr (abfd)->a_data > obj_datasec (abfd)->size)
   4069  1.1.1.10  christos 	pos = obj_datasec (abfd)->filepos + exec_hdr (abfd)->a_data;
   4070   1.1.1.9  christos       else if (obj_datasec (abfd)->size == 0
   4071   1.1.1.9  christos 	       && exec_hdr (abfd)->a_text > obj_textsec (abfd)->size)
   4072       1.1     skrll 	pos = obj_textsec (abfd)->filepos + exec_hdr (abfd)->a_text;
   4073       1.1     skrll       if (pos != 0)
   4074   1.1.1.9  christos 	{
   4075       1.1     skrll 	  bfd_byte b = 0;
   4076       1.1     skrll 
   4077   1.1.1.9  christos 	  if (bfd_seek (abfd, pos - 1, SEEK_SET) != 0
   4078   1.1.1.9  christos 	      || bfd_write (&b, 1, abfd) != 1)
   4079   1.1.1.9  christos 	    goto error_return;
   4080   1.1.1.9  christos 	}
   4081       1.1     skrll     }
   4082       1.1     skrll 
   4083   1.1.1.9  christos   return true;
   4084       1.1     skrll 
   4085       1.1     skrll  error_return:
   4086       1.1     skrll   free (aout_info.contents);
   4087       1.1     skrll   free (aout_info.relocs);
   4088       1.1     skrll   free (aout_info.symbol_map);
   4089   1.1.1.9  christos   free (aout_info.output_syms);
   4090   1.1.1.3  christos   if (includes_hash_initialized)
   4091       1.1     skrll     bfd_hash_table_free (&aout_info.includes.root);
   4092       1.1     skrll   return false;
   4093       1.1     skrll }
   4094       1.1     skrll 
   4095       1.1     skrll /* Adjust and write out the symbols for an a.out file.  Set the new
   4096       1.1     skrll    symbol indices into a symbol_map.  */
   4097       1.1     skrll 
   4098       1.1     skrll static bool
   4099       1.1     skrll aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd)
   4100       1.1     skrll {
   4101       1.1     skrll   bfd *output_bfd;
   4102       1.1     skrll   bfd_size_type sym_count;
   4103   1.1.1.9  christos   char *strings;
   4104   1.1.1.9  christos   enum bfd_link_strip strip;
   4105       1.1     skrll   enum bfd_link_discard discard;
   4106   1.1.1.3  christos   struct external_nlist *outsym;
   4107       1.1     skrll   bfd_size_type strtab_index;
   4108       1.1     skrll   struct external_nlist *sym;
   4109   1.1.1.3  christos   struct external_nlist *sym_end;
   4110   1.1.1.3  christos   struct aout_link_hash_entry **sym_hash;
   4111   1.1.1.3  christos   int *symbol_map;
   4112       1.1     skrll   bool pass;
   4113       1.1     skrll   bool skip_next;
   4114       1.1     skrll 
   4115       1.1     skrll   output_bfd = flaginfo->output_bfd;
   4116       1.1     skrll   sym_count = obj_aout_external_sym_count (input_bfd);
   4117   1.1.1.9  christos   strings = obj_aout_external_strings (input_bfd);
   4118   1.1.1.9  christos   strip = flaginfo->info->strip;
   4119   1.1.1.9  christos   discard = flaginfo->info->discard;
   4120       1.1     skrll   outsym = flaginfo->output_syms;
   4121       1.1     skrll 
   4122       1.1     skrll   /* First write out a symbol for this object file, unless we are
   4123   1.1.1.9  christos      discarding such symbols.  */
   4124   1.1.1.9  christos   if (strip != strip_all
   4125   1.1.1.3  christos       && (strip != strip_some
   4126   1.1.1.9  christos 	  || bfd_hash_lookup (flaginfo->info->keep_hash,
   4127       1.1     skrll 			      bfd_get_filename (input_bfd),
   4128   1.1.1.9  christos 			      false, false) != NULL)
   4129       1.1     skrll       && discard != discard_all)
   4130       1.1     skrll     {
   4131   1.1.1.8  christos       H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
   4132       1.1     skrll       H_PUT_8 (output_bfd, 0, outsym->e_ovly);
   4133       1.1     skrll       H_PUT_16 (output_bfd, 0, outsym->e_desc);
   4134       1.1     skrll       strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
   4135       1.1     skrll 				       bfd_get_filename (input_bfd), false);
   4136       1.1     skrll       if (strtab_index == (bfd_size_type) -1)
   4137       1.1     skrll 	return false;
   4138   1.1.1.9  christos       PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
   4139   1.1.1.9  christos       PUT_WORD (output_bfd,
   4140       1.1     skrll 		(bfd_section_vma (obj_textsec (input_bfd)->output_section)
   4141       1.1     skrll 		 + obj_textsec (input_bfd)->output_offset),
   4142       1.1     skrll 		outsym->e_value);
   4143   1.1.1.3  christos       ++obj_aout_external_sym_count (output_bfd);
   4144       1.1     skrll       ++outsym;
   4145       1.1     skrll     }
   4146       1.1     skrll 
   4147       1.1     skrll   pass = false;
   4148       1.1     skrll   skip_next = false;
   4149       1.1     skrll   sym = obj_aout_external_syms (input_bfd);
   4150   1.1.1.9  christos   sym_end = sym + sym_count;
   4151       1.1     skrll   sym_hash = obj_aout_sym_hashes (input_bfd);
   4152       1.1     skrll   symbol_map = flaginfo->symbol_map;
   4153   1.1.1.9  christos   memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
   4154       1.1     skrll   for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
   4155       1.1     skrll     {
   4156   1.1.1.6  christos       const char *name;
   4157   1.1.1.6  christos       int type;
   4158   1.1.1.6  christos       struct aout_link_hash_entry *h;
   4159       1.1     skrll       bool skip;
   4160       1.1     skrll       asection *symsec;
   4161       1.1     skrll       bfd_vma val = 0;
   4162       1.1     skrll       bool copy;
   4163   1.1.1.6  christos 
   4164   1.1.1.6  christos       /* We set *symbol_map to 0 above for all symbols.  If it has
   4165       1.1     skrll 	 already been set to -1 for this symbol, it means that we are
   4166       1.1     skrll 	 discarding it because it appears in a duplicate header file.
   4167       1.1     skrll 	 See the N_BINCL code below.  */
   4168       1.1     skrll       if (*symbol_map == -1)
   4169       1.1     skrll 	continue;
   4170       1.1     skrll 
   4171       1.1     skrll       /* Initialize *symbol_map to -1, which means that the symbol was
   4172       1.1     skrll 	 not copied into the output file.  We will change it later if
   4173       1.1     skrll 	 we do copy the symbol over.  */
   4174       1.1     skrll       *symbol_map = -1;
   4175       1.1     skrll 
   4176       1.1     skrll       type = H_GET_8 (input_bfd, sym->e_type);
   4177   1.1.1.9  christos       name = strings + GET_WORD (input_bfd, sym->e_strx);
   4178       1.1     skrll 
   4179       1.1     skrll       h = NULL;
   4180       1.1     skrll 
   4181       1.1     skrll       if (pass)
   4182       1.1     skrll 	{
   4183       1.1     skrll 	  /* Pass this symbol through.  It is the target of an
   4184   1.1.1.9  christos 	     indirect or warning symbol.  */
   4185       1.1     skrll 	  val = GET_WORD (input_bfd, sym->e_value);
   4186       1.1     skrll 	  pass = false;
   4187       1.1     skrll 	}
   4188       1.1     skrll       else if (skip_next)
   4189       1.1     skrll 	{
   4190       1.1     skrll 	  /* Skip this symbol, which is the target of an indirect
   4191       1.1     skrll 	     symbol that we have changed to no longer be an indirect
   4192       1.1     skrll 	     symbol.  */
   4193       1.1     skrll 	  skip_next = false;
   4194       1.1     skrll 	  continue;
   4195       1.1     skrll 	}
   4196       1.1     skrll       else
   4197       1.1     skrll 	{
   4198   1.1.1.6  christos 	  struct aout_link_hash_entry *hresolve;
   4199       1.1     skrll 
   4200       1.1     skrll 	  /* We have saved the hash table entry for this symbol, if
   4201       1.1     skrll 	     there is one.  Note that we could just look it up again
   4202       1.1     skrll 	     in the hash table, provided we first check that it is an
   4203       1.1     skrll 	     external symbol. */
   4204       1.1     skrll 	  h = *sym_hash;
   4205       1.1     skrll 
   4206       1.1     skrll 	  /* Use the name from the hash table, in case the symbol was
   4207       1.1     skrll 	     wrapped.  */
   4208       1.1     skrll 	  if (h != NULL)
   4209       1.1     skrll 	    name = h->root.root.string;
   4210       1.1     skrll 
   4211       1.1     skrll 	  /* If this is an indirect or warning symbol, then change
   4212       1.1     skrll 	     hresolve to the base symbol.  We also change *sym_hash so
   4213       1.1     skrll 	     that the relocation routines relocate against the real
   4214       1.1     skrll 	     symbol.  */
   4215       1.1     skrll 	  hresolve = h;
   4216       1.1     skrll 	  if (h != NULL
   4217       1.1     skrll 	      && (h->root.type == bfd_link_hash_indirect
   4218       1.1     skrll 		  || h->root.type == bfd_link_hash_warning))
   4219       1.1     skrll 	    {
   4220       1.1     skrll 	      hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
   4221       1.1     skrll 	      while (hresolve->root.type == bfd_link_hash_indirect
   4222       1.1     skrll 		     || hresolve->root.type == bfd_link_hash_warning)
   4223       1.1     skrll 		hresolve = ((struct aout_link_hash_entry *)
   4224       1.1     skrll 			    hresolve->root.u.i.link);
   4225       1.1     skrll 	      *sym_hash = hresolve;
   4226   1.1.1.9  christos 	    }
   4227       1.1     skrll 
   4228       1.1     skrll 	  /* If the symbol has already been written out, skip it.  */
   4229       1.1     skrll 	  if (h != NULL
   4230       1.1     skrll 	      && h->root.type != bfd_link_hash_warning
   4231       1.1     skrll 	      && h->written)
   4232   1.1.1.9  christos 	    {
   4233       1.1     skrll 	      if ((type & N_TYPE) == N_INDR
   4234       1.1     skrll 		  || type == N_WARNING)
   4235       1.1     skrll 		skip_next = true;
   4236       1.1     skrll 	      *symbol_map = h->indx;
   4237       1.1     skrll 	      continue;
   4238   1.1.1.9  christos 	    }
   4239   1.1.1.9  christos 
   4240       1.1     skrll 	  /* See if we are stripping this symbol.  */
   4241       1.1     skrll 	  skip = false;
   4242   1.1.1.9  christos 	  switch (strip)
   4243   1.1.1.9  christos 	    {
   4244   1.1.1.9  christos 	    case strip_none:
   4245       1.1     skrll 	      break;
   4246       1.1     skrll 	    case strip_debugger:
   4247   1.1.1.9  christos 	      if (is_stab (type, name))
   4248       1.1     skrll 		skip = true;
   4249       1.1     skrll 	      break;
   4250       1.1     skrll 	    case strip_some:
   4251       1.1     skrll 	      if (bfd_hash_lookup (flaginfo->info->keep_hash, name,
   4252       1.1     skrll 				   false, false) == NULL)
   4253   1.1.1.9  christos 		skip = true;
   4254       1.1     skrll 	      break;
   4255       1.1     skrll 	    case strip_all:
   4256       1.1     skrll 	      skip = true;
   4257       1.1     skrll 	      break;
   4258   1.1.1.9  christos 	    }
   4259   1.1.1.9  christos 	  if (skip)
   4260   1.1.1.9  christos 	    {
   4261   1.1.1.9  christos 	      if (h != NULL)
   4262   1.1.1.9  christos 		h->written = true;
   4263   1.1.1.9  christos 	      continue;
   4264   1.1.1.9  christos 	    }
   4265   1.1.1.9  christos 
   4266   1.1.1.9  christos 	  /* Get the value of the symbol.  */
   4267   1.1.1.9  christos 	  if (is_stab (type, name))
   4268   1.1.1.9  christos 	    {
   4269   1.1.1.9  christos 	      switch (type)
   4270   1.1.1.9  christos 		{
   4271   1.1.1.9  christos 		default:
   4272   1.1.1.9  christos 		  symsec = bfd_abs_section_ptr;
   4273   1.1.1.9  christos 		  break;
   4274   1.1.1.9  christos 		case N_SO:
   4275   1.1.1.9  christos 		case N_SOL:
   4276   1.1.1.9  christos 		case N_FUN:
   4277   1.1.1.9  christos 		case N_ENTRY:
   4278   1.1.1.9  christos 		case N_SLINE:
   4279   1.1.1.9  christos 		case N_FN:
   4280   1.1.1.9  christos 		  symsec = obj_textsec (input_bfd);
   4281   1.1.1.9  christos 		  break;
   4282   1.1.1.9  christos 		case N_STSYM:
   4283   1.1.1.9  christos 		case N_DSLINE:
   4284   1.1.1.9  christos 		  symsec = obj_datasec (input_bfd);
   4285       1.1     skrll 		  break;
   4286       1.1     skrll 		case N_LCSYM:
   4287       1.1     skrll 		case N_BSLINE:
   4288       1.1     skrll 		  symsec = obj_bsssec (input_bfd);
   4289       1.1     skrll 		  break;
   4290       1.1     skrll 		}
   4291       1.1     skrll 	      val = GET_WORD (input_bfd, sym->e_value);
   4292       1.1     skrll 	    }
   4293       1.1     skrll 	  else if ((type & N_TYPE) == N_TEXT
   4294       1.1     skrll 	      || type == N_WEAKT)
   4295       1.1     skrll 	    symsec = obj_textsec (input_bfd);
   4296       1.1     skrll 	  else if ((type & N_TYPE) == N_DATA
   4297       1.1     skrll 		   || type == N_WEAKD)
   4298       1.1     skrll 	    symsec = obj_datasec (input_bfd);
   4299       1.1     skrll 	  else if ((type & N_TYPE) == N_BSS
   4300       1.1     skrll 		   || type == N_WEAKB)
   4301       1.1     skrll 	    symsec = obj_bsssec (input_bfd);
   4302       1.1     skrll 	  else if ((type & N_TYPE) == N_ABS
   4303       1.1     skrll 		   || type == N_WEAKA)
   4304       1.1     skrll 	    symsec = bfd_abs_section_ptr;
   4305       1.1     skrll 	  else if (((type & N_TYPE) == N_INDR
   4306       1.1     skrll 		    && (hresolve == NULL
   4307       1.1     skrll 			|| (hresolve->root.type != bfd_link_hash_defined
   4308   1.1.1.9  christos 			    && hresolve->root.type != bfd_link_hash_defweak
   4309       1.1     skrll 			    && hresolve->root.type != bfd_link_hash_common)))
   4310       1.1     skrll 		   || type == N_WARNING)
   4311       1.1     skrll 	    {
   4312       1.1     skrll 	      /* Pass the next symbol through unchanged.  The
   4313       1.1     skrll 		 condition above for indirect symbols is so that if
   4314       1.1     skrll 		 the indirect symbol was defined, we output it with
   4315       1.1     skrll 		 the correct definition so the debugger will
   4316       1.1     skrll 		 understand it.  */
   4317       1.1     skrll 	      pass = true;
   4318       1.1     skrll 	      val = GET_WORD (input_bfd, sym->e_value);
   4319   1.1.1.9  christos 	      symsec = NULL;
   4320       1.1     skrll 	    }
   4321       1.1     skrll 	  else
   4322       1.1     skrll 	    {
   4323       1.1     skrll 	      /* If we get here with an indirect symbol, it means that
   4324       1.1     skrll 		 we are outputting it with a real definition.  In such
   4325       1.1     skrll 		 a case we do not want to output the next symbol,
   4326       1.1     skrll 		 which is the target of the indirection.  */
   4327       1.1     skrll 	      if ((type & N_TYPE) == N_INDR)
   4328       1.1     skrll 		skip_next = true;
   4329       1.1     skrll 
   4330       1.1     skrll 	      symsec = NULL;
   4331       1.1     skrll 
   4332       1.1     skrll 	      /* We need to get the value from the hash table.  We use
   4333       1.1     skrll 		 hresolve so that if we have defined an indirect
   4334       1.1     skrll 		 symbol we output the final definition.  */
   4335       1.1     skrll 	      if (h == NULL)
   4336       1.1     skrll 		{
   4337       1.1     skrll 		  switch (type & N_TYPE)
   4338       1.1     skrll 		    {
   4339       1.1     skrll 		    case N_SETT:
   4340       1.1     skrll 		      symsec = obj_textsec (input_bfd);
   4341       1.1     skrll 		      break;
   4342       1.1     skrll 		    case N_SETD:
   4343       1.1     skrll 		      symsec = obj_datasec (input_bfd);
   4344       1.1     skrll 		      break;
   4345       1.1     skrll 		    case N_SETB:
   4346       1.1     skrll 		      symsec = obj_bsssec (input_bfd);
   4347       1.1     skrll 		      break;
   4348       1.1     skrll 		    case N_SETA:
   4349       1.1     skrll 		      symsec = bfd_abs_section_ptr;
   4350       1.1     skrll 		      break;
   4351       1.1     skrll 		    default:
   4352       1.1     skrll 		      val = 0;
   4353       1.1     skrll 		      break;
   4354       1.1     skrll 		    }
   4355       1.1     skrll 		}
   4356       1.1     skrll 	      else if (hresolve->root.type == bfd_link_hash_defined
   4357       1.1     skrll 		       || hresolve->root.type == bfd_link_hash_defweak)
   4358       1.1     skrll 		{
   4359       1.1     skrll 		  asection *input_section;
   4360   1.1.1.8  christos 		  asection *output_section;
   4361       1.1     skrll 
   4362       1.1     skrll 		  /* This case usually means a common symbol which was
   4363       1.1     skrll 		     turned into a defined symbol.  */
   4364       1.1     skrll 		  input_section = hresolve->root.u.def.section;
   4365       1.1     skrll 		  output_section = input_section->output_section;
   4366       1.1     skrll 		  BFD_ASSERT (bfd_is_abs_section (output_section)
   4367       1.1     skrll 			      || output_section->owner == output_bfd);
   4368       1.1     skrll 		  val = (hresolve->root.u.def.value
   4369       1.1     skrll 			 + bfd_section_vma (output_section)
   4370       1.1     skrll 			 + input_section->output_offset);
   4371       1.1     skrll 
   4372       1.1     skrll 		  /* Get the correct type based on the section.  If
   4373       1.1     skrll 		     this is a constructed set, force it to be
   4374       1.1     skrll 		     globally visible.  */
   4375       1.1     skrll 		  if (type == N_SETT
   4376       1.1     skrll 		      || type == N_SETD
   4377       1.1     skrll 		      || type == N_SETB
   4378       1.1     skrll 		      || type == N_SETA)
   4379       1.1     skrll 		    type |= N_EXT;
   4380       1.1     skrll 
   4381       1.1     skrll 		  type &=~ N_TYPE;
   4382       1.1     skrll 
   4383       1.1     skrll 		  if (output_section == obj_textsec (output_bfd))
   4384       1.1     skrll 		    type |= (hresolve->root.type == bfd_link_hash_defined
   4385       1.1     skrll 			     ? N_TEXT
   4386       1.1     skrll 			     : N_WEAKT);
   4387       1.1     skrll 		  else if (output_section == obj_datasec (output_bfd))
   4388       1.1     skrll 		    type |= (hresolve->root.type == bfd_link_hash_defined
   4389       1.1     skrll 			     ? N_DATA
   4390       1.1     skrll 			     : N_WEAKD);
   4391       1.1     skrll 		  else if (output_section == obj_bsssec (output_bfd))
   4392       1.1     skrll 		    type |= (hresolve->root.type == bfd_link_hash_defined
   4393       1.1     skrll 			     ? N_BSS
   4394       1.1     skrll 			     : N_WEAKB);
   4395       1.1     skrll 		  else
   4396       1.1     skrll 		    type |= (hresolve->root.type == bfd_link_hash_defined
   4397       1.1     skrll 			     ? N_ABS
   4398       1.1     skrll 			     : N_WEAKA);
   4399       1.1     skrll 		}
   4400       1.1     skrll 	      else if (hresolve->root.type == bfd_link_hash_common)
   4401       1.1     skrll 		val = hresolve->root.u.c.size;
   4402       1.1     skrll 	      else if (hresolve->root.type == bfd_link_hash_undefweak)
   4403       1.1     skrll 		{
   4404       1.1     skrll 		  val = 0;
   4405       1.1     skrll 		  type = N_WEAKU;
   4406       1.1     skrll 		}
   4407       1.1     skrll 	      else
   4408       1.1     skrll 		val = 0;
   4409       1.1     skrll 	    }
   4410       1.1     skrll 	  if (symsec != NULL)
   4411   1.1.1.9  christos 	    val = (symsec->output_section->vma
   4412       1.1     skrll 		   + symsec->output_offset
   4413       1.1     skrll 		   + (GET_WORD (input_bfd, sym->e_value)
   4414       1.1     skrll 		      - symsec->vma));
   4415       1.1     skrll 
   4416       1.1     skrll 	  /* If this is a global symbol set the written flag, and if
   4417       1.1     skrll 	     it is a local symbol see if we should discard it.  */
   4418       1.1     skrll 	  if (h != NULL)
   4419       1.1     skrll 	    {
   4420       1.1     skrll 	      h->written = true;
   4421       1.1     skrll 	      h->indx = obj_aout_external_sym_count (output_bfd);
   4422       1.1     skrll 	    }
   4423       1.1     skrll 	  else if ((type & N_TYPE) != N_SETT
   4424       1.1     skrll 		   && (type & N_TYPE) != N_SETD
   4425   1.1.1.9  christos 		   && (type & N_TYPE) != N_SETB
   4426       1.1     skrll 		   && (type & N_TYPE) != N_SETA)
   4427   1.1.1.9  christos 	    {
   4428       1.1     skrll 	      switch (discard)
   4429       1.1     skrll 		{
   4430   1.1.1.9  christos 		case discard_none:
   4431       1.1     skrll 		case discard_sec_merge:
   4432       1.1     skrll 		  break;
   4433       1.1     skrll 		case discard_l:
   4434       1.1     skrll 		  if (!is_stab (type, name)
   4435   1.1.1.9  christos 		      && bfd_is_local_label_name (input_bfd, name))
   4436       1.1     skrll 		    skip = true;
   4437       1.1     skrll 		  break;
   4438       1.1     skrll 		case discard_all:
   4439       1.1     skrll 		  skip = true;
   4440       1.1     skrll 		  break;
   4441       1.1     skrll 		}
   4442       1.1     skrll 	      if (skip)
   4443       1.1     skrll 		{
   4444       1.1     skrll 		  pass = false;
   4445       1.1     skrll 		  continue;
   4446       1.1     skrll 		}
   4447       1.1     skrll 	    }
   4448       1.1     skrll 
   4449       1.1     skrll 	  /* An N_BINCL symbol indicates the start of the stabs
   4450       1.1     skrll 	     entries for a header file.  We need to scan ahead to the
   4451       1.1     skrll 	     next N_EINCL symbol, ignoring nesting, adding up all the
   4452       1.1     skrll 	     characters in the symbol names, not including the file
   4453       1.1     skrll 	     numbers in types (the first number after an open
   4454       1.1     skrll 	     parenthesis).  */
   4455       1.1     skrll 	  if (type == N_BINCL)
   4456       1.1     skrll 	    {
   4457       1.1     skrll 	      struct external_nlist *incl_sym;
   4458       1.1     skrll 	      int nest;
   4459       1.1     skrll 	      struct aout_link_includes_entry *incl_entry;
   4460       1.1     skrll 	      struct aout_link_includes_totals *t;
   4461       1.1     skrll 
   4462       1.1     skrll 	      val = 0;
   4463       1.1     skrll 	      nest = 0;
   4464       1.1     skrll 	      for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
   4465       1.1     skrll 		{
   4466       1.1     skrll 		  int incl_type;
   4467       1.1     skrll 
   4468       1.1     skrll 		  incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
   4469       1.1     skrll 		  if (incl_type == N_EINCL)
   4470       1.1     skrll 		    {
   4471       1.1     skrll 		      if (nest == 0)
   4472       1.1     skrll 			break;
   4473       1.1     skrll 		      --nest;
   4474       1.1     skrll 		    }
   4475       1.1     skrll 		  else if (incl_type == N_BINCL)
   4476       1.1     skrll 		    ++nest;
   4477       1.1     skrll 		  else if (nest == 0)
   4478       1.1     skrll 		    {
   4479       1.1     skrll 		      const char *s;
   4480       1.1     skrll 
   4481       1.1     skrll 		      s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
   4482       1.1     skrll 		      for (; *s != '\0'; s++)
   4483       1.1     skrll 			{
   4484       1.1     skrll 			  val += *s;
   4485       1.1     skrll 			  if (*s == '(')
   4486       1.1     skrll 			    {
   4487       1.1     skrll 			      /* Skip the file number.  */
   4488       1.1     skrll 			      ++s;
   4489   1.1.1.6  christos 			      while (ISDIGIT (*s))
   4490   1.1.1.6  christos 				++s;
   4491   1.1.1.3  christos 			      --s;
   4492   1.1.1.3  christos 			    }
   4493   1.1.1.9  christos 			}
   4494       1.1     skrll 		    }
   4495   1.1.1.9  christos 		}
   4496       1.1     skrll 
   4497       1.1     skrll 	      /* If we have already included a header file with the
   4498       1.1     skrll 		 same value, then replace this one with an N_EXCL
   4499       1.1     skrll 		 symbol.  */
   4500       1.1     skrll 	      copy = ! flaginfo->info->keep_memory;
   4501       1.1     skrll 	      incl_entry = aout_link_includes_lookup (&flaginfo->includes,
   4502   1.1.1.6  christos 						      name, true, copy);
   4503   1.1.1.3  christos 	      if (incl_entry == NULL)
   4504       1.1     skrll 		return false;
   4505       1.1     skrll 	      for (t = incl_entry->totals; t != NULL; t = t->next)
   4506   1.1.1.9  christos 		if (t->total == val)
   4507       1.1     skrll 		  break;
   4508       1.1     skrll 	      if (t == NULL)
   4509       1.1     skrll 		{
   4510       1.1     skrll 		  /* This is the first time we have seen this header
   4511       1.1     skrll 		     file with this set of stabs strings.  */
   4512       1.1     skrll 		  t = bfd_hash_allocate (&flaginfo->includes.root,
   4513       1.1     skrll 					 sizeof *t);
   4514       1.1     skrll 		  if (t == NULL)
   4515       1.1     skrll 		    return false;
   4516   1.1.1.6  christos 		  t->total = val;
   4517   1.1.1.6  christos 		  t->next = incl_entry->totals;
   4518       1.1     skrll 		  incl_entry->totals = t;
   4519       1.1     skrll 		}
   4520       1.1     skrll 	      else
   4521       1.1     skrll 		{
   4522       1.1     skrll 		  int *incl_map;
   4523       1.1     skrll 
   4524       1.1     skrll 		  /* This is a duplicate header file.  We must change
   4525       1.1     skrll 		     it to be an N_EXCL entry, and mark all the
   4526       1.1     skrll 		     included symbols to prevent outputting them.  */
   4527       1.1     skrll 		  type = N_EXCL;
   4528       1.1     skrll 
   4529       1.1     skrll 		  nest = 0;
   4530       1.1     skrll 		  for (incl_sym = sym + 1, incl_map = symbol_map + 1;
   4531       1.1     skrll 		       incl_sym < sym_end;
   4532       1.1     skrll 		       incl_sym++, incl_map++)
   4533       1.1     skrll 		    {
   4534       1.1     skrll 		      int incl_type;
   4535       1.1     skrll 
   4536       1.1     skrll 		      incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
   4537       1.1     skrll 		      if (incl_type == N_EINCL)
   4538       1.1     skrll 			{
   4539       1.1     skrll 			  if (nest == 0)
   4540       1.1     skrll 			    {
   4541       1.1     skrll 			      *incl_map = -1;
   4542       1.1     skrll 			      break;
   4543       1.1     skrll 			    }
   4544       1.1     skrll 			  --nest;
   4545       1.1     skrll 			}
   4546       1.1     skrll 		      else if (incl_type == N_BINCL)
   4547       1.1     skrll 			++nest;
   4548       1.1     skrll 		      else if (nest == 0)
   4549   1.1.1.9  christos 			*incl_map = -1;
   4550   1.1.1.9  christos 		    }
   4551   1.1.1.9  christos 		}
   4552   1.1.1.3  christos 	    }
   4553       1.1     skrll 	}
   4554       1.1     skrll 
   4555       1.1     skrll       /* Copy this symbol into the list of symbols we are going to
   4556       1.1     skrll 	 write out.  */
   4557       1.1     skrll       H_PUT_8 (output_bfd, type, outsym->e_type);
   4558       1.1     skrll       H_PUT_8 (output_bfd, H_GET_8 (input_bfd, sym->e_ovly), outsym->e_ovly);
   4559       1.1     skrll       H_PUT_16 (output_bfd, H_GET_16 (input_bfd, sym->e_desc), outsym->e_desc);
   4560   1.1.1.9  christos       copy = false;
   4561       1.1     skrll       if (! flaginfo->info->keep_memory)
   4562   1.1.1.3  christos 	{
   4563       1.1     skrll 	  /* name points into a string table which we are going to
   4564       1.1     skrll 	     free.  If there is a hash table entry, use that string.
   4565   1.1.1.9  christos 	     Otherwise, copy name into memory.  */
   4566       1.1     skrll 	  if (h != NULL)
   4567       1.1     skrll 	    name = h->root.root.string;
   4568       1.1     skrll 	  else
   4569       1.1     skrll 	    copy = true;
   4570       1.1     skrll 	}
   4571       1.1     skrll       strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
   4572       1.1     skrll 				       name, copy);
   4573       1.1     skrll       if (strtab_index == (bfd_size_type) -1)
   4574   1.1.1.3  christos 	return false;
   4575       1.1     skrll       PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
   4576       1.1     skrll       PUT_WORD (output_bfd, val, outsym->e_value);
   4577       1.1     skrll       *symbol_map = obj_aout_external_sym_count (output_bfd);
   4578   1.1.1.3  christos       ++obj_aout_external_sym_count (output_bfd);
   4579   1.1.1.9  christos       ++outsym;
   4580   1.1.1.3  christos     }
   4581       1.1     skrll 
   4582  1.1.1.10  christos   /* Write out the output symbols we have just constructed.  */
   4583   1.1.1.9  christos   if (outsym > flaginfo->output_syms)
   4584   1.1.1.3  christos     {
   4585       1.1     skrll       bfd_size_type size;
   4586       1.1     skrll 
   4587   1.1.1.9  christos       if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0)
   4588       1.1     skrll 	return false;
   4589       1.1     skrll       size = outsym - flaginfo->output_syms;
   4590       1.1     skrll       size *= EXTERNAL_NLIST_SIZE;
   4591       1.1     skrll       if (bfd_write (flaginfo->output_syms, size, output_bfd) != size)
   4592       1.1     skrll 	return false;
   4593       1.1     skrll       flaginfo->symoff += size;
   4594       1.1     skrll     }
   4595       1.1     skrll 
   4596       1.1     skrll   return true;
   4597       1.1     skrll }
   4598       1.1     skrll 
   4599       1.1     skrll /* Write out a symbol that was not associated with an a.out input
   4600       1.1     skrll    object.  */
   4601       1.1     skrll 
   4602       1.1     skrll static bfd_vma
   4603       1.1     skrll bfd_getp32 (const void *p)
   4604       1.1     skrll {
   4605       1.1     skrll   const bfd_byte *addr = p;
   4606       1.1     skrll   unsigned long v;
   4607       1.1     skrll 
   4608       1.1     skrll   v = (unsigned long) addr[1] << 24;
   4609       1.1     skrll   v |= (unsigned long) addr[0] << 16;
   4610       1.1     skrll   v |= (unsigned long) addr[3] << 8;
   4611       1.1     skrll   v |= (unsigned long) addr[2];
   4612       1.1     skrll   return v;
   4613       1.1     skrll }
   4614       1.1     skrll 
   4615       1.1     skrll #define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000)
   4616       1.1     skrll 
   4617       1.1     skrll static bfd_signed_vma
   4618       1.1     skrll bfd_getp_signed_32 (const void *p)
   4619       1.1     skrll {
   4620       1.1     skrll   const bfd_byte *addr = p;
   4621       1.1     skrll   unsigned long v;
   4622       1.1     skrll 
   4623       1.1     skrll   v = (unsigned long) addr[1] << 24;
   4624       1.1     skrll   v |= (unsigned long) addr[0] << 16;
   4625       1.1     skrll   v |= (unsigned long) addr[3] << 8;
   4626       1.1     skrll   v |= (unsigned long) addr[2];
   4627       1.1     skrll   return COERCE32 (v);
   4628       1.1     skrll }
   4629       1.1     skrll 
   4630       1.1     skrll static void
   4631       1.1     skrll bfd_putp32 (bfd_vma data, void *p)
   4632       1.1     skrll {
   4633       1.1     skrll   bfd_byte *addr = p;
   4634       1.1     skrll 
   4635       1.1     skrll   addr[0] = (data >> 16) & 0xff;
   4636       1.1     skrll   addr[1] = (data >> 24) & 0xff;
   4637       1.1     skrll   addr[2] = (data >> 0) & 0xff;
   4638       1.1     skrll   addr[3] = (data >> 8) & 0xff;
   4639       1.1     skrll }
   4640       1.1     skrll 
   4641       1.1     skrll const bfd_target MY (vec) =
   4642       1.1     skrll {
   4643       1.1     skrll   TARGETNAME,			/* Name.  */
   4644       1.1     skrll   bfd_target_aout_flavour,
   4645   1.1.1.3  christos   BFD_ENDIAN_LITTLE,		/* Target byte order (little).  */
   4646   1.1.1.9  christos   BFD_ENDIAN_LITTLE,		/* Target headers byte order (little).  */
   4647  1.1.1.12  christos   (HAS_RELOC | EXEC_P |		/* Object flags.  */
   4648       1.1     skrll    HAS_LINENO | HAS_DEBUG |
   4649       1.1     skrll    HAS_SYMS | HAS_LOCALS | WP_TEXT),
   4650       1.1     skrll   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
   4651       1.1     skrll   MY_symbol_leading_char,
   4652       1.1     skrll   AR_PAD_CHAR,			/* AR_pad_char.  */
   4653       1.1     skrll   15,				/* AR_max_namelen.  */
   4654   1.1.1.7  christos   0,				/* match priority.  */
   4655   1.1.1.7  christos   TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
   4656   1.1.1.7  christos   TARGET_MERGE_SECTIONS,
   4657   1.1.1.7  christos   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
   4658   1.1.1.7  christos      bfd_getp32, bfd_getp_signed_32, bfd_putp32,
   4659   1.1.1.7  christos      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
   4660   1.1.1.7  christos   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
   4661   1.1.1.7  christos      bfd_getp32, bfd_getp_signed_32, bfd_putp32,
   4662   1.1.1.7  christos      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers.  */
   4663   1.1.1.7  christos   {				/* bfd_check_format.  */
   4664   1.1.1.7  christos     _bfd_dummy_target,
   4665   1.1.1.7  christos     MY_object_p,
   4666   1.1.1.7  christos     bfd_generic_archive_p,
   4667   1.1.1.7  christos     MY_core_file_p
   4668   1.1.1.7  christos   },
   4669   1.1.1.7  christos   {				/* bfd_set_format.  */
   4670   1.1.1.7  christos     _bfd_bool_bfd_false_error,
   4671   1.1.1.7  christos     MY_mkobject,
   4672   1.1.1.7  christos     _bfd_generic_mkarchive,
   4673   1.1.1.7  christos     _bfd_bool_bfd_false_error
   4674   1.1.1.7  christos   },
   4675   1.1.1.7  christos   {			/* bfd_write_contents.  */
   4676   1.1.1.7  christos     _bfd_bool_bfd_false_error,
   4677   1.1.1.7  christos     MY_write_object_contents,
   4678   1.1.1.7  christos     _bfd_write_archive_contents,
   4679   1.1.1.7  christos     _bfd_bool_bfd_false_error
   4680   1.1.1.7  christos   },
   4681   1.1.1.7  christos 
   4682       1.1     skrll   BFD_JUMP_TABLE_GENERIC (MY),
   4683       1.1     skrll   BFD_JUMP_TABLE_COPY (MY),
   4684       1.1     skrll   BFD_JUMP_TABLE_CORE (MY),
   4685       1.1     skrll   BFD_JUMP_TABLE_ARCHIVE (MY),
   4686       1.1     skrll   BFD_JUMP_TABLE_SYMBOLS (MY),
   4687       1.1     skrll   BFD_JUMP_TABLE_RELOCS (MY),
   4688                       BFD_JUMP_TABLE_WRITE (MY),
   4689                       BFD_JUMP_TABLE_LINK (MY),
   4690                       BFD_JUMP_TABLE_DYNAMIC (MY),
   4691                     
   4692                       /* Alternative_target.  */
   4693                       NULL,
   4694                     
   4695                       (void *) MY_backend_data
   4696                     };
   4697