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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [bfd/] [aoutx.h] - Blame information for rev 866

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

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

powered by: WebSVN 2.1.0

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