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