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

Subversion Repositories open8_urisc

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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