00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "bfd.h"
00028 #include "sysdep.h"
00029 #include "libbfd.h"
00030
00031 #include "aout/adobe.h"
00032
00033 #include "aout/stab_gnu.h"
00034 #include "libaout.h"
00035
00036
00037 extern const bfd_target a_out_adobe_vec;
00038
00039 static const bfd_target *aout_adobe_callback
00040 PARAMS ((bfd *));
00041 extern bfd_boolean aout_32_slurp_symbol_table
00042 PARAMS ((bfd *abfd));
00043 extern bfd_boolean aout_32_write_syms
00044 PARAMS ((bfd *));
00045 static void aout_adobe_write_section
00046 PARAMS ((bfd *abfd, sec_ptr sect));
00047 static const bfd_target * aout_adobe_object_p
00048 PARAMS ((bfd *));
00049 static bfd_boolean aout_adobe_mkobject
00050 PARAMS ((bfd *));
00051 static bfd_boolean aout_adobe_write_object_contents
00052 PARAMS ((bfd *));
00053 static bfd_boolean aout_adobe_set_section_contents
00054 PARAMS ((bfd *, asection *, const PTR, file_ptr, bfd_size_type));
00055 static bfd_boolean aout_adobe_set_arch_mach
00056 PARAMS ((bfd *, enum bfd_architecture, unsigned long));
00057 static int aout_adobe_sizeof_headers
00058 PARAMS ((bfd *, bfd_boolean));
00059
00060
00061
00062
00063 void aout_adobe_swap_exec_header_in
00064 PARAMS ((bfd *, struct external_exec *, struct internal_exec *));
00065
00066 void
00067 aout_adobe_swap_exec_header_in (abfd, raw_bytes, execp)
00068 bfd *abfd;
00069 struct external_exec *raw_bytes;
00070 struct internal_exec *execp;
00071 {
00072 struct external_exec *bytes = (struct external_exec *) raw_bytes;
00073
00074
00075 execp->a_info = H_GET_32 (abfd, bytes->e_info);
00076 execp->a_text = GET_WORD (abfd, bytes->e_text);
00077 execp->a_data = GET_WORD (abfd, bytes->e_data);
00078 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
00079 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
00080 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
00081 execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
00082 execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
00083 }
00084
00085
00086
00087
00088 void aout_adobe_swap_exec_header_out
00089 PARAMS ((bfd *, struct internal_exec *, struct external_exec *));
00090
00091 void
00092 aout_adobe_swap_exec_header_out (abfd, execp, raw_bytes)
00093 bfd *abfd;
00094 struct internal_exec *execp;
00095 struct external_exec *raw_bytes;
00096 {
00097 struct external_exec *bytes = (struct external_exec *) raw_bytes;
00098
00099
00100
00101 H_PUT_32 (abfd, execp->a_info , bytes->e_info);
00102 PUT_WORD (abfd, execp->a_text , bytes->e_text);
00103 PUT_WORD (abfd, execp->a_data , bytes->e_data);
00104 PUT_WORD (abfd, execp->a_bss , bytes->e_bss);
00105 PUT_WORD (abfd, execp->a_syms , bytes->e_syms);
00106 PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
00107 PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
00108 PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
00109 }
00110
00111 static const bfd_target *
00112 aout_adobe_object_p (abfd)
00113 bfd *abfd;
00114 {
00115 struct internal_exec anexec;
00116 struct external_exec exec_bytes;
00117 char *targ;
00118 bfd_size_type amt = EXEC_BYTES_SIZE;
00119
00120 if (bfd_bread ((PTR) &exec_bytes, amt, abfd) != amt)
00121 {
00122 if (bfd_get_error () != bfd_error_system_call)
00123 bfd_set_error (bfd_error_wrong_format);
00124 return 0;
00125 }
00126
00127 anexec.a_info = H_GET_32 (abfd, exec_bytes.e_info);
00128
00129
00130
00131
00132
00133
00134
00135 if (N_BADMAG (anexec))
00136 {
00137 targ = getenv ("GNUTARGET");
00138 if (targ && !strcmp (targ, a_out_adobe_vec.name))
00139
00140 ;
00141 else
00142 {
00143 bfd_set_error (bfd_error_wrong_format);
00144 return 0;
00145 }
00146 }
00147
00148 aout_adobe_swap_exec_header_in (abfd, &exec_bytes, &anexec);
00149 return aout_32_some_aout_object_p (abfd, &anexec, aout_adobe_callback);
00150 }
00151
00152
00153
00154
00155 static const bfd_target *
00156 aout_adobe_callback (abfd)
00157 bfd *abfd;
00158 {
00159 struct internal_exec *execp = exec_hdr (abfd);
00160 asection *sect;
00161 struct external_segdesc ext[1];
00162 char *section_name;
00163 char try_again[30];
00164 char *newname;
00165 int trynum;
00166 flagword flags;
00167
00168
00169 bfd_set_arch_mach (abfd, bfd_arch_unknown, 0L);
00170
00171
00172 obj_str_filepos (abfd) = N_STROFF (*execp);
00173 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
00174
00175
00176 for (;;)
00177 {
00178 bfd_size_type amt = sizeof (*ext);
00179 if (bfd_bread ((PTR) ext, amt, abfd) != amt)
00180 {
00181 if (bfd_get_error () != bfd_error_system_call)
00182 bfd_set_error (bfd_error_wrong_format);
00183
00184 return 0;
00185 }
00186 switch (ext->e_type[0])
00187 {
00188 case N_TEXT:
00189 section_name = ".text";
00190 flags = SEC_CODE | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
00191 break;
00192
00193 case N_DATA:
00194 section_name = ".data";
00195 flags = SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS;
00196 break;
00197
00198 case N_BSS:
00199 section_name = ".bss";
00200 flags = SEC_DATA | SEC_HAS_CONTENTS;
00201 break;
00202
00203 case 0:
00204 goto no_more_sections;
00205
00206 default:
00207 (*_bfd_error_handler)
00208 (_("%B: Unknown section type in a.out.adobe file: %x\n"),
00209 abfd, ext->e_type[0]);
00210 goto no_more_sections;
00211 }
00212
00213
00214
00215 bfd_set_error (bfd_error_no_error);
00216 sect = bfd_make_section (abfd, section_name);
00217 trynum = 0;
00218
00219 while (!sect)
00220 {
00221 if (bfd_get_error () != bfd_error_no_error)
00222
00223 return 0;
00224 sprintf (try_again, "%s%d", section_name, ++trynum);
00225 sect = bfd_make_section (abfd, try_again);
00226 }
00227
00228
00229 if (sect->name == try_again)
00230 {
00231 amt = strlen (sect->name);
00232 newname = (char *) bfd_zalloc (abfd, amt);
00233 if (newname == NULL)
00234 return 0;
00235 strcpy (newname, sect->name);
00236 sect->name = newname;
00237 }
00238
00239
00240 bfd_set_section_flags (abfd, sect, flags);
00241
00242 sect->size = ((ext->e_size[0] << 8)
00243 | ext->e_size[1] << 8
00244 | ext->e_size[2]);
00245 sect->vma = H_GET_32 (abfd, ext->e_virtbase);
00246 sect->filepos = H_GET_32 (abfd, ext->e_filebase);
00247
00248
00249
00250 if (trynum == 0)
00251 switch (ext->e_type[0])
00252 {
00253 case N_TEXT:
00254 sect->rel_filepos = N_TRELOFF (*execp);
00255 sect->reloc_count = execp->a_trsize;
00256 break;
00257
00258 case N_DATA:
00259 sect->rel_filepos = N_DRELOFF (*execp);
00260 sect->reloc_count = execp->a_drsize;
00261 break;
00262
00263 default:
00264 break;
00265 }
00266 }
00267 no_more_sections:
00268
00269 adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
00270 adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
00271 adata (abfd).page_size = 1;
00272 adata (abfd).segment_size = 1;
00273 adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
00274
00275 return abfd->xvec;
00276 }
00277
00278 struct bout_data_struct
00279 {
00280 struct aoutdata a;
00281 struct internal_exec e;
00282 };
00283
00284 static bfd_boolean
00285 aout_adobe_mkobject (abfd)
00286 bfd *abfd;
00287 {
00288 struct bout_data_struct *rawptr;
00289 bfd_size_type amt = sizeof (struct bout_data_struct);
00290
00291 rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, amt);
00292 if (rawptr == NULL)
00293 return FALSE;
00294
00295 abfd->tdata.bout_data = rawptr;
00296 exec_hdr (abfd) = &rawptr->e;
00297
00298 adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external);
00299 adata (abfd).symbol_entry_size = sizeof (struct external_nlist);
00300 adata (abfd).page_size = 1;
00301 adata (abfd).segment_size = 1;
00302 adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
00303
00304 return TRUE;
00305 }
00306
00307 static bfd_boolean
00308 aout_adobe_write_object_contents (abfd)
00309 bfd *abfd;
00310 {
00311 struct external_exec swapped_hdr;
00312 static struct external_segdesc sentinel[1];
00313 asection *sect;
00314 bfd_size_type amt;
00315
00316 exec_hdr (abfd)->a_info = ZMAGIC;
00317
00318
00319
00320 exec_hdr (abfd)->a_text = 0;
00321 exec_hdr (abfd)->a_data = 0;
00322 exec_hdr (abfd)->a_bss = 0;
00323 exec_hdr (abfd)->a_trsize = 0;
00324 exec_hdr (abfd)->a_drsize = 0;
00325
00326 for (sect = abfd->sections; sect; sect = sect->next)
00327 {
00328 if (sect->flags & SEC_CODE)
00329 {
00330 exec_hdr (abfd)->a_text += sect->size;
00331 exec_hdr (abfd)->a_trsize += sect->reloc_count *
00332 sizeof (struct reloc_std_external);
00333 }
00334 else if (sect->flags & SEC_DATA)
00335 {
00336 exec_hdr (abfd)->a_data += sect->size;
00337 exec_hdr (abfd)->a_drsize += sect->reloc_count *
00338 sizeof (struct reloc_std_external);
00339 }
00340 else if (sect->flags & SEC_ALLOC && !(sect->flags & SEC_LOAD))
00341 {
00342 exec_hdr (abfd)->a_bss += sect->size;
00343 }
00344 }
00345
00346 exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd)
00347 * sizeof (struct external_nlist);
00348 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
00349
00350 aout_adobe_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
00351
00352 amt = EXEC_BYTES_SIZE;
00353 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
00354 || bfd_bwrite ((PTR) &swapped_hdr, amt, abfd) != amt)
00355 return FALSE;
00356
00357
00358
00359
00360 for (sect = abfd->sections; sect; sect = sect->next)
00361 if (sect->flags & SEC_CODE)
00362 aout_adobe_write_section (abfd, sect);
00363
00364 for (sect = abfd->sections; sect; sect = sect->next)
00365 if (sect->flags & SEC_DATA)
00366 aout_adobe_write_section (abfd, sect);
00367
00368 for (sect = abfd->sections; sect; sect = sect->next)
00369 if (!(sect->flags & (SEC_CODE | SEC_DATA)))
00370 aout_adobe_write_section (abfd, sect);
00371
00372
00373 amt = sizeof (*sentinel);
00374 if (bfd_bwrite ((PTR) sentinel, amt, abfd) != amt)
00375 return FALSE;
00376
00377
00378 if (bfd_get_symcount (abfd) != 0)
00379 {
00380 if (bfd_seek (abfd, (file_ptr) (N_SYMOFF (*exec_hdr (abfd))), SEEK_SET)
00381 != 0)
00382 return FALSE;
00383
00384 if (! aout_32_write_syms (abfd))
00385 return FALSE;
00386
00387 if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*exec_hdr (abfd))), SEEK_SET)
00388 != 0)
00389 return FALSE;
00390
00391 for (sect = abfd->sections; sect; sect = sect->next)
00392 if (sect->flags & SEC_CODE)
00393 if (!aout_32_squirt_out_relocs (abfd, sect))
00394 return FALSE;
00395
00396 if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*exec_hdr (abfd))), SEEK_SET)
00397 != 0)
00398 return FALSE;
00399
00400 for (sect = abfd->sections; sect; sect = sect->next)
00401 if (sect->flags & SEC_DATA)
00402 if (!aout_32_squirt_out_relocs (abfd, sect))
00403 return FALSE;
00404 }
00405
00406 return TRUE;
00407 }
00408
00409 static void
00410 aout_adobe_write_section (abfd, sect)
00411 bfd *abfd ATTRIBUTE_UNUSED;
00412 sec_ptr sect ATTRIBUTE_UNUSED;
00413 {
00414
00415 }
00416
00417 static bfd_boolean
00418 aout_adobe_set_section_contents (abfd, section, location, offset, count)
00419 bfd *abfd;
00420 asection *section;
00421 const PTR location;
00422 file_ptr offset;
00423 bfd_size_type count;
00424 {
00425 file_ptr section_start;
00426 sec_ptr sect;
00427
00428
00429 if (! abfd->output_has_begun)
00430 {
00431
00432
00433 section_start = N_TXTOFF (ignore<-->me);
00434
00435 for (sect = abfd->sections; sect; sect = sect->next)
00436 {
00437 if (sect->flags & SEC_CODE)
00438 {
00439 sect->filepos = section_start;
00440
00441 section_start += sect->size;
00442 }
00443 }
00444
00445 for (sect = abfd->sections; sect; sect = sect->next)
00446 {
00447 if (sect->flags & SEC_DATA)
00448 {
00449 sect->filepos = section_start;
00450
00451 section_start += sect->size;
00452 }
00453 }
00454
00455 for (sect = abfd->sections; sect; sect = sect->next)
00456 {
00457 if (sect->flags & SEC_HAS_CONTENTS &&
00458 !(sect->flags & (SEC_CODE | SEC_DATA)))
00459 {
00460 sect->filepos = section_start;
00461
00462 section_start += sect->size;
00463 }
00464 }
00465 }
00466
00467
00468
00469 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
00470 return FALSE;
00471
00472 if (count == 0)
00473 return TRUE;
00474
00475 return bfd_bwrite ((PTR) location, count, abfd) == count;
00476 }
00477
00478 static bfd_boolean
00479 aout_adobe_set_arch_mach (abfd, arch, machine)
00480 bfd *abfd;
00481 enum bfd_architecture arch;
00482 unsigned long machine;
00483 {
00484 if (! bfd_default_set_arch_mach (abfd, arch, machine))
00485 return FALSE;
00486
00487 if (arch == bfd_arch_unknown
00488 || arch == bfd_arch_m68k)
00489 return TRUE;
00490
00491 return FALSE;
00492 }
00493
00494 static int
00495 aout_adobe_sizeof_headers (ignore_abfd, ignore)
00496 bfd *ignore_abfd ATTRIBUTE_UNUSED;
00497 bfd_boolean ignore ATTRIBUTE_UNUSED;
00498 {
00499 return sizeof (struct internal_exec);
00500 }
00501
00502
00503
00504 #define aout_32_close_and_cleanup aout_32_bfd_free_cached_info
00505
00506 #define aout_32_bfd_make_debug_symbol \
00507 ((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
00508
00509 #define aout_32_bfd_reloc_type_lookup \
00510 ((reloc_howto_type *(*) \
00511 PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
00512
00513 #define aout_32_set_arch_mach aout_adobe_set_arch_mach
00514 #define aout_32_set_section_contents aout_adobe_set_section_contents
00515
00516 #define aout_32_sizeof_headers aout_adobe_sizeof_headers
00517 #define aout_32_bfd_get_relocated_section_contents \
00518 bfd_generic_get_relocated_section_contents
00519 #define aout_32_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
00520 #define aout_32_bfd_relax_section bfd_generic_relax_section
00521 #define aout_32_bfd_gc_sections bfd_generic_gc_sections
00522 #define aout_32_bfd_merge_sections bfd_generic_merge_sections
00523 #define aout_32_bfd_is_group_section bfd_generic_is_group_section
00524 #define aout_32_bfd_discard_group bfd_generic_discard_group
00525 #define aout_32_section_already_linked \
00526 _bfd_generic_section_already_linked
00527 #define aout_32_bfd_link_hash_table_create \
00528 _bfd_generic_link_hash_table_create
00529 #define aout_32_bfd_link_hash_table_free \
00530 _bfd_generic_link_hash_table_free
00531 #define aout_32_bfd_link_add_symbols _bfd_generic_link_add_symbols
00532 #define aout_32_bfd_link_just_syms _bfd_generic_link_just_syms
00533 #define aout_32_bfd_final_link _bfd_generic_final_link
00534 #define aout_32_bfd_link_split_section _bfd_generic_link_split_section
00535
00536 const bfd_target a_out_adobe_vec =
00537 {
00538 "a.out.adobe",
00539 bfd_target_aout_flavour,
00540 BFD_ENDIAN_BIG,
00541 BFD_ENDIAN_BIG,
00542 (HAS_RELOC | EXEC_P |
00543 HAS_LINENO | HAS_DEBUG |
00544 HAS_SYMS | HAS_LOCALS | WP_TEXT ),
00545
00546 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_DATA | SEC_RELOC),
00547 '_',
00548 ' ',
00549 16,
00550
00551 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
00552 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
00553 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
00554 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
00555 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
00556 bfd_getb16, bfd_getb_signed_16, bfd_putb16,
00557 {_bfd_dummy_target, aout_adobe_object_p,
00558 bfd_generic_archive_p, _bfd_dummy_target},
00559 {bfd_false, aout_adobe_mkobject,
00560 _bfd_generic_mkarchive, bfd_false},
00561 {bfd_false, aout_adobe_write_object_contents,
00562 _bfd_write_archive_contents, bfd_false},
00563
00564 BFD_JUMP_TABLE_GENERIC (aout_32),
00565 BFD_JUMP_TABLE_COPY (_bfd_generic),
00566 BFD_JUMP_TABLE_CORE (_bfd_nocore),
00567 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd),
00568 BFD_JUMP_TABLE_SYMBOLS (aout_32),
00569 BFD_JUMP_TABLE_RELOCS (aout_32),
00570 BFD_JUMP_TABLE_WRITE (aout_32),
00571 BFD_JUMP_TABLE_LINK (aout_32),
00572 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
00573
00574 NULL,
00575
00576 (PTR) 0
00577 };