Change 'partial_inplace' to true (this target uses REL relocations) and
[deliverable/binutils-gdb.git] / bfd / aout-adobe.c
CommitLineData
252b5132 1/* BFD back-end for a.out.adobe binaries.
7898deda 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000
5f771d47 3 Free Software Foundation, Inc.
252b5132
RH
4 Written by Cygnus Support. Based on bout.c.
5
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22#include "bfd.h"
23#include "sysdep.h"
24#include "libbfd.h"
25
26#include "aout/adobe.h"
27
28#include "aout/stab_gnu.h"
29#include "libaout.h" /* BFD a.out internal data structures */
30
336eced2
KH
31/* Forward decl. */
32extern const bfd_target a_out_adobe_vec;
252b5132
RH
33
34static const bfd_target *aout_adobe_callback PARAMS ((bfd *));
35
36extern boolean aout_32_slurp_symbol_table PARAMS ((bfd *abfd));
37extern boolean aout_32_write_syms PARAMS ((bfd *));
38static void aout_adobe_write_section PARAMS ((bfd *abfd, sec_ptr sect));
39
40/* Swaps the information in an executable header taken from a raw byte
41 stream memory image, into the internal exec_header structure. */
42
43void aout_adobe_swap_exec_header_in
44 PARAMS ((bfd *abfd, struct external_exec *raw_bytes,
45 struct internal_exec *execp));
c4dfa77f 46
252b5132
RH
47void
48aout_adobe_swap_exec_header_in (abfd, raw_bytes, execp)
49 bfd *abfd;
50 struct external_exec *raw_bytes;
51 struct internal_exec *execp;
52{
336eced2 53 struct external_exec *bytes = (struct external_exec *) raw_bytes;
252b5132
RH
54
55 /* Now fill in fields in the execp, from the bytes in the raw data. */
56 execp->a_info = bfd_h_get_32 (abfd, bytes->e_info);
57 execp->a_text = GET_WORD (abfd, bytes->e_text);
58 execp->a_data = GET_WORD (abfd, bytes->e_data);
59 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
60 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
61 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
62 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
63 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
64}
65
66/* Swaps the information in an internal exec header structure into the
67 supplied buffer ready for writing to disk. */
68
69PROTO(void, aout_adobe_swap_exec_header_out,
70 (bfd *abfd,
71 struct internal_exec *execp,
72 struct external_exec *raw_bytes));
73void
74aout_adobe_swap_exec_header_out (abfd, execp, raw_bytes)
75 bfd *abfd;
76 struct internal_exec *execp;
77 struct external_exec *raw_bytes;
78{
336eced2 79 struct external_exec *bytes = (struct external_exec *) raw_bytes;
252b5132 80
336eced2
KH
81 /* Now fill in fields in the raw data, from the fields in the exec
82 struct. */
252b5132
RH
83 bfd_h_put_32 (abfd, execp->a_info , bytes->e_info);
84 PUT_WORD (abfd, execp->a_text , bytes->e_text);
85 PUT_WORD (abfd, execp->a_data , bytes->e_data);
86 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
87 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
88 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
89 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
90 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
91}
92
252b5132
RH
93static const bfd_target *
94aout_adobe_object_p (abfd)
95 bfd *abfd;
96{
97 struct internal_exec anexec;
98 struct external_exec exec_bytes;
99 char *targ;
100
101 if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
336eced2
KH
102 != EXEC_BYTES_SIZE)
103 {
104 if (bfd_get_error () != bfd_error_system_call)
105 bfd_set_error (bfd_error_wrong_format);
106 return 0;
107 }
252b5132
RH
108
109 anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
110
111 /* Normally we just compare for the magic number.
112 However, a bunch of Adobe tools aren't fixed up yet; they generate
113 files using ZMAGIC(!).
114 If the environment variable GNUTARGET is set to "a.out.adobe", we will
115 take just about any a.out file as an Adobe a.out file. FIXME! */
116
336eced2
KH
117 if (N_BADMAG (anexec))
118 {
119 targ = getenv ("GNUTARGET");
120 if (targ && !strcmp (targ, a_out_adobe_vec.name))
121 /* Just continue anyway, if specifically set to this format. */
122 ;
123 else
124 {
125 bfd_set_error (bfd_error_wrong_format);
126 return 0;
127 }
128 }
252b5132
RH
129
130 aout_adobe_swap_exec_header_in (abfd, &exec_bytes, &anexec);
131 return aout_32_some_aout_object_p (abfd, &anexec, aout_adobe_callback);
132}
133
252b5132
RH
134/* Finish up the opening of a b.out file for reading. Fill in all the
135 fields that are not handled by common code. */
136
137static const bfd_target *
138aout_adobe_callback (abfd)
139 bfd *abfd;
140{
141 struct internal_exec *execp = exec_hdr (abfd);
142 asection *sect;
143 struct external_segdesc ext[1];
144 char *section_name;
145 char try_again[30]; /* name and number */
146 char *newname;
147 int trynum;
148 flagword flags;
149
150 /* Architecture and machine type -- unknown in this format. */
336eced2 151 bfd_set_arch_mach (abfd, bfd_arch_unknown, 0);
252b5132
RH
152
153 /* The positions of the string table and symbol table. */
154 obj_str_filepos (abfd) = N_STROFF (*execp);
155 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
156
157 /* Suck up the section information from the file, one section at a time. */
158
336eced2
KH
159 for (;;)
160 {
161 if (bfd_read ((PTR) ext, 1, sizeof (*ext), abfd) != sizeof (*ext))
162 {
163 if (bfd_get_error () != bfd_error_system_call)
164 bfd_set_error (bfd_error_wrong_format);
165 return 0;
166 }
167 switch (ext->e_type[0])
168 {
169 case N_TEXT:
170 section_name = ".text";
171 flags = SEC_CODE | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
172 break;
173
174 case N_DATA:
175 section_name = ".data";
176 flags = SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
177 break;
178
179 case N_BSS:
180 section_name = ".bss";
181 flags = SEC_DATA | SEC_HAS_CONTENTS;
182 break;
183
184 case 0:
185 goto no_more_sections;
186
187 default:
188 (*_bfd_error_handler)
189 (_("%s: Unknown section type in a.out.adobe file: %x\n"),
190 bfd_get_filename (abfd), ext->e_type[0]);
191 goto no_more_sections;
192 }
193
194 /* First one is called ".text" or whatever; subsequent ones are
195 ".text1", ".text2", ... */
196
197 bfd_set_error (bfd_error_no_error);
198 sect = bfd_make_section (abfd, section_name);
199 trynum = 0;
200 while (!sect)
201 {
202 if (bfd_get_error () != bfd_error_no_error)
203 /* Some other error -- slide into the sunset. */
204 return 0;
205 sprintf (try_again, "%s%d", section_name, ++trynum);
206 sect = bfd_make_section (abfd, try_again);
207 }
208
209 /* Fix the name, if it is a sprintf'd name. */
210 if (sect->name == try_again)
211 {
212 newname = (char *) bfd_zalloc (abfd, strlen (sect->name));
213 if (newname == NULL)
214 return 0;
215 strcpy (newname, sect->name);
216 sect->name = newname;
217 }
218
219 /* Now set the section's attributes. */
220 bfd_set_section_flags (abfd, sect, flags);
221 /* Assumed big-endian. */
222 sect->_raw_size = ((ext->e_size[0] << 8)
223 | ext->e_size[1] << 8)
224 | ext->e_size[2];
225 sect->_cooked_size = sect->_raw_size;
226 sect->vma = bfd_h_get_32 (abfd, ext->e_virtbase);
227 sect->filepos = bfd_h_get_32 (abfd, ext->e_filebase);
228 /* FIXME XXX alignment? */
229
230 /* Set relocation information for first section of each type. */
231 if (trynum == 0)
232 switch (ext->e_type[0])
233 {
234 case N_TEXT:
235 sect->rel_filepos = N_TRELOFF (*execp);
236 sect->reloc_count = execp->a_trsize;
237 break;
238
239 case N_DATA:
240 sect->rel_filepos = N_DRELOFF (*execp);
241 sect->reloc_count = execp->a_drsize;
242 break;
243 }
252b5132 244 }
336eced2 245 no_more_sections:
252b5132 246
336eced2
KH
247 adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
248 adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
249 adata (abfd).page_size = 1; /* Not applicable. */
250 adata (abfd).segment_size = 1; /* Not applicable. */
251 adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
252b5132
RH
252
253 return abfd->xvec;
254}
255
256struct bout_data_struct {
336eced2
KH
257 struct aoutdata a;
258 struct internal_exec e;
252b5132
RH
259};
260
261static boolean
262aout_adobe_mkobject (abfd)
263 bfd *abfd;
264{
265 struct bout_data_struct *rawptr;
266
267 rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct));
268 if (rawptr == NULL)
336eced2 269 return false;
252b5132
RH
270
271 abfd->tdata.bout_data = rawptr;
272 exec_hdr (abfd) = &rawptr->e;
273
336eced2
KH
274 adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
275 adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
276 adata (abfd).page_size = 1; /* Not applicable. */
277 adata (abfd).segment_size = 1; /* Not applicable. */
278 adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
252b5132
RH
279
280 return true;
281}
282
252b5132
RH
283static boolean
284aout_adobe_write_object_contents (abfd)
285 bfd *abfd;
286{
287 struct external_exec swapped_hdr;
336eced2 288 static struct external_segdesc sentinel[1]; /* Initialized to zero. */
252b5132
RH
289 asection *sect;
290
291 exec_hdr (abfd)->a_info = ZMAGIC;
292
c4dfa77f 293 /* Calculate text size as total of text sections, etc. */
252b5132
RH
294
295 exec_hdr (abfd)->a_text = 0;
296 exec_hdr (abfd)->a_data = 0;
297 exec_hdr (abfd)->a_bss = 0;
298 exec_hdr (abfd)->a_trsize = 0;
299 exec_hdr (abfd)->a_drsize = 0;
300
336eced2
KH
301 for (sect = abfd->sections; sect; sect = sect->next)
302 {
303 if (sect->flags & SEC_CODE)
304 {
305 exec_hdr (abfd)->a_text += sect->_raw_size;
306 exec_hdr (abfd)->a_trsize += sect->reloc_count *
307 sizeof (struct reloc_std_external);
308 }
309 else if (sect->flags & SEC_DATA)
310 {
311 exec_hdr (abfd)->a_data += sect->_raw_size;
312 exec_hdr (abfd)->a_drsize += sect->reloc_count *
313 sizeof (struct reloc_std_external);
314 }
315 else if (sect->flags & SEC_ALLOC && !(sect->flags & SEC_LOAD))
316 {
317 exec_hdr (abfd)->a_bss += sect->_raw_size;
318 }
252b5132 319 }
252b5132
RH
320
321 exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd)
336eced2 322 * sizeof (struct external_nlist);
252b5132
RH
323 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
324
325 aout_adobe_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
326
327 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
328 || (bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd)
329 != EXEC_BYTES_SIZE))
330 return false;
331
332 /* Now write out the section information. Text first, data next, rest
333 afterward. */
334
336eced2
KH
335 for (sect = abfd->sections; sect; sect = sect->next)
336 {
337 if (sect->flags & SEC_CODE)
338 {
339 aout_adobe_write_section (abfd, sect);
340 }
252b5132 341 }
336eced2
KH
342 for (sect = abfd->sections; sect; sect = sect->next)
343 {
344 if (sect->flags & SEC_DATA)
345 {
346 aout_adobe_write_section (abfd, sect);
347 }
252b5132 348 }
336eced2
KH
349 for (sect = abfd->sections; sect; sect = sect->next)
350 {
351 if (!(sect->flags & (SEC_CODE | SEC_DATA)))
352 {
353 aout_adobe_write_section (abfd, sect);
354 }
252b5132 355 }
252b5132
RH
356
357 /* Write final `sentinel` section header (with type of 0). */
358 if (bfd_write ((PTR) sentinel, 1, sizeof (*sentinel), abfd)
359 != sizeof (*sentinel))
360 return false;
361
336eced2 362 /* Now write out reloc info, followed by syms and strings. */
c4dfa77f 363 if (bfd_get_symcount (abfd) != 0)
252b5132 364 {
336eced2 365 if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*exec_hdr (abfd))), SEEK_SET)
252b5132
RH
366 != 0)
367 return false;
368
369 if (! aout_32_write_syms (abfd))
370 return false;
371
336eced2 372 if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*exec_hdr (abfd))), SEEK_SET)
252b5132
RH
373 != 0)
374 return false;
375
336eced2
KH
376 for (sect = abfd->sections; sect; sect = sect->next)
377 {
378 if (sect->flags & SEC_CODE)
379 {
380 if (!aout_32_squirt_out_relocs (abfd, sect))
381 return false;
382 }
383 }
252b5132 384
336eced2 385 if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*exec_hdr (abfd))), SEEK_SET)
252b5132
RH
386 != 0)
387 return false;
388
336eced2
KH
389 for (sect = abfd->sections; sect; sect = sect->next)
390 {
391 if (sect->flags & SEC_DATA)
392 {
393 if (!aout_32_squirt_out_relocs (abfd, sect))
394 return false;
395 }
396 }
252b5132
RH
397 }
398 return true;
399}
400
401static void
402aout_adobe_write_section (abfd, sect)
5f771d47
ILT
403 bfd *abfd ATTRIBUTE_UNUSED;
404 sec_ptr sect ATTRIBUTE_UNUSED;
252b5132
RH
405{
406 /* FIXME XXX */
407}
408\f
409static boolean
410aout_adobe_set_section_contents (abfd, section, location, offset, count)
411 bfd *abfd;
412 asection *section;
413 PTR location;
414 file_ptr offset;
415 bfd_size_type count;
416{
417 file_ptr section_start;
418 sec_ptr sect;
419
336eced2
KH
420 /* Set by bfd.c handler. */
421 if (abfd->output_has_begun == false)
422 {
423 /* Assign file offsets to sections. Text sections are first, and
424 are contiguous. Then data sections. Everything else at the end. */
425
426 section_start = N_TXTOFF (ignore<-->me);
427
428 for (sect = abfd->sections; sect; sect = sect->next)
429 {
430 if (sect->flags & SEC_CODE)
431 {
432 sect->filepos = section_start;
433 /* FIXME: Round to alignment. */
434 section_start += sect->_raw_size;
435 }
436 }
437
438 for (sect = abfd->sections; sect; sect = sect->next)
439 {
440 if (sect->flags & SEC_DATA)
441 {
442 sect->filepos = section_start;
443 /* FIXME: Round to alignment. */
444 section_start += sect->_raw_size;
445 }
446 }
447
448 for (sect = abfd->sections; sect; sect = sect->next)
449 {
450 if (sect->flags & SEC_HAS_CONTENTS &&
451 !(sect->flags & (SEC_CODE | SEC_DATA)))
452 {
453 sect->filepos = section_start;
454 /* FIXME: Round to alignment. */
455 section_start += sect->_raw_size;
456 }
457 }
252b5132 458 }
252b5132 459
336eced2
KH
460 /* Regardless, once we know what we're doing, we might as well get
461 going. */
252b5132
RH
462 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
463 return false;
464
336eced2
KH
465 if (count != 0)
466 {
467 return (bfd_write ((PTR) location, 1, count, abfd) == count) ? true : false;
468 }
252b5132
RH
469 return true;
470}
471
472static boolean
473aout_adobe_set_arch_mach (abfd, arch, machine)
474 bfd *abfd;
475 enum bfd_architecture arch;
476 unsigned long machine;
477{
478 if (! bfd_default_set_arch_mach (abfd, arch, machine))
479 return false;
480
481 if (arch == bfd_arch_unknown
482 || arch == bfd_arch_m68k)
483 return true;
484
485 return false;
486}
487
c4dfa77f 488static int
252b5132 489aout_adobe_sizeof_headers (ignore_abfd, ignore)
5f771d47
ILT
490 bfd *ignore_abfd ATTRIBUTE_UNUSED;
491 boolean ignore ATTRIBUTE_UNUSED;
252b5132 492{
beb0d161 493 return sizeof (struct internal_exec);
252b5132
RH
494}
495
252b5132
RH
496/* Build the transfer vector for Adobe A.Out files. */
497
498#define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
499
500#define aout_32_bfd_make_debug_symbol \
501 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
502
503#define aout_32_bfd_reloc_type_lookup \
504 ((reloc_howto_type *(*) \
505 PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
506
507#define aout_32_set_arch_mach aout_adobe_set_arch_mach
508#define aout_32_set_section_contents aout_adobe_set_section_contents
509
510#define aout_32_sizeof_headers aout_adobe_sizeof_headers
511#define aout_32_bfd_get_relocated_section_contents \
512 bfd_generic_get_relocated_section_contents
513#define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
514#define aout_32_bfd_relax_section bfd_generic_relax_section
515#define aout_32_bfd_gc_sections bfd_generic_gc_sections
8550eb6e 516#define aout_32_bfd_merge_sections bfd_generic_merge_sections
252b5132
RH
517#define aout_32_bfd_link_hash_table_create \
518 _bfd_generic_link_hash_table_create
519#define aout_32_bfd_link_add_symbols _bfd_generic_link_add_symbols
520#define aout_32_bfd_final_link _bfd_generic_final_link
521#define aout_32_bfd_link_split_section _bfd_generic_link_split_section
522
336eced2 523const bfd_target a_out_adobe_vec = {
252b5132
RH
524 "a.out.adobe", /* name */
525 bfd_target_aout_flavour,
526 BFD_ENDIAN_BIG, /* data byte order is unknown (big assumed) */
527 BFD_ENDIAN_BIG, /* hdr byte order is big */
528 (HAS_RELOC | EXEC_P | /* object flags */
529 HAS_LINENO | HAS_DEBUG |
530 HAS_SYMS | HAS_LOCALS | WP_TEXT ),
531 /* section flags */
532 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_DATA | SEC_RELOC),
533 '_', /* symbol leading char */
534 ' ', /* ar_pad_char */
535 16, /* ar_max_namelen */
536
537 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
336eced2
KH
538 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
539 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
252b5132 540 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
336eced2
KH
541 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
542 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
543 {_bfd_dummy_target, aout_adobe_object_p, /* bfd_check_format */
252b5132 544 bfd_generic_archive_p, _bfd_dummy_target},
336eced2 545 {bfd_false, aout_adobe_mkobject, /* bfd_set_format */
252b5132 546 _bfd_generic_mkarchive, bfd_false},
336eced2 547 {bfd_false, aout_adobe_write_object_contents, /* bfd_write_contents */
252b5132
RH
548 _bfd_write_archive_contents, bfd_false},
549
336eced2
KH
550 BFD_JUMP_TABLE_GENERIC (aout_32),
551 BFD_JUMP_TABLE_COPY (_bfd_generic),
552 BFD_JUMP_TABLE_CORE (_bfd_nocore),
553 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
554 BFD_JUMP_TABLE_SYMBOLS (aout_32),
555 BFD_JUMP_TABLE_RELOCS (aout_32),
556 BFD_JUMP_TABLE_WRITE (aout_32),
557 BFD_JUMP_TABLE_LINK (aout_32),
558 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
252b5132 559
c3c89269 560 NULL,
c4dfa77f 561
252b5132
RH
562 (PTR) 0
563};
This page took 0.117175 seconds and 4 git commands to generate.