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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [aoutx.h] - Blame information for rev 55

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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