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