Lint.
[deliverable/binutils-gdb.git] / bfd / sunos.c
CommitLineData
4a81b561 1/*** bfd backend for sunos binaries */
fc723380 2/** a.out files */
4a81b561
DHW
3
4/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
5
6This file is part of BFD, the Binary File Diddler.
7
8BFD is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 1, or (at your option)
11any later version.
12
13BFD is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with BFD; see the file COPYING. If not, write to
20the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21
fc723380 22/* $Id$ */
4a81b561 23
c93595dd 24#include <ansidecl.h>
4a81b561
DHW
25#include "sysdep.h"
26#include "bfd.h"
27#include "libbfd.h"
4a81b561 28
fc723380 29#include "a.out.sun4.h"
4a81b561
DHW
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
fc723380
JG
35void (*bfd_error_trap)();
36
37/*SUPPRESS558*/
38/*SUPPRESS529*/
4a81b561
DHW
39
40#define CTOR_TABLE_RELOC_IDX 2
9846338e 41static reloc_howto_type howto_table_ext[] =
4a81b561 42{
4cddd1c9
SC
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),
4a81b561
DHW
70};
71
c93595dd
SC
72/* Convert standard reloc records to "arelent" format (incl byte swap). */
73
9846338e 74static reloc_howto_type howto_table_std[] = {
fc723380 75 /* type rs size bsz pcrel bitpos abs ovrf sf name part_inpl readmask setmask pcdone */
4cddd1c9
SC
76HOWTO( 0, 0, 0, 8, false, 0, true, true,0,"8", true, 0x000000ff,0x000000ff, false),
77HOWTO( 1, 0, 1, 16, false, 0, true, true,0,"16", true, 0x0000ffff,0x0000ffff, false),
78HOWTO( 2, 0, 2, 32, false, 0, true, true,0,"32", true, 0xffffffff,0xffffffff, false),
79HOWTO( 3, 0, 3, 64, false, 0, true, true,0,"64", true, 0xdeaddead,0xdeaddead, false),
80HOWTO( 4, 0, 0, 8, true, 0, false, true,0,"DISP8", true, 0x000000ff,0x000000ff, false),
81HOWTO( 5, 0, 1, 16, true, 0, false, true,0,"DISP16", true, 0x0000ffff,0x0000ffff, false),
82HOWTO( 6, 0, 2, 32, true, 0, false, true,0,"DISP32", true, 0xffffffff,0xffffffff, false),
83HOWTO( 7, 0, 3, 64, true, 0, false, true,0,"DISP64", true, 0xfeedface,0xfeedface, false),
c93595dd
SC
84};
85
9846338e
SC
86
87bfd_error_vector_type bfd_error_vector;
c93595dd 88
4a81b561
DHW
89PROTO (void , sunos4_write_syms, ());
90PROTO (static boolean,sunos4_squirt_out_relocs,(bfd *abfd, asection *section));
91
c93595dd
SC
92
93static size_t
94reloc_size_func(abfd)
95bfd *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
9846338e
SC
106static void
107DEFUN(bfd_aout_swap_exec_header_in,(abfd, raw_bytes, execp),
108 bfd *abfd AND
109 unsigned char *raw_bytes AND
110 struct exec *execp)
c93595dd
SC
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
9846338e
SC
125static void
126DEFUN(bfd_aout_swap_exec_header_out,(abfd, execp, raw_bytes),
127 bfd *abfd AND
128 struct exec *execp AND
129 unsigned char *raw_bytes)
c93595dd
SC
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
4a81b561
DHW
144bfd_target *
145sunos4_object_p (abfd)
146 bfd *abfd;
147{
c93595dd
SC
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;
9846338e 152 PTR rawptr;
4a81b561
DHW
153
154 bfd_error = system_call_error;
155
9846338e 156 if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) !=
c93595dd 157 sizeof (magicbuf))
4a81b561 158 return 0;
c93595dd 159 magic = bfd_h_getlong (abfd, magicbuf);
4a81b561 160
fc723380 161 if (N_BADMAG (*((struct exec *) &magic))) return 0;
4a81b561 162
c93595dd 163 if (bfd_seek (abfd, 0L, false) < 0) return 0;
4a81b561 164
9846338e 165 if (bfd_read ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
c93595dd 166 != EXEC_BYTES_SIZE) {
4a81b561
DHW
167 bfd_error = wrong_format;
168 return 0;
169 }
170
171 /* Use an intermediate variable for clarity */
9872a49c 172 rawptr = (PTR) bfd_zalloc (abfd, sizeof (struct sunexdata) + sizeof (struct exec));
4a81b561
DHW
173
174 if (rawptr == NULL) {
175 bfd_error = no_memory;
176 return 0;
177 }
178
c93595dd
SC
179 set_tdata (abfd, ((struct sunexdata *) rawptr));
180 exec_hdr (abfd) = execp =
4a81b561
DHW
181 (struct exec *) ((char *)rawptr + sizeof (struct sunexdata));
182
c93595dd 183 bfd_aout_swap_exec_header_in (abfd, exec_bytes, execp);
4a81b561
DHW
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
c93595dd
SC
195 if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
196 if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
4a81b561
DHW
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;
c93595dd 201 switch (N_MACHTYPE (*execp)) {
4a81b561
DHW
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
fc723380
JG
235 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct nlist);
236
4a81b561 237 /* Remember the positions of the string table and symbol table. */
fc723380
JG
238 obj_str_filepos (abfd) = N_STROFF (*execp);
239 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
4a81b561
DHW
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;
c93595dd
SC
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
d6a554ae
JG
261 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
262 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
c93595dd
SC
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));
4a81b561
DHW
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
279boolean
280sunos4_mkobject (abfd)
281 bfd *abfd;
282{
283 char *rawptr;
284
285 bfd_error = system_call_error;
286
287 /* Use an intermediate variable for clarity */
fc723380 288 rawptr = bfd_zalloc (abfd, sizeof (struct sunexdata) + sizeof (struct exec));
4a81b561
DHW
289
290 if (rawptr == NULL) {
291 bfd_error = no_memory;
292 return false;
293 }
294
fc723380 295 set_tdata (abfd, (struct sunexdata *) rawptr);
4a81b561
DHW
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
317static enum machine_type
318aout_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:
9872a49c
SC
328 if (machine == 0) arch_flags = M_SPARC;
329 break;
4a81b561
DHW
330
331 case bfd_arch_m68k:
9872a49c
SC
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;
4a81b561
DHW
340
341 case bfd_arch_i386:
9872a49c
SC
342 if (machine == 0) arch_flags = M_386;
343 break;
4a81b561
DHW
344
345 case bfd_arch_a29k:
9872a49c
SC
346 if (machine == 0) arch_flags = M_29K;
347 break;
4a81b561
DHW
348
349 default:
9872a49c
SC
350 arch_flags = M_UNKNOWN;
351 break;
4a81b561
DHW
352 }
353 return arch_flags;
354}
355
356boolean
357sunos4_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
370boolean
371sunos4_write_object_contents (abfd)
372 bfd *abfd;
373{
9846338e 374 size_t data_pad = 0;
c93595dd 375 unsigned char exec_bytes[EXEC_BYTES_SIZE];
4a81b561
DHW
376 struct exec *execp = exec_hdr (abfd);
377
c93595dd 378 execp->a_text = obj_textsec (abfd)->size;
4a81b561
DHW
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 }
c93595dd 405
4a81b561
DHW
406 N_SET_MAGIC (*execp, OMAGIC);
407 if (abfd->flags & D_PAGED) {
fc723380
JG
408 /* This is not strictly true, but will probably do for the default
409 case. FIXME. */
4a81b561
DHW
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)
9846338e
SC
418 {
419 data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1)
420 & (- PAGE_SIZE)) - obj_datasec(abfd)->size;
4a81b561 421
9846338e
SC
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;
4a81b561 427
9846338e 428 }
4a81b561
DHW
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);
c93595dd 436
4a81b561 437 execp->a_trsize = ((obj_textsec (abfd)->reloc_count) *
c93595dd
SC
438 reloc_size_func(abfd));
439
4a81b561 440 execp->a_drsize = ((obj_datasec (abfd)->reloc_count) *
c93595dd 441 reloc_size_func(abfd));
4a81b561 442
c93595dd 443 bfd_aout_swap_exec_header_out (abfd, execp, exec_bytes);
4a81b561 444
c93595dd 445 bfd_seek (abfd, 0L, false);
9846338e 446 bfd_write ((PTR) exec_bytes, 1, EXEC_BYTES_SIZE, abfd);
4a81b561
DHW
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,
c93595dd 453 (long)(N_SYMOFF(*execp)), false);
4a81b561
DHW
454
455 sunos4_write_syms (abfd);
456
d6a554ae 457 bfd_seek (abfd, (long)(N_TRELOFF(*execp)), false);
4a81b561
DHW
458
459 if (!sunos4_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
d6a554ae 460 bfd_seek (abfd, (long)(N_DRELOFF(*execp)), false);
4a81b561
DHW
461
462 if (!sunos4_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
463 }
464 return true;
465}
fc723380
JG
466\f
467/* core files */
4a81b561
DHW
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. */
481struct 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
c93595dd
SC
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
4a81b561
DHW
509struct 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) */
c93595dd
SC
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. */
4a81b561 523 int c_ucode; /* Exception no. from u_code */
c93595dd
SC
524 /* (this member is not accessible by name since we don't
525 portably know the size of fp_stuff.) */
4a81b561
DHW
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
532PROTO (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)
c93595dd 539#define core_reg2sec(bfd) (((struct suncordata *) ((bfd)->tdata))->reg2_section)
4a81b561
DHW
540
541/* These are stored in the bfd's tdata */
542struct 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
550bfd_target *
551sunos4_core_file_p (abfd)
552 bfd *abfd;
553{
c93595dd 554 unsigned char longbuf[4]; /* Raw bytes of various header fields */
4a81b561
DHW
555 int core_size;
556 int core_mag;
557 struct core *core;
558 char *rawptr;
559
560 bfd_error = system_call_error;
561
9846338e 562 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
c93595dd 563 sizeof (longbuf))
4a81b561 564 return 0;
c93595dd 565 core_mag = bfd_h_getlong (abfd, longbuf);
4a81b561
DHW
566
567 if (core_mag != CORE_MAGIC) return 0;
568
569 /* SunOS core headers can vary in length; second word is size; */
9846338e 570 if (bfd_read ((PTR)longbuf, 1, sizeof (longbuf), abfd) !=
c93595dd
SC
571 sizeof (longbuf))
572 return 0;
573 core_size = bfd_h_getlong (abfd, longbuf);
574 /* Sanity check */
575 if (core_size > 20000)
4a81b561 576 return 0;
4a81b561 577
c93595dd 578 if (bfd_seek (abfd, 0L, false) < 0) return 0;
4a81b561 579
9872a49c 580 rawptr = bfd_zalloc (abfd, core_size + sizeof (struct suncordata));
4a81b561
DHW
581 if (rawptr == NULL) {
582 bfd_error = no_memory;
583 return 0;
584 }
585
586 core = (struct core *) (rawptr + sizeof (struct suncordata));
587
9846338e 588 if ((bfd_read ((PTR) core, 1, core_size, abfd)) != core_size) {
4a81b561 589 bfd_error = system_call_error;
fc723380 590 bfd_release (abfd, rawptr);
4a81b561
DHW
591 return 0;
592 }
593
594 swapcore (abfd, core);
c93595dd 595 set_tdata (abfd, ((struct suncordata *) rawptr));
4a81b561
DHW
596 core_hdr (abfd) = core;
597
598 /* create the sections. This is raunchy, but bfd_close wants to reclaim
599 them */
9872a49c 600 core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
4a81b561 601 if (core_stacksec (abfd) == NULL) {
c93595dd 602loser:
4a81b561 603 bfd_error = no_memory;
fc723380 604 bfd_release (abfd, rawptr);
4a81b561
DHW
605 return 0;
606 }
9872a49c 607 core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
4a81b561 608 if (core_datasec (abfd) == NULL) {
c93595dd 609loser1:
fc723380 610 bfd_release (abfd, core_stacksec (abfd));
4a81b561
DHW
611 goto loser;
612 }
9872a49c 613 core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
4a81b561 614 if (core_regsec (abfd) == NULL) {
c93595dd 615loser2:
fc723380 616 bfd_release (abfd, core_datasec (abfd));
4a81b561
DHW
617 goto loser1;
618 }
9872a49c 619 core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
c93595dd 620 if (core_reg2sec (abfd) == NULL) {
fc723380 621 bfd_release (abfd, core_regsec (abfd));
4a81b561
DHW
622 goto loser2;
623 }
624
625 core_stacksec (abfd)->name = ".stack";
626 core_datasec (abfd)->name = ".data";
627 core_regsec (abfd)->name = ".reg";
c93595dd 628 core_reg2sec (abfd)->name = ".reg2";
4a81b561
DHW
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;
c93595dd 633 core_reg2sec (abfd)->flags = SEC_ALLOC;
4a81b561
DHW
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);
c93595dd
SC
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);
4a81b561
DHW
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;
c93595dd 645 core_reg2sec (abfd)->vma = -1;
4a81b561
DHW
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);
c93595dd 651 core_reg2sec (abfd)->filepos = (file_ptr)(((struct core *)0)->fp_stuff);
4a81b561
DHW
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;
c93595dd 657 core_reg2sec (abfd)->alignment_power = 2;
4a81b561
DHW
658
659 abfd->sections = core_stacksec (abfd);
660 core_stacksec (abfd)->next = core_datasec (abfd);
661 core_datasec (abfd)->next = core_regsec (abfd);
c93595dd 662 core_regsec (abfd)->next = core_reg2sec (abfd);
4a81b561
DHW
663
664 abfd->section_count = 4;
665
666 return abfd->xvec;
667}
668
669char *
670sunos4_core_file_failing_command (abfd)
671 bfd *abfd;
672{
673 return core_hdr (abfd)->c_cmdname;
674}
675
676int
677sunos4_core_file_failing_signal (abfd)
678 bfd *abfd;
679{
680 return core_hdr (abfd)->c_signo;
681}
682
683boolean
684sunos4_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
c93595dd 692 return (bcmp ((char *)&core_hdr (core_bfd), (char*) &exec_hdr (exec_bfd),
4a81b561
DHW
693 sizeof (struct exec)) == 0) ? true : false;
694}
695
696/* byte-swap core structure */
c93595dd 697/* FIXME, this needs more work to swap IN a core struct from raw bytes */
4a81b561
DHW
698static void
699swapcore (abfd, core)
c93595dd 700 bfd *abfd;
4a81b561
DHW
701 struct core *core;
702{
c93595dd
SC
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. */
4a81b561
DHW
716}
717\f
718/** exec and core file sections */
719
720boolean
721sunos4_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
4a81b561
DHW
745 /* We allow more than three sections internally */
746 return true;
747}
748
749boolean
750sunos4_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)
4432f8ad 758 { /* set by bfd.c handler */
fc723380 759 if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
4432f8ad
SC
760 {
761 bfd_error = invalid_operation;
762 return false;
763 }
4a81b561 764
41489b9a
SC
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
4432f8ad 772 }
4a81b561 773 /* regardless, once we know what we're doing, we might as well get going */
4432f8ad
SC
774 if (section != obj_bsssec(abfd)) {
775 bfd_seek (abfd, section->filepos + offset, SEEK_SET);
4a81b561 776
4432f8ad
SC
777 if (count) {
778 return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
779 true : false;
780 }
781 return false;
4a81b561 782 }
4432f8ad 783 return true;
4a81b561 784}
fc723380 785
4a81b561
DHW
786boolean
787sunos4_get_section_contents (abfd, section, location, offset, count)
788 bfd *abfd;
789 sec_ptr section;
9846338e 790 PTR location;
4a81b561
DHW
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
847static void
848translate_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);
9872a49c 861 arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
4a81b561
DHW
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 ;
fc723380
JG
883
884 /* We modify the symbol to belong to a section depending upon the
4a81b561
DHW
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
fc723380 888 symbol attached to this section. */
4a81b561
DHW
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
c93595dd 899 reloc->relent.howto = howto_table_ext +CTOR_TABLE_RELOC_IDX;
4a81b561
DHW
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}
c93595dd 978
4a81b561
DHW
979void
980translate_to_native_sym_flags (sym_pointer, cache_ptr_g, abfd)
981 struct nlist *sym_pointer;
4432f8ad 982 PTR cache_ptr_g;
4a81b561
DHW
983 bfd *abfd;
984{
985 asymbol *cache_ptr = (asymbol *)cache_ptr_g;
986
fc723380 987 /* FIXME check for writing bss */
4a81b561
DHW
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 {
fc723380
JG
999 bfd_error_vector.nonrepresentable_section(abfd,
1000 bfd_get_output_section(cache_ptr)->name);
4a81b561
DHW
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 }
4a81b561
DHW
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
1034asymbol *
1035sunos4_make_empty_symbol (abfd)
1036bfd *abfd;
1037{
1038 aout_symbol_type *new =
9872a49c 1039 (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
4a81b561
DHW
1040 new->symbol.the_bfd = abfd;
1041
1042 return &new->symbol;
1043}
1044
1045boolean
9846338e
SC
1046DEFUN(sunos4_slurp_symbol_table, (abfd),
1047 bfd *abfd)
4a81b561 1048{
4a81b561
DHW
1049 size_t symbol_size;
1050 size_t string_size;
fc723380 1051 unsigned char string_chars[LONG_SIZE];
4a81b561
DHW
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);
fc723380 1065 if (bfd_read ((PTR)string_chars, LONG_SIZE, 1, abfd) != LONG_SIZE)
4a81b561 1066 return false;
fc723380 1067 string_size = bfd_h_getlong (abfd, string_chars);
4a81b561 1068
9872a49c 1069 strings = bfd_alloc(abfd, string_size + 1);
d6a554ae 1070 cached = (aout_symbol_type *)
fc723380
JG
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. */
d6a554ae 1073 syms = (struct nlist *) bfd_alloc(abfd, symbol_size);
4a81b561
DHW
1074
1075 bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
9846338e 1076 if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
4a81b561 1077 bailout:
fc723380
JG
1078 if (syms) bfd_release (abfd, syms);
1079 if (cached) bfd_release (abfd, cached);
1080 if (strings)bfd_release (abfd, strings);
4a81b561
DHW
1081 return false;
1082 }
1083
1084 bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
9846338e 1085 if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
4a81b561
DHW
1086 goto bailout;
1087 }
1088
1089 /* OK, now walk the new symtable, cacheing symbol properties */
9872a49c
SC
1090 {
1091 register struct nlist *sym_pointer;
fc723380 1092 register struct nlist *sym_end = syms + bfd_get_symcount (abfd);
9872a49c 1093 register aout_symbol_type *cache_ptr = cached;
4a81b561 1094
4a81b561
DHW
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);
4a81b561 1107 }
9846338e 1108
9872a49c
SC
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);
4a81b561 1124
9872a49c
SC
1125 }
1126 }
4a81b561
DHW
1127
1128 obj_aout_symbols (abfd) = cached;
9872a49c 1129 bfd_release (abfd, (PTR)syms);
4a81b561
DHW
1130
1131 return true;
1132}
1133
9846338e 1134
4a81b561 1135void
9846338e
SC
1136DEFUN(sunos4_write_syms,(abfd),
1137 bfd *abfd)
4a81b561
DHW
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;
4432f8ad 1172 translate_to_native_sym_flags (&nsp, (PTR)g, abfd);
4a81b561
DHW
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);
9846338e 1177 bfd_write((PTR)&nsp,1, sizeof(nsp), abfd);
4a81b561
DHW
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
9846338e 1186 bfd_write((PTR)&stindex, 1, sizeof(stindex), abfd);
4a81b561
DHW
1187
1188 generic = bfd_get_outsymbols(abfd);
1189 for (count = 0; count < bfd_get_symcount(abfd); count++)
1190 {
1191 asymbol *g = *(generic++);
1192
fc723380 1193 if (g->name)
4a81b561
DHW
1194 {
1195 size_t length = strlen(g->name)+1;
9846338e 1196 bfd_write((PTR)g->name, 1, length, abfd);
4a81b561
DHW
1197 }
1198 if ((g->flags & BSF_FAKE)==0) {
1199 g->name = itos(count); /* smash the generic symbol */
1200 }
1201 }
1202}
1203
9846338e 1204
4a81b561 1205void
9846338e
SC
1206DEFUN(sunos4_reclaim_symbol_table,(abfd),
1207 bfd *abfd)
4a81b561 1208{
4a81b561 1209
4a81b561
DHW
1210}
1211\f
1212unsigned int
1213sunos4_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
1221unsigned int
1222sunos4_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
4a81b561 1237\f
c93595dd
SC
1238/* Standard reloc stuff */
1239/* Output standard relocation information to a file in target byte order. */
1240
1241void
fc723380 1242swap_std_reloc_out (abfd, g, natptr)
c93595dd 1243 bfd *abfd;
fc723380 1244 arelent *g; /* Generic relocation struct */
c93595dd 1245 struct reloc_std_bytes *natptr;
c93595dd
SC
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;
c93595dd 1253
fc723380 1254 bfd_h_putlong (abfd, g->address, natptr->r_address);
c93595dd 1255
b6316534 1256 r_length = g->howto->size ; /* Size as a power of two */
fc723380
JG
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;
c93595dd 1262
fc723380 1263 r_addend = g->addend; /* Start here, see how it goes */
c93595dd 1264
fc723380 1265 /* name was clobbered by sunos4_write_syms to be symbol index */
c93595dd 1266
fc723380
JG
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;
c93595dd
SC
1272 }
1273
fc723380
JG
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) {
d0ec7a8e
SC
1280 /* It is possible to have a reloc with nothing, we generate an
1281 abs + 0 */
1282 r_addend = 0;
fc723380
JG
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;
c93595dd 1296 }
fc723380
JG
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 }
c93595dd
SC
1326}
1327
1328
1329/* Extended stuff */
1330/* Output extended relocation information to a file in target byte order. */
1331
1332void
fc723380 1333swap_ext_reloc_out (abfd, g, natptr)
c93595dd 1334 bfd *abfd;
fc723380 1335 arelent *g; /* Generic relocation struct */
c93595dd 1336 register struct reloc_ext_bytes *natptr;
c93595dd 1337{
c93595dd
SC
1338 int r_index;
1339 int r_extern;
1340 unsigned int r_type;
1341 unsigned int r_addend;
c93595dd 1342
fc723380 1343 bfd_h_putlong (abfd, g->address, natptr->r_address);
c93595dd 1344
fc723380
JG
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;
c93595dd 1348
fc723380 1349 r_addend = g->addend; /* Start here, see how it goes */
c93595dd 1350
fc723380 1351 /* name was clobbered by sunos4_write_syms to be symbol index*/
4a81b561 1352
fc723380
JG
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;
c93595dd 1358 }
c93595dd 1359
fc723380
JG
1360 r_index = stoi((*(g->sym_ptr_ptr))->name);
1361 r_extern = 1;
c93595dd 1362 }
fc723380
JG
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 }
c93595dd 1385
fc723380
JG
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);
c93595dd 1401 }
fc723380
JG
1402
1403 bfd_h_putlong (abfd, r_addend, natptr->r_addend);
c93595dd 1404}
fc723380 1405
c93595dd
SC
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: \
fc723380
JG
1431 cache_ptr->section = NULL; /* No section */ \
1432 cache_ptr->addend = ad; /* FIXME, is this right? */ \
c93595dd
SC
1433 BFD_ASSERT(1); \
1434 break; \
1435 default: \
fc723380
JG
1436 cache_ptr->section = NULL; /* No section */ \
1437 cache_ptr->addend = ad; /* FIXME, is this right? */ \
c93595dd
SC
1438 BFD_ASSERT(1); \
1439 break; \
1440 } \
1441 } \
1442
1443void
1444swap_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));
c93595dd
SC
1476}
1477
1478void
1479swap_std_reloc_in (abfd, bytes, cache_ptr, symbols)
1480 bfd *abfd;
fc723380 1481 struct reloc_std_bytes *bytes;
c93595dd
SC
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);
fc723380 1491
c93595dd
SC
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)
fc723380 1505 >> RELOC_STD_BITS_LENGTH_SH_BIG;
c93595dd
SC
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)
fc723380 1516 >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
c93595dd
SC
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 */
4a81b561
DHW
1526
1527boolean
1528sunos4_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;
9846338e 1535 PTR relocs;
4a81b561 1536 arelent *reloc_cache;
c93595dd 1537 size_t each_size;
4a81b561
DHW
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);
c93595dd
SC
1558 each_size = reloc_size_func(abfd);
1559
1560 count = reloc_size / each_size;
4a81b561 1561
9872a49c
SC
1562
1563 reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1564 (arelent)));
fc723380
JG
1565 if (!reloc_cache) {
1566nomem:
1567 bfd_error = no_memory;
1568 return false;
1569 }
1570
9872a49c 1571 relocs = bfd_alloc (abfd, reloc_size);
fc723380
JG
1572 if (!relocs) {
1573 bfd_release (abfd, reloc_cache);
1574 goto nomem;
1575 }
4a81b561 1576
fc723380
JG
1577 if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1578 bfd_release (abfd, relocs);
1579 bfd_release (abfd, reloc_cache);
4a81b561 1580 bfd_error = system_call_error;
4a81b561
DHW
1581 return false;
1582 }
1583
fc723380
JG
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;
c93595dd 1588
fc723380
JG
1589 for (; counter < count; counter++, rptr++, cache_ptr++) {
1590 swap_ext_reloc_in(abfd, rptr, cache_ptr, symbols);
c93595dd 1591 }
fc723380 1592 } else {
9846338e 1593 register struct reloc_std_bytes *rptr = (struct reloc_std_bytes *) relocs;
4a81b561
DHW
1594 unsigned int counter = 0;
1595 arelent *cache_ptr = reloc_cache;
1596
1597 for (; counter < count; counter++, rptr++, cache_ptr++) {
c93595dd 1598 swap_std_reloc_in(abfd, rptr, cache_ptr, symbols);
4a81b561 1599 }
4a81b561 1600
c93595dd 1601 }
fc723380
JG
1602
1603 bfd_release (abfd,relocs);
4a81b561
DHW
1604 asect->relocation = reloc_cache;
1605 asect->reloc_count = count;
1606 return true;
1607}
1608
c93595dd
SC
1609
1610
1611/* Write out a relocation section into an object file. */
1612
4a81b561
DHW
1613static boolean
1614sunos4_squirt_out_relocs (abfd, section)
1615 bfd *abfd;
1616 asection *section;
1617{
1618 arelent **generic;
fc723380 1619 unsigned char *native, *natptr;
c93595dd 1620 size_t each_size;
4a81b561
DHW
1621
1622 unsigned int count = section->reloc_count;
c93595dd 1623 size_t natsize;
4a81b561
DHW
1624
1625 if (count == 0) return true;
c93595dd
SC
1626
1627 each_size = reloc_size_func(abfd);
1628 natsize = each_size * count;
9872a49c 1629 native = (unsigned char *) bfd_zalloc (abfd, natsize);
4a81b561
DHW
1630 if (!native) {
1631 bfd_error = no_memory;
1632 return false;
1633 }
1634
c93595dd 1635 generic = section->orelocation;
4a81b561 1636
c93595dd
SC
1637 if (each_size == RELOC_EXT_SIZE)
1638 {
fc723380
JG
1639 for (natptr = native;
1640 count != 0;
1641 --count, natptr += each_size, ++generic)
b6316534 1642 swap_ext_reloc_out (abfd, *generic, (struct reloc_ext_bytes *)natptr);
c93595dd
SC
1643 }
1644 else
1645 {
fc723380
JG
1646 for (natptr = native;
1647 count != 0;
1648 --count, natptr += each_size, ++generic)
b6316534 1649 swap_std_reloc_out(abfd, *generic, (struct reloc_std_bytes *)natptr);
4a81b561
DHW
1650 }
1651
9846338e 1652 if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
9872a49c 1653 bfd_release(abfd, native);
4a81b561
DHW
1654 return false;
1655 }
9872a49c 1656 bfd_release (abfd, native);
4a81b561
DHW
1657
1658 return true;
1659}
1660
1661/* This is stupid. This function should be a boolean predicate */
1662unsigned int
1663sunos4_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
1696unsigned int
1697sunos4_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
c93595dd 1709
4a81b561
DHW
1710 if (asect == obj_datasec (abfd))
1711 return (sizeof (arelent *) *
c93595dd 1712 ((exec_hdr(abfd)->a_drsize / reloc_size_func(abfd))
4a81b561
DHW
1713 +1));
1714
1715 if (asect == obj_textsec (abfd))
1716 return (sizeof (arelent *) *
c93595dd 1717 ((exec_hdr(abfd)->a_trsize / reloc_size_func(abfd))
4a81b561
DHW
1718 +1));
1719
1720 bfd_error = invalid_operation;
1721 return 0;
1722}
1723
1724void
b1847ba9 1725sunos4_reclaim_reloc (ignore_abfd, ignore)
4a81b561 1726 bfd *ignore_abfd;
b1847ba9 1727 sec_ptr ignore;
4a81b561 1728{
9872a49c 1729
4a81b561
DHW
1730}
1731\f
1732
1733alent *
1734sunos4_get_lineno(ignore_abfd, ignore_symbol)
1735bfd *ignore_abfd;
4432f8ad 1736PTR ignore_symbol;
4a81b561
DHW
1737{
1738return (alent *)NULL;
1739}
1740
1741void
1742sunos4_print_symbol(ignore_abfd, file, symbol, how)
1743bfd *ignore_abfd;
1744FILE *file;
1745asymbol *symbol;
1746bfd_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),
fc723380 1754 (unsigned)(aout_symbol(symbol)->other & 0xff),
4a81b561
DHW
1755 (unsigned)(aout_symbol(symbol)->type));
1756 break;
1757 case bfd_print_symbol_all_enum:
1758 {
9846338e 1759 CONST char *section_name = symbol->section == (asection *)NULL ?
4a81b561
DHW
1760 "*abs" : symbol->section->name;
1761
9846338e 1762 bfd_print_symbol_vandf((PTR)file,symbol);
4a81b561
DHW
1763
1764 fprintf(file," %-5s %04x %02x %02x %s",
1765 section_name,
1766 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
fc723380 1767 (unsigned)(aout_symbol(symbol)->other & 0xff),
4a81b561
DHW
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
1777boolean
1778sunos4_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
4a81b561
DHW
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
1799boolean
9846338e
SC
1800DEFUN(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)
4a81b561
DHW
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) {
9846338e 1854 CONST char *function = func->name;
4a81b561
DHW
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
39a2ce33 1875static int
b1847ba9
JG
1876DEFUN(sunos4_sizeof_headers,(ignore_abfd),
1877 bfd *ignore_abfd)
39a2ce33 1878{
b1847ba9 1879 return 0; /* FIXME, this is the wrong value! */
39a2ce33
SC
1880}
1881
9872a49c
SC
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
9846338e 1888bfd_target aout_big_vec =
4a81b561
DHW
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 */
4a81b561
DHW
1898 ' ', /* ar_pad_char */
1899 16, /* ar_max_namelen */
4a81b561
DHW
1900 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1901 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1902
9872a49c
SC
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)
4a81b561
DHW
1909 };
1910
9872a49c 1911
9846338e
SC
1912bfd_target aout_little_vec =
1913{
1914 "a.out-generic-little", /* name */
1915 bfd_target_aout_flavour_enum,
9872a49c
SC
1916 false, /* target byte order */
1917 false, /* target headers byte order */
9846338e
SC
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 */
9846338e
SC
1922 ' ', /* ar_pad_char */
1923 16, /* ar_max_namelen */
9846338e
SC
1924 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* data */
1925 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* hdrs */
1926
9872a49c
SC
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)
9846338e 1934 };
This page took 0.107419 seconds and 4 git commands to generate.