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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [aoutx.h] - Blame information for rev 1776

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

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

powered by: WebSVN 2.1.0

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