Back to index

cell-binutils  2.17cvs20070401
pdp11.c
Go to the documentation of this file.
00001 /* BFD back-end for PDP-11 a.out binaries.
00002    Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007
00003    Free Software Foundation, Inc.
00004 
00005    This file is part of BFD, the Binary File Descriptor library.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
00020 
00021 /* BFD backend for PDP-11, running 2.11BSD in particular.
00022 
00023    This file was hacked up by looking hard at the existing vaxnetbsd
00024    back end and the header files in 2.11BSD.
00025 
00026    TODO
00027    * support for V7 file formats
00028    * support for overlay object files (see 2.11 a.out(5))
00029    * support for old and very old archives
00030    (see 2.11 ar(5), historical section)
00031 
00032    Search for TODO to find other areas needing more work.  */
00033 
00034 #define       BYTES_IN_WORD 2
00035 #define       BYTES_IN_LONG 4
00036 #define ARCH_SIZE    16
00037 #undef TARGET_IS_BIG_ENDIAN_P
00038 
00039 #define       TARGET_PAGE_SIZE     1024
00040 #define       SEGMENT__SIZE TARGET_PAGE_SIZE
00041 
00042 #define       DEFAULT_ARCH  bfd_arch_pdp11
00043 #define       DEFAULT_MID   M_PDP11
00044 
00045 /* Do not "beautify" the CONCAT* macro args.  Traditional C will not
00046    remove whitespace added here, and thus will fail to concatenate
00047    the tokens.  */
00048 #define MY(OP) CONCAT2 (pdp11_aout_,OP)
00049 
00050 /* This needs to start with a.out so GDB knows it is an a.out variant.  */
00051 #define TARGETNAME "a.out-pdp11"
00052 
00053 /* This is the normal load address for executables.  */
00054 #define TEXT_START_ADDR            0
00055 
00056 /* The header is not included in the text segment.  */
00057 #define N_HEADER_IN_TEXT(x) 0
00058 
00059 /* There are no shared libraries.  */
00060 #define N_SHARED_LIB(x)     0
00061 
00062 /* There is no flags field.  */
00063 #define N_FLAGS(exec)              0
00064 
00065 #define N_SET_FLAGS(exec, flags) do { } while (0)
00066 #define N_BADMAG(x) (((x).a_info != OMAGIC)   \
00067                 && ((x).a_info != NMAGIC)   \
00068                 && ((x).a_info != A_MAGIC3) \
00069                 && ((x).a_info != A_MAGIC4) \
00070                 && ((x).a_info != A_MAGIC5) \
00071                 && ((x).a_info != A_MAGIC6))
00072 
00073 #include "bfd.h"
00074 
00075 #define external_exec pdp11_external_exec
00076 struct pdp11_external_exec
00077 {
00078   bfd_byte e_info[2];              /* Magic number.  */
00079   bfd_byte e_text[2];              /* Length of text section in bytes.  */
00080   bfd_byte e_data[2];              /* Length of data section in bytes.  */
00081   bfd_byte e_bss[2];        /* Length of bss area in bytes.  */
00082   bfd_byte e_syms[2];              /* Length of symbol table in bytes.  */
00083   bfd_byte e_entry[2];             /* Start address.  */
00084   bfd_byte e_unused[2];            /* Not used.  */
00085   bfd_byte e_flag[2];              /* Relocation info stripped.  */
00086   bfd_byte e_relocatable;   /* Ugly hack.  */
00087 };
00088 
00089 #define       EXEC_BYTES_SIZE      (8 * 2)
00090 
00091 #define       A_MAGIC1      OMAGIC
00092 #define OMAGIC              0407   /* ...object file or impure executable.  */
00093 #define       A_MAGIC2      NMAGIC
00094 #define NMAGIC              0410   /* Pure executable.  */
00095 #define ZMAGIC              0413   /* Demand-paged executable.  */
00096 #define       A_MAGIC3      0411   /* Separated I&D.  */
00097 #define       A_MAGIC4      0405   /* Overlay.  */
00098 #define       A_MAGIC5      0430   /* Auto-overlay (nonseparate).  */
00099 #define       A_MAGIC6      0431   /* Auto-overlay (separate).  */
00100 #define QMAGIC              0
00101 #define BMAGIC              0
00102 
00103 #define A_FLAG_RELOC_STRIPPED      0x0001
00104 
00105 #define external_nlist pdp11_external_nlist
00106 struct pdp11_external_nlist
00107 {
00108   bfd_byte e_unused[2];            /* Unused.  */
00109   bfd_byte e_strx[2];              /* Index into string table of name.  */
00110   bfd_byte e_type[1];              /* Type of symbol.  */
00111   bfd_byte e_ovly[1];              /* Overlay number.  */
00112   bfd_byte e_value[2];             /* Value of symbol.  */
00113 };
00114 
00115 #define       EXTERNAL_NLIST_SIZE  8
00116 
00117 #define N_TXTOFF(x)  (EXEC_BYTES_SIZE)
00118 #define N_DATOFF(x)  (N_TXTOFF(x) + (x).a_text)
00119 #define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
00120 #define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_trsize)
00121 #define N_SYMOFF(x)  (N_DRELOFF(x) + (x).a_drsize)
00122 #define N_STROFF(x)  (N_SYMOFF(x) + (x).a_syms)
00123 
00124 #define WRITE_HEADERS(abfd, execp) pdp11_aout_write_headers (abfd, execp)
00125 
00126 #include "sysdep.h"
00127 #include "libbfd.h"
00128 #include "libaout.h"
00129 
00130 #define SWAP_MAGIC(ext) bfd_getl16 (ext)
00131 
00132 #define MY_entry_is_text_address 1
00133 
00134 #define MY_write_object_contents MY(write_object_contents)
00135 static bfd_boolean MY(write_object_contents) (bfd *);
00136 #define MY_text_includes_header 1
00137 
00138 #define MY_BFD_TARGET
00139 
00140 #include "aout-target.h"
00141 
00142 /* Start of modified aoutx.h.  */
00143 #define KEEPIT udata.i
00144 
00145 #include <string.h>         /* For strchr and friends.  */
00146 #include "bfd.h"
00147 #include "sysdep.h"
00148 #include "safe-ctype.h"
00149 #include "bfdlink.h"
00150 
00151 #include "libaout.h"
00152 #include "aout/aout64.h"
00153 #include "aout/stab_gnu.h"
00154 #include "aout/ar.h"
00155 
00156 #undef N_TYPE
00157 #undef N_UNDF
00158 #undef N_ABS
00159 #undef N_TEXT
00160 #undef N_DATA
00161 #undef N_BSS
00162 #undef N_REG
00163 #undef N_FN
00164 #undef N_EXT
00165 #define N_TYPE              0x1f   /* Type mask.  */
00166 #define N_UNDF              0x00   /* Undefined.  */
00167 #define N_ABS        0x01   /* Absolute.  */
00168 #define N_TEXT              0x02   /* Text segment.  */
00169 #define N_DATA              0x03   /* Data segment.  */
00170 #define N_BSS        0x04   /* Bss segment.  */
00171 #define N_REG        0x14   /* Register symbol.  */
00172 #define N_FN         0x1f   /* File name.  */
00173 #define N_EXT        0x20   /* External flag.  */
00174 
00175 #define RELOC_SIZE 2
00176 
00177 #define RELFLG              0x0001 /* PC-relative flag.  */
00178 #define RTYPE        0x000e /* Type mask.  */
00179 #define RIDXMASK     0xfff0 /* Index mask.  */
00180 
00181 #define RABS         0x00   /* Absolute.  */
00182 #define RTEXT        0x02   /* Text.  */
00183 #define RDATA        0x04   /* Data.  */
00184 #define RBSS         0x06   /* Bss.  */
00185 #define REXT         0x08   /* External.  */
00186 
00187 #define RINDEX(x)    (((x) & 0xfff0) >> 4)
00188 
00189 #ifndef MY_final_link_relocate
00190 #define MY_final_link_relocate _bfd_final_link_relocate
00191 #endif
00192 
00193 #ifndef MY_relocate_contents
00194 #define MY_relocate_contents _bfd_relocate_contents
00195 #endif
00196 
00197 /* A hash table used for header files with N_BINCL entries.  */
00198 
00199 struct aout_link_includes_table
00200 {
00201   struct bfd_hash_table root;
00202 };
00203 
00204 /* A linked list of totals that we have found for a particular header
00205    file.  */
00206 
00207 struct aout_link_includes_totals
00208 {
00209   struct aout_link_includes_totals *next;
00210   bfd_vma total;
00211 };
00212 
00213 /* An entry in the header file hash table.  */
00214 
00215 struct aout_link_includes_entry
00216 {
00217   struct bfd_hash_entry root;
00218   /* List of totals we have found for this file.  */
00219   struct aout_link_includes_totals *totals;
00220 };
00221 
00222 /* During the final link step we need to pass around a bunch of
00223    information, so we do it in an instance of this structure.  */
00224 
00225 struct aout_final_link_info
00226 {
00227   /* General link information.  */
00228   struct bfd_link_info *info;
00229   /* Output bfd.  */
00230   bfd *output_bfd;
00231   /* Reloc file positions.  */
00232   file_ptr treloff, dreloff;
00233   /* File position of symbols.  */
00234   file_ptr symoff;
00235   /* String table.  */
00236   struct bfd_strtab_hash *strtab;
00237   /* Header file hash table.  */
00238   struct aout_link_includes_table includes;
00239   /* A buffer large enough to hold the contents of any section.  */
00240   bfd_byte *contents;
00241   /* A buffer large enough to hold the relocs of any section.  */
00242   void * relocs;
00243   /* A buffer large enough to hold the symbol map of any input BFD.  */
00244   int *symbol_map;
00245   /* A buffer large enough to hold output symbols of any input BFD.  */
00246   struct external_nlist *output_syms;
00247 };
00248 
00249 reloc_howto_type howto_table_pdp11[] =
00250 {
00251   /* type              rs size bsz  pcrel bitpos ovrf                     sf name     part_inpl readmask  setmask    pcdone */
00252 HOWTO( 0,            0,  1,  16,  FALSE, 0, complain_overflow_signed,0,"16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
00253 HOWTO( 1,            0,  1,  16,  TRUE,  0, complain_overflow_signed,0,"DISP16",    TRUE, 0x0000ffff,0x0000ffff, FALSE),
00254 };
00255 
00256 #define TABLE_SIZE(TABLE)   (sizeof(TABLE)/sizeof(TABLE[0]))
00257 
00258 
00259 static bfd_boolean aout_link_check_archive_element (bfd *, struct bfd_link_info *, bfd_boolean *);
00260 static bfd_boolean aout_link_add_object_symbols    (bfd *, struct bfd_link_info *);
00261 static bfd_boolean aout_link_add_symbols           (bfd *, struct bfd_link_info *);
00262 static bfd_boolean aout_link_write_symbols         (struct aout_final_link_info *, bfd *);
00263 
00264 
00265 reloc_howto_type *
00266 NAME (aout, reloc_type_lookup) (bfd * abfd ATTRIBUTE_UNUSED,
00267                             bfd_reloc_code_real_type code)
00268 {
00269   switch (code)
00270     {
00271     case BFD_RELOC_16:
00272       return &howto_table_pdp11[0];
00273     case BFD_RELOC_16_PCREL:
00274       return &howto_table_pdp11[1];
00275     default:
00276       return NULL;
00277     }
00278 }
00279 
00280 reloc_howto_type *
00281 NAME (aout, reloc_name_lookup) (bfd *abfd ATTRIBUTE_UNUSED,
00282                                   const char *r_name)
00283 {
00284   unsigned int i;
00285 
00286   for (i = 0;
00287        i < sizeof (howto_table_pdp11) / sizeof (howto_table_pdp11[0]);
00288        i++)
00289     if (howto_table_pdp11[i].name != NULL
00290        && strcasecmp (howto_table_pdp11[i].name, r_name) == 0)
00291       return &howto_table_pdp11[i];
00292 
00293   return NULL;
00294 }
00295 
00296 static int
00297 pdp11_aout_write_headers (bfd *abfd, struct internal_exec *execp)
00298 {
00299   struct external_exec exec_bytes;
00300   bfd_size_type text_size;
00301   file_ptr text_end;
00302 
00303   if (adata(abfd).magic == undecided_magic)
00304     NAME (aout, adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
00305 
00306   execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;
00307   execp->a_entry = bfd_get_start_address (abfd);
00308 
00309   if (obj_textsec (abfd)->reloc_count > 0
00310       || obj_datasec (abfd)->reloc_count > 0)
00311     {
00312       execp->a_trsize = execp->a_text;
00313       execp->a_drsize = execp->a_data;
00314     }
00315   else
00316     {
00317       execp->a_trsize = 0;
00318       execp->a_drsize = 0;
00319     }
00320 
00321   NAME (aout, swap_exec_header_out) (abfd, execp, & exec_bytes);
00322 
00323   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
00324     return FALSE;
00325 
00326   if (bfd_bwrite ((void *) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd)
00327       != EXEC_BYTES_SIZE)
00328     return FALSE;
00329 
00330   /* Now write out reloc info, followed by syms and strings.  */
00331   if (bfd_get_outsymbols (abfd) != NULL
00332       && bfd_get_symcount (abfd) != 0)
00333     {
00334       if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) != 0)
00335        return FALSE;
00336 
00337       if (! NAME (aout, write_syms) (abfd))
00338        return FALSE;
00339     }
00340 
00341   if (obj_textsec (abfd)->reloc_count > 0
00342       || obj_datasec (abfd)->reloc_count > 0)
00343     {
00344       if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) != 0
00345          || !NAME (aout, squirt_out_relocs) (abfd, obj_textsec (abfd))
00346          || bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) != 0
00347          || !NAME (aout, squirt_out_relocs) (abfd, obj_datasec (abfd)))  
00348        return FALSE;
00349     }
00350 
00351   return TRUE;
00352 }
00353 
00354 /* Write an object file.
00355    Section contents have already been written.  We write the
00356    file header, symbols, and relocation.  */
00357 
00358 static bfd_boolean
00359 MY(write_object_contents) (bfd *abfd)
00360 {
00361   struct internal_exec *execp = exec_hdr (abfd);
00362 
00363   /* We must make certain that the magic number has been set.  This
00364      will normally have been done by set_section_contents, but only if
00365      there actually are some section contents.  */
00366   if (! abfd->output_has_begun)
00367     {
00368       bfd_size_type text_size;
00369       file_ptr text_end;
00370 
00371       NAME (aout, adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
00372     }
00373 
00374   obj_reloc_entry_size (abfd) = RELOC_SIZE;
00375 
00376   return WRITE_HEADERS (abfd, execp);
00377 }
00378 
00379 /* Swap the information in an executable header @var{raw_bytes} taken
00380    from a raw byte stream memory image into the internal exec header
00381    structure "execp".  */
00382 
00383 #ifndef NAME_swap_exec_header_in
00384 void
00385 NAME (aout, swap_exec_header_in) (bfd *abfd,
00386                               struct external_exec *bytes,
00387                               struct internal_exec *execp)
00388 {
00389   /* The internal_exec structure has some fields that are unused in this
00390      configuration (IE for i960), so ensure that all such uninitialized
00391      fields are zero'd out.  There are places where two of these structs
00392      are memcmp'd, and thus the contents do matter.  */
00393   memset ((void *) execp, 0, sizeof (struct internal_exec));
00394   /* Now fill in fields in the execp, from the bytes in the raw data.  */
00395   execp->a_info   = GET_MAGIC (abfd, bytes->e_info);
00396   execp->a_text   = GET_WORD (abfd, bytes->e_text);
00397   execp->a_data   = GET_WORD (abfd, bytes->e_data);
00398   execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
00399   execp->a_syms   = GET_WORD (abfd, bytes->e_syms);
00400   execp->a_entry  = GET_WORD (abfd, bytes->e_entry);
00401 
00402   if (GET_WORD (abfd, bytes->e_flag) & A_FLAG_RELOC_STRIPPED)
00403     {
00404       execp->a_trsize = 0;
00405       execp->a_drsize = 0;
00406     }
00407   else
00408     {
00409       execp->a_trsize = execp->a_text;
00410       execp->a_drsize = execp->a_data;
00411     }
00412 }
00413 #define NAME_swap_exec_header_in NAME (aout, swap_exec_header_in)
00414 #endif
00415 
00416 /*  Swap the information in an internal exec header structure
00417     "execp" into the buffer "bytes" ready for writing to disk.  */
00418 void
00419 NAME (aout, swap_exec_header_out) (bfd *abfd,
00420                                struct internal_exec *execp,
00421                                struct external_exec *bytes)
00422 {
00423   /* Now fill in fields in the raw data, from the fields in the exec struct.  */
00424   PUT_MAGIC (abfd, execp->a_info,         bytes->e_info);
00425   PUT_WORD (abfd, execp->a_text,          bytes->e_text);
00426   PUT_WORD (abfd, execp->a_data,          bytes->e_data);
00427   PUT_WORD (abfd, execp->a_bss,                  bytes->e_bss);
00428   PUT_WORD (abfd, execp->a_syms,          bytes->e_syms);
00429   PUT_WORD (abfd, execp->a_entry,         bytes->e_entry);
00430   PUT_WORD (abfd, 0,                      bytes->e_unused);
00431 
00432   if ((execp->a_trsize == 0 || execp->a_text == 0)
00433       && (execp->a_drsize == 0 || execp->a_data == 0))
00434     PUT_WORD (abfd, A_FLAG_RELOC_STRIPPED, bytes->e_flag);
00435   else if (execp->a_trsize == execp->a_text
00436           && execp->a_drsize == execp->a_data)
00437     PUT_WORD (abfd, 0, bytes->e_flag);
00438   else
00439     {
00440       /* TODO: print a proper warning message.  */
00441       fprintf (stderr, "BFD:%s:%d: internal error\n", __FILE__, __LINE__);
00442       PUT_WORD (abfd, 0,                  bytes->e_flag);
00443     }
00444 }
00445 
00446 /* Make all the section for an a.out file.  */
00447 
00448 bfd_boolean
00449 NAME (aout, make_sections) (bfd *abfd)
00450 {
00451   if (obj_textsec (abfd) == NULL && bfd_make_section (abfd, ".text") == NULL)
00452     return FALSE;
00453   if (obj_datasec (abfd) == NULL && bfd_make_section (abfd, ".data") == NULL)
00454     return FALSE;
00455   if (obj_bsssec (abfd) == NULL  && bfd_make_section (abfd, ".bss") == NULL)
00456     return FALSE;
00457   return TRUE;
00458 }
00459 
00460 /* Some a.out variant thinks that the file open in ABFD
00461    checking is an a.out file.  Do some more checking, and set up
00462    for access if it really is.  Call back to the calling
00463    environment's "finish up" function just before returning, to
00464    handle any last-minute setup.  */
00465 
00466 const bfd_target *
00467 NAME (aout, some_aout_object_p) (bfd *abfd,
00468                              struct internal_exec *execp,
00469                              const bfd_target *(*callback_to_real_object_p) (bfd *))
00470 {
00471   struct aout_data_struct *rawptr, *oldrawptr;
00472   const bfd_target *result;
00473   bfd_size_type amt = sizeof (struct aout_data_struct);
00474 
00475   rawptr = bfd_zalloc (abfd, amt);
00476   if (rawptr == NULL)
00477     return 0;
00478 
00479   oldrawptr = abfd->tdata.aout_data;
00480   abfd->tdata.aout_data = rawptr;
00481 
00482   /* Copy the contents of the old tdata struct.
00483      In particular, we want the subformat, since for hpux it was set in
00484      hp300hpux.c:swap_exec_header_in and will be used in
00485      hp300hpux.c:callback.  */
00486   if (oldrawptr != NULL)
00487     *abfd->tdata.aout_data = *oldrawptr;
00488 
00489   abfd->tdata.aout_data->a.hdr = &rawptr->e;
00490   *(abfd->tdata.aout_data->a.hdr) = *execp;      /* Copy in the internal_exec struct.  */
00491   execp = abfd->tdata.aout_data->a.hdr;
00492 
00493   /* Set the file flags.  */
00494   abfd->flags = BFD_NO_FLAGS;
00495   if (execp->a_drsize || execp->a_trsize)
00496     abfd->flags |= HAS_RELOC;
00497   /* Setting of EXEC_P has been deferred to the bottom of this function.  */
00498   if (execp->a_syms)
00499     abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
00500   if (N_DYNAMIC(*execp))
00501     abfd->flags |= DYNAMIC;
00502 
00503   if (N_MAGIC (*execp) == ZMAGIC)
00504     {
00505       abfd->flags |= D_PAGED | WP_TEXT;
00506       adata (abfd).magic = z_magic;
00507     }
00508   else if (N_MAGIC (*execp) == QMAGIC)
00509     {
00510       abfd->flags |= D_PAGED | WP_TEXT;
00511       adata (abfd).magic = z_magic;
00512       adata (abfd).subformat = q_magic_format;
00513     }
00514   else if (N_MAGIC (*execp) == NMAGIC)
00515     {
00516       abfd->flags |= WP_TEXT;
00517       adata (abfd).magic = n_magic;
00518     }
00519   else if (N_MAGIC (*execp) == OMAGIC
00520           || N_MAGIC (*execp) == BMAGIC)
00521     adata (abfd).magic = o_magic;
00522   else
00523     {
00524       /* Should have been checked with N_BADMAG before this routine
00525         was called.  */
00526       abort ();
00527     }
00528 
00529   bfd_get_start_address (abfd) = execp->a_entry;
00530 
00531   obj_aout_symbols (abfd) = NULL;
00532   bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
00533 
00534   /* The default relocation entry size is that of traditional V7 Unix.  */
00535   obj_reloc_entry_size (abfd) = RELOC_SIZE;
00536 
00537   /* The default symbol entry size is that of traditional Unix.  */
00538   obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
00539 
00540 #ifdef USE_MMAP
00541   bfd_init_window (&obj_aout_sym_window (abfd));
00542   bfd_init_window (&obj_aout_string_window (abfd));
00543 #endif
00544 
00545   obj_aout_external_syms (abfd) = NULL;
00546   obj_aout_external_strings (abfd) = NULL;
00547   obj_aout_sym_hashes (abfd) = NULL;
00548 
00549   if (! NAME (aout, make_sections) (abfd))
00550     return NULL;
00551 
00552   obj_datasec (abfd)->size = execp->a_data;
00553   obj_bsssec (abfd)->size = execp->a_bss;
00554 
00555   obj_textsec (abfd)->flags =
00556     (execp->a_trsize != 0
00557      ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
00558      : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
00559   obj_datasec (abfd)->flags =
00560     (execp->a_drsize != 0
00561      ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
00562      : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
00563   obj_bsssec (abfd)->flags = SEC_ALLOC;
00564 
00565 #ifdef THIS_IS_ONLY_DOCUMENTATION
00566   /* The common code can't fill in these things because they depend
00567      on either the start address of the text segment, the rounding
00568      up of virtual addresses between segments, or the starting file
00569      position of the text segment -- all of which varies among different
00570      versions of a.out.  */
00571 
00572   /* Call back to the format-dependent code to fill in the rest of the
00573      fields and do any further cleanup.  Things that should be filled
00574      in by the callback:  */
00575   struct exec *execp = exec_hdr (abfd);
00576 
00577   obj_textsec (abfd)->size = N_TXTSIZE(*execp);
00578   /* Data and bss are already filled in since they're so standard.  */
00579 
00580   /* The virtual memory addresses of the sections.  */
00581   obj_textsec (abfd)->vma = N_TXTADDR(*execp);
00582   obj_datasec (abfd)->vma = N_DATADDR(*execp);
00583   obj_bsssec  (abfd)->vma = N_BSSADDR(*execp);
00584 
00585   /* The file offsets of the sections.  */
00586   obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
00587   obj_datasec (abfd)->filepos = N_DATOFF(*execp);
00588 
00589   /* The file offsets of the relocation info.  */
00590   obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
00591   obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
00592 
00593   /* The file offsets of the string table and symbol table.  */
00594   obj_str_filepos (abfd) = N_STROFF (*execp);
00595   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
00596 
00597   /* Determine the architecture and machine type of the object file.  */
00598   abfd->obj_arch = bfd_arch_obscure;
00599 
00600   adata(abfd)->page_size = TARGET_PAGE_SIZE;
00601   adata(abfd)->segment_size = SEGMENT_SIZE;
00602   adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
00603 
00604   return abfd->xvec;
00605 
00606   /* The architecture is encoded in various ways in various a.out variants,
00607      or is not encoded at all in some of them.  The relocation size depends
00608      on the architecture and the a.out variant.  Finally, the return value
00609      is the bfd_target vector in use.  If an error occurs, return zero and
00610      set bfd_error to the appropriate error code.
00611 
00612      Formats such as b.out, which have additional fields in the a.out
00613      header, should cope with them in this callback as well.  */
00614 #endif /* DOCUMENTATION */
00615 
00616   result = (*callback_to_real_object_p)(abfd);
00617 
00618   /* Now that the segment addresses have been worked out, take a better
00619      guess at whether the file is executable.  If the entry point
00620      is within the text segment, assume it is.  (This makes files
00621      executable even if their entry point address is 0, as long as
00622      their text starts at zero.).
00623 
00624      This test had to be changed to deal with systems where the text segment
00625      runs at a different location than the default.  The problem is that the
00626      entry address can appear to be outside the text segment, thus causing an
00627      erroneous conclusion that the file isn't executable.
00628 
00629      To fix this, we now accept any non-zero entry point as an indication of
00630      executability.  This will work most of the time, since only the linker
00631      sets the entry point, and that is likely to be non-zero for most systems. */
00632 
00633   if (execp->a_entry != 0
00634       || (execp->a_entry >= obj_textsec(abfd)->vma
00635          && execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->size))
00636     abfd->flags |= EXEC_P;
00637 #ifdef STAT_FOR_EXEC
00638   else
00639     {
00640       struct stat stat_buf;
00641 
00642       /* The original heuristic doesn't work in some important cases.
00643         The a.out file has no information about the text start
00644         address.  For files (like kernels) linked to non-standard
00645         addresses (ld -Ttext nnn) the entry point may not be between
00646         the default text start (obj_textsec(abfd)->vma) and
00647         (obj_textsec(abfd)->vma) + text size.  This is not just a mach
00648         issue.  Many kernels are loaded at non standard addresses.  */
00649       if (abfd->iostream != NULL
00650          && (abfd->flags & BFD_IN_MEMORY) == 0
00651          && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
00652          && ((stat_buf.st_mode & 0111) != 0))
00653        abfd->flags |= EXEC_P;
00654     }
00655 #endif /* STAT_FOR_EXEC */
00656 
00657   if (!result)
00658     {
00659       free (rawptr);
00660       abfd->tdata.aout_data = oldrawptr;
00661     }
00662   return result;
00663 }
00664 
00665 /* Initialize ABFD for use with a.out files.  */
00666 
00667 bfd_boolean
00668 NAME (aout, mkobject) (bfd *abfd)
00669 {
00670   struct aout_data_struct  *rawptr;
00671   bfd_size_type amt = sizeof (struct aout_data_struct);
00672 
00673   bfd_set_error (bfd_error_system_call);
00674 
00675   /* Use an intermediate variable for clarity.  */
00676   rawptr = bfd_zalloc (abfd, amt);
00677 
00678   if (rawptr == NULL)
00679     return FALSE;
00680 
00681   abfd->tdata.aout_data = rawptr;
00682   exec_hdr (abfd) = &(rawptr->e);
00683 
00684   obj_textsec (abfd) = NULL;
00685   obj_datasec (abfd) = NULL;
00686   obj_bsssec (abfd)  = NULL;
00687 
00688   return TRUE;
00689 }
00690 
00691 /* Keep track of machine architecture and machine type for
00692    a.out's. Return the <<machine_type>> for a particular
00693    architecture and machine, or <<M_UNKNOWN>> if that exact architecture
00694    and machine can't be represented in a.out format.
00695 
00696    If the architecture is understood, machine type 0 (default)
00697    is always understood.  */
00698 
00699 enum machine_type
00700 NAME (aout, machine_type) (enum bfd_architecture arch,
00701                         unsigned long machine,
00702                         bfd_boolean *unknown)
00703 {
00704   enum machine_type arch_flags;
00705 
00706   arch_flags = M_UNKNOWN;
00707   *unknown = TRUE;
00708 
00709   switch (arch)
00710     {
00711     case bfd_arch_sparc:
00712       if (machine == 0
00713          || machine == bfd_mach_sparc
00714          || machine == bfd_mach_sparc_sparclite
00715          || machine == bfd_mach_sparc_v9)
00716        arch_flags = M_SPARC;
00717       else if (machine == bfd_mach_sparc_sparclet)
00718        arch_flags = M_SPARCLET;
00719       break;
00720 
00721     case bfd_arch_m68k:
00722       switch (machine)
00723        {
00724        case 0:                    arch_flags = M_68010; break;
00725        case bfd_mach_m68000: arch_flags = M_UNKNOWN; *unknown = FALSE; break;
00726        case bfd_mach_m68010: arch_flags = M_68010; break;
00727        case bfd_mach_m68020: arch_flags = M_68020; break;
00728        default:            arch_flags = M_UNKNOWN; break;
00729        }
00730       break;
00731 
00732     case bfd_arch_i386:
00733       if (machine == 0
00734          || machine == bfd_mach_i386_i386
00735          || machine == bfd_mach_i386_i386_intel_syntax)
00736        arch_flags = M_386;
00737       break;
00738 
00739     case bfd_arch_arm:
00740       if (machine == 0)     arch_flags = M_ARM;
00741       break;
00742 
00743     case bfd_arch_mips:
00744       switch (machine)
00745        {
00746        case 0:
00747        case 2000:
00748        case bfd_mach_mips3000:
00749           arch_flags = M_MIPS1;
00750          break;
00751        case bfd_mach_mips4000: /* MIPS3 */
00752        case bfd_mach_mips4400:
00753        case bfd_mach_mips8000: /* MIPS4 */
00754        case bfd_mach_mips6000: /* Real MIPS2: */
00755           arch_flags = M_MIPS2;
00756          break;
00757        default:
00758          arch_flags = M_UNKNOWN;
00759          break;
00760        }
00761       break;
00762 
00763     case bfd_arch_ns32k:
00764       switch (machine)
00765        {
00766        case 0:              arch_flags = M_NS32532; break;
00767        case 32032:          arch_flags = M_NS32032; break;
00768        case 32532:          arch_flags = M_NS32532; break;
00769        default:             arch_flags = M_UNKNOWN; break;
00770        }
00771       break;
00772 
00773     case bfd_arch_pdp11:
00774       /* TODO: arch_flags = M_PDP11; */
00775       *unknown = FALSE;
00776       break;
00777 
00778     case bfd_arch_vax:
00779       *unknown = FALSE;
00780       break;
00781 
00782     default:
00783       arch_flags = M_UNKNOWN;
00784     }
00785 
00786   if (arch_flags != M_UNKNOWN)
00787     *unknown = FALSE;
00788 
00789   return arch_flags;
00790 }
00791 
00792 /* Set the architecture and the machine of the ABFD to the
00793    values ARCH and MACHINE.  Verify that @ABFD's format
00794    can support the architecture required.  */
00795 
00796 bfd_boolean
00797 NAME (aout, set_arch_mach) (bfd *abfd,
00798                          enum bfd_architecture arch,
00799                          unsigned long machine)
00800 {
00801   if (! bfd_default_set_arch_mach (abfd, arch, machine))
00802     return FALSE;
00803 
00804   if (arch != bfd_arch_unknown)
00805     {
00806       bfd_boolean unknown;
00807 
00808       NAME (aout, machine_type) (arch, machine, &unknown);
00809       if (unknown)
00810        return FALSE;
00811     }
00812 
00813   obj_reloc_entry_size (abfd) = RELOC_SIZE;
00814 
00815   return (*aout_backend_info(abfd)->set_sizes) (abfd);
00816 }
00817 
00818 static void
00819 adjust_o_magic (bfd *abfd, struct internal_exec *execp)
00820 {
00821   file_ptr pos = adata (abfd).exec_bytes_size;
00822   bfd_vma vma = 0;
00823   int pad = 0;
00824 
00825   /* Text.  */
00826   obj_textsec (abfd)->filepos = pos;
00827   if (! obj_textsec (abfd)->user_set_vma)
00828     obj_textsec (abfd)->vma = vma;
00829   else
00830     vma = obj_textsec (abfd)->vma;
00831 
00832   pos += obj_textsec (abfd)->size;
00833   vma += obj_textsec (abfd)->size;
00834 
00835   /* Data.  */
00836   if (!obj_datasec (abfd)->user_set_vma)
00837     {
00838       obj_textsec (abfd)->size += pad;
00839       pos += pad;
00840       vma += pad;
00841       obj_datasec (abfd)->vma = vma;
00842     }
00843   else
00844     vma = obj_datasec (abfd)->vma;
00845   obj_datasec (abfd)->filepos = pos;
00846   pos += obj_datasec (abfd)->size;
00847   vma += obj_datasec (abfd)->size;
00848 
00849   /* BSS.  */
00850   if (! obj_bsssec (abfd)->user_set_vma)
00851     {
00852       obj_datasec (abfd)->size += pad;
00853       pos += pad;
00854       vma += pad;
00855       obj_bsssec (abfd)->vma = vma;
00856     }
00857   else
00858     {
00859       /* The VMA of the .bss section is set by the VMA of the
00860          .data section plus the size of the .data section.  We may
00861          need to add padding bytes to make this true.  */
00862       pad = obj_bsssec (abfd)->vma - vma;
00863       if (pad > 0)
00864        {
00865          obj_datasec (abfd)->size += pad;
00866          pos += pad;
00867        }
00868     }
00869   obj_bsssec (abfd)->filepos = pos;
00870 
00871   /* Fix up the exec header.  */
00872   execp->a_text = obj_textsec (abfd)->size;
00873   execp->a_data = obj_datasec (abfd)->size;
00874   execp->a_bss  = obj_bsssec (abfd)->size;
00875   N_SET_MAGIC (*execp, OMAGIC);
00876 }
00877 
00878 static void
00879 adjust_z_magic (bfd *abfd, struct internal_exec *execp)
00880 {
00881   bfd_size_type data_pad, text_pad;
00882   file_ptr text_end;
00883   const struct aout_backend_data *abdp;
00884   int ztih;                 /* Nonzero if text includes exec header.  */
00885 
00886   abdp = aout_backend_info (abfd);
00887 
00888   /* Text.  */
00889   ztih = (abdp != NULL
00890          && (abdp->text_includes_header
00891              || obj_aout_subformat (abfd) == q_magic_format));
00892   obj_textsec(abfd)->filepos = (ztih
00893                             ? adata(abfd).exec_bytes_size
00894                             : adata(abfd).zmagic_disk_block_size);
00895   if (! obj_textsec(abfd)->user_set_vma)
00896     {
00897       /* ?? Do we really need to check for relocs here?  */
00898       obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC)
00899                             ? 0
00900                             : (ztih
00901                                ? (abdp->default_text_vma
00902                                   + adata (abfd).exec_bytes_size)
00903                                : abdp->default_text_vma));
00904       text_pad = 0;
00905     }
00906   else
00907     {
00908       /* The .text section is being loaded at an unusual address.  We
00909          may need to pad it such that the .data section starts at a page
00910          boundary.  */
00911       if (ztih)
00912        text_pad = ((obj_textsec (abfd)->filepos - obj_textsec (abfd)->vma)
00913                   & (adata (abfd).page_size - 1));
00914       else
00915        text_pad = ((- obj_textsec (abfd)->vma)
00916                   & (adata (abfd).page_size - 1));
00917     }
00918 
00919   /* Find start of data.  */
00920   if (ztih)
00921     {
00922       text_end = obj_textsec (abfd)->filepos + obj_textsec (abfd)->size;
00923       text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
00924     }
00925   else
00926     {
00927       /* Note that if page_size == zmagic_disk_block_size, then
00928         filepos == page_size, and this case is the same as the ztih
00929         case.  */
00930       text_end = obj_textsec (abfd)->size;
00931       text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
00932       text_end += obj_textsec (abfd)->filepos;
00933     }
00934 
00935   obj_textsec (abfd)->size += text_pad;
00936   text_end += text_pad;
00937 
00938   /* Data.  */
00939   if (!obj_datasec(abfd)->user_set_vma)
00940     {
00941       bfd_vma vma;
00942       vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->size;
00943       obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
00944     }
00945   if (abdp && abdp->zmagic_mapped_contiguous)
00946     {
00947       text_pad = (obj_datasec(abfd)->vma
00948                 - obj_textsec(abfd)->vma
00949                 - obj_textsec(abfd)->size);
00950       obj_textsec(abfd)->size += text_pad;
00951     }
00952   obj_datasec (abfd)->filepos = (obj_textsec (abfd)->filepos
00953                             + obj_textsec (abfd)->size);
00954 
00955   /* Fix up exec header while we're at it.  */
00956   execp->a_text = obj_textsec(abfd)->size;
00957   if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
00958     execp->a_text += adata(abfd).exec_bytes_size;
00959   if (obj_aout_subformat (abfd) == q_magic_format)
00960     N_SET_MAGIC (*execp, QMAGIC);
00961   else
00962     N_SET_MAGIC (*execp, ZMAGIC);
00963 
00964   /* Spec says data section should be rounded up to page boundary.  */
00965   obj_datasec(abfd)->size
00966     = align_power (obj_datasec(abfd)->size,
00967                  obj_bsssec(abfd)->alignment_power);
00968   execp->a_data = BFD_ALIGN (obj_datasec(abfd)->size,
00969                           adata(abfd).page_size);
00970   data_pad = execp->a_data - obj_datasec(abfd)->size;
00971 
00972   /* BSS.  */
00973   if (!obj_bsssec(abfd)->user_set_vma)
00974     obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
00975                           + obj_datasec(abfd)->size);
00976   /* If the BSS immediately follows the data section and extra space
00977      in the page is left after the data section, fudge data
00978      in the header so that the bss section looks smaller by that
00979      amount.  We'll start the bss section there, and lie to the OS.
00980      (Note that a linker script, as well as the above assignment,
00981      could have explicitly set the BSS vma to immediately follow
00982      the data section.)  */
00983   if (align_power (obj_bsssec(abfd)->vma, obj_bsssec(abfd)->alignment_power)
00984       == obj_datasec(abfd)->vma + obj_datasec(abfd)->size)
00985     execp->a_bss = (data_pad > obj_bsssec(abfd)->size) ? 0 :
00986       obj_bsssec(abfd)->size - data_pad;
00987   else
00988     execp->a_bss = obj_bsssec(abfd)->size;
00989 }
00990 
00991 static void
00992 adjust_n_magic (bfd *abfd, struct internal_exec *execp)
00993 {
00994   file_ptr pos = adata(abfd).exec_bytes_size;
00995   bfd_vma vma = 0;
00996   int pad;
00997 
00998   /* Text.  */
00999   obj_textsec(abfd)->filepos = pos;
01000   if (!obj_textsec(abfd)->user_set_vma)
01001     obj_textsec(abfd)->vma = vma;
01002   else
01003     vma = obj_textsec(abfd)->vma;
01004   pos += obj_textsec(abfd)->size;
01005   vma += obj_textsec(abfd)->size;
01006 
01007   /* Data.  */
01008   obj_datasec(abfd)->filepos = pos;
01009   if (!obj_datasec(abfd)->user_set_vma)
01010     obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
01011   vma = obj_datasec(abfd)->vma;
01012 
01013   /* Since BSS follows data immediately, see if it needs alignment.  */
01014   vma += obj_datasec(abfd)->size;
01015   pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
01016   obj_datasec(abfd)->size += pad;
01017   pos += obj_datasec(abfd)->size;
01018 
01019   /* BSS.  */
01020   if (!obj_bsssec(abfd)->user_set_vma)
01021     obj_bsssec(abfd)->vma = vma;
01022   else
01023     vma = obj_bsssec(abfd)->vma;
01024 
01025   /* Fix up exec header.  */
01026   execp->a_text = obj_textsec(abfd)->size;
01027   execp->a_data = obj_datasec(abfd)->size;
01028   execp->a_bss = obj_bsssec(abfd)->size;
01029   N_SET_MAGIC (*execp, NMAGIC);
01030 }
01031 
01032 bfd_boolean
01033 NAME (aout, adjust_sizes_and_vmas) (bfd *abfd,
01034                                 bfd_size_type *text_size,
01035                                 file_ptr * text_end ATTRIBUTE_UNUSED)
01036 {
01037   struct internal_exec *execp = exec_hdr (abfd);
01038 
01039   if (! NAME (aout, make_sections) (abfd))
01040     return FALSE;
01041 
01042   if (adata(abfd).magic != undecided_magic)
01043     return TRUE;
01044 
01045   obj_textsec(abfd)->size =
01046     align_power(obj_textsec(abfd)->size,
01047               obj_textsec(abfd)->alignment_power);
01048 
01049   *text_size = obj_textsec (abfd)->size;
01050   /* Rule (heuristic) for when to pad to a new page.  Note that there
01051      are (at least) two ways demand-paged (ZMAGIC) files have been
01052      handled.  Most Berkeley-based systems start the text segment at
01053      (TARGET_PAGE_SIZE).  However, newer versions of SUNOS start the text
01054      segment right after the exec header; the latter is counted in the
01055      text segment size, and is paged in by the kernel with the rest of
01056      the text. */
01057 
01058   /* This perhaps isn't the right way to do this, but made it simpler for me
01059      to understand enough to implement it.  Better would probably be to go
01060      right from BFD flags to alignment/positioning characteristics.  But the
01061      old code was sloppy enough about handling the flags, and had enough
01062      other magic, that it was a little hard for me to understand.  I think
01063      I understand it better now, but I haven't time to do the cleanup this
01064      minute.  */
01065 
01066   if (abfd->flags & WP_TEXT)
01067     adata(abfd).magic = n_magic;
01068   else
01069     adata(abfd).magic = o_magic;
01070 
01071 #ifdef BFD_AOUT_DEBUG /* requires gcc2 */
01072 #if __GNUC__ >= 2
01073   fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
01074           ({ char *str;
01075              switch (adata(abfd).magic) {
01076              case n_magic: str = "NMAGIC"; break;
01077              case o_magic: str = "OMAGIC"; break;
01078              case z_magic: str = "ZMAGIC"; break;
01079              default: abort ();
01080              }
01081              str;
01082            }),
01083           obj_textsec(abfd)->vma, obj_textsec(abfd)->size,
01084               obj_textsec(abfd)->alignment_power,
01085           obj_datasec(abfd)->vma, obj_datasec(abfd)->size,
01086               obj_datasec(abfd)->alignment_power,
01087           obj_bsssec(abfd)->vma, obj_bsssec(abfd)->size,
01088               obj_bsssec(abfd)->alignment_power);
01089 #endif
01090 #endif
01091 
01092   switch (adata(abfd).magic)
01093     {
01094     case o_magic:
01095       adjust_o_magic (abfd, execp);
01096       break;
01097     case z_magic:
01098       adjust_z_magic (abfd, execp);
01099       break;
01100     case n_magic:
01101       adjust_n_magic (abfd, execp);
01102       break;
01103     default:
01104       abort ();
01105     }
01106 
01107 #ifdef BFD_AOUT_DEBUG
01108   fprintf (stderr, "       text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
01109           obj_textsec(abfd)->vma, obj_textsec(abfd)->size,
01110               obj_textsec(abfd)->filepos,
01111           obj_datasec(abfd)->vma, obj_datasec(abfd)->size,
01112               obj_datasec(abfd)->filepos,
01113           obj_bsssec(abfd)->vma, obj_bsssec(abfd)->size);
01114 #endif
01115 
01116   return TRUE;
01117 }
01118 
01119 /* Called by the BFD in response to a bfd_make_section request.  */
01120 
01121 bfd_boolean
01122 NAME (aout, new_section_hook) (bfd *abfd, asection *newsect)
01123 {
01124   /* Align to double at least.  */
01125   newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
01126 
01127   if (bfd_get_format (abfd) == bfd_object)
01128     {
01129       if (obj_textsec (abfd) == NULL
01130          && !strcmp (newsect->name, ".text"))
01131        {
01132          obj_textsec(abfd)= newsect;
01133          newsect->target_index = N_TEXT;
01134        }
01135       else if (obj_datasec (abfd) == NULL
01136               && !strcmp (newsect->name, ".data"))
01137        {
01138          obj_datasec (abfd) = newsect;
01139          newsect->target_index = N_DATA;
01140        }
01141       else if (obj_bsssec (abfd) == NULL
01142               && !strcmp (newsect->name, ".bss"))
01143        {
01144          obj_bsssec (abfd) = newsect;
01145          newsect->target_index = N_BSS;
01146        }
01147     }
01148 
01149   /* We allow more than three sections internally.  */
01150   return _bfd_generic_new_section_hook (abfd, newsect);
01151 }
01152 
01153 bfd_boolean
01154 NAME (aout, set_section_contents) (bfd *abfd,
01155                                sec_ptr section,
01156                                const void * location,
01157                                file_ptr offset,
01158                                bfd_size_type count)
01159 {
01160   file_ptr text_end;
01161   bfd_size_type text_size;
01162 
01163   if (! abfd->output_has_begun)
01164     {
01165       if (! NAME (aout, adjust_sizes_and_vmas) (abfd, & text_size, & text_end))
01166        return FALSE;
01167     }
01168 
01169   if (section == obj_bsssec (abfd))
01170     {
01171       bfd_set_error (bfd_error_no_contents);
01172       return FALSE;
01173     }
01174 
01175   if (section != obj_textsec (abfd)
01176       && section != obj_datasec (abfd))
01177     {
01178       (*_bfd_error_handler)
01179        ("%s: can not represent section `%s' in a.out object file format",
01180         bfd_get_filename (abfd), bfd_get_section_name (abfd, section));
01181       bfd_set_error (bfd_error_nonrepresentable_section);
01182       return FALSE;
01183     }
01184 
01185   if (count != 0)
01186     {
01187       if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
01188          || bfd_bwrite (location, count, abfd) != count)
01189        return FALSE;
01190     }
01191 
01192   return TRUE;
01193 }
01194 
01195 /* Read the external symbols from an a.out file.  */
01196 
01197 static bfd_boolean
01198 aout_get_external_symbols (bfd *abfd)
01199 {
01200   if (obj_aout_external_syms (abfd) == NULL)
01201     {
01202       bfd_size_type count;
01203       struct external_nlist *syms;
01204 
01205       count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
01206 
01207 #ifdef USE_MMAP
01208       if (! bfd_get_file_window (abfd, obj_sym_filepos (abfd),
01209                              exec_hdr (abfd)->a_syms,
01210                              &obj_aout_sym_window (abfd), TRUE))
01211        return FALSE;
01212       syms = (struct external_nlist *) obj_aout_sym_window (abfd).data;
01213 #else
01214       /* We allocate using malloc to make the values easy to free
01215         later on.  If we put them on the objalloc it might not be
01216         possible to free them.  */
01217       syms = bfd_malloc (count * EXTERNAL_NLIST_SIZE);
01218       if (syms == NULL && count != 0)
01219        return FALSE;
01220 
01221       if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
01222          || (bfd_bread (syms, exec_hdr (abfd)->a_syms, abfd)
01223              != exec_hdr (abfd)->a_syms))
01224        {
01225          free (syms);
01226          return FALSE;
01227        }
01228 #endif
01229 
01230       obj_aout_external_syms (abfd) = syms;
01231       obj_aout_external_sym_count (abfd) = count;
01232     }
01233 
01234   if (obj_aout_external_strings (abfd) == NULL
01235       && exec_hdr (abfd)->a_syms != 0)
01236     {
01237       unsigned char string_chars[BYTES_IN_LONG];
01238       bfd_size_type stringsize;
01239       char *strings;
01240 
01241       /* Get the size of the strings.  */
01242       if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
01243          || (bfd_bread ((void *) string_chars, (bfd_size_type) BYTES_IN_LONG,
01244                      abfd) != BYTES_IN_LONG))
01245        return FALSE;
01246       stringsize = H_GET_32 (abfd, string_chars);
01247 
01248 #ifdef USE_MMAP
01249       if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize,
01250                              &obj_aout_string_window (abfd), TRUE))
01251        return FALSE;
01252       strings = (char *) obj_aout_string_window (abfd).data;
01253 #else
01254       strings = bfd_malloc (stringsize + 1);
01255       if (strings == NULL)
01256        return FALSE;
01257 
01258       /* Skip space for the string count in the buffer for convenience
01259         when using indexes.  */
01260       if (bfd_bread (strings + 4, stringsize - 4, abfd) != stringsize - 4)
01261        {
01262          free (strings);
01263          return FALSE;
01264        }
01265 #endif
01266       /* Ensure that a zero index yields an empty string.  */
01267       strings[0] = '\0';
01268 
01269       strings[stringsize - 1] = 0;
01270 
01271       obj_aout_external_strings (abfd) = strings;
01272       obj_aout_external_string_size (abfd) = stringsize;
01273     }
01274 
01275   return TRUE;
01276 }
01277 
01278 /* Translate an a.out symbol into a BFD symbol.  The desc, other, type
01279    and symbol->value fields of CACHE_PTR will be set from the a.out
01280    nlist structure.  This function is responsible for setting
01281    symbol->flags and symbol->section, and adjusting symbol->value.  */
01282 
01283 static bfd_boolean
01284 translate_from_native_sym_flags (bfd *abfd,
01285                              aout_symbol_type *cache_ptr)
01286 {
01287   flagword visible;
01288 
01289   if (cache_ptr->type == N_FN)
01290     {
01291       asection *sec;
01292 
01293       /* This is a debugging symbol.  */
01294       cache_ptr->symbol.flags = BSF_DEBUGGING;
01295 
01296       /* Work out the symbol section.  */
01297       switch (cache_ptr->type & N_TYPE)
01298        {
01299        case N_TEXT:
01300        case N_FN:
01301          sec = obj_textsec (abfd);
01302          break;
01303        case N_DATA:
01304          sec = obj_datasec (abfd);
01305          break;
01306        case N_BSS:
01307          sec = obj_bsssec (abfd);
01308          break;
01309        default:
01310        case N_ABS:
01311          sec = bfd_abs_section_ptr;
01312          break;
01313        }
01314 
01315       cache_ptr->symbol.section = sec;
01316       cache_ptr->symbol.value -= sec->vma;
01317 
01318       return TRUE;
01319     }
01320 
01321   /* Get the default visibility.  This does not apply to all types, so
01322      we just hold it in a local variable to use if wanted.  */
01323   if ((cache_ptr->type & N_EXT) == 0)
01324     visible = BSF_LOCAL;
01325   else
01326     visible = BSF_GLOBAL;
01327 
01328   switch (cache_ptr->type)
01329     {
01330     default:
01331     case N_ABS: case N_ABS | N_EXT:
01332       cache_ptr->symbol.section = bfd_abs_section_ptr;
01333       cache_ptr->symbol.flags = visible;
01334       break;
01335 
01336     case N_UNDF | N_EXT:
01337       if (cache_ptr->symbol.value != 0)
01338        {
01339          /* This is a common symbol.  */
01340          cache_ptr->symbol.flags = BSF_GLOBAL;
01341          cache_ptr->symbol.section = bfd_com_section_ptr;
01342        }
01343       else
01344        {
01345          cache_ptr->symbol.flags = 0;
01346          cache_ptr->symbol.section = bfd_und_section_ptr;
01347        }
01348       break;
01349 
01350     case N_TEXT: case N_TEXT | N_EXT:
01351       cache_ptr->symbol.section = obj_textsec (abfd);
01352       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
01353       cache_ptr->symbol.flags = visible;
01354       break;
01355 
01356     case N_DATA: case N_DATA | N_EXT:
01357       cache_ptr->symbol.section = obj_datasec (abfd);
01358       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
01359       cache_ptr->symbol.flags = visible;
01360       break;
01361 
01362     case N_BSS: case N_BSS | N_EXT:
01363       cache_ptr->symbol.section = obj_bsssec (abfd);
01364       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
01365       cache_ptr->symbol.flags = visible;
01366       break;
01367     }
01368 
01369   return TRUE;
01370 }
01371 
01372 /* Set the fields of SYM_POINTER according to CACHE_PTR.  */
01373 
01374 static bfd_boolean
01375 translate_to_native_sym_flags (bfd *abfd,
01376                             asymbol *cache_ptr,
01377                             struct external_nlist *sym_pointer)
01378 {
01379   bfd_vma value = cache_ptr->value;
01380   asection *sec;
01381   bfd_vma off;
01382 
01383   /* Mask out any existing type bits in case copying from one section
01384      to another.  */
01385   sym_pointer->e_type[0] &= ~N_TYPE;
01386 
01387   sec = bfd_get_section (cache_ptr);
01388   off = 0;
01389 
01390   if (sec == NULL)
01391     {
01392       /* This case occurs, e.g., for the *DEBUG* section of a COFF
01393         file.  */
01394       (*_bfd_error_handler)
01395        ("%B: can not represent section for symbol `%s' in a.out object file format",
01396         abfd, cache_ptr->name != NULL ? cache_ptr->name : "*unknown*");
01397       bfd_set_error (bfd_error_nonrepresentable_section);
01398       return FALSE;
01399     }
01400 
01401   if (sec->output_section != NULL)
01402     {
01403       off = sec->output_offset;
01404       sec = sec->output_section;
01405     }
01406 
01407   if (bfd_is_abs_section (sec))
01408     sym_pointer->e_type[0] |= N_ABS;
01409   else if (sec == obj_textsec (abfd))
01410     sym_pointer->e_type[0] |= N_TEXT;
01411   else if (sec == obj_datasec (abfd))
01412     sym_pointer->e_type[0] |= N_DATA;
01413   else if (sec == obj_bsssec (abfd))
01414     sym_pointer->e_type[0] |= N_BSS;
01415   else if (bfd_is_und_section (sec))
01416     sym_pointer->e_type[0] = N_UNDF | N_EXT;
01417   else if (bfd_is_com_section (sec))
01418     sym_pointer->e_type[0] = N_UNDF | N_EXT;
01419   else
01420     {
01421       (*_bfd_error_handler)
01422        ("%B: can not represent section `%A' in a.out object file format",
01423         abfd, sec);
01424       bfd_set_error (bfd_error_nonrepresentable_section);
01425       return FALSE;
01426     }
01427 
01428   /* Turn the symbol from section relative to absolute again */
01429   value += sec->vma + off;
01430 
01431   if ((cache_ptr->flags & BSF_DEBUGGING) != 0)
01432     sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
01433   else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
01434     sym_pointer->e_type[0] |= N_EXT;
01435 
01436   PUT_WORD(abfd, value, sym_pointer->e_value);
01437 
01438   return TRUE;
01439 }
01440 
01441 /* Native-level interface to symbols. */
01442 
01443 asymbol *
01444 NAME (aout, make_empty_symbol) (bfd *abfd)
01445 {
01446   bfd_size_type amt = sizeof (aout_symbol_type);
01447   aout_symbol_type *new = bfd_zalloc (abfd, amt);
01448 
01449   if (!new)
01450     return NULL;
01451   new->symbol.the_bfd = abfd;
01452 
01453   return &new->symbol;
01454 }
01455 
01456 /* Translate a set of internal symbols into external symbols.  */
01457 
01458 bfd_boolean
01459 NAME (aout, translate_symbol_table) (bfd *abfd,
01460                                  aout_symbol_type *in,
01461                                  struct external_nlist *ext,
01462                                  bfd_size_type count,
01463                                  char *str,
01464                                  bfd_size_type strsize,
01465                                  bfd_boolean dynamic)
01466 {
01467   struct external_nlist *ext_end;
01468 
01469   ext_end = ext + count;
01470   for (; ext < ext_end; ext++, in++)
01471     {
01472       bfd_vma x;
01473 
01474       x = GET_WORD (abfd, ext->e_strx);
01475       in->symbol.the_bfd = abfd;
01476 
01477       /* For the normal symbols, the zero index points at the number
01478         of bytes in the string table but is to be interpreted as the
01479         null string.  For the dynamic symbols, the number of bytes in
01480         the string table is stored in the __DYNAMIC structure and the
01481         zero index points at an actual string.  */
01482       if (x == 0 && ! dynamic)
01483        in->symbol.name = "";
01484       else if (x < strsize)
01485        in->symbol.name = str + x;
01486       else
01487        return FALSE;
01488 
01489       in->symbol.value = GET_SWORD (abfd,  ext->e_value);
01490       /* TODO: is 0 a safe value here?  */
01491       in->desc = 0;
01492       in->other = 0;
01493       in->type = H_GET_8 (abfd,  ext->e_type);
01494       in->symbol.udata.p = NULL;
01495 
01496       if (! translate_from_native_sym_flags (abfd, in))
01497        return FALSE;
01498 
01499       if (dynamic)
01500        in->symbol.flags |= BSF_DYNAMIC;
01501     }
01502 
01503   return TRUE;
01504 }
01505 
01506 /* We read the symbols into a buffer, which is discarded when this
01507    function exits.  We read the strings into a buffer large enough to
01508    hold them all plus all the cached symbol entries.  */
01509 
01510 bfd_boolean
01511 NAME (aout, slurp_symbol_table) (bfd *abfd)
01512 {
01513   struct external_nlist *old_external_syms;
01514   aout_symbol_type *cached;
01515   bfd_size_type cached_size;
01516 
01517   /* If there's no work to be done, don't do any.  */
01518   if (obj_aout_symbols (abfd) != NULL)
01519     return TRUE;
01520 
01521   old_external_syms = obj_aout_external_syms (abfd);
01522 
01523   if (! aout_get_external_symbols (abfd))
01524     return FALSE;
01525 
01526   cached_size = obj_aout_external_sym_count (abfd);
01527   cached_size *= sizeof (aout_symbol_type);
01528   cached = bfd_zmalloc (cached_size);
01529   if (cached == NULL && cached_size != 0)
01530     return FALSE;
01531 
01532   /* Convert from external symbol information to internal.  */
01533   if (! (NAME (aout, translate_symbol_table)
01534         (abfd, cached,
01535          obj_aout_external_syms (abfd),
01536          obj_aout_external_sym_count (abfd),
01537          obj_aout_external_strings (abfd),
01538          obj_aout_external_string_size (abfd),
01539          FALSE)))
01540     {
01541       free (cached);
01542       return FALSE;
01543     }
01544 
01545   bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd);
01546 
01547   obj_aout_symbols (abfd) = cached;
01548 
01549   /* It is very likely that anybody who calls this function will not
01550      want the external symbol information, so if it was allocated
01551      because of our call to aout_get_external_symbols, we free it up
01552      right away to save space.  */
01553   if (old_external_syms == NULL
01554       && obj_aout_external_syms (abfd) != NULL)
01555     {
01556 #ifdef USE_MMAP
01557       bfd_free_window (&obj_aout_sym_window (abfd));
01558 #else
01559       free (obj_aout_external_syms (abfd));
01560 #endif
01561       obj_aout_external_syms (abfd) = NULL;
01562     }
01563 
01564   return TRUE;
01565 }
01566 
01567 /* We use a hash table when writing out symbols so that we only write
01568    out a particular string once.  This helps particularly when the
01569    linker writes out stabs debugging entries, because each different
01570    contributing object file tends to have many duplicate stabs
01571    strings.
01572 
01573    This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
01574    if BFD_TRADITIONAL_FORMAT is set.  */
01575 
01576 /* Get the index of a string in a strtab, adding it if it is not
01577    already present.  */
01578 
01579 static INLINE bfd_size_type
01580 add_to_stringtab (bfd *abfd,
01581                 struct bfd_strtab_hash *tab,
01582                 const char *str,
01583                 bfd_boolean copy)
01584 {
01585   bfd_boolean hash;
01586   bfd_size_type index;
01587 
01588   /* An index of 0 always means the empty string.  */
01589   if (str == 0 || *str == '\0')
01590     return 0;
01591 
01592   /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
01593      doesn't understand a hashed string table.  */
01594   hash = TRUE;
01595   if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
01596     hash = FALSE;
01597 
01598   index = _bfd_stringtab_add (tab, str, hash, copy);
01599 
01600   if (index != (bfd_size_type) -1)
01601     /* Add BYTES_IN_LONG to the return value to account for the
01602        space taken up by the string table size.  */
01603     index += BYTES_IN_LONG;
01604 
01605   return index;
01606 }
01607 
01608 /* Write out a strtab.  ABFD is already at the right location in the
01609    file.  */
01610 
01611 static bfd_boolean
01612 emit_stringtab (bfd *abfd, struct bfd_strtab_hash *tab)
01613 {
01614   bfd_byte buffer[BYTES_IN_LONG];
01615 
01616   /* The string table starts with the size.  */
01617   H_PUT_32 (abfd, _bfd_stringtab_size (tab) + BYTES_IN_LONG, buffer);
01618   if (bfd_bwrite ((void *) buffer, (bfd_size_type) BYTES_IN_LONG, abfd)
01619       != BYTES_IN_LONG)
01620     return FALSE;
01621 
01622   return _bfd_stringtab_emit (abfd, tab);
01623 }
01624 
01625 bfd_boolean
01626 NAME (aout, write_syms) (bfd *abfd)
01627 {
01628   unsigned int count ;
01629   asymbol **generic = bfd_get_outsymbols (abfd);
01630   struct bfd_strtab_hash *strtab;
01631 
01632   strtab = _bfd_stringtab_init ();
01633   if (strtab == NULL)
01634     return FALSE;
01635 
01636   for (count = 0; count < bfd_get_symcount (abfd); count++)
01637     {
01638       asymbol *g = generic[count];
01639       bfd_size_type indx;
01640       struct external_nlist nsp;
01641 
01642       PUT_WORD (abfd, 0, nsp.e_unused);
01643 
01644       indx = add_to_stringtab (abfd, strtab, g->name, FALSE);
01645       if (indx == (bfd_size_type) -1)
01646        goto error_return;
01647       PUT_WORD (abfd, indx, nsp.e_strx);
01648 
01649       if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
01650        H_PUT_8 (abfd, aout_symbol(g)->type,  nsp.e_type);
01651       else
01652        H_PUT_8 (abfd, 0, nsp.e_type);
01653 
01654       if (! translate_to_native_sym_flags (abfd, g, &nsp))
01655        goto error_return;
01656 
01657       H_PUT_8 (abfd, 0, nsp.e_ovly);
01658 
01659       if (bfd_bwrite ((void *)&nsp, (bfd_size_type) EXTERNAL_NLIST_SIZE, abfd)
01660          != EXTERNAL_NLIST_SIZE)
01661        goto error_return;
01662 
01663       /* NB: `KEEPIT' currently overlays `udata.p', so set this only
01664         here, at the end.  */
01665       g->KEEPIT = count;
01666     }
01667 
01668   if (! emit_stringtab (abfd, strtab))
01669     goto error_return;
01670 
01671   _bfd_stringtab_free (strtab);
01672 
01673   return TRUE;
01674 
01675 error_return:
01676   _bfd_stringtab_free (strtab);
01677   return FALSE;
01678 }
01679 
01680 
01681 long
01682 NAME (aout, canonicalize_symtab) (bfd *abfd, asymbol **location)
01683 {
01684   unsigned int counter = 0;
01685   aout_symbol_type *symbase;
01686 
01687   if (!NAME (aout, slurp_symbol_table) (abfd))
01688     return -1;
01689 
01690   for (symbase = obj_aout_symbols (abfd); counter++ < bfd_get_symcount (abfd);)
01691     *(location++) = (asymbol *)(symbase++);
01692   *location++ =0;
01693   return bfd_get_symcount (abfd);
01694 }
01695 
01696 
01697 /* Output extended relocation information to a file in target byte order.  */
01698 
01699 static void
01700 pdp11_aout_swap_reloc_out (bfd *abfd, arelent *g, bfd_byte *natptr)
01701 {
01702   int r_index;
01703   int r_pcrel;
01704   int reloc_entry;
01705   int r_type;
01706   asymbol *sym = *(g->sym_ptr_ptr);
01707   asection *output_section = sym->section->output_section;
01708 
01709   if (g->addend != 0)
01710     fprintf (stderr, "BFD: can't do this reloc addend stuff\n");
01711 
01712   r_pcrel = g->howto->pc_relative;
01713 
01714   if (bfd_is_abs_section (output_section))
01715     r_type = RABS;
01716   else if (output_section == obj_textsec (abfd))
01717     r_type = RTEXT;
01718   else if (output_section == obj_datasec (abfd))
01719     r_type = RDATA;
01720   else if (output_section == obj_bsssec (abfd))
01721     r_type = RBSS;
01722   else if (bfd_is_und_section (output_section))
01723     r_type = REXT;
01724   else if (bfd_is_com_section (output_section))
01725     r_type = REXT;
01726   else
01727     r_type = -1;
01728 
01729   BFD_ASSERT (r_type != -1);
01730 
01731   if (r_type == RABS)
01732     r_index = 0;
01733   else
01734     r_index = (*(g->sym_ptr_ptr))->KEEPIT;
01735 
01736   reloc_entry = r_index << 4 | r_type | r_pcrel;
01737 
01738   PUT_WORD (abfd, reloc_entry, natptr);
01739 }
01740 
01741 /* BFD deals internally with all things based from the section they're
01742    in. so, something in 10 bytes into a text section  with a base of
01743    50 would have a symbol (.text+10) and know .text vma was 50.
01744 
01745    Aout keeps all it's symbols based from zero, so the symbol would
01746    contain 60. This macro subs the base of each section from the value
01747    to give the true offset from the section */
01748 
01749 
01750 #define MOVE_ADDRESS(ad)                                              \
01751   if (r_extern)                                                \
01752     {                                                          \
01753       /* Undefined symbol.  */                                        \
01754       cache_ptr->sym_ptr_ptr = symbols + r_index;                     \
01755       cache_ptr->addend = ad;                                         \
01756     }                                                          \
01757   else                                                         \
01758     {                                                          \
01759       /* Defined, section relative. replace symbol with pointer to           \
01760         symbol which points to section.  */                           \
01761       switch (r_index)                                                \
01762        {                                                       \
01763        case N_TEXT:                                            \
01764        case N_TEXT | N_EXT:                                    \
01765          cache_ptr->sym_ptr_ptr  = obj_textsec (abfd)->symbol_ptr_ptr;       \
01766          cache_ptr->addend = ad  - su->textsec->vma;                  \
01767          break;                                                \
01768        case N_DATA:                                            \
01769        case N_DATA | N_EXT:                                    \
01770          cache_ptr->sym_ptr_ptr  = obj_datasec (abfd)->symbol_ptr_ptr;       \
01771          cache_ptr->addend = ad - su->datasec->vma;                   \
01772          break;                                                \
01773        case N_BSS:                                             \
01774        case N_BSS | N_EXT:                                     \
01775          cache_ptr->sym_ptr_ptr  = obj_bsssec (abfd)->symbol_ptr_ptr; \
01776          cache_ptr->addend = ad - su->bsssec->vma;                    \
01777          break;                                                \
01778        default:                                                \
01779        case N_ABS:                                             \
01780        case N_ABS | N_EXT:                                     \
01781          cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;       \
01782          cache_ptr->addend = ad;                               \
01783          break;                                                \
01784        }                                                       \
01785     }
01786 
01787 static void
01788 pdp11_aout_swap_reloc_in (bfd *          abfd,
01789                        bfd_byte *     bytes,
01790                        arelent *      cache_ptr,
01791                        bfd_size_type  offset,
01792                        asymbol **     symbols,
01793                        bfd_size_type  symcount)
01794 {
01795   struct aoutdata *su = &(abfd->tdata.aout_data->a);
01796   unsigned int r_index;
01797   int reloc_entry;
01798   int r_extern;
01799   int r_pcrel;
01800 
01801   reloc_entry = GET_WORD (abfd, (void *) bytes);
01802 
01803   r_pcrel = reloc_entry & RELFLG;
01804 
01805   cache_ptr->address = offset;
01806   cache_ptr->howto = howto_table_pdp11 + (r_pcrel ? 1 : 0);
01807 
01808   if ((reloc_entry & RTYPE) == RABS)
01809     r_index = N_ABS;
01810   else
01811     r_index = RINDEX (reloc_entry);
01812 
01813   /* r_extern reflects whether the symbol the reloc is against is
01814      local or global.  */
01815   r_extern = (reloc_entry & RTYPE) == REXT;
01816 
01817   if (r_extern && r_index > symcount)
01818     {
01819       /* We could arrange to return an error, but it might be useful
01820          to see the file even if it is bad.  */
01821       r_extern = 0;
01822       r_index = N_ABS;
01823     }
01824 
01825   MOVE_ADDRESS(0);
01826 }
01827 
01828 /* Read and swap the relocs for a section.  */
01829 
01830 bfd_boolean
01831 NAME (aout, slurp_reloc_table) (bfd *abfd, sec_ptr asect, asymbol **symbols)
01832 {
01833   bfd_byte *rptr;
01834   bfd_size_type count;
01835   bfd_size_type reloc_size;
01836   void * relocs;
01837   arelent *reloc_cache;
01838   size_t each_size;
01839   unsigned int counter = 0;
01840   arelent *cache_ptr;
01841 
01842   if (asect->relocation)
01843     return TRUE;
01844 
01845   if (asect->flags & SEC_CONSTRUCTOR)
01846     return TRUE;
01847 
01848   if (asect == obj_datasec (abfd))
01849     reloc_size = exec_hdr(abfd)->a_drsize;
01850   else if (asect == obj_textsec (abfd))
01851     reloc_size = exec_hdr(abfd)->a_trsize;
01852   else if (asect == obj_bsssec (abfd))
01853     reloc_size = 0;
01854   else
01855     {
01856       bfd_set_error (bfd_error_invalid_operation);
01857       return FALSE;
01858     }
01859 
01860   if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
01861     return FALSE;
01862 
01863   each_size = obj_reloc_entry_size (abfd);
01864 
01865   relocs = bfd_malloc (reloc_size);
01866   if (relocs == NULL && reloc_size != 0)
01867     return FALSE;
01868 
01869   if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
01870     {
01871       free (relocs);
01872       return FALSE;
01873     }
01874 
01875   count = reloc_size / each_size;
01876 
01877   /* Count the number of NON-ZERO relocs, this is the count we want.  */
01878   {
01879     unsigned int real_count = 0;
01880 
01881     for (counter = 0; counter < count; counter++)
01882       {
01883        int x;
01884 
01885        x = GET_WORD (abfd, (char *) relocs + each_size * counter);
01886        if (x != 0)
01887          real_count++;
01888       }
01889 
01890     count = real_count;
01891   }
01892 
01893   reloc_cache = bfd_zmalloc (count * sizeof (arelent));
01894   if (reloc_cache == NULL && count != 0)
01895     return FALSE;
01896 
01897   cache_ptr = reloc_cache;
01898 
01899   rptr = relocs;
01900   for (counter = 0;
01901        counter < count;
01902        counter++, rptr += RELOC_SIZE, cache_ptr++)
01903     {
01904       while (GET_WORD (abfd, (void *) rptr) == 0)
01905        {
01906          rptr += RELOC_SIZE;
01907          if ((char *) rptr >= (char *) relocs + reloc_size)
01908            goto done;
01909        }
01910 
01911       pdp11_aout_swap_reloc_in (abfd, rptr, cache_ptr,
01912                             (bfd_size_type) ((char *) rptr - (char *) relocs),
01913                             symbols,
01914                             (bfd_size_type) bfd_get_symcount (abfd));
01915     }
01916  done:
01917   /* Just in case, if rptr >= relocs + reloc_size should happen
01918      too early.  */
01919   BFD_ASSERT (counter == count);
01920 
01921   free (relocs);
01922 
01923   asect->relocation = reloc_cache;
01924   asect->reloc_count = cache_ptr - reloc_cache;
01925 
01926   return TRUE;
01927 }
01928 
01929 /* Write out a relocation section into an object file.  */
01930 
01931 bfd_boolean
01932 NAME (aout, squirt_out_relocs) (bfd *abfd, asection *section)
01933 {
01934   arelent **generic;
01935   unsigned char *native;
01936   unsigned int count = section->reloc_count;
01937   bfd_size_type natsize;
01938 
01939   natsize = section->size;
01940   native = bfd_zalloc (abfd, natsize);
01941   if (!native)
01942     return FALSE;
01943 
01944   generic = section->orelocation;
01945   if (generic != NULL)
01946     {
01947       while (count > 0)
01948        {
01949          bfd_byte *r;
01950 
01951          r = native + (*generic)->address;
01952          pdp11_aout_swap_reloc_out (abfd, *generic, r);
01953          count--;
01954          generic++;
01955        }
01956     }
01957 
01958   if (bfd_bwrite ((void *) native, natsize, abfd) != natsize)
01959     {
01960       bfd_release (abfd, native);
01961       return FALSE;
01962     }
01963 
01964   bfd_release (abfd, native);
01965   return TRUE;
01966 }
01967 
01968 /* This is stupid.  This function should be a boolean predicate.  */
01969 
01970 long
01971 NAME (aout, canonicalize_reloc) (bfd *abfd,
01972                              sec_ptr section,
01973                              arelent **relptr,
01974                              asymbol **symbols)
01975 {
01976   arelent *tblptr = section->relocation;
01977   unsigned int count;
01978 
01979   if (section == obj_bsssec (abfd))
01980     {
01981       *relptr = NULL;
01982       return 0;
01983     }
01984 
01985   if (!(tblptr || NAME (aout, slurp_reloc_table)(abfd, section, symbols)))
01986     return -1;
01987 
01988   if (section->flags & SEC_CONSTRUCTOR)
01989     {
01990       arelent_chain *chain = section->constructor_chain;
01991 
01992       for (count = 0; count < section->reloc_count; count ++)
01993        {
01994          *relptr ++ = &chain->relent;
01995          chain = chain->next;
01996        }
01997     }
01998   else
01999     {
02000       tblptr = section->relocation;
02001 
02002       for (count = 0; count++ < section->reloc_count;)
02003        *relptr++ = tblptr++;
02004     }
02005 
02006   *relptr = 0;
02007 
02008   return section->reloc_count;
02009 }
02010 
02011 long
02012 NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect)
02013 {
02014   if (bfd_get_format (abfd) != bfd_object)
02015     {
02016       bfd_set_error (bfd_error_invalid_operation);
02017       return -1;
02018     }
02019 
02020   if (asect->flags & SEC_CONSTRUCTOR)
02021     return (sizeof (arelent *) * (asect->reloc_count + 1));
02022 
02023   if (asect == obj_datasec (abfd))
02024     return (sizeof (arelent *)
02025            * ((exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd))
02026               + 1));
02027 
02028   if (asect == obj_textsec (abfd))
02029     return (sizeof (arelent *)
02030            * ((exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd))
02031               + 1));
02032 
02033   /* TODO: why are there two if statements for obj_bsssec()? */
02034 
02035   if (asect == obj_bsssec (abfd))
02036     return sizeof (arelent *);
02037 
02038   if (asect == obj_bsssec (abfd))
02039     return 0;
02040 
02041   bfd_set_error (bfd_error_invalid_operation);
02042   return -1;
02043 }
02044 
02045 
02046 long
02047 NAME (aout, get_symtab_upper_bound) (bfd *abfd)
02048 {
02049   if (!NAME (aout, slurp_symbol_table) (abfd))
02050     return -1;
02051 
02052   return (bfd_get_symcount (abfd) + 1) * (sizeof (aout_symbol_type *));
02053 }
02054 
02055 alent *
02056 NAME (aout, get_lineno) (bfd * abfd ATTRIBUTE_UNUSED,
02057                       asymbol * symbol ATTRIBUTE_UNUSED)
02058 {
02059   return NULL;
02060 }
02061 
02062 void
02063 NAME (aout, get_symbol_info) (bfd * abfd ATTRIBUTE_UNUSED,
02064                            asymbol *symbol,
02065                            symbol_info *ret)
02066 {
02067   bfd_symbol_info (symbol, ret);
02068 
02069   if (ret->type == '?')
02070     {
02071       int type_code = aout_symbol(symbol)->type & 0xff;
02072       const char *stab_name = bfd_get_stab_name (type_code);
02073       static char buf[10];
02074 
02075       if (stab_name == NULL)
02076        {
02077          sprintf(buf, "(%d)", type_code);
02078          stab_name = buf;
02079        }
02080       ret->type = '-';
02081       ret->stab_type  = type_code;
02082       ret->stab_other = (unsigned) (aout_symbol(symbol)->other & 0xff);
02083       ret->stab_desc  = (unsigned) (aout_symbol(symbol)->desc & 0xffff);
02084       ret->stab_name  = stab_name;
02085     }
02086 }
02087 
02088 void
02089 NAME (aout, print_symbol) (bfd * abfd,
02090                         void * afile,
02091                         asymbol *symbol,
02092                         bfd_print_symbol_type how)
02093 {
02094   FILE *file = (FILE *) afile;
02095 
02096   switch (how)
02097     {
02098     case bfd_print_symbol_name:
02099       if (symbol->name)
02100        fprintf(file,"%s", symbol->name);
02101       break;
02102     case bfd_print_symbol_more:
02103       fprintf(file,"%4x %2x %2x",
02104              (unsigned) (aout_symbol (symbol)->desc & 0xffff),
02105              (unsigned) (aout_symbol (symbol)->other & 0xff),
02106              (unsigned) (aout_symbol (symbol)->type));
02107       break;
02108     case bfd_print_symbol_all:
02109       {
02110        const char *section_name = symbol->section->name;
02111 
02112        bfd_print_symbol_vandf (abfd, (void *) file, symbol);
02113 
02114        fprintf (file," %-5s %04x %02x %02x",
02115                section_name,
02116                (unsigned) (aout_symbol (symbol)->desc & 0xffff),
02117                (unsigned) (aout_symbol (symbol)->other & 0xff),
02118                (unsigned) (aout_symbol (symbol)->type  & 0xff));
02119        if (symbol->name)
02120          fprintf(file," %s", symbol->name);
02121       }
02122       break;
02123     }
02124 }
02125 
02126 /* If we don't have to allocate more than 1MB to hold the generic
02127    symbols, we use the generic minisymbol method: it's faster, since
02128    it only translates the symbols once, not multiple times.  */
02129 #define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
02130 
02131 /* Read minisymbols.  For minisymbols, we use the unmodified a.out
02132    symbols.  The minisymbol_to_symbol function translates these into
02133    BFD asymbol structures.  */
02134 
02135 long
02136 NAME (aout, read_minisymbols) (bfd *abfd,
02137                             bfd_boolean dynamic,
02138                             void * *minisymsp,
02139                             unsigned int *sizep)
02140 {
02141   if (dynamic)
02142     /* We could handle the dynamic symbols here as well, but it's
02143        easier to hand them off.  */
02144     return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
02145 
02146   if (! aout_get_external_symbols (abfd))
02147     return -1;
02148 
02149   if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
02150     return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
02151 
02152   *minisymsp = (void *) obj_aout_external_syms (abfd);
02153 
02154   /* By passing the external symbols back from this routine, we are
02155      giving up control over the memory block.  Clear
02156      obj_aout_external_syms, so that we do not try to free it
02157      ourselves.  */
02158   obj_aout_external_syms (abfd) = NULL;
02159 
02160   *sizep = EXTERNAL_NLIST_SIZE;
02161   return obj_aout_external_sym_count (abfd);
02162 }
02163 
02164 /* Convert a minisymbol to a BFD asymbol.  A minisymbol is just an
02165    unmodified a.out symbol.  The SYM argument is a structure returned
02166    by bfd_make_empty_symbol, which we fill in here.  */
02167 
02168 asymbol *
02169 NAME (aout, minisymbol_to_symbol) (bfd *abfd,
02170                                bfd_boolean dynamic,
02171                                const void * minisym,
02172                                asymbol *sym)
02173 {
02174   if (dynamic
02175       || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
02176     return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
02177 
02178   memset (sym, 0, sizeof (aout_symbol_type));
02179 
02180   /* We call translate_symbol_table to translate a single symbol.  */
02181   if (! (NAME (aout, translate_symbol_table)
02182         (abfd,
02183          (aout_symbol_type *) sym,
02184          (struct external_nlist *) minisym,
02185          (bfd_size_type) 1,
02186          obj_aout_external_strings (abfd),
02187          obj_aout_external_string_size (abfd),
02188          FALSE)))
02189     return NULL;
02190 
02191   return sym;
02192 }
02193 
02194 /* Provided a BFD, a section and an offset into the section, calculate
02195    and return the name of the source file and the line nearest to the
02196    wanted location.  */
02197 
02198 bfd_boolean
02199 NAME (aout, find_nearest_line) (bfd *abfd,
02200                             asection *section,
02201                             asymbol **symbols,
02202                             bfd_vma offset,
02203                             const char **filename_ptr,
02204                             const char **functionname_ptr,
02205                             unsigned int *line_ptr)
02206 {
02207   /* Run down the file looking for the filename, function and linenumber.  */
02208   asymbol **p;
02209   const char *directory_name = NULL;
02210   const char *main_file_name = NULL;
02211   const char *current_file_name = NULL;
02212   const char *line_file_name = NULL; /* Value of current_file_name at line number.  */
02213   bfd_vma low_line_vma = 0;
02214   bfd_vma low_func_vma = 0;
02215   asymbol *func = 0;
02216   size_t filelen, funclen;
02217   char *buf;
02218 
02219   *filename_ptr = abfd->filename;
02220   *functionname_ptr = 0;
02221   *line_ptr = 0;
02222 
02223   if (symbols != NULL)
02224     {
02225       for (p = symbols; *p; p++)
02226        {
02227          aout_symbol_type  *q = (aout_symbol_type *)(*p);
02228        next:
02229          switch (q->type)
02230            {
02231            case N_TEXT:
02232              /* If this looks like a file name symbol, and it comes after
02233                the line number we have found so far, but before the
02234                offset, then we have probably not found the right line
02235                number.  */
02236              if (q->symbol.value <= offset
02237                 && ((q->symbol.value > low_line_vma
02238                      && (line_file_name != NULL
02239                         || *line_ptr != 0))
02240                     || (q->symbol.value > low_func_vma
02241                        && func != NULL)))
02242               {
02243                 const char * symname;
02244 
02245                 symname = q->symbol.name;
02246                 if (strcmp (symname + strlen (symname) - 2, ".o") == 0)
02247                   {
02248                     if (q->symbol.value > low_line_vma)
02249                      {
02250                        *line_ptr = 0;
02251                        line_file_name = NULL;
02252                      }
02253                     if (q->symbol.value > low_func_vma)
02254                      func = NULL;
02255                   }
02256               }
02257              break;
02258 
02259            case N_SO:
02260              /* If this symbol is less than the offset, but greater than
02261                the line number we have found so far, then we have not
02262                found the right line number.  */
02263              if (q->symbol.value <= offset)
02264               {
02265                 if (q->symbol.value > low_line_vma)
02266                   {
02267                     *line_ptr = 0;
02268                     line_file_name = NULL;
02269                   }
02270                 if (q->symbol.value > low_func_vma)
02271                   func = NULL;
02272               }
02273 
02274              main_file_name = current_file_name = q->symbol.name;
02275              /* Look ahead to next symbol to check if that too is an N_SO.  */
02276              p++;
02277              if (*p == NULL)
02278               break;
02279              q = (aout_symbol_type *)(*p);
02280              if (q->type != (int) N_SO)
02281               goto next;
02282 
02283              /* Found a second N_SO  First is directory; second is filename.  */
02284              directory_name = current_file_name;
02285              main_file_name = current_file_name = q->symbol.name;
02286              if (obj_textsec(abfd) != section)
02287               goto done;
02288              break;
02289            case N_SOL:
02290              current_file_name = q->symbol.name;
02291              break;
02292 
02293            case N_SLINE:
02294            case N_DSLINE:
02295            case N_BSLINE:
02296              /* We'll keep this if it resolves nearer than the one we have
02297                already.  */
02298              if (q->symbol.value >= low_line_vma
02299                 && q->symbol.value <= offset)
02300               {
02301                 *line_ptr = q->desc;
02302                 low_line_vma = q->symbol.value;
02303                 line_file_name = current_file_name;
02304               }
02305              break;
02306 
02307            case N_FUN:
02308              {
02309               /* We'll keep this if it is nearer than the one we have already.  */
02310               if (q->symbol.value >= low_func_vma &&
02311                   q->symbol.value <= offset)
02312                 {
02313                   low_func_vma = q->symbol.value;
02314                   func = (asymbol *) q;
02315                 }
02316               else if (q->symbol.value > offset)
02317                 goto done;
02318              }
02319              break;
02320            }
02321        }
02322     }
02323 
02324  done:
02325   if (*line_ptr != 0)
02326     main_file_name = line_file_name;
02327 
02328   if (main_file_name == NULL
02329       || main_file_name[0] == '/'
02330       || directory_name == NULL)
02331     filelen = 0;
02332   else
02333     filelen = strlen (directory_name) + strlen (main_file_name);
02334   if (func == NULL)
02335     funclen = 0;
02336   else
02337     funclen = strlen (bfd_asymbol_name (func));
02338 
02339   if (adata (abfd).line_buf != NULL)
02340     free (adata (abfd).line_buf);
02341   if (filelen + funclen == 0)
02342     adata (abfd).line_buf = buf = NULL;
02343   else
02344     {
02345       buf = bfd_malloc ((bfd_size_type) filelen + funclen + 3);
02346       adata (abfd).line_buf = buf;
02347       if (buf == NULL)
02348        return FALSE;
02349     }
02350 
02351   if (main_file_name != NULL)
02352     {
02353       if (main_file_name[0] == '/' || directory_name == NULL)
02354        *filename_ptr = main_file_name;
02355       else
02356        {
02357          sprintf (buf, "%s%s", directory_name, main_file_name);
02358          *filename_ptr = buf;
02359          buf += filelen + 1;
02360        }
02361     }
02362 
02363   if (func)
02364     {
02365       const char *function = func->name;
02366       char *colon;
02367 
02368       /* The caller expects a symbol name.  We actually have a
02369         function name, without the leading underscore.  Put the
02370         underscore back in, so that the caller gets a symbol name.  */
02371       if (bfd_get_symbol_leading_char (abfd) == '\0')
02372        strcpy (buf, function);
02373       else
02374        {
02375          buf[0] = bfd_get_symbol_leading_char (abfd);
02376          strcpy (buf + 1, function);
02377        }
02378 
02379       /* Have to remove : stuff.  */
02380       colon = strchr (buf, ':');
02381       if (colon != NULL)
02382        *colon = '\0';
02383       *functionname_ptr = buf;
02384     }
02385 
02386   return TRUE;
02387 }
02388 
02389 int
02390 NAME (aout, sizeof_headers) (bfd *abfd,
02391                           struct bfd_link_info *info ATTRIBUTE_UNUSED)
02392 {
02393   return adata (abfd).exec_bytes_size;
02394 }
02395 
02396 /* Free all information we have cached for this BFD.  We can always
02397    read it again later if we need it.  */
02398 
02399 bfd_boolean
02400 NAME (aout, bfd_free_cached_info) (bfd *abfd)
02401 {
02402   asection *o;
02403 
02404   if (bfd_get_format (abfd) != bfd_object)
02405     return TRUE;
02406 
02407 #define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
02408   BFCI_FREE (obj_aout_symbols (abfd));
02409 
02410 #ifdef USE_MMAP
02411   obj_aout_external_syms (abfd) = 0;
02412   bfd_free_window (&obj_aout_sym_window (abfd));
02413   bfd_free_window (&obj_aout_string_window (abfd));
02414   obj_aout_external_strings (abfd) = 0;
02415 #else
02416   BFCI_FREE (obj_aout_external_syms (abfd));
02417   BFCI_FREE (obj_aout_external_strings (abfd));
02418 #endif
02419   for (o = abfd->sections; o != NULL; o = o->next)
02420     BFCI_FREE (o->relocation);
02421 #undef BFCI_FREE
02422 
02423   return TRUE;
02424 }
02425 
02426 /* Routine to create an entry in an a.out link hash table.  */
02427 
02428 struct bfd_hash_entry *
02429 NAME (aout, link_hash_newfunc) (struct bfd_hash_entry *entry,
02430                             struct bfd_hash_table *table,
02431                             const char *string)
02432 {
02433   struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
02434 
02435   /* Allocate the structure if it has not already been allocated by a
02436      subclass.  */
02437   if (ret == NULL)
02438     ret = bfd_hash_allocate (table, sizeof (* ret));
02439   if (ret == NULL)
02440     return NULL;
02441 
02442   /* Call the allocation method of the superclass.  */
02443   ret = (struct aout_link_hash_entry *)
02444         _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string);
02445   if (ret)
02446     {
02447       /* Set local fields.  */
02448       ret->written = FALSE;
02449       ret->indx = -1;
02450     }
02451 
02452   return (struct bfd_hash_entry *) ret;
02453 }
02454 
02455 /* Initialize an a.out link hash table.  */
02456 
02457 bfd_boolean
02458 NAME (aout, link_hash_table_init) (struct aout_link_hash_table *table,
02459                                bfd *abfd,
02460                                struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
02461                                                              struct bfd_hash_table *,
02462                                                              const char *),
02463                                unsigned int entsize)
02464 {
02465   return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
02466 }
02467 
02468 /* Create an a.out link hash table.  */
02469 
02470 struct bfd_link_hash_table *
02471 NAME (aout, link_hash_table_create) (bfd *abfd)
02472 {
02473   struct aout_link_hash_table *ret;
02474   bfd_size_type amt = sizeof (struct aout_link_hash_table);
02475 
02476   ret = bfd_alloc (abfd, amt);
02477   if (ret == NULL)
02478     return NULL;
02479   if (! NAME (aout, link_hash_table_init) (ret, abfd,
02480                                       NAME (aout, link_hash_newfunc),
02481                                       sizeof (struct aout_link_hash_entry)))
02482     {
02483       free (ret);
02484       return NULL;
02485     }
02486   return &ret->root;
02487 }
02488 
02489 /* Free up the internal symbols read from an a.out file.  */
02490 
02491 static bfd_boolean
02492 aout_link_free_symbols (bfd *abfd)
02493 {
02494   if (obj_aout_external_syms (abfd) != NULL)
02495     {
02496 #ifdef USE_MMAP
02497       bfd_free_window (&obj_aout_sym_window (abfd));
02498 #else
02499       free ((void *) obj_aout_external_syms (abfd));
02500 #endif
02501       obj_aout_external_syms (abfd) = NULL;
02502     }
02503 
02504   if (obj_aout_external_strings (abfd) != NULL)
02505     {
02506 #ifdef USE_MMAP
02507       bfd_free_window (&obj_aout_string_window (abfd));
02508 #else
02509       free ((void *) obj_aout_external_strings (abfd));
02510 #endif
02511       obj_aout_external_strings (abfd) = NULL;
02512     }
02513   return TRUE;
02514 }
02515 
02516 /* Given an a.out BFD, add symbols to the global hash table as
02517    appropriate.  */
02518 
02519 bfd_boolean
02520 NAME (aout, link_add_symbols) (bfd *abfd, struct bfd_link_info *info)
02521 {
02522   switch (bfd_get_format (abfd))
02523     {
02524     case bfd_object:
02525       return aout_link_add_object_symbols (abfd, info);
02526     case bfd_archive:
02527       return _bfd_generic_link_add_archive_symbols
02528        (abfd, info, aout_link_check_archive_element);
02529     default:
02530       bfd_set_error (bfd_error_wrong_format);
02531       return FALSE;
02532     }
02533 }
02534 
02535 /* Add symbols from an a.out object file.  */
02536 
02537 static bfd_boolean
02538 aout_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
02539 {
02540   if (! aout_get_external_symbols (abfd))
02541     return FALSE;
02542   if (! aout_link_add_symbols (abfd, info))
02543     return FALSE;
02544   if (! info->keep_memory)
02545     {
02546       if (! aout_link_free_symbols (abfd))
02547        return FALSE;
02548     }
02549   return TRUE;
02550 }
02551 
02552 /* Look through the internal symbols to see if this object file should
02553    be included in the link.  We should include this object file if it
02554    defines any symbols which are currently undefined.  If this object
02555    file defines a common symbol, then we may adjust the size of the
02556    known symbol but we do not include the object file in the link
02557    (unless there is some other reason to include it).  */
02558 
02559 static bfd_boolean
02560 aout_link_check_ar_symbols (bfd *abfd,
02561                          struct bfd_link_info *info,
02562                          bfd_boolean *pneeded)
02563 {
02564   struct external_nlist *p;
02565   struct external_nlist *pend;
02566   char *strings;
02567 
02568   *pneeded = FALSE;
02569 
02570   /* Look through all the symbols.  */
02571   p = obj_aout_external_syms (abfd);
02572   pend = p + obj_aout_external_sym_count (abfd);
02573   strings = obj_aout_external_strings (abfd);
02574   for (; p < pend; p++)
02575     {
02576       int type = H_GET_8 (abfd, p->e_type);
02577       const char *name;
02578       struct bfd_link_hash_entry *h;
02579 
02580       /* Ignore symbols that are not externally visible.  This is an
02581         optimization only, as we check the type more thoroughly
02582         below.  */
02583       if ((type & N_EXT) == 0
02584          || type == N_FN)
02585        continue;
02586 
02587       name = strings + GET_WORD (abfd, p->e_strx);
02588       h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
02589 
02590       /* We are only interested in symbols that are currently
02591         undefined or common.  */
02592       if (h == NULL
02593          || (h->type != bfd_link_hash_undefined
02594              && h->type != bfd_link_hash_common))
02595        continue;
02596 
02597       if (type == (N_TEXT | N_EXT)
02598          || type == (N_DATA | N_EXT)
02599          || type == (N_BSS | N_EXT)
02600          || type == (N_ABS | N_EXT))
02601        {
02602          /* This object file defines this symbol.  We must link it
02603             in.  This is true regardless of whether the current
02604             definition of the symbol is undefined or common.  If the
02605             current definition is common, we have a case in which we
02606             have already seen an object file including
02607                 int a;
02608             and this object file from the archive includes
02609                 int a = 5;
02610             In such a case we must include this object file.
02611 
02612             FIXME: The SunOS 4.1.3 linker will pull in the archive
02613             element if the symbol is defined in the .data section,
02614             but not if it is defined in the .text section.  That
02615             seems a bit crazy to me, and I haven't implemented it.
02616             However, it might be correct.  */
02617          if (! (*info->callbacks->add_archive_element) (info, abfd, name))
02618            return FALSE;
02619          *pneeded = TRUE;
02620          return TRUE;
02621        }
02622 
02623       if (type == (N_UNDF | N_EXT))
02624        {
02625          bfd_vma value;
02626 
02627          value = GET_WORD (abfd, p->e_value);
02628          if (value != 0)
02629            {
02630              /* This symbol is common in the object from the archive
02631                file.  */
02632              if (h->type == bfd_link_hash_undefined)
02633               {
02634                 bfd *symbfd;
02635                 unsigned int power;
02636 
02637                 symbfd = h->u.undef.abfd;
02638                 if (symbfd == NULL)
02639                   {
02640                     /* This symbol was created as undefined from
02641                       outside BFD.  We assume that we should link
02642                       in the object file.  This is done for the -u
02643                       option in the linker.  */
02644                     if (! (*info->callbacks->add_archive_element)
02645                        (info, abfd, name))
02646                      return FALSE;
02647                     *pneeded = TRUE;
02648                     return TRUE;
02649                   }
02650                 /* Turn the current link symbol into a common
02651                    symbol.  It is already on the undefs list.  */
02652                 h->type = bfd_link_hash_common;
02653                 h->u.c.p = bfd_hash_allocate (&info->hash->table,
02654                                           sizeof (struct bfd_link_hash_common_entry));
02655                 if (h->u.c.p == NULL)
02656                   return FALSE;
02657 
02658                 h->u.c.size = value;
02659 
02660                 /* FIXME: This isn't quite right.  The maximum
02661                    alignment of a common symbol should be set by the
02662                    architecture of the output file, not of the input
02663                    file.  */
02664                 power = bfd_log2 (value);
02665                 if (power > bfd_get_arch_info (abfd)->section_align_power)
02666                   power = bfd_get_arch_info (abfd)->section_align_power;
02667                 h->u.c.p->alignment_power = power;
02668 
02669                 h->u.c.p->section = bfd_make_section_old_way (symbfd,
02670                                                         "COMMON");
02671               }
02672              else
02673               {
02674                 /* Adjust the size of the common symbol if
02675                    necessary.  */
02676                 if (value > h->u.c.size)
02677                   h->u.c.size = value;
02678               }
02679            }
02680        }
02681     }
02682 
02683   /* We do not need this object file.  */
02684   return TRUE;
02685 }
02686 
02687 /* Check a single archive element to see if we need to include it in
02688    the link.  *PNEEDED is set according to whether this element is
02689    needed in the link or not.  This is called from
02690    _bfd_generic_link_add_archive_symbols.  */
02691 
02692 static bfd_boolean
02693 aout_link_check_archive_element (bfd *abfd,
02694                              struct bfd_link_info *info,
02695                              bfd_boolean *pneeded)
02696 {
02697   if (! aout_get_external_symbols (abfd))
02698     return FALSE;
02699 
02700   if (! aout_link_check_ar_symbols (abfd, info, pneeded))
02701     return FALSE;
02702 
02703   if (*pneeded)
02704     {
02705       if (! aout_link_add_symbols (abfd, info))
02706        return FALSE;
02707     }
02708 
02709   if (! info->keep_memory || ! *pneeded)
02710     {
02711       if (! aout_link_free_symbols (abfd))
02712        return FALSE;
02713     }
02714 
02715   return TRUE;
02716 }
02717 
02718 /* Add all symbols from an object file to the hash table.  */
02719 
02720 static bfd_boolean
02721 aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
02722 {
02723   bfd_boolean (*add_one_symbol)
02724     (struct bfd_link_info *, bfd *, const char *, flagword, asection *,
02725      bfd_vma, const char *, bfd_boolean, bfd_boolean,
02726      struct bfd_link_hash_entry **);
02727   struct external_nlist *syms;
02728   bfd_size_type sym_count;
02729   char *strings;
02730   bfd_boolean copy;
02731   struct aout_link_hash_entry **sym_hash;
02732   struct external_nlist *p;
02733   struct external_nlist *pend;
02734 
02735   syms = obj_aout_external_syms (abfd);
02736   sym_count = obj_aout_external_sym_count (abfd);
02737   strings = obj_aout_external_strings (abfd);
02738   if (info->keep_memory)
02739     copy = FALSE;
02740   else
02741     copy = TRUE;
02742 
02743   if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
02744     {
02745       if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
02746             (abfd, info, &syms, &sym_count, &strings)))
02747        return FALSE;
02748     }
02749 
02750   /* We keep a list of the linker hash table entries that correspond
02751      to particular symbols.  We could just look them up in the hash
02752      table, but keeping the list is more efficient.  Perhaps this
02753      should be conditional on info->keep_memory.  */
02754   sym_hash = bfd_alloc (abfd,
02755                      sym_count * sizeof (struct aout_link_hash_entry *));
02756   if (sym_hash == NULL && sym_count != 0)
02757     return FALSE;
02758   obj_aout_sym_hashes (abfd) = sym_hash;
02759 
02760   add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
02761   if (add_one_symbol == NULL)
02762     add_one_symbol = _bfd_generic_link_add_one_symbol;
02763 
02764   p = syms;
02765   pend = p + sym_count;
02766   for (; p < pend; p++, sym_hash++)
02767     {
02768       int type;
02769       const char *name;
02770       bfd_vma value;
02771       asection *section;
02772       flagword flags;
02773       const char *string;
02774 
02775       *sym_hash = NULL;
02776 
02777       type = H_GET_8 (abfd, p->e_type);
02778 
02779       name = strings + GET_WORD (abfd, p->e_strx);
02780       value = GET_WORD (abfd, p->e_value);
02781       flags = BSF_GLOBAL;
02782       string = NULL;
02783       switch (type)
02784        {
02785        default:
02786          abort ();
02787 
02788        case N_UNDF:
02789        case N_ABS:
02790        case N_TEXT:
02791        case N_DATA:
02792        case N_BSS:
02793        case N_REG:
02794        case N_FN:
02795          /* Ignore symbols that are not externally visible.  */
02796          continue;
02797 
02798        case N_UNDF | N_EXT:
02799          if (value == 0)
02800            {
02801              section = bfd_und_section_ptr;
02802              flags = 0;
02803            }
02804          else
02805            section = bfd_com_section_ptr;
02806          break;
02807        case N_ABS | N_EXT:
02808          section = bfd_abs_section_ptr;
02809          break;
02810        case N_TEXT | N_EXT:
02811          section = obj_textsec (abfd);
02812          value -= bfd_get_section_vma (abfd, section);
02813          break;
02814        case N_DATA | N_EXT:
02815          /* Treat N_SETV symbols as N_DATA symbol; see comment in
02816             translate_from_native_sym_flags.  */
02817          section = obj_datasec (abfd);
02818          value -= bfd_get_section_vma (abfd, section);
02819          break;
02820        case N_BSS | N_EXT:
02821          section = obj_bsssec (abfd);
02822          value -= bfd_get_section_vma (abfd, section);
02823          break;
02824        }
02825 
02826       if (! ((*add_one_symbol)
02827             (info, abfd, name, flags, section, value, string, copy, FALSE,
02828              (struct bfd_link_hash_entry **) sym_hash)))
02829        return FALSE;
02830 
02831       /* Restrict the maximum alignment of a common symbol based on
02832         the architecture, since a.out has no way to represent
02833         alignment requirements of a section in a .o file.  FIXME:
02834         This isn't quite right: it should use the architecture of the
02835         output file, not the input files.  */
02836       if ((*sym_hash)->root.type == bfd_link_hash_common
02837          && ((*sym_hash)->root.u.c.p->alignment_power >
02838              bfd_get_arch_info (abfd)->section_align_power))
02839        (*sym_hash)->root.u.c.p->alignment_power =
02840          bfd_get_arch_info (abfd)->section_align_power;
02841 
02842       /* If this is a set symbol, and we are not building sets, then
02843         it is possible for the hash entry to not have been set.  In
02844         such a case, treat the symbol as not globally defined.  */
02845       if ((*sym_hash)->root.type == bfd_link_hash_new)
02846        {
02847          BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
02848          *sym_hash = NULL;
02849        }
02850     }
02851 
02852   return TRUE;
02853 }
02854 
02855 /* Look up an entry in an the header file hash table.  */
02856 
02857 #define aout_link_includes_lookup(table, string, create, copy) \
02858   ((struct aout_link_includes_entry *) \
02859    bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
02860 
02861 /* The function to create a new entry in the header file hash table.  */
02862 
02863 static struct bfd_hash_entry *
02864 aout_link_includes_newfunc (struct bfd_hash_entry *entry,
02865                          struct bfd_hash_table *table,
02866                          const char *string)
02867 {
02868   struct aout_link_includes_entry * ret =
02869     (struct aout_link_includes_entry *) entry;
02870 
02871   /* Allocate the structure if it has not already been allocated by a
02872      subclass.  */
02873   if (ret == NULL)
02874     ret = bfd_hash_allocate (table,
02875                           sizeof (struct aout_link_includes_entry));
02876   if (ret == NULL)
02877     return NULL;
02878 
02879   /* Call the allocation method of the superclass.  */
02880   ret = ((struct aout_link_includes_entry *)
02881         bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
02882   if (ret)
02883     /* Set local fields.  */
02884     ret->totals = NULL;
02885 
02886   return (struct bfd_hash_entry *) ret;
02887 }
02888 
02889 static bfd_boolean
02890 aout_link_write_other_symbol (struct aout_link_hash_entry *h, void * data)
02891 {
02892   struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
02893   bfd *output_bfd;
02894   int type;
02895   bfd_vma val;
02896   struct external_nlist outsym;
02897   bfd_size_type indx;
02898   bfd_size_type amt;
02899 
02900   if (h->root.type == bfd_link_hash_warning)
02901     {
02902       h = (struct aout_link_hash_entry *) h->root.u.i.link;
02903       if (h->root.type == bfd_link_hash_new)
02904        return TRUE;
02905     }
02906 
02907   output_bfd = finfo->output_bfd;
02908 
02909   if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
02910     {
02911       if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
02912             (output_bfd, finfo->info, h)))
02913        {
02914          /* FIXME: No way to handle errors.  */
02915          abort ();
02916        }
02917     }
02918 
02919   if (h->written)
02920     return TRUE;
02921 
02922   h->written = TRUE;
02923 
02924   /* An indx of -2 means the symbol must be written.  */
02925   if (h->indx != -2
02926       && (finfo->info->strip == strip_all
02927          || (finfo->info->strip == strip_some
02928              && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
02929                               FALSE, FALSE) == NULL)))
02930     return TRUE;
02931 
02932   switch (h->root.type)
02933     {
02934     default:
02935       abort ();
02936       /* Avoid variable not initialized warnings.  */
02937       return TRUE;
02938     case bfd_link_hash_new:
02939       /* This can happen for set symbols when sets are not being
02940          built.  */
02941       return TRUE;
02942     case bfd_link_hash_undefined:
02943       type = N_UNDF | N_EXT;
02944       val = 0;
02945       break;
02946     case bfd_link_hash_defined:
02947     case bfd_link_hash_defweak:
02948       {
02949        asection *sec;
02950 
02951        sec = h->root.u.def.section->output_section;
02952        BFD_ASSERT (bfd_is_abs_section (sec)
02953                   || sec->owner == output_bfd);
02954        if (sec == obj_textsec (output_bfd))
02955          type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
02956        else if (sec == obj_datasec (output_bfd))
02957          type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
02958        else if (sec == obj_bsssec (output_bfd))
02959          type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
02960        else
02961          type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
02962        type |= N_EXT;
02963        val = (h->root.u.def.value
02964               + sec->vma
02965               + h->root.u.def.section->output_offset);
02966       }
02967       break;
02968     case bfd_link_hash_common:
02969       type = N_UNDF | N_EXT;
02970       val = h->root.u.c.size;
02971       break;
02972     case bfd_link_hash_undefweak:
02973       type = N_WEAKU;
02974       val = 0;
02975     case bfd_link_hash_indirect:
02976     case bfd_link_hash_warning:
02977       /* FIXME: Ignore these for now.  The circumstances under which
02978         they should be written out are not clear to me.  */
02979       return TRUE;
02980     }
02981 
02982   H_PUT_8 (output_bfd, type, outsym.e_type);
02983   indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
02984                         FALSE);
02985   if (indx == (bfd_size_type) -1)
02986     /* FIXME: No way to handle errors.  */
02987     abort ();
02988 
02989   PUT_WORD (output_bfd, indx, outsym.e_strx);
02990   PUT_WORD (output_bfd, val, outsym.e_value);
02991 
02992   amt = EXTERNAL_NLIST_SIZE;
02993   if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
02994       || bfd_bwrite ((void *) &outsym, amt, output_bfd) != amt)
02995     /* FIXME: No way to handle errors.  */
02996     abort ();
02997 
02998   finfo->symoff += amt;
02999   h->indx = obj_aout_external_sym_count (output_bfd);
03000   ++obj_aout_external_sym_count (output_bfd);
03001 
03002   return TRUE;
03003 }
03004 
03005 /* Handle a link order which is supposed to generate a reloc.  */
03006 
03007 static bfd_boolean
03008 aout_link_reloc_link_order (struct aout_final_link_info *finfo,
03009                          asection *o,
03010                          struct bfd_link_order *p)
03011 {
03012   struct bfd_link_order_reloc *pr;
03013   int r_index;
03014   int r_extern;
03015   reloc_howto_type *howto;
03016   file_ptr *reloff_ptr;
03017   struct reloc_std_external srel;
03018   void * rel_ptr;
03019   bfd_size_type rel_size;
03020 
03021   pr = p->u.reloc.p;
03022 
03023   if (p->type == bfd_section_reloc_link_order)
03024     {
03025       r_extern = 0;
03026       if (bfd_is_abs_section (pr->u.section))
03027        r_index = N_ABS | N_EXT;
03028       else
03029        {
03030          BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
03031          r_index = pr->u.section->target_index;
03032        }
03033     }
03034   else
03035     {
03036       struct aout_link_hash_entry *h;
03037 
03038       BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
03039       r_extern = 1;
03040       h = ((struct aout_link_hash_entry *)
03041           bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
03042                                     pr->u.name, FALSE, FALSE, TRUE));
03043       if (h != NULL
03044          && h->indx >= 0)
03045        r_index = h->indx;
03046       else if (h != NULL)
03047        {
03048          /* We decided to strip this symbol, but it turns out that we
03049             can't.  Note that we lose the other and desc information
03050             here.  I don't think that will ever matter for a global
03051             symbol.  */
03052          h->indx = -2;
03053          h->written = FALSE;
03054          if (! aout_link_write_other_symbol (h, (void *) finfo))
03055            return FALSE;
03056          r_index = h->indx;
03057        }
03058       else
03059        {
03060          if (! ((*finfo->info->callbacks->unattached_reloc)
03061                (finfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0)))
03062            return FALSE;
03063          r_index = 0;
03064        }
03065     }
03066 
03067   howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
03068   if (howto == 0)
03069     {
03070       bfd_set_error (bfd_error_bad_value);
03071       return FALSE;
03072     }
03073 
03074   if (o == obj_textsec (finfo->output_bfd))
03075     reloff_ptr = &finfo->treloff;
03076   else if (o == obj_datasec (finfo->output_bfd))
03077     reloff_ptr = &finfo->dreloff;
03078   else
03079     abort ();
03080 
03081 #ifdef MY_put_reloc
03082   MY_put_reloc(finfo->output_bfd, r_extern, r_index, p->offset, howto,
03083               &srel);
03084 #else
03085   {
03086     int r_pcrel;
03087     int r_baserel;
03088     int r_jmptable;
03089     int r_relative;
03090     int r_length;
03091 
03092     fprintf (stderr, "TODO: line %d in bfd/pdp11.c\n", __LINE__);
03093 
03094     r_pcrel = howto->pc_relative;
03095     r_baserel = (howto->type & 8) != 0;
03096     r_jmptable = (howto->type & 16) != 0;
03097     r_relative = (howto->type & 32) != 0;
03098     r_length = howto->size;
03099 
03100     PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
03101     if (bfd_header_big_endian (finfo->output_bfd))
03102       {
03103        srel.r_index[0] = r_index >> 16;
03104        srel.r_index[1] = r_index >> 8;
03105        srel.r_index[2] = r_index;
03106        srel.r_type[0] =
03107          ((r_extern ?     RELOC_STD_BITS_EXTERN_BIG : 0)
03108           | (r_pcrel ?    RELOC_STD_BITS_PCREL_BIG : 0)
03109           | (r_baserel ?  RELOC_STD_BITS_BASEREL_BIG : 0)
03110           | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
03111           | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
03112           | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
03113       }
03114     else
03115       {
03116        srel.r_index[2] = r_index >> 16;
03117        srel.r_index[1] = r_index >> 8;
03118        srel.r_index[0] = r_index;
03119        srel.r_type[0] =
03120          ((r_extern ?     RELOC_STD_BITS_EXTERN_LITTLE : 0)
03121           | (r_pcrel ?    RELOC_STD_BITS_PCREL_LITTLE : 0)
03122           | (r_baserel ?  RELOC_STD_BITS_BASEREL_LITTLE : 0)
03123           | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
03124           | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
03125           | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
03126       }
03127   }
03128 #endif
03129   rel_ptr = (void *) &srel;
03130 
03131   /* We have to write the addend into the object file, since
03132      standard a.out relocs are in place.  It would be more
03133      reliable if we had the current contents of the file here,
03134      rather than assuming zeroes, but we can't read the file since
03135      it was opened using bfd_openw.  */
03136   if (pr->addend != 0)
03137     {
03138       bfd_size_type size;
03139       bfd_reloc_status_type r;
03140       bfd_byte *buf;
03141       bfd_boolean ok;
03142 
03143       size = bfd_get_reloc_size (howto);
03144       buf = bfd_zmalloc (size);
03145       if (buf == NULL)
03146        return FALSE;
03147       r = MY_relocate_contents (howto, finfo->output_bfd,
03148                             pr->addend, buf);
03149       switch (r)
03150        {
03151        case bfd_reloc_ok:
03152          break;
03153        default:
03154        case bfd_reloc_outofrange:
03155          abort ();
03156        case bfd_reloc_overflow:
03157          if (! ((*finfo->info->callbacks->reloc_overflow)
03158                (finfo->info, NULL,
03159                 (p->type == bfd_section_reloc_link_order
03160                  ? bfd_section_name (finfo->output_bfd,
03161                                    pr->u.section)
03162                  : pr->u.name),
03163                 howto->name, pr->addend, NULL,
03164                 (asection *) NULL, (bfd_vma) 0)))
03165            {
03166              free (buf);
03167              return FALSE;
03168            }
03169          break;
03170        }
03171       ok = bfd_set_section_contents (finfo->output_bfd, o,
03172                                  (void *) buf,
03173                                  (file_ptr) p->offset,
03174                                  size);
03175       free (buf);
03176       if (! ok)
03177        return FALSE;
03178     }
03179 
03180   rel_size = obj_reloc_entry_size (finfo->output_bfd);
03181   if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
03182       || bfd_bwrite (rel_ptr, rel_size, finfo->output_bfd) != rel_size)
03183     return FALSE;
03184 
03185   *reloff_ptr += rel_size;
03186 
03187   /* Assert that the relocs have not run into the symbols, and that n
03188      the text relocs have not run into the data relocs.  */
03189   BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
03190              && (reloff_ptr != &finfo->treloff
03191                 || (*reloff_ptr
03192                     <= obj_datasec (finfo->output_bfd)->rel_filepos)));
03193 
03194   return TRUE;
03195 }
03196 
03197 /* Get the section corresponding to a reloc index.  */
03198 
03199 static inline asection *
03200 aout_reloc_type_to_section (bfd *abfd, int type)
03201 {
03202   switch (type)
03203     {
03204     case RTEXT:      return obj_textsec (abfd);
03205     case RDATA: return obj_datasec (abfd);
03206     case RBSS:  return obj_bsssec (abfd);
03207     case RABS:  return bfd_abs_section_ptr;
03208     case REXT:  return bfd_und_section_ptr;
03209     default:    abort ();
03210     }
03211 }
03212 
03213 static bfd_boolean
03214 pdp11_aout_link_input_section (struct aout_final_link_info *finfo,
03215                             bfd *input_bfd,
03216                             asection *input_section,
03217                             bfd_byte *relocs,
03218                             bfd_size_type rel_size,
03219                             bfd_byte *contents)
03220 {
03221   bfd_boolean (*check_dynamic_reloc)
03222     (struct bfd_link_info *, bfd *, asection *,
03223      struct aout_link_hash_entry *, void *, bfd_byte *, bfd_boolean *,
03224      bfd_vma *);
03225   bfd *output_bfd;
03226   bfd_boolean relocatable;
03227   struct external_nlist *syms;
03228   char *strings;
03229   struct aout_link_hash_entry **sym_hashes;
03230   int *symbol_map;
03231   bfd_size_type reloc_count;
03232   bfd_byte *rel;
03233   bfd_byte *rel_end;
03234 
03235   output_bfd = finfo->output_bfd;
03236   check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
03237 
03238   BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_SIZE);
03239   BFD_ASSERT (input_bfd->xvec->header_byteorder
03240              == output_bfd->xvec->header_byteorder);
03241 
03242   relocatable = finfo->info->relocatable;
03243   syms = obj_aout_external_syms (input_bfd);
03244   strings = obj_aout_external_strings (input_bfd);
03245   sym_hashes = obj_aout_sym_hashes (input_bfd);
03246   symbol_map = finfo->symbol_map;
03247 
03248   reloc_count = rel_size / RELOC_SIZE;
03249   rel = relocs;
03250   rel_end = rel + rel_size;
03251   for (; rel < rel_end; rel += RELOC_SIZE)
03252     {
03253       bfd_vma r_addr;
03254       int r_index;
03255       int r_type;
03256       int r_pcrel;
03257       int r_extern;
03258       reloc_howto_type *howto;
03259       struct aout_link_hash_entry *h = NULL;
03260       bfd_vma relocation;
03261       bfd_reloc_status_type r;
03262       int reloc_entry;
03263 
03264       reloc_entry = GET_WORD (input_bfd, (void *) rel);
03265       if (reloc_entry == 0)
03266        continue;
03267 
03268       {
03269        unsigned int howto_idx;
03270 
03271        r_index = (reloc_entry & RIDXMASK) >> 4;
03272        r_type = reloc_entry & RTYPE;
03273        r_pcrel = reloc_entry & RELFLG;
03274        r_addr = (char *) rel - (char *) relocs;
03275 
03276        r_extern = (r_type == REXT);
03277 
03278        howto_idx = r_pcrel;
03279        BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_pdp11));
03280        howto = howto_table_pdp11 + howto_idx;
03281       }
03282 
03283       if (relocatable)
03284        {
03285          /* We are generating a relocatable output file, and must
03286             modify the reloc accordingly.  */
03287          if (r_extern)
03288            {
03289              /* If we know the symbol this relocation is against,
03290                convert it into a relocation against a section.  This
03291                is what the native linker does.  */
03292              h = sym_hashes[r_index];
03293              if (h != NULL
03294                 && (h->root.type == bfd_link_hash_defined
03295                     || h->root.type == bfd_link_hash_defweak))
03296               {
03297                 asection *output_section;
03298 
03299                 /* Compute a new r_index.  */
03300                 output_section = h->root.u.def.section->output_section;
03301                 if (output_section == obj_textsec (output_bfd))
03302                   r_type = N_TEXT;
03303                 else if (output_section == obj_datasec (output_bfd))
03304                   r_type = N_DATA;
03305                 else if (output_section == obj_bsssec (output_bfd))
03306                   r_type = N_BSS;
03307                 else
03308                   r_type = N_ABS;
03309 
03310                 /* Add the symbol value and the section VMA to the
03311                    addend stored in the contents.  */
03312                 relocation = (h->root.u.def.value
03313                             + output_section->vma
03314                             + h->root.u.def.section->output_offset);
03315               }
03316              else
03317               {
03318                 /* We must change r_index according to the symbol
03319                    map.  */
03320                 r_index = symbol_map[r_index];
03321 
03322                 if (r_index == -1)
03323                   {
03324                     if (h != NULL)
03325                      {
03326                        /* We decided to strip this symbol, but it
03327                              turns out that we can't.  Note that we
03328                              lose the other and desc information here.
03329                              I don't think that will ever matter for a
03330                              global symbol.  */
03331                        if (h->indx < 0)
03332                          {
03333                            h->indx = -2;
03334                            h->written = FALSE;
03335                            if (! aout_link_write_other_symbol (h,
03336                                                           (void *) finfo))
03337                             return FALSE;
03338                          }
03339                        r_index = h->indx;
03340                      }
03341                     else
03342                      {
03343                        const char *name;
03344 
03345                        name = strings + GET_WORD (input_bfd,
03346                                                syms[r_index].e_strx);
03347                        if (! ((*finfo->info->callbacks->unattached_reloc)
03348                              (finfo->info, name, input_bfd, input_section,
03349                               r_addr)))
03350                          return FALSE;
03351                        r_index = 0;
03352                      }
03353                   }
03354 
03355                 relocation = 0;
03356               }
03357 
03358              /* Write out the new r_index value.  */
03359              reloc_entry = GET_WORD (input_bfd, rel);
03360              reloc_entry &= RIDXMASK;
03361              reloc_entry |= r_index << 4;
03362              PUT_WORD (input_bfd, reloc_entry, rel);
03363            }
03364          else
03365            {
03366              asection *section;
03367 
03368              /* This is a relocation against a section.  We must
03369                adjust by the amount that the section moved.  */
03370              section = aout_reloc_type_to_section (input_bfd, r_type);
03371              relocation = (section->output_section->vma
03372                          + section->output_offset
03373                          - section->vma);
03374            }
03375 
03376          /* Change the address of the relocation.  */
03377          fprintf (stderr, "TODO: change the address of the relocation\n");
03378 
03379          /* Adjust a PC relative relocation by removing the reference
03380             to the original address in the section and including the
03381             reference to the new address.  */
03382          if (r_pcrel)
03383            relocation -= (input_section->output_section->vma
03384                         + input_section->output_offset
03385                         - input_section->vma);
03386 
03387 #ifdef MY_relocatable_reloc
03388          MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
03389 #endif
03390 
03391          if (relocation == 0)
03392            r = bfd_reloc_ok;
03393          else
03394            r = MY_relocate_contents (howto,
03395                                   input_bfd, relocation,
03396                                   contents + r_addr);
03397        }
03398       else
03399        {
03400          bfd_boolean hundef;
03401 
03402          /* We are generating an executable, and must do a full
03403             relocation.  */
03404          hundef = FALSE;
03405          if (r_extern)
03406            {
03407              h = sym_hashes[r_index];
03408 
03409              if (h != NULL
03410                 && (h->root.type == bfd_link_hash_defined
03411                     || h->root.type == bfd_link_hash_defweak))
03412               {
03413                 relocation = (h->root.u.def.value
03414                             + h->root.u.def.section->output_section->vma
03415                             + h->root.u.def.section->output_offset);
03416               }
03417              else if (h != NULL
03418                      && h->root.type == bfd_link_hash_undefweak)
03419               relocation = 0;
03420              else
03421               {
03422                 hundef = TRUE;
03423                 relocation = 0;
03424               }
03425            }
03426          else
03427            {
03428              asection *section;
03429 
03430              section = aout_reloc_type_to_section (input_bfd, r_type);
03431              relocation = (section->output_section->vma
03432                          + section->output_offset
03433                          - section->vma);
03434              if (r_pcrel)
03435               relocation += input_section->vma;
03436            }
03437 
03438          if (check_dynamic_reloc != NULL)
03439            {
03440              bfd_boolean skip;
03441 
03442              if (! ((*check_dynamic_reloc)
03443                    (finfo->info, input_bfd, input_section, h,
03444                     (void *) rel, contents, &skip, &relocation)))
03445               return FALSE;
03446              if (skip)
03447               continue;
03448            }
03449 
03450          /* Now warn if a global symbol is undefined.  We could not
03451              do this earlier, because check_dynamic_reloc might want
03452              to skip this reloc.  */
03453          if (hundef && ! finfo->info->shared)
03454            {
03455              const char *name;
03456 
03457              if (h != NULL)
03458               name = h->root.root.string;
03459              else
03460               name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
03461              if (! ((*finfo->info->callbacks->undefined_symbol)
03462                    (finfo->info, name, input_bfd, input_section,
03463                     r_addr, TRUE)))
03464               return FALSE;
03465            }
03466 
03467          r = MY_final_link_relocate (howto,
03468                                   input_bfd, input_section,
03469                                   contents, r_addr, relocation,
03470                                   (bfd_vma) 0);
03471        }
03472 
03473       if (r != bfd_reloc_ok)
03474        {
03475          switch (r)
03476            {
03477            default:
03478            case bfd_reloc_outofrange:
03479              abort ();
03480            case bfd_reloc_overflow:
03481              {
03482               const char *name;
03483 
03484               if (h != NULL)
03485                 name = NULL;
03486               else if (r_extern)
03487                 name = strings + GET_WORD (input_bfd,
03488                                         syms[r_index].e_strx);
03489               else
03490                 {
03491                   asection *s;
03492 
03493                   s = aout_reloc_type_to_section (input_bfd, r_type);
03494                   name = bfd_section_name (input_bfd, s);
03495                 }
03496               if (! ((*finfo->info->callbacks->reloc_overflow)
03497                      (finfo->info, (h ? &h->root : NULL), name,
03498                      howto->name, (bfd_vma) 0, input_bfd,
03499                      input_section, r_addr)))
03500                 return FALSE;
03501              }
03502              break;
03503            }
03504        }
03505     }
03506 
03507   return TRUE;
03508 }
03509 
03510 /* Link an a.out section into the output file.  */
03511 
03512 static bfd_boolean
03513 aout_link_input_section (struct aout_final_link_info *finfo,
03514                       bfd *input_bfd,
03515                       asection *input_section,
03516                       file_ptr *reloff_ptr,
03517                       bfd_size_type rel_size)
03518 {
03519   bfd_size_type input_size;
03520   void * relocs;
03521 
03522   /* Get the section contents.  */
03523   input_size = input_section->size;
03524   if (! bfd_get_section_contents (input_bfd, input_section,
03525                               (void *) finfo->contents,
03526                               (file_ptr) 0, input_size))
03527     return FALSE;
03528 
03529   /* Read in the relocs if we haven't already done it.  */
03530   if (aout_section_data (input_section) != NULL
03531       && aout_section_data (input_section)->relocs != NULL)
03532     relocs = aout_section_data (input_section)->relocs;
03533   else
03534     {
03535       relocs = finfo->relocs;
03536       if (rel_size > 0)
03537        {
03538          if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
03539              || bfd_bread (relocs, rel_size, input_bfd) != rel_size)
03540            return FALSE;
03541        }
03542     }
03543 
03544   /* Relocate the section contents.  */
03545   if (! pdp11_aout_link_input_section (finfo, input_bfd, input_section,
03546                                    (bfd_byte *) relocs,
03547                                    rel_size, finfo->contents))
03548     return FALSE;
03549 
03550   /* Write out the section contents.  */
03551   if (! bfd_set_section_contents (finfo->output_bfd,
03552                               input_section->output_section,
03553                               (void *) finfo->contents,
03554                               (file_ptr) input_section->output_offset,
03555                               input_size))
03556     return FALSE;
03557 
03558   /* If we are producing relocatable output, the relocs were
03559      modified, and we now write them out.  */
03560   if (finfo->info->relocatable && rel_size > 0)
03561     {
03562       if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
03563        return FALSE;
03564       if (bfd_bwrite (relocs, rel_size, finfo->output_bfd) != rel_size)
03565        return FALSE;
03566       *reloff_ptr += rel_size;
03567 
03568       /* Assert that the relocs have not run into the symbols, and
03569         that if these are the text relocs they have not run into the
03570         data relocs.  */
03571       BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
03572                 && (reloff_ptr != &finfo->treloff
03573                     || (*reloff_ptr
03574                        <= obj_datasec (finfo->output_bfd)->rel_filepos)));
03575     }
03576 
03577   return TRUE;
03578 }
03579 
03580 /* Link an a.out input BFD into the output file.  */
03581 
03582 static bfd_boolean
03583 aout_link_input_bfd (struct aout_final_link_info *finfo, bfd *input_bfd)
03584 {
03585   bfd_size_type sym_count;
03586 
03587   BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
03588 
03589   /* If this is a dynamic object, it may need special handling.  */
03590   if ((input_bfd->flags & DYNAMIC) != 0
03591       && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
03592     return ((*aout_backend_info (input_bfd)->link_dynamic_object)
03593            (finfo->info, input_bfd));
03594 
03595   /* Get the symbols.  We probably have them already, unless
03596      finfo->info->keep_memory is FALSE.  */
03597   if (! aout_get_external_symbols (input_bfd))
03598     return FALSE;
03599 
03600   sym_count = obj_aout_external_sym_count (input_bfd);
03601 
03602   /* Write out the symbols and get a map of the new indices.  The map
03603      is placed into finfo->symbol_map.  */
03604   if (! aout_link_write_symbols (finfo, input_bfd))
03605     return FALSE;
03606 
03607   /* Relocate and write out the sections.  These functions use the
03608      symbol map created by aout_link_write_symbols.  The linker_mark
03609      field will be set if these sections are to be included in the
03610      link, which will normally be the case.  */
03611   if (obj_textsec (input_bfd)->linker_mark)
03612     {
03613       if (! aout_link_input_section (finfo, input_bfd,
03614                                  obj_textsec (input_bfd),
03615                                  &finfo->treloff,
03616                                  exec_hdr (input_bfd)->a_trsize))
03617        return FALSE;
03618     }
03619   if (obj_datasec (input_bfd)->linker_mark)
03620     {
03621       if (! aout_link_input_section (finfo, input_bfd,
03622                                  obj_datasec (input_bfd),
03623                                  &finfo->dreloff,
03624                                  exec_hdr (input_bfd)->a_drsize))
03625        return FALSE;
03626     }
03627 
03628   /* If we are not keeping memory, we don't need the symbols any
03629      longer.  We still need them if we are keeping memory, because the
03630      strings in the hash table point into them.  */
03631   if (! finfo->info->keep_memory)
03632     {
03633       if (! aout_link_free_symbols (input_bfd))
03634        return FALSE;
03635     }
03636 
03637   return TRUE;
03638 }
03639 
03640 /* Do the final link step.  This is called on the output BFD.  The
03641    INFO structure should point to a list of BFDs linked through the
03642    link_next field which can be used to find each BFD which takes part
03643    in the output.  Also, each section in ABFD should point to a list
03644    of bfd_link_order structures which list all the input sections for
03645    the output section.  */
03646 
03647 bfd_boolean
03648 NAME (aout, final_link) (bfd *abfd,
03649                       struct bfd_link_info *info,
03650                       void (*callback) (bfd *, file_ptr *, file_ptr *, file_ptr *))
03651 {
03652   struct aout_final_link_info aout_info;
03653   bfd_boolean includes_hash_initialized = FALSE;
03654   bfd *sub;
03655   bfd_size_type trsize, drsize;
03656   bfd_size_type max_contents_size;
03657   bfd_size_type max_relocs_size;
03658   bfd_size_type max_sym_count;
03659   bfd_size_type text_size;
03660   file_ptr text_end;
03661   struct bfd_link_order *p;
03662   asection *o;
03663   bfd_boolean have_link_order_relocs;
03664 
03665   if (info->shared)
03666     abfd->flags |= DYNAMIC;
03667 
03668   aout_info.info = info;
03669   aout_info.output_bfd = abfd;
03670   aout_info.contents = NULL;
03671   aout_info.relocs = NULL;
03672   aout_info.symbol_map = NULL;
03673   aout_info.output_syms = NULL;
03674 
03675   if (!bfd_hash_table_init_n (&aout_info.includes.root,
03676                            aout_link_includes_newfunc,
03677                            sizeof (struct aout_link_includes_entry),
03678                            251))
03679     goto error_return;
03680   includes_hash_initialized = TRUE;
03681 
03682   /* Figure out the largest section size.  Also, if generating
03683      relocatable output, count the relocs.  */
03684   trsize = 0;
03685   drsize = 0;
03686   max_contents_size = 0;
03687   max_relocs_size = 0;
03688   max_sym_count = 0;
03689   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
03690     {
03691       size_t sz;
03692 
03693       if (info->relocatable)
03694        {
03695          if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
03696            {
03697              trsize += exec_hdr (sub)->a_trsize;
03698              drsize += exec_hdr (sub)->a_drsize;
03699            }
03700          else
03701            {
03702              /* FIXME: We need to identify the .text and .data sections
03703                and call get_reloc_upper_bound and canonicalize_reloc to
03704                work out the number of relocs needed, and then multiply
03705                by the reloc size.  */
03706              (*_bfd_error_handler)
03707               ("%s: relocatable link from %s to %s not supported",
03708                bfd_get_filename (abfd),
03709                sub->xvec->name, abfd->xvec->name);
03710              bfd_set_error (bfd_error_invalid_operation);
03711              goto error_return;
03712            }
03713        }
03714 
03715       if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
03716        {
03717          sz = obj_textsec (sub)->size;
03718          if (sz > max_contents_size)
03719            max_contents_size = sz;
03720          sz = obj_datasec (sub)->size;
03721          if (sz > max_contents_size)
03722            max_contents_size = sz;
03723 
03724          sz = exec_hdr (sub)->a_trsize;
03725          if (sz > max_relocs_size)
03726            max_relocs_size = sz;
03727          sz = exec_hdr (sub)->a_drsize;
03728          if (sz > max_relocs_size)
03729            max_relocs_size = sz;
03730 
03731          sz = obj_aout_external_sym_count (sub);
03732          if (sz > max_sym_count)
03733            max_sym_count = sz;
03734        }
03735     }
03736 
03737   if (info->relocatable)
03738     {
03739       if (obj_textsec (abfd) != NULL)
03740        trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
03741                                            ->map_head.link_order)
03742                  * obj_reloc_entry_size (abfd));
03743       if (obj_datasec (abfd) != NULL)
03744        drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
03745                                            ->map_head.link_order)
03746                  * obj_reloc_entry_size (abfd));
03747     }
03748 
03749   exec_hdr (abfd)->a_trsize = trsize;
03750   exec_hdr (abfd)->a_drsize = drsize;
03751   exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
03752 
03753   /* Adjust the section sizes and vmas according to the magic number.
03754      This sets a_text, a_data and a_bss in the exec_hdr and sets the
03755      filepos for each section.  */
03756   if (! NAME (aout, adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
03757     goto error_return;
03758 
03759   /* The relocation and symbol file positions differ among a.out
03760      targets.  We are passed a callback routine from the backend
03761      specific code to handle this.
03762      FIXME: At this point we do not know how much space the symbol
03763      table will require.  This will not work for any (nonstandard)
03764      a.out target that needs to know the symbol table size before it
03765      can compute the relocation file positions.  This may or may not
03766      be the case for the hp300hpux target, for example.  */
03767   (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
03768               &aout_info.symoff);
03769   obj_textsec (abfd)->rel_filepos = aout_info.treloff;
03770   obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
03771   obj_sym_filepos (abfd) = aout_info.symoff;
03772 
03773   /* We keep a count of the symbols as we output them.  */
03774   obj_aout_external_sym_count (abfd) = 0;
03775 
03776   /* We accumulate the string table as we write out the symbols.  */
03777   aout_info.strtab = _bfd_stringtab_init ();
03778   if (aout_info.strtab == NULL)
03779     goto error_return;
03780 
03781   /* Allocate buffers to hold section contents and relocs.  */
03782   aout_info.contents = bfd_malloc (max_contents_size);
03783   aout_info.relocs = bfd_malloc (max_relocs_size);
03784   aout_info.symbol_map = bfd_malloc (max_sym_count * sizeof (int *));
03785   aout_info.output_syms = bfd_malloc ((max_sym_count + 1)
03786                                   * sizeof (struct external_nlist));
03787   if ((aout_info.contents == NULL && max_contents_size != 0)
03788       || (aout_info.relocs == NULL && max_relocs_size != 0)
03789       || (aout_info.symbol_map == NULL && max_sym_count != 0)
03790       || aout_info.output_syms == NULL)
03791     goto error_return;
03792 
03793   /* If we have a symbol named __DYNAMIC, force it out now.  This is
03794      required by SunOS.  Doing this here rather than in sunos.c is a
03795      hack, but it's easier than exporting everything which would be
03796      needed.  */
03797   {
03798     struct aout_link_hash_entry *h;
03799 
03800     h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
03801                             FALSE, FALSE, FALSE);
03802     if (h != NULL)
03803       aout_link_write_other_symbol (h, &aout_info);
03804   }
03805 
03806   /* The most time efficient way to do the link would be to read all
03807      the input object files into memory and then sort out the
03808      information into the output file.  Unfortunately, that will
03809      probably use too much memory.  Another method would be to step
03810      through everything that composes the text section and write it
03811      out, and then everything that composes the data section and write
03812      it out, and then write out the relocs, and then write out the
03813      symbols.  Unfortunately, that requires reading stuff from each
03814      input file several times, and we will not be able to keep all the
03815      input files open simultaneously, and reopening them will be slow.
03816 
03817      What we do is basically process one input file at a time.  We do
03818      everything we need to do with an input file once--copy over the
03819      section contents, handle the relocation information, and write
03820      out the symbols--and then we throw away the information we read
03821      from it.  This approach requires a lot of lseeks of the output
03822      file, which is unfortunate but still faster than reopening a lot
03823      of files.
03824 
03825      We use the output_has_begun field of the input BFDs to see
03826      whether we have already handled it.  */
03827   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
03828     sub->output_has_begun = FALSE;
03829 
03830   /* Mark all sections which are to be included in the link.  This
03831      will normally be every section.  We need to do this so that we
03832      can identify any sections which the linker has decided to not
03833      include.  */
03834   for (o = abfd->sections; o != NULL; o = o->next)
03835     {
03836       for (p = o->map_head.link_order; p != NULL; p = p->next)
03837        if (p->type == bfd_indirect_link_order)
03838          p->u.indirect.section->linker_mark = TRUE;
03839     }
03840 
03841   have_link_order_relocs = FALSE;
03842   for (o = abfd->sections; o != NULL; o = o->next)
03843     {
03844       for (p = o->map_head.link_order;
03845           p != NULL;
03846           p = p->next)
03847        {
03848          if (p->type == bfd_indirect_link_order
03849              && (bfd_get_flavour (p->u.indirect.section->owner)
03850                 == bfd_target_aout_flavour))
03851            {
03852              bfd *input_bfd;
03853 
03854              input_bfd = p->u.indirect.section->owner;
03855              if (! input_bfd->output_has_begun)
03856               {
03857                 if (! aout_link_input_bfd (&aout_info, input_bfd))
03858                   goto error_return;
03859                 input_bfd->output_has_begun = TRUE;
03860               }
03861            }
03862          else if (p->type == bfd_section_reloc_link_order
03863                  || p->type == bfd_symbol_reloc_link_order)
03864            /* These are handled below.  */
03865            have_link_order_relocs = TRUE;
03866          else
03867            {
03868              if (! _bfd_default_link_order (abfd, info, o, p))
03869               goto error_return;
03870            }
03871        }
03872     }
03873 
03874   /* Write out any symbols that we have not already written out.  */
03875   aout_link_hash_traverse (aout_hash_table (info),
03876                         aout_link_write_other_symbol,
03877                         (void *) &aout_info);
03878 
03879   /* Now handle any relocs we were asked to create by the linker.
03880      These did not come from any input file.  We must do these after
03881      we have written out all the symbols, so that we know the symbol
03882      indices to use.  */
03883   if (have_link_order_relocs)
03884     {
03885       for (o = abfd->sections; o != NULL; o = o->next)
03886        {
03887          for (p = o->map_head.link_order;
03888               p != NULL;
03889               p = p->next)
03890            {
03891              if (p->type == bfd_section_reloc_link_order
03892                 || p->type == bfd_symbol_reloc_link_order)
03893               {
03894                 if (! aout_link_reloc_link_order (&aout_info, o, p))
03895                   goto error_return;
03896               }
03897            }
03898        }
03899     }
03900 
03901   if (aout_info.contents != NULL)
03902     {
03903       free (aout_info.contents);
03904       aout_info.contents = NULL;
03905     }
03906   if (aout_info.relocs != NULL)
03907     {
03908       free (aout_info.relocs);
03909       aout_info.relocs = NULL;
03910     }
03911   if (aout_info.symbol_map != NULL)
03912     {
03913       free (aout_info.symbol_map);
03914       aout_info.symbol_map = NULL;
03915     }
03916   if (aout_info.output_syms != NULL)
03917     {
03918       free (aout_info.output_syms);
03919       aout_info.output_syms = NULL;
03920     }
03921   if (includes_hash_initialized)
03922     {
03923       bfd_hash_table_free (&aout_info.includes.root);
03924       includes_hash_initialized = FALSE;
03925     }
03926 
03927   /* Finish up any dynamic linking we may be doing.  */
03928   if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
03929     {
03930       if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
03931        goto error_return;
03932     }
03933 
03934   /* Update the header information.  */
03935   abfd->symcount = obj_aout_external_sym_count (abfd);
03936   exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
03937   obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
03938   obj_textsec (abfd)->reloc_count =
03939     exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
03940   obj_datasec (abfd)->reloc_count =
03941     exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
03942 
03943   /* Write out the string table, unless there are no symbols.  */
03944   if (abfd->symcount > 0)
03945     {
03946       if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
03947          || ! emit_stringtab (abfd, aout_info.strtab))
03948        goto error_return;
03949     }
03950   else if (obj_textsec (abfd)->reloc_count == 0
03951           && obj_datasec (abfd)->reloc_count == 0)
03952     {
03953       bfd_byte b;
03954 
03955       b = 0;
03956       if (bfd_seek (abfd,
03957                   (file_ptr) (obj_datasec (abfd)->filepos
03958                             + exec_hdr (abfd)->a_data
03959                             - 1),
03960                   SEEK_SET) != 0
03961          || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
03962        goto error_return;
03963     }
03964 
03965   return TRUE;
03966 
03967  error_return:
03968   if (aout_info.contents != NULL)
03969     free (aout_info.contents);
03970   if (aout_info.relocs != NULL)
03971     free (aout_info.relocs);
03972   if (aout_info.symbol_map != NULL)
03973     free (aout_info.symbol_map);
03974   if (aout_info.output_syms != NULL)
03975     free (aout_info.output_syms);
03976   if (includes_hash_initialized)
03977     bfd_hash_table_free (&aout_info.includes.root);
03978   return FALSE;
03979 }
03980 
03981 /* Adjust and write out the symbols for an a.out file.  Set the new
03982    symbol indices into a symbol_map.  */
03983 
03984 static bfd_boolean
03985 aout_link_write_symbols (struct aout_final_link_info *finfo, bfd *input_bfd)
03986 {
03987   bfd *output_bfd;
03988   bfd_size_type sym_count;
03989   char *strings;
03990   enum bfd_link_strip strip;
03991   enum bfd_link_discard discard;
03992   struct external_nlist *outsym;
03993   bfd_size_type strtab_index;
03994   struct external_nlist *sym;
03995   struct external_nlist *sym_end;
03996   struct aout_link_hash_entry **sym_hash;
03997   int *symbol_map;
03998   bfd_boolean pass;
03999   bfd_boolean skip_next;
04000 
04001   output_bfd = finfo->output_bfd;
04002   sym_count = obj_aout_external_sym_count (input_bfd);
04003   strings = obj_aout_external_strings (input_bfd);
04004   strip = finfo->info->strip;
04005   discard = finfo->info->discard;
04006   outsym = finfo->output_syms;
04007 
04008   /* First write out a symbol for this object file, unless we are
04009      discarding such symbols.  */
04010   if (strip != strip_all
04011       && (strip != strip_some
04012          || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
04013                            FALSE, FALSE) != NULL)
04014       && discard != discard_all)
04015     {
04016       H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
04017       strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
04018                                    input_bfd->filename, FALSE);
04019       if (strtab_index == (bfd_size_type) -1)
04020        return FALSE;
04021       PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
04022       PUT_WORD (output_bfd,
04023               (bfd_get_section_vma (output_bfd,
04024                                   obj_textsec (input_bfd)->output_section)
04025                + obj_textsec (input_bfd)->output_offset),
04026               outsym->e_value);
04027       ++obj_aout_external_sym_count (output_bfd);
04028       ++outsym;
04029     }
04030 
04031   pass = FALSE;
04032   skip_next = FALSE;
04033   sym = obj_aout_external_syms (input_bfd);
04034   sym_end = sym + sym_count;
04035   sym_hash = obj_aout_sym_hashes (input_bfd);
04036   symbol_map = finfo->symbol_map;
04037   memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
04038   for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
04039     {
04040       const char *name;
04041       int type;
04042       struct aout_link_hash_entry *h;
04043       bfd_boolean skip;
04044       asection *symsec;
04045       bfd_vma val = 0;
04046       bfd_boolean copy;
04047 
04048       /* We set *symbol_map to 0 above for all symbols.  If it has
04049          already been set to -1 for this symbol, it means that we are
04050          discarding it because it appears in a duplicate header file.
04051          See the N_BINCL code below.  */
04052       if (*symbol_map == -1)
04053        continue;
04054 
04055       /* Initialize *symbol_map to -1, which means that the symbol was
04056          not copied into the output file.  We will change it later if
04057          we do copy the symbol over.  */
04058       *symbol_map = -1;
04059 
04060       type = H_GET_8 (input_bfd, sym->e_type);
04061       name = strings + GET_WORD (input_bfd, sym->e_strx);
04062 
04063       h = NULL;
04064 
04065       if (pass)
04066        {
04067          /* Pass this symbol through.  It is the target of an
04068             indirect or warning symbol.  */
04069          val = GET_WORD (input_bfd, sym->e_value);
04070          pass = FALSE;
04071        }
04072       else if (skip_next)
04073        {
04074          /* Skip this symbol, which is the target of an indirect
04075             symbol that we have changed to no longer be an indirect
04076             symbol.  */
04077          skip_next = FALSE;
04078          continue;
04079        }
04080       else
04081        {
04082          struct aout_link_hash_entry *hresolve;
04083 
04084          /* We have saved the hash table entry for this symbol, if
04085             there is one.  Note that we could just look it up again
04086             in the hash table, provided we first check that it is an
04087             external symbol. */
04088          h = *sym_hash;
04089 
04090          /* Use the name from the hash table, in case the symbol was
04091              wrapped.  */
04092          if (h != NULL)
04093            name = h->root.root.string;
04094 
04095          /* If this is an indirect or warning symbol, then change
04096             hresolve to the base symbol.  We also change *sym_hash so
04097             that the relocation routines relocate against the real
04098             symbol.  */
04099          hresolve = h;
04100          if (h != NULL
04101              && (h->root.type == bfd_link_hash_indirect
04102                 || h->root.type == bfd_link_hash_warning))
04103            {
04104              hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
04105              while (hresolve->root.type == bfd_link_hash_indirect
04106                    || hresolve->root.type == bfd_link_hash_warning)
04107               hresolve = ((struct aout_link_hash_entry *)
04108                          hresolve->root.u.i.link);
04109              *sym_hash = hresolve;
04110            }
04111 
04112          /* If the symbol has already been written out, skip it.  */
04113          if (h != NULL
04114              && h->root.type != bfd_link_hash_warning
04115              && h->written)
04116            {
04117              if ((type & N_TYPE) == N_INDR
04118                 || type == N_WARNING)
04119               skip_next = TRUE;
04120              *symbol_map = h->indx;
04121              continue;
04122            }
04123 
04124          /* See if we are stripping this symbol.  */
04125          skip = FALSE;
04126          switch (strip)
04127            {
04128            case strip_none:
04129              break;
04130            case strip_debugger:
04131              if ((type & N_STAB) != 0)
04132               skip = TRUE;
04133              break;
04134            case strip_some:
04135              if (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE)
04136                 == NULL)
04137               skip = TRUE;
04138              break;
04139            case strip_all:
04140              skip = TRUE;
04141              break;
04142            }
04143          if (skip)
04144            {
04145              if (h != NULL)
04146               h->written = TRUE;
04147              continue;
04148            }
04149 
04150          /* Get the value of the symbol.  */
04151          if ((type & N_TYPE) == N_TEXT
04152              || type == N_WEAKT)
04153            symsec = obj_textsec (input_bfd);
04154          else if ((type & N_TYPE) == N_DATA
04155                  || type == N_WEAKD)
04156            symsec = obj_datasec (input_bfd);
04157          else if ((type & N_TYPE) == N_BSS
04158                  || type == N_WEAKB)
04159            symsec = obj_bsssec (input_bfd);
04160          else if ((type & N_TYPE) == N_ABS
04161                  || type == N_WEAKA)
04162            symsec = bfd_abs_section_ptr;
04163          else if (((type & N_TYPE) == N_INDR
04164                   && (hresolve == NULL
04165                      || (hresolve->root.type != bfd_link_hash_defined
04166                          && hresolve->root.type != bfd_link_hash_defweak
04167                          && hresolve->root.type != bfd_link_hash_common)))
04168                  || type == N_WARNING)
04169            {
04170              /* Pass the next symbol through unchanged.  The
04171                condition above for indirect symbols is so that if
04172                the indirect symbol was defined, we output it with
04173                the correct definition so the debugger will
04174                understand it.  */
04175              pass = TRUE;
04176              val = GET_WORD (input_bfd, sym->e_value);
04177              symsec = NULL;
04178            }
04179          else if ((type & N_STAB) != 0)
04180            {
04181              val = GET_WORD (input_bfd, sym->e_value);
04182              symsec = NULL;
04183            }
04184          else
04185            {
04186              /* If we get here with an indirect symbol, it means that
04187                we are outputting it with a real definition.  In such
04188                a case we do not want to output the next symbol,
04189                which is the target of the indirection.  */
04190              if ((type & N_TYPE) == N_INDR)
04191               skip_next = TRUE;
04192 
04193              symsec = NULL;
04194 
04195              /* We need to get the value from the hash table.  We use
04196                hresolve so that if we have defined an indirect
04197                symbol we output the final definition.  */
04198              if (h == NULL)
04199               {
04200                 switch (type & N_TYPE)
04201                   {
04202                   case N_SETT:
04203                     symsec = obj_textsec (input_bfd);
04204                     break;
04205                   case N_SETD:
04206                     symsec = obj_datasec (input_bfd);
04207                     break;
04208                   case N_SETB:
04209                     symsec = obj_bsssec (input_bfd);
04210                     break;
04211                   case N_SETA:
04212                     symsec = bfd_abs_section_ptr;
04213                     break;
04214                   default:
04215                     val = 0;
04216                     break;
04217                   }
04218               }
04219              else if (hresolve->root.type == bfd_link_hash_defined
04220                      || hresolve->root.type == bfd_link_hash_defweak)
04221               {
04222                 asection *input_section;
04223                 asection *output_section;
04224 
04225                 /* This case usually means a common symbol which was
04226                    turned into a defined symbol.  */
04227                 input_section = hresolve->root.u.def.section;
04228                 output_section = input_section->output_section;
04229                 BFD_ASSERT (bfd_is_abs_section (output_section)
04230                            || output_section->owner == output_bfd);
04231                 val = (hresolve->root.u.def.value
04232                       + bfd_get_section_vma (output_bfd, output_section)
04233                       + input_section->output_offset);
04234 
04235                 /* Get the correct type based on the section.  If
04236                    this is a constructed set, force it to be
04237                    globally visible.  */
04238                 if (type == N_SETT
04239                     || type == N_SETD
04240                     || type == N_SETB
04241                     || type == N_SETA)
04242                   type |= N_EXT;
04243 
04244                 type &=~ N_TYPE;
04245 
04246                 if (output_section == obj_textsec (output_bfd))
04247                   type |= (hresolve->root.type == bfd_link_hash_defined
04248                           ? N_TEXT
04249                           : N_WEAKT);
04250                 else if (output_section == obj_datasec (output_bfd))
04251                   type |= (hresolve->root.type == bfd_link_hash_defined
04252                           ? N_DATA
04253                           : N_WEAKD);
04254                 else if (output_section == obj_bsssec (output_bfd))
04255                   type |= (hresolve->root.type == bfd_link_hash_defined
04256                           ? N_BSS
04257                           : N_WEAKB);
04258                 else
04259                   type |= (hresolve->root.type == bfd_link_hash_defined
04260                           ? N_ABS
04261                           : N_WEAKA);
04262               }
04263              else if (hresolve->root.type == bfd_link_hash_common)
04264               val = hresolve->root.u.c.size;
04265              else if (hresolve->root.type == bfd_link_hash_undefweak)
04266               {
04267                 val = 0;
04268                 type = N_WEAKU;
04269               }
04270              else
04271               val = 0;
04272            }
04273          if (symsec != NULL)
04274            val = (symsec->output_section->vma
04275                  + symsec->output_offset
04276                  + (GET_WORD (input_bfd, sym->e_value)
04277                     - symsec->vma));
04278 
04279          /* If this is a global symbol set the written flag, and if
04280             it is a local symbol see if we should discard it.  */
04281          if (h != NULL)
04282            {
04283              h->written = TRUE;
04284              h->indx = obj_aout_external_sym_count (output_bfd);
04285            }
04286          else if ((type & N_TYPE) != N_SETT
04287                  && (type & N_TYPE) != N_SETD
04288                  && (type & N_TYPE) != N_SETB
04289                  && (type & N_TYPE) != N_SETA)
04290            {
04291              switch (discard)
04292               {
04293               case discard_none:
04294               case discard_sec_merge:
04295                 break;
04296               case discard_l:
04297                 if ((type & N_STAB) == 0
04298                     && bfd_is_local_label_name (input_bfd, name))
04299                   skip = TRUE;
04300                 break;
04301               case discard_all:
04302                 skip = TRUE;
04303                 break;
04304               }
04305              if (skip)
04306               {
04307                 pass = FALSE;
04308                 continue;
04309               }
04310            }
04311 
04312          /* An N_BINCL symbol indicates the start of the stabs
04313             entries for a header file.  We need to scan ahead to the
04314             next N_EINCL symbol, ignoring nesting, adding up all the
04315             characters in the symbol names, not including the file
04316             numbers in types (the first number after an open
04317             parenthesis).  */
04318          if (type == N_BINCL)
04319            {
04320              struct external_nlist *incl_sym;
04321              int nest;
04322              struct aout_link_includes_entry *incl_entry;
04323              struct aout_link_includes_totals *t;
04324 
04325              val = 0;
04326              nest = 0;
04327              for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
04328               {
04329                 int incl_type;
04330 
04331                 incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
04332                 if (incl_type == N_EINCL)
04333                   {
04334                     if (nest == 0)
04335                      break;
04336                     --nest;
04337                   }
04338                 else if (incl_type == N_BINCL)
04339                   ++nest;
04340                 else if (nest == 0)
04341                   {
04342                     const char *s;
04343 
04344                     s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
04345                     for (; *s != '\0'; s++)
04346                      {
04347                        val += *s;
04348                        if (*s == '(')
04349                          {
04350                            /* Skip the file number.  */
04351                            ++s;
04352                            while (ISDIGIT (*s))
04353                             ++s;
04354                            --s;
04355                          }
04356                      }
04357                   }
04358               }
04359 
04360              /* If we have already included a header file with the
04361                  same value, then replace this one with an N_EXCL
04362                  symbol.  */
04363              copy = ! finfo->info->keep_memory;
04364              incl_entry = aout_link_includes_lookup (&finfo->includes,
04365                                                 name, TRUE, copy);
04366              if (incl_entry == NULL)
04367               return FALSE;
04368              for (t = incl_entry->totals; t != NULL; t = t->next)
04369               if (t->total == val)
04370                 break;
04371              if (t == NULL)
04372               {
04373                 /* This is the first time we have seen this header
04374                      file with this set of stabs strings.  */
04375                 t = bfd_hash_allocate (&finfo->includes.root,
04376                                     sizeof *t);
04377                 if (t == NULL)
04378                   return FALSE;
04379                 t->total = val;
04380                 t->next = incl_entry->totals;
04381                 incl_entry->totals = t;
04382               }
04383              else
04384               {
04385                 int *incl_map;
04386 
04387                 /* This is a duplicate header file.  We must change
04388                      it to be an N_EXCL entry, and mark all the
04389                      included symbols to prevent outputting them.  */
04390                 type = N_EXCL;
04391 
04392                 nest = 0;
04393                 for (incl_sym = sym + 1, incl_map = symbol_map + 1;
04394                      incl_sym < sym_end;
04395                      incl_sym++, incl_map++)
04396                   {
04397                     int incl_type;
04398 
04399                     incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
04400                     if (incl_type == N_EINCL)
04401                      {
04402                        if (nest == 0)
04403                          {
04404                            *incl_map = -1;
04405                            break;
04406                          }
04407                        --nest;
04408                      }
04409                     else if (incl_type == N_BINCL)
04410                      ++nest;
04411                     else if (nest == 0)
04412                      *incl_map = -1;
04413                   }
04414               }
04415            }
04416        }
04417 
04418       /* Copy this symbol into the list of symbols we are going to
04419         write out.  */
04420       H_PUT_8 (output_bfd, type, outsym->e_type);
04421       copy = FALSE;
04422       if (! finfo->info->keep_memory)
04423        {
04424          /* name points into a string table which we are going to
04425             free.  If there is a hash table entry, use that string.
04426             Otherwise, copy name into memory.  */
04427          if (h != NULL)
04428            name = h->root.root.string;
04429          else
04430            copy = TRUE;
04431        }
04432       strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
04433                                    name, copy);
04434       if (strtab_index == (bfd_size_type) -1)
04435        return FALSE;
04436       PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
04437       PUT_WORD (output_bfd, val, outsym->e_value);
04438       *symbol_map = obj_aout_external_sym_count (output_bfd);
04439       ++obj_aout_external_sym_count (output_bfd);
04440       ++outsym;
04441     }
04442 
04443   /* Write out the output symbols we have just constructed.  */
04444   if (outsym > finfo->output_syms)
04445     {
04446       bfd_size_type size;
04447 
04448       if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
04449        return FALSE;
04450       size = outsym - finfo->output_syms;
04451       size *= EXTERNAL_NLIST_SIZE;
04452       if (bfd_bwrite ((void *) finfo->output_syms, size, output_bfd) != size)
04453        return FALSE;
04454       finfo->symoff += size;
04455     }
04456 
04457   return TRUE;
04458 }
04459 
04460 /* Write out a symbol that was not associated with an a.out input
04461    object.  */
04462 
04463 static bfd_vma
04464 bfd_getp32 (const void *p)
04465 {
04466   const bfd_byte *addr = p;
04467   unsigned long v;
04468 
04469   v = (unsigned long) addr[1] << 24;
04470   v |= (unsigned long) addr[0] << 16;
04471   v |= (unsigned long) addr[3] << 8;
04472   v |= (unsigned long) addr[2];
04473   return v;
04474 }
04475 
04476 #define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000)
04477 
04478 static bfd_signed_vma
04479 bfd_getp_signed_32 (const void *p)
04480 {
04481   const bfd_byte *addr = p;
04482   unsigned long v;
04483 
04484   v = (unsigned long) addr[1] << 24;
04485   v |= (unsigned long) addr[0] << 16;
04486   v |= (unsigned long) addr[3] << 8;
04487   v |= (unsigned long) addr[2];
04488   return COERCE32 (v);
04489 }
04490 
04491 static void
04492 bfd_putp32 (bfd_vma data, void *p)
04493 {
04494   bfd_byte *addr = p;
04495 
04496   addr[0] = (data >> 16) & 0xff;
04497   addr[1] = (data >> 24) & 0xff;
04498   addr[2] = (data >> 0) & 0xff;
04499   addr[3] = (data >> 8) & 0xff;
04500 }
04501 
04502 const bfd_target MY (vec) =
04503 {
04504   TARGETNAME,               /* Name.  */
04505   bfd_target_aout_flavour,
04506   BFD_ENDIAN_LITTLE,        /* Target byte order (little).  */
04507   BFD_ENDIAN_LITTLE,        /* Target headers byte order (little).  */
04508   (HAS_RELOC | EXEC_P |            /* Object flags.  */
04509    HAS_LINENO | HAS_DEBUG |
04510    HAS_SYMS | HAS_LOCALS | WP_TEXT),
04511   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
04512   MY_symbol_leading_char,
04513   AR_PAD_CHAR,                     /* AR_pad_char.  */
04514   15,                       /* AR_max_namelen.  */
04515   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
04516      bfd_getp32, bfd_getp_signed_32, bfd_putp32,
04517      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data.  */
04518   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
04519      bfd_getp32, bfd_getp_signed_32, bfd_putp32,
04520      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers.  */
04521     {_bfd_dummy_target, MY_object_p,             /* bfd_check_format.  */
04522        bfd_generic_archive_p, MY_core_file_p},
04523     {bfd_false, MY_mkobject,                     /* bfd_set_format.  */
04524        _bfd_generic_mkarchive, bfd_false},
04525     {bfd_false, MY_write_object_contents,        /* bfd_write_contents.  */
04526        _bfd_write_archive_contents, bfd_false},
04527 
04528      BFD_JUMP_TABLE_GENERIC (MY),
04529      BFD_JUMP_TABLE_COPY (MY),
04530      BFD_JUMP_TABLE_CORE (MY),
04531      BFD_JUMP_TABLE_ARCHIVE (MY),
04532      BFD_JUMP_TABLE_SYMBOLS (MY),
04533      BFD_JUMP_TABLE_RELOCS (MY),
04534      BFD_JUMP_TABLE_WRITE (MY),
04535      BFD_JUMP_TABLE_LINK (MY),
04536      BFD_JUMP_TABLE_DYNAMIC (MY),
04537 
04538   /* Alternative_target.  */
04539   NULL,
04540 
04541   (void *) MY_backend_data
04542 };