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