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