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

Subversion Repositories or1k_old

[/] [or1k_old/] [tags/] [VER_5_3/] [gdb-5.3/] [bfd/] [aoutx.h] - Blame information for rev 1782

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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