Merge devo/bfd with GDB's bfd.
[deliverable/binutils-gdb.git] / bfd / aout.c
CommitLineData
4a81b561 1/*** bfd backend for sunos binaries */
fc723380 2/** a.out files */
4a81b561
DHW
3
4/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
5
6This file is part of BFD, the Binary File Diddler.
7
8BFD is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 1, or (at your option)
11any later version.
12
13BFD is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with BFD; see the file COPYING. If not, write to
20the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21
fc723380 22/* $Id$ */
4a81b561 23
c93595dd 24#include <ansidecl.h>
4a81b561
DHW
25#include "sysdep.h"
26#include "bfd.h"
27#include "libbfd.h"
4a81b561 28
fc723380 29#include "a.out.sun4.h"
4a81b561
DHW
30#include "a.out.gnu.h"
31#include "stab.gnu.h"
32#include "ar.h"
33#include "liba.out.h" /* BFD a.out internal data structures */
34
fc723380
JG
35void (*bfd_error_trap)();
36
37/*SUPPRESS558*/
38/*SUPPRESS529*/
4a81b561
DHW
39
40#define CTOR_TABLE_RELOC_IDX 2
aa802a32 41static reloc_howto_type howto_table_ext[] =
4a81b561 42{
4cddd1c9
SC
43 HOWTO(RELOC_8, 0, 0, 8, false, 0, true, true,0,"8", false, 0,0x000000ff, false),
44 HOWTO(RELOC_16, 0, 1, 16, false, 0, true, true,0,"16", false, 0,0x0000ffff, false),
45 HOWTO(RELOC_32, 0, 2, 32, false, 0, true, true,0,"32", false, 0,0xffffffff, false),
46 HOWTO(RELOC_DISP8, 0, 0, 8, true, 0, false, true,0,"DISP8", false, 0,0x000000ff, false),
47 HOWTO(RELOC_DISP16, 0, 1, 16, true, 0, false, true,0,"DISP16", false, 0,0x0000ffff, false),
48 HOWTO(RELOC_DISP32, 0, 2, 32, true, 0, false, true,0,"DISP32", false, 0,0xffffffff, false),
49 HOWTO(RELOC_WDISP30,2, 2, 30, true, 0, false, true,0,"WDISP30", false, 0,0x3fffffff, false),
50 HOWTO(RELOC_WDISP22,2, 2, 22, true, 0, false, true,0,"WDISP22", false, 0,0x003fffff, false),
51 HOWTO(RELOC_HI22, 10, 2, 22, false, 0, false, true,0,"HI22", false, 0,0x003fffff, false),
52 HOWTO(RELOC_22, 0, 2, 22, false, 0, false, true,0,"22", false, 0,0x003fffff, false),
53 HOWTO(RELOC_13, 0, 2, 13, false, 0, false, true,0,"13", false, 0,0x00001fff, false),
54 HOWTO(RELOC_LO10, 0, 2, 10, false, 0, false, true,0,"LO10", false, 0,0x000003ff, false),
55 HOWTO(RELOC_SFA_BASE,0, 2, 32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false),
56 HOWTO(RELOC_SFA_OFF13,0,2, 32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false),
57 HOWTO(RELOC_BASE10, 0, 2, 16, false, 0, false, true,0,"BASE10", false, 0,0x0000ffff, false),
58 HOWTO(RELOC_BASE13, 0, 2, 13, false, 0, false, true,0,"BASE13", false, 0,0x00001fff, false),
59 HOWTO(RELOC_BASE22, 0, 2, 0, false, 0, false, true,0,"BASE22", false, 0,0x00000000, false),
60 HOWTO(RELOC_PC10, 0, 2, 10, false, 0, false, true,0,"PC10", false, 0,0x000003ff, false),
61 HOWTO(RELOC_PC22, 0, 2, 22, false, 0, false, true,0,"PC22", false, 0,0x003fffff, false),
62 HOWTO(RELOC_JMP_TBL,0, 2, 32, false, 0, false, true,0,"JMP_TBL", false, 0,0xffffffff, false),
63 HOWTO(RELOC_SEGOFF16,0, 2, 0, false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false),
64 HOWTO(RELOC_GLOB_DAT,0, 2, 0, false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false),
65 HOWTO(RELOC_JMP_SLOT,0, 2, 0, false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false),
66 HOWTO(RELOC_RELATIVE,0, 2, 0, false, 0, false, true,0,"RELATIVE", false, 0,0x00000000, false),
67 HOWTO(RELOC_JUMPTARG,2, 13, 16, true, 0, false, true,0,"JUMPTARG", false, 0,0x0000ffff, false),
68 HOWTO(RELOC_CONST, 0, 13, 16, false, 0, false, true,0,"CONST", false, 0,0x0000ffff, false),
69 HOWTO(RELOC_CONSTH, 16, 13, 16, false, 0, false, true,0,"CONSTH", false, 0,0x0000ffff, false),
4a81b561
DHW
70};
71
c93595dd
SC
72/* Convert standard reloc records to "arelent" format (incl byte swap). */
73
aa802a32 74static reloc_howto_type howto_table_std[] = {
fc723380 75 /* type rs size bsz pcrel bitpos abs ovrf sf name part_inpl readmask setmask pcdone */
4cddd1c9
SC
76HOWTO( 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff,0x000000ff, false),
77HOWTO( 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff,0x0000ffff, false),
78HOWTO( 2, 0, 2, 32, false, 0, true, true,0,"32", true, 0xffffffff,0xffffffff, false),
79HOWTO( 3, 0, 3, 64, false, 0, true, true,0,"64", true, 0xdeaddead,0xdeaddead, false),
80HOWTO( 4, 0, 0, 8, true, 0, false, true,0,"DISP8", true, 0x000000ff,0x000000ff, false),
81HOWTO( 5, 0, 1, 16, true, 0, false, true,0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
82HOWTO( 6, 0, 2, 32, true, 0, false, true,0,"DISP32", true, 0xffffffff,0xffffffff, false),
83HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedface,0xfeedface, false),
c93595dd
SC
84};
85
aa802a32
SC
86
87bfd_error_vector_type bfd_error_vector;
c93595dd 88
4a81b561
DHW
89PROTO (void , sunos4_write_syms, ());
90PROTO (static boolean,sunos4_squirt_out_relocs,(bfd *abfd, asection *section));
91
c93595dd
SC
92
93static size_t
94reloc_size_func(abfd)
95bfd *abfd;
96{
97 switch (bfd_get_architecture (abfd)) {
98 case bfd_arch_sparc:
99 case bfd_arch_a29k:
100 return RELOC_EXT_SIZE;
101 default:
102 return RELOC_STD_SIZE;
103 }
104}
105
aa802a32
SC
106static void
107DEFUN(bfd_aout_swap_exec_header_in,(abfd, raw_bytes, execp),
108 bfd *abfd AND
109 unsigned char *raw_bytes AND
110 struct exec *execp)
c93595dd
SC
111{
112 struct exec_bytes *bytes = (struct exec_bytes *)raw_bytes;
113
114 /* Now fill in fields in the execp, from the bytes in the raw data. */
115 execp->a_info = bfd_h_getlong (abfd, bytes->a_info);
116 execp->a_text = bfd_h_getlong (abfd, bytes->a_text);
117 execp->a_data = bfd_h_getlong (abfd, bytes->a_data);
118 execp->a_bss = bfd_h_getlong (abfd, bytes->a_bss);
119 execp->a_syms = bfd_h_getlong (abfd, bytes->a_syms);
120 execp->a_entry = bfd_h_getlong (abfd, bytes->a_entry);
121 execp->a_trsize = bfd_h_getlong (abfd, bytes->a_trsize);
122 execp->a_drsize = bfd_h_getlong (abfd, bytes->a_drsize);
123}
124
aa802a32
SC
125static void
126DEFUN(bfd_aout_swap_exec_header_out,(abfd, execp, raw_bytes),
127 bfd *abfd AND
128 struct exec *execp AND
129 unsigned char *raw_bytes)
c93595dd
SC
130{
131 struct exec_bytes *bytes = (struct exec_bytes *)raw_bytes;
132
133 /* Now fill in fields in the raw data, from the fields in the exec struct. */
134 bfd_h_putlong (abfd, execp->a_info , bytes->a_info);
135 bfd_h_putlong (abfd, execp->a_text , bytes->a_text);
136 bfd_h_putlong (abfd, execp->a_data , bytes->a_data);
137 bfd_h_putlong (abfd, execp->a_bss , bytes->a_bss);
138 bfd_h_putlong (abfd, execp->a_syms , bytes->a_syms);
139 bfd_h_putlong (abfd, execp->a_entry , bytes->a_entry);
140 bfd_h_putlong (abfd, execp->a_trsize, bytes->a_trsize);
141 bfd_h_putlong (abfd, execp->a_drsize, bytes->a_drsize);
142}
143
4a81b561
DHW
144bfd_target *
145sunos4_object_p (abfd)
146 bfd *abfd;
147{
c93595dd
SC
148 unsigned char magicbuf[4]; /* Raw bytes of magic number from file */
149 unsigned long magic; /* Swapped magic number */
150 unsigned char exec_bytes[EXEC_BYTES_SIZE]; /* Raw bytes of exec hdr */
151 struct exec *execp;
9846338e 152 PTR rawptr;
4a81b561
DHW
153
154 bfd_error = system_call_error;
155
9846338e 156 if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) !=
c93595dd 157 sizeof (magicbuf))
4a81b561 158 return 0;
c93595dd 159 magic = bfd_h_getlong (abfd, magicbuf);
4a81b561 160
fc723380 161 if (N_BADMAG (*((struct exec *) &magic))) return 0;
4a81b561 162
c93595dd 163 if (bfd_seek (abfd, 0L, false) < 0) return 0;
4a81b561 164
9846338e 165 if (bfd_read ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
c93595dd 166 != EXEC_BYTES_SIZE) {
4a81b561
DHW
167 bfd_error = wrong_format;
168 return 0;
169 }
170
171 /* Use an intermediate variable for clarity */
9872a49c 172 rawptr = (PTR) bfd_zalloc (abfd, sizeof (struct sunexdata) + sizeof (struct exec));
4a81b561
DHW
173
174 if (rawptr == NULL) {
175 bfd_error = no_memory;
176 return 0;
177 }
178
c93595dd
SC
179 set_tdata (abfd, ((struct sunexdata *) rawptr));
180 exec_hdr (abfd) = execp =
4a81b561
DHW
181 (struct exec *) ((char *)rawptr + sizeof (struct sunexdata));
182
c93595dd 183 bfd_aout_swap_exec_header_in (abfd, exec_bytes, execp);
4a81b561
DHW
184
185 /* Set the file flags */
186 abfd->flags = NO_FLAGS;
187 if (execp->a_drsize || execp->a_trsize)
188 abfd->flags |= HAS_RELOC;
189 if (execp->a_entry)
190 abfd->flags |= EXEC_P;
191 if (execp->a_syms)
192 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
193
194
c93595dd
SC
195 if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
196 if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
4a81b561
DHW
197
198 /* Determine the architecture and machine type of the object file. */
199 abfd->obj_arch = bfd_arch_unknown; /* Default values */
200 abfd->obj_machine = 0;
c93595dd 201 switch (N_MACHTYPE (*execp)) {
4a81b561
DHW
202
203 case M_UNKNOWN:
204 break;
205
206 case M_68010:
207 abfd->obj_arch = bfd_arch_m68k;
208 abfd->obj_machine = 68010;
209 break;
210
211 case M_68020:
212 abfd->obj_arch = bfd_arch_m68k;
213 abfd->obj_machine = 68020;
214 break;
215
216 case M_SPARC:
217 abfd->obj_arch = bfd_arch_sparc;
218 break;
219
220 case M_386:
221 abfd->obj_arch = bfd_arch_i386;
222 break;
223
224 case M_29K:
225 abfd->obj_arch = bfd_arch_a29k;
226 break;
227
228 default:
229 abfd->obj_arch = bfd_arch_obscure;
230 break;
231 }
232
233 bfd_get_start_address (abfd) = execp->a_entry;
234
fc723380
JG
235 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct nlist);
236
4a81b561 237 /* Remember the positions of the string table and symbol table. */
fc723380
JG
238 obj_str_filepos (abfd) = N_STROFF (*execp);
239 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
4a81b561
DHW
240
241 /* create the sections. This is raunchy, but bfd_close wants to reclaim
242 them */
243 obj_textsec (abfd) = (asection *)NULL;
244 obj_datasec (abfd) = (asection *)NULL;
245 obj_bsssec (abfd) = (asection *)NULL;
246 obj_aout_symbols(abfd) = (aout_symbol_type *)NULL;
247 (void)bfd_make_section(abfd, ".text");
248 (void)bfd_make_section(abfd, ".data");
249 (void)bfd_make_section(abfd, ".bss");
250
251 obj_datasec (abfd)->size = execp->a_data;
252 obj_bsssec (abfd)->size = execp->a_bss;
253 obj_textsec (abfd)->size = execp->a_text;
c93595dd
SC
254 obj_datasec (abfd)->vma = N_DATADDR(*execp);
255 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
256 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
257
258 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
259 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
260
d6a554ae
JG
261 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
262 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
c93595dd
SC
263
264 obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
265 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
266 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
267 obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
268 (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
269 (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
4a81b561
DHW
270 obj_bsssec (abfd)->flags = SEC_ALLOC;
271
272 abfd->sections = obj_textsec (abfd);
273 obj_textsec (abfd)->next = obj_datasec (abfd);
274 obj_datasec (abfd)->next = obj_bsssec (abfd);
275 return abfd->xvec;
276}
277
278
279boolean
280sunos4_mkobject (abfd)
281 bfd *abfd;
282{
283 char *rawptr;
284
285 bfd_error = system_call_error;
286
287 /* Use an intermediate variable for clarity */
fc723380 288 rawptr = bfd_zalloc (abfd, sizeof (struct sunexdata) + sizeof (struct exec));
4a81b561
DHW
289
290 if (rawptr == NULL) {
291 bfd_error = no_memory;
292 return false;
293 }
294
fc723380 295 set_tdata (abfd, (struct sunexdata *) rawptr);
4a81b561
DHW
296 exec_hdr (abfd) = (struct exec *) (rawptr + sizeof (struct sunexdata));
297
298 /* For simplicity's sake we just make all the sections right here. */
299
300 obj_textsec (abfd) = (asection *)NULL;
301 obj_datasec (abfd) = (asection *)NULL;
302 obj_bsssec (abfd) = (asection *)NULL;
303 bfd_make_section (abfd, ".text");
304 bfd_make_section (abfd, ".data");
305 bfd_make_section (abfd, ".bss");
306
307 return true;
308}
309
310/* Keep track of machine architecture and machine type for a.out's.
311 Return the machine_type for a particular arch&machine, or M_UNKNOWN
312 if that exact arch&machine can't be represented in a.out format.
313
314 If the architecture is understood, machine type 0 (default) should
315 always be understood. */
316
317static enum machine_type
318aout_machine_type (arch, machine)
319 enum bfd_architecture arch;
320 unsigned long machine;
321{
322 enum machine_type arch_flags;
323
324 arch_flags = M_UNKNOWN;
325
326 switch (arch) {
327 case bfd_arch_sparc:
9872a49c
SC
328 if (machine == 0) arch_flags = M_SPARC;
329 break;
4a81b561
DHW
330
331 case bfd_arch_m68k:
9872a49c
SC
332 switch (machine) {
333 case 0: arch_flags = M_68010; break;
334 case 68000: arch_flags = M_UNKNOWN; break;
335 case 68010: arch_flags = M_68010; break;
336 case 68020: arch_flags = M_68020; break;
337 default: arch_flags = M_UNKNOWN; break;
338 }
339 break;
4a81b561
DHW
340
341 case bfd_arch_i386:
9872a49c
SC
342 if (machine == 0) arch_flags = M_386;
343 break;
4a81b561
DHW
344
345 case bfd_arch_a29k:
9872a49c
SC
346 if (machine == 0) arch_flags = M_29K;
347 break;
4a81b561
DHW
348
349 default:
9872a49c
SC
350 arch_flags = M_UNKNOWN;
351 break;
4a81b561
DHW
352 }
353 return arch_flags;
354}
355
356boolean
357sunos4_set_arch_mach (abfd, arch, machine)
358 bfd *abfd;
359 enum bfd_architecture arch;
360 unsigned long machine;
361{
362 abfd->obj_arch = arch;
363 abfd->obj_machine = machine;
364 if (arch != bfd_arch_unknown &&
365 aout_machine_type (arch, machine) == M_UNKNOWN)
366 return false; /* We can't represent this type */
367 return true; /* We're easy ... */
368}
369
370boolean
371sunos4_write_object_contents (abfd)
372 bfd *abfd;
373{
aa802a32 374 size_t data_pad = 0;
c93595dd 375 unsigned char exec_bytes[EXEC_BYTES_SIZE];
4a81b561
DHW
376 struct exec *execp = exec_hdr (abfd);
377
c93595dd 378 execp->a_text = obj_textsec (abfd)->size;
4a81b561
DHW
379
380 /* Magic number, maestro, please! */
381 switch (bfd_get_architecture(abfd)) {
382 case bfd_arch_m68k:
383 switch (bfd_get_machine(abfd)) {
384 case 68010:
385 N_SET_MACHTYPE(*execp, M_68010);
386 break;
387 default:
388 case 68020:
389 N_SET_MACHTYPE(*execp, M_68020);
390 break;
391 }
392 break;
393 case bfd_arch_sparc:
394 N_SET_MACHTYPE(*execp, M_SPARC);
395 break;
396 case bfd_arch_i386:
397 N_SET_MACHTYPE(*execp, M_386);
398 break;
399 case bfd_arch_a29k:
400 N_SET_MACHTYPE(*execp, M_29K);
401 break;
402 default:
403 N_SET_MACHTYPE(*execp, M_UNKNOWN);
404 }
c93595dd 405
4a81b561
DHW
406 N_SET_MAGIC (*execp, OMAGIC);
407 if (abfd->flags & D_PAGED) {
fc723380
JG
408 /* This is not strictly true, but will probably do for the default
409 case. FIXME. */
4a81b561
DHW
410 execp->a_text = obj_textsec (abfd)->size + sizeof(struct exec);
411 N_SET_MAGIC (*execp, ZMAGIC);
412 } else if (abfd->flags & WP_TEXT) {
413 N_SET_MAGIC (*execp, NMAGIC);
414 }
415 N_SET_FLAGS (*execp, 0x1); /* copied from ld.c; who the hell knows? */
416
417 if (abfd->flags & D_PAGED)
aa802a32
SC
418 {
419 data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1)
420 & (- PAGE_SIZE)) - obj_datasec(abfd)->size;
4a81b561 421
aa802a32
SC
422 if (data_pad > obj_bsssec(abfd)->size)
423 execp->a_bss = 0;
424 else
425 execp->a_bss = obj_bsssec(abfd)->size - data_pad;
426 execp->a_data = obj_datasec(abfd)->size + data_pad;
4a81b561 427
aa802a32 428 }
4a81b561
DHW
429 else {
430 execp->a_data = obj_datasec (abfd)->size;
431 execp->a_bss = obj_bsssec (abfd)->size;
432 }
433
434 execp->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
435 execp->a_entry = bfd_get_start_address (abfd);
c93595dd 436
4a81b561 437 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
c93595dd
SC
438 reloc_size_func(abfd));
439
4a81b561 440 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
c93595dd 441 reloc_size_func(abfd));
4a81b561 442
c93595dd 443 bfd_aout_swap_exec_header_out (abfd, execp, exec_bytes);
4a81b561 444
c93595dd 445 bfd_seek (abfd, 0L, false);
9846338e 446 bfd_write ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd);
4a81b561
DHW
447
448 /* Now write out reloc info, followed by syms and strings */
449
450 if (bfd_get_symcount (abfd) != 0)
9846338e
SC
451 {
452 bfd_seek (abfd,
453 (long)(N_SYMOFF(*execp)), false);
4a81b561 454
9846338e 455 sunos4_write_syms (abfd);
4a81b561 456
d6a554ae 457 bfd_seek (abfd, (long)(N_TRELOFF(*execp)), false);
4a81b561 458
9846338e 459 if (!sunos4_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
d6a554ae 460 bfd_seek (abfd, (long)(N_DRELOFF(*execp)), false);
4a81b561 461
9846338e
SC
462 if (!sunos4_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
463 }
4a81b561
DHW
464 return true;
465}
fc723380
JG
466\f
467/* core files */
4a81b561
DHW
468
469#define CORE_MAGIC 0x080456
470#define CORE_NAMELEN 16
471
472/* The core structure is taken from the Sun documentation.
473 Unfortunately, they don't document the FPA structure, or at least I
474 can't find it easily. Fortunately the core header contains its own
475 length. So this shouldn't cause problems, except for c_ucode, which
476 so far we don't use but is easy to find with a little arithmetic. */
477
478/* But the reg structure can be gotten from the SPARC processor handbook.
479 This really should be in a GNU include file though so that gdb can use
480 the same info. */
481struct regs {
482 int r_psr;
483 int r_pc;
484 int r_npc;
485 int r_y;
486 int r_g1;
487 int r_g2;
488 int r_g3;
489 int r_g4;
490 int r_g5;
491 int r_g6;
492 int r_g7;
493 int r_o0;
494 int r_o1;
495 int r_o2;
496 int r_o3;
497 int r_o4;
498 int r_o5;
499 int r_o6;
500 int r_o7;
501};
502
503/* Taken from Sun documentation: */
504
c93595dd
SC
505/* FIXME: It's worse than we expect. This struct contains TWO substructs
506 neither of whose size we know, WITH STUFF IN BETWEEN THEM! We can't
507 even portably access the stuff in between! */
508
4a81b561
DHW
509struct core {
510 int c_magic; /* Corefile magic number */
511 int c_len; /* Sizeof (struct core) */
512 struct regs c_regs; /* General purpose registers */
513 struct exec c_aouthdr; /* A.out header */
514 int c_signo; /* Killing signal, if any */
515 int c_tsize; /* Text size (bytes) */
516 int c_dsize; /* Data size (bytes) */
517 int c_ssize; /* Stack size (bytes) */
518 char c_cmdname[CORE_NAMELEN + 1]; /* Command name */
519 double fp_stuff[1]; /* external FPU state (size unknown by us) */
c93595dd
SC
520 /* The type "double" is critical here, for alignment.
521 SunOS declares a struct here, but the struct's alignment
522 is double since it contains doubles. */
4a81b561 523 int c_ucode; /* Exception no. from u_code */
c93595dd
SC
524 /* (this member is not accessible by name since we don't
525 portably know the size of fp_stuff.) */
4a81b561
DHW
526};
527
528/* Supposedly the user stack grows downward from the bottom of kernel memory.
529 Presuming that this remains true, this definition will work. */
530#define USRSTACK (-(128*1024*1024))
531
532PROTO (static void, swapcore, (bfd *abfd, struct core *core));
533
534/* need this cast b/c ptr is really void * */
535#define core_hdr(bfd) (((struct suncordata *) (bfd->tdata))->hdr)
536#define core_datasec(bfd) (((struct suncordata *) ((bfd)->tdata))->data_section)
537#define core_stacksec(bfd) (((struct suncordata*)((bfd)->tdata))->stack_section)
538#define core_regsec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg_section)
c93595dd 539#define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section)
4a81b561
DHW
540
541/* These are stored in the bfd's tdata */
542struct suncordata {
543 struct core *hdr; /* core file header */
544 asection *data_section;
545 asection *stack_section;
546 asection *reg_section;
547 asection *reg2_section;
548};
549
550bfd_target *
551sunos4_core_file_p (abfd)
552 bfd *abfd;
553{
c93595dd 554 unsigned char longbuf[4]; /* Raw bytes of various header fields */
4a81b561
DHW
555 int core_size;
556 int core_mag;
557 struct core *core;
558 char *rawptr;
559
560 bfd_error = system_call_error;
561
9846338e 562 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
c93595dd 563 sizeof (longbuf))
4a81b561 564 return 0;
c93595dd 565 core_mag = bfd_h_getlong (abfd, longbuf);
4a81b561
DHW
566
567 if (core_mag != CORE_MAGIC) return 0;
568
569 /* SunOS core headers can vary in length; second word is size; */
9846338e 570 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
c93595dd
SC
571 sizeof (longbuf))
572 return 0;
573 core_size = bfd_h_getlong (abfd, longbuf);
574 /* Sanity check */
575 if (core_size > 20000)
4a81b561 576 return 0;
4a81b561 577
c93595dd 578 if (bfd_seek (abfd, 0L, false) < 0) return 0;
4a81b561 579
9872a49c 580 rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata));
4a81b561
DHW
581 if (rawptr == NULL) {
582 bfd_error = no_memory;
583 return 0;
584 }
585
586 core = (struct core *) (rawptr + sizeof (struct suncordata));
587
9846338e 588 if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
4a81b561 589 bfd_error = system_call_error;
fc723380 590 bfd_release (abfd, rawptr);
4a81b561
DHW
591 return 0;
592 }
593
594 swapcore (abfd, core);
c93595dd 595 set_tdata (abfd, ((struct suncordata *) rawptr));
4a81b561
DHW
596 core_hdr (abfd) = core;
597
598 /* create the sections. This is raunchy, but bfd_close wants to reclaim
599 them */
9872a49c 600 core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
4a81b561 601 if (core_stacksec (abfd) == NULL) {
c93595dd 602loser:
4a81b561 603 bfd_error = no_memory;
fc723380 604 bfd_release (abfd, rawptr);
4a81b561
DHW
605 return 0;
606 }
9872a49c 607 core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
4a81b561 608 if (core_datasec (abfd) == NULL) {
c93595dd 609loser1:
fc723380 610 bfd_release (abfd, core_stacksec (abfd));
4a81b561
DHW
611 goto loser;
612 }
9872a49c 613 core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
4a81b561 614 if (core_regsec (abfd) == NULL) {
c93595dd 615loser2:
fc723380 616 bfd_release (abfd, core_datasec (abfd));
4a81b561
DHW
617 goto loser1;
618 }
9872a49c 619 core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
c93595dd 620 if (core_reg2sec (abfd) == NULL) {
fc723380 621 bfd_release (abfd, core_regsec (abfd));
4a81b561
DHW
622 goto loser2;
623 }
624
625 core_stacksec (abfd)->name = ".stack";
626 core_datasec (abfd)->name = ".data";
627 core_regsec (abfd)->name = ".reg";
c93595dd 628 core_reg2sec (abfd)->name = ".reg2";
4a81b561
DHW
629
630 core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
631 core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
632 core_regsec (abfd)->flags = SEC_ALLOC;
c93595dd 633 core_reg2sec (abfd)->flags = SEC_ALLOC;
4a81b561
DHW
634
635 core_stacksec (abfd)->size = core->c_ssize;
636 core_datasec (abfd)->size = core->c_dsize;
637 core_regsec (abfd)->size = (sizeof core->c_regs);
c93595dd
SC
638 /* Float regs take up end of struct, except c_ucode. */
639 core_reg2sec (abfd)->size = core_size - (sizeof core->c_ucode) -
640 (file_ptr)(((struct core *)0)->fp_stuff);
4a81b561
DHW
641
642 core_stacksec (abfd)->vma = (USRSTACK - core->c_ssize);
643 core_datasec (abfd)->vma = N_DATADDR(core->c_aouthdr);
644 core_regsec (abfd)->vma = -1;
c93595dd 645 core_reg2sec (abfd)->vma = -1;
4a81b561
DHW
646
647 core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
648 core_datasec (abfd)->filepos = core->c_len;
649 /* In file header: */
650 core_regsec (abfd)->filepos = (file_ptr)(&((struct core *)0)->c_regs);
c93595dd 651 core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff);
4a81b561
DHW
652
653 /* Align to word at least */
654 core_stacksec (abfd)->alignment_power = 2;
655 core_datasec (abfd)->alignment_power = 2;
656 core_regsec (abfd)->alignment_power = 2;
c93595dd 657 core_reg2sec (abfd)->alignment_power = 2;
4a81b561
DHW
658
659 abfd->sections = core_stacksec (abfd);
660 core_stacksec (abfd)->next = core_datasec (abfd);
661 core_datasec (abfd)->next = core_regsec (abfd);
c93595dd 662 core_regsec (abfd)->next = core_reg2sec (abfd);
4a81b561
DHW
663
664 abfd->section_count = 4;
665
666 return abfd->xvec;
667}
668
669char *
670sunos4_core_file_failing_command (abfd)
671 bfd *abfd;
672{
673 return core_hdr (abfd)->c_cmdname;
674}
675
676int
677sunos4_core_file_failing_signal (abfd)
678 bfd *abfd;
679{
680 return core_hdr (abfd)->c_signo;
681}
682
683boolean
684sunos4_core_file_matches_executable_p (core_bfd, exec_bfd)
685 bfd *core_bfd, *exec_bfd;
686{
687 if (core_bfd->xvec != exec_bfd->xvec) {
688 bfd_error = system_call_error;
689 return false;
690 }
691
c93595dd 692 return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
4a81b561
DHW
693 sizeof (struct exec)) == 0) ? true : false;
694}
695
696/* byte-swap core structure */
c93595dd 697/* FIXME, this needs more work to swap IN a core struct from raw bytes */
4a81b561
DHW
698static void
699swapcore (abfd, core)
c93595dd 700 bfd *abfd;
4a81b561
DHW
701 struct core *core;
702{
c93595dd
SC
703 unsigned char exec_bytes[EXEC_BYTES_SIZE];
704
705 core->c_magic = bfd_h_getlong (abfd, (unsigned char *)&core->c_magic);
706 core->c_len = bfd_h_getlong (abfd, (unsigned char *)&core->c_len );
707 /* Leave integer registers in target byte order. */
708 bcopy ((char *)&(core->c_aouthdr), (char *)exec_bytes, EXEC_BYTES_SIZE);
709 bfd_aout_swap_exec_header_in (abfd, exec_bytes, &core->c_aouthdr);
710 core->c_signo = bfd_h_getlong (abfd, (unsigned char *)&core->c_signo);
711 core->c_tsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_tsize);
712 core->c_dsize = bfd_h_getlong (abfd, (unsigned char *)&core->c_dsize);
713 core->c_ssize = bfd_h_getlong (abfd, (unsigned char *)&core->c_ssize);
714 /* Leave FP registers in target byte order. */
715 /* Leave "c_ucode" unswapped for now, since we can't find it easily. */
4a81b561
DHW
716}
717\f
718/** exec and core file sections */
719
720boolean
721sunos4_new_section_hook (abfd, newsect)
722 bfd *abfd;
723 asection *newsect;
724{
725 /* align to double at least */
726 newsect->alignment_power = 3;
727
728 if (bfd_get_format (abfd) == bfd_object) {
729 if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
730 obj_textsec(abfd)= newsect;
731 return true;
732 }
733
734 if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
735 obj_datasec(abfd) = newsect;
736 return true;
737 }
738
739 if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
740 obj_bsssec(abfd) = newsect;
741 return true;
742 }
743 }
744
4a81b561
DHW
745 /* We allow more than three sections internally */
746 return true;
747}
748
749boolean
750sunos4_set_section_contents (abfd, section, location, offset, count)
751 bfd *abfd;
752 sec_ptr section;
753 unsigned char *location;
754 file_ptr offset;
755 int count;
756{
757 if (abfd->output_has_begun == false)
4432f8ad 758 { /* set by bfd.c handler */
fc723380 759 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
4432f8ad
SC
760 {
761 bfd_error = invalid_operation;
762 return false;
763 }
4a81b561 764
fc723380
JG
765 obj_textsec (abfd)->filepos = sizeof(struct exec);
766 obj_datasec(abfd)->filepos = obj_textsec (abfd)->filepos
767 + obj_textsec (abfd)->size;
4432f8ad 768 }
4a81b561 769 /* regardless, once we know what we're doing, we might as well get going */
4432f8ad
SC
770 if (section != obj_bsssec(abfd)) {
771 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
4a81b561 772
4432f8ad
SC
773 if (count) {
774 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
775 true : false;
776 }
777 return false;
4a81b561 778 }
4432f8ad 779 return true;
4a81b561 780}
fc723380 781
4a81b561
DHW
782boolean
783sunos4_get_section_contents (abfd, section, location, offset, count)
784 bfd *abfd;
785 sec_ptr section;
9846338e 786 PTR location;
4a81b561
DHW
787 file_ptr offset;
788 int count;
789{
790 if (count) {
791 if (offset >= section->size) return false;
792
793 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
794
795 return (bfd_read (location, 1, count, abfd) == count) ? true:false;
796 }
797 else return true;
798}
799
800\f
801/* Classify stabs symbols */
802
803
804#define sym_in_text_section(sym) \
805 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
806
807#define sym_in_data_section(sym) \
808 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
809
810#define sym_in_bss_section(sym) \
811 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
812
813/* Symbol is undefined if type is N_UNDF|N_EXT and if it has
814 zero in the "value" field. Nonzeroes there are fortrancommon
815 symbols. */
816#define sym_is_undefined(sym) \
817 ((sym)->n_type == (N_UNDF | N_EXT) && (sym)->n_value == 0)
818
819/* Symbol is a global definition if N_EXT is on and if it has
820 a nonzero type field. */
821#define sym_is_global_defn(sym) \
822 (((sym)->n_type & N_EXT) && (sym)->n_type & N_TYPE)
823
824/* Symbol is debugger info if any bits outside N_TYPE or N_EXT
825 are on. */
826#define sym_is_debugger_info(sym) \
827 ((sym)->n_type & ~(N_EXT | N_TYPE))
828
829#define sym_is_fortrancommon(sym) \
830 (((sym)->n_type == (N_EXT)) && (sym)->n_value != 0)
831
832/* Symbol is absolute if it has N_ABS set */
833#define sym_is_absolute(sym) \
834 (((sym)->n_type & N_TYPE)== N_ABS)
835
836
837#define sym_is_indirect(sym) \
838 (((sym)->n_type & N_ABS)== N_ABS)
839
840/* Only in their own functions for ease of debugging; when sym flags have
841 stabilised these should be inlined into their (single) caller */
842
843static void
844translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd)
845 struct nlist *sym_pointer;
846 aout_symbol_type *cache_ptr;
847 bfd *abfd;
848{
849 switch (cache_ptr->type & N_TYPE) {
850 case N_SETA:
851 case N_SETT:
852 case N_SETD:
853 case N_SETB:
854 {
855 asection *section = bfd_make_section(abfd,
856 cache_ptr->symbol.name);
9872a49c 857 arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
4a81b561
DHW
858
859 switch ( (cache_ptr->type & N_TYPE) ) {
860 case N_SETA:
861 reloc->relent.section = (asection *)NULL;
862 cache_ptr->symbol.section = (asection *)NULL;
863 break;
864 case N_SETT:
865 reloc->relent.section = (asection *)obj_textsec(abfd);
866 cache_ptr->symbol.value -= reloc->relent.section->vma;
867 break;
868 case N_SETD:
869 reloc->relent.section = (asection *)obj_datasec(abfd);
870 cache_ptr->symbol.value -= reloc->relent.section->vma;
871 break;
872 case N_SETB:
873 reloc->relent.section = (asection *)obj_bsssec(abfd);
874 cache_ptr->symbol.value -= reloc->relent.section->vma;
875 break;
876 }
877 cache_ptr->symbol.section = reloc->relent.section;
878 reloc->relent.addend = cache_ptr->symbol.value ;
fc723380
JG
879
880 /* We modify the symbol to belong to a section depending upon the
4a81b561
DHW
881 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
882 really care, and add to the size of the section to contain a
883 pointer to the symbol. Build a reloc entry to relocate to this
fc723380 884 symbol attached to this section. */
4a81b561
DHW
885
886 section->flags = SEC_CONSTRUCTOR;
887 section->reloc_count++;
888 section->alignment_power = 2;
889 reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
890 reloc->next = section->constructor_chain;
891 section->constructor_chain = reloc;
892 reloc->relent.address = section->size;
893 section->size += sizeof(int *);
894
c93595dd 895 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
4a81b561
DHW
896 cache_ptr->symbol.flags |= BSF_DEBUGGING ;
897 }
898 break;
899 default:
900
901 if (sym_is_debugger_info (sym_pointer)) {
902 cache_ptr->symbol.flags = BSF_DEBUGGING ;
903 /* Work out the section correct for this symbol */
904 switch (sym_pointer->n_type & N_TYPE)
905 {
906 case N_TEXT:
907 case N_FN:
908 cache_ptr->symbol.section = obj_textsec (abfd);
909 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
910 break;
911 case N_DATA:
912 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
913 cache_ptr->symbol.section = obj_datasec (abfd);
914 break;
915 case N_BSS :
916 cache_ptr->symbol.section = obj_bsssec (abfd);
917 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
918 break;
919 case N_ABS:
920 default:
921 cache_ptr->symbol.section = 0;
922 break;
923 }
924 }
925 else {
926 if (sym_is_fortrancommon (sym_pointer))
927 {
928 cache_ptr->symbol.flags = BSF_FORT_COMM;
929 cache_ptr->symbol.section = (asection *)NULL;
930 }
931 else {
932 if (sym_is_undefined (sym_pointer)) {
933 cache_ptr->symbol.flags = BSF_UNDEFINED;
934 }
935 else if (sym_is_global_defn (sym_pointer)) {
936 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
937 }
938
939 else if (sym_is_absolute (sym_pointer)) {
940 cache_ptr->symbol.flags = BSF_ABSOLUTE;
941 }
942 else {
943 cache_ptr->symbol.flags = BSF_LOCAL;
944 }
945
946 /* In a.out, the value of a symbol is always relative to the
947 * start of the file, if this is a data symbol we'll subtract
948 * the size of the text section to get the section relative
949 * value. If this is a bss symbol (which would be strange)
950 * we'll subtract the size of the previous two sections
951 * to find the section relative address.
952 */
953
954 if (sym_in_text_section (sym_pointer)) {
955 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
956 cache_ptr->symbol.section = obj_textsec (abfd);
957 }
958 else if (sym_in_data_section (sym_pointer)){
959 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
960 cache_ptr->symbol.section = obj_datasec (abfd);
961 }
962 else if (sym_in_bss_section(sym_pointer)) {
963 cache_ptr->symbol.section = obj_bsssec (abfd);
964 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
965 }
966 else {
967 cache_ptr->symbol.section = (asection *)NULL;
968 cache_ptr->symbol.flags |= BSF_ABSOLUTE;
969 }
970 }
971 }
972 }
973}
c93595dd 974
4a81b561
DHW
975void
976translate_to_native_sym_flags (sym_pointer, cache_ptr_g, abfd)
977 struct nlist *sym_pointer;
4432f8ad 978 PTR cache_ptr_g;
4a81b561
DHW
979 bfd *abfd;
980{
981 asymbol *cache_ptr = (asymbol *)cache_ptr_g;
982
fc723380 983 /* FIXME check for writing bss */
4a81b561
DHW
984 if (bfd_get_section(cache_ptr)) {
985 if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
986 sym_pointer->n_type |= N_BSS;
987 }
988 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
989 sym_pointer->n_type |= N_DATA;
990 }
991 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
992 sym_pointer->n_type |= N_TEXT;
993 }
994 else {
fc723380
JG
995 bfd_error_vector.nonrepresentable_section(abfd,
996 bfd_get_output_section(cache_ptr)->name);
4a81b561
DHW
997 }
998 /* Turn the symbol from section relative to absolute again */
999 sym_pointer->n_value +=
1000 cache_ptr->section->output_section->vma
1001 + cache_ptr->section->output_offset ;
1002 }
1003 else {
1004 sym_pointer->n_type |= N_ABS;
1005 }
1006
1007 if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
1008 sym_pointer->n_type = (N_UNDF | N_EXT);
1009 return;
1010 }
1011
1012 if (cache_ptr->flags & BSF_ABSOLUTE) {
1013 sym_pointer->n_type |= N_ABS;
1014 }
1015
1016 if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1017 sym_pointer->n_type |= N_EXT;
1018 }
1019 if (cache_ptr->flags & BSF_DEBUGGING) {
1020 sym_pointer->n_type = ((aout_symbol_type *)cache_ptr)->type;
1021 }
4a81b561
DHW
1022}
1023\f
1024/* Native-level interface to symbols. */
1025
1026/* We read the symbols into a buffer, which is discarded when this
1027 function exits. We read the strings into a buffer large enough to
1028 hold them all plus all the cached symbol entries. */
1029
1030asymbol *
1031sunos4_make_empty_symbol (abfd)
1032bfd *abfd;
1033{
1034 aout_symbol_type *new =
9872a49c 1035 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
4a81b561
DHW
1036 new->symbol.the_bfd = abfd;
1037
1038 return &new->symbol;
1039}
1040
1041boolean
aa802a32
SC
1042DEFUN(sunos4_slurp_symbol_table, (abfd),
1043 bfd *abfd)
4a81b561 1044{
4a81b561
DHW
1045 size_t symbol_size;
1046 size_t string_size;
fc723380 1047 unsigned char string_chars[LONG_SIZE];
4a81b561
DHW
1048 struct nlist *syms;
1049 char *strings;
1050 aout_symbol_type *cached;
1051
1052 /* If there's no work to be done, don't do any */
1053 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1054 symbol_size = exec_hdr(abfd)->a_syms;
1055 if (symbol_size == 0) {
1056 bfd_error = no_symbols;
1057 return false;
1058 }
1059
1060 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
fc723380 1061 if (bfd_read ((PTR)string_chars, LONG_SIZE, 1, abfd) != LONG_SIZE)
4a81b561 1062 return false;
fc723380 1063 string_size = bfd_h_getlong (abfd, string_chars);
4a81b561 1064
9872a49c 1065 strings = bfd_alloc(abfd, string_size + 1);
d6a554ae 1066 cached = (aout_symbol_type *)
fc723380
JG
1067 bfd_zalloc(abfd, bfd_get_symcount (abfd) * sizeof(aout_symbol_type));
1068 /* Alloc this last, so we can free it if obstack is in use. */
d6a554ae 1069 syms = (struct nlist *) bfd_alloc(abfd, symbol_size);
4a81b561
DHW
1070
1071 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
9846338e 1072 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
4a81b561 1073 bailout:
fc723380
JG
1074 if (syms) bfd_release (abfd, syms);
1075 if (cached) bfd_release (abfd, cached);
1076 if (strings)bfd_release (abfd, strings);
4a81b561
DHW
1077 return false;
1078 }
1079
1080 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
9846338e 1081 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
4a81b561
DHW
1082 goto bailout;
1083 }
1084
1085 /* OK, now walk the new symtable, cacheing symbol properties */
9872a49c
SC
1086 {
1087 register struct nlist *sym_pointer;
fc723380 1088 register struct nlist *sym_end = syms + bfd_get_symcount (abfd);
9872a49c 1089 register aout_symbol_type *cache_ptr = cached;
4a81b561 1090
4a81b561
DHW
1091 /* run through the table and byte swap if needed */
1092 for (sym_pointer = syms; sym_pointer < sym_end; sym_pointer++) {
1093 sym_pointer->n_un.n_strx =
1094 bfd_h_get_x (abfd, &sym_pointer->n_un.n_strx);
1095 sym_pointer->n_desc =
1096 bfd_h_get_x (abfd, &sym_pointer->n_desc);
1097 sym_pointer->n_value =
1098 bfd_h_get_x (abfd, &sym_pointer->n_value);
1099 sym_pointer->n_other = (char)
1100 bfd_h_get_x(abfd, &sym_pointer->n_other);
1101 sym_pointer->n_type = (char)
1102 bfd_h_get_x(abfd, &sym_pointer->n_type);
4a81b561 1103 }
726cc6ef 1104
9872a49c
SC
1105 /* Run through table and copy values */
1106 for (sym_pointer = syms, cache_ptr = cached;
1107 sym_pointer < sym_end; sym_pointer++, cache_ptr++)
1108 {
1109 cache_ptr->symbol.the_bfd = abfd;
1110 if (sym_pointer->n_un.n_strx)
1111 cache_ptr->symbol.name = sym_pointer->n_un.n_strx + strings;
1112 else
1113 cache_ptr->symbol.name = (char *)NULL;
1114 cache_ptr->symbol.value = sym_pointer->n_value;
1115 cache_ptr->desc = sym_pointer->n_desc;
1116 cache_ptr->other = sym_pointer->n_other;
1117 cache_ptr->type = sym_pointer->n_type;
1118 cache_ptr->symbol.udata = 0;
1119 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
4a81b561 1120
9872a49c
SC
1121 }
1122 }
4a81b561
DHW
1123
1124 obj_aout_symbols (abfd) = cached;
9872a49c 1125 bfd_release (abfd, (PTR)syms);
4a81b561
DHW
1126
1127 return true;
1128}
1129
aa802a32 1130
4a81b561 1131void
aa802a32
SC
1132DEFUN(sunos4_write_syms,(abfd),
1133 bfd *abfd)
4a81b561
DHW
1134{
1135 unsigned int count ;
1136 asymbol **generic = bfd_get_outsymbols (abfd);
1137
1138 unsigned int stindex = sizeof(stindex); /* initial string length */
1139
1140 for (count = 0; count < bfd_get_symcount (abfd); count++) {
1141 asymbol *g = generic[count];
1142 struct nlist nsp;
1143
1144 if (g->name) {
1145 unsigned int length = strlen(g->name) +1;
1146 bfd_h_putlong (abfd, stindex, (unsigned char *)&nsp.n_un.n_strx);
1147 stindex += length;
1148 }
1149 else {
1150 bfd_h_putlong (abfd, 0, (unsigned char *)&nsp.n_un.n_strx);
1151 }
1152
1153 if (g->the_bfd->xvec->flavour == abfd->xvec->flavour)
1154 {
1155 nsp.n_desc = aout_symbol( g)->desc;
1156 nsp.n_other = aout_symbol(g)->other;
1157 nsp.n_type = aout_symbol(g)->type;
1158 }
1159 else
1160 {
1161 nsp.n_desc = 0;
1162 nsp.n_other = 0;
1163 nsp.n_type = 0;
1164 }
1165
1166
1167 nsp.n_value = g->value;
4432f8ad 1168 translate_to_native_sym_flags (&nsp, (PTR)g, abfd);
4a81b561
DHW
1169
1170
1171 bfd_h_putshort (abfd, nsp.n_desc, (unsigned char *)&nsp.n_desc);
1172 bfd_h_putlong (abfd, nsp.n_value, (unsigned char *)&nsp.n_value);
9846338e 1173 bfd_write((PTR)&nsp,1, sizeof(nsp), abfd);
4a81b561
DHW
1174 }
1175
1176
1177 /* Now output the strings. Be sure to put string length into correct
1178 * byte ordering before writing it.
1179 */
1180 bfd_h_putlong (abfd, stindex, (unsigned char *)&stindex);
1181
9846338e 1182 bfd_write((PTR)&stindex, 1, sizeof(stindex), abfd);
4a81b561
DHW
1183
1184 generic = bfd_get_outsymbols(abfd);
1185 for (count = 0; count < bfd_get_symcount(abfd); count++)
1186 {
1187 asymbol *g = *(generic++);
1188
fc723380 1189 if (g->name)
4a81b561
DHW
1190 {
1191 size_t length = strlen(g->name)+1;
9846338e 1192 bfd_write((PTR)g->name, 1, length, abfd);
4a81b561
DHW
1193 }
1194 if ((g->flags & BSF_FAKE)==0) {
1195 g->name = itos(count); /* smash the generic symbol */
1196 }
1197 }
1198}
1199
aa802a32 1200
4a81b561 1201void
aa802a32
SC
1202DEFUN(sunos4_reclaim_symbol_table,(abfd),
1203 bfd *abfd)
4a81b561 1204{
4a81b561 1205
4a81b561
DHW
1206}
1207\f
1208unsigned int
1209sunos4_get_symtab_upper_bound (abfd)
1210 bfd *abfd;
1211{
1212 if (!sunos4_slurp_symbol_table (abfd)) return 0;
1213
1214 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1215}
1216
1217unsigned int
1218sunos4_get_symtab (abfd, location)
1219 bfd *abfd;
1220 asymbol **location;
1221{
1222 unsigned int counter = 0;
1223 aout_symbol_type *symbase;
1224
1225 if (!sunos4_slurp_symbol_table (abfd)) return 0;
1226
1227 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1228 *(location++) = (asymbol *)( symbase++);
1229 *location++ =0;
1230 return bfd_get_symcount(abfd);
1231}
1232
4a81b561 1233\f
c93595dd
SC
1234/* Standard reloc stuff */
1235/* Output standard relocation information to a file in target byte order. */
1236
1237void
fc723380 1238swap_std_reloc_out (abfd, g, natptr)
c93595dd 1239 bfd *abfd;
fc723380 1240 arelent *g; /* Generic relocation struct */
c93595dd 1241 struct reloc_std_bytes *natptr;
c93595dd
SC
1242{
1243 int r_index;
1244 int r_extern;
1245 unsigned int r_length;
1246 int r_pcrel;
1247 int r_baserel, r_jmptable, r_relative;
1248 unsigned int r_addend;
c93595dd 1249
fc723380 1250 bfd_h_putlong (abfd, g->address, natptr->r_address);
c93595dd 1251
fc723380
JG
1252 r_length = g->howto->size; /* Size as a power of two */
1253 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
1254 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
1255 r_baserel = 0;
1256 r_jmptable = 0;
1257 r_relative = 0;
4a81b561 1258
fc723380 1259 r_addend = g->addend; /* Start here, see how it goes */
c93595dd 1260
fc723380 1261 /* name was clobbered by sunos4_write_syms to be symbol index */
c93595dd 1262
fc723380
JG
1263 if (g->sym_ptr_ptr != NULL)
1264 {
1265 if ((*(g->sym_ptr_ptr))->section) {
1266 /* put the section offset into the addend for output */
1267 r_addend += (*(g->sym_ptr_ptr))->section->vma;
c93595dd
SC
1268 }
1269
fc723380
JG
1270 r_index = stoi((*(g->sym_ptr_ptr))->name);
1271 r_extern = 1;
1272 }
1273 else {
1274 r_extern = 0;
1275 if (g->section == NULL) {
1276 BFD_ASSERT(0);
1277 r_index = N_ABS | N_EXT;
1278 }
1279 else if(g->section->output_section == obj_textsec(abfd)) {
1280 r_index = N_TEXT | N_EXT;
1281 r_addend += g->section->output_section->vma;
1282 }
1283 else if (g->section->output_section == obj_datasec(abfd)) {
1284 r_index = N_DATA | N_EXT;
1285 r_addend += g->section->output_section->vma;
1286 }
1287 else if (g->section->output_section == obj_bsssec(abfd)) {
1288 r_index = N_BSS | N_EXT ;
1289 r_addend += g->section->output_section->vma;
c93595dd 1290 }
fc723380
JG
1291 else {
1292 BFD_ASSERT(0);
1293 }
1294 }
1295
1296 /* now the fun stuff */
1297 if (abfd->xvec->header_byteorder_big_p != false) {
1298 natptr->r_index[0] = r_index >> 16;
1299 natptr->r_index[1] = r_index >> 8;
1300 natptr->r_index[2] = r_index;
1301 natptr->r_bits[0] =
1302 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
1303 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
1304 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
1305 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
1306 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
1307 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
1308 } else {
1309 natptr->r_index[2] = r_index >> 16;
1310 natptr->r_index[1] = r_index >> 8;
1311 natptr->r_index[0] = r_index;
1312 natptr->r_bits[0] =
1313 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
1314 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
1315 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
1316 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1317 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1318 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
1319 }
c93595dd
SC
1320}
1321
1322
1323/* Extended stuff */
1324/* Output extended relocation information to a file in target byte order. */
1325
1326void
fc723380 1327swap_ext_reloc_out (abfd, g, natptr)
c93595dd 1328 bfd *abfd;
fc723380 1329 arelent *g; /* Generic relocation struct */
c93595dd 1330 register struct reloc_ext_bytes *natptr;
c93595dd 1331{
c93595dd
SC
1332 int r_index;
1333 int r_extern;
1334 unsigned int r_type;
1335 unsigned int r_addend;
c93595dd 1336
fc723380 1337 bfd_h_putlong (abfd, g->address, natptr->r_address);
c93595dd 1338
fc723380
JG
1339 /* Find a type in the output format which matches the input howto -
1340 at the moment we assume input format == output format FIXME!! */
1341 r_type = (enum reloc_type) g->howto->type;
c93595dd 1342
fc723380 1343 r_addend = g->addend; /* Start here, see how it goes */
c93595dd 1344
fc723380 1345 /* name was clobbered by sunos4_write_syms to be symbol index*/
c93595dd 1346
fc723380
JG
1347 if (g->sym_ptr_ptr != NULL)
1348 {
1349 if ((*(g->sym_ptr_ptr))->section) {
1350 /* put the section offset into the addend for output */
1351 r_addend += (*(g->sym_ptr_ptr))->section->vma;
c93595dd 1352 }
c93595dd 1353
fc723380
JG
1354 r_index = stoi((*(g->sym_ptr_ptr))->name);
1355 r_extern = 1;
c93595dd 1356 }
fc723380
JG
1357 else {
1358 r_extern = 0;
1359 if (g->section == NULL) {
1360 BFD_ASSERT(0);
1361 r_index = N_ABS | N_EXT;
1362 }
1363 else if(g->section->output_section == obj_textsec(abfd)) {
1364 r_index = N_TEXT | N_EXT;
1365 r_addend += g->section->output_section->vma;
1366 }
1367 else if (g->section->output_section == obj_datasec(abfd)) {
1368 r_index = N_DATA | N_EXT;
1369 r_addend += g->section->output_section->vma;
1370 }
1371 else if (g->section->output_section == obj_bsssec(abfd)) {
1372 r_index = N_BSS | N_EXT ;
1373 r_addend += g->section->output_section->vma;
1374 }
1375 else {
1376 BFD_ASSERT(0);
1377 }
1378 }
c93595dd 1379
fc723380
JG
1380 /* now the fun stuff */
1381 if (abfd->xvec->header_byteorder_big_p != false) {
1382 natptr->r_index[0] = r_index >> 16;
1383 natptr->r_index[1] = r_index >> 8;
1384 natptr->r_index[2] = r_index;
1385 natptr->r_bits[0] =
1386 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1387 || (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1388 } else {
1389 natptr->r_index[2] = r_index >> 16;
1390 natptr->r_index[1] = r_index >> 8;
1391 natptr->r_index[0] = r_index;
1392 natptr->r_bits[0] =
1393 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1394 || (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
c93595dd 1395 }
fc723380
JG
1396
1397 bfd_h_putlong (abfd, r_addend, natptr->r_addend);
c93595dd 1398}
fc723380 1399
c93595dd
SC
1400#define MOVE_ADDRESS(ad) \
1401 if (r_extern) { \
1402 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1403 cache_ptr->section = (asection *)NULL; \
1404 cache_ptr->addend = ad; \
1405 } else { \
1406 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1407 switch (r_index) { \
1408 case N_TEXT: \
1409 case N_TEXT | N_EXT: \
1410 cache_ptr->section = obj_textsec(abfd); \
1411 cache_ptr->addend = ad - su->textsec->vma; \
1412 break; \
1413 case N_DATA: \
1414 case N_DATA | N_EXT: \
1415 cache_ptr->section = obj_datasec(abfd); \
1416 cache_ptr->addend = ad - su->datasec->vma; \
1417 break; \
1418 case N_BSS: \
1419 case N_BSS | N_EXT: \
1420 cache_ptr->section = obj_bsssec(abfd); \
1421 cache_ptr->addend = ad - su->bsssec->vma; \
1422 break; \
1423 case N_ABS: \
1424 case N_ABS | N_EXT: \
fc723380
JG
1425 cache_ptr->section = NULL; /* No section */ \
1426 cache_ptr->addend = ad; /* FIXME, is this right? */ \
c93595dd
SC
1427 BFD_ASSERT(1); \
1428 break; \
1429 default: \
fc723380
JG
1430 cache_ptr->section = NULL; /* No section */ \
1431 cache_ptr->addend = ad; /* FIXME, is this right? */ \
c93595dd
SC
1432 BFD_ASSERT(1); \
1433 break; \
1434 } \
1435 } \
1436
1437void
1438swap_ext_reloc_in (abfd, bytes, cache_ptr, symbols)
1439 bfd *abfd;
1440 struct reloc_ext_bytes *bytes;
1441 arelent *cache_ptr;
1442 asymbol **symbols;
1443{
1444 int r_index;
1445 int r_extern;
1446 unsigned int r_type;
1447 struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1448
1449 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1450
1451 /* now the fun stuff */
1452 if (abfd->xvec->header_byteorder_big_p != false) {
1453 r_index = (bytes->r_index[0] << 16)
1454 | (bytes->r_index[1] << 8)
1455 | bytes->r_index[2];
1456 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_BIG));
1457 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_BIG)
1458 >> RELOC_EXT_BITS_TYPE_SH_BIG;
1459 } else {
1460 r_index = (bytes->r_index[2] << 16)
1461 | (bytes->r_index[1] << 8)
1462 | bytes->r_index[0];
1463 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1464 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1465 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1466 }
1467
1468 cache_ptr->howto = howto_table_ext + r_type;
1469 MOVE_ADDRESS(bfd_h_getlong(abfd,bytes->r_addend));
c93595dd
SC
1470}
1471
1472void
1473swap_std_reloc_in (abfd, bytes, cache_ptr, symbols)
1474 bfd *abfd;
fc723380 1475 struct reloc_std_bytes *bytes;
c93595dd
SC
1476 arelent *cache_ptr;
1477 asymbol **symbols;
1478{
1479 int r_index;
1480 int r_extern;
1481 unsigned int r_length;
1482 int r_pcrel;
1483 int r_baserel, r_jmptable, r_relative;
1484 struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
fc723380 1485
c93595dd
SC
1486 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1487
1488 /* now the fun stuff */
1489 if (abfd->xvec->header_byteorder_big_p != false) {
1490 r_index = (bytes->r_index[0] << 16)
1491 | (bytes->r_index[1] << 8)
1492 | bytes->r_index[2];
1493 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_BIG));
1494 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_BIG));
1495 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_BIG));
1496 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1497 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_BIG));
1498 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_BIG)
fc723380 1499 >> RELOC_STD_BITS_LENGTH_SH_BIG;
c93595dd
SC
1500 } else {
1501 r_index = (bytes->r_index[2] << 16)
1502 | (bytes->r_index[1] << 8)
1503 | bytes->r_index[0];
1504 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1505 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_LITTLE));
1506 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1507 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1508 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1509 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_LITTLE)
fc723380 1510 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
c93595dd
SC
1511 }
1512
1513 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
1514 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1515
1516 MOVE_ADDRESS(0);
1517}
1518
1519/* Reloc hackery */
4a81b561
DHW
1520
1521boolean
1522sunos4_slurp_reloc_table (abfd, asect, symbols)
1523 bfd *abfd;
1524 sec_ptr asect;
1525 asymbol **symbols;
1526{
1527 unsigned int count;
1528 size_t reloc_size;
9846338e 1529 PTR relocs;
4a81b561 1530 arelent *reloc_cache;
c93595dd 1531 size_t each_size;
4a81b561
DHW
1532
1533 if (asect->relocation) return true;
1534
1535 if (asect->flags & SEC_CONSTRUCTOR) return true;
1536
1537 if (asect == obj_datasec (abfd)) {
1538 reloc_size = exec_hdr(abfd)->a_drsize;
1539 goto doit;
1540 }
1541
1542 if (asect == obj_textsec (abfd)) {
1543 reloc_size = exec_hdr(abfd)->a_trsize;
1544 goto doit;
1545 }
1546
1547 bfd_error = invalid_operation;
1548 return false;
1549
1550 doit:
1551 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
c93595dd
SC
1552 each_size = reloc_size_func(abfd);
1553
1554 count = reloc_size / each_size;
4a81b561 1555
9872a49c
SC
1556
1557 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1558 (arelent)));
fc723380
JG
1559 if (!reloc_cache) {
1560nomem:
1561 bfd_error = no_memory;
1562 return false;
1563 }
1564
9872a49c 1565 relocs = bfd_alloc (abfd, reloc_size);
fc723380
JG
1566 if (!relocs) {
1567 bfd_release (abfd, reloc_cache);
1568 goto nomem;
1569 }
4a81b561 1570
fc723380
JG
1571 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1572 bfd_release (abfd, relocs);
1573 bfd_release (abfd, reloc_cache);
4a81b561 1574 bfd_error = system_call_error;
4a81b561
DHW
1575 return false;
1576 }
1577
fc723380
JG
1578 if (each_size == RELOC_EXT_SIZE) {
1579 register struct reloc_ext_bytes *rptr = (struct reloc_ext_bytes *) relocs;
1580 unsigned int counter = 0;
1581 arelent *cache_ptr = reloc_cache;
c93595dd 1582
fc723380
JG
1583 for (; counter < count; counter++, rptr++, cache_ptr++) {
1584 swap_ext_reloc_in(abfd, rptr, cache_ptr, symbols);
c93595dd 1585 }
fc723380 1586 } else {
9846338e 1587 register struct reloc_std_bytes *rptr = (struct reloc_std_bytes *) relocs;
4a81b561
DHW
1588 unsigned int counter = 0;
1589 arelent *cache_ptr = reloc_cache;
1590
1591 for (; counter < count; counter++, rptr++, cache_ptr++) {
c93595dd 1592 swap_std_reloc_in(abfd, rptr, cache_ptr, symbols);
4a81b561 1593 }
4a81b561 1594
c93595dd 1595 }
fc723380
JG
1596
1597 bfd_release (abfd,relocs);
4a81b561
DHW
1598 asect->relocation = reloc_cache;
1599 asect->reloc_count = count;
1600 return true;
1601}
1602
c93595dd
SC
1603
1604
1605/* Write out a relocation section into an object file. */
1606
4a81b561
DHW
1607static boolean
1608sunos4_squirt_out_relocs (abfd, section)
1609 bfd *abfd;
1610 asection *section;
1611{
1612 arelent **generic;
fc723380 1613 unsigned char *native, *natptr;
c93595dd 1614 size_t each_size;
4a81b561
DHW
1615
1616 unsigned int count = section->reloc_count;
c93595dd 1617 size_t natsize;
4a81b561
DHW
1618
1619 if (count == 0) return true;
c93595dd
SC
1620
1621 each_size = reloc_size_func(abfd);
1622 natsize = each_size * count;
9872a49c 1623 native = (unsigned char *) bfd_zalloc (abfd, natsize);
4a81b561
DHW
1624 if (!native) {
1625 bfd_error = no_memory;
1626 return false;
1627 }
1628
c93595dd 1629 generic = section->orelocation;
4a81b561 1630
c93595dd
SC
1631 if (each_size == RELOC_EXT_SIZE)
1632 {
fc723380
JG
1633 for (natptr = native;
1634 count != 0;
1635 --count, natptr += each_size, ++generic)
1636 swap_ext_reloc_out (abfd, generic, (struct reloc_ext_bytes *)native);
c93595dd
SC
1637 }
1638 else
1639 {
fc723380
JG
1640 for (natptr = native;
1641 count != 0;
1642 --count, natptr += each_size, ++generic)
1643 swap_std_reloc_out(abfd, generic, (struct reloc_std_bytes *)native);
4a81b561
DHW
1644 }
1645
9846338e 1646 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
9872a49c 1647 bfd_release(abfd, native);
4a81b561
DHW
1648 return false;
1649 }
9872a49c 1650 bfd_release (abfd, native);
4a81b561
DHW
1651
1652 return true;
1653}
1654
1655/* This is stupid. This function should be a boolean predicate */
1656unsigned int
1657sunos4_canonicalize_reloc (abfd, section, relptr, symbols)
1658 bfd *abfd;
1659 sec_ptr section;
1660 arelent **relptr;
1661 asymbol **symbols;
1662{
1663 arelent *tblptr = section->relocation;
1664 unsigned int count;
1665
1666 if (!(tblptr || sunos4_slurp_reloc_table (abfd, section, symbols)))
1667 return 0;
1668
1669 if (section->flags & SEC_CONSTRUCTOR) {
1670 arelent_chain *chain = section->constructor_chain;
1671 for (count = 0; count < section->reloc_count; count ++) {
1672 *relptr ++ = &chain->relent;
1673 chain = chain->next;
1674 }
1675 }
1676 else {
1677 tblptr = section->relocation;
1678 if (!tblptr) return 0;
1679
1680 for (count = 0; count++ < section->reloc_count;)
1681 {
1682 *relptr++ = tblptr++;
1683 }
1684 }
1685 *relptr = 0;
1686
1687 return section->reloc_count;
1688}
1689
1690unsigned int
1691sunos4_get_reloc_upper_bound (abfd, asect)
1692 bfd *abfd;
1693 sec_ptr asect;
1694{
1695 if (bfd_get_format (abfd) != bfd_object) {
1696 bfd_error = invalid_operation;
1697 return 0;
1698 }
1699 if (asect->flags & SEC_CONSTRUCTOR) {
1700 return (sizeof (arelent *) * (asect->reloc_count+1));
1701 }
1702
c93595dd 1703
4a81b561
DHW
1704 if (asect == obj_datasec (abfd))
1705 return (sizeof (arelent *) *
c93595dd 1706 ((exec_hdr(abfd)->a_drsize / reloc_size_func(abfd))
4a81b561
DHW
1707 +1));
1708
1709 if (asect == obj_textsec (abfd))
1710 return (sizeof (arelent *) *
c93595dd 1711 ((exec_hdr(abfd)->a_trsize / reloc_size_func(abfd))
4a81b561
DHW
1712 +1));
1713
1714 bfd_error = invalid_operation;
1715 return 0;
1716}
1717
1718void
1719sunos4_reclaim_reloc (ignore_abfd, section)
1720 bfd *ignore_abfd;
1721 sec_ptr section;
1722{
9872a49c 1723
4a81b561
DHW
1724}
1725\f
1726
1727alent *
1728sunos4_get_lineno(ignore_abfd, ignore_symbol)
1729bfd *ignore_abfd;
4432f8ad 1730PTR ignore_symbol;
4a81b561
DHW
1731{
1732return (alent *)NULL;
1733}
1734
1735void
1736sunos4_print_symbol(ignore_abfd, file, symbol, how)
1737bfd *ignore_abfd;
1738FILE *file;
1739asymbol *symbol;
1740bfd_print_symbol_enum_type how;
1741{
1742 switch (how) {
1743 case bfd_print_symbol_name_enum:
1744 fprintf(file,"%s", symbol->name);
1745 break;
1746 case bfd_print_symbol_type_enum:
1747 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
fc723380 1748 (unsigned)(aout_symbol(symbol)->other & 0xff),
4a81b561
DHW
1749 (unsigned)(aout_symbol(symbol)->type));
1750 break;
1751 case bfd_print_symbol_all_enum:
1752 {
9846338e 1753 CONST char *section_name = symbol->section == (asection *)NULL ?
4a81b561
DHW
1754 "*abs" : symbol->section->name;
1755
9846338e 1756 bfd_print_symbol_vandf((PTR)file,symbol);
4a81b561
DHW
1757
1758 fprintf(file," %-5s %04x %02x %02x %s",
1759 section_name,
1760 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
fc723380 1761 (unsigned)(aout_symbol(symbol)->other & 0xff),
4a81b561
DHW
1762 (unsigned)(aout_symbol(symbol)->type & 0xff),
1763 symbol->name);
1764 }
1765 break;
1766 }
1767}
1768/* Once we know all the stuff that could be consed, we know how to clean
1769 it up. So why don't we? */
1770
1771boolean
1772sunos4_close_and_cleanup (abfd)
1773 bfd *abfd;
1774{
1775 if (!bfd_read_p (abfd))
1776 switch (abfd->format) {
1777 case bfd_archive:
1778 if (!_bfd_write_archive_contents (abfd)) return false; break;
1779 case bfd_object:
1780 if (!sunos4_write_object_contents (abfd)) return false; break;
1781 default: bfd_error = invalid_operation; return false;
1782 }
1783
4a81b561
DHW
1784 return true;
1785}
1786
1787/*
1788 provided a bfd, a section and an offset into the section, calculate
1789 and return the name of the source file and the line nearest to the
1790 wanted location.
1791*/
1792
1793boolean
aa802a32
SC
1794DEFUN(sunos4_find_nearest_line,(abfd,
1795 section,
1796 symbols,
1797 offset,
1798 filename_ptr,
1799 functionname_ptr,
1800 line_ptr),
1801 bfd *abfd AND
1802 asection *section AND
1803 asymbol **symbols AND
1804 bfd_vma offset AND
9846338e
SC
1805 CONST char **filename_ptr AND
1806 CONST char **functionname_ptr AND
aa802a32 1807 unsigned int *line_ptr)
4a81b561
DHW
1808{
1809 /* Run down the file looking for the filename, function and linenumber */
1810 asymbol **p;
1811 static char buffer[100];
1812 bfd_vma high_line_vma = ~0;
1813 bfd_vma low_func_vma = 0;
1814 asymbol *func = 0;
1815 *filename_ptr = abfd->filename;
1816 *functionname_ptr = 0;
1817 *line_ptr = 0;
1818 if (symbols != (asymbol **)NULL) {
1819 for (p = symbols; *p; p++) {
1820 aout_symbol_type *q = (aout_symbol_type *)(*p);
1821 switch (q->type){
1822 case N_SO:
1823 *filename_ptr = q->symbol.name;
1824 if (obj_textsec(abfd) != section) {
1825 return true;
1826 }
1827 break;
1828 case N_SLINE:
1829
1830 case N_DSLINE:
1831 case N_BSLINE:
1832 /* We'll keep this if it resolves nearer than the one we have already */
1833 if (q->symbol.value >= offset &&
1834 q->symbol.value < high_line_vma) {
1835 *line_ptr = q->desc;
1836 high_line_vma = q->symbol.value;
1837 }
1838 break;
1839 case N_FUN:
1840 {
1841 /* We'll keep this if it is nearer than the one we have already */
1842 if (q->symbol.value >= low_func_vma &&
1843 q->symbol.value <= offset) {
1844 low_func_vma = q->symbol.value;
1845 func = (asymbol *)q;
1846 }
1847 if (*line_ptr && func) {
9846338e 1848 CONST char *function = func->name;
4a81b561
DHW
1849 char *p;
1850 strncpy(buffer, function, sizeof(buffer)-1);
1851 buffer[sizeof(buffer)-1] = 0;
1852 /* Have to remove : stuff */
1853 p = strchr(buffer,':');
1854 if (p != NULL) {*p = NULL; }
1855 *functionname_ptr = buffer;
1856 return true;
1857
1858 }
1859 }
1860 break;
1861 }
1862 }
1863 }
1864
1865 return true;
1866
1867}
1868
39a2ce33
SC
1869static int
1870DEFUN(sunos4_sizeof_headers,(abfd),
1871 bfd *abfd)
1872{
1873return 0;
1874}
1875
9872a49c
SC
1876#define sunos4_openr_next_archived_file bfd_generic_openr_next_archived_file
1877#define sunos4_generic_stat_arch_elt bfd_generic_stat_arch_elt
1878#define sunos4_slurp_armap bfd_slurp_bsd_armap
1879#define sunos4_slurp_extended_name_table bfd_true
1880#define sunos4_write_armap bsd_write_armap
1881#define sunos4_truncate_arname bfd_bsd_truncate_arname
9846338e 1882bfd_target aout_big_vec =
4a81b561
DHW
1883{
1884 "a.out-generic-big", /* name */
1885 bfd_target_aout_flavour_enum,
1886 true, /* target byte order */
1887 true, /* target headers byte order */
1888 (HAS_RELOC | EXEC_P | /* object flags */
1889 HAS_LINENO | HAS_DEBUG |
1890 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1891 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
4a81b561
DHW
1892 ' ', /* ar_pad_char */
1893 16, /* ar_max_namelen */
4a81b561
DHW
1894 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1895 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1896
9872a49c
SC
1897 {_bfd_dummy_target, sunos4_object_p,
1898 bfd_generic_archive_p, sunos4_core_file_p},
1899 {bfd_false, sunos4_mkobject,
1900 _bfd_generic_mkarchive, bfd_false},
1901
1902 JUMP_TABLE(sunos4)
4a81b561
DHW
1903 };
1904
9872a49c 1905
726cc6ef
RP
1906bfd_target aout_little_vec =
1907{
1908 "a.out-generic-little", /* name */
1909 bfd_target_aout_flavour_enum,
9872a49c
SC
1910 false, /* target byte order */
1911 false, /* target headers byte order */
726cc6ef
RP
1912 (HAS_RELOC | EXEC_P | /* object flags */
1913 HAS_LINENO | HAS_DEBUG |
1914 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1915 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
726cc6ef
RP
1916 ' ', /* ar_pad_char */
1917 16, /* ar_max_namelen */
726cc6ef
RP
1918 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* data */
1919 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* hdrs */
1920
9872a49c
SC
1921
1922 {_bfd_dummy_target, sunos4_object_p,
1923 bfd_generic_archive_p, sunos4_core_file_p},
1924 {bfd_false, sunos4_mkobject,
1925 _bfd_generic_mkarchive, bfd_false},
1926
1927 JUMP_TABLE(sunos4)
726cc6ef
RP
1928 };
1929
This page took 0.10732 seconds and 4 git commands to generate.