f4e70b0a4ba79a407c84a9c972f9137c271df76a
[deliverable/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_textsec(abfd)->size = align_power(obj_textsec(abfd)->size,
767 obj_textsec(abfd)->alignment_power);
768 obj_datasec(abfd)->filepos = obj_textsec (abfd)->filepos + obj_textsec (abfd)->size;
769 obj_datasec(abfd)->size = align_power(obj_datasec(abfd)->size,
770 obj_datasec(abfd)->alignment_power);
771
772 }
773 /* regardless, once we know what we're doing, we might as well get going */
774 if (section != obj_bsssec(abfd)) {
775 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
776
777 if (count) {
778 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
779 true : false;
780 }
781 return false;
782 }
783 return true;
784 }
785
786 boolean
787 sunos4_get_section_contents (abfd, section, location, offset, count)
788 bfd *abfd;
789 sec_ptr section;
790 PTR location;
791 file_ptr offset;
792 int count;
793 {
794 if (count) {
795 if (offset >= section->size) return false;
796
797 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
798
799 return (bfd_read (location, 1, count, abfd) == count) ? true:false;
800 }
801 else return true;
802 }
803
804 \f
805 /* Classify stabs symbols */
806
807
808 #define sym_in_text_section(sym) \
809 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
810
811 #define sym_in_data_section(sym) \
812 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
813
814 #define sym_in_bss_section(sym) \
815 (((sym)->n_type & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
816
817 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
818 zero in the "value" field. Nonzeroes there are fortrancommon
819 symbols. */
820 #define sym_is_undefined(sym) \
821 ((sym)->n_type == (N_UNDF | N_EXT) && (sym)->n_value == 0)
822
823 /* Symbol is a global definition if N_EXT is on and if it has
824 a nonzero type field. */
825 #define sym_is_global_defn(sym) \
826 (((sym)->n_type & N_EXT) && (sym)->n_type & N_TYPE)
827
828 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
829 are on. */
830 #define sym_is_debugger_info(sym) \
831 ((sym)->n_type & ~(N_EXT | N_TYPE))
832
833 #define sym_is_fortrancommon(sym) \
834 (((sym)->n_type == (N_EXT)) && (sym)->n_value != 0)
835
836 /* Symbol is absolute if it has N_ABS set */
837 #define sym_is_absolute(sym) \
838 (((sym)->n_type & N_TYPE)== N_ABS)
839
840
841 #define sym_is_indirect(sym) \
842 (((sym)->n_type & N_ABS)== N_ABS)
843
844 /* Only in their own functions for ease of debugging; when sym flags have
845 stabilised these should be inlined into their (single) caller */
846
847 static void
848 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd)
849 struct nlist *sym_pointer;
850 aout_symbol_type *cache_ptr;
851 bfd *abfd;
852 {
853 switch (cache_ptr->type & N_TYPE) {
854 case N_SETA:
855 case N_SETT:
856 case N_SETD:
857 case N_SETB:
858 {
859 asection *section = bfd_make_section(abfd,
860 cache_ptr->symbol.name);
861 arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
862
863 switch ( (cache_ptr->type & N_TYPE) ) {
864 case N_SETA:
865 reloc->relent.section = (asection *)NULL;
866 cache_ptr->symbol.section = (asection *)NULL;
867 break;
868 case N_SETT:
869 reloc->relent.section = (asection *)obj_textsec(abfd);
870 cache_ptr->symbol.value -= reloc->relent.section->vma;
871 break;
872 case N_SETD:
873 reloc->relent.section = (asection *)obj_datasec(abfd);
874 cache_ptr->symbol.value -= reloc->relent.section->vma;
875 break;
876 case N_SETB:
877 reloc->relent.section = (asection *)obj_bsssec(abfd);
878 cache_ptr->symbol.value -= reloc->relent.section->vma;
879 break;
880 }
881 cache_ptr->symbol.section = reloc->relent.section;
882 reloc->relent.addend = cache_ptr->symbol.value ;
883
884 /* We modify the symbol to belong to a section depending upon the
885 name of the symbol - probably __CTOR__ or __DTOR__ but we don't
886 really care, and add to the size of the section to contain a
887 pointer to the symbol. Build a reloc entry to relocate to this
888 symbol attached to this section. */
889
890 section->flags = SEC_CONSTRUCTOR;
891 section->reloc_count++;
892 section->alignment_power = 2;
893 reloc->relent.sym_ptr_ptr = (asymbol **)NULL;
894 reloc->next = section->constructor_chain;
895 section->constructor_chain = reloc;
896 reloc->relent.address = section->size;
897 section->size += sizeof(int *);
898
899 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
900 cache_ptr->symbol.flags |= BSF_DEBUGGING ;
901 }
902 break;
903 default:
904
905 if (sym_is_debugger_info (sym_pointer)) {
906 cache_ptr->symbol.flags = BSF_DEBUGGING ;
907 /* Work out the section correct for this symbol */
908 switch (sym_pointer->n_type & N_TYPE)
909 {
910 case N_TEXT:
911 case N_FN:
912 cache_ptr->symbol.section = obj_textsec (abfd);
913 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
914 break;
915 case N_DATA:
916 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
917 cache_ptr->symbol.section = obj_datasec (abfd);
918 break;
919 case N_BSS :
920 cache_ptr->symbol.section = obj_bsssec (abfd);
921 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
922 break;
923 case N_ABS:
924 default:
925 cache_ptr->symbol.section = 0;
926 break;
927 }
928 }
929 else {
930 if (sym_is_fortrancommon (sym_pointer))
931 {
932 cache_ptr->symbol.flags = BSF_FORT_COMM;
933 cache_ptr->symbol.section = (asection *)NULL;
934 }
935 else {
936 if (sym_is_undefined (sym_pointer)) {
937 cache_ptr->symbol.flags = BSF_UNDEFINED;
938 }
939 else if (sym_is_global_defn (sym_pointer)) {
940 cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
941 }
942
943 else if (sym_is_absolute (sym_pointer)) {
944 cache_ptr->symbol.flags = BSF_ABSOLUTE;
945 }
946 else {
947 cache_ptr->symbol.flags = BSF_LOCAL;
948 }
949
950 /* In a.out, the value of a symbol is always relative to the
951 * start of the file, if this is a data symbol we'll subtract
952 * the size of the text section to get the section relative
953 * value. If this is a bss symbol (which would be strange)
954 * we'll subtract the size of the previous two sections
955 * to find the section relative address.
956 */
957
958 if (sym_in_text_section (sym_pointer)) {
959 cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
960 cache_ptr->symbol.section = obj_textsec (abfd);
961 }
962 else if (sym_in_data_section (sym_pointer)){
963 cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
964 cache_ptr->symbol.section = obj_datasec (abfd);
965 }
966 else if (sym_in_bss_section(sym_pointer)) {
967 cache_ptr->symbol.section = obj_bsssec (abfd);
968 cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
969 }
970 else {
971 cache_ptr->symbol.section = (asection *)NULL;
972 cache_ptr->symbol.flags |= BSF_ABSOLUTE;
973 }
974 }
975 }
976 }
977 }
978
979 void
980 translate_to_native_sym_flags (sym_pointer, cache_ptr_g, abfd)
981 struct nlist *sym_pointer;
982 PTR cache_ptr_g;
983 bfd *abfd;
984 {
985 asymbol *cache_ptr = (asymbol *)cache_ptr_g;
986
987 /* FIXME check for writing bss */
988 if (bfd_get_section(cache_ptr)) {
989 if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
990 sym_pointer->n_type |= N_BSS;
991 }
992 else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
993 sym_pointer->n_type |= N_DATA;
994 }
995 else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
996 sym_pointer->n_type |= N_TEXT;
997 }
998 else {
999 bfd_error_vector.nonrepresentable_section(abfd,
1000 bfd_get_output_section(cache_ptr)->name);
1001 }
1002 /* Turn the symbol from section relative to absolute again */
1003 sym_pointer->n_value +=
1004 cache_ptr->section->output_section->vma
1005 + cache_ptr->section->output_offset ;
1006 }
1007 else {
1008 sym_pointer->n_type |= N_ABS;
1009 }
1010
1011 if (cache_ptr->flags & (BSF_FORT_COMM | BSF_UNDEFINED)) {
1012 sym_pointer->n_type = (N_UNDF | N_EXT);
1013 return;
1014 }
1015
1016 if (cache_ptr->flags & BSF_ABSOLUTE) {
1017 sym_pointer->n_type |= N_ABS;
1018 }
1019
1020 if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1021 sym_pointer->n_type |= N_EXT;
1022 }
1023 if (cache_ptr->flags & BSF_DEBUGGING) {
1024 sym_pointer->n_type = ((aout_symbol_type *)cache_ptr)->type;
1025 }
1026 }
1027 \f
1028 /* Native-level interface to symbols. */
1029
1030 /* We read the symbols into a buffer, which is discarded when this
1031 function exits. We read the strings into a buffer large enough to
1032 hold them all plus all the cached symbol entries. */
1033
1034 asymbol *
1035 sunos4_make_empty_symbol (abfd)
1036 bfd *abfd;
1037 {
1038 aout_symbol_type *new =
1039 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1040 new->symbol.the_bfd = abfd;
1041
1042 return &new->symbol;
1043 }
1044
1045 boolean
1046 DEFUN(sunos4_slurp_symbol_table, (abfd),
1047 bfd *abfd)
1048 {
1049 size_t symbol_size;
1050 size_t string_size;
1051 unsigned char string_chars[LONG_SIZE];
1052 struct nlist *syms;
1053 char *strings;
1054 aout_symbol_type *cached;
1055
1056 /* If there's no work to be done, don't do any */
1057 if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1058 symbol_size = exec_hdr(abfd)->a_syms;
1059 if (symbol_size == 0) {
1060 bfd_error = no_symbols;
1061 return false;
1062 }
1063
1064 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1065 if (bfd_read ((PTR)string_chars, LONG_SIZE, 1, abfd) != LONG_SIZE)
1066 return false;
1067 string_size = bfd_h_getlong (abfd, string_chars);
1068
1069 strings = bfd_alloc(abfd, string_size + 1);
1070 cached = (aout_symbol_type *)
1071 bfd_zalloc(abfd, bfd_get_symcount (abfd) * sizeof(aout_symbol_type));
1072 /* Alloc this last, so we can free it if obstack is in use. */
1073 syms = (struct nlist *) bfd_alloc(abfd, symbol_size);
1074
1075 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1076 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
1077 bailout:
1078 if (syms) bfd_release (abfd, syms);
1079 if (cached) bfd_release (abfd, cached);
1080 if (strings)bfd_release (abfd, strings);
1081 return false;
1082 }
1083
1084 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1085 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
1086 goto bailout;
1087 }
1088
1089 /* OK, now walk the new symtable, cacheing symbol properties */
1090 {
1091 register struct nlist *sym_pointer;
1092 register struct nlist *sym_end = syms + bfd_get_symcount (abfd);
1093 register aout_symbol_type *cache_ptr = cached;
1094
1095 /* run through the table and byte swap if needed */
1096 for (sym_pointer = syms; sym_pointer < sym_end; sym_pointer++) {
1097 sym_pointer->n_un.n_strx =
1098 bfd_h_get_x (abfd, &sym_pointer->n_un.n_strx);
1099 sym_pointer->n_desc =
1100 bfd_h_get_x (abfd, &sym_pointer->n_desc);
1101 sym_pointer->n_value =
1102 bfd_h_get_x (abfd, &sym_pointer->n_value);
1103 sym_pointer->n_other = (char)
1104 bfd_h_get_x(abfd, &sym_pointer->n_other);
1105 sym_pointer->n_type = (char)
1106 bfd_h_get_x(abfd, &sym_pointer->n_type);
1107 }
1108
1109 /* Run through table and copy values */
1110 for (sym_pointer = syms, cache_ptr = cached;
1111 sym_pointer < sym_end; sym_pointer++, cache_ptr++)
1112 {
1113 cache_ptr->symbol.the_bfd = abfd;
1114 if (sym_pointer->n_un.n_strx)
1115 cache_ptr->symbol.name = sym_pointer->n_un.n_strx + strings;
1116 else
1117 cache_ptr->symbol.name = (char *)NULL;
1118 cache_ptr->symbol.value = sym_pointer->n_value;
1119 cache_ptr->desc = sym_pointer->n_desc;
1120 cache_ptr->other = sym_pointer->n_other;
1121 cache_ptr->type = sym_pointer->n_type;
1122 cache_ptr->symbol.udata = 0;
1123 translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1124
1125 }
1126 }
1127
1128 obj_aout_symbols (abfd) = cached;
1129 bfd_release (abfd, (PTR)syms);
1130
1131 return true;
1132 }
1133
1134
1135 void
1136 DEFUN(sunos4_write_syms,(abfd),
1137 bfd *abfd)
1138 {
1139 unsigned int count ;
1140 asymbol **generic = bfd_get_outsymbols (abfd);
1141
1142 unsigned int stindex = sizeof(stindex); /* initial string length */
1143
1144 for (count = 0; count < bfd_get_symcount (abfd); count++) {
1145 asymbol *g = generic[count];
1146 struct nlist nsp;
1147
1148 if (g->name) {
1149 unsigned int length = strlen(g->name) +1;
1150 bfd_h_putlong (abfd, stindex, (unsigned char *)&nsp.n_un.n_strx);
1151 stindex += length;
1152 }
1153 else {
1154 bfd_h_putlong (abfd, 0, (unsigned char *)&nsp.n_un.n_strx);
1155 }
1156
1157 if (g->the_bfd->xvec->flavour == abfd->xvec->flavour)
1158 {
1159 nsp.n_desc = aout_symbol( g)->desc;
1160 nsp.n_other = aout_symbol(g)->other;
1161 nsp.n_type = aout_symbol(g)->type;
1162 }
1163 else
1164 {
1165 nsp.n_desc = 0;
1166 nsp.n_other = 0;
1167 nsp.n_type = 0;
1168 }
1169
1170
1171 nsp.n_value = g->value;
1172 translate_to_native_sym_flags (&nsp, (PTR)g, abfd);
1173
1174
1175 bfd_h_putshort (abfd, nsp.n_desc, (unsigned char *)&nsp.n_desc);
1176 bfd_h_putlong (abfd, nsp.n_value, (unsigned char *)&nsp.n_value);
1177 bfd_write((PTR)&nsp,1, sizeof(nsp), abfd);
1178 }
1179
1180
1181 /* Now output the strings. Be sure to put string length into correct
1182 * byte ordering before writing it.
1183 */
1184 bfd_h_putlong (abfd, stindex, (unsigned char *)&stindex);
1185
1186 bfd_write((PTR)&stindex, 1, sizeof(stindex), abfd);
1187
1188 generic = bfd_get_outsymbols(abfd);
1189 for (count = 0; count < bfd_get_symcount(abfd); count++)
1190 {
1191 asymbol *g = *(generic++);
1192
1193 if (g->name)
1194 {
1195 size_t length = strlen(g->name)+1;
1196 bfd_write((PTR)g->name, 1, length, abfd);
1197 }
1198 if ((g->flags & BSF_FAKE)==0) {
1199 g->name = itos(count); /* smash the generic symbol */
1200 }
1201 }
1202 }
1203
1204
1205 void
1206 DEFUN(sunos4_reclaim_symbol_table,(abfd),
1207 bfd *abfd)
1208 {
1209
1210 }
1211 \f
1212 unsigned int
1213 sunos4_get_symtab_upper_bound (abfd)
1214 bfd *abfd;
1215 {
1216 if (!sunos4_slurp_symbol_table (abfd)) return 0;
1217
1218 return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1219 }
1220
1221 unsigned int
1222 sunos4_get_symtab (abfd, location)
1223 bfd *abfd;
1224 asymbol **location;
1225 {
1226 unsigned int counter = 0;
1227 aout_symbol_type *symbase;
1228
1229 if (!sunos4_slurp_symbol_table (abfd)) return 0;
1230
1231 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1232 *(location++) = (asymbol *)( symbase++);
1233 *location++ =0;
1234 return bfd_get_symcount(abfd);
1235 }
1236
1237 \f
1238 /* Standard reloc stuff */
1239 /* Output standard relocation information to a file in target byte order. */
1240
1241 void
1242 swap_std_reloc_out (abfd, g, natptr)
1243 bfd *abfd;
1244 arelent *g; /* Generic relocation struct */
1245 struct reloc_std_bytes *natptr;
1246 {
1247 int r_index;
1248 int r_extern;
1249 unsigned int r_length;
1250 int r_pcrel;
1251 int r_baserel, r_jmptable, r_relative;
1252 unsigned int r_addend;
1253
1254 bfd_h_putlong (abfd, g->address, natptr->r_address);
1255
1256 r_length = g->howto->size ; /* Size as a power of two */
1257 r_pcrel = (int) g->howto->pc_relative; /* Relative to PC? */
1258 /* r_baserel, r_jmptable, r_relative??? FIXME-soon */
1259 r_baserel = 0;
1260 r_jmptable = 0;
1261 r_relative = 0;
1262
1263 r_addend = g->addend; /* Start here, see how it goes */
1264
1265 /* name was clobbered by sunos4_write_syms to be symbol index */
1266
1267 if (g->sym_ptr_ptr != NULL)
1268 {
1269 if ((*(g->sym_ptr_ptr))->section) {
1270 /* put the section offset into the addend for output */
1271 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1272 }
1273
1274 r_index = stoi((*(g->sym_ptr_ptr))->name);
1275 r_extern = 1;
1276 }
1277 else {
1278 r_extern = 0;
1279 if (g->section == NULL) {
1280 /* It is possible to have a reloc with nothing, we generate an
1281 abs + 0 */
1282 r_addend = 0;
1283 r_index = N_ABS | N_EXT;
1284 }
1285 else if(g->section->output_section == obj_textsec(abfd)) {
1286 r_index = N_TEXT | N_EXT;
1287 r_addend += g->section->output_section->vma;
1288 }
1289 else if (g->section->output_section == obj_datasec(abfd)) {
1290 r_index = N_DATA | N_EXT;
1291 r_addend += g->section->output_section->vma;
1292 }
1293 else if (g->section->output_section == obj_bsssec(abfd)) {
1294 r_index = N_BSS | N_EXT ;
1295 r_addend += g->section->output_section->vma;
1296 }
1297 else {
1298 BFD_ASSERT(0);
1299 }
1300 }
1301
1302 /* now the fun stuff */
1303 if (abfd->xvec->header_byteorder_big_p != false) {
1304 natptr->r_index[0] = r_index >> 16;
1305 natptr->r_index[1] = r_index >> 8;
1306 natptr->r_index[2] = r_index;
1307 natptr->r_bits[0] =
1308 (r_extern? RELOC_STD_BITS_EXTERN_BIG: 0)
1309 | (r_pcrel? RELOC_STD_BITS_PCREL_BIG: 0)
1310 | (r_baserel? RELOC_STD_BITS_BASEREL_BIG: 0)
1311 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_BIG: 0)
1312 | (r_relative? RELOC_STD_BITS_RELATIVE_BIG: 0)
1313 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG);
1314 } else {
1315 natptr->r_index[2] = r_index >> 16;
1316 natptr->r_index[1] = r_index >> 8;
1317 natptr->r_index[0] = r_index;
1318 natptr->r_bits[0] =
1319 (r_extern? RELOC_STD_BITS_EXTERN_LITTLE: 0)
1320 | (r_pcrel? RELOC_STD_BITS_PCREL_LITTLE: 0)
1321 | (r_baserel? RELOC_STD_BITS_BASEREL_LITTLE: 0)
1322 | (r_jmptable? RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1323 | (r_relative? RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1324 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE);
1325 }
1326 }
1327
1328
1329 /* Extended stuff */
1330 /* Output extended relocation information to a file in target byte order. */
1331
1332 void
1333 swap_ext_reloc_out (abfd, g, natptr)
1334 bfd *abfd;
1335 arelent *g; /* Generic relocation struct */
1336 register struct reloc_ext_bytes *natptr;
1337 {
1338 int r_index;
1339 int r_extern;
1340 unsigned int r_type;
1341 unsigned int r_addend;
1342
1343 bfd_h_putlong (abfd, g->address, natptr->r_address);
1344
1345 /* Find a type in the output format which matches the input howto -
1346 at the moment we assume input format == output format FIXME!! */
1347 r_type = (enum reloc_type) g->howto->type;
1348
1349 r_addend = g->addend; /* Start here, see how it goes */
1350
1351 /* name was clobbered by sunos4_write_syms to be symbol index*/
1352
1353 if (g->sym_ptr_ptr != NULL)
1354 {
1355 if ((*(g->sym_ptr_ptr))->section) {
1356 /* put the section offset into the addend for output */
1357 r_addend += (*(g->sym_ptr_ptr))->section->vma;
1358 }
1359
1360 r_index = stoi((*(g->sym_ptr_ptr))->name);
1361 r_extern = 1;
1362 }
1363 else {
1364 r_extern = 0;
1365 if (g->section == NULL) {
1366 BFD_ASSERT(0);
1367 r_index = N_ABS | N_EXT;
1368 }
1369 else if(g->section->output_section == obj_textsec(abfd)) {
1370 r_index = N_TEXT | N_EXT;
1371 r_addend += g->section->output_section->vma;
1372 }
1373 else if (g->section->output_section == obj_datasec(abfd)) {
1374 r_index = N_DATA | N_EXT;
1375 r_addend += g->section->output_section->vma;
1376 }
1377 else if (g->section->output_section == obj_bsssec(abfd)) {
1378 r_index = N_BSS | N_EXT ;
1379 r_addend += g->section->output_section->vma;
1380 }
1381 else {
1382 BFD_ASSERT(0);
1383 }
1384 }
1385
1386 /* now the fun stuff */
1387 if (abfd->xvec->header_byteorder_big_p != false) {
1388 natptr->r_index[0] = r_index >> 16;
1389 natptr->r_index[1] = r_index >> 8;
1390 natptr->r_index[2] = r_index;
1391 natptr->r_bits[0] =
1392 (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1393 || (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1394 } else {
1395 natptr->r_index[2] = r_index >> 16;
1396 natptr->r_index[1] = r_index >> 8;
1397 natptr->r_index[0] = r_index;
1398 natptr->r_bits[0] =
1399 (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1400 || (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1401 }
1402
1403 bfd_h_putlong (abfd, r_addend, natptr->r_addend);
1404 }
1405
1406 #define MOVE_ADDRESS(ad) \
1407 if (r_extern) { \
1408 cache_ptr->sym_ptr_ptr = symbols + r_index; \
1409 cache_ptr->section = (asection *)NULL; \
1410 cache_ptr->addend = ad; \
1411 } else { \
1412 cache_ptr->sym_ptr_ptr = (asymbol **)NULL; \
1413 switch (r_index) { \
1414 case N_TEXT: \
1415 case N_TEXT | N_EXT: \
1416 cache_ptr->section = obj_textsec(abfd); \
1417 cache_ptr->addend = ad - su->textsec->vma; \
1418 break; \
1419 case N_DATA: \
1420 case N_DATA | N_EXT: \
1421 cache_ptr->section = obj_datasec(abfd); \
1422 cache_ptr->addend = ad - su->datasec->vma; \
1423 break; \
1424 case N_BSS: \
1425 case N_BSS | N_EXT: \
1426 cache_ptr->section = obj_bsssec(abfd); \
1427 cache_ptr->addend = ad - su->bsssec->vma; \
1428 break; \
1429 case N_ABS: \
1430 case N_ABS | N_EXT: \
1431 cache_ptr->section = NULL; /* No section */ \
1432 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1433 BFD_ASSERT(1); \
1434 break; \
1435 default: \
1436 cache_ptr->section = NULL; /* No section */ \
1437 cache_ptr->addend = ad; /* FIXME, is this right? */ \
1438 BFD_ASSERT(1); \
1439 break; \
1440 } \
1441 } \
1442
1443 void
1444 swap_ext_reloc_in (abfd, bytes, cache_ptr, symbols)
1445 bfd *abfd;
1446 struct reloc_ext_bytes *bytes;
1447 arelent *cache_ptr;
1448 asymbol **symbols;
1449 {
1450 int r_index;
1451 int r_extern;
1452 unsigned int r_type;
1453 struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1454
1455 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1456
1457 /* now the fun stuff */
1458 if (abfd->xvec->header_byteorder_big_p != false) {
1459 r_index = (bytes->r_index[0] << 16)
1460 | (bytes->r_index[1] << 8)
1461 | bytes->r_index[2];
1462 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_BIG));
1463 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_BIG)
1464 >> RELOC_EXT_BITS_TYPE_SH_BIG;
1465 } else {
1466 r_index = (bytes->r_index[2] << 16)
1467 | (bytes->r_index[1] << 8)
1468 | bytes->r_index[0];
1469 r_extern = (0 != (bytes->r_bits[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1470 r_type = (bytes->r_bits[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1471 >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1472 }
1473
1474 cache_ptr->howto = howto_table_ext + r_type;
1475 MOVE_ADDRESS(bfd_h_getlong(abfd,bytes->r_addend));
1476 }
1477
1478 void
1479 swap_std_reloc_in (abfd, bytes, cache_ptr, symbols)
1480 bfd *abfd;
1481 struct reloc_std_bytes *bytes;
1482 arelent *cache_ptr;
1483 asymbol **symbols;
1484 {
1485 int r_index;
1486 int r_extern;
1487 unsigned int r_length;
1488 int r_pcrel;
1489 int r_baserel, r_jmptable, r_relative;
1490 struct sunexdata *su = (struct sunexdata *)(abfd->tdata);
1491
1492 cache_ptr->address = bfd_h_getlong (abfd, bytes->r_address);
1493
1494 /* now the fun stuff */
1495 if (abfd->xvec->header_byteorder_big_p != false) {
1496 r_index = (bytes->r_index[0] << 16)
1497 | (bytes->r_index[1] << 8)
1498 | bytes->r_index[2];
1499 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_BIG));
1500 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_BIG));
1501 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_BIG));
1502 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1503 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_BIG));
1504 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_BIG)
1505 >> RELOC_STD_BITS_LENGTH_SH_BIG;
1506 } else {
1507 r_index = (bytes->r_index[2] << 16)
1508 | (bytes->r_index[1] << 8)
1509 | bytes->r_index[0];
1510 r_extern = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1511 r_pcrel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_PCREL_LITTLE));
1512 r_baserel = (0 != (bytes->r_bits[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1513 r_jmptable= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1514 r_relative= (0 != (bytes->r_bits[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1515 r_length = (bytes->r_bits[0] & RELOC_STD_BITS_LENGTH_LITTLE)
1516 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1517 }
1518
1519 cache_ptr->howto = howto_table_std + r_length + 4 * r_pcrel;
1520 /* FIXME-soon: Roll baserel, jmptable, relative bits into howto setting */
1521
1522 MOVE_ADDRESS(0);
1523 }
1524
1525 /* Reloc hackery */
1526
1527 boolean
1528 sunos4_slurp_reloc_table (abfd, asect, symbols)
1529 bfd *abfd;
1530 sec_ptr asect;
1531 asymbol **symbols;
1532 {
1533 unsigned int count;
1534 size_t reloc_size;
1535 PTR relocs;
1536 arelent *reloc_cache;
1537 size_t each_size;
1538
1539 if (asect->relocation) return true;
1540
1541 if (asect->flags & SEC_CONSTRUCTOR) return true;
1542
1543 if (asect == obj_datasec (abfd)) {
1544 reloc_size = exec_hdr(abfd)->a_drsize;
1545 goto doit;
1546 }
1547
1548 if (asect == obj_textsec (abfd)) {
1549 reloc_size = exec_hdr(abfd)->a_trsize;
1550 goto doit;
1551 }
1552
1553 bfd_error = invalid_operation;
1554 return false;
1555
1556 doit:
1557 bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1558 each_size = reloc_size_func(abfd);
1559
1560 count = reloc_size / each_size;
1561
1562
1563 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1564 (arelent)));
1565 if (!reloc_cache) {
1566 nomem:
1567 bfd_error = no_memory;
1568 return false;
1569 }
1570
1571 relocs = bfd_alloc (abfd, reloc_size);
1572 if (!relocs) {
1573 bfd_release (abfd, reloc_cache);
1574 goto nomem;
1575 }
1576
1577 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1578 bfd_release (abfd, relocs);
1579 bfd_release (abfd, reloc_cache);
1580 bfd_error = system_call_error;
1581 return false;
1582 }
1583
1584 if (each_size == RELOC_EXT_SIZE) {
1585 register struct reloc_ext_bytes *rptr = (struct reloc_ext_bytes *) relocs;
1586 unsigned int counter = 0;
1587 arelent *cache_ptr = reloc_cache;
1588
1589 for (; counter < count; counter++, rptr++, cache_ptr++) {
1590 swap_ext_reloc_in(abfd, rptr, cache_ptr, symbols);
1591 }
1592 } else {
1593 register struct reloc_std_bytes *rptr = (struct reloc_std_bytes *) relocs;
1594 unsigned int counter = 0;
1595 arelent *cache_ptr = reloc_cache;
1596
1597 for (; counter < count; counter++, rptr++, cache_ptr++) {
1598 swap_std_reloc_in(abfd, rptr, cache_ptr, symbols);
1599 }
1600
1601 }
1602
1603 bfd_release (abfd,relocs);
1604 asect->relocation = reloc_cache;
1605 asect->reloc_count = count;
1606 return true;
1607 }
1608
1609
1610
1611 /* Write out a relocation section into an object file. */
1612
1613 static boolean
1614 sunos4_squirt_out_relocs (abfd, section)
1615 bfd *abfd;
1616 asection *section;
1617 {
1618 arelent **generic;
1619 unsigned char *native, *natptr;
1620 size_t each_size;
1621
1622 unsigned int count = section->reloc_count;
1623 size_t natsize;
1624
1625 if (count == 0) return true;
1626
1627 each_size = reloc_size_func(abfd);
1628 natsize = each_size * count;
1629 native = (unsigned char *) bfd_zalloc (abfd, natsize);
1630 if (!native) {
1631 bfd_error = no_memory;
1632 return false;
1633 }
1634
1635 generic = section->orelocation;
1636
1637 if (each_size == RELOC_EXT_SIZE)
1638 {
1639 for (natptr = native;
1640 count != 0;
1641 --count, natptr += each_size, ++generic)
1642 swap_ext_reloc_out (abfd, *generic, (struct reloc_ext_bytes *)natptr);
1643 }
1644 else
1645 {
1646 for (natptr = native;
1647 count != 0;
1648 --count, natptr += each_size, ++generic)
1649 swap_std_reloc_out(abfd, *generic, (struct reloc_std_bytes *)natptr);
1650 }
1651
1652 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1653 bfd_release(abfd, native);
1654 return false;
1655 }
1656 bfd_release (abfd, native);
1657
1658 return true;
1659 }
1660
1661 /* This is stupid. This function should be a boolean predicate */
1662 unsigned int
1663 sunos4_canonicalize_reloc (abfd, section, relptr, symbols)
1664 bfd *abfd;
1665 sec_ptr section;
1666 arelent **relptr;
1667 asymbol **symbols;
1668 {
1669 arelent *tblptr = section->relocation;
1670 unsigned int count;
1671
1672 if (!(tblptr || sunos4_slurp_reloc_table (abfd, section, symbols)))
1673 return 0;
1674
1675 if (section->flags & SEC_CONSTRUCTOR) {
1676 arelent_chain *chain = section->constructor_chain;
1677 for (count = 0; count < section->reloc_count; count ++) {
1678 *relptr ++ = &chain->relent;
1679 chain = chain->next;
1680 }
1681 }
1682 else {
1683 tblptr = section->relocation;
1684 if (!tblptr) return 0;
1685
1686 for (count = 0; count++ < section->reloc_count;)
1687 {
1688 *relptr++ = tblptr++;
1689 }
1690 }
1691 *relptr = 0;
1692
1693 return section->reloc_count;
1694 }
1695
1696 unsigned int
1697 sunos4_get_reloc_upper_bound (abfd, asect)
1698 bfd *abfd;
1699 sec_ptr asect;
1700 {
1701 if (bfd_get_format (abfd) != bfd_object) {
1702 bfd_error = invalid_operation;
1703 return 0;
1704 }
1705 if (asect->flags & SEC_CONSTRUCTOR) {
1706 return (sizeof (arelent *) * (asect->reloc_count+1));
1707 }
1708
1709
1710 if (asect == obj_datasec (abfd))
1711 return (sizeof (arelent *) *
1712 ((exec_hdr(abfd)->a_drsize / reloc_size_func(abfd))
1713 +1));
1714
1715 if (asect == obj_textsec (abfd))
1716 return (sizeof (arelent *) *
1717 ((exec_hdr(abfd)->a_trsize / reloc_size_func(abfd))
1718 +1));
1719
1720 bfd_error = invalid_operation;
1721 return 0;
1722 }
1723
1724 void
1725 sunos4_reclaim_reloc (ignore_abfd, ignore)
1726 bfd *ignore_abfd;
1727 sec_ptr ignore;
1728 {
1729
1730 }
1731 \f
1732
1733 alent *
1734 sunos4_get_lineno(ignore_abfd, ignore_symbol)
1735 bfd *ignore_abfd;
1736 PTR ignore_symbol;
1737 {
1738 return (alent *)NULL;
1739 }
1740
1741 void
1742 sunos4_print_symbol(ignore_abfd, file, symbol, how)
1743 bfd *ignore_abfd;
1744 FILE *file;
1745 asymbol *symbol;
1746 bfd_print_symbol_enum_type how;
1747 {
1748 switch (how) {
1749 case bfd_print_symbol_name_enum:
1750 fprintf(file,"%s", symbol->name);
1751 break;
1752 case bfd_print_symbol_type_enum:
1753 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1754 (unsigned)(aout_symbol(symbol)->other & 0xff),
1755 (unsigned)(aout_symbol(symbol)->type));
1756 break;
1757 case bfd_print_symbol_all_enum:
1758 {
1759 CONST char *section_name = symbol->section == (asection *)NULL ?
1760 "*abs" : symbol->section->name;
1761
1762 bfd_print_symbol_vandf((PTR)file,symbol);
1763
1764 fprintf(file," %-5s %04x %02x %02x %s",
1765 section_name,
1766 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1767 (unsigned)(aout_symbol(symbol)->other & 0xff),
1768 (unsigned)(aout_symbol(symbol)->type & 0xff),
1769 symbol->name);
1770 }
1771 break;
1772 }
1773 }
1774 /* Once we know all the stuff that could be consed, we know how to clean
1775 it up. So why don't we? */
1776
1777 boolean
1778 sunos4_close_and_cleanup (abfd)
1779 bfd *abfd;
1780 {
1781 if (!bfd_read_p (abfd))
1782 switch (abfd->format) {
1783 case bfd_archive:
1784 if (!_bfd_write_archive_contents (abfd)) return false; break;
1785 case bfd_object:
1786 if (!sunos4_write_object_contents (abfd)) return false; break;
1787 default: bfd_error = invalid_operation; return false;
1788 }
1789
1790 return true;
1791 }
1792
1793 /*
1794 provided a bfd, a section and an offset into the section, calculate
1795 and return the name of the source file and the line nearest to the
1796 wanted location.
1797 */
1798
1799 boolean
1800 DEFUN(sunos4_find_nearest_line,(abfd,
1801 section,
1802 symbols,
1803 offset,
1804 filename_ptr,
1805 functionname_ptr,
1806 line_ptr),
1807 bfd *abfd AND
1808 asection *section AND
1809 asymbol **symbols AND
1810 bfd_vma offset AND
1811 CONST char **filename_ptr AND
1812 CONST char **functionname_ptr AND
1813 unsigned int *line_ptr)
1814 {
1815 /* Run down the file looking for the filename, function and linenumber */
1816 asymbol **p;
1817 static char buffer[100];
1818 bfd_vma high_line_vma = ~0;
1819 bfd_vma low_func_vma = 0;
1820 asymbol *func = 0;
1821 *filename_ptr = abfd->filename;
1822 *functionname_ptr = 0;
1823 *line_ptr = 0;
1824 if (symbols != (asymbol **)NULL) {
1825 for (p = symbols; *p; p++) {
1826 aout_symbol_type *q = (aout_symbol_type *)(*p);
1827 switch (q->type){
1828 case N_SO:
1829 *filename_ptr = q->symbol.name;
1830 if (obj_textsec(abfd) != section) {
1831 return true;
1832 }
1833 break;
1834 case N_SLINE:
1835
1836 case N_DSLINE:
1837 case N_BSLINE:
1838 /* We'll keep this if it resolves nearer than the one we have already */
1839 if (q->symbol.value >= offset &&
1840 q->symbol.value < high_line_vma) {
1841 *line_ptr = q->desc;
1842 high_line_vma = q->symbol.value;
1843 }
1844 break;
1845 case N_FUN:
1846 {
1847 /* We'll keep this if it is nearer than the one we have already */
1848 if (q->symbol.value >= low_func_vma &&
1849 q->symbol.value <= offset) {
1850 low_func_vma = q->symbol.value;
1851 func = (asymbol *)q;
1852 }
1853 if (*line_ptr && func) {
1854 CONST char *function = func->name;
1855 char *p;
1856 strncpy(buffer, function, sizeof(buffer)-1);
1857 buffer[sizeof(buffer)-1] = 0;
1858 /* Have to remove : stuff */
1859 p = strchr(buffer,':');
1860 if (p != NULL) {*p = NULL; }
1861 *functionname_ptr = buffer;
1862 return true;
1863
1864 }
1865 }
1866 break;
1867 }
1868 }
1869 }
1870
1871 return true;
1872
1873 }
1874
1875 static int
1876 DEFUN(sunos4_sizeof_headers,(ignore_abfd),
1877 bfd *ignore_abfd)
1878 {
1879 return 0; /* FIXME, this is the wrong value! */
1880 }
1881
1882 #define sunos4_openr_next_archived_file bfd_generic_openr_next_archived_file
1883 #define sunos4_generic_stat_arch_elt bfd_generic_stat_arch_elt
1884 #define sunos4_slurp_armap bfd_slurp_bsd_armap
1885 #define sunos4_slurp_extended_name_table bfd_true
1886 #define sunos4_write_armap bsd_write_armap
1887 #define sunos4_truncate_arname bfd_bsd_truncate_arname
1888 bfd_target aout_big_vec =
1889 {
1890 "a.out-generic-big", /* name */
1891 bfd_target_aout_flavour_enum,
1892 true, /* target byte order */
1893 true, /* target headers byte order */
1894 (HAS_RELOC | EXEC_P | /* object flags */
1895 HAS_LINENO | HAS_DEBUG |
1896 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1897 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1898 ' ', /* ar_pad_char */
1899 16, /* ar_max_namelen */
1900 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1901 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1902
1903 {_bfd_dummy_target, sunos4_object_p,
1904 bfd_generic_archive_p, sunos4_core_file_p},
1905 {bfd_false, sunos4_mkobject,
1906 _bfd_generic_mkarchive, bfd_false},
1907
1908 JUMP_TABLE(sunos4)
1909 };
1910
1911
1912 bfd_target aout_little_vec =
1913 {
1914 "a.out-generic-little", /* name */
1915 bfd_target_aout_flavour_enum,
1916 false, /* target byte order */
1917 false, /* target headers byte order */
1918 (HAS_RELOC | EXEC_P | /* object flags */
1919 HAS_LINENO | HAS_DEBUG |
1920 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1921 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1922 ' ', /* ar_pad_char */
1923 16, /* ar_max_namelen */
1924 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* data */
1925 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* hdrs */
1926
1927
1928 {_bfd_dummy_target, sunos4_object_p,
1929 bfd_generic_archive_p, sunos4_core_file_p},
1930 {bfd_false, sunos4_mkobject,
1931 _bfd_generic_mkarchive, bfd_false},
1932
1933 JUMP_TABLE(sunos4)
1934 };
This page took 0.095931 seconds and 4 git commands to generate.