OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [pdp11.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.