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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [bfd/] [aoutx.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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