Various portability lints.
[deliverable/binutils-gdb.git] / bfd / aout.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 /* It is possible to have a reloc with nothing, we generate an
1277 abs + 0 */
1278 r_addend = 0;
1279 r_index = N_ABS | N_EXT;
1280 }
1281 else if(g->section->output_section == obj_textsec(abfd)) {
1282 r_index = N_TEXT | N_EXT;
1283 r_addend += g->section->output_section->vma;
1284 }
1285 else if (g->section->output_section == obj_datasec(abfd)) {
1286 r_index = N_DATA | N_EXT;
1287 r_addend += g->section->output_section->vma;
1288 }
1289 else if (g->section->output_section == obj_bsssec(abfd)) {
1290 r_index = N_BSS | N_EXT ;
1291 r_addend += g->section->output_section->vma;
1292 }
1293 else {
1294 BFD_ASSERT(0);
1295 }
1296 }
1297
1298 /* now the fun stuff */
1299 if (abfd->xvec->header_byteorder_big_p != false) {
1300 natptr->r_index[0] = r_index >> 16;
1301 natptr->r_index[1] = r_index >> 8;
1302 natptr->r_index[2] = r_index;
1303 natptr->r_bits[0] =
1304 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
1305 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
1306 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
1307 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
1308 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
1309 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
1310 } else {
1311 natptr->r_index[2] = r_index >> 16;
1312 natptr->r_index[1] = r_index >> 8;
1313 natptr->r_index[0] = r_index;
1314 natptr->r_bits[0] =
1315 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
1316 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
1317 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
1318 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1319 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1320 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
1321 }
1322 }
1323
1324
1325 /* Extended stuff */
1326 /* Output extended relocation information to a file in target byte order. */
1327
1328 void
1329 swap_ext_reloc_out (abfd, g, natptr)
1330 bfd *abfd;
1331 arelent *g; /* Generic relocation struct */
1332 register struct reloc_ext_bytes *natptr;
1333 {
1334 int r_index;
1335 int r_extern;
1336 unsigned int r_type;
1337 unsigned int r_addend;
1338
1339 bfd_h_putlong (abfd, g->address, natptr->r_address);
1340
1341 /* Find a type in the output format which matches the input howto -
1342 at the moment we assume input format == output format FIXME!! */
1343 r_type = (enum reloc_type) g->howto->type;
1344
1345 r_addend = g->addend; /* Start here, see how it goes */
1346
1347 /* name was clobbered by sunos4_write_syms to be symbol index*/
1348
1349 if (g->sym_ptr_ptr != NULL)
1350 {
1351 if ((*(g->sym_ptr_ptr))->section) {
1352 /* put the section offset into the addend for output */
1353 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1354 }
1355
1356 r_index = stoi((*(g->sym_ptr_ptr))->name);
1357 r_extern = 1;
1358 }
1359 else {
1360 r_extern = 0;
1361 if (g->section == NULL) {
1362 BFD_ASSERT(0);
1363 r_index = N_ABS | N_EXT;
1364 }
1365 else if(g->section->output_section == obj_textsec(abfd)) {
1366 r_index = N_TEXT | N_EXT;
1367 r_addend += g->section->output_section->vma;
1368 }
1369 else if (g->section->output_section == obj_datasec(abfd)) {
1370 r_index = N_DATA | N_EXT;
1371 r_addend += g->section->output_section->vma;
1372 }
1373 else if (g->section->output_section == obj_bsssec(abfd)) {
1374 r_index = N_BSS | N_EXT ;
1375 r_addend += g->section->output_section->vma;
1376 }
1377 else {
1378 BFD_ASSERT(0);
1379 }
1380 }
1381
1382 /* now the fun stuff */
1383 if (abfd->xvec->header_byteorder_big_p != false) {
1384 natptr->r_index[0] = r_index >> 16;
1385 natptr->r_index[1] = r_index >> 8;
1386 natptr->r_index[2] = r_index;
1387 natptr->r_bits[0] =
1388 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1389 || (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1390 } else {
1391 natptr->r_index[2] = r_index >> 16;
1392 natptr->r_index[1] = r_index >> 8;
1393 natptr->r_index[0] = r_index;
1394 natptr->r_bits[0] =
1395 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1396 || (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1397 }
1398
1399 bfd_h_putlong (abfd, r_addend, natptr->r_addend);
1400 }
1401
1402 #define MOVE_ADDRESS(ad) \
1403 if (r_extern) { \
1404 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1405 cache_ptr->section = (asection *)NULL; \
1406 cache_ptr->addend = ad; \
1407 } else { \
1408 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1409 switch (r_index) { \
1410 case N_TEXT: \
1411 case N_TEXT | N_EXT: \
1412 cache_ptr->section = obj_textsec(abfd); \
1413 cache_ptr->addend = ad - su->textsec->vma; \
1414 break; \
1415 case N_DATA: \
1416 case N_DATA | N_EXT: \
1417 cache_ptr->section = obj_datasec(abfd); \
1418 cache_ptr->addend = ad - su->datasec->vma; \
1419 break; \
1420 case N_BSS: \
1421 case N_BSS | N_EXT: \
1422 cache_ptr->section = obj_bsssec(abfd); \
1423 cache_ptr->addend = ad - su->bsssec->vma; \
1424 break; \
1425 case N_ABS: \
1426 case N_ABS | N_EXT: \
1427 cache_ptr->section = NULL; /* No section */ \
1428 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1429 BFD_ASSERT(1); \
1430 break; \
1431 default: \
1432 cache_ptr->section = NULL; /* No section */ \
1433 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1434 BFD_ASSERT(1); \
1435 break; \
1436 } \
1437 } \
1438
1439 void
1440 swap_ext_reloc_in (abfd, bytes, cache_ptr, symbols)
1441 bfd *abfd;
1442 struct reloc_ext_bytes *bytes;
1443 arelent *cache_ptr;
1444 asymbol **symbols;
1445 {
1446 int r_index;
1447 int r_extern;
1448 unsigned int r_type;
1449 struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1450
1451 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1452
1453 /* now the fun stuff */
1454 if (abfd->xvec->header_byteorder_big_p != false) {
1455 r_index = (bytes->r_index[0] << 16)
1456 | (bytes->r_index[1] << 8)
1457 | bytes->r_index[2];
1458 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_BIG));
1459 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_BIG)
1460 >> RELOC_EXT_BITS_TYPE_SH_BIG;
1461 } else {
1462 r_index = (bytes->r_index[2] << 16)
1463 | (bytes->r_index[1] << 8)
1464 | bytes->r_index[0];
1465 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1466 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1467 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1468 }
1469
1470 cache_ptr->howto = howto_table_ext + r_type;
1471 MOVE_ADDRESS(bfd_h_getlong(abfd,bytes->r_addend));
1472 }
1473
1474 void
1475 swap_std_reloc_in (abfd, bytes, cache_ptr, symbols)
1476 bfd *abfd;
1477 struct reloc_std_bytes *bytes;
1478 arelent *cache_ptr;
1479 asymbol **symbols;
1480 {
1481 int r_index;
1482 int r_extern;
1483 unsigned int r_length;
1484 int r_pcrel;
1485 int r_baserel, r_jmptable, r_relative;
1486 struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1487
1488 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1489
1490 /* now the fun stuff */
1491 if (abfd->xvec->header_byteorder_big_p != false) {
1492 r_index = (bytes->r_index[0] << 16)
1493 | (bytes->r_index[1] << 8)
1494 | bytes->r_index[2];
1495 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_BIG));
1496 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_BIG));
1497 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_BIG));
1498 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1499 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_BIG));
1500 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_BIG)
1501 >> RELOC_STD_BITS_LENGTH_SH_BIG;
1502 } else {
1503 r_index = (bytes->r_index[2] << 16)
1504 | (bytes->r_index[1] << 8)
1505 | bytes->r_index[0];
1506 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1507 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_LITTLE));
1508 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1509 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1510 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1511 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_LITTLE)
1512 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1513 }
1514
1515 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
1516 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1517
1518 MOVE_ADDRESS(0);
1519 }
1520
1521 /* Reloc hackery */
1522
1523 boolean
1524 sunos4_slurp_reloc_table (abfd, asect, symbols)
1525 bfd *abfd;
1526 sec_ptr asect;
1527 asymbol **symbols;
1528 {
1529 unsigned int count;
1530 size_t reloc_size;
1531 PTR relocs;
1532 arelent *reloc_cache;
1533 size_t each_size;
1534
1535 if (asect->relocation) return true;
1536
1537 if (asect->flags & SEC_CONSTRUCTOR) return true;
1538
1539 if (asect == obj_datasec (abfd)) {
1540 reloc_size = exec_hdr(abfd)->a_drsize;
1541 goto doit;
1542 }
1543
1544 if (asect == obj_textsec (abfd)) {
1545 reloc_size = exec_hdr(abfd)->a_trsize;
1546 goto doit;
1547 }
1548
1549 bfd_error = invalid_operation;
1550 return false;
1551
1552 doit:
1553 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1554 each_size = reloc_size_func(abfd);
1555
1556 count = reloc_size / each_size;
1557
1558
1559 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1560 (arelent)));
1561 if (!reloc_cache) {
1562 nomem:
1563 bfd_error = no_memory;
1564 return false;
1565 }
1566
1567 relocs = bfd_alloc (abfd, reloc_size);
1568 if (!relocs) {
1569 bfd_release (abfd, reloc_cache);
1570 goto nomem;
1571 }
1572
1573 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1574 bfd_release (abfd, relocs);
1575 bfd_release (abfd, reloc_cache);
1576 bfd_error = system_call_error;
1577 return false;
1578 }
1579
1580 if (each_size == RELOC_EXT_SIZE) {
1581 register struct reloc_ext_bytes *rptr = (struct reloc_ext_bytes *) relocs;
1582 unsigned int counter = 0;
1583 arelent *cache_ptr = reloc_cache;
1584
1585 for (; counter < count; counter++, rptr++, cache_ptr++) {
1586 swap_ext_reloc_in(abfd, rptr, cache_ptr, symbols);
1587 }
1588 } else {
1589 register struct reloc_std_bytes *rptr = (struct reloc_std_bytes *) relocs;
1590 unsigned int counter = 0;
1591 arelent *cache_ptr = reloc_cache;
1592
1593 for (; counter < count; counter++, rptr++, cache_ptr++) {
1594 swap_std_reloc_in(abfd, rptr, cache_ptr, symbols);
1595 }
1596
1597 }
1598
1599 bfd_release (abfd,relocs);
1600 asect->relocation = reloc_cache;
1601 asect->reloc_count = count;
1602 return true;
1603 }
1604
1605
1606
1607 /* Write out a relocation section into an object file. */
1608
1609 static boolean
1610 sunos4_squirt_out_relocs (abfd, section)
1611 bfd *abfd;
1612 asection *section;
1613 {
1614 arelent **generic;
1615 unsigned char *native, *natptr;
1616 size_t each_size;
1617
1618 unsigned int count = section->reloc_count;
1619 size_t natsize;
1620
1621 if (count == 0) return true;
1622
1623 each_size = reloc_size_func(abfd);
1624 natsize = each_size * count;
1625 native = (unsigned char *) bfd_zalloc (abfd, natsize);
1626 if (!native) {
1627 bfd_error = no_memory;
1628 return false;
1629 }
1630
1631 generic = section->orelocation;
1632
1633 if (each_size == RELOC_EXT_SIZE)
1634 {
1635 for (natptr = native;
1636 count != 0;
1637 --count, natptr += each_size, ++generic)
1638 swap_ext_reloc_out (abfd, *generic, (struct reloc_ext_bytes *)natptr);
1639 }
1640 else
1641 {
1642 for (natptr = native;
1643 count != 0;
1644 --count, natptr += each_size, ++generic)
1645 swap_std_reloc_out(abfd, *generic, (struct reloc_std_bytes *)natptr);
1646 }
1647
1648 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1649 bfd_release(abfd, native);
1650 return false;
1651 }
1652 bfd_release (abfd, native);
1653
1654 return true;
1655 }
1656
1657 /* This is stupid. This function should be a boolean predicate */
1658 unsigned int
1659 sunos4_canonicalize_reloc (abfd, section, relptr, symbols)
1660 bfd *abfd;
1661 sec_ptr section;
1662 arelent **relptr;
1663 asymbol **symbols;
1664 {
1665 arelent *tblptr = section->relocation;
1666 unsigned int count;
1667
1668 if (!(tblptr || sunos4_slurp_reloc_table (abfd, section, symbols)))
1669 return 0;
1670
1671 if (section->flags & SEC_CONSTRUCTOR) {
1672 arelent_chain *chain = section->constructor_chain;
1673 for (count = 0; count < section->reloc_count; count ++) {
1674 *relptr ++ = &chain->relent;
1675 chain = chain->next;
1676 }
1677 }
1678 else {
1679 tblptr = section->relocation;
1680 if (!tblptr) return 0;
1681
1682 for (count = 0; count++ < section->reloc_count;)
1683 {
1684 *relptr++ = tblptr++;
1685 }
1686 }
1687 *relptr = 0;
1688
1689 return section->reloc_count;
1690 }
1691
1692 unsigned int
1693 sunos4_get_reloc_upper_bound (abfd, asect)
1694 bfd *abfd;
1695 sec_ptr asect;
1696 {
1697 if (bfd_get_format (abfd) != bfd_object) {
1698 bfd_error = invalid_operation;
1699 return 0;
1700 }
1701 if (asect->flags & SEC_CONSTRUCTOR) {
1702 return (sizeof (arelent *) * (asect->reloc_count+1));
1703 }
1704
1705
1706 if (asect == obj_datasec (abfd))
1707 return (sizeof (arelent *) *
1708 ((exec_hdr(abfd)->a_drsize / reloc_size_func(abfd))
1709 +1));
1710
1711 if (asect == obj_textsec (abfd))
1712 return (sizeof (arelent *) *
1713 ((exec_hdr(abfd)->a_trsize / reloc_size_func(abfd))
1714 +1));
1715
1716 bfd_error = invalid_operation;
1717 return 0;
1718 }
1719
1720 void
1721 sunos4_reclaim_reloc (ignore_abfd, ignore)
1722 bfd *ignore_abfd;
1723 sec_ptr ignore;
1724 {
1725
1726 }
1727 \f
1728
1729 alent *
1730 sunos4_get_lineno(ignore_abfd, ignore_symbol)
1731 bfd *ignore_abfd;
1732 PTR ignore_symbol;
1733 {
1734 return (alent *)NULL;
1735 }
1736
1737 void
1738 sunos4_print_symbol(ignore_abfd, file, symbol, how)
1739 bfd *ignore_abfd;
1740 FILE *file;
1741 asymbol *symbol;
1742 bfd_print_symbol_enum_type how;
1743 {
1744 switch (how) {
1745 case bfd_print_symbol_name_enum:
1746 fprintf(file,"%s", symbol->name);
1747 break;
1748 case bfd_print_symbol_type_enum:
1749 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1750 (unsigned)(aout_symbol(symbol)->other & 0xff),
1751 (unsigned)(aout_symbol(symbol)->type));
1752 break;
1753 case bfd_print_symbol_all_enum:
1754 {
1755 CONST char *section_name = symbol->section == (asection *)NULL ?
1756 "*abs" : symbol->section->name;
1757
1758 bfd_print_symbol_vandf((PTR)file,symbol);
1759
1760 fprintf(file," %-5s %04x %02x %02x %s",
1761 section_name,
1762 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1763 (unsigned)(aout_symbol(symbol)->other & 0xff),
1764 (unsigned)(aout_symbol(symbol)->type & 0xff),
1765 symbol->name);
1766 }
1767 break;
1768 }
1769 }
1770 /* Once we know all the stuff that could be consed, we know how to clean
1771 it up. So why don't we? */
1772
1773 boolean
1774 sunos4_close_and_cleanup (abfd)
1775 bfd *abfd;
1776 {
1777 if (!bfd_read_p (abfd))
1778 switch (abfd->format) {
1779 case bfd_archive:
1780 if (!_bfd_write_archive_contents (abfd)) return false; break;
1781 case bfd_object:
1782 if (!sunos4_write_object_contents (abfd)) return false; break;
1783 default: bfd_error = invalid_operation; return false;
1784 }
1785
1786 return true;
1787 }
1788
1789 /*
1790 provided a bfd, a section and an offset into the section, calculate
1791 and return the name of the source file and the line nearest to the
1792 wanted location.
1793 */
1794
1795 boolean
1796 DEFUN(sunos4_find_nearest_line,(abfd,
1797 section,
1798 symbols,
1799 offset,
1800 filename_ptr,
1801 functionname_ptr,
1802 line_ptr),
1803 bfd *abfd AND
1804 asection *section AND
1805 asymbol **symbols AND
1806 bfd_vma offset AND
1807 CONST char **filename_ptr AND
1808 CONST char **functionname_ptr AND
1809 unsigned int *line_ptr)
1810 {
1811 /* Run down the file looking for the filename, function and linenumber */
1812 asymbol **p;
1813 static char buffer[100];
1814 bfd_vma high_line_vma = ~0;
1815 bfd_vma low_func_vma = 0;
1816 asymbol *func = 0;
1817 *filename_ptr = abfd->filename;
1818 *functionname_ptr = 0;
1819 *line_ptr = 0;
1820 if (symbols != (asymbol **)NULL) {
1821 for (p = symbols; *p; p++) {
1822 aout_symbol_type *q = (aout_symbol_type *)(*p);
1823 switch (q->type){
1824 case N_SO:
1825 *filename_ptr = q->symbol.name;
1826 if (obj_textsec(abfd) != section) {
1827 return true;
1828 }
1829 break;
1830 case N_SLINE:
1831
1832 case N_DSLINE:
1833 case N_BSLINE:
1834 /* We'll keep this if it resolves nearer than the one we have already */
1835 if (q->symbol.value >= offset &&
1836 q->symbol.value < high_line_vma) {
1837 *line_ptr = q->desc;
1838 high_line_vma = q->symbol.value;
1839 }
1840 break;
1841 case N_FUN:
1842 {
1843 /* We'll keep this if it is nearer than the one we have already */
1844 if (q->symbol.value >= low_func_vma &&
1845 q->symbol.value <= offset) {
1846 low_func_vma = q->symbol.value;
1847 func = (asymbol *)q;
1848 }
1849 if (*line_ptr && func) {
1850 CONST char *function = func->name;
1851 char *p;
1852 strncpy(buffer, function, sizeof(buffer)-1);
1853 buffer[sizeof(buffer)-1] = 0;
1854 /* Have to remove : stuff */
1855 p = strchr(buffer,':');
1856 if (p != NULL) {*p = NULL; }
1857 *functionname_ptr = buffer;
1858 return true;
1859
1860 }
1861 }
1862 break;
1863 }
1864 }
1865 }
1866
1867 return true;
1868
1869 }
1870
1871 static int
1872 DEFUN(sunos4_sizeof_headers,(ignore_abfd),
1873 bfd *ignore_abfd)
1874 {
1875 return 0; /* FIXME, this is the wrong value! */
1876 }
1877
1878 #define sunos4_openr_next_archived_file bfd_generic_openr_next_archived_file
1879 #define sunos4_generic_stat_arch_elt bfd_generic_stat_arch_elt
1880 #define sunos4_slurp_armap bfd_slurp_bsd_armap
1881 #define sunos4_slurp_extended_name_table bfd_true
1882 #define sunos4_write_armap bsd_write_armap
1883 #define sunos4_truncate_arname bfd_bsd_truncate_arname
1884 bfd_target aout_big_vec =
1885 {
1886 "a.out-generic-big", /* name */
1887 bfd_target_aout_flavour_enum,
1888 true, /* target byte order */
1889 true, /* target headers byte order */
1890 (HAS_RELOC | EXEC_P | /* object flags */
1891 HAS_LINENO | HAS_DEBUG |
1892 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1893 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1894 ' ', /* ar_pad_char */
1895 16, /* ar_max_namelen */
1896 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1897 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1898
1899 {_bfd_dummy_target, sunos4_object_p,
1900 bfd_generic_archive_p, sunos4_core_file_p},
1901 {bfd_false, sunos4_mkobject,
1902 _bfd_generic_mkarchive, bfd_false},
1903
1904 JUMP_TABLE(sunos4)
1905 };
1906
1907
1908 bfd_target aout_little_vec =
1909 {
1910 "a.out-generic-little", /* name */
1911 bfd_target_aout_flavour_enum,
1912 false, /* target byte order */
1913 false, /* target headers byte order */
1914 (HAS_RELOC | EXEC_P | /* object flags */
1915 HAS_LINENO | HAS_DEBUG |
1916 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1917 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1918 ' ', /* ar_pad_char */
1919 16, /* ar_max_namelen */
1920 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* data */
1921 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* hdrs */
1922
1923
1924 {_bfd_dummy_target, sunos4_object_p,
1925 bfd_generic_archive_p, sunos4_core_file_p},
1926 {bfd_false, sunos4_mkobject,
1927 _bfd_generic_mkarchive, bfd_false},
1928
1929 JUMP_TABLE(sunos4)
1930 };
This page took 0.070906 seconds and 5 git commands to generate.