OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [bfd/] [aoutx.h] - Blame information for rev 587

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

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

powered by: WebSVN 2.1.0

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