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