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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #define BYTES_IN_WORD 2
00038 #define BYTES_IN_LONG 4
00039 #define ARCH_SIZE 16
00040 #undef TARGET_IS_BIG_ENDIAN_P
00041
00042 #define TARGET_PAGE_SIZE 1024
00043 #define SEGMENT__SIZE TARGET_PAGE_SIZE
00044
00045 #define DEFAULT_ARCH bfd_arch_pdp11
00046 #define DEFAULT_MID M_PDP11
00047
00048
00049
00050
00051 #define MY(OP) CONCAT2 (pdp11_aout_,OP)
00052
00053
00054 #define TARGETNAME "a.out-pdp11"
00055
00056
00057 #define TEXT_START_ADDR 0
00058
00059
00060 #define N_HEADER_IN_TEXT(x) 0
00061
00062
00063 #define N_SHARED_LIB(x) 0
00064
00065
00066 #define N_FLAGS(exec) 0
00067
00068 #define N_SET_FLAGS(exec, flags) do { } while (0)
00069 #define N_BADMAG(x) (((x).a_info != OMAGIC) && \
00070 ((x).a_info != NMAGIC) && \
00071 ((x).a_info != A_MAGIC3) && \
00072 ((x).a_info != A_MAGIC4) && \
00073 ((x).a_info != A_MAGIC5) && \
00074 ((x).a_info != A_MAGIC6))
00075
00076 #include "bfd.h"
00077
00078 #define external_exec pdp11_external_exec
00079 struct pdp11_external_exec
00080 {
00081 bfd_byte e_info[2];
00082 bfd_byte e_text[2];
00083 bfd_byte e_data[2];
00084 bfd_byte e_bss[2];
00085 bfd_byte e_syms[2];
00086 bfd_byte e_entry[2];
00087 bfd_byte e_unused[2];
00088 bfd_byte e_flag[2];
00089 bfd_byte e_relocatable;
00090 };
00091
00092 #define EXEC_BYTES_SIZE (8 * 2)
00093
00094 #define A_MAGIC1 OMAGIC
00095 #define OMAGIC 0407
00096 #define A_MAGIC2 NMAGIC
00097 #define NMAGIC 0410
00098 #define ZMAGIC 0413
00099 #define A_MAGIC3 0411
00100 #define A_MAGIC4 0405
00101 #define A_MAGIC5 0430
00102 #define A_MAGIC6 0431
00103 #define QMAGIC 0
00104 #define BMAGIC 0
00105
00106 #define A_FLAG_RELOC_STRIPPED 0x0001
00107
00108 #define external_nlist pdp11_external_nlist
00109 struct pdp11_external_nlist
00110 {
00111 bfd_byte e_unused[2];
00112 bfd_byte e_strx[2];
00113 bfd_byte e_type[1];
00114 bfd_byte e_ovly[1];
00115 bfd_byte e_value[2];
00116 };
00117
00118 #define EXTERNAL_NLIST_SIZE 8
00119
00120 #define N_TXTOFF(x) (EXEC_BYTES_SIZE)
00121 #define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
00122 #define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
00123 #define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_trsize)
00124 #define N_SYMOFF(x) (N_DRELOFF(x) + (x).a_drsize)
00125 #define N_STROFF(x) (N_SYMOFF(x) + (x).a_syms)
00126
00127 #define WRITE_HEADERS(abfd, execp) pdp11_aout_write_headers (abfd, execp)
00128
00129 #include "sysdep.h"
00130 #include "libbfd.h"
00131 #include "libaout.h"
00132
00133 #define SWAP_MAGIC(ext) bfd_getl16 (ext)
00134
00135 #define MY_entry_is_text_address 1
00136
00137 #define MY_write_object_contents MY(write_object_contents)
00138 static bfd_boolean MY(write_object_contents) PARAMS ((bfd *abfd));
00139 #define MY_text_includes_header 1
00140
00141 static bfd_vma bfd_getp32 (const void *);
00142 static bfd_signed_vma bfd_getp_signed_32 (const void *);
00143 static void bfd_putp32 (bfd_vma, void *);
00144
00145 #define MY_BFD_TARGET
00146
00147 #include "aout-target.h"
00148
00149 const bfd_target MY(vec) =
00150 {
00151 TARGETNAME,
00152 bfd_target_aout_flavour,
00153 BFD_ENDIAN_LITTLE,
00154 BFD_ENDIAN_LITTLE,
00155 (HAS_RELOC | EXEC_P |
00156 HAS_LINENO | HAS_DEBUG |
00157 HAS_SYMS | HAS_LOCALS | WP_TEXT),
00158 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_CODE | SEC_DATA),
00159 MY_symbol_leading_char,
00160 AR_PAD_CHAR,
00161 15,
00162 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
00163 bfd_getp32, bfd_getp_signed_32, bfd_putp32,
00164 bfd_getl16, bfd_getl_signed_16, bfd_putl16,
00165 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
00166 bfd_getp32, bfd_getp_signed_32, bfd_putp32,
00167 bfd_getl16, bfd_getl_signed_16, bfd_putl16,
00168 {_bfd_dummy_target, MY_object_p,
00169 bfd_generic_archive_p, MY_core_file_p},
00170 {bfd_false, MY_mkobject,
00171 _bfd_generic_mkarchive, bfd_false},
00172 {bfd_false, MY_write_object_contents,
00173 _bfd_write_archive_contents, bfd_false},
00174
00175 BFD_JUMP_TABLE_GENERIC (MY),
00176 BFD_JUMP_TABLE_COPY (MY),
00177 BFD_JUMP_TABLE_CORE (MY),
00178 BFD_JUMP_TABLE_ARCHIVE (MY),
00179 BFD_JUMP_TABLE_SYMBOLS (MY),
00180 BFD_JUMP_TABLE_RELOCS (MY),
00181 BFD_JUMP_TABLE_WRITE (MY),
00182 BFD_JUMP_TABLE_LINK (MY),
00183 BFD_JUMP_TABLE_DYNAMIC (MY),
00184
00185
00186 NULL,
00187
00188 (PTR) MY_backend_data,
00189 };
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 #define KEEPIT udata.i
00313
00314 #include <string.h>
00315 #include "bfd.h"
00316 #include "sysdep.h"
00317 #include "safe-ctype.h"
00318 #include "bfdlink.h"
00319
00320 #include "libaout.h"
00321
00322 #include "aout/aout64.h"
00323 #include "aout/stab_gnu.h"
00324 #include "aout/ar.h"
00325
00326 #undef N_TYPE
00327 #undef N_UNDF
00328 #undef N_ABS
00329 #undef N_TEXT
00330 #undef N_DATA
00331 #undef N_BSS
00332 #undef N_REG
00333 #undef N_FN
00334 #undef N_EXT
00335 #define N_TYPE 0x1f
00336 #define N_UNDF 0x00
00337 #define N_ABS 0x01
00338 #define N_TEXT 0x02
00339 #define N_DATA 0x03
00340 #define N_BSS 0x04
00341 #define N_REG 0x14
00342 #define N_FN 0x1f
00343
00344 #define N_EXT 0x20
00345
00346 #define RELOC_SIZE 2
00347
00348 #define RELFLG 0x0001
00349 #define RTYPE 0x000e
00350 #define RIDXMASK 0xfff0
00351
00352 #define RABS 0x00
00353 #define RTEXT 0x02
00354 #define RDATA 0x04
00355 #define RBSS 0x06
00356 #define REXT 0x08
00357
00358 #define RINDEX(x) (((x) & 0xfff0) >> 4)
00359
00360 static bfd_boolean aout_get_external_symbols PARAMS ((bfd *));
00361 static bfd_boolean translate_from_native_sym_flags
00362 PARAMS ((bfd *, aout_symbol_type *));
00363 static bfd_boolean translate_to_native_sym_flags
00364 PARAMS ((bfd *, asymbol *, struct external_nlist *));
00365 static void adjust_o_magic PARAMS ((bfd *, struct internal_exec *));
00366 static void adjust_z_magic PARAMS ((bfd *, struct internal_exec *));
00367 static void adjust_n_magic PARAMS ((bfd *, struct internal_exec *));
00368
00369 static int pdp11_aout_write_headers PARAMS ((bfd *, struct internal_exec *));
00370 void pdp11_aout_swap_reloc_out PARAMS ((bfd *, arelent *, bfd_byte *));
00371 void pdp11_aout_swap_reloc_in
00372 PARAMS ((bfd *, bfd_byte *, arelent *,
00373 bfd_size_type, asymbol **, bfd_size_type));
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 #ifndef MY_final_link_relocate
00391 #define MY_final_link_relocate _bfd_final_link_relocate
00392 #endif
00393
00394 #ifndef MY_relocate_contents
00395 #define MY_relocate_contents _bfd_relocate_contents
00396 #endif
00397
00398 reloc_howto_type howto_table_pdp11[] =
00399 {
00400
00401 HOWTO( 0, 0, 1, 16, FALSE, 0, complain_overflow_signed,0,"16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
00402 HOWTO( 1, 0, 1, 16, TRUE, 0, complain_overflow_signed,0,"DISP16", TRUE, 0x0000ffff,0x0000ffff, FALSE),
00403 };
00404
00405 #define TABLE_SIZE(TABLE) (sizeof(TABLE)/sizeof(TABLE[0]))
00406
00407 reloc_howto_type *
00408 NAME(aout,reloc_type_lookup) (abfd,code)
00409 bfd * abfd ATTRIBUTE_UNUSED;
00410 bfd_reloc_code_real_type code;
00411 {
00412 switch (code)
00413 {
00414 case BFD_RELOC_16:
00415 return &howto_table_pdp11[0];
00416 case BFD_RELOC_16_PCREL:
00417 return &howto_table_pdp11[1];
00418 default:
00419 return (reloc_howto_type *)NULL;
00420 }
00421 }
00422
00423 static int
00424 pdp11_aout_write_headers (abfd, execp)
00425 bfd *abfd;
00426 struct internal_exec *execp;
00427 {
00428 struct external_exec exec_bytes;
00429 bfd_size_type text_size;
00430 file_ptr text_end;
00431
00432 if (adata(abfd).magic == undecided_magic)
00433 NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
00434
00435 execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_NLIST_SIZE;
00436 execp->a_entry = bfd_get_start_address (abfd);
00437
00438 if (obj_textsec (abfd)->reloc_count > 0 ||
00439 obj_datasec (abfd)->reloc_count > 0)
00440 {
00441 execp->a_trsize = execp->a_text;
00442 execp->a_drsize = execp->a_data;
00443 }
00444 else
00445 {
00446 execp->a_trsize = 0;
00447 execp->a_drsize = 0;
00448 }
00449
00450 NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes);
00451
00452 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
00453 return FALSE;
00454
00455 if (bfd_bwrite ((PTR) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, abfd)
00456 != EXEC_BYTES_SIZE)
00457 return FALSE;
00458
00459
00460
00461 if (bfd_get_outsymbols (abfd) != (asymbol **) NULL
00462 && bfd_get_symcount (abfd) != 0)
00463 {
00464 if (bfd_seek (abfd, (file_ptr) (N_SYMOFF(*execp)), SEEK_SET) != 0)
00465 return FALSE;
00466
00467 if (! NAME(aout,write_syms) (abfd))
00468 return FALSE;
00469 }
00470
00471 if (obj_textsec (abfd)->reloc_count > 0 ||
00472 obj_datasec (abfd)->reloc_count > 0)
00473 {
00474 if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) != 0)
00475 return FALSE;
00476 if (!NAME(aout,squirt_out_relocs) (abfd, obj_textsec (abfd)))
00477 return FALSE;
00478
00479 if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) != 0)
00480 return FALSE;
00481 if (!NAME(aout,squirt_out_relocs) (abfd, obj_datasec (abfd)))
00482 return FALSE;
00483 }
00484
00485 return TRUE;
00486 }
00487
00488
00489
00490
00491
00492 static bfd_boolean
00493 MY(write_object_contents) (abfd)
00494 bfd *abfd;
00495 {
00496 struct internal_exec *execp = exec_hdr (abfd);
00497
00498
00499
00500
00501 if (! abfd->output_has_begun)
00502 {
00503 bfd_size_type text_size;
00504 file_ptr text_end;
00505
00506 NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end);
00507 }
00508
00509 obj_reloc_entry_size (abfd) = RELOC_SIZE;
00510
00511 return WRITE_HEADERS(abfd, execp);
00512 }
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 #ifndef NAME_swap_exec_header_in
00542 void
00543 NAME(aout,swap_exec_header_in) (abfd, raw_bytes, execp)
00544 bfd *abfd;
00545 struct external_exec *raw_bytes;
00546 struct internal_exec *execp;
00547 {
00548 struct external_exec *bytes = (struct external_exec *)raw_bytes;
00549
00550
00551
00552
00553
00554 memset ((PTR) execp, 0, sizeof (struct internal_exec));
00555
00556 execp->a_info = GET_MAGIC (abfd, bytes->e_info);
00557 execp->a_text = GET_WORD (abfd, bytes->e_text);
00558 execp->a_data = GET_WORD (abfd, bytes->e_data);
00559 execp->a_bss = GET_WORD (abfd, bytes->e_bss);
00560 execp->a_syms = GET_WORD (abfd, bytes->e_syms);
00561 execp->a_entry = GET_WORD (abfd, bytes->e_entry);
00562
00563 if (GET_WORD (abfd, bytes->e_flag) & A_FLAG_RELOC_STRIPPED)
00564 {
00565 execp->a_trsize = 0;
00566 execp->a_drsize = 0;
00567 }
00568 else
00569 {
00570 execp->a_trsize = execp->a_text;
00571 execp->a_drsize = execp->a_data;
00572 }
00573 }
00574 #define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in)
00575 #endif
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 void
00592 NAME(aout,swap_exec_header_out) (abfd, execp, raw_bytes)
00593 bfd *abfd;
00594 struct internal_exec *execp;
00595 struct external_exec *raw_bytes;
00596 {
00597 struct external_exec *bytes = (struct external_exec *)raw_bytes;
00598
00599
00600 PUT_MAGIC (abfd, execp->a_info, bytes->e_info);
00601 PUT_WORD (abfd, execp->a_text, bytes->e_text);
00602 PUT_WORD (abfd, execp->a_data, bytes->e_data);
00603 PUT_WORD (abfd, execp->a_bss, bytes->e_bss);
00604 PUT_WORD (abfd, execp->a_syms, bytes->e_syms);
00605 PUT_WORD (abfd, execp->a_entry, bytes->e_entry);
00606 PUT_WORD (abfd, 0, bytes->e_unused);
00607
00608 if ((execp->a_trsize == 0 || execp->a_text == 0) &&
00609 (execp->a_drsize == 0 || execp->a_data == 0))
00610 PUT_WORD (abfd, A_FLAG_RELOC_STRIPPED, bytes->e_flag);
00611 else if (execp->a_trsize == execp->a_text &&
00612 execp->a_drsize == execp->a_data)
00613 PUT_WORD (abfd, 0, bytes->e_flag);
00614 else
00615 {
00616
00617 fprintf (stderr, "BFD:%s:%d: internal error\n", __FILE__, __LINE__);
00618 PUT_WORD (abfd, 0, bytes->e_flag);
00619 }
00620 }
00621
00622
00623
00624 bfd_boolean
00625 NAME(aout,make_sections) (abfd)
00626 bfd *abfd;
00627 {
00628 if (obj_textsec (abfd) == (asection *) NULL
00629 && bfd_make_section (abfd, ".text") == (asection *) NULL)
00630 return FALSE;
00631 if (obj_datasec (abfd) == (asection *) NULL
00632 && bfd_make_section (abfd, ".data") == (asection *) NULL)
00633 return FALSE;
00634 if (obj_bsssec (abfd) == (asection *) NULL
00635 && bfd_make_section (abfd, ".bss") == (asection *) NULL)
00636 return FALSE;
00637 return TRUE;
00638 }
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 const bfd_target *
00658 NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
00659 bfd *abfd;
00660 struct internal_exec *execp;
00661 const bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *));
00662 {
00663 struct aout_data_struct *rawptr, *oldrawptr;
00664 const bfd_target *result;
00665 bfd_size_type amt = sizeof (struct aout_data_struct);
00666
00667 rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
00668 if (rawptr == NULL)
00669 return 0;
00670
00671 oldrawptr = abfd->tdata.aout_data;
00672 abfd->tdata.aout_data = rawptr;
00673
00674
00675
00676
00677
00678 if (oldrawptr != NULL)
00679 *abfd->tdata.aout_data = *oldrawptr;
00680
00681 abfd->tdata.aout_data->a.hdr = &rawptr->e;
00682 *(abfd->tdata.aout_data->a.hdr) = *execp;
00683 execp = abfd->tdata.aout_data->a.hdr;
00684
00685
00686 abfd->flags = BFD_NO_FLAGS;
00687 if (execp->a_drsize || execp->a_trsize)
00688 abfd->flags |= HAS_RELOC;
00689
00690 if (execp->a_syms)
00691 abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
00692 if (N_DYNAMIC(*execp))
00693 abfd->flags |= DYNAMIC;
00694
00695 if (N_MAGIC (*execp) == ZMAGIC)
00696 {
00697 abfd->flags |= D_PAGED | WP_TEXT;
00698 adata (abfd).magic = z_magic;
00699 }
00700 else if (N_MAGIC (*execp) == QMAGIC)
00701 {
00702 abfd->flags |= D_PAGED | WP_TEXT;
00703 adata (abfd).magic = z_magic;
00704 adata (abfd).subformat = q_magic_format;
00705 }
00706 else if (N_MAGIC (*execp) == NMAGIC)
00707 {
00708 abfd->flags |= WP_TEXT;
00709 adata (abfd).magic = n_magic;
00710 }
00711 else if (N_MAGIC (*execp) == OMAGIC
00712 || N_MAGIC (*execp) == BMAGIC)
00713 adata (abfd).magic = o_magic;
00714 else
00715 {
00716
00717
00718 abort ();
00719 }
00720
00721 bfd_get_start_address (abfd) = execp->a_entry;
00722
00723 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
00724 bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
00725
00726
00727 obj_reloc_entry_size (abfd) = RELOC_SIZE;
00728
00729
00730 obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
00731
00732 #ifdef USE_MMAP
00733 bfd_init_window (&obj_aout_sym_window (abfd));
00734 bfd_init_window (&obj_aout_string_window (abfd));
00735 #endif
00736 obj_aout_external_syms (abfd) = NULL;
00737 obj_aout_external_strings (abfd) = NULL;
00738 obj_aout_sym_hashes (abfd) = NULL;
00739
00740 if (! NAME(aout,make_sections) (abfd))
00741 return NULL;
00742
00743 obj_datasec (abfd)->size = execp->a_data;
00744 obj_bsssec (abfd)->size = execp->a_bss;
00745
00746 obj_textsec (abfd)->flags =
00747 (execp->a_trsize != 0
00748 ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
00749 : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
00750 obj_datasec (abfd)->flags =
00751 (execp->a_drsize != 0
00752 ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
00753 : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
00754 obj_bsssec (abfd)->flags = SEC_ALLOC;
00755
00756 #ifdef THIS_IS_ONLY_DOCUMENTATION
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767 struct exec *execp = exec_hdr (abfd);
00768
00769 obj_textsec (abfd)->size = N_TXTSIZE(*execp);
00770
00771
00772
00773 obj_textsec (abfd)->vma = N_TXTADDR(*execp);
00774 obj_datasec (abfd)->vma = N_DATADDR(*execp);
00775 obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
00776
00777
00778 obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
00779 obj_datasec (abfd)->filepos = N_DATOFF(*execp);
00780
00781
00782 obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
00783 obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
00784
00785
00786 obj_str_filepos (abfd) = N_STROFF (*execp);
00787 obj_sym_filepos (abfd) = N_SYMOFF (*execp);
00788
00789
00790 abfd->obj_arch = bfd_arch_obscure;
00791
00792 adata(abfd)->page_size = TARGET_PAGE_SIZE;
00793 adata(abfd)->segment_size = SEGMENT_SIZE;
00794 adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
00795
00796 return abfd->xvec;
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806 #endif
00807
00808 result = (*callback_to_real_object_p)(abfd);
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825 if (execp->a_entry != 0
00826 || (execp->a_entry >= obj_textsec(abfd)->vma
00827 && execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->size))
00828 abfd->flags |= EXEC_P;
00829 #ifdef STAT_FOR_EXEC
00830 else
00831 {
00832 struct stat stat_buf;
00833
00834
00835
00836
00837
00838
00839
00840
00841 if (abfd->iostream != NULL
00842 && (abfd->flags & BFD_IN_MEMORY) == 0
00843 && (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
00844 && ((stat_buf.st_mode & 0111) != 0))
00845 abfd->flags |= EXEC_P;
00846 }
00847 #endif
00848
00849 if (!result)
00850 {
00851 free (rawptr);
00852 abfd->tdata.aout_data = oldrawptr;
00853 }
00854 return result;
00855 }
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868 bfd_boolean
00869 NAME(aout,mkobject) (abfd)
00870 bfd *abfd;
00871 {
00872 struct aout_data_struct *rawptr;
00873 bfd_size_type amt = sizeof (struct aout_data_struct);
00874
00875 bfd_set_error (bfd_error_system_call);
00876
00877
00878 rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
00879
00880 if (rawptr == NULL)
00881 return FALSE;
00882
00883 abfd->tdata.aout_data = rawptr;
00884 exec_hdr (abfd) = &(rawptr->e);
00885
00886 obj_textsec (abfd) = (asection *)NULL;
00887 obj_datasec (abfd) = (asection *)NULL;
00888 obj_bsssec (abfd) = (asection *)NULL;
00889
00890 return TRUE;
00891 }
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 enum machine_type
00914 NAME(aout,machine_type) (arch, machine, unknown)
00915 enum bfd_architecture arch;
00916 unsigned long machine;
00917 bfd_boolean *unknown;
00918 {
00919 enum machine_type arch_flags;
00920
00921 arch_flags = M_UNKNOWN;
00922 *unknown = TRUE;
00923
00924 switch (arch)
00925 {
00926 case bfd_arch_sparc:
00927 if (machine == 0
00928 || machine == bfd_mach_sparc
00929 || machine == bfd_mach_sparc_sparclite
00930 || machine == bfd_mach_sparc_v9)
00931 arch_flags = M_SPARC;
00932 else if (machine == bfd_mach_sparc_sparclet)
00933 arch_flags = M_SPARCLET;
00934 break;
00935
00936 case bfd_arch_m68k:
00937 switch (machine)
00938 {
00939 case 0: arch_flags = M_68010; break;
00940 case bfd_mach_m68000: arch_flags = M_UNKNOWN; *unknown = FALSE; break;
00941 case bfd_mach_m68010: arch_flags = M_68010; break;
00942 case bfd_mach_m68020: arch_flags = M_68020; break;
00943 default: arch_flags = M_UNKNOWN; break;
00944 }
00945 break;
00946
00947 case bfd_arch_i386:
00948 if (machine == 0
00949 || machine == bfd_mach_i386_i386
00950 || machine == bfd_mach_i386_i386_intel_syntax)
00951 arch_flags = M_386;
00952 break;
00953
00954 case bfd_arch_a29k:
00955 if (machine == 0) arch_flags = M_29K;
00956 break;
00957
00958 case bfd_arch_arm:
00959 if (machine == 0) arch_flags = M_ARM;
00960 break;
00961
00962 case bfd_arch_mips:
00963 switch (machine)
00964 {
00965 case 0:
00966 case 2000:
00967 case bfd_mach_mips3000:
00968 arch_flags = M_MIPS1;
00969 break;
00970 case bfd_mach_mips4000:
00971 case bfd_mach_mips4400:
00972 case bfd_mach_mips8000:
00973 case bfd_mach_mips6000:
00974 arch_flags = M_MIPS2;
00975 break;
00976 default:
00977 arch_flags = M_UNKNOWN;
00978 break;
00979 }
00980 break;
00981
00982 case bfd_arch_ns32k:
00983 switch (machine)
00984 {
00985 case 0: arch_flags = M_NS32532; break;
00986 case 32032: arch_flags = M_NS32032; break;
00987 case 32532: arch_flags = M_NS32532; break;
00988 default: arch_flags = M_UNKNOWN; break;
00989 }
00990 break;
00991
00992 case bfd_arch_pdp11:
00993
00994 *unknown = FALSE;
00995 break;
00996
00997 case bfd_arch_vax:
00998 *unknown = FALSE;
00999 break;
01000
01001 default:
01002 arch_flags = M_UNKNOWN;
01003 }
01004
01005 if (arch_flags != M_UNKNOWN)
01006 *unknown = FALSE;
01007
01008 return arch_flags;
01009 }
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028 bfd_boolean
01029 NAME(aout,set_arch_mach) (abfd, arch, machine)
01030 bfd *abfd;
01031 enum bfd_architecture arch;
01032 unsigned long machine;
01033 {
01034 if (! bfd_default_set_arch_mach (abfd, arch, machine))
01035 return FALSE;
01036
01037 if (arch != bfd_arch_unknown)
01038 {
01039 bfd_boolean unknown;
01040
01041 NAME(aout,machine_type) (arch, machine, &unknown);
01042 if (unknown)
01043 return FALSE;
01044 }
01045
01046 obj_reloc_entry_size (abfd) = RELOC_SIZE;
01047
01048 return (*aout_backend_info(abfd)->set_sizes) (abfd);
01049 }
01050
01051 static void
01052 adjust_o_magic (abfd, execp)
01053 bfd *abfd;
01054 struct internal_exec *execp;
01055 {
01056 file_ptr pos = adata (abfd).exec_bytes_size;
01057 bfd_vma vma = 0;
01058 int pad = 0;
01059
01060
01061 obj_textsec (abfd)->filepos = pos;
01062 if (! obj_textsec (abfd)->user_set_vma)
01063 obj_textsec (abfd)->vma = vma;
01064 else
01065 vma = obj_textsec (abfd)->vma;
01066
01067 pos += obj_textsec (abfd)->size;
01068 vma += obj_textsec (abfd)->size;
01069
01070
01071 if (!obj_datasec (abfd)->user_set_vma)
01072 {
01073 obj_textsec (abfd)->size += pad;
01074 pos += pad;
01075 vma += pad;
01076 obj_datasec (abfd)->vma = vma;
01077 }
01078 else
01079 vma = obj_datasec (abfd)->vma;
01080 obj_datasec (abfd)->filepos = pos;
01081 pos += obj_datasec (abfd)->size;
01082 vma += obj_datasec (abfd)->size;
01083
01084
01085 if (! obj_bsssec (abfd)->user_set_vma)
01086 {
01087 obj_datasec (abfd)->size += pad;
01088 pos += pad;
01089 vma += pad;
01090 obj_bsssec (abfd)->vma = vma;
01091 }
01092 else
01093 {
01094
01095
01096
01097 pad = obj_bsssec (abfd)->vma - vma;
01098 if (pad > 0)
01099 {
01100 obj_datasec (abfd)->size += pad;
01101 pos += pad;
01102 }
01103 }
01104 obj_bsssec (abfd)->filepos = pos;
01105
01106
01107 execp->a_text = obj_textsec (abfd)->size;
01108 execp->a_data = obj_datasec (abfd)->size;
01109 execp->a_bss = obj_bsssec (abfd)->size;
01110 N_SET_MAGIC (*execp, OMAGIC);
01111 }
01112
01113 static void
01114 adjust_z_magic (abfd, execp)
01115 bfd *abfd;
01116 struct internal_exec *execp;
01117 {
01118 bfd_size_type data_pad, text_pad;
01119 file_ptr text_end;
01120 const struct aout_backend_data *abdp;
01121 int ztih;
01122
01123 abdp = aout_backend_info (abfd);
01124
01125
01126 ztih = (abdp != NULL
01127 && (abdp->text_includes_header
01128 || obj_aout_subformat (abfd) == q_magic_format));
01129 obj_textsec(abfd)->filepos = (ztih
01130 ? adata(abfd).exec_bytes_size
01131 : adata(abfd).zmagic_disk_block_size);
01132 if (! obj_textsec(abfd)->user_set_vma)
01133 {
01134
01135 obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC)
01136 ? 0
01137 : (ztih
01138 ? (abdp->default_text_vma
01139 + adata (abfd).exec_bytes_size)
01140 : abdp->default_text_vma));
01141 text_pad = 0;
01142 }
01143 else
01144 {
01145
01146
01147
01148 if (ztih)
01149 text_pad = ((obj_textsec (abfd)->filepos - obj_textsec (abfd)->vma)
01150 & (adata (abfd).page_size - 1));
01151 else
01152 text_pad = ((- obj_textsec (abfd)->vma)
01153 & (adata (abfd).page_size - 1));
01154 }
01155
01156
01157 if (ztih)
01158 {
01159 text_end = obj_textsec (abfd)->filepos + obj_textsec (abfd)->size;
01160 text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
01161 }
01162 else
01163 {
01164
01165
01166
01167 text_end = obj_textsec (abfd)->size;
01168 text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
01169 text_end += obj_textsec (abfd)->filepos;
01170 }
01171
01172 obj_textsec (abfd)->size += text_pad;
01173 text_end += text_pad;
01174
01175
01176 if (!obj_datasec(abfd)->user_set_vma)
01177 {
01178 bfd_vma vma;
01179 vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->size;
01180 obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
01181 }
01182 if (abdp && abdp->zmagic_mapped_contiguous)
01183 {
01184 text_pad = (obj_datasec(abfd)->vma
01185 - obj_textsec(abfd)->vma
01186 - obj_textsec(abfd)->size);
01187 obj_textsec(abfd)->size += text_pad;
01188 }
01189 obj_datasec (abfd)->filepos = (obj_textsec (abfd)->filepos
01190 + obj_textsec (abfd)->size);
01191
01192
01193 execp->a_text = obj_textsec(abfd)->size;
01194 if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
01195 execp->a_text += adata(abfd).exec_bytes_size;
01196 if (obj_aout_subformat (abfd) == q_magic_format)
01197 N_SET_MAGIC (*execp, QMAGIC);
01198 else
01199 N_SET_MAGIC (*execp, ZMAGIC);
01200
01201
01202 obj_datasec(abfd)->size
01203 = align_power (obj_datasec(abfd)->size,
01204 obj_bsssec(abfd)->alignment_power);
01205 execp->a_data = BFD_ALIGN (obj_datasec(abfd)->size,
01206 adata(abfd).page_size);
01207 data_pad = execp->a_data - obj_datasec(abfd)->size;
01208
01209
01210 if (!obj_bsssec(abfd)->user_set_vma)
01211 obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
01212 + obj_datasec(abfd)->size);
01213
01214
01215
01216
01217
01218
01219
01220 if (align_power (obj_bsssec(abfd)->vma, obj_bsssec(abfd)->alignment_power)
01221 == obj_datasec(abfd)->vma + obj_datasec(abfd)->size)
01222 execp->a_bss = (data_pad > obj_bsssec(abfd)->size) ? 0 :
01223 obj_bsssec(abfd)->size - data_pad;
01224 else
01225 execp->a_bss = obj_bsssec(abfd)->size;
01226 }
01227
01228 static void
01229 adjust_n_magic (abfd, execp)
01230 bfd *abfd;
01231 struct internal_exec *execp;
01232 {
01233 file_ptr pos = adata(abfd).exec_bytes_size;
01234 bfd_vma vma = 0;
01235 int pad;
01236
01237
01238 obj_textsec(abfd)->filepos = pos;
01239 if (!obj_textsec(abfd)->user_set_vma)
01240 obj_textsec(abfd)->vma = vma;
01241 else
01242 vma = obj_textsec(abfd)->vma;
01243 pos += obj_textsec(abfd)->size;
01244 vma += obj_textsec(abfd)->size;
01245
01246
01247 obj_datasec(abfd)->filepos = pos;
01248 if (!obj_datasec(abfd)->user_set_vma)
01249 obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
01250 vma = obj_datasec(abfd)->vma;
01251
01252
01253 vma += obj_datasec(abfd)->size;
01254 pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
01255 obj_datasec(abfd)->size += pad;
01256 pos += obj_datasec(abfd)->size;
01257
01258
01259 if (!obj_bsssec(abfd)->user_set_vma)
01260 obj_bsssec(abfd)->vma = vma;
01261 else
01262 vma = obj_bsssec(abfd)->vma;
01263
01264
01265 execp->a_text = obj_textsec(abfd)->size;
01266 execp->a_data = obj_datasec(abfd)->size;
01267 execp->a_bss = obj_bsssec(abfd)->size;
01268 N_SET_MAGIC (*execp, NMAGIC);
01269 }
01270
01271 bfd_boolean
01272 NAME(aout,adjust_sizes_and_vmas) (abfd, text_size, text_end)
01273 bfd *abfd;
01274 bfd_size_type *text_size;
01275 file_ptr * text_end ATTRIBUTE_UNUSED;
01276 {
01277 struct internal_exec *execp = exec_hdr (abfd);
01278
01279 if (! NAME(aout,make_sections) (abfd))
01280 return FALSE;
01281
01282 if (adata(abfd).magic != undecided_magic)
01283 return TRUE;
01284
01285 obj_textsec(abfd)->size =
01286 align_power(obj_textsec(abfd)->size,
01287 obj_textsec(abfd)->alignment_power);
01288
01289 *text_size = obj_textsec (abfd)->size;
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306 if (abfd->flags & WP_TEXT)
01307 adata(abfd).magic = n_magic;
01308 else
01309 adata(abfd).magic = o_magic;
01310
01311 #ifdef BFD_AOUT_DEBUG
01312 #if __GNUC__ >= 2
01313 fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
01314 ({ char *str;
01315 switch (adata(abfd).magic) {
01316 case n_magic: str = "NMAGIC"; break;
01317 case o_magic: str = "OMAGIC"; break;
01318 case z_magic: str = "ZMAGIC"; break;
01319 default: abort ();
01320 }
01321 str;
01322 }),
01323 obj_textsec(abfd)->vma, obj_textsec(abfd)->size,
01324 obj_textsec(abfd)->alignment_power,
01325 obj_datasec(abfd)->vma, obj_datasec(abfd)->size,
01326 obj_datasec(abfd)->alignment_power,
01327 obj_bsssec(abfd)->vma, obj_bsssec(abfd)->size,
01328 obj_bsssec(abfd)->alignment_power);
01329 #endif
01330 #endif
01331
01332 switch (adata(abfd).magic)
01333 {
01334 case o_magic:
01335 adjust_o_magic (abfd, execp);
01336 break;
01337 case z_magic:
01338 adjust_z_magic (abfd, execp);
01339 break;
01340 case n_magic:
01341 adjust_n_magic (abfd, execp);
01342 break;
01343 default:
01344 abort ();
01345 }
01346
01347 #ifdef BFD_AOUT_DEBUG
01348 fprintf (stderr, " text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
01349 obj_textsec(abfd)->vma, obj_textsec(abfd)->size,
01350 obj_textsec(abfd)->filepos,
01351 obj_datasec(abfd)->vma, obj_datasec(abfd)->size,
01352 obj_datasec(abfd)->filepos,
01353 obj_bsssec(abfd)->vma, obj_bsssec(abfd)->size);
01354 #endif
01355
01356 return TRUE;
01357 }
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372 bfd_boolean
01373 NAME(aout,new_section_hook) (abfd, newsect)
01374 bfd *abfd;
01375 asection *newsect;
01376 {
01377
01378 newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
01379
01380
01381 if (bfd_get_format (abfd) == bfd_object)
01382 {
01383 if (obj_textsec (abfd) == NULL
01384 && ! strcmp (newsect->name, ".text"))
01385 {
01386 obj_textsec(abfd)= newsect;
01387 newsect->target_index = N_TEXT;
01388 return TRUE;
01389 }
01390
01391 if (obj_datasec (abfd) == NULL
01392 && ! strcmp (newsect->name, ".data"))
01393 {
01394 obj_datasec (abfd) = newsect;
01395 newsect->target_index = N_DATA;
01396 return TRUE;
01397 }
01398
01399 if (obj_bsssec (abfd) == NULL
01400 && !strcmp (newsect->name, ".bss"))
01401 {
01402 obj_bsssec (abfd) = newsect;
01403 newsect->target_index = N_BSS;
01404 return TRUE;
01405 }
01406 }
01407
01408
01409 return TRUE;
01410 }
01411
01412 bfd_boolean
01413 NAME(aout,set_section_contents) (abfd, section, location, offset, count)
01414 bfd *abfd;
01415 sec_ptr section;
01416 const PTR location;
01417 file_ptr offset;
01418 bfd_size_type count;
01419 {
01420 file_ptr text_end;
01421 bfd_size_type text_size;
01422
01423 if (! abfd->output_has_begun)
01424 {
01425 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
01426 return FALSE;
01427 }
01428
01429 if (section == obj_bsssec (abfd))
01430 {
01431 bfd_set_error (bfd_error_no_contents);
01432 return FALSE;
01433 }
01434
01435 if (section != obj_textsec (abfd)
01436 && section != obj_datasec (abfd))
01437 {
01438 (*_bfd_error_handler)
01439 ("%s: can not represent section `%s' in a.out object file format",
01440 bfd_get_filename (abfd), bfd_get_section_name (abfd, section));
01441 bfd_set_error (bfd_error_nonrepresentable_section);
01442 return FALSE;
01443 }
01444
01445 if (count != 0)
01446 {
01447 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
01448 || bfd_bwrite (location, count, abfd) != count)
01449 return FALSE;
01450 }
01451
01452 return TRUE;
01453 }
01454
01455
01456
01457 static bfd_boolean
01458 aout_get_external_symbols (abfd)
01459 bfd *abfd;
01460 {
01461 if (obj_aout_external_syms (abfd) == (struct external_nlist *) NULL)
01462 {
01463 bfd_size_type count;
01464 struct external_nlist *syms;
01465
01466 count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
01467
01468 #ifdef USE_MMAP
01469 if (! bfd_get_file_window (abfd, obj_sym_filepos (abfd),
01470 exec_hdr (abfd)->a_syms,
01471 &obj_aout_sym_window (abfd), TRUE))
01472 return FALSE;
01473 syms = (struct external_nlist *) obj_aout_sym_window (abfd).data;
01474 #else
01475
01476
01477
01478 syms = (struct external_nlist *) bfd_malloc (count * EXTERNAL_NLIST_SIZE);
01479 if (syms == (struct external_nlist *) NULL && count != 0)
01480 return FALSE;
01481
01482 if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
01483 || (bfd_bread (syms, exec_hdr (abfd)->a_syms, abfd)
01484 != exec_hdr (abfd)->a_syms))
01485 {
01486 free (syms);
01487 return FALSE;
01488 }
01489 #endif
01490
01491 obj_aout_external_syms (abfd) = syms;
01492 obj_aout_external_sym_count (abfd) = count;
01493 }
01494
01495 if (obj_aout_external_strings (abfd) == NULL
01496 && exec_hdr (abfd)->a_syms != 0)
01497 {
01498 unsigned char string_chars[BYTES_IN_LONG];
01499 bfd_size_type stringsize;
01500 char *strings;
01501
01502
01503 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
01504 || (bfd_bread ((PTR) string_chars, (bfd_size_type) BYTES_IN_LONG,
01505 abfd) != BYTES_IN_LONG))
01506 return FALSE;
01507 stringsize = H_GET_32 (abfd, string_chars);
01508
01509 #ifdef USE_MMAP
01510 if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize,
01511 &obj_aout_string_window (abfd), TRUE))
01512 return FALSE;
01513 strings = (char *) obj_aout_string_window (abfd).data;
01514 #else
01515 strings = (char *) bfd_malloc (stringsize + 1);
01516 if (strings == NULL)
01517 return FALSE;
01518
01519
01520
01521 if (bfd_bread (strings + 4, stringsize - 4, abfd) != stringsize - 4)
01522 {
01523 free (strings);
01524 return FALSE;
01525 }
01526 #endif
01527
01528
01529 strings[0] = '\0';
01530
01531 strings[stringsize - 1] = 0;
01532
01533 obj_aout_external_strings (abfd) = strings;
01534 obj_aout_external_string_size (abfd) = stringsize;
01535 }
01536
01537 return TRUE;
01538 }
01539
01540
01541
01542
01543
01544
01545 static bfd_boolean
01546 translate_from_native_sym_flags (abfd, cache_ptr)
01547 bfd *abfd;
01548 aout_symbol_type *cache_ptr;
01549 {
01550 flagword visible;
01551
01552 if (cache_ptr->type == N_FN)
01553 {
01554 asection *sec;
01555
01556
01557
01558 cache_ptr->symbol.flags = BSF_DEBUGGING;
01559
01560
01561 switch (cache_ptr->type & N_TYPE)
01562 {
01563 case N_TEXT:
01564 case N_FN:
01565 sec = obj_textsec (abfd);
01566 break;
01567 case N_DATA:
01568 sec = obj_datasec (abfd);
01569 break;
01570 case N_BSS:
01571 sec = obj_bsssec (abfd);
01572 break;
01573 default:
01574 case N_ABS:
01575 sec = bfd_abs_section_ptr;
01576 break;
01577 }
01578
01579 cache_ptr->symbol.section = sec;
01580 cache_ptr->symbol.value -= sec->vma;
01581
01582 return TRUE;
01583 }
01584
01585
01586
01587 if ((cache_ptr->type & N_EXT) == 0)
01588 visible = BSF_LOCAL;
01589 else
01590 visible = BSF_GLOBAL;
01591
01592 switch (cache_ptr->type)
01593 {
01594 default:
01595 case N_ABS: case N_ABS | N_EXT:
01596 cache_ptr->symbol.section = bfd_abs_section_ptr;
01597 cache_ptr->symbol.flags = visible;
01598 break;
01599
01600 case N_UNDF | N_EXT:
01601 if (cache_ptr->symbol.value != 0)
01602 {
01603
01604 cache_ptr->symbol.flags = BSF_GLOBAL;
01605 cache_ptr->symbol.section = bfd_com_section_ptr;
01606 }
01607 else
01608 {
01609 cache_ptr->symbol.flags = 0;
01610 cache_ptr->symbol.section = bfd_und_section_ptr;
01611 }
01612 break;
01613
01614 case N_TEXT: case N_TEXT | N_EXT:
01615 cache_ptr->symbol.section = obj_textsec (abfd);
01616 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
01617 cache_ptr->symbol.flags = visible;
01618 break;
01619
01620 case N_DATA: case N_DATA | N_EXT:
01621 cache_ptr->symbol.section = obj_datasec (abfd);
01622 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
01623 cache_ptr->symbol.flags = visible;
01624 break;
01625
01626 case N_BSS: case N_BSS | N_EXT:
01627 cache_ptr->symbol.section = obj_bsssec (abfd);
01628 cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
01629 cache_ptr->symbol.flags = visible;
01630 break;
01631 }
01632
01633 return TRUE;
01634 }
01635
01636
01637
01638 static bfd_boolean
01639 translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
01640 bfd *abfd;
01641 asymbol *cache_ptr;
01642 struct external_nlist *sym_pointer;
01643 {
01644 bfd_vma value = cache_ptr->value;
01645 asection *sec;
01646 bfd_vma off;
01647
01648
01649
01650 sym_pointer->e_type[0] &= ~N_TYPE;
01651
01652 sec = bfd_get_section (cache_ptr);
01653 off = 0;
01654
01655 if (sec == NULL)
01656 {
01657
01658
01659 (*_bfd_error_handler)
01660 ("%B: can not represent section for symbol `%s' in a.out object file format",
01661 abfd, cache_ptr->name != NULL ? cache_ptr->name : "*unknown*");
01662 bfd_set_error (bfd_error_nonrepresentable_section);
01663 return FALSE;
01664 }
01665
01666 if (sec->output_section != NULL)
01667 {
01668 off = sec->output_offset;
01669 sec = sec->output_section;
01670 }
01671
01672 if (bfd_is_abs_section (sec))
01673 sym_pointer->e_type[0] |= N_ABS;
01674 else if (sec == obj_textsec (abfd))
01675 sym_pointer->e_type[0] |= N_TEXT;
01676 else if (sec == obj_datasec (abfd))
01677 sym_pointer->e_type[0] |= N_DATA;
01678 else if (sec == obj_bsssec (abfd))
01679 sym_pointer->e_type[0] |= N_BSS;
01680 else if (bfd_is_und_section (sec))
01681 sym_pointer->e_type[0] = N_UNDF | N_EXT;
01682 else if (bfd_is_com_section (sec))
01683 sym_pointer->e_type[0] = N_UNDF | N_EXT;
01684 else
01685 {
01686 (*_bfd_error_handler)
01687 ("%B: can not represent section `%A' in a.out object file format",
01688 abfd, sec);
01689 bfd_set_error (bfd_error_nonrepresentable_section);
01690 return FALSE;
01691 }
01692
01693
01694 value += sec->vma + off;
01695
01696 if ((cache_ptr->flags & BSF_DEBUGGING) != 0)
01697 sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
01698 else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
01699 sym_pointer->e_type[0] |= N_EXT;
01700
01701 PUT_WORD(abfd, value, sym_pointer->e_value);
01702
01703 return TRUE;
01704 }
01705
01706
01707
01708 asymbol *
01709 NAME(aout,make_empty_symbol) (abfd)
01710 bfd *abfd;
01711 {
01712 bfd_size_type amt = sizeof (aout_symbol_type);
01713 aout_symbol_type *new = (aout_symbol_type *) bfd_zalloc (abfd, amt);
01714 if (!new)
01715 return NULL;
01716 new->symbol.the_bfd = abfd;
01717
01718 return &new->symbol;
01719 }
01720
01721
01722
01723 bfd_boolean
01724 NAME(aout,translate_symbol_table) (abfd, in, ext, count, str, strsize, dynamic)
01725 bfd *abfd;
01726 aout_symbol_type *in;
01727 struct external_nlist *ext;
01728 bfd_size_type count;
01729 char *str;
01730 bfd_size_type strsize;
01731 bfd_boolean dynamic;
01732 {
01733 struct external_nlist *ext_end;
01734
01735 ext_end = ext + count;
01736 for (; ext < ext_end; ext++, in++)
01737 {
01738 bfd_vma x;
01739
01740 x = GET_WORD (abfd, ext->e_strx);
01741 in->symbol.the_bfd = abfd;
01742
01743
01744
01745
01746
01747
01748 if (x == 0 && ! dynamic)
01749 in->symbol.name = "";
01750 else if (x < strsize)
01751 in->symbol.name = str + x;
01752 else
01753 return FALSE;
01754
01755 in->symbol.value = GET_SWORD (abfd, ext->e_value);
01756
01757 in->desc = 0;
01758 in->other = 0;
01759 in->type = H_GET_8 (abfd, ext->e_type);
01760 in->symbol.udata.p = NULL;
01761
01762 if (! translate_from_native_sym_flags (abfd, in))
01763 return FALSE;
01764
01765 if (dynamic)
01766 in->symbol.flags |= BSF_DYNAMIC;
01767 }
01768
01769 return TRUE;
01770 }
01771
01772
01773
01774
01775
01776 bfd_boolean
01777 NAME(aout,slurp_symbol_table) (abfd)
01778 bfd *abfd;
01779 {
01780 struct external_nlist *old_external_syms;
01781 aout_symbol_type *cached;
01782 bfd_size_type cached_size;
01783
01784
01785 if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
01786 return TRUE;
01787
01788 old_external_syms = obj_aout_external_syms (abfd);
01789
01790 if (! aout_get_external_symbols (abfd))
01791 return FALSE;
01792
01793 cached_size = obj_aout_external_sym_count (abfd);
01794 cached_size *= sizeof (aout_symbol_type);
01795 cached = (aout_symbol_type *) bfd_zmalloc (cached_size);
01796 if (cached == NULL && cached_size != 0)
01797 return FALSE;
01798
01799
01800 if (! (NAME(aout,translate_symbol_table)
01801 (abfd, cached,
01802 obj_aout_external_syms (abfd),
01803 obj_aout_external_sym_count (abfd),
01804 obj_aout_external_strings (abfd),
01805 obj_aout_external_string_size (abfd),
01806 FALSE)))
01807 {
01808 free (cached);
01809 return FALSE;
01810 }
01811
01812 bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd);
01813
01814 obj_aout_symbols (abfd) = cached;
01815
01816
01817
01818
01819
01820 if (old_external_syms == (struct external_nlist *) NULL
01821 && obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
01822 {
01823 #ifdef USE_MMAP
01824 bfd_free_window (&obj_aout_sym_window (abfd));
01825 #else
01826 free (obj_aout_external_syms (abfd));
01827 #endif
01828 obj_aout_external_syms (abfd) = NULL;
01829 }
01830
01831 return TRUE;
01832 }
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843 static bfd_size_type add_to_stringtab
01844 PARAMS ((bfd *, struct bfd_strtab_hash *, const char *, bfd_boolean));
01845 static bfd_boolean emit_stringtab PARAMS ((bfd *, struct bfd_strtab_hash *));
01846
01847
01848
01849
01850 static INLINE bfd_size_type
01851 add_to_stringtab (abfd, tab, str, copy)
01852 bfd *abfd;
01853 struct bfd_strtab_hash *tab;
01854 const char *str;
01855 bfd_boolean copy;
01856 {
01857 bfd_boolean hash;
01858 bfd_size_type index;
01859
01860
01861 if (str == 0 || *str == '\0')
01862 return 0;
01863
01864
01865
01866 hash = TRUE;
01867 if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
01868 hash = FALSE;
01869
01870 index = _bfd_stringtab_add (tab, str, hash, copy);
01871
01872 if (index != (bfd_size_type) -1)
01873 {
01874
01875
01876 index += BYTES_IN_LONG;
01877 }
01878
01879 return index;
01880 }
01881
01882
01883
01884
01885 static bfd_boolean
01886 emit_stringtab (abfd, tab)
01887 register bfd *abfd;
01888 struct bfd_strtab_hash *tab;
01889 {
01890 bfd_byte buffer[BYTES_IN_LONG];
01891
01892
01893 H_PUT_32 (abfd, _bfd_stringtab_size (tab) + BYTES_IN_LONG, buffer);
01894 if (bfd_bwrite ((PTR) buffer, (bfd_size_type) BYTES_IN_LONG, abfd)
01895 != BYTES_IN_LONG)
01896 return FALSE;
01897
01898 return _bfd_stringtab_emit (abfd, tab);
01899 }
01900
01901 bfd_boolean
01902 NAME(aout,write_syms) (abfd)
01903 bfd *abfd;
01904 {
01905 unsigned int count ;
01906 asymbol **generic = bfd_get_outsymbols (abfd);
01907 struct bfd_strtab_hash *strtab;
01908
01909 strtab = _bfd_stringtab_init ();
01910 if (strtab == NULL)
01911 return FALSE;
01912
01913 for (count = 0; count < bfd_get_symcount (abfd); count++)
01914 {
01915 asymbol *g = generic[count];
01916 bfd_size_type indx;
01917 struct external_nlist nsp;
01918
01919 PUT_WORD (abfd, 0, nsp.e_unused);
01920
01921 indx = add_to_stringtab (abfd, strtab, g->name, FALSE);
01922 if (indx == (bfd_size_type) -1)
01923 goto error_return;
01924 PUT_WORD (abfd, indx, nsp.e_strx);
01925
01926 if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
01927 H_PUT_8 (abfd, aout_symbol(g)->type, nsp.e_type);
01928 else
01929 H_PUT_8 (abfd, 0, nsp.e_type);
01930
01931 if (! translate_to_native_sym_flags (abfd, g, &nsp))
01932 goto error_return;
01933
01934 H_PUT_8 (abfd, 0, nsp.e_ovly);
01935
01936 if (bfd_bwrite ((PTR)&nsp, (bfd_size_type) EXTERNAL_NLIST_SIZE, abfd)
01937 != EXTERNAL_NLIST_SIZE)
01938 goto error_return;
01939
01940
01941
01942 g->KEEPIT = count;
01943 }
01944
01945 if (! emit_stringtab (abfd, strtab))
01946 goto error_return;
01947
01948 _bfd_stringtab_free (strtab);
01949
01950 return TRUE;
01951
01952 error_return:
01953 _bfd_stringtab_free (strtab);
01954 return FALSE;
01955 }
01956
01957
01958 long
01959 NAME(aout,canonicalize_symtab) (abfd, location)
01960 bfd *abfd;
01961 asymbol **location;
01962 {
01963 unsigned int counter = 0;
01964 aout_symbol_type *symbase;
01965
01966 if (!NAME(aout,slurp_symbol_table)(abfd))
01967 return -1;
01968
01969 for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
01970 *(location++) = (asymbol *)( symbase++);
01971 *location++ =0;
01972 return bfd_get_symcount (abfd);
01973 }
01974
01975
01976
01977
01978
01979
01980
01981 void
01982 pdp11_aout_swap_reloc_out (abfd, g, natptr)
01983 bfd *abfd;
01984 arelent *g;
01985 bfd_byte *natptr;
01986 {
01987 int r_index;
01988 int r_pcrel;
01989 int reloc_entry;
01990 int r_type;
01991 asymbol *sym = *(g->sym_ptr_ptr);
01992 asection *output_section = sym->section->output_section;
01993
01994 if (g->addend != 0)
01995 fprintf (stderr, "BFD: can't do this reloc addend stuff\n");
01996
01997 r_pcrel = g->howto->pc_relative;
01998
01999 if (bfd_is_abs_section (output_section))
02000 r_type = RABS;
02001 else if (output_section == obj_textsec (abfd))
02002 r_type = RTEXT;
02003 else if (output_section == obj_datasec (abfd))
02004 r_type = RDATA;
02005 else if (output_section == obj_bsssec (abfd))
02006 r_type = RBSS;
02007 else if (bfd_is_und_section (output_section))
02008 r_type = REXT;
02009 else if (bfd_is_com_section (output_section))
02010 r_type = REXT;
02011 else
02012 r_type = -1;
02013
02014 BFD_ASSERT (r_type != -1);
02015
02016 if (r_type == RABS)
02017 r_index = 0;
02018 else
02019 r_index = (*(g->sym_ptr_ptr))->KEEPIT;
02020
02021 reloc_entry = r_index << 4 | r_type | r_pcrel;
02022
02023 PUT_WORD (abfd, reloc_entry, natptr);
02024 }
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035 #define MOVE_ADDRESS(ad) \
02036 if (r_extern) \
02037 { \
02038 \
02039 cache_ptr->sym_ptr_ptr = symbols + r_index; \
02040 cache_ptr->addend = ad; \
02041 } \
02042 else \
02043 { \
02044
02045 \
02046 switch (r_index) \
02047 { \
02048 case N_TEXT: \
02049 case N_TEXT | N_EXT: \
02050 cache_ptr->sym_ptr_ptr = obj_textsec (abfd)->symbol_ptr_ptr; \
02051 cache_ptr->addend = ad - su->textsec->vma; \
02052 break; \
02053 case N_DATA: \
02054 case N_DATA | N_EXT: \
02055 cache_ptr->sym_ptr_ptr = obj_datasec (abfd)->symbol_ptr_ptr; \
02056 cache_ptr->addend = ad - su->datasec->vma; \
02057 break; \
02058 case N_BSS: \
02059 case N_BSS | N_EXT: \
02060 cache_ptr->sym_ptr_ptr = obj_bsssec (abfd)->symbol_ptr_ptr; \
02061 cache_ptr->addend = ad - su->bsssec->vma; \
02062 break; \
02063 default: \
02064 case N_ABS: \
02065 case N_ABS | N_EXT: \
02066 cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; \
02067 cache_ptr->addend = ad; \
02068 break; \
02069 } \
02070 }
02071
02072 void
02073 pdp11_aout_swap_reloc_in (abfd, bytes, cache_ptr, offset,
02074 symbols, symcount)
02075 bfd *abfd;
02076 bfd_byte *bytes;
02077 arelent *cache_ptr;
02078 bfd_size_type offset;
02079 asymbol **symbols;
02080 bfd_size_type symcount;
02081 {
02082 struct aoutdata *su = &(abfd->tdata.aout_data->a);
02083 unsigned int r_index;
02084 int reloc_entry;
02085 int r_extern;
02086 int r_pcrel;
02087
02088 reloc_entry = GET_WORD (abfd, (PTR)bytes);
02089
02090 r_pcrel = reloc_entry & RELFLG;
02091
02092 cache_ptr->address = offset;
02093 cache_ptr->howto = howto_table_pdp11 + (r_pcrel ? 1 : 0);
02094
02095 if ((reloc_entry & RTYPE) == RABS)
02096 r_index = N_ABS;
02097 else
02098 r_index = RINDEX (reloc_entry);
02099
02100
02101
02102 r_extern = (reloc_entry & RTYPE) == REXT;
02103
02104 if (r_extern && r_index > symcount)
02105 {
02106
02107
02108 r_extern = 0;
02109 r_index = N_ABS;
02110 }
02111
02112 MOVE_ADDRESS(0);
02113 }
02114
02115
02116
02117 bfd_boolean
02118 NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
02119 bfd *abfd;
02120 sec_ptr asect;
02121 asymbol **symbols;
02122 {
02123 bfd_byte *rptr;
02124 bfd_size_type count;
02125 bfd_size_type reloc_size;
02126 PTR relocs;
02127 arelent *reloc_cache;
02128 size_t each_size;
02129 unsigned int counter = 0;
02130 arelent *cache_ptr;
02131
02132 if (asect->relocation)
02133 return TRUE;
02134
02135 if (asect->flags & SEC_CONSTRUCTOR)
02136 return TRUE;
02137
02138 if (asect == obj_datasec (abfd))
02139 reloc_size = exec_hdr(abfd)->a_drsize;
02140 else if (asect == obj_textsec (abfd))
02141 reloc_size = exec_hdr(abfd)->a_trsize;
02142 else if (asect == obj_bsssec (abfd))
02143 reloc_size = 0;
02144 else
02145 {
02146 bfd_set_error (bfd_error_invalid_operation);
02147 return FALSE;
02148 }
02149
02150 if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
02151 return FALSE;
02152
02153 each_size = obj_reloc_entry_size (abfd);
02154
02155 relocs = bfd_malloc (reloc_size);
02156 if (relocs == NULL && reloc_size != 0)
02157 return FALSE;
02158
02159 if (bfd_bread (relocs, reloc_size, abfd) != reloc_size)
02160 {
02161 free (relocs);
02162 return FALSE;
02163 }
02164
02165 count = reloc_size / each_size;
02166
02167
02168 {
02169 unsigned int real_count = 0;
02170
02171 for (counter = 0; counter < count; counter++)
02172 {
02173 int x;
02174
02175 x = GET_WORD (abfd, (char *) relocs + each_size * counter);
02176 if (x != 0)
02177 real_count++;
02178 }
02179
02180 count = real_count;
02181 }
02182
02183 reloc_cache = (arelent *) bfd_zmalloc (count * sizeof (arelent));
02184 if (reloc_cache == NULL && count != 0)
02185 return FALSE;
02186
02187 cache_ptr = reloc_cache;
02188
02189 rptr = relocs;
02190 for (counter = 0;
02191 counter < count;
02192 counter++, rptr += RELOC_SIZE, cache_ptr++)
02193 {
02194 while (GET_WORD (abfd, (PTR)rptr) == 0)
02195 {
02196 rptr += RELOC_SIZE;
02197 if ((char *) rptr >= (char *) relocs + reloc_size)
02198 goto done;
02199 }
02200
02201 pdp11_aout_swap_reloc_in (abfd, rptr, cache_ptr,
02202 (bfd_size_type) ((char *) rptr - (char *) relocs),
02203 symbols,
02204 (bfd_size_type) bfd_get_symcount (abfd));
02205 }
02206 done:
02207
02208
02209 BFD_ASSERT (counter == count);
02210
02211 free (relocs);
02212
02213 asect->relocation = reloc_cache;
02214 asect->reloc_count = cache_ptr - reloc_cache;
02215
02216 return TRUE;
02217 }
02218
02219
02220
02221 bfd_boolean
02222 NAME(aout,squirt_out_relocs) (abfd, section)
02223 bfd *abfd;
02224 asection *section;
02225 {
02226 arelent **generic;
02227 unsigned char *native;
02228 unsigned int count = section->reloc_count;
02229 bfd_size_type natsize;
02230
02231 natsize = section->size;
02232 native = (unsigned char *) bfd_zalloc (abfd, natsize);
02233 if (!native)
02234 return FALSE;
02235
02236 generic = section->orelocation;
02237 if (generic != NULL)
02238 {
02239 while (count > 0)
02240 {
02241 bfd_byte *r;
02242
02243 r = native + (*generic)->address;
02244 pdp11_aout_swap_reloc_out (abfd, *generic, r);
02245 count--;
02246 generic++;
02247 }
02248 }
02249
02250 if (bfd_bwrite ((PTR) native, natsize, abfd) != natsize)
02251 {
02252 bfd_release (abfd, native);
02253 return FALSE;
02254 }
02255
02256 bfd_release (abfd, native);
02257 return TRUE;
02258 }
02259
02260
02261 long
02262 NAME(aout,canonicalize_reloc) (abfd, section, relptr, symbols)
02263 bfd *abfd;
02264 sec_ptr section;
02265 arelent **relptr;
02266 asymbol **symbols;
02267 {
02268 arelent *tblptr = section->relocation;
02269 unsigned int count;
02270
02271 if (section == obj_bsssec (abfd))
02272 {
02273 *relptr = NULL;
02274 return 0;
02275 }
02276
02277 if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
02278 return -1;
02279
02280 if (section->flags & SEC_CONSTRUCTOR)
02281 {
02282 arelent_chain *chain = section->constructor_chain;
02283
02284 for (count = 0; count < section->reloc_count; count ++)
02285 {
02286 *relptr ++ = &chain->relent;
02287 chain = chain->next;
02288 }
02289 }
02290 else
02291 {
02292 tblptr = section->relocation;
02293
02294 for (count = 0; count++ < section->reloc_count;)
02295 *relptr++ = tblptr++;
02296 }
02297
02298 *relptr = 0;
02299
02300 return section->reloc_count;
02301 }
02302
02303 long
02304 NAME(aout,get_reloc_upper_bound) (abfd, asect)
02305 bfd *abfd;
02306 sec_ptr asect;
02307 {
02308 if (bfd_get_format (abfd) != bfd_object)
02309 {
02310 bfd_set_error (bfd_error_invalid_operation);
02311 return -1;
02312 }
02313
02314 if (asect->flags & SEC_CONSTRUCTOR)
02315 return (sizeof (arelent *) * (asect->reloc_count+1));
02316
02317 if (asect == obj_datasec (abfd))
02318 return (sizeof (arelent *)
02319 * ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
02320 + 1));
02321
02322 if (asect == obj_textsec (abfd))
02323 return (sizeof (arelent *)
02324 * ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
02325 + 1));
02326
02327
02328
02329 if (asect == obj_bsssec (abfd))
02330 return sizeof (arelent *);
02331
02332 if (asect == obj_bsssec (abfd))
02333 return 0;
02334
02335 bfd_set_error (bfd_error_invalid_operation);
02336 return -1;
02337 }
02338
02339
02340 long
02341 NAME(aout,get_symtab_upper_bound) (abfd)
02342 bfd *abfd;
02343 {
02344 if (!NAME(aout,slurp_symbol_table)(abfd))
02345 return -1;
02346
02347 return (bfd_get_symcount (abfd) + 1) * (sizeof (aout_symbol_type *));
02348 }
02349
02350 alent *
02351 NAME(aout,get_lineno) (abfd, symbol)
02352 bfd * abfd ATTRIBUTE_UNUSED;
02353 asymbol * symbol ATTRIBUTE_UNUSED;
02354 {
02355 return (alent *)NULL;
02356 }
02357
02358 void
02359 NAME(aout,get_symbol_info) (abfd, symbol, ret)
02360 bfd * abfd ATTRIBUTE_UNUSED;
02361 asymbol *symbol;
02362 symbol_info *ret;
02363 {
02364 bfd_symbol_info (symbol, ret);
02365
02366 if (ret->type == '?')
02367 {
02368 int type_code = aout_symbol(symbol)->type & 0xff;
02369 const char *stab_name = bfd_get_stab_name (type_code);
02370 static char buf[10];
02371
02372 if (stab_name == NULL)
02373 {
02374 sprintf(buf, "(%d)", type_code);
02375 stab_name = buf;
02376 }
02377 ret->type = '-';
02378 ret->stab_type = type_code;
02379 ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff);
02380 ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff);
02381 ret->stab_name = stab_name;
02382 }
02383 }
02384
02385 void
02386 NAME(aout,print_symbol) (abfd, afile, symbol, how)
02387 bfd * abfd;
02388 PTR afile;
02389 asymbol *symbol;
02390 bfd_print_symbol_type how;
02391 {
02392 FILE *file = (FILE *)afile;
02393
02394 switch (how)
02395 {
02396 case bfd_print_symbol_name:
02397 if (symbol->name)
02398 fprintf(file,"%s", symbol->name);
02399 break;
02400 case bfd_print_symbol_more:
02401 fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
02402 (unsigned)(aout_symbol(symbol)->other & 0xff),
02403 (unsigned)(aout_symbol(symbol)->type));
02404 break;
02405 case bfd_print_symbol_all:
02406 {
02407 const char *section_name = symbol->section->name;
02408
02409 bfd_print_symbol_vandf (abfd, (PTR)file, symbol);
02410
02411 fprintf (file," %-5s %04x %02x %02x",
02412 section_name,
02413 (unsigned)(aout_symbol(symbol)->desc & 0xffff),
02414 (unsigned)(aout_symbol(symbol)->other & 0xff),
02415 (unsigned)(aout_symbol(symbol)->type & 0xff));
02416 if (symbol->name)
02417 fprintf(file," %s", symbol->name);
02418 }
02419 break;
02420 }
02421 }
02422
02423
02424
02425
02426 #define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
02427
02428
02429
02430
02431
02432 long
02433 NAME(aout,read_minisymbols) (abfd, dynamic, minisymsp, sizep)
02434 bfd *abfd;
02435 bfd_boolean dynamic;
02436 PTR *minisymsp;
02437 unsigned int *sizep;
02438 {
02439 if (dynamic)
02440 {
02441
02442
02443 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
02444 }
02445
02446 if (! aout_get_external_symbols (abfd))
02447 return -1;
02448
02449 if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
02450 return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
02451
02452 *minisymsp = (PTR) obj_aout_external_syms (abfd);
02453
02454
02455
02456
02457
02458 obj_aout_external_syms (abfd) = NULL;
02459
02460 *sizep = EXTERNAL_NLIST_SIZE;
02461 return obj_aout_external_sym_count (abfd);
02462 }
02463
02464
02465
02466
02467
02468 asymbol *
02469 NAME(aout,minisymbol_to_symbol) (abfd, dynamic, minisym, sym)
02470 bfd *abfd;
02471 bfd_boolean dynamic;
02472 const PTR minisym;
02473 asymbol *sym;
02474 {
02475 if (dynamic
02476 || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
02477 return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
02478
02479 memset (sym, 0, sizeof (aout_symbol_type));
02480
02481
02482 if (! (NAME(aout,translate_symbol_table)
02483 (abfd,
02484 (aout_symbol_type *) sym,
02485 (struct external_nlist *) minisym,
02486 (bfd_size_type) 1,
02487 obj_aout_external_strings (abfd),
02488 obj_aout_external_string_size (abfd),
02489 FALSE)))
02490 return NULL;
02491
02492 return sym;
02493 }
02494
02495
02496
02497
02498
02499
02500
02501 bfd_boolean
02502 NAME(aout,find_nearest_line)
02503 (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
02504 bfd *abfd;
02505 asection *section;
02506 asymbol **symbols;
02507 bfd_vma offset;
02508 const char **filename_ptr;
02509 const char **functionname_ptr;
02510 unsigned int *line_ptr;
02511 {
02512
02513 asymbol **p;
02514 const char *directory_name = NULL;
02515 const char *main_file_name = NULL;
02516 const char *current_file_name = NULL;
02517 const char *line_file_name = NULL;
02518 bfd_vma low_line_vma = 0;
02519 bfd_vma low_func_vma = 0;
02520 asymbol *func = 0;
02521 size_t filelen, funclen;
02522 char *buf;
02523
02524 *filename_ptr = abfd->filename;
02525 *functionname_ptr = 0;
02526 *line_ptr = 0;
02527
02528 if (symbols != (asymbol **)NULL)
02529 {
02530 for (p = symbols; *p; p++)
02531 {
02532 aout_symbol_type *q = (aout_symbol_type *)(*p);
02533 next:
02534 switch (q->type)
02535 {
02536 case N_TEXT:
02537
02538
02539
02540
02541 if (q->symbol.value <= offset
02542 && ((q->symbol.value > low_line_vma
02543 && (line_file_name != NULL
02544 || *line_ptr != 0))
02545 || (q->symbol.value > low_func_vma
02546 && func != NULL)))
02547 {
02548 const char * symname;
02549
02550 symname = q->symbol.name;
02551 if (strcmp (symname + strlen (symname) - 2, ".o") == 0)
02552 {
02553 if (q->symbol.value > low_line_vma)
02554 {
02555 *line_ptr = 0;
02556 line_file_name = NULL;
02557 }
02558 if (q->symbol.value > low_func_vma)
02559 func = NULL;
02560 }
02561 }
02562 break;
02563
02564 case N_SO:
02565
02566
02567
02568 if (q->symbol.value <= offset)
02569 {
02570 if (q->symbol.value > low_line_vma)
02571 {
02572 *line_ptr = 0;
02573 line_file_name = NULL;
02574 }
02575 if (q->symbol.value > low_func_vma)
02576 func = NULL;
02577 }
02578
02579 main_file_name = current_file_name = q->symbol.name;
02580
02581 p++;
02582 if (*p == NULL)
02583 break;
02584 q = (aout_symbol_type *)(*p);
02585 if (q->type != (int)N_SO)
02586 goto next;
02587
02588
02589 directory_name = current_file_name;
02590 main_file_name = current_file_name = q->symbol.name;
02591 if (obj_textsec(abfd) != section)
02592 goto done;
02593 break;
02594 case N_SOL:
02595 current_file_name = q->symbol.name;
02596 break;
02597
02598 case N_SLINE:
02599 case N_DSLINE:
02600 case N_BSLINE:
02601
02602
02603 if (q->symbol.value >= low_line_vma
02604 && q->symbol.value <= offset)
02605 {
02606 *line_ptr = q->desc;
02607 low_line_vma = q->symbol.value;
02608 line_file_name = current_file_name;
02609 }
02610 break;
02611
02612 case N_FUN:
02613 {
02614
02615 if (q->symbol.value >= low_func_vma &&
02616 q->symbol.value <= offset)
02617 {
02618 low_func_vma = q->symbol.value;
02619 func = (asymbol *)q;
02620 }
02621 else if (q->symbol.value > offset)
02622 goto done;
02623 }
02624 break;
02625 }
02626 }
02627 }
02628
02629 done:
02630 if (*line_ptr != 0)
02631 main_file_name = line_file_name;
02632
02633 if (main_file_name == NULL
02634 || main_file_name[0] == '/'
02635 || directory_name == NULL)
02636 filelen = 0;
02637 else
02638 filelen = strlen (directory_name) + strlen (main_file_name);
02639 if (func == NULL)
02640 funclen = 0;
02641 else
02642 funclen = strlen (bfd_asymbol_name (func));
02643
02644 if (adata (abfd).line_buf != NULL)
02645 free (adata (abfd).line_buf);
02646 if (filelen + funclen == 0)
02647 adata (abfd).line_buf = buf = NULL;
02648 else
02649 {
02650 buf = (char *) bfd_malloc ((bfd_size_type) filelen + funclen + 3);
02651 adata (abfd).line_buf = buf;
02652 if (buf == NULL)
02653 return FALSE;
02654 }
02655
02656 if (main_file_name != NULL)
02657 {
02658 if (main_file_name[0] == '/' || directory_name == NULL)
02659 *filename_ptr = main_file_name;
02660 else
02661 {
02662 sprintf (buf, "%s%s", directory_name, main_file_name);
02663 *filename_ptr = buf;
02664 buf += filelen + 1;
02665 }
02666 }
02667
02668 if (func)
02669 {
02670 const char *function = func->name;
02671 char *colon;
02672
02673
02674
02675
02676 if (bfd_get_symbol_leading_char (abfd) == '\0')
02677 strcpy (buf, function);
02678 else
02679 {
02680 buf[0] = bfd_get_symbol_leading_char (abfd);
02681 strcpy (buf + 1, function);
02682 }
02683
02684
02685 colon = strchr (buf, ':');
02686 if (colon != NULL)
02687 *colon = '\0';
02688 *functionname_ptr = buf;
02689 }
02690
02691 return TRUE;
02692 }
02693
02694 int
02695 NAME(aout,sizeof_headers) (abfd, execable)
02696 bfd *abfd;
02697 bfd_boolean execable ATTRIBUTE_UNUSED;
02698 {
02699 return adata(abfd).exec_bytes_size;
02700 }
02701
02702
02703
02704
02705 bfd_boolean
02706 NAME(aout,bfd_free_cached_info) (abfd)
02707 bfd *abfd;
02708 {
02709 asection *o;
02710
02711 if (bfd_get_format (abfd) != bfd_object)
02712 return TRUE;
02713
02714 #define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
02715 BFCI_FREE (obj_aout_symbols (abfd));
02716 #ifdef USE_MMAP
02717 obj_aout_external_syms (abfd) = 0;
02718 bfd_free_window (&obj_aout_sym_window (abfd));
02719 bfd_free_window (&obj_aout_string_window (abfd));
02720 obj_aout_external_strings (abfd) = 0;
02721 #else
02722 BFCI_FREE (obj_aout_external_syms (abfd));
02723 BFCI_FREE (obj_aout_external_strings (abfd));
02724 #endif
02725 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
02726 BFCI_FREE (o->relocation);
02727 #undef BFCI_FREE
02728
02729 return TRUE;
02730 }
02731
02732
02733
02734 static bfd_boolean aout_link_add_object_symbols
02735 PARAMS ((bfd *, struct bfd_link_info *));
02736 static bfd_boolean aout_link_check_archive_element
02737 PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean *));
02738 static bfd_boolean aout_link_free_symbols PARAMS ((bfd *));
02739 static bfd_boolean aout_link_check_ar_symbols
02740 PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean *pneeded));
02741 static bfd_boolean aout_link_add_symbols
02742 PARAMS ((bfd *, struct bfd_link_info *));
02743
02744
02745
02746 struct bfd_hash_entry *
02747 NAME(aout,link_hash_newfunc) (entry, table, string)
02748 struct bfd_hash_entry *entry;
02749 struct bfd_hash_table *table;
02750 const char *string;
02751 {
02752 struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
02753
02754
02755
02756 if (ret == (struct aout_link_hash_entry *) NULL)
02757 ret = ((struct aout_link_hash_entry *)
02758 bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
02759 if (ret == (struct aout_link_hash_entry *) NULL)
02760 return (struct bfd_hash_entry *) ret;
02761
02762
02763 ret = ((struct aout_link_hash_entry *)
02764 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
02765 table, string));
02766 if (ret)
02767 {
02768
02769 ret->written = FALSE;
02770 ret->indx = -1;
02771 }
02772
02773 return (struct bfd_hash_entry *) ret;
02774 }
02775
02776
02777
02778 bfd_boolean
02779 NAME(aout,link_hash_table_init) (table, abfd, newfunc)
02780 struct aout_link_hash_table *table;
02781 bfd *abfd;
02782 struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
02783 struct bfd_hash_table *,
02784 const char *));
02785 {
02786 return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
02787 }
02788
02789
02790
02791 struct bfd_link_hash_table *
02792 NAME(aout,link_hash_table_create) (abfd)
02793 bfd *abfd;
02794 {
02795 struct aout_link_hash_table *ret;
02796 bfd_size_type amt = sizeof (struct aout_link_hash_table);
02797
02798 ret = ((struct aout_link_hash_table *) bfd_alloc (abfd, amt));
02799 if (ret == NULL)
02800 return (struct bfd_link_hash_table *) NULL;
02801 if (! NAME(aout,link_hash_table_init) (ret, abfd,
02802 NAME(aout,link_hash_newfunc)))
02803 {
02804 free (ret);
02805 return (struct bfd_link_hash_table *) NULL;
02806 }
02807 return &ret->root;
02808 }
02809
02810
02811
02812
02813 bfd_boolean
02814 NAME(aout,link_add_symbols) (abfd, info)
02815 bfd *abfd;
02816 struct bfd_link_info *info;
02817 {
02818 switch (bfd_get_format (abfd))
02819 {
02820 case bfd_object:
02821 return aout_link_add_object_symbols (abfd, info);
02822 case bfd_archive:
02823 return _bfd_generic_link_add_archive_symbols
02824 (abfd, info, aout_link_check_archive_element);
02825 default:
02826 bfd_set_error (bfd_error_wrong_format);
02827 return FALSE;
02828 }
02829 }
02830
02831
02832
02833 static bfd_boolean
02834 aout_link_add_object_symbols (abfd, info)
02835 bfd *abfd;
02836 struct bfd_link_info *info;
02837 {
02838 if (! aout_get_external_symbols (abfd))
02839 return FALSE;
02840 if (! aout_link_add_symbols (abfd, info))
02841 return FALSE;
02842 if (! info->keep_memory)
02843 {
02844 if (! aout_link_free_symbols (abfd))
02845 return FALSE;
02846 }
02847 return TRUE;
02848 }
02849
02850
02851
02852
02853
02854
02855 static bfd_boolean
02856 aout_link_check_archive_element (abfd, info, pneeded)
02857 bfd *abfd;
02858 struct bfd_link_info *info;
02859 bfd_boolean *pneeded;
02860 {
02861 if (! aout_get_external_symbols (abfd))
02862 return FALSE;
02863
02864 if (! aout_link_check_ar_symbols (abfd, info, pneeded))
02865 return FALSE;
02866
02867 if (*pneeded)
02868 {
02869 if (! aout_link_add_symbols (abfd, info))
02870 return FALSE;
02871 }
02872
02873 if (! info->keep_memory || ! *pneeded)
02874 {
02875 if (! aout_link_free_symbols (abfd))
02876 return FALSE;
02877 }
02878
02879 return TRUE;
02880 }
02881
02882
02883
02884 static bfd_boolean
02885 aout_link_free_symbols (abfd)
02886 bfd *abfd;
02887 {
02888 if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
02889 {
02890 #ifdef USE_MMAP
02891 bfd_free_window (&obj_aout_sym_window (abfd));
02892 #else
02893 free ((PTR) obj_aout_external_syms (abfd));
02894 #endif
02895 obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
02896 }
02897 if (obj_aout_external_strings (abfd) != (char *) NULL)
02898 {
02899 #ifdef USE_MMAP
02900 bfd_free_window (&obj_aout_string_window (abfd));
02901 #else
02902 free ((PTR) obj_aout_external_strings (abfd));
02903 #endif
02904 obj_aout_external_strings (abfd) = (char *) NULL;
02905 }
02906 return TRUE;
02907 }
02908
02909
02910
02911
02912
02913
02914
02915
02916 static bfd_boolean
02917 aout_link_check_ar_symbols (abfd, info, pneeded)
02918 bfd *abfd;
02919 struct bfd_link_info *info;
02920 bfd_boolean *pneeded;
02921 {
02922 register struct external_nlist *p;
02923 struct external_nlist *pend;
02924 char *strings;
02925
02926 *pneeded = FALSE;
02927
02928
02929 p = obj_aout_external_syms (abfd);
02930 pend = p + obj_aout_external_sym_count (abfd);
02931 strings = obj_aout_external_strings (abfd);
02932 for (; p < pend; p++)
02933 {
02934 int type = H_GET_8 (abfd, p->e_type);
02935 const char *name;
02936 struct bfd_link_hash_entry *h;
02937
02938
02939
02940
02941 if ((type & N_EXT) == 0
02942 || type == N_FN)
02943 continue;
02944
02945 name = strings + GET_WORD (abfd, p->e_strx);
02946 h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
02947
02948
02949
02950 if (h == (struct bfd_link_hash_entry *) NULL
02951 || (h->type != bfd_link_hash_undefined
02952 && h->type != bfd_link_hash_common))
02953 continue;
02954
02955 if (type == (N_TEXT | N_EXT)
02956 || type == (N_DATA | N_EXT)
02957 || type == (N_BSS | N_EXT)
02958 || type == (N_ABS | N_EXT))
02959 {
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
02976 return FALSE;
02977 *pneeded = TRUE;
02978 return TRUE;
02979 }
02980
02981 if (type == (N_UNDF | N_EXT))
02982 {
02983 bfd_vma value;
02984
02985 value = GET_WORD (abfd, p->e_value);
02986 if (value != 0)
02987 {
02988
02989
02990 if (h->type == bfd_link_hash_undefined)
02991 {
02992 bfd *symbfd;
02993 unsigned int power;
02994
02995 symbfd = h->u.undef.abfd;
02996 if (symbfd == (bfd *) NULL)
02997 {
02998
02999
03000
03001
03002 if (! (*info->callbacks->add_archive_element) (info,
03003 abfd,
03004 name))
03005 return FALSE;
03006 *pneeded = TRUE;
03007 return TRUE;
03008 }
03009
03010
03011 h->type = bfd_link_hash_common;
03012 h->u.c.p = ((struct bfd_link_hash_common_entry *)
03013 bfd_hash_allocate (&info->hash->table,
03014 sizeof (struct bfd_link_hash_common_entry)));
03015 if (h->u.c.p == NULL)
03016 return FALSE;
03017
03018 h->u.c.size = value;
03019
03020
03021
03022
03023
03024 power = bfd_log2 (value);
03025 if (power > bfd_get_arch_info (abfd)->section_align_power)
03026 power = bfd_get_arch_info (abfd)->section_align_power;
03027 h->u.c.p->alignment_power = power;
03028
03029 h->u.c.p->section = bfd_make_section_old_way (symbfd,
03030 "COMMON");
03031 }
03032 else
03033 {
03034
03035
03036 if (value > h->u.c.size)
03037 h->u.c.size = value;
03038 }
03039 }
03040 }
03041 }
03042
03043
03044 return TRUE;
03045 }
03046
03047
03048
03049 static bfd_boolean
03050 aout_link_add_symbols (abfd, info)
03051 bfd *abfd;
03052 struct bfd_link_info *info;
03053 {
03054 bfd_boolean (*add_one_symbol)
03055 PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,
03056 bfd_vma, const char *, bfd_boolean, bfd_boolean,
03057 struct bfd_link_hash_entry **));
03058 struct external_nlist *syms;
03059 bfd_size_type sym_count;
03060 char *strings;
03061 bfd_boolean copy;
03062 struct aout_link_hash_entry **sym_hash;
03063 register struct external_nlist *p;
03064 struct external_nlist *pend;
03065
03066 syms = obj_aout_external_syms (abfd);
03067 sym_count = obj_aout_external_sym_count (abfd);
03068 strings = obj_aout_external_strings (abfd);
03069 if (info->keep_memory)
03070 copy = FALSE;
03071 else
03072 copy = TRUE;
03073
03074 if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
03075 {
03076 if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
03077 (abfd, info, &syms, &sym_count, &strings)))
03078 return FALSE;
03079 }
03080
03081
03082
03083
03084
03085 sym_hash = ((struct aout_link_hash_entry **)
03086 bfd_alloc (abfd,
03087 sym_count * sizeof (struct aout_link_hash_entry *)));
03088 if (sym_hash == NULL && sym_count != 0)
03089 return FALSE;
03090 obj_aout_sym_hashes (abfd) = sym_hash;
03091
03092 add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
03093 if (add_one_symbol == NULL)
03094 add_one_symbol = _bfd_generic_link_add_one_symbol;
03095
03096 p = syms;
03097 pend = p + sym_count;
03098 for (; p < pend; p++, sym_hash++)
03099 {
03100 int type;
03101 const char *name;
03102 bfd_vma value;
03103 asection *section;
03104 flagword flags;
03105 const char *string;
03106
03107 *sym_hash = NULL;
03108
03109 type = H_GET_8 (abfd, p->e_type);
03110
03111 name = strings + GET_WORD (abfd, p->e_strx);
03112 value = GET_WORD (abfd, p->e_value);
03113 flags = BSF_GLOBAL;
03114 string = NULL;
03115 switch (type)
03116 {
03117 default:
03118 abort ();
03119
03120 case N_UNDF:
03121 case N_ABS:
03122 case N_TEXT:
03123 case N_DATA:
03124 case N_BSS:
03125 case N_REG:
03126 case N_FN:
03127
03128 continue;
03129
03130 case N_UNDF | N_EXT:
03131 if (value == 0)
03132 {
03133 section = bfd_und_section_ptr;
03134 flags = 0;
03135 }
03136 else
03137 section = bfd_com_section_ptr;
03138 break;
03139 case N_ABS | N_EXT:
03140 section = bfd_abs_section_ptr;
03141 break;
03142 case N_TEXT | N_EXT:
03143 section = obj_textsec (abfd);
03144 value -= bfd_get_section_vma (abfd, section);
03145 break;
03146 case N_DATA | N_EXT:
03147
03148
03149 section = obj_datasec (abfd);
03150 value -= bfd_get_section_vma (abfd, section);
03151 break;
03152 case N_BSS | N_EXT:
03153 section = obj_bsssec (abfd);
03154 value -= bfd_get_section_vma (abfd, section);
03155 break;
03156 }
03157
03158 if (! ((*add_one_symbol)
03159 (info, abfd, name, flags, section, value, string, copy, FALSE,
03160 (struct bfd_link_hash_entry **) sym_hash)))
03161 return FALSE;
03162
03163
03164
03165
03166
03167
03168 if ((*sym_hash)->root.type == bfd_link_hash_common
03169 && ((*sym_hash)->root.u.c.p->alignment_power >
03170 bfd_get_arch_info (abfd)->section_align_power))
03171 (*sym_hash)->root.u.c.p->alignment_power =
03172 bfd_get_arch_info (abfd)->section_align_power;
03173
03174
03175
03176
03177 if ((*sym_hash)->root.type == bfd_link_hash_new)
03178 {
03179 BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
03180 *sym_hash = NULL;
03181 }
03182 }
03183
03184 return TRUE;
03185 }
03186
03187
03188
03189 struct aout_link_includes_table
03190 {
03191 struct bfd_hash_table root;
03192 };
03193
03194
03195
03196
03197 struct aout_link_includes_totals
03198 {
03199 struct aout_link_includes_totals *next;
03200 bfd_vma total;
03201 };
03202
03203
03204
03205 struct aout_link_includes_entry
03206 {
03207 struct bfd_hash_entry root;
03208
03209 struct aout_link_includes_totals *totals;
03210 };
03211
03212
03213
03214 #define aout_link_includes_lookup(table, string, create, copy) \
03215 ((struct aout_link_includes_entry *) \
03216 bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
03217
03218
03219
03220
03221 struct aout_final_link_info
03222 {
03223
03224 struct bfd_link_info *info;
03225
03226 bfd *output_bfd;
03227
03228 file_ptr treloff, dreloff;
03229
03230 file_ptr symoff;
03231
03232 struct bfd_strtab_hash *strtab;
03233
03234 struct aout_link_includes_table includes;
03235
03236 bfd_byte *contents;
03237
03238 PTR relocs;
03239
03240 int *symbol_map;
03241
03242 struct external_nlist *output_syms;
03243 };
03244
03245 static struct bfd_hash_entry *aout_link_includes_newfunc
03246 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
03247 static bfd_boolean aout_link_input_bfd
03248 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
03249 static bfd_boolean aout_link_write_symbols
03250 PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
03251 static bfd_boolean aout_link_write_other_symbol
03252 PARAMS ((struct aout_link_hash_entry *, PTR));
03253 static bfd_boolean aout_link_input_section
03254 PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
03255 asection *input_section, file_ptr *reloff_ptr,
03256 bfd_size_type rel_size));
03257 static INLINE asection *aout_reloc_type_to_section
03258 PARAMS ((bfd *, int));
03259 static bfd_boolean aout_link_reloc_link_order
03260 PARAMS ((struct aout_final_link_info *, asection *,
03261 struct bfd_link_order *));
03262 static bfd_boolean pdp11_aout_link_input_section
03263 PARAMS ((struct aout_final_link_info *finfo,
03264 bfd *input_bfd,
03265 asection *input_section,
03266 bfd_byte *relocs,
03267 bfd_size_type rel_size,
03268 bfd_byte *contents));
03269
03270
03271
03272 static struct bfd_hash_entry *
03273 aout_link_includes_newfunc (entry, table, string)
03274 struct bfd_hash_entry *entry;
03275 struct bfd_hash_table *table;
03276 const char *string;
03277 {
03278 struct aout_link_includes_entry *ret =
03279 (struct aout_link_includes_entry *) entry;
03280
03281
03282
03283 if (ret == (struct aout_link_includes_entry *) NULL)
03284 ret = ((struct aout_link_includes_entry *)
03285 bfd_hash_allocate (table,
03286 sizeof (struct aout_link_includes_entry)));
03287 if (ret == (struct aout_link_includes_entry *) NULL)
03288 return (struct bfd_hash_entry *) ret;
03289
03290
03291 ret = ((struct aout_link_includes_entry *)
03292 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
03293 if (ret)
03294 {
03295
03296 ret->totals = NULL;
03297 }
03298
03299 return (struct bfd_hash_entry *) ret;
03300 }
03301
03302
03303
03304
03305
03306
03307
03308
03309 bfd_boolean
03310 NAME(aout,final_link) (abfd, info, callback)
03311 bfd *abfd;
03312 struct bfd_link_info *info;
03313 void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
03314 {
03315 struct aout_final_link_info aout_info;
03316 bfd_boolean includes_hash_initialized = FALSE;
03317 register bfd *sub;
03318 bfd_size_type trsize, drsize;
03319 bfd_size_type max_contents_size;
03320 bfd_size_type max_relocs_size;
03321 bfd_size_type max_sym_count;
03322 bfd_size_type text_size;
03323 file_ptr text_end;
03324 register struct bfd_link_order *p;
03325 asection *o;
03326 bfd_boolean have_link_order_relocs;
03327
03328 if (info->shared)
03329 abfd->flags |= DYNAMIC;
03330
03331 aout_info.info = info;
03332 aout_info.output_bfd = abfd;
03333 aout_info.contents = NULL;
03334 aout_info.relocs = NULL;
03335 aout_info.symbol_map = NULL;
03336 aout_info.output_syms = NULL;
03337
03338 if (! bfd_hash_table_init_n (&aout_info.includes.root,
03339 aout_link_includes_newfunc,
03340 251))
03341 goto error_return;
03342 includes_hash_initialized = TRUE;
03343
03344
03345
03346 trsize = 0;
03347 drsize = 0;
03348 max_contents_size = 0;
03349 max_relocs_size = 0;
03350 max_sym_count = 0;
03351 for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
03352 {
03353 size_t sz;
03354
03355 if (info->relocatable)
03356 {
03357 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
03358 {
03359 trsize += exec_hdr (sub)->a_trsize;
03360 drsize += exec_hdr (sub)->a_drsize;
03361 }
03362 else
03363 {
03364
03365
03366
03367
03368 (*_bfd_error_handler)
03369 ("%s: relocatable link from %s to %s not supported",
03370 bfd_get_filename (abfd),
03371 sub->xvec->name, abfd->xvec->name);
03372 bfd_set_error (bfd_error_invalid_operation);
03373 goto error_return;
03374 }
03375 }
03376
03377 if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
03378 {
03379 sz = obj_textsec (sub)->size;
03380 if (sz > max_contents_size)
03381 max_contents_size = sz;
03382 sz = obj_datasec (sub)->size;
03383 if (sz > max_contents_size)
03384 max_contents_size = sz;
03385
03386 sz = exec_hdr (sub)->a_trsize;
03387 if (sz > max_relocs_size)
03388 max_relocs_size = sz;
03389 sz = exec_hdr (sub)->a_drsize;
03390 if (sz > max_relocs_size)
03391 max_relocs_size = sz;
03392
03393 sz = obj_aout_external_sym_count (sub);
03394 if (sz > max_sym_count)
03395 max_sym_count = sz;
03396 }
03397 }
03398
03399 if (info->relocatable)
03400 {
03401 if (obj_textsec (abfd) != (asection *) NULL)
03402 trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
03403 ->link_order_head)
03404 * obj_reloc_entry_size (abfd));
03405 if (obj_datasec (abfd) != (asection *) NULL)
03406 drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
03407 ->link_order_head)
03408 * obj_reloc_entry_size (abfd));
03409 }
03410
03411 exec_hdr (abfd)->a_trsize = trsize;
03412 exec_hdr (abfd)->a_drsize = drsize;
03413
03414 exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
03415
03416
03417
03418
03419 if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
03420 goto error_return;
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430 (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
03431 &aout_info.symoff);
03432 obj_textsec (abfd)->rel_filepos = aout_info.treloff;
03433 obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
03434 obj_sym_filepos (abfd) = aout_info.symoff;
03435
03436
03437 obj_aout_external_sym_count (abfd) = 0;
03438
03439
03440 aout_info.strtab = _bfd_stringtab_init ();
03441 if (aout_info.strtab == NULL)
03442 goto error_return;
03443
03444
03445 aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
03446 aout_info.relocs = (PTR) bfd_malloc (max_relocs_size);
03447 aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int *));
03448 aout_info.output_syms = ((struct external_nlist *)
03449 bfd_malloc ((max_sym_count + 1)
03450 * sizeof (struct external_nlist)));
03451 if ((aout_info.contents == NULL && max_contents_size != 0)
03452 || (aout_info.relocs == NULL && max_relocs_size != 0)
03453 || (aout_info.symbol_map == NULL && max_sym_count != 0)
03454 || aout_info.output_syms == NULL)
03455 goto error_return;
03456
03457
03458
03459
03460
03461 {
03462 struct aout_link_hash_entry *h;
03463
03464 h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
03465 FALSE, FALSE, FALSE);
03466 if (h != NULL)
03467 aout_link_write_other_symbol (h, &aout_info);
03468 }
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491 for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
03492 sub->output_has_begun = FALSE;
03493
03494
03495
03496
03497
03498 for (o = abfd->sections; o != NULL; o = o->next)
03499 {
03500 for (p = o->link_order_head; p != NULL; p = p->next)
03501 {
03502 if (p->type == bfd_indirect_link_order)
03503 p->u.indirect.section->linker_mark = TRUE;
03504 }
03505 }
03506
03507 have_link_order_relocs = FALSE;
03508 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
03509 {
03510 for (p = o->link_order_head;
03511 p != (struct bfd_link_order *) NULL;
03512 p = p->next)
03513 {
03514 if (p->type == bfd_indirect_link_order
03515 && (bfd_get_flavour (p->u.indirect.section->owner)
03516 == bfd_target_aout_flavour))
03517 {
03518 bfd *input_bfd;
03519
03520 input_bfd = p->u.indirect.section->owner;
03521 if (! input_bfd->output_has_begun)
03522 {
03523 if (! aout_link_input_bfd (&aout_info, input_bfd))
03524 goto error_return;
03525 input_bfd->output_has_begun = TRUE;
03526 }
03527 }
03528 else if (p->type == bfd_section_reloc_link_order
03529 || p->type == bfd_symbol_reloc_link_order)
03530 {
03531
03532 have_link_order_relocs = TRUE;
03533 }
03534 else
03535 {
03536 if (! _bfd_default_link_order (abfd, info, o, p))
03537 goto error_return;
03538 }
03539 }
03540 }
03541
03542
03543 aout_link_hash_traverse (aout_hash_table (info),
03544 aout_link_write_other_symbol,
03545 (PTR) &aout_info);
03546
03547
03548
03549
03550
03551 if (have_link_order_relocs)
03552 {
03553 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
03554 {
03555 for (p = o->link_order_head;
03556 p != (struct bfd_link_order *) NULL;
03557 p = p->next)
03558 {
03559 if (p->type == bfd_section_reloc_link_order
03560 || p->type == bfd_symbol_reloc_link_order)
03561 {
03562 if (! aout_link_reloc_link_order (&aout_info, o, p))
03563 goto error_return;
03564 }
03565 }
03566 }
03567 }
03568
03569 if (aout_info.contents != NULL)
03570 {
03571 free (aout_info.contents);
03572 aout_info.contents = NULL;
03573 }
03574 if (aout_info.relocs != NULL)
03575 {
03576 free (aout_info.relocs);
03577 aout_info.relocs = NULL;
03578 }
03579 if (aout_info.symbol_map != NULL)
03580 {
03581 free (aout_info.symbol_map);
03582 aout_info.symbol_map = NULL;
03583 }
03584 if (aout_info.output_syms != NULL)
03585 {
03586 free (aout_info.output_syms);
03587 aout_info.output_syms = NULL;
03588 }
03589 if (includes_hash_initialized)
03590 {
03591 bfd_hash_table_free (&aout_info.includes.root);
03592 includes_hash_initialized = FALSE;
03593 }
03594
03595
03596 if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
03597 {
03598 if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
03599 goto error_return;
03600 }
03601
03602
03603 abfd->symcount = obj_aout_external_sym_count (abfd);
03604 exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
03605 obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
03606 obj_textsec (abfd)->reloc_count =
03607 exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
03608 obj_datasec (abfd)->reloc_count =
03609 exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
03610
03611
03612 if (abfd->symcount > 0)
03613 {
03614 if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
03615 || ! emit_stringtab (abfd, aout_info.strtab))
03616 goto error_return;
03617 }
03618 else if (obj_textsec (abfd)->reloc_count == 0
03619 && obj_datasec (abfd)->reloc_count == 0)
03620 {
03621 bfd_byte b;
03622
03623 b = 0;
03624 if (bfd_seek (abfd,
03625 (file_ptr) (obj_datasec (abfd)->filepos
03626 + exec_hdr (abfd)->a_data
03627 - 1),
03628 SEEK_SET) != 0
03629 || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
03630 goto error_return;
03631 }
03632
03633 return TRUE;
03634
03635 error_return:
03636 if (aout_info.contents != NULL)
03637 free (aout_info.contents);
03638 if (aout_info.relocs != NULL)
03639 free (aout_info.relocs);
03640 if (aout_info.symbol_map != NULL)
03641 free (aout_info.symbol_map);
03642 if (aout_info.output_syms != NULL)
03643 free (aout_info.output_syms);
03644 if (includes_hash_initialized)
03645 bfd_hash_table_free (&aout_info.includes.root);
03646 return FALSE;
03647 }
03648
03649
03650
03651 static bfd_boolean
03652 aout_link_input_bfd (finfo, input_bfd)
03653 struct aout_final_link_info *finfo;
03654 bfd *input_bfd;
03655 {
03656 bfd_size_type sym_count;
03657
03658 BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
03659
03660
03661 if ((input_bfd->flags & DYNAMIC) != 0
03662 && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
03663 {
03664 return ((*aout_backend_info (input_bfd)->link_dynamic_object)
03665 (finfo->info, input_bfd));
03666 }
03667
03668
03669
03670 if (! aout_get_external_symbols (input_bfd))
03671 return FALSE;
03672
03673 sym_count = obj_aout_external_sym_count (input_bfd);
03674
03675
03676
03677 if (! aout_link_write_symbols (finfo, input_bfd))
03678 return FALSE;
03679
03680
03681
03682
03683
03684 if (obj_textsec (input_bfd)->linker_mark)
03685 {
03686 if (! aout_link_input_section (finfo, input_bfd,
03687 obj_textsec (input_bfd),
03688 &finfo->treloff,
03689 exec_hdr (input_bfd)->a_trsize))
03690 return FALSE;
03691 }
03692 if (obj_datasec (input_bfd)->linker_mark)
03693 {
03694 if (! aout_link_input_section (finfo, input_bfd,
03695 obj_datasec (input_bfd),
03696 &finfo->dreloff,
03697 exec_hdr (input_bfd)->a_drsize))
03698 return FALSE;
03699 }
03700
03701
03702
03703
03704 if (! finfo->info->keep_memory)
03705 {
03706 if (! aout_link_free_symbols (input_bfd))
03707 return FALSE;
03708 }
03709
03710 return TRUE;
03711 }
03712
03713
03714
03715
03716 static bfd_boolean
03717 aout_link_write_symbols (finfo, input_bfd)
03718 struct aout_final_link_info *finfo;
03719 bfd *input_bfd;
03720 {
03721 bfd *output_bfd;
03722 bfd_size_type sym_count;
03723 char *strings;
03724 enum bfd_link_strip strip;
03725 enum bfd_link_discard discard;
03726 struct external_nlist *outsym;
03727 bfd_size_type strtab_index;
03728 register struct external_nlist *sym;
03729 struct external_nlist *sym_end;
03730 struct aout_link_hash_entry **sym_hash;
03731 int *symbol_map;
03732 bfd_boolean pass;
03733 bfd_boolean skip_next;
03734
03735 output_bfd = finfo->output_bfd;
03736 sym_count = obj_aout_external_sym_count (input_bfd);
03737 strings = obj_aout_external_strings (input_bfd);
03738 strip = finfo->info->strip;
03739 discard = finfo->info->discard;
03740 outsym = finfo->output_syms;
03741
03742
03743
03744 if (strip != strip_all
03745 && (strip != strip_some
03746 || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
03747 FALSE, FALSE) != NULL)
03748 && discard != discard_all)
03749 {
03750 H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
03751 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
03752 input_bfd->filename, FALSE);
03753 if (strtab_index == (bfd_size_type) -1)
03754 return FALSE;
03755 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
03756 PUT_WORD (output_bfd,
03757 (bfd_get_section_vma (output_bfd,
03758 obj_textsec (input_bfd)->output_section)
03759 + obj_textsec (input_bfd)->output_offset),
03760 outsym->e_value);
03761 ++obj_aout_external_sym_count (output_bfd);
03762 ++outsym;
03763 }
03764
03765 pass = FALSE;
03766 skip_next = FALSE;
03767 sym = obj_aout_external_syms (input_bfd);
03768 sym_end = sym + sym_count;
03769 sym_hash = obj_aout_sym_hashes (input_bfd);
03770 symbol_map = finfo->symbol_map;
03771 memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
03772 for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
03773 {
03774 const char *name;
03775 int type;
03776 struct aout_link_hash_entry *h;
03777 bfd_boolean skip;
03778 asection *symsec;
03779 bfd_vma val = 0;
03780 bfd_boolean copy;
03781
03782
03783
03784
03785
03786 if (*symbol_map == -1)
03787 continue;
03788
03789
03790
03791
03792 *symbol_map = -1;
03793
03794 type = H_GET_8 (input_bfd, sym->e_type);
03795 name = strings + GET_WORD (input_bfd, sym->e_strx);
03796
03797 h = NULL;
03798
03799 if (pass)
03800 {
03801
03802
03803 val = GET_WORD (input_bfd, sym->e_value);
03804 pass = FALSE;
03805 }
03806 else if (skip_next)
03807 {
03808
03809
03810
03811 skip_next = FALSE;
03812 continue;
03813 }
03814 else
03815 {
03816 struct aout_link_hash_entry *hresolve;
03817
03818
03819
03820
03821
03822 h = *sym_hash;
03823
03824
03825
03826 if (h != NULL)
03827 name = h->root.root.string;
03828
03829
03830
03831
03832
03833 hresolve = h;
03834 if (h != (struct aout_link_hash_entry *) NULL
03835 && (h->root.type == bfd_link_hash_indirect
03836 || h->root.type == bfd_link_hash_warning))
03837 {
03838 hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
03839 while (hresolve->root.type == bfd_link_hash_indirect
03840 || hresolve->root.type == bfd_link_hash_warning)
03841 hresolve = ((struct aout_link_hash_entry *)
03842 hresolve->root.u.i.link);
03843 *sym_hash = hresolve;
03844 }
03845
03846
03847 if (h != (struct aout_link_hash_entry *) NULL
03848 && h->root.type != bfd_link_hash_warning
03849 && h->written)
03850 {
03851 if ((type & N_TYPE) == N_INDR
03852 || type == N_WARNING)
03853 skip_next = TRUE;
03854 *symbol_map = h->indx;
03855 continue;
03856 }
03857
03858
03859 skip = FALSE;
03860 switch (strip)
03861 {
03862 case strip_none:
03863 break;
03864 case strip_debugger:
03865 if ((type & N_STAB) != 0)
03866 skip = TRUE;
03867 break;
03868 case strip_some:
03869 if (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE)
03870 == NULL)
03871 skip = TRUE;
03872 break;
03873 case strip_all:
03874 skip = TRUE;
03875 break;
03876 }
03877 if (skip)
03878 {
03879 if (h != (struct aout_link_hash_entry *) NULL)
03880 h->written = TRUE;
03881 continue;
03882 }
03883
03884
03885 if ((type & N_TYPE) == N_TEXT
03886 || type == N_WEAKT)
03887 symsec = obj_textsec (input_bfd);
03888 else if ((type & N_TYPE) == N_DATA
03889 || type == N_WEAKD)
03890 symsec = obj_datasec (input_bfd);
03891 else if ((type & N_TYPE) == N_BSS
03892 || type == N_WEAKB)
03893 symsec = obj_bsssec (input_bfd);
03894 else if ((type & N_TYPE) == N_ABS
03895 || type == N_WEAKA)
03896 symsec = bfd_abs_section_ptr;
03897 else if (((type & N_TYPE) == N_INDR
03898 && (hresolve == (struct aout_link_hash_entry *) NULL
03899 || (hresolve->root.type != bfd_link_hash_defined
03900 && hresolve->root.type != bfd_link_hash_defweak
03901 && hresolve->root.type != bfd_link_hash_common)))
03902 || type == N_WARNING)
03903 {
03904
03905
03906
03907
03908
03909 pass = TRUE;
03910 val = GET_WORD (input_bfd, sym->e_value);
03911 symsec = NULL;
03912 }
03913 else if ((type & N_STAB) != 0)
03914 {
03915 val = GET_WORD (input_bfd, sym->e_value);
03916 symsec = NULL;
03917 }
03918 else
03919 {
03920
03921
03922
03923
03924 if ((type & N_TYPE) == N_INDR)
03925 skip_next = TRUE;
03926
03927 symsec = NULL;
03928
03929
03930
03931
03932 if (h == (struct aout_link_hash_entry *) NULL)
03933 {
03934 switch (type & N_TYPE)
03935 {
03936 case N_SETT:
03937 symsec = obj_textsec (input_bfd);
03938 break;
03939 case N_SETD:
03940 symsec = obj_datasec (input_bfd);
03941 break;
03942 case N_SETB:
03943 symsec = obj_bsssec (input_bfd);
03944 break;
03945 case N_SETA:
03946 symsec = bfd_abs_section_ptr;
03947 break;
03948 default:
03949 val = 0;
03950 break;
03951 }
03952 }
03953 else if (hresolve->root.type == bfd_link_hash_defined
03954 || hresolve->root.type == bfd_link_hash_defweak)
03955 {
03956 asection *input_section;
03957 asection *output_section;
03958
03959
03960
03961 input_section = hresolve->root.u.def.section;
03962 output_section = input_section->output_section;
03963 BFD_ASSERT (bfd_is_abs_section (output_section)
03964 || output_section->owner == output_bfd);
03965 val = (hresolve->root.u.def.value
03966 + bfd_get_section_vma (output_bfd, output_section)
03967 + input_section->output_offset);
03968
03969
03970
03971
03972 if (type == N_SETT
03973 || type == N_SETD
03974 || type == N_SETB
03975 || type == N_SETA)
03976 type |= N_EXT;
03977
03978 type &=~ N_TYPE;
03979
03980 if (output_section == obj_textsec (output_bfd))
03981 type |= (hresolve->root.type == bfd_link_hash_defined
03982 ? N_TEXT
03983 : N_WEAKT);
03984 else if (output_section == obj_datasec (output_bfd))
03985 type |= (hresolve->root.type == bfd_link_hash_defined
03986 ? N_DATA
03987 : N_WEAKD);
03988 else if (output_section == obj_bsssec (output_bfd))
03989 type |= (hresolve->root.type == bfd_link_hash_defined
03990 ? N_BSS
03991 : N_WEAKB);
03992 else
03993 type |= (hresolve->root.type == bfd_link_hash_defined
03994 ? N_ABS
03995 : N_WEAKA);
03996 }
03997 else if (hresolve->root.type == bfd_link_hash_common)
03998 val = hresolve->root.u.c.size;
03999 else if (hresolve->root.type == bfd_link_hash_undefweak)
04000 {
04001 val = 0;
04002 type = N_WEAKU;
04003 }
04004 else
04005 val = 0;
04006 }
04007 if (symsec != (asection *) NULL)
04008 val = (symsec->output_section->vma
04009 + symsec->output_offset
04010 + (GET_WORD (input_bfd, sym->e_value)
04011 - symsec->vma));
04012
04013
04014
04015 if (h != (struct aout_link_hash_entry *) NULL)
04016 {
04017 h->written = TRUE;
04018 h->indx = obj_aout_external_sym_count (output_bfd);
04019 }
04020 else if ((type & N_TYPE) != N_SETT
04021 && (type & N_TYPE) != N_SETD
04022 && (type & N_TYPE) != N_SETB
04023 && (type & N_TYPE) != N_SETA)
04024 {
04025 switch (discard)
04026 {
04027 case discard_none:
04028 case discard_sec_merge:
04029 break;
04030 case discard_l:
04031 if ((type & N_STAB) == 0
04032 && bfd_is_local_label_name (input_bfd, name))
04033 skip = TRUE;
04034 break;
04035 case discard_all:
04036 skip = TRUE;
04037 break;
04038 }
04039 if (skip)
04040 {
04041 pass = FALSE;
04042 continue;
04043 }
04044 }
04045
04046
04047
04048
04049
04050
04051
04052 if (type == N_BINCL)
04053 {
04054 struct external_nlist *incl_sym;
04055 int nest;
04056 struct aout_link_includes_entry *incl_entry;
04057 struct aout_link_includes_totals *t;
04058
04059 val = 0;
04060 nest = 0;
04061 for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
04062 {
04063 int incl_type;
04064
04065 incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
04066 if (incl_type == N_EINCL)
04067 {
04068 if (nest == 0)
04069 break;
04070 --nest;
04071 }
04072 else if (incl_type == N_BINCL)
04073 ++nest;
04074 else if (nest == 0)
04075 {
04076 const char *s;
04077
04078 s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
04079 for (; *s != '\0'; s++)
04080 {
04081 val += *s;
04082 if (*s == '(')
04083 {
04084
04085 ++s;
04086 while (ISDIGIT (*s))
04087 ++s;
04088 --s;
04089 }
04090 }
04091 }
04092 }
04093
04094
04095
04096
04097 copy = ! finfo->info->keep_memory;
04098 incl_entry = aout_link_includes_lookup (&finfo->includes,
04099 name, TRUE, copy);
04100 if (incl_entry == NULL)
04101 return FALSE;
04102 for (t = incl_entry->totals; t != NULL; t = t->next)
04103 if (t->total == val)
04104 break;
04105 if (t == NULL)
04106 {
04107
04108
04109 t = ((struct aout_link_includes_totals *)
04110 bfd_hash_allocate (&finfo->includes.root,
04111 sizeof *t));
04112 if (t == NULL)
04113 return FALSE;
04114 t->total = val;
04115 t->next = incl_entry->totals;
04116 incl_entry->totals = t;
04117 }
04118 else
04119 {
04120 int *incl_map;
04121
04122
04123
04124
04125 type = N_EXCL;
04126
04127 nest = 0;
04128 for (incl_sym = sym + 1, incl_map = symbol_map + 1;
04129 incl_sym < sym_end;
04130 incl_sym++, incl_map++)
04131 {
04132 int incl_type;
04133
04134 incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
04135 if (incl_type == N_EINCL)
04136 {
04137 if (nest == 0)
04138 {
04139 *incl_map = -1;
04140 break;
04141 }
04142 --nest;
04143 }
04144 else if (incl_type == N_BINCL)
04145 ++nest;
04146 else if (nest == 0)
04147 *incl_map = -1;
04148 }
04149 }
04150 }
04151 }
04152
04153
04154
04155 H_PUT_8 (output_bfd, type, outsym->e_type);
04156 copy = FALSE;
04157 if (! finfo->info->keep_memory)
04158 {
04159
04160
04161
04162 if (h != (struct aout_link_hash_entry *) NULL)
04163 name = h->root.root.string;
04164 else
04165 copy = TRUE;
04166 }
04167 strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
04168 name, copy);
04169 if (strtab_index == (bfd_size_type) -1)
04170 return FALSE;
04171 PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
04172 PUT_WORD (output_bfd, val, outsym->e_value);
04173 *symbol_map = obj_aout_external_sym_count (output_bfd);
04174 ++obj_aout_external_sym_count (output_bfd);
04175 ++outsym;
04176 }
04177
04178
04179 if (outsym > finfo->output_syms)
04180 {
04181 bfd_size_type size;
04182
04183 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
04184 return FALSE;
04185 size = outsym - finfo->output_syms;
04186 size *= EXTERNAL_NLIST_SIZE;
04187 if (bfd_bwrite ((PTR) finfo->output_syms, size, output_bfd) != size)
04188 return FALSE;
04189 finfo->symoff += size;
04190 }
04191
04192 return TRUE;
04193 }
04194
04195
04196
04197
04198 static bfd_boolean
04199 aout_link_write_other_symbol (h, data)
04200 struct aout_link_hash_entry *h;
04201 PTR data;
04202 {
04203 struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
04204 bfd *output_bfd;
04205 int type;
04206 bfd_vma val;
04207 struct external_nlist outsym;
04208 bfd_size_type indx;
04209 bfd_size_type amt;
04210
04211 if (h->root.type == bfd_link_hash_warning)
04212 {
04213 h = (struct aout_link_hash_entry *) h->root.u.i.link;
04214 if (h->root.type == bfd_link_hash_new)
04215 return TRUE;
04216 }
04217
04218 output_bfd = finfo->output_bfd;
04219
04220 if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
04221 {
04222 if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
04223 (output_bfd, finfo->info, h)))
04224 {
04225
04226 abort ();
04227 }
04228 }
04229
04230 if (h->written)
04231 return TRUE;
04232
04233 h->written = TRUE;
04234
04235
04236 if (h->indx != -2
04237 && (finfo->info->strip == strip_all
04238 || (finfo->info->strip == strip_some
04239 && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
04240 FALSE, FALSE) == NULL)))
04241 return TRUE;
04242
04243 switch (h->root.type)
04244 {
04245 default:
04246 abort ();
04247
04248 return TRUE;
04249 case bfd_link_hash_new:
04250
04251
04252 return TRUE;
04253 case bfd_link_hash_undefined:
04254 type = N_UNDF | N_EXT;
04255 val = 0;
04256 break;
04257 case bfd_link_hash_defined:
04258 case bfd_link_hash_defweak:
04259 {
04260 asection *sec;
04261
04262 sec = h->root.u.def.section->output_section;
04263 BFD_ASSERT (bfd_is_abs_section (sec)
04264 || sec->owner == output_bfd);
04265 if (sec == obj_textsec (output_bfd))
04266 type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
04267 else if (sec == obj_datasec (output_bfd))
04268 type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
04269 else if (sec == obj_bsssec (output_bfd))
04270 type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
04271 else
04272 type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
04273 type |= N_EXT;
04274 val = (h->root.u.def.value
04275 + sec->vma
04276 + h->root.u.def.section->output_offset);
04277 }
04278 break;
04279 case bfd_link_hash_common:
04280 type = N_UNDF | N_EXT;
04281 val = h->root.u.c.size;
04282 break;
04283 case bfd_link_hash_undefweak:
04284 type = N_WEAKU;
04285 val = 0;
04286 case bfd_link_hash_indirect:
04287 case bfd_link_hash_warning:
04288
04289
04290 return TRUE;
04291 }
04292
04293 H_PUT_8 (output_bfd, type, outsym.e_type);
04294 indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
04295 FALSE);
04296 if (indx == (bfd_size_type) -1)
04297 {
04298
04299 abort ();
04300 }
04301 PUT_WORD (output_bfd, indx, outsym.e_strx);
04302 PUT_WORD (output_bfd, val, outsym.e_value);
04303
04304 amt = EXTERNAL_NLIST_SIZE;
04305 if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
04306 || bfd_bwrite ((PTR) &outsym, amt, output_bfd) != amt)
04307 {
04308
04309 abort ();
04310 }
04311
04312 finfo->symoff += amt;
04313 h->indx = obj_aout_external_sym_count (output_bfd);
04314 ++obj_aout_external_sym_count (output_bfd);
04315
04316 return TRUE;
04317 }
04318
04319
04320
04321 static bfd_boolean
04322 aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
04323 rel_size)
04324 struct aout_final_link_info *finfo;
04325 bfd *input_bfd;
04326 asection *input_section;
04327 file_ptr *reloff_ptr;
04328 bfd_size_type rel_size;
04329 {
04330 bfd_size_type input_size;
04331 PTR relocs;
04332
04333
04334 input_size = input_section->size;
04335 if (! bfd_get_section_contents (input_bfd, input_section,
04336 (PTR) finfo->contents,
04337 (file_ptr) 0, input_size))
04338 return FALSE;
04339
04340
04341 if (aout_section_data (input_section) != NULL
04342 && aout_section_data (input_section)->relocs != NULL)
04343 relocs = aout_section_data (input_section)->relocs;
04344 else
04345 {
04346 relocs = finfo->relocs;
04347 if (rel_size > 0)
04348 {
04349 if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
04350 || bfd_bread (relocs, rel_size, input_bfd) != rel_size)
04351 return FALSE;
04352 }
04353 }
04354
04355
04356 if (! pdp11_aout_link_input_section (finfo, input_bfd, input_section,
04357 (bfd_byte *) relocs,
04358 rel_size, finfo->contents))
04359 return FALSE;
04360
04361
04362 if (! bfd_set_section_contents (finfo->output_bfd,
04363 input_section->output_section,
04364 (PTR) finfo->contents,
04365 (file_ptr) input_section->output_offset,
04366 input_size))
04367 return FALSE;
04368
04369
04370
04371 if (finfo->info->relocatable && rel_size > 0)
04372 {
04373 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
04374 return FALSE;
04375 if (bfd_bwrite (relocs, rel_size, finfo->output_bfd) != rel_size)
04376 return FALSE;
04377 *reloff_ptr += rel_size;
04378
04379
04380
04381
04382 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
04383 && (reloff_ptr != &finfo->treloff
04384 || (*reloff_ptr
04385 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
04386 }
04387
04388 return TRUE;
04389 }
04390
04391
04392
04393 static INLINE asection *
04394 aout_reloc_type_to_section (abfd, type)
04395 bfd *abfd;
04396 int type;
04397 {
04398 switch (type)
04399 {
04400 case RTEXT:
04401 return obj_textsec (abfd);
04402 case RDATA:
04403 return obj_datasec (abfd);
04404 case RBSS:
04405 return obj_bsssec (abfd);
04406 case RABS:
04407 return bfd_abs_section_ptr;
04408 case REXT:
04409 return bfd_und_section_ptr;
04410 default:
04411 abort ();
04412 }
04413 }
04414
04415 static bfd_boolean
04416 pdp11_aout_link_input_section (finfo, input_bfd, input_section, relocs,
04417 rel_size, contents)
04418 struct aout_final_link_info *finfo;
04419 bfd *input_bfd;
04420 asection *input_section;
04421 bfd_byte *relocs;
04422 bfd_size_type rel_size;
04423 bfd_byte *contents;
04424 {
04425 bfd_boolean (*check_dynamic_reloc)
04426 PARAMS ((struct bfd_link_info *, bfd *, asection *,
04427 struct aout_link_hash_entry *, PTR, bfd_byte *, bfd_boolean *,
04428 bfd_vma *));
04429 bfd *output_bfd;
04430 bfd_boolean relocatable;
04431 struct external_nlist *syms;
04432 char *strings;
04433 struct aout_link_hash_entry **sym_hashes;
04434 int *symbol_map;
04435 bfd_size_type reloc_count;
04436 bfd_byte *rel;
04437 bfd_byte *rel_end;
04438
04439 output_bfd = finfo->output_bfd;
04440 check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
04441
04442 BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_SIZE);
04443 BFD_ASSERT (input_bfd->xvec->header_byteorder
04444 == output_bfd->xvec->header_byteorder);
04445
04446 relocatable = finfo->info->relocatable;
04447 syms = obj_aout_external_syms (input_bfd);
04448 strings = obj_aout_external_strings (input_bfd);
04449 sym_hashes = obj_aout_sym_hashes (input_bfd);
04450 symbol_map = finfo->symbol_map;
04451
04452 reloc_count = rel_size / RELOC_SIZE;
04453 rel = relocs;
04454 rel_end = rel + rel_size;
04455 for (; rel < rel_end; rel += RELOC_SIZE)
04456 {
04457 bfd_vma r_addr;
04458 int r_index;
04459 int r_type;
04460 int r_pcrel;
04461 int r_extern;
04462 reloc_howto_type *howto;
04463 struct aout_link_hash_entry *h = NULL;
04464 bfd_vma relocation;
04465 bfd_reloc_status_type r;
04466 int reloc_entry;
04467
04468 reloc_entry = GET_WORD (input_bfd, (PTR)rel);
04469 if (reloc_entry == 0)
04470 continue;
04471
04472 {
04473 unsigned int howto_idx;
04474
04475 r_index = (reloc_entry & RIDXMASK) >> 4;
04476 r_type = reloc_entry & RTYPE;
04477 r_pcrel = reloc_entry & RELFLG;
04478 r_addr = (char *)rel - (char *)relocs;
04479
04480 r_extern = (r_type == REXT);
04481
04482 howto_idx = r_pcrel;
04483 BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_pdp11));
04484 howto = howto_table_pdp11 + howto_idx;
04485 }
04486
04487 if (relocatable)
04488 {
04489
04490
04491 if (r_extern)
04492 {
04493
04494
04495
04496 h = sym_hashes[r_index];
04497 if (h != (struct aout_link_hash_entry *) NULL
04498 && (h->root.type == bfd_link_hash_defined
04499 || h->root.type == bfd_link_hash_defweak))
04500 {
04501 asection *output_section;
04502
04503
04504 output_section = h->root.u.def.section->output_section;
04505 if (output_section == obj_textsec (output_bfd))
04506 r_type = N_TEXT;
04507 else if (output_section == obj_datasec (output_bfd))
04508 r_type = N_DATA;
04509 else if (output_section == obj_bsssec (output_bfd))
04510 r_type = N_BSS;
04511 else
04512 r_type = N_ABS;
04513
04514
04515
04516 relocation = (h->root.u.def.value
04517 + output_section->vma
04518 + h->root.u.def.section->output_offset);
04519 }
04520 else
04521 {
04522
04523
04524 r_index = symbol_map[r_index];
04525
04526 if (r_index == -1)
04527 {
04528 if (h != NULL)
04529 {
04530
04531
04532
04533
04534
04535 if (h->indx < 0)
04536 {
04537 h->indx = -2;
04538 h->written = FALSE;
04539 if (! aout_link_write_other_symbol (h,
04540 (PTR) finfo))
04541 return FALSE;
04542 }
04543 r_index = h->indx;
04544 }
04545 else
04546 {
04547 const char *name;
04548
04549 name = strings + GET_WORD (input_bfd,
04550 syms[r_index].e_strx);
04551 if (! ((*finfo->info->callbacks->unattached_reloc)
04552 (finfo->info, name, input_bfd, input_section,
04553 r_addr)))
04554 return FALSE;
04555 r_index = 0;
04556 }
04557 }
04558
04559 relocation = 0;
04560 }
04561
04562
04563 reloc_entry = GET_WORD (input_bfd, rel);
04564 reloc_entry &= RIDXMASK;
04565 reloc_entry |= r_index << 4;
04566 PUT_WORD (input_bfd, reloc_entry, rel);
04567 }
04568 else
04569 {
04570 asection *section;
04571
04572
04573
04574 section = aout_reloc_type_to_section (input_bfd, r_type);
04575 relocation = (section->output_section->vma
04576 + section->output_offset
04577 - section->vma);
04578 }
04579
04580
04581 fprintf (stderr, "TODO: change the address of the relocation\n");
04582
04583
04584
04585
04586 if (r_pcrel)
04587 relocation -= (input_section->output_section->vma
04588 + input_section->output_offset
04589 - input_section->vma);
04590
04591 #ifdef MY_relocatable_reloc
04592 MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
04593 #endif
04594
04595 if (relocation == 0)
04596 r = bfd_reloc_ok;
04597 else
04598 r = MY_relocate_contents (howto,
04599 input_bfd, relocation,
04600 contents + r_addr);
04601 }
04602 else
04603 {
04604 bfd_boolean hundef;
04605
04606
04607
04608 hundef = FALSE;
04609 if (r_extern)
04610 {
04611 h = sym_hashes[r_index];
04612
04613 if (h != (struct aout_link_hash_entry *) NULL
04614 && (h->root.type == bfd_link_hash_defined
04615 || h->root.type == bfd_link_hash_defweak))
04616 {
04617 relocation = (h->root.u.def.value
04618 + h->root.u.def.section->output_section->vma
04619 + h->root.u.def.section->output_offset);
04620 }
04621 else if (h != (struct aout_link_hash_entry *) NULL
04622 && h->root.type == bfd_link_hash_undefweak)
04623 relocation = 0;
04624 else
04625 {
04626 hundef = TRUE;
04627 relocation = 0;
04628 }
04629 }
04630 else
04631 {
04632 asection *section;
04633
04634 section = aout_reloc_type_to_section (input_bfd, r_type);
04635 relocation = (section->output_section->vma
04636 + section->output_offset
04637 - section->vma);
04638 if (r_pcrel)
04639 relocation += input_section->vma;
04640 }
04641
04642 if (check_dynamic_reloc != NULL)
04643 {
04644 bfd_boolean skip;
04645
04646 if (! ((*check_dynamic_reloc)
04647 (finfo->info, input_bfd, input_section, h,
04648 (PTR) rel, contents, &skip, &relocation)))
04649 return FALSE;
04650 if (skip)
04651 continue;
04652 }
04653
04654
04655
04656
04657 if (hundef && ! finfo->info->shared)
04658 {
04659 const char *name;
04660
04661 if (h != NULL)
04662 name = h->root.root.string;
04663 else
04664 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
04665 if (! ((*finfo->info->callbacks->undefined_symbol)
04666 (finfo->info, name, input_bfd, input_section,
04667 r_addr, TRUE)))
04668 return FALSE;
04669 }
04670
04671 r = MY_final_link_relocate (howto,
04672 input_bfd, input_section,
04673 contents, r_addr, relocation,
04674 (bfd_vma) 0);
04675 }
04676
04677 if (r != bfd_reloc_ok)
04678 {
04679 switch (r)
04680 {
04681 default:
04682 case bfd_reloc_outofrange:
04683 abort ();
04684 case bfd_reloc_overflow:
04685 {
04686 const char *name;
04687
04688 if (h != NULL)
04689 name = NULL;
04690 else if (r_extern)
04691 name = strings + GET_WORD (input_bfd,
04692 syms[r_index].e_strx);
04693 else
04694 {
04695 asection *s;
04696
04697 s = aout_reloc_type_to_section (input_bfd, r_type);
04698 name = bfd_section_name (input_bfd, s);
04699 }
04700 if (! ((*finfo->info->callbacks->reloc_overflow)
04701 (finfo->info, (h ? &h->root : NULL), name,
04702 howto->name, (bfd_vma) 0, input_bfd,
04703 input_section, r_addr)))
04704 return FALSE;
04705 }
04706 break;
04707 }
04708 }
04709 }
04710
04711 return TRUE;
04712 }
04713
04714
04715
04716 static bfd_boolean
04717 aout_link_reloc_link_order (finfo, o, p)
04718 struct aout_final_link_info *finfo;
04719 asection *o;
04720 struct bfd_link_order *p;
04721 {
04722 struct bfd_link_order_reloc *pr;
04723 int r_index;
04724 int r_extern;
04725 reloc_howto_type *howto;
04726 file_ptr *reloff_ptr;
04727 struct reloc_std_external srel;
04728 PTR rel_ptr;
04729 bfd_size_type rel_size;
04730
04731 pr = p->u.reloc.p;
04732
04733 if (p->type == bfd_section_reloc_link_order)
04734 {
04735 r_extern = 0;
04736 if (bfd_is_abs_section (pr->u.section))
04737 r_index = N_ABS | N_EXT;
04738 else
04739 {
04740 BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
04741 r_index = pr->u.section->target_index;
04742 }
04743 }
04744 else
04745 {
04746 struct aout_link_hash_entry *h;
04747
04748 BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
04749 r_extern = 1;
04750 h = ((struct aout_link_hash_entry *)
04751 bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
04752 pr->u.name, FALSE, FALSE, TRUE));
04753 if (h != (struct aout_link_hash_entry *) NULL
04754 && h->indx >= 0)
04755 r_index = h->indx;
04756 else if (h != NULL)
04757 {
04758
04759
04760
04761
04762 h->indx = -2;
04763 h->written = FALSE;
04764 if (! aout_link_write_other_symbol (h, (PTR) finfo))
04765 return FALSE;
04766 r_index = h->indx;
04767 }
04768 else
04769 {
04770 if (! ((*finfo->info->callbacks->unattached_reloc)
04771 (finfo->info, pr->u.name, (bfd *) NULL,
04772 (asection *) NULL, (bfd_vma) 0)))
04773 return FALSE;
04774 r_index = 0;
04775 }
04776 }
04777
04778 howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
04779 if (howto == 0)
04780 {
04781 bfd_set_error (bfd_error_bad_value);
04782 return FALSE;
04783 }
04784
04785 if (o == obj_textsec (finfo->output_bfd))
04786 reloff_ptr = &finfo->treloff;
04787 else if (o == obj_datasec (finfo->output_bfd))
04788 reloff_ptr = &finfo->dreloff;
04789 else
04790 abort ();
04791
04792 #ifdef MY_put_reloc
04793 MY_put_reloc(finfo->output_bfd, r_extern, r_index, p->offset, howto,
04794 &srel);
04795 #else
04796 {
04797 int r_pcrel;
04798 int r_baserel;
04799 int r_jmptable;
04800 int r_relative;
04801 int r_length;
04802
04803 fprintf (stderr, "TODO: line %d in bfd/pdp11.c\n", __LINE__);
04804
04805 r_pcrel = howto->pc_relative;
04806 r_baserel = (howto->type & 8) != 0;
04807 r_jmptable = (howto->type & 16) != 0;
04808 r_relative = (howto->type & 32) != 0;
04809 r_length = howto->size;
04810
04811 PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
04812 if (bfd_header_big_endian (finfo->output_bfd))
04813 {
04814 srel.r_index[0] = r_index >> 16;
04815 srel.r_index[1] = r_index >> 8;
04816 srel.r_index[2] = r_index;
04817 srel.r_type[0] =
04818 ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
04819 | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
04820 | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
04821 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
04822 | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
04823 | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
04824 }
04825 else
04826 {
04827 srel.r_index[2] = r_index >> 16;
04828 srel.r_index[1] = r_index >> 8;
04829 srel.r_index[0] = r_index;
04830 srel.r_type[0] =
04831 ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
04832 | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
04833 | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
04834 | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
04835 | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
04836 | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
04837 }
04838 }
04839 #endif
04840 rel_ptr = (PTR) &srel;
04841
04842
04843
04844
04845
04846
04847 if (pr->addend != 0)
04848 {
04849 bfd_size_type size;
04850 bfd_reloc_status_type r;
04851 bfd_byte *buf;
04852 bfd_boolean ok;
04853
04854 size = bfd_get_reloc_size (howto);
04855 buf = (bfd_byte *) bfd_zmalloc (size);
04856 if (buf == (bfd_byte *) NULL)
04857 return FALSE;
04858 r = MY_relocate_contents (howto, finfo->output_bfd,
04859 pr->addend, buf);
04860 switch (r)
04861 {
04862 case bfd_reloc_ok:
04863 break;
04864 default:
04865 case bfd_reloc_outofrange:
04866 abort ();
04867 case bfd_reloc_overflow:
04868 if (! ((*finfo->info->callbacks->reloc_overflow)
04869 (finfo->info, NULL,
04870 (p->type == bfd_section_reloc_link_order
04871 ? bfd_section_name (finfo->output_bfd,
04872 pr->u.section)
04873 : pr->u.name),
04874 howto->name, pr->addend, (bfd *) NULL,
04875 (asection *) NULL, (bfd_vma) 0)))
04876 {
04877 free (buf);
04878 return FALSE;
04879 }
04880 break;
04881 }
04882 ok = bfd_set_section_contents (finfo->output_bfd, o,
04883 (PTR) buf,
04884 (file_ptr) p->offset,
04885 size);
04886 free (buf);
04887 if (! ok)
04888 return FALSE;
04889 }
04890
04891 rel_size = obj_reloc_entry_size (finfo->output_bfd);
04892 if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
04893 || bfd_bwrite (rel_ptr, rel_size, finfo->output_bfd) != rel_size)
04894 return FALSE;
04895
04896 *reloff_ptr += rel_size;
04897
04898
04899
04900 BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
04901 && (reloff_ptr != &finfo->treloff
04902 || (*reloff_ptr
04903 <= obj_datasec (finfo->output_bfd)->rel_filepos)));
04904
04905 return TRUE;
04906 }
04907
04908
04909 static bfd_vma
04910 bfd_getp32 (const void *p)
04911 {
04912 const bfd_byte *addr = p;
04913 unsigned long v;
04914 v = (unsigned long) addr[1] << 24;
04915 v |= (unsigned long) addr[0] << 16;
04916 v |= (unsigned long) addr[3] << 8;
04917 v |= (unsigned long) addr[2];
04918 return v;
04919 }
04920
04921 #define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000)
04922
04923 static bfd_signed_vma
04924 bfd_getp_signed_32 (const void *p)
04925 {
04926 const bfd_byte *addr = p;
04927 unsigned long v;
04928 v = (unsigned long) addr[1] << 24;
04929 v |= (unsigned long) addr[0] << 16;
04930 v |= (unsigned long) addr[3] << 8;
04931 v |= (unsigned long) addr[2];
04932 return COERCE32 (v);
04933 }
04934
04935 static void
04936 bfd_putp32 (bfd_vma data, void *p)
04937 {
04938 bfd_byte *addr = p;
04939 addr[0] = (data >> 16) & 0xff;
04940 addr[1] = (data >> 24) & 0xff;
04941 addr[2] = (data >> 0) & 0xff;
04942 addr[3] = (data >> 8) & 0xff;
04943 }