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