Linker now works for go32; other changes keep it from breaking the other
[external/binutils.git] / bfd / aoutx.h
1 /* BFD semi-generic back-end for a.out binaries
2    Copyright (C) 1990-1991 Free Software Foundation, Inc.
3    Written by Cygnus Support.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 /*
22 SECTION
23         a.out backends
24
25
26 DESCRIPTION
27
28         BFD supports a number of different flavours of a.out format,
29         though the major differences are only the sizes of the
30         structures on disk, and the shape of the relocation
31         information. 
32
33         The support is split into a basic support file @code{aoutx.h}
34         and other files which derive functions from the base. One
35         derivation file is @code{aoutf1.h} (for a.out flavour 1), and
36         adds to the basic a.out functions support for sun3, sun4, 386
37         and 29k a.out files, to create a target jump vector for a
38         specific target. 
39
40         This information is further split out into more specific files
41         for each machine, including @code{sunos.c} for sun3 and sun4,
42         @code{newsos3.c} for the Sony NEWS, and @code{demo64.c} for a
43         demonstration of a 64 bit a.out format.
44
45         The base file @code{aoutx.h} defines general mechanisms for
46         reading and writing records to and from disk, and various
47         other methods which BFD requires. It is included by
48         @code{aout32.c} and @code{aout64.c} to form the names
49         aout_32_swap_exec_header_in, aout_64_swap_exec_header_in, etc.
50
51         As an example, this is what goes on to make the back end for a
52         sun4, from aout32.c 
53
54 |       #define ARCH_SIZE 32
55 |       #include "aoutx.h"
56
57         Which exports names:
58
59 |       ...
60 |       aout_32_canonicalize_reloc
61 |       aout_32_find_nearest_line
62 |       aout_32_get_lineno
63 |       aout_32_get_reloc_upper_bound
64 |       ...
65
66         from sunos.c
67
68 |       #define ARCH 32
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 aout32.c, and produces the jump vector
74
75 |       sunos_big_vec
76
77         The 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 <<../include/sys/h-XXX.h>> (for your host).  These
97         values, plus the structures and macros defined in <<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 <<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 <<config/mt-XXX>> file, and modify configure.in to use the
106         <<mt-XXX>> file (by setting "<<bfd_target=XXX>>") when your
107         configuration is selected.
108
109 */
110
111 /* Some assumptions:
112    * Any BFD with D_PAGED set is ZMAGIC, and vice versa.
113      Doesn't matter what the setting of WP_TEXT is on output, but it'll
114      get set on input.
115    * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC.
116    * Any BFD with both flags clear is OMAGIC.
117    (Just want to make these explicit, so the conditions tested in this
118    file make sense if you're more familiar with a.out than with BFD.)  */
119
120 #define KEEPIT flags
121 #define KEEPITTYPE int
122
123 #include "bfd.h"
124 #include <sysdep.h>
125 #include <ansidecl.h>
126
127 struct external_exec;
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 extern void (*bfd_error_trap)();
135
136 /*
137 SUBSECTION
138         relocations
139
140 DESCRIPTION
141         The file @code{aoutx.h} caters for both the @emph{standard}
142         and @emph{extended} forms of a.out relocation records.
143
144         The standard records are characterised by containing only an
145         address, a symbol index and a type field. The extended records
146         (used on 29ks and sparcs) also have a full integer for an
147         addend. 
148
149 */
150 #define CTOR_TABLE_RELOC_IDX 2
151
152 #define howto_table_ext NAME(aout,ext_howto_table)
153 #define howto_table_std NAME(aout,std_howto_table)
154
155 reloc_howto_type howto_table_ext[] = 
156 {
157   HOWTO(RELOC_8,      0,  0,    8,  false, 0, true,  true,0,"8",      false, 0,0x000000ff, false),
158   HOWTO(RELOC_16,     0,  1,    16, false, 0, true,  true,0,"16",      false, 0,0x0000ffff, false),
159   HOWTO(RELOC_32,     0,  2,    32, false, 0, true,  true,0,"32",      false, 0,0xffffffff, false),
160   HOWTO(RELOC_DISP8,  0,  0,    8,  true,  0, false, true,0,"DISP8",    false, 0,0x000000ff, false),
161   HOWTO(RELOC_DISP16, 0,  1,    16, true,  0, false, true,0,"DISP16",   false, 0,0x0000ffff, false),
162   HOWTO(RELOC_DISP32, 0,  2,    32, true,  0, false, true,0,"DISP32",   false, 0,0xffffffff, false),
163   HOWTO(RELOC_WDISP30,2,  2,    30, true,  0, false, true,0,"WDISP30",  false, 0,0x3fffffff, false),
164   HOWTO(RELOC_WDISP22,2,  2,    22, true,  0, false, true,0,"WDISP22",  false, 0,0x003fffff, false),
165   HOWTO(RELOC_HI22,   10, 2,    22, false, 0, false, true,0,"HI22",     false, 0,0x003fffff, false),
166   HOWTO(RELOC_22,      0, 2,    22, false, 0, false, true,0,"22",       false, 0,0x003fffff, false),
167   HOWTO(RELOC_13,       0, 2,   13, false, 0, false, true,0,"13",       false, 0,0x00001fff, false),
168   HOWTO(RELOC_LO10,     0, 2,   10, false, 0, false, true,0,"LO10",     false, 0,0x000003ff, false),
169   HOWTO(RELOC_SFA_BASE,0, 2,    32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false),
170   HOWTO(RELOC_SFA_OFF13,0,2,    32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false),
171   HOWTO(RELOC_BASE10, 0,  2,    16, false, 0, false, true,0,"BASE10",   false, 0,0x0000ffff, false),
172   HOWTO(RELOC_BASE13, 0,  2,    13, false, 0, false, true,0,"BASE13",   false, 0,0x00001fff, false),
173   HOWTO(RELOC_BASE22, 0,  2,    0,  false, 0, false, true,0,"BASE22",   false, 0,0x00000000, false),
174   HOWTO(RELOC_PC10,   0,  2,    10, false, 0, false, true,0,"PC10",     false, 0,0x000003ff, false),
175   HOWTO(RELOC_PC22,   0,  2,    22, false, 0, false, true,0,"PC22",     false, 0,0x003fffff, false),
176   HOWTO(RELOC_JMP_TBL,0,  2,    32, false, 0, false, true,0,"JMP_TBL",  false, 0,0xffffffff, false),
177   HOWTO(RELOC_SEGOFF16,0, 2,    0,  false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false),
178   HOWTO(RELOC_GLOB_DAT,0, 2,    0,  false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false),
179   HOWTO(RELOC_JMP_SLOT,0, 2,    0,  false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false),
180   HOWTO(RELOC_RELATIVE,0, 2,    0,  false, 0, false,    true,0,"RELATIVE",      false, 0,0x00000000, false),
181 };
182
183 /* Convert standard reloc records to "arelent" format (incl byte swap).  */
184
185 reloc_howto_type howto_table_std[] = {
186   /* type           rs   size bsz  pcrel bitpos  abs ovrf sf name    part_inpl   readmask  setmask  pcdone */
187 HOWTO( 0,              0,  0,   8,  false, 0, true,  true,0,"8",        true, 0x000000ff,0x000000ff, false),
188 HOWTO( 1,              0,  1,   16, false, 0, true,  true,0,"16",       true, 0x0000ffff,0x0000ffff, false),
189 HOWTO( 2,              0,  2,   32, false, 0, true,  true,0,"32",       true, 0xffffffff,0xffffffff, false),
190 HOWTO( 3,              0,  3,   64, false, 0, true,  true,0,"64",       true, 0xdeaddead,0xdeaddead, false),
191 HOWTO( 4,              0,  0,   8,  true,  0, false, true,0,"DISP8",    true, 0x000000ff,0x000000ff, false),
192 HOWTO( 5,              0,  1,   16, true,  0, false, true,0,"DISP16",   true, 0x0000ffff,0x0000ffff, false),
193 HOWTO( 6,              0,  2,   32, true,  0, false, true,0,"DISP32",   true, 0xffffffff,0xffffffff, false),
194 HOWTO( 7,              0,  3,   64, true,  0, false, true,0,"DISP64",   true, 0xfeedface,0xfeedface, false),
195 };
196
197 CONST struct reloc_howto_struct *
198 DEFUN(NAME(aout,reloc_type_lookup),(abfd,code),
199       bfd *abfd AND
200       bfd_reloc_code_real_type code)
201 {
202 #define EXT(i,j)        case i: return &howto_table_ext[j]
203 #define STD(i,j)        case i: return &howto_table_std[j]
204   int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
205   if (code == BFD_RELOC_CTOR)
206     switch (bfd_get_arch_info (abfd)->bits_per_address)
207       {
208       case 32:
209         code = BFD_RELOC_32;
210         break;
211       }
212   if (ext)
213     switch (code)
214       {
215         EXT (BFD_RELOC_32, 2);
216         EXT (BFD_RELOC_HI22, 8);
217         EXT (BFD_RELOC_LO10, 11);
218         EXT (BFD_RELOC_32_PCREL_S2, 6);
219       }
220   else
221     /* std relocs */
222     switch (code)
223       {
224         STD (BFD_RELOC_16, 1);
225         STD (BFD_RELOC_32, 2);
226         STD (BFD_RELOC_8_PCREL, 4);
227         STD (BFD_RELOC_16_PCREL, 5);
228         STD (BFD_RELOC_32_PCREL, 6);
229       }
230   return 0;
231 }
232
233 extern bfd_error_vector_type bfd_error_vector;
234
235 /*
236 SUBSECTION
237         Internal Entry Points
238
239 DESCRIPTION
240         @code{aoutx.h} exports several routines for accessing the
241         contents of an a.out file, which are gathered and exported in
242         turn by various format specific files (eg sunos.c).
243
244 */
245
246 /*
247 FUNCTION
248          aout_<size>_swap_exec_header_in
249
250 DESCRIPTION
251         Swaps the information in an executable header taken from a raw
252         byte stream memory image, into the internal exec_header
253         structure.
254
255 EXAMPLE
256         void aout_<size>_swap_exec_header_in,
257            (bfd *abfd,
258             struct external_exec *raw_bytes,
259             struct internal_exec *execp);
260 */
261          
262 void
263 DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
264       bfd *abfd AND
265       struct external_exec *raw_bytes AND
266       struct internal_exec *execp)
267 {
268   struct external_exec *bytes = (struct external_exec *)raw_bytes;
269
270   /* The internal_exec structure has some fields that are unused in this
271      configuration (IE for i960), so ensure that all such uninitialized
272      fields are zero'd out.  There are places where two of these structs
273      are memcmp'd, and thus the contents do matter. */
274   memset (execp, 0, sizeof (struct internal_exec));
275   /* Now fill in fields in the execp, from the bytes in the raw data.  */
276   execp->a_info   = bfd_h_get_32 (abfd, bytes->e_info);
277   execp->a_text   = GET_WORD (abfd, bytes->e_text);
278   execp->a_data   = GET_WORD (abfd, bytes->e_data);
279   execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
280   execp->a_syms   = GET_WORD (abfd, bytes->e_syms);
281   execp->a_entry  = GET_WORD (abfd, bytes->e_entry);
282   execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
283   execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
284 }
285
286 /*
287 FUNCTION
288         aout_<size>_swap_exec_header_out
289
290 DESCRIPTION
291         Swaps the information in an internal exec header structure
292         into the supplied buffer ready for writing to disk.
293
294 EXAMPLE
295         void aout_<size>_swap_exec_header_out
296           (bfd *abfd,
297            struct internal_exec *execp,
298            struct external_exec *raw_bytes);
299 */
300 void
301 DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
302      bfd *abfd AND
303      struct internal_exec *execp AND 
304      struct external_exec *raw_bytes)
305 {
306   struct external_exec *bytes = (struct external_exec *)raw_bytes;
307
308   /* Now fill in fields in the raw data, from the fields in the exec struct. */
309   bfd_h_put_32 (abfd, execp->a_info  , bytes->e_info);
310   PUT_WORD (abfd, execp->a_text  , bytes->e_text);
311   PUT_WORD (abfd, execp->a_data  , bytes->e_data);
312   PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
313   PUT_WORD (abfd, execp->a_syms  , bytes->e_syms);
314   PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
315   PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
316   PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
317 }
318
319
320
321 /*
322 FUNCTION
323         aout_<size>_some_aout_object_p
324
325 DESCRIPTION
326         Some A.OUT variant thinks that the file whose format we're
327         checking is an a.out file.  Do some more checking, and set up
328         for access if it really is.  Call back to the calling
329         environments "finish up" function just before returning, to
330         handle any last-minute setup.  
331
332 EXAMPLE
333         bfd_target *aout_<size>_some_aout_object_p
334          (bfd *abfd,
335           bfd_target *(*callback_to_real_object_p)());
336 */
337  
338 bfd_target *
339 DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
340       bfd *abfd AND
341       struct internal_exec *execp AND
342       bfd_target *(*callback_to_real_object_p) ())
343 {
344   struct aout_data_struct *rawptr, *oldrawptr;
345   bfd_target *result;
346
347   rawptr = (struct aout_data_struct  *) bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
348   if (rawptr == NULL) {
349     bfd_error = no_memory;
350     return 0;
351   }
352
353   oldrawptr = abfd->tdata.aout_data;
354   abfd->tdata.aout_data = rawptr;
355   abfd->tdata.aout_data->a.hdr = &rawptr->e;
356   *(abfd->tdata.aout_data->a.hdr) = *execp;     /* Copy in the internal_exec struct */
357   execp = abfd->tdata.aout_data->a.hdr;
358
359   /* Set the file flags */
360   abfd->flags = NO_FLAGS;
361   if (execp->a_drsize || execp->a_trsize)
362     abfd->flags |= HAS_RELOC;
363   /* Setting of EXEC_P has been deferred to the bottom of this function */
364   if (execp->a_syms) 
365     abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
366
367   if (N_MAGIC (*execp) == ZMAGIC)
368     {
369       abfd->flags |= D_PAGED|WP_TEXT;
370       adata(abfd).magic = z_magic;
371     }
372   else if (N_MAGIC (*execp) == NMAGIC)
373     {
374       abfd->flags |= WP_TEXT;
375       adata(abfd).magic = n_magic;
376     }
377   else
378     adata(abfd).magic = o_magic;
379
380   bfd_get_start_address (abfd) = execp->a_entry;
381
382   obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
383   bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
384
385   /* The default relocation entry size is that of traditional V7 Unix.  */
386   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
387
388   /* The default symbol entry size is that of traditional Unix. */
389   obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
390
391   /* create the sections.  This is raunchy, but bfd_close wants to reclaim
392      them */
393
394   obj_textsec (abfd) = bfd_make_section_old_way (abfd, ".text");
395   obj_datasec (abfd) = bfd_make_section_old_way (abfd, ".data");
396   obj_bsssec (abfd) = bfd_make_section_old_way (abfd, ".bss");
397
398 #if 0
399   (void)bfd_make_section (abfd, ".text");
400   (void)bfd_make_section (abfd, ".data");
401   (void)bfd_make_section (abfd, ".bss");
402 #endif
403
404   obj_datasec (abfd)->_raw_size = execp->a_data;
405   obj_bsssec (abfd)->_raw_size = execp->a_bss;
406
407   obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
408        (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC) :
409        (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
410   obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
411        (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC) :
412        (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
413   obj_bsssec (abfd)->flags = SEC_ALLOC;
414
415 #ifdef THIS_IS_ONLY_DOCUMENTATION
416   /* The common code can't fill in these things because they depend
417      on either the start address of the text segment, the rounding
418      up of virtual addersses between segments, or the starting file 
419      position of the text segment -- all of which varies among different
420      versions of a.out.  */
421
422   /* Call back to the format-dependent code to fill in the rest of the 
423      fields and do any further cleanup.  Things that should be filled
424      in by the callback:  */
425
426   struct exec *execp = exec_hdr (abfd);
427
428   obj_textsec (abfd)->size = N_TXTSIZE(*execp);
429   obj_textsec (abfd)->raw_size = N_TXTSIZE(*execp);
430   /* data and bss are already filled in since they're so standard */
431
432   /* The virtual memory addresses of the sections */
433   obj_textsec (abfd)->vma = N_TXTADDR(*execp);
434   obj_datasec (abfd)->vma = N_DATADDR(*execp);
435   obj_bsssec  (abfd)->vma = N_BSSADDR(*execp);
436
437   /* The file offsets of the sections */
438   obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
439   obj_datasec (abfd)->filepos = N_DATOFF(*execp);
440
441   /* The file offsets of the relocation info */
442   obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
443   obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
444
445   /* The file offsets of the string table and symbol table.  */
446   obj_str_filepos (abfd) = N_STROFF (*execp);
447   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
448
449   /* Determine the architecture and machine type of the object file.  */
450   switch (N_MACHTYPE (*exec_hdr (abfd))) {
451   default:
452     abfd->obj_arch = bfd_arch_obscure;
453     break;
454   }
455
456   adata(abfd)->page_size = PAGE_SIZE;
457   adata(abfd)->segment_size = SEGMENT_SIZE;
458   adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
459
460   return abfd->xvec;
461
462   /* The architecture is encoded in various ways in various a.out variants,
463      or is not encoded at all in some of them.  The relocation size depends
464      on the architecture and the a.out variant.  Finally, the return value
465      is the bfd_target vector in use.  If an error occurs, return zero and
466      set bfd_error to the appropriate error code.
467      
468      Formats such as b.out, which have additional fields in the a.out
469      header, should cope with them in this callback as well.  */
470 #endif                          /* DOCUMENTATION */
471
472   result = (*callback_to_real_object_p)(abfd);
473
474   /* Now that the segment addresses have been worked out, take a better
475      guess at whether the file is executable.  If the entry point
476      is within the text segment, assume it is.  (This makes files
477      executable even if their entry point address is 0, as long as
478      their text starts at zero.)  
479
480      At some point we should probably break down and stat the file and
481      declare it executable if (one of) its 'x' bits are on...  */
482   if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
483       (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
484     abfd->flags |= EXEC_P;
485   if (result)
486     {
487       abfd->sections = obj_textsec (abfd);
488       obj_textsec (abfd)->next = obj_datasec (abfd);
489       obj_datasec (abfd)->next = obj_bsssec (abfd);
490     }
491   else
492     {
493       free (rawptr);
494       abfd->tdata.aout_data = oldrawptr;
495     }
496   return result;
497 }
498
499 /*
500 FUNCTION
501         aout_<size>_mkobject
502
503 DESCRIPTION
504         This routine initializes a BFD for use with a.out files.
505
506 EXAMPLE
507         boolean aout_<size>_mkobject, (bfd *);
508 */
509
510 boolean
511 DEFUN(NAME(aout,mkobject),(abfd),
512      bfd *abfd)
513 {
514   struct aout_data_struct  *rawptr;
515
516   bfd_error = system_call_error;
517
518   /* Use an intermediate variable for clarity */
519   rawptr = (struct aout_data_struct  *)bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
520   
521   if (rawptr == NULL) {
522     bfd_error = no_memory;
523     return false;
524   }
525   
526   abfd->tdata.aout_data = rawptr;
527   exec_hdr (abfd) = &(rawptr->e);
528   
529   /* For simplicity's sake we just make all the sections right here. */
530   
531   obj_textsec (abfd) = (asection *)NULL;
532   obj_datasec (abfd) = (asection *)NULL;
533   obj_bsssec (abfd) = (asection *)NULL;
534   bfd_make_section (abfd, ".text");
535   bfd_make_section (abfd, ".data");
536   bfd_make_section (abfd, ".bss");
537   bfd_make_section (abfd, BFD_ABS_SECTION_NAME);
538   bfd_make_section (abfd, BFD_UND_SECTION_NAME);
539   bfd_make_section (abfd, BFD_COM_SECTION_NAME);
540   
541   return true;
542 }
543
544
545 /*
546 FUNCTION
547         aout_<size>_machine_type
548
549 DESCRIPTION
550         Keep track of machine architecture and machine type for
551         a.out's. Return the machine_type for a particular
552         arch&machine, or M_UNKNOWN if that exact arch&machine can't be
553         represented in a.out format. 
554
555         If the architecture is understood, machine type 0 (default)
556         should always be understood.  
557
558 EXAMPLE
559         enum machine_type  aout_<size>_machine_type
560          (enum bfd_architecture arch,
561           unsigned long machine));
562 */
563
564 enum machine_type
565 DEFUN(NAME(aout,machine_type),(arch, machine),
566       enum bfd_architecture arch AND
567       unsigned long machine)
568 {
569   enum machine_type arch_flags;
570     
571   arch_flags = M_UNKNOWN;
572     
573   switch (arch) {
574   case bfd_arch_sparc:
575     if (machine == 0)   arch_flags = M_SPARC;
576     break;
577       
578   case bfd_arch_m68k:
579     switch (machine) {
580     case 0:             arch_flags = M_68010; break;
581     case 68000:         arch_flags = M_UNKNOWN; break;
582     case 68010:         arch_flags = M_68010; break;
583     case 68020:         arch_flags = M_68020; break;
584     default:            arch_flags = M_UNKNOWN; break;
585     }
586     break;
587       
588   case bfd_arch_i386:
589     if (machine == 0)   arch_flags = M_386;
590     break;
591       
592   case bfd_arch_a29k:
593     if (machine == 0)   arch_flags = M_29K;
594     break;
595       
596   default:
597     arch_flags = M_UNKNOWN;
598     break;
599   }
600   return arch_flags;
601 }
602
603
604 /*
605 FUNCTION
606         aout_<size>_set_arch_mach
607
608 DESCRIPTION
609         Sets the architecture and the machine of the BFD to those
610         values supplied. Verifies that the format can support the
611         architecture required.
612
613 EXAMPLE
614         boolean aout_<size>_set_arch_mach,
615          (bfd *,
616           enum bfd_architecture,
617           unsigned long machine));
618 */
619
620 boolean
621 DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
622       bfd *abfd AND
623       enum bfd_architecture arch AND
624       unsigned long machine)
625 {
626   bfd_default_set_arch_mach(abfd, arch, machine);
627   if (arch != bfd_arch_unknown &&
628       NAME(aout,machine_type) (arch, machine) == M_UNKNOWN)
629     return false;               /* We can't represent this type */
630
631   /* Determine the size of a relocation entry */
632   switch (arch) {
633   case bfd_arch_sparc:
634   case bfd_arch_a29k:
635     obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
636     break;
637   default:
638     obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
639     break;
640   }
641
642   return (*aout_backend_info(abfd)->set_sizes) (abfd);
643 }
644
645 boolean
646 DEFUN (NAME (aout,adjust_sizes_and_vmas), (abfd, text_size, text_end),
647        bfd *abfd AND bfd_size_type *text_size AND file_ptr *text_end)
648 {
649   struct internal_exec *execp = exec_hdr (abfd);
650   if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL)) 
651     {
652       bfd_error = invalid_operation;
653       return false;
654     }
655   if (adata(abfd).magic != undecided_magic) return true;
656   obj_textsec(abfd)->_raw_size =              
657     align_power(obj_textsec(abfd)->_raw_size,
658                 obj_textsec(abfd)->alignment_power);
659
660   *text_size = obj_textsec (abfd)->_raw_size;
661   /* Rule (heuristic) for when to pad to a new page.  Note that there
662    * are (at least) two ways demand-paged (ZMAGIC) files have been
663    * handled.  Most Berkeley-based systems start the text segment at
664    * (PAGE_SIZE).  However, newer versions of SUNOS start the text
665    * segment right after the exec header; the latter is counted in the
666    * text segment size, and is paged in by the kernel with the rest of
667    * the text. */
668
669   /* This perhaps isn't the right way to do this, but made it simpler for me
670      to understand enough to implement it.  Better would probably be to go
671      right from BFD flags to alignment/positioning characteristics.  But the
672      old code was sloppy enough about handling the flags, and had enough
673      other magic, that it was a little hard for me to understand.  I think
674      I understand it better now, but I haven't time to do the cleanup this
675      minute.  */
676   if (adata(abfd).magic == undecided_magic)
677     {
678       if (abfd->flags & D_PAGED)
679         /* whether or not WP_TEXT is set */
680         adata(abfd).magic = z_magic;
681       else if (abfd->flags & WP_TEXT)
682         adata(abfd).magic = n_magic;
683       else
684         adata(abfd).magic = o_magic;
685     }
686
687 #ifdef BFD_AOUT_DEBUG /* requires gcc2 */
688 #if __GNUC__ >= 2
689   fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
690            ({ char *str;
691               switch (adata(abfd).magic) {
692               case n_magic: str = "NMAGIC"; break;
693               case o_magic: str = "OMAGIC"; break;
694               case z_magic: str = "ZMAGIC"; break;
695               default: abort ();
696               }
697               str;
698             }),
699            obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size, obj_textsec(abfd)->alignment_power,
700            obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size, obj_datasec(abfd)->alignment_power,
701            obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size, obj_bsssec(abfd)->alignment_power);
702 #endif
703 #endif
704
705   switch (adata(abfd).magic)
706     {
707     case o_magic:
708       {
709         file_ptr pos = adata (abfd).exec_bytes_size;
710         bfd_vma vma = 0;
711         int pad = 0;
712
713         obj_textsec(abfd)->filepos = pos;
714         pos += obj_textsec(abfd)->_raw_size;
715         vma += obj_textsec(abfd)->_raw_size;
716         if (!obj_datasec(abfd)->user_set_vma)
717           {
718 #if 0       /* ?? Does alignment in the file image really matter? */
719             pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma;
720 #endif
721             obj_textsec(abfd)->_raw_size += pad;
722             pos += pad;
723             vma += pad;
724             obj_datasec(abfd)->vma = vma;
725           }
726         obj_datasec(abfd)->filepos = pos;
727         pos += obj_datasec(abfd)->_raw_size;
728         vma += obj_datasec(abfd)->_raw_size;
729         if (!obj_bsssec(abfd)->user_set_vma)
730           {
731 #if 0
732             pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
733 #endif
734             obj_datasec(abfd)->_raw_size += pad;
735             pos += pad;
736             vma += pad;
737             obj_bsssec(abfd)->vma = vma;
738           }
739         obj_bsssec(abfd)->filepos = pos;
740         execp->a_text = obj_textsec(abfd)->_raw_size;
741         execp->a_data = obj_datasec(abfd)->_raw_size;
742         execp->a_bss = obj_bsssec(abfd)->_raw_size;
743         N_SET_MAGIC (*execp, OMAGIC);
744       }
745       break;
746     case z_magic:
747       {
748         bfd_size_type data_pad, text_pad;
749         file_ptr text_end;
750         CONST struct aout_backend_data *abdp;
751         int ztih;
752         bfd_vma data_vma;
753
754         abdp = aout_backend_info (abfd);
755         ztih = abdp && abdp->text_includes_header;
756         obj_textsec(abfd)->filepos = (ztih
757                                       ? adata(abfd).exec_bytes_size
758                                       : adata(abfd).page_size);
759         if (! obj_textsec(abfd)->user_set_vma)
760           /* ?? Do we really need to check for relocs here?  */
761           obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC)
762                                     ? 0
763                                     : (ztih
764                                        ? (abdp->default_text_vma
765                                           + adata(abfd).exec_bytes_size)
766                                        : abdp->default_text_vma));
767         /* Could take strange alignment of text section into account here?  */
768
769         /* Find start of data.  */
770         text_end = obj_textsec(abfd)->filepos + obj_textsec(abfd)->_raw_size;
771         text_pad = BFD_ALIGN (text_end, adata(abfd).page_size) - text_end;
772         obj_textsec(abfd)->_raw_size += text_pad;
773         text_end += text_pad;
774
775         if (!obj_datasec(abfd)->user_set_vma)
776           {
777             bfd_vma vma;
778             vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size;
779             obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
780           }
781         data_vma = obj_datasec(abfd)->vma;
782         if (abdp && abdp->zmagic_mapped_contiguous)
783           {
784             text_pad = (obj_datasec(abfd)->vma
785                         - obj_textsec(abfd)->vma
786                         - obj_textsec(abfd)->_raw_size);
787             obj_textsec(abfd)->_raw_size += text_pad;
788           }
789         obj_datasec(abfd)->filepos = (obj_textsec(abfd)->filepos
790                                       + obj_textsec(abfd)->_raw_size);
791
792         /* Fix up exec header while we're at it.  */
793         execp->a_text = obj_textsec(abfd)->_raw_size;
794         if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
795           execp->a_text += adata(abfd).exec_bytes_size;
796         N_SET_MAGIC (*execp, ZMAGIC);
797         /* Spec says data section should be rounded up to page boundary.  */
798         /* If extra space in page is left after data section, fudge data
799            in the header so that the bss section looks smaller by that
800            amount.  We'll start the bss section there, and lie to the OS.  */
801         obj_datasec(abfd)->_raw_size
802           = align_power (obj_datasec(abfd)->_raw_size,
803                          obj_bsssec(abfd)->alignment_power);
804         execp->a_data = BFD_ALIGN (obj_datasec(abfd)->_raw_size,
805                                    adata(abfd).page_size);
806         data_pad = execp->a_data - obj_datasec(abfd)->_raw_size;
807         /* This code is almost surely botched.  It'll only get tested
808            for the case where the application does explicitly set the VMA
809            of the BSS section.  */
810         if (obj_bsssec(abfd)->user_set_vma
811             && (obj_bsssec(abfd)->vma
812                 > BFD_ALIGN (obj_datasec(abfd)->vma
813                              + obj_datasec(abfd)->_raw_size,
814                              adata(abfd).page_size)))
815           {
816             /* Can't play with squeezing into data pages; fix this code.  */
817             abort ();
818           }
819         if (!obj_bsssec(abfd)->user_set_vma)
820           obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
821                                    + obj_datasec(abfd)->_raw_size);
822         if (data_pad > obj_bsssec(abfd)->_raw_size)
823           execp->a_bss = 0;
824         else
825           execp->a_bss = obj_bsssec(abfd)->_raw_size - data_pad;
826       }
827       break;
828     case n_magic:
829       {
830         CONST struct aout_backend_data *abdp;
831         file_ptr pos = adata(abfd).exec_bytes_size;
832         bfd_vma vma = 0;
833         int pad;
834
835         obj_textsec(abfd)->filepos = pos;
836         if (!obj_textsec(abfd)->user_set_vma)
837           obj_textsec(abfd)->vma = vma;
838         else
839           vma = obj_textsec(abfd)->vma;
840         pos += obj_textsec(abfd)->_raw_size;
841         vma += obj_textsec(abfd)->_raw_size;
842         obj_datasec(abfd)->filepos = pos;
843         if (!obj_datasec(abfd)->user_set_vma)
844           obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
845         vma = obj_datasec(abfd)->vma;
846
847         /* Since BSS follows data immediately, see if it needs alignment.  */
848         vma += obj_datasec(abfd)->_raw_size;
849         pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
850         obj_datasec(abfd)->_raw_size += pad;
851         pos += obj_datasec(abfd)->_raw_size;
852
853         if (!obj_bsssec(abfd)->user_set_vma)
854           obj_bsssec(abfd)->vma = vma;
855         else
856           vma = obj_bsssec(abfd)->vma;
857       }
858       execp->a_text = obj_textsec(abfd)->_raw_size;
859       execp->a_data = obj_datasec(abfd)->_raw_size;
860       execp->a_bss = obj_bsssec(abfd)->_raw_size;
861       N_SET_MAGIC (*execp, NMAGIC);
862       break;
863     default:
864       abort ();
865     }
866 #ifdef BFD_AOUT_DEBUG
867   fprintf (stderr, "       text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
868            obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size, obj_textsec(abfd)->filepos,
869            obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size, obj_datasec(abfd)->filepos,
870            obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size);
871 #endif
872   return true;
873 }
874
875 /*
876 FUNCTION
877         aout_<size>new_section_hook
878   
879 DESCRIPTION
880         Called by the BFD in response to a @code{bfd_make_section}
881         request.
882
883 EXAMPLE
884         boolean aout_<size>_new_section_hook,
885            (bfd *abfd,
886             asection *newsect));
887 */
888 boolean
889 DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
890         bfd *abfd AND
891         asection *newsect)
892 {
893   /* align to double at least */
894   newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
895
896     
897   if (bfd_get_format (abfd) == bfd_object) 
898   {
899     if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
900         obj_textsec(abfd)= newsect;
901         newsect->target_index = N_TEXT | N_EXT;
902         return true;
903       }
904       
905     if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
906         obj_datasec(abfd) = newsect;
907         newsect->target_index = N_DATA | N_EXT;
908         return true;
909       }
910       
911     if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
912         obj_bsssec(abfd) = newsect;
913         newsect->target_index = N_BSS | N_EXT;
914         return true;
915       }
916
917   }
918     
919   /* We allow more than three sections internally */
920   return true;
921 }
922
923 boolean
924   DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
925         bfd *abfd AND
926         sec_ptr section AND
927         PTR location AND
928         file_ptr offset AND
929         bfd_size_type count)
930 {
931   file_ptr text_end;
932   bfd_size_type text_size;
933
934   if (abfd->output_has_begun == false)
935       {                         /* set by bfd.c handler */
936         switch (abfd->direction)
937             {
938             case read_direction:
939             case no_direction:
940               bfd_error = invalid_operation;
941               return false;
942
943             case write_direction:
944               if (NAME(aout,adjust_sizes_and_vmas) (abfd,
945                                                     &text_size,
946                                                     &text_end) == false)
947                 return false;
948             case both_direction:
949               break;
950             }
951       }
952
953   /* regardless, once we know what we're doing, we might as well get going */
954   if (section != obj_bsssec(abfd)) 
955       {
956         bfd_seek (abfd, section->filepos + offset, SEEK_SET);
957     
958         if (count) {
959           return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
960             true : false;
961         }
962         return true;
963       }
964   return true;
965 }
966 \f
967 /* Classify stabs symbols */
968
969 #define sym_in_text_section(sym) \
970   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
971
972 #define sym_in_data_section(sym) \
973   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
974
975 #define sym_in_bss_section(sym) \
976   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
977
978 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
979   zero in the "value" field.  Nonzeroes there are fortrancommon
980   symbols.  */
981 #define sym_is_undefined(sym) \
982   ((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
983
984 /* Symbol is a global definition if N_EXT is on and if it has
985   a nonzero type field.  */
986 #define sym_is_global_defn(sym) \
987   (((sym)->type & N_EXT) && (sym)->type & N_TYPE)
988
989 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
990   are on.  */
991 #define sym_is_debugger_info(sym) \
992   ((sym)->type & ~(N_EXT | N_TYPE))
993
994 #define sym_is_fortrancommon(sym)       \
995   (((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
996
997 /* Symbol is absolute if it has N_ABS set */
998 #define sym_is_absolute(sym) \
999   (((sym)->type  & N_TYPE)== N_ABS)
1000
1001
1002 #define sym_is_indirect(sym) \
1003   (((sym)->type & N_ABS)== N_ABS)
1004
1005 /* Only in their own functions for ease of debugging; when sym flags have
1006   stabilised these should be inlined into their (single) caller */
1007   
1008 static void
1009 DEFUN(translate_from_native_sym_flags,(sym_pointer, cache_ptr, abfd),
1010       struct external_nlist *sym_pointer AND
1011       aout_symbol_type *cache_ptr AND
1012       bfd *abfd)
1013 {
1014   switch (cache_ptr->type & N_TYPE) 
1015   {
1016   case N_SETA:
1017   case N_SETT:
1018   case N_SETD:
1019   case N_SETB:
1020   {
1021     char *copy = bfd_alloc(abfd, strlen(cache_ptr->symbol.name)+1);
1022     asection *section ;
1023     asection *into_section;
1024       
1025     arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
1026     strcpy(copy, cache_ptr->symbol.name);
1027
1028     /* Make sure that this bfd has a section with the right contructor
1029        name */
1030     section = bfd_get_section_by_name (abfd, copy);
1031     if (!section)
1032      section = bfd_make_section(abfd,copy);
1033
1034     /* Build a relocation entry for the constructor */
1035     switch ( (cache_ptr->type  & N_TYPE) ) 
1036     {
1037     case N_SETA:
1038       into_section = &bfd_abs_section;
1039       break;
1040     case N_SETT:
1041       into_section = (asection *)obj_textsec(abfd);
1042       break;
1043     case N_SETD:
1044       into_section = (asection *)obj_datasec(abfd);
1045       break;
1046     case N_SETB:
1047       into_section = (asection *)obj_bsssec(abfd);
1048       break;
1049     default:
1050       abort();
1051     }
1052
1053     /* Build a relocation pointing into the constuctor section
1054        pointing at the symbol in the set vector specified */
1055
1056     reloc->relent.addend = cache_ptr->symbol.value;
1057     cache_ptr->symbol.section =  into_section->symbol->section;
1058     reloc->relent.sym_ptr_ptr  = into_section->symbol_ptr_ptr;
1059
1060           
1061     /* We modify the symbol to belong to a section depending upon the
1062        name of the symbol - probably __CTOR__ or __DTOR__ but we don't
1063        really care, and add to the size of the section to contain a
1064        pointer to the symbol. Build a reloc entry to relocate to this
1065        symbol attached to this section.  */
1066           
1067     section->flags = SEC_CONSTRUCTOR;
1068
1069           
1070     section->reloc_count++;
1071     section->alignment_power = 2;
1072
1073     reloc->next = section->constructor_chain;
1074     section->constructor_chain = reloc;
1075     reloc->relent.address = section->_raw_size;
1076     section->_raw_size += sizeof(int *);
1077
1078     reloc->relent.howto = howto_table_ext + CTOR_TABLE_RELOC_IDX;
1079     cache_ptr->symbol.flags |=  BSF_DEBUGGING  | BSF_CONSTRUCTOR;
1080   }
1081     break;
1082   default:
1083     if (cache_ptr->type ==  N_WARNING) 
1084     {
1085       /* This symbol is the text of a warning message, the next symbol
1086          is the symbol to associate the warning with */
1087       cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
1088       cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
1089       /* We furgle with the next symbol in place. We don't want it to be undefined, we'll trample the type */
1090       (sym_pointer+1)->e_type[0] = 0xff;
1091       break;
1092     }
1093     if ((cache_ptr->type | N_EXT) == (N_INDR | N_EXT)) {
1094         /* Two symbols in a row for an INDR message. The first symbol
1095            contains the name we will match, the second symbol contains the
1096            name the first name is translated into. It is supplied to us
1097            undefined. This is good, since we want to pull in any files which
1098            define it */
1099         cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT;
1100         cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
1101         cache_ptr->symbol.section = &bfd_und_section;
1102         break;
1103       }
1104
1105       
1106     if (sym_is_debugger_info (cache_ptr)) {
1107         cache_ptr->symbol.flags = BSF_DEBUGGING ;
1108         /* Work out the section correct for this symbol */
1109         switch (cache_ptr->type & N_TYPE) 
1110         {
1111         case N_TEXT:
1112         case N_FN:
1113           cache_ptr->symbol.section = obj_textsec (abfd);
1114           cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
1115           break;
1116         case N_DATA:
1117           cache_ptr->symbol.value  -= obj_datasec(abfd)->vma;
1118           cache_ptr->symbol.section = obj_datasec (abfd);
1119           break;
1120         case N_BSS :
1121           cache_ptr->symbol.section = obj_bsssec (abfd);
1122           cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
1123           break;
1124         default:
1125         case N_ABS:
1126
1127           cache_ptr->symbol.section = &bfd_abs_section;
1128           break;
1129         }
1130       }
1131     else {
1132
1133         if (sym_is_fortrancommon (cache_ptr))
1134         {
1135           cache_ptr->symbol.flags = 0;
1136           cache_ptr->symbol.section = &bfd_com_section;
1137         }
1138         else {
1139
1140
1141           }
1142           
1143         /* In a.out, the value of a symbol is always relative to the 
1144          * start of the file, if this is a data symbol we'll subtract
1145          * the size of the text section to get the section relative
1146          * value. If this is a bss symbol (which would be strange)
1147          * we'll subtract the size of the previous two sections
1148          * to find the section relative address.
1149          */
1150           
1151         if (sym_in_text_section (cache_ptr))   {
1152             cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
1153             cache_ptr->symbol.section = obj_textsec (abfd);
1154           }
1155         else if (sym_in_data_section (cache_ptr)){
1156             cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
1157             cache_ptr->symbol.section = obj_datasec (abfd);
1158           }
1159         else if (sym_in_bss_section(cache_ptr)) {
1160             cache_ptr->symbol.section = obj_bsssec (abfd);
1161             cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
1162           }
1163         else  if (sym_is_undefined (cache_ptr)) {
1164             cache_ptr->symbol.flags = 0;
1165             cache_ptr->symbol.section = &bfd_und_section;
1166           }
1167         else if (sym_is_absolute(cache_ptr))
1168         {
1169           cache_ptr->symbol.section = &bfd_abs_section;
1170         }
1171             
1172         if (sym_is_global_defn (cache_ptr)) 
1173         {
1174           cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1175         } 
1176         else 
1177         {
1178           cache_ptr->symbol.flags = BSF_LOCAL;
1179         }
1180       }
1181   }
1182 }
1183
1184
1185
1186 static void
1187 DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
1188      struct external_nlist *sym_pointer AND
1189      asymbol *cache_ptr AND
1190      bfd *abfd)
1191 {
1192   bfd_vma value = cache_ptr->value;
1193
1194   /* mask out any existing type bits in case copying from one section
1195      to another */
1196   sym_pointer->e_type[0] &= ~N_TYPE;
1197   
1198   if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
1199       sym_pointer->e_type[0] |= N_BSS;
1200     }
1201   else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
1202       sym_pointer->e_type[0] |= N_DATA;
1203     }
1204   else  if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
1205       sym_pointer->e_type[0] |= N_TEXT;
1206     }
1207   else if (bfd_get_output_section(cache_ptr) == &bfd_abs_section) 
1208   {
1209     sym_pointer->e_type[0] |= N_ABS;
1210   }
1211   else if (bfd_get_output_section(cache_ptr) == &bfd_und_section) 
1212   {
1213     sym_pointer->e_type[0] = (N_UNDF | N_EXT);
1214   }
1215   else if (bfd_get_output_section(cache_ptr) == &bfd_com_section) {
1216       sym_pointer->e_type[0] = (N_UNDF | N_EXT);
1217     }    
1218   else {    
1219       if (cache_ptr->section->output_section) 
1220       {
1221         
1222         bfd_error_vector.nonrepresentable_section(abfd,
1223                                                   bfd_get_output_section(cache_ptr)->name);
1224       }
1225       else 
1226       {
1227         bfd_error_vector.nonrepresentable_section(abfd,
1228                                                   cache_ptr->section->name);
1229         
1230       }
1231       
1232     }
1233   /* Turn the symbol from section relative to absolute again */
1234     
1235   value +=  cache_ptr->section->output_section->vma  + cache_ptr->section->output_offset ;
1236
1237
1238   if (cache_ptr->flags & (BSF_WARNING)) {
1239       (sym_pointer+1)->e_type[0] = 1;
1240     }  
1241     
1242   if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1243       sym_pointer->e_type[0] |= N_EXT;
1244     }
1245   if (cache_ptr->flags & BSF_DEBUGGING) {
1246       sym_pointer->e_type [0]= ((aout_symbol_type *)cache_ptr)->type;
1247     }
1248
1249   PUT_WORD(abfd, value, sym_pointer->e_value);
1250 }
1251 \f
1252 /* Native-level interface to symbols. */
1253
1254 /* We read the symbols into a buffer, which is discarded when this
1255 function exits.  We read the strings into a buffer large enough to
1256 hold them all plus all the cached symbol entries. */
1257
1258 asymbol *
1259 DEFUN(NAME(aout,make_empty_symbol),(abfd),
1260       bfd *abfd)
1261 {
1262   aout_symbol_type  *new =
1263     (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1264   new->symbol.the_bfd = abfd;
1265     
1266   return &new->symbol;
1267 }
1268
1269 boolean
1270 DEFUN(NAME(aout,slurp_symbol_table),(abfd),
1271       bfd *abfd)
1272 {
1273   bfd_size_type symbol_size;
1274   bfd_size_type string_size;
1275   unsigned char string_chars[BYTES_IN_WORD];
1276   struct external_nlist *syms;
1277   char *strings;
1278   aout_symbol_type *cached;
1279     
1280   /* If there's no work to be done, don't do any */
1281   if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1282   symbol_size = exec_hdr(abfd)->a_syms;
1283   if (symbol_size == 0) {
1284     bfd_error = no_symbols;
1285     return false;
1286   }
1287     
1288   bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1289   if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
1290     return false;
1291   string_size = GET_WORD (abfd, string_chars);
1292     
1293   strings =(char *) bfd_alloc(abfd, string_size + 1);
1294   cached = (aout_symbol_type *)
1295     bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
1296
1297   /* malloc this, so we can free it if simply. The symbol caching
1298      might want to allocate onto the bfd's obstack  */
1299   syms = (struct external_nlist *) bfd_xmalloc(symbol_size);
1300   bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1301   if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
1302   bailout:
1303     if (syms)   free (syms);
1304     if (cached) bfd_release (abfd, cached);
1305     if (strings)bfd_release (abfd, strings);
1306     return false;
1307   }
1308     
1309   bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1310   if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
1311     goto bailout;
1312   }
1313     
1314   /* OK, now walk the new symtable, cacheing symbol properties */
1315     {
1316       register struct external_nlist *sym_pointer;
1317       register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
1318       register aout_symbol_type *cache_ptr = cached;
1319         
1320       /* Run through table and copy values */
1321       for (sym_pointer = syms, cache_ptr = cached;
1322            sym_pointer < sym_end; sym_pointer++, cache_ptr++) 
1323           {
1324             bfd_vma x = GET_WORD(abfd, sym_pointer->e_strx);
1325             cache_ptr->symbol.the_bfd = abfd;
1326             if (x)
1327               cache_ptr->symbol.name = x + strings;
1328             else
1329               cache_ptr->symbol.name = (char *)NULL;
1330               
1331             cache_ptr->symbol.value = GET_SWORD(abfd,  sym_pointer->e_value);
1332             cache_ptr->desc = bfd_h_get_16(abfd, sym_pointer->e_desc);
1333             cache_ptr->other = bfd_h_get_8(abfd, sym_pointer->e_other);
1334             cache_ptr->type = bfd_h_get_8(abfd,  sym_pointer->e_type);
1335             cache_ptr->symbol.udata = 0;
1336             translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1337           }
1338     }
1339     
1340   obj_aout_symbols (abfd) =  cached;
1341   free((PTR)syms);
1342     
1343   return true;
1344 }
1345
1346
1347 void
1348 DEFUN(NAME(aout,write_syms),(abfd),
1349       bfd *abfd)
1350   {
1351     unsigned int count ;
1352     asymbol **generic = bfd_get_outsymbols (abfd);
1353     
1354     bfd_size_type stindex = BYTES_IN_WORD; /* initial string length */
1355     
1356     for (count = 0; count < bfd_get_symcount (abfd); count++) {
1357       asymbol *g = generic[count];
1358       struct external_nlist nsp;
1359
1360
1361       if (g->name) {
1362         unsigned int length = strlen(g->name) +1;
1363         PUT_WORD  (abfd, stindex, (unsigned char *)nsp.e_strx);
1364         stindex += length;
1365       }
1366       else 
1367
1368       {
1369         PUT_WORD  (abfd, 0, (unsigned char *)nsp.e_strx);
1370       }
1371       
1372       if (g->the_bfd->xvec->flavour == abfd->xvec->flavour) 
1373           {
1374             bfd_h_put_16(abfd, aout_symbol(g)->desc,  nsp.e_desc);
1375             bfd_h_put_8(abfd, aout_symbol(g)->other,  nsp.e_other);
1376             bfd_h_put_8(abfd, aout_symbol(g)->type,  nsp.e_type);
1377           }
1378       else
1379           {
1380             bfd_h_put_16(abfd,0, nsp.e_desc);
1381             bfd_h_put_8(abfd, 0,  nsp.e_other);
1382             bfd_h_put_8(abfd, 0,  nsp.e_type);
1383           }
1384
1385       translate_to_native_sym_flags (&nsp, g, abfd);
1386
1387       bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd);
1388     }
1389     
1390     /* Now output the strings.  Be sure to put string length into correct
1391        byte ordering before writing it.  */
1392       {
1393         char buffer[BYTES_IN_WORD];
1394         PUT_WORD  (abfd, stindex, (unsigned char *)buffer);
1395     
1396         bfd_write((PTR)buffer, 1, BYTES_IN_WORD, abfd);
1397       }
1398     generic = bfd_get_outsymbols(abfd);
1399     for (count = 0; count < bfd_get_symcount(abfd); count++) 
1400         {
1401           asymbol *g = *(generic++);
1402           
1403           if (g->name)
1404               {
1405                 size_t length = strlen(g->name)+1;
1406                 bfd_write((PTR)g->name, 1, length, abfd);
1407               }
1408             g->KEEPIT = (KEEPITTYPE) count;
1409         }
1410   }
1411
1412
1413
1414 unsigned int
1415 DEFUN(NAME(aout,get_symtab),(abfd, location),
1416       bfd *abfd AND
1417       asymbol **location)
1418 {
1419     unsigned int counter = 0;
1420     aout_symbol_type *symbase;
1421
1422     if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1423
1424     for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1425       *(location++) = (asymbol *)( symbase++);
1426     *location++ =0;
1427     return bfd_get_symcount (abfd);
1428 }
1429
1430 \f
1431 /* Standard reloc stuff */
1432 /* Output standard relocation information to a file in target byte order. */
1433
1434 void
1435 DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1436       bfd *abfd AND
1437       arelent *g AND
1438       struct reloc_std_external *natptr)
1439 {
1440   int r_index;
1441   asymbol *sym = *(g->sym_ptr_ptr);
1442   int r_extern;
1443   unsigned int r_length;
1444   int r_pcrel;
1445   int r_baserel, r_jmptable, r_relative;
1446   unsigned int r_addend;
1447   asection *output_section = sym->section->output_section;
1448
1449   PUT_WORD(abfd, g->address, natptr->r_address);
1450
1451   r_length = g->howto->size ;   /* Size as a power of two */
1452   r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC? */
1453   /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
1454   r_baserel = 0;
1455   r_jmptable = 0;
1456   r_relative = 0;
1457     
1458   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1459     
1460   /* name was clobbered by aout_write_syms to be symbol index */
1461
1462   /* If this relocation is relative to a symbol then set the 
1463      r_index to the symbols index, and the r_extern bit.
1464
1465      Absolute symbols can come in in two ways, either as an offset
1466      from the abs section, or as a symbol which has an abs value.
1467      check for that here
1468      */
1469      
1470
1471   if (output_section == &bfd_com_section 
1472       || output_section == &bfd_abs_section
1473       || output_section == &bfd_und_section) 
1474     {
1475       if (bfd_abs_section.symbol == sym)
1476       {
1477         /* Whoops, looked like an abs symbol, but is really an offset
1478            from the abs section */
1479         r_index = 0;
1480         r_extern = 0;
1481        }
1482       else 
1483       {
1484         /* Fill in symbol */
1485         r_extern = 1;
1486         r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
1487      
1488       }
1489     }
1490   else 
1491     {
1492       /* Just an ordinary section */
1493       r_extern = 0;
1494       r_index  = output_section->target_index;      
1495     }
1496
1497   /* now the fun stuff */
1498   if (abfd->xvec->header_byteorder_big_p != false) {
1499       natptr->r_index[0] = r_index >> 16;
1500       natptr->r_index[1] = r_index >> 8;
1501       natptr->r_index[2] = r_index;
1502       natptr->r_type[0] =
1503        (r_extern?    RELOC_STD_BITS_EXTERN_BIG: 0)
1504         | (r_pcrel?     RELOC_STD_BITS_PCREL_BIG: 0)
1505          | (r_baserel?   RELOC_STD_BITS_BASEREL_BIG: 0)
1506           | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_BIG: 0)
1507            | (r_relative?  RELOC_STD_BITS_RELATIVE_BIG: 0)
1508             | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG);
1509     } else {
1510         natptr->r_index[2] = r_index >> 16;
1511         natptr->r_index[1] = r_index >> 8;
1512         natptr->r_index[0] = r_index;
1513         natptr->r_type[0] =
1514          (r_extern?    RELOC_STD_BITS_EXTERN_LITTLE: 0)
1515           | (r_pcrel?     RELOC_STD_BITS_PCREL_LITTLE: 0)
1516            | (r_baserel?   RELOC_STD_BITS_BASEREL_LITTLE: 0)
1517             | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1518              | (r_relative?  RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1519               | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE);
1520       }
1521 }
1522
1523
1524 /* Extended stuff */
1525 /* Output extended relocation information to a file in target byte order. */
1526
1527 void
1528 DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
1529       bfd *abfd AND
1530       arelent *g AND
1531       register struct reloc_ext_external *natptr)
1532 {
1533   int r_index;
1534   int r_extern;
1535   unsigned int r_type;
1536   unsigned int r_addend;
1537   asymbol *sym = *(g->sym_ptr_ptr);    
1538   asection *output_section = sym->section->output_section;
1539   
1540   PUT_WORD (abfd, g->address, natptr->r_address);
1541     
1542   r_type = (unsigned int) g->howto->type;
1543     
1544   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1545
1546
1547   /* If this relocation is relative to a symbol then set the 
1548      r_index to the symbols index, and the r_extern bit.
1549
1550      Absolute symbols can come in in two ways, either as an offset
1551      from the abs section, or as a symbol which has an abs value.
1552      check for that here
1553      */
1554      
1555   if (output_section == &bfd_com_section 
1556       || output_section == &bfd_abs_section
1557       || output_section == &bfd_und_section) 
1558   {
1559     if (bfd_abs_section.symbol == sym)
1560     {
1561       /* Whoops, looked like an abs symbol, but is really an offset
1562          from the abs section */
1563       r_index = 0;
1564       r_extern = 0;
1565      }
1566     else 
1567     {
1568       r_extern = 1;
1569       r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
1570     }
1571   }
1572   else 
1573   {
1574     /* Just an ordinary section */
1575     r_extern = 0;
1576     r_index  = output_section->target_index;      
1577   }
1578          
1579          
1580   /* now the fun stuff */
1581   if (abfd->xvec->header_byteorder_big_p != false) {
1582     natptr->r_index[0] = r_index >> 16;
1583     natptr->r_index[1] = r_index >> 8;
1584     natptr->r_index[2] = r_index;
1585     natptr->r_type[0] =
1586      (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1587       | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1588   } else {
1589     natptr->r_index[2] = r_index >> 16;
1590     natptr->r_index[1] = r_index >> 8;
1591     natptr->r_index[0] = r_index;
1592     natptr->r_type[0] =
1593      (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1594       | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1595   }
1596
1597   PUT_WORD (abfd, r_addend, natptr->r_addend);
1598 }
1599
1600 /* BFD deals internally with all things based from the section they're
1601    in. so, something in 10 bytes into a text section  with a base of
1602    50 would have a symbol (.text+10) and know .text vma was 50. 
1603
1604    Aout keeps all it's symbols based from zero, so the symbol would
1605    contain 60. This macro subs the base of each section from the value
1606    to give the true offset from the section */
1607
1608
1609 #define MOVE_ADDRESS(ad)                                                \
1610   if (r_extern) {                                                       \
1611    /* undefined symbol */                                               \
1612      cache_ptr->sym_ptr_ptr = symbols + r_index;                        \
1613      cache_ptr->addend = ad;                                            \
1614      } else {                                                           \
1615     /* defined, section relative. replace symbol with pointer to        \
1616        symbol which points to section  */                               \
1617     switch (r_index) {                                                  \
1618     case N_TEXT:                                                        \
1619     case N_TEXT | N_EXT:                                                \
1620       cache_ptr->sym_ptr_ptr  = obj_textsec(abfd)->symbol_ptr_ptr;      \
1621       cache_ptr->addend = ad  - su->textsec->vma;                       \
1622       break;                                                            \
1623     case N_DATA:                                                        \
1624     case N_DATA | N_EXT:                                                \
1625       cache_ptr->sym_ptr_ptr  = obj_datasec(abfd)->symbol_ptr_ptr;      \
1626       cache_ptr->addend = ad - su->datasec->vma;                        \
1627       break;                                                            \
1628     case N_BSS:                                                         \
1629     case N_BSS | N_EXT:                                                 \
1630       cache_ptr->sym_ptr_ptr  = obj_bsssec(abfd)->symbol_ptr_ptr;       \
1631       cache_ptr->addend = ad - su->bsssec->vma;                         \
1632       break;                                                            \
1633     default:                                                            \
1634     case N_ABS:                                                         \
1635     case N_ABS | N_EXT:                                                 \
1636      cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;   \
1637       cache_ptr->addend = ad;                                           \
1638       break;                                                            \
1639     }                                                                   \
1640   }                                                                     \
1641
1642 void
1643 DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
1644       bfd *abfd AND
1645       struct reloc_ext_external *bytes AND
1646       arelent *cache_ptr AND
1647       asymbol **symbols)
1648 {
1649   int r_index;
1650   int r_extern;
1651   unsigned int r_type;
1652   struct aoutdata *su = &(abfd->tdata.aout_data->a);
1653
1654   cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
1655
1656   /* now the fun stuff */
1657   if (abfd->xvec->header_byteorder_big_p != false) {
1658     r_index =  (bytes->r_index[0] << 16)
1659              | (bytes->r_index[1] << 8)
1660              |  bytes->r_index[2];
1661     r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
1662     r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
1663                                       >> RELOC_EXT_BITS_TYPE_SH_BIG;
1664   } else {
1665     r_index =  (bytes->r_index[2] << 16)
1666              | (bytes->r_index[1] << 8)
1667              |  bytes->r_index[0];
1668     r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1669     r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1670                                       >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1671   }
1672
1673   cache_ptr->howto =  howto_table_ext + r_type;
1674   MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
1675 }
1676
1677 void
1678 DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
1679   bfd *abfd AND
1680   struct reloc_std_external *bytes AND
1681   arelent *cache_ptr AND
1682   asymbol **symbols)
1683 {
1684   int r_index;
1685   int r_extern;
1686   unsigned int r_length;
1687   int r_pcrel;
1688   int r_baserel, r_jmptable, r_relative;
1689   struct aoutdata  *su = &(abfd->tdata.aout_data->a);
1690
1691   cache_ptr->address = (int32_type)(bfd_h_get_32 (abfd, bytes->r_address));
1692
1693   /* now the fun stuff */
1694   if (abfd->xvec->header_byteorder_big_p != false) {
1695     r_index =  (bytes->r_index[0] << 16)
1696       | (bytes->r_index[1] << 8)
1697         |  bytes->r_index[2];
1698     r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
1699     r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
1700     r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
1701     r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1702     r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
1703     r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) 
1704                         >> RELOC_STD_BITS_LENGTH_SH_BIG;
1705   } else {
1706     r_index =  (bytes->r_index[2] << 16)
1707       | (bytes->r_index[1] << 8)
1708         |  bytes->r_index[0];
1709     r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1710     r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
1711     r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1712     r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1713     r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1714     r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) 
1715                         >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1716   }
1717
1718   cache_ptr->howto =  howto_table_std + r_length + 4 * r_pcrel;
1719   /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
1720
1721   MOVE_ADDRESS(0);
1722 }
1723
1724 /* Reloc hackery */
1725
1726 boolean
1727 DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
1728       bfd *abfd AND
1729       sec_ptr asect AND
1730       asymbol **symbols)
1731 {
1732   unsigned int count;
1733   bfd_size_type reloc_size;
1734   PTR relocs;
1735   arelent *reloc_cache;
1736   size_t each_size;
1737
1738   if (asect->relocation) return true;
1739
1740   if (asect->flags & SEC_CONSTRUCTOR) return true;
1741
1742   if (asect == obj_datasec (abfd)) {
1743     reloc_size = exec_hdr(abfd)->a_drsize;
1744     goto doit;
1745   }
1746
1747   if (asect == obj_textsec (abfd)) {
1748     reloc_size = exec_hdr(abfd)->a_trsize;
1749     goto doit;
1750   }
1751
1752   bfd_error = invalid_operation;
1753   return false;
1754
1755  doit:
1756   bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1757   each_size = obj_reloc_entry_size (abfd);
1758
1759   count = reloc_size / each_size;
1760
1761
1762   reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1763                                                        (arelent)));
1764   if (!reloc_cache) {
1765 nomem:
1766     bfd_error = no_memory;
1767     return false;
1768   }
1769
1770   relocs = (PTR) bfd_alloc (abfd, reloc_size);
1771   if (!relocs) {
1772     bfd_release (abfd, reloc_cache);
1773     goto nomem;
1774   }
1775
1776   if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1777     bfd_release (abfd, relocs);
1778     bfd_release (abfd, reloc_cache);
1779     bfd_error = system_call_error;
1780     return false;
1781   }
1782
1783   if (each_size == RELOC_EXT_SIZE) {
1784     register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
1785     unsigned int counter = 0;
1786     arelent *cache_ptr = reloc_cache;
1787
1788     for (; counter < count; counter++, rptr++, cache_ptr++) {
1789       NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
1790     }
1791   } else {
1792     register struct reloc_std_external *rptr = (struct reloc_std_external*) relocs;
1793     unsigned int counter = 0;
1794     arelent *cache_ptr = reloc_cache;
1795
1796     for (; counter < count; counter++, rptr++, cache_ptr++) {
1797         NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
1798     }
1799
1800   }
1801
1802   bfd_release (abfd,relocs);
1803   asect->relocation = reloc_cache;
1804   asect->reloc_count = count;
1805   return true;
1806 }
1807
1808
1809
1810 /* Write out a relocation section into an object file.  */
1811
1812 boolean
1813 DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
1814       bfd *abfd AND
1815       asection *section)
1816 {
1817   arelent **generic;
1818   unsigned char *native, *natptr;
1819   size_t each_size;
1820
1821   unsigned int count = section->reloc_count;
1822   size_t natsize;
1823
1824   if (count == 0) return true;
1825
1826   each_size = obj_reloc_entry_size (abfd);
1827   natsize = each_size * count;
1828   native = (unsigned char *) bfd_zalloc (abfd, natsize);
1829   if (!native) {
1830     bfd_error = no_memory;
1831     return false;
1832   }
1833
1834   generic = section->orelocation;
1835
1836   if (each_size == RELOC_EXT_SIZE) 
1837     {
1838       for (natptr = native;
1839            count != 0;
1840            --count, natptr += each_size, ++generic)
1841         NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
1842     }
1843   else 
1844     {
1845       for (natptr = native;
1846            count != 0;
1847            --count, natptr += each_size, ++generic)
1848         NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
1849     }
1850
1851   if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1852     bfd_release(abfd, native);
1853     return false;
1854   }
1855   bfd_release (abfd, native);
1856
1857   return true;
1858 }
1859
1860 /* This is stupid.  This function should be a boolean predicate */
1861 unsigned int
1862 DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
1863       bfd *abfd AND
1864       sec_ptr section AND
1865       arelent **relptr AND
1866       asymbol **symbols)
1867 {
1868   arelent *tblptr = section->relocation;
1869   unsigned int count;
1870
1871   if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
1872     return 0;
1873
1874   if (section->flags & SEC_CONSTRUCTOR) {
1875     arelent_chain *chain = section->constructor_chain;
1876     for (count = 0; count < section->reloc_count; count ++) {
1877       *relptr ++ = &chain->relent;
1878       chain = chain->next;
1879     }
1880   }
1881   else {
1882     tblptr = section->relocation;
1883     if (!tblptr) return 0;
1884
1885     for (count = 0; count++ < section->reloc_count;) 
1886       {
1887         *relptr++ = tblptr++;
1888       }
1889   }
1890   *relptr = 0;
1891
1892   return section->reloc_count;
1893 }
1894
1895 unsigned int
1896 DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
1897      bfd *abfd AND
1898      sec_ptr asect)
1899 {
1900   if (bfd_get_format (abfd) != bfd_object) {
1901     bfd_error = invalid_operation;
1902     return 0;
1903   }
1904   if (asect->flags & SEC_CONSTRUCTOR) {
1905     return (sizeof (arelent *) * (asect->reloc_count+1));
1906   }
1907
1908
1909   if (asect == obj_datasec (abfd))
1910     return (sizeof (arelent *) *
1911             ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
1912              +1));
1913
1914   if (asect == obj_textsec (abfd))
1915     return (sizeof (arelent *) *
1916             ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
1917              +1));
1918
1919   bfd_error = invalid_operation;
1920   return 0;
1921 }
1922
1923 \f
1924  unsigned int
1925 DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
1926      bfd *abfd)
1927 {
1928   if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1929
1930   return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1931 }
1932  alent *
1933 DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
1934       bfd *ignore_abfd AND
1935       asymbol *ignore_symbol)
1936 {
1937 return (alent *)NULL;
1938 }
1939
1940
1941 void 
1942 DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
1943       bfd *ignore_abfd AND
1944       PTR afile AND
1945       asymbol *symbol AND
1946       bfd_print_symbol_type how)
1947 {
1948   FILE *file = (FILE *)afile;
1949
1950   switch (how) {
1951   case bfd_print_symbol_name:
1952     if (symbol->name)
1953       fprintf(file,"%s", symbol->name);
1954     break;
1955   case bfd_print_symbol_more:
1956     fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1957             (unsigned)(aout_symbol(symbol)->other & 0xff),
1958             (unsigned)(aout_symbol(symbol)->type));
1959     break;
1960   case bfd_print_symbol_all:
1961     {
1962    CONST char *section_name = symbol->section->name;
1963
1964
1965       bfd_print_symbol_vandf((PTR)file,symbol);
1966
1967       fprintf(file," %-5s %04x %02x %02x",
1968               section_name,
1969               (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1970               (unsigned)(aout_symbol(symbol)->other & 0xff),
1971               (unsigned)(aout_symbol(symbol)->type  & 0xff));
1972       if (symbol->name)
1973         fprintf(file," %s", symbol->name);
1974     }
1975     break;
1976   case bfd_print_symbol_nm:
1977     {
1978       int section_code = bfd_decode_symclass  (symbol);
1979
1980       if (section_code == 'U')
1981         fprintf(file, "        ");
1982       else
1983         fprintf_vma(file, symbol->value+symbol->section->vma);
1984       if (section_code == '?')
1985         {
1986           int type_code = aout_symbol(symbol)->type  & 0xff;
1987           char *stab_name = aout_stab_name(type_code);
1988           char buf[10];
1989           if (stab_name == NULL)
1990             {
1991               sprintf(buf, "(%d)", type_code);
1992               stab_name = buf;
1993             }
1994           fprintf(file," - %02x %04x %5s",
1995                   (unsigned)(aout_symbol(symbol)->other & 0xff),
1996                   (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1997                   stab_name);
1998         }
1999       else
2000         fprintf(file," %c", section_code);
2001       if (symbol->name)
2002         fprintf(file," %s", symbol->name);
2003     }
2004     break;
2005   }
2006 }
2007
2008 /* 
2009  provided a BFD, a section and an offset into the section, calculate
2010  and return the name of the source file and the line nearest to the
2011  wanted location.
2012 */
2013  
2014 boolean
2015 DEFUN(NAME(aout,find_nearest_line),(abfd,
2016                                      section,
2017                                      symbols,
2018                                      offset,
2019                                      filename_ptr,
2020                                      functionname_ptr,
2021                                      line_ptr),
2022       bfd *abfd AND
2023       asection *section AND
2024       asymbol **symbols AND
2025       bfd_vma offset AND
2026       CONST char **filename_ptr AND
2027       CONST char **functionname_ptr AND
2028       unsigned int *line_ptr)
2029 {
2030   /* Run down the file looking for the filename, function and linenumber */
2031   asymbol **p;
2032   static  char buffer[100];
2033   static  char filename_buffer[200];
2034   CONST char *directory_name = NULL;
2035   CONST char *main_file_name = NULL;
2036   CONST char *current_file_name = NULL;
2037   CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */
2038   bfd_vma high_line_vma = ~0;
2039   bfd_vma low_func_vma = 0;
2040   asymbol *func = 0;
2041   *filename_ptr = abfd->filename;
2042   *functionname_ptr = 0;
2043   *line_ptr = 0;
2044   if (symbols != (asymbol **)NULL) {
2045     for (p = symbols; *p; p++) {
2046       aout_symbol_type  *q = (aout_symbol_type *)(*p);
2047     next:
2048       switch (q->type){
2049       case N_SO:
2050         main_file_name = current_file_name = q->symbol.name;
2051         /* Look ahead to next symbol to check if that too is an N_SO. */
2052         p++;
2053         if (*p == NULL)
2054           break;
2055         q = (aout_symbol_type *)(*p);
2056         if (q->type != (int)N_SO)
2057           goto next;
2058
2059         /* Found a second N_SO  First is directory; second is filename. */
2060         directory_name = current_file_name;
2061         main_file_name = current_file_name = q->symbol.name;
2062         if (obj_textsec(abfd) != section)
2063           goto done;
2064         break;
2065       case N_SOL:
2066         current_file_name = q->symbol.name;
2067         break;
2068
2069       case N_SLINE:
2070
2071       case N_DSLINE:
2072       case N_BSLINE:
2073         /* We'll keep this if it resolves nearer than the one we have already */
2074         if (q->symbol.value >= offset &&
2075             q->symbol.value < high_line_vma) {
2076           *line_ptr = q->desc;
2077           high_line_vma = q->symbol.value;
2078           line_file_name = current_file_name;
2079         }
2080         break;
2081       case N_FUN:
2082         {
2083           /* We'll keep this if it is nearer than the one we have already */
2084           if (q->symbol.value >= low_func_vma &&
2085               q->symbol.value <= offset) {
2086             low_func_vma = q->symbol.value;
2087             func = (asymbol *)q;
2088           }
2089           if (*line_ptr && func) {
2090             CONST char *function = func->name;
2091             char *p;
2092             strncpy(buffer, function, sizeof(buffer)-1);
2093             buffer[sizeof(buffer)-1] = 0;
2094             /* Have to remove : stuff */
2095             p = strchr(buffer,':');
2096             if (p != NULL) { *p = '\0'; }
2097             *functionname_ptr = buffer;
2098             goto done;
2099
2100           }
2101         }
2102         break;
2103       }
2104     }
2105   }
2106
2107  done:
2108   if (*line_ptr)
2109     main_file_name = line_file_name;
2110   if (main_file_name) {
2111       if (main_file_name[0] == '/' || directory_name == NULL)
2112           *filename_ptr = main_file_name;
2113       else {
2114           sprintf(filename_buffer, "%.140s%.50s",
2115                   directory_name, main_file_name);
2116           *filename_ptr = filename_buffer;
2117       }
2118   }
2119   return true;
2120
2121 }
2122
2123 int 
2124 DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
2125       bfd *abfd AND
2126       boolean execable)
2127 {
2128   return adata(abfd).exec_bytes_size;
2129 }