00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "bfd.h"
00028 #include "sysdep.h"
00029 #include "bfdlink.h"
00030 #include "libbfd.h"
00031 #include "aout/ar.h"
00032 #include "aout/ranlib.h"
00033 #include "aout/stab_gnu.h"
00034
00035
00036
00037
00038 #include "libaout.h"
00039 #include "aout/aout64.h"
00040 #undef N_ABS
00041 #undef exec_hdr
00042 #undef obj_sym_filepos
00043
00044 #include "coff/internal.h"
00045 #include "coff/sym.h"
00046 #include "coff/symconst.h"
00047 #include "coff/ecoff.h"
00048 #include "libcoff.h"
00049 #include "libecoff.h"
00050
00051
00052
00053 static int ecoff_get_magic
00054 PARAMS ((bfd *));
00055 static long ecoff_sec_to_styp_flags
00056 PARAMS ((const char *, flagword));
00057 static bfd_boolean ecoff_slurp_symbolic_header
00058 PARAMS ((bfd *));
00059 static bfd_boolean ecoff_set_symbol_info
00060 PARAMS ((bfd *, SYMR *, asymbol *, int, int));
00061 static void ecoff_emit_aggregate
00062 PARAMS ((bfd *, FDR *, char *, RNDXR *, long, const char *));
00063 static char *ecoff_type_to_string
00064 PARAMS ((bfd *, FDR *, unsigned int));
00065 static bfd_boolean ecoff_slurp_reloc_table
00066 PARAMS ((bfd *, asection *, asymbol **));
00067 static int ecoff_sort_hdrs
00068 PARAMS ((const PTR, const PTR));
00069 static bfd_boolean ecoff_compute_section_file_positions
00070 PARAMS ((bfd *));
00071 static bfd_size_type ecoff_compute_reloc_file_positions
00072 PARAMS ((bfd *));
00073 static bfd_boolean ecoff_get_extr
00074 PARAMS ((asymbol *, EXTR *));
00075 static void ecoff_set_index
00076 PARAMS ((asymbol *, bfd_size_type));
00077 static unsigned int ecoff_armap_hash
00078 PARAMS ((const char *, unsigned int *, unsigned int, unsigned int));
00079
00080
00081 static asection bfd_debug_section =
00082 {
00083
00084 "*DEBUG*", 0, 0, NULL, 0, 0,
00085
00086 0, 0, 0, 0,
00087
00088 0, 0, 0, 0,
00089
00090 0, 0,
00091
00092 0, 0, 0, 0,
00093
00094 0, NULL, 0,
00095
00096 NULL, NULL, 0, 0, 0,
00097
00098 0, NULL, NULL, NULL, 0,
00099
00100 0, NULL, 0,
00101
00102 0, NULL, NULL, NULL,
00103
00104 (struct bfd_symbol *) NULL,
00105
00106 (struct bfd_symbol **) NULL,
00107
00108 NULL, NULL
00109 };
00110
00111
00112
00113 bfd_boolean
00114 _bfd_ecoff_mkobject (abfd)
00115 bfd *abfd;
00116 {
00117 bfd_size_type amt = sizeof (ecoff_data_type);
00118
00119 abfd->tdata.ecoff_obj_data = (struct ecoff_tdata *) bfd_zalloc (abfd, amt);
00120 if (abfd->tdata.ecoff_obj_data == NULL)
00121 return FALSE;
00122
00123 return TRUE;
00124 }
00125
00126
00127
00128
00129 PTR
00130 _bfd_ecoff_mkobject_hook (abfd, filehdr, aouthdr)
00131 bfd *abfd;
00132 PTR filehdr;
00133 PTR aouthdr;
00134 {
00135 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
00136 struct internal_aouthdr *internal_a = (struct internal_aouthdr *) aouthdr;
00137 ecoff_data_type *ecoff;
00138
00139 if (! _bfd_ecoff_mkobject (abfd))
00140 return NULL;
00141
00142 ecoff = ecoff_data (abfd);
00143 ecoff->gp_size = 8;
00144 ecoff->sym_filepos = internal_f->f_symptr;
00145
00146 if (internal_a != (struct internal_aouthdr *) NULL)
00147 {
00148 int i;
00149
00150 ecoff->text_start = internal_a->text_start;
00151 ecoff->text_end = internal_a->text_start + internal_a->tsize;
00152 ecoff->gp = internal_a->gp_value;
00153 ecoff->gprmask = internal_a->gprmask;
00154 for (i = 0; i < 4; i++)
00155 ecoff->cprmask[i] = internal_a->cprmask[i];
00156 ecoff->fprmask = internal_a->fprmask;
00157 if (internal_a->magic == ECOFF_AOUT_ZMAGIC)
00158 abfd->flags |= D_PAGED;
00159 else
00160 abfd->flags &=~ D_PAGED;
00161 }
00162
00163
00164
00165
00166
00167
00168
00169 return (PTR) ecoff;
00170 }
00171
00172
00173
00174 bfd_boolean
00175 _bfd_ecoff_new_section_hook (abfd, section)
00176 bfd *abfd ATTRIBUTE_UNUSED;
00177 asection *section;
00178 {
00179 section->alignment_power = 4;
00180
00181 if (strcmp (section->name, _TEXT) == 0
00182 || strcmp (section->name, _INIT) == 0
00183 || strcmp (section->name, _FINI) == 0)
00184 section->flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC;
00185 else if (strcmp (section->name, _DATA) == 0
00186 || strcmp (section->name, _SDATA) == 0)
00187 section->flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC;
00188 else if (strcmp (section->name, _RDATA) == 0
00189 || strcmp (section->name, _LIT8) == 0
00190 || strcmp (section->name, _LIT4) == 0
00191 || strcmp (section->name, _RCONST) == 0
00192 || strcmp (section->name, _PDATA) == 0)
00193 section->flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY;
00194 else if (strcmp (section->name, _BSS) == 0
00195 || strcmp (section->name, _SBSS) == 0)
00196 section->flags |= SEC_ALLOC;
00197 else if (strcmp (section->name, _LIB) == 0)
00198
00199 section->flags |= SEC_COFF_SHARED_LIBRARY;
00200
00201
00202
00203
00204
00205 return TRUE;
00206 }
00207
00208
00209
00210
00211
00212
00213 bfd_boolean
00214 _bfd_ecoff_set_arch_mach_hook (abfd, filehdr)
00215 bfd *abfd;
00216 PTR filehdr;
00217 {
00218 struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
00219 enum bfd_architecture arch;
00220 unsigned long mach;
00221
00222 switch (internal_f->f_magic)
00223 {
00224 case MIPS_MAGIC_1:
00225 case MIPS_MAGIC_LITTLE:
00226 case MIPS_MAGIC_BIG:
00227 arch = bfd_arch_mips;
00228 mach = bfd_mach_mips3000;
00229 break;
00230
00231 case MIPS_MAGIC_LITTLE2:
00232 case MIPS_MAGIC_BIG2:
00233
00234 arch = bfd_arch_mips;
00235 mach = bfd_mach_mips6000;
00236 break;
00237
00238 case MIPS_MAGIC_LITTLE3:
00239 case MIPS_MAGIC_BIG3:
00240
00241 arch = bfd_arch_mips;
00242 mach = bfd_mach_mips4000;
00243 break;
00244
00245 case ALPHA_MAGIC:
00246 arch = bfd_arch_alpha;
00247 mach = 0;
00248 break;
00249
00250 default:
00251 arch = bfd_arch_obscure;
00252 mach = 0;
00253 break;
00254 }
00255
00256 return bfd_default_set_arch_mach (abfd, arch, mach);
00257 }
00258
00259
00260
00261
00262 static int
00263 ecoff_get_magic (abfd)
00264 bfd *abfd;
00265 {
00266 int big, little;
00267
00268 switch (bfd_get_arch (abfd))
00269 {
00270 case bfd_arch_mips:
00271 switch (bfd_get_mach (abfd))
00272 {
00273 default:
00274 case 0:
00275 case bfd_mach_mips3000:
00276 big = MIPS_MAGIC_BIG;
00277 little = MIPS_MAGIC_LITTLE;
00278 break;
00279
00280 case bfd_mach_mips6000:
00281 big = MIPS_MAGIC_BIG2;
00282 little = MIPS_MAGIC_LITTLE2;
00283 break;
00284
00285 case bfd_mach_mips4000:
00286 big = MIPS_MAGIC_BIG3;
00287 little = MIPS_MAGIC_LITTLE3;
00288 break;
00289 }
00290
00291 return bfd_big_endian (abfd) ? big : little;
00292
00293 case bfd_arch_alpha:
00294 return ALPHA_MAGIC;
00295
00296 default:
00297 abort ();
00298 return 0;
00299 }
00300 }
00301
00302
00303
00304 static long
00305 ecoff_sec_to_styp_flags (name, flags)
00306 const char *name;
00307 flagword flags;
00308 {
00309 long styp;
00310
00311 styp = 0;
00312
00313 if (strcmp (name, _TEXT) == 0)
00314 styp = STYP_TEXT;
00315 else if (strcmp (name, _DATA) == 0)
00316 styp = STYP_DATA;
00317 else if (strcmp (name, _SDATA) == 0)
00318 styp = STYP_SDATA;
00319 else if (strcmp (name, _RDATA) == 0)
00320 styp = STYP_RDATA;
00321 else if (strcmp (name, _LITA) == 0)
00322 styp = STYP_LITA;
00323 else if (strcmp (name, _LIT8) == 0)
00324 styp = STYP_LIT8;
00325 else if (strcmp (name, _LIT4) == 0)
00326 styp = STYP_LIT4;
00327 else if (strcmp (name, _BSS) == 0)
00328 styp = STYP_BSS;
00329 else if (strcmp (name, _SBSS) == 0)
00330 styp = STYP_SBSS;
00331 else if (strcmp (name, _INIT) == 0)
00332 styp = STYP_ECOFF_INIT;
00333 else if (strcmp (name, _FINI) == 0)
00334 styp = STYP_ECOFF_FINI;
00335 else if (strcmp (name, _PDATA) == 0)
00336 styp = STYP_PDATA;
00337 else if (strcmp (name, _XDATA) == 0)
00338 styp = STYP_XDATA;
00339 else if (strcmp (name, _LIB) == 0)
00340 styp = STYP_ECOFF_LIB;
00341 else if (strcmp (name, _GOT) == 0)
00342 styp = STYP_GOT;
00343 else if (strcmp (name, _HASH) == 0)
00344 styp = STYP_HASH;
00345 else if (strcmp (name, _DYNAMIC) == 0)
00346 styp = STYP_DYNAMIC;
00347 else if (strcmp (name, _LIBLIST) == 0)
00348 styp = STYP_LIBLIST;
00349 else if (strcmp (name, _RELDYN) == 0)
00350 styp = STYP_RELDYN;
00351 else if (strcmp (name, _CONFLIC) == 0)
00352 styp = STYP_CONFLIC;
00353 else if (strcmp (name, _DYNSTR) == 0)
00354 styp = STYP_DYNSTR;
00355 else if (strcmp (name, _DYNSYM) == 0)
00356 styp = STYP_DYNSYM;
00357 else if (strcmp (name, _COMMENT) == 0)
00358 {
00359 styp = STYP_COMMENT;
00360 flags &=~ SEC_NEVER_LOAD;
00361 }
00362 else if (strcmp (name, _RCONST) == 0)
00363 styp = STYP_RCONST;
00364 else if (flags & SEC_CODE)
00365 styp = STYP_TEXT;
00366 else if (flags & SEC_DATA)
00367 styp = STYP_DATA;
00368 else if (flags & SEC_READONLY)
00369 styp = STYP_RDATA;
00370 else if (flags & SEC_LOAD)
00371 styp = STYP_REG;
00372 else
00373 styp = STYP_BSS;
00374
00375 if (flags & SEC_NEVER_LOAD)
00376 styp |= STYP_NOLOAD;
00377
00378 return styp;
00379 }
00380
00381
00382
00383 bfd_boolean
00384 _bfd_ecoff_styp_to_sec_flags (abfd, hdr, name, section, flags_ptr)
00385 bfd *abfd ATTRIBUTE_UNUSED;
00386 PTR hdr;
00387 const char *name ATTRIBUTE_UNUSED;
00388 asection *section ATTRIBUTE_UNUSED;
00389 flagword * flags_ptr;
00390 {
00391 struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
00392 long styp_flags = internal_s->s_flags;
00393 flagword sec_flags = 0;
00394
00395 if (styp_flags & STYP_NOLOAD)
00396 sec_flags |= SEC_NEVER_LOAD;
00397
00398
00399
00400 if ((styp_flags & STYP_TEXT)
00401 || (styp_flags & STYP_ECOFF_INIT)
00402 || (styp_flags & STYP_ECOFF_FINI)
00403 || (styp_flags & STYP_DYNAMIC)
00404 || (styp_flags & STYP_LIBLIST)
00405 || (styp_flags & STYP_RELDYN)
00406 || styp_flags == STYP_CONFLIC
00407 || (styp_flags & STYP_DYNSTR)
00408 || (styp_flags & STYP_DYNSYM)
00409 || (styp_flags & STYP_HASH))
00410 {
00411 if (sec_flags & SEC_NEVER_LOAD)
00412 sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY;
00413 else
00414 sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC;
00415 }
00416 else if ((styp_flags & STYP_DATA)
00417 || (styp_flags & STYP_RDATA)
00418 || (styp_flags & STYP_SDATA)
00419 || styp_flags == STYP_PDATA
00420 || styp_flags == STYP_XDATA
00421 || (styp_flags & STYP_GOT)
00422 || styp_flags == STYP_RCONST)
00423 {
00424 if (sec_flags & SEC_NEVER_LOAD)
00425 sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY;
00426 else
00427 sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC;
00428 if ((styp_flags & STYP_RDATA)
00429 || styp_flags == STYP_PDATA
00430 || styp_flags == STYP_RCONST)
00431 sec_flags |= SEC_READONLY;
00432 }
00433 else if ((styp_flags & STYP_BSS)
00434 || (styp_flags & STYP_SBSS))
00435 sec_flags |= SEC_ALLOC;
00436 else if ((styp_flags & STYP_INFO) || styp_flags == STYP_COMMENT)
00437 sec_flags |= SEC_NEVER_LOAD;
00438 else if ((styp_flags & STYP_LITA)
00439 || (styp_flags & STYP_LIT8)
00440 || (styp_flags & STYP_LIT4))
00441 sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY;
00442 else if (styp_flags & STYP_ECOFF_LIB)
00443 sec_flags |= SEC_COFF_SHARED_LIBRARY;
00444 else
00445 sec_flags |= SEC_ALLOC | SEC_LOAD;
00446
00447 * flags_ptr = sec_flags;
00448 return TRUE;
00449 }
00450
00451
00452
00453 static bfd_boolean
00454 ecoff_slurp_symbolic_header (abfd)
00455 bfd *abfd;
00456 {
00457 const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
00458 bfd_size_type external_hdr_size;
00459 PTR raw = NULL;
00460 HDRR *internal_symhdr;
00461
00462
00463 if (ecoff_data (abfd)->debug_info.symbolic_header.magic ==
00464 backend->debug_swap.sym_magic)
00465 return TRUE;
00466
00467
00468 if (ecoff_data (abfd)->sym_filepos == 0)
00469 {
00470 bfd_get_symcount (abfd) = 0;
00471 return TRUE;
00472 }
00473
00474
00475
00476
00477
00478 external_hdr_size = backend->debug_swap.external_hdr_size;
00479 if (bfd_get_symcount (abfd) != external_hdr_size)
00480 {
00481 bfd_set_error (bfd_error_bad_value);
00482 return FALSE;
00483 }
00484
00485
00486 raw = (PTR) bfd_malloc (external_hdr_size);
00487 if (raw == NULL)
00488 goto error_return;
00489
00490 if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) != 0
00491 || bfd_bread (raw, external_hdr_size, abfd) != external_hdr_size)
00492 goto error_return;
00493 internal_symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
00494 (*backend->debug_swap.swap_hdr_in) (abfd, raw, internal_symhdr);
00495
00496 if (internal_symhdr->magic != backend->debug_swap.sym_magic)
00497 {
00498 bfd_set_error (bfd_error_bad_value);
00499 goto error_return;
00500 }
00501
00502
00503 bfd_get_symcount (abfd) = (internal_symhdr->isymMax
00504 + internal_symhdr->iextMax);
00505
00506 if (raw != NULL)
00507 free (raw);
00508 return TRUE;
00509 error_return:
00510 if (raw != NULL)
00511 free (raw);
00512 return FALSE;
00513 }
00514
00515
00516
00517
00518
00519 bfd_boolean
00520 _bfd_ecoff_slurp_symbolic_info (abfd, ignore, debug)
00521 bfd *abfd;
00522 asection *ignore ATTRIBUTE_UNUSED;
00523 struct ecoff_debug_info *debug;
00524 {
00525 const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
00526 HDRR *internal_symhdr;
00527 bfd_size_type raw_base;
00528 bfd_size_type raw_size;
00529 PTR raw;
00530 bfd_size_type external_fdr_size;
00531 char *fraw_src;
00532 char *fraw_end;
00533 struct fdr *fdr_ptr;
00534 bfd_size_type raw_end;
00535 bfd_size_type cb_end;
00536 bfd_size_type amt;
00537 file_ptr pos;
00538
00539 BFD_ASSERT (debug == &ecoff_data (abfd)->debug_info);
00540
00541
00542
00543 if (ecoff_data (abfd)->raw_syments != (PTR) NULL)
00544 return TRUE;
00545 if (ecoff_data (abfd)->sym_filepos == 0)
00546 {
00547 bfd_get_symcount (abfd) = 0;
00548 return TRUE;
00549 }
00550
00551 if (! ecoff_slurp_symbolic_header (abfd))
00552 return FALSE;
00553
00554 internal_symhdr = &debug->symbolic_header;
00555
00556
00557 raw_base = (ecoff_data (abfd)->sym_filepos
00558 + backend->debug_swap.external_hdr_size);
00559
00560
00561
00562
00563
00564
00565 raw_end = 0;
00566
00567 #define UPDATE_RAW_END(start, count, size) \
00568 cb_end = internal_symhdr->start + internal_symhdr->count * (size); \
00569 if (cb_end > raw_end) \
00570 raw_end = cb_end
00571
00572 UPDATE_RAW_END (cbLineOffset, cbLine, sizeof (unsigned char));
00573 UPDATE_RAW_END (cbDnOffset, idnMax, backend->debug_swap.external_dnr_size);
00574 UPDATE_RAW_END (cbPdOffset, ipdMax, backend->debug_swap.external_pdr_size);
00575 UPDATE_RAW_END (cbSymOffset, isymMax, backend->debug_swap.external_sym_size);
00576
00577
00578 UPDATE_RAW_END (cbOptOffset, ioptMax, sizeof (char));
00579 UPDATE_RAW_END (cbAuxOffset, iauxMax, sizeof (union aux_ext));
00580 UPDATE_RAW_END (cbSsOffset, issMax, sizeof (char));
00581 UPDATE_RAW_END (cbSsExtOffset, issExtMax, sizeof (char));
00582 UPDATE_RAW_END (cbFdOffset, ifdMax, backend->debug_swap.external_fdr_size);
00583 UPDATE_RAW_END (cbRfdOffset, crfd, backend->debug_swap.external_rfd_size);
00584 UPDATE_RAW_END (cbExtOffset, iextMax, backend->debug_swap.external_ext_size);
00585
00586 #undef UPDATE_RAW_END
00587
00588 raw_size = raw_end - raw_base;
00589 if (raw_size == 0)
00590 {
00591 ecoff_data (abfd)->sym_filepos = 0;
00592 return TRUE;
00593 }
00594 raw = (PTR) bfd_alloc (abfd, raw_size);
00595 if (raw == NULL)
00596 return FALSE;
00597
00598 pos = ecoff_data (abfd)->sym_filepos;
00599 pos += backend->debug_swap.external_hdr_size;
00600 if (bfd_seek (abfd, pos, SEEK_SET) != 0
00601 || bfd_bread (raw, raw_size, abfd) != raw_size)
00602 {
00603 bfd_release (abfd, raw);
00604 return FALSE;
00605 }
00606
00607 ecoff_data (abfd)->raw_syments = raw;
00608
00609
00610 #define FIX(off1, off2, type) \
00611 if (internal_symhdr->off1 == 0) \
00612 debug->off2 = (type) NULL; \
00613 else \
00614 debug->off2 = (type) ((char *) raw \
00615 + (internal_symhdr->off1 \
00616 - raw_base))
00617
00618 FIX (cbLineOffset, line, unsigned char *);
00619 FIX (cbDnOffset, external_dnr, PTR);
00620 FIX (cbPdOffset, external_pdr, PTR);
00621 FIX (cbSymOffset, external_sym, PTR);
00622 FIX (cbOptOffset, external_opt, PTR);
00623 FIX (cbAuxOffset, external_aux, union aux_ext *);
00624 FIX (cbSsOffset, ss, char *);
00625 FIX (cbSsExtOffset, ssext, char *);
00626 FIX (cbFdOffset, external_fdr, PTR);
00627 FIX (cbRfdOffset, external_rfd, PTR);
00628 FIX (cbExtOffset, external_ext, PTR);
00629 #undef FIX
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 amt = internal_symhdr->ifdMax;
00640 amt *= sizeof (struct fdr);
00641 debug->fdr = (struct fdr *) bfd_alloc (abfd, amt);
00642 if (debug->fdr == NULL)
00643 return FALSE;
00644 external_fdr_size = backend->debug_swap.external_fdr_size;
00645 fdr_ptr = debug->fdr;
00646 fraw_src = (char *) debug->external_fdr;
00647 fraw_end = fraw_src + internal_symhdr->ifdMax * external_fdr_size;
00648 for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
00649 (*backend->debug_swap.swap_fdr_in) (abfd, (PTR) fraw_src, fdr_ptr);
00650
00651 return TRUE;
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662 static asection ecoff_scom_section;
00663 static asymbol ecoff_scom_symbol;
00664 static asymbol *ecoff_scom_symbol_ptr;
00665
00666
00667
00668 asymbol *
00669 _bfd_ecoff_make_empty_symbol (abfd)
00670 bfd *abfd;
00671 {
00672 ecoff_symbol_type *new;
00673 bfd_size_type amt = sizeof (ecoff_symbol_type);
00674
00675 new = (ecoff_symbol_type *) bfd_zalloc (abfd, amt);
00676 if (new == (ecoff_symbol_type *) NULL)
00677 return (asymbol *) NULL;
00678 new->symbol.section = (asection *) NULL;
00679 new->fdr = (FDR *) NULL;
00680 new->local = FALSE;
00681 new->native = NULL;
00682 new->symbol.the_bfd = abfd;
00683 return &new->symbol;
00684 }
00685
00686
00687
00688 static bfd_boolean
00689 ecoff_set_symbol_info (abfd, ecoff_sym, asym, ext, weak)
00690 bfd *abfd;
00691 SYMR *ecoff_sym;
00692 asymbol *asym;
00693 int ext;
00694 int weak;
00695 {
00696 asym->the_bfd = abfd;
00697 asym->value = ecoff_sym->value;
00698 asym->section = &bfd_debug_section;
00699 asym->udata.i = 0;
00700
00701
00702 switch (ecoff_sym->st)
00703 {
00704 case stGlobal:
00705 case stStatic:
00706 case stLabel:
00707 case stProc:
00708 case stStaticProc:
00709 break;
00710 case stNil:
00711 if (ECOFF_IS_STAB (ecoff_sym))
00712 {
00713 asym->flags = BSF_DEBUGGING;
00714 return TRUE;
00715 }
00716 break;
00717 default:
00718 asym->flags = BSF_DEBUGGING;
00719 return TRUE;
00720 }
00721
00722 if (weak)
00723 asym->flags = BSF_EXPORT | BSF_WEAK;
00724 else if (ext)
00725 asym->flags = BSF_EXPORT | BSF_GLOBAL;
00726 else
00727 {
00728 asym->flags = BSF_LOCAL;
00729
00730
00731
00732
00733
00734
00735 if (ecoff_sym->st == stProc
00736 || ecoff_sym->st == stLabel
00737 || ECOFF_IS_STAB (ecoff_sym))
00738 asym->flags |= BSF_DEBUGGING;
00739 }
00740
00741 if (ecoff_sym->st == stProc || ecoff_sym->st == stStaticProc)
00742 asym->flags |= BSF_FUNCTION;
00743
00744 switch (ecoff_sym->sc)
00745 {
00746 case scNil:
00747
00748
00749
00750
00751 asym->flags = BSF_LOCAL;
00752 break;
00753 case scText:
00754 asym->section = bfd_make_section_old_way (abfd, ".text");
00755 asym->value -= asym->section->vma;
00756 break;
00757 case scData:
00758 asym->section = bfd_make_section_old_way (abfd, ".data");
00759 asym->value -= asym->section->vma;
00760 break;
00761 case scBss:
00762 asym->section = bfd_make_section_old_way (abfd, ".bss");
00763 asym->value -= asym->section->vma;
00764 break;
00765 case scRegister:
00766 asym->flags = BSF_DEBUGGING;
00767 break;
00768 case scAbs:
00769 asym->section = bfd_abs_section_ptr;
00770 break;
00771 case scUndefined:
00772 asym->section = bfd_und_section_ptr;
00773 asym->flags = 0;
00774 asym->value = 0;
00775 break;
00776 case scCdbLocal:
00777 case scBits:
00778 case scCdbSystem:
00779 case scRegImage:
00780 case scInfo:
00781 case scUserStruct:
00782 asym->flags = BSF_DEBUGGING;
00783 break;
00784 case scSData:
00785 asym->section = bfd_make_section_old_way (abfd, ".sdata");
00786 asym->value -= asym->section->vma;
00787 break;
00788 case scSBss:
00789 asym->section = bfd_make_section_old_way (abfd, ".sbss");
00790 asym->value -= asym->section->vma;
00791 break;
00792 case scRData:
00793 asym->section = bfd_make_section_old_way (abfd, ".rdata");
00794 asym->value -= asym->section->vma;
00795 break;
00796 case scVar:
00797 asym->flags = BSF_DEBUGGING;
00798 break;
00799 case scCommon:
00800 if (asym->value > ecoff_data (abfd)->gp_size)
00801 {
00802 asym->section = bfd_com_section_ptr;
00803 asym->flags = 0;
00804 break;
00805 }
00806
00807 case scSCommon:
00808 if (ecoff_scom_section.name == NULL)
00809 {
00810
00811 ecoff_scom_section.name = SCOMMON;
00812 ecoff_scom_section.flags = SEC_IS_COMMON;
00813 ecoff_scom_section.output_section = &ecoff_scom_section;
00814 ecoff_scom_section.symbol = &ecoff_scom_symbol;
00815 ecoff_scom_section.symbol_ptr_ptr = &ecoff_scom_symbol_ptr;
00816 ecoff_scom_symbol.name = SCOMMON;
00817 ecoff_scom_symbol.flags = BSF_SECTION_SYM;
00818 ecoff_scom_symbol.section = &ecoff_scom_section;
00819 ecoff_scom_symbol_ptr = &ecoff_scom_symbol;
00820 }
00821 asym->section = &ecoff_scom_section;
00822 asym->flags = 0;
00823 break;
00824 case scVarRegister:
00825 case scVariant:
00826 asym->flags = BSF_DEBUGGING;
00827 break;
00828 case scSUndefined:
00829 asym->section = bfd_und_section_ptr;
00830 asym->flags = 0;
00831 asym->value = 0;
00832 break;
00833 case scInit:
00834 asym->section = bfd_make_section_old_way (abfd, ".init");
00835 asym->value -= asym->section->vma;
00836 break;
00837 case scBasedVar:
00838 case scXData:
00839 case scPData:
00840 asym->flags = BSF_DEBUGGING;
00841 break;
00842 case scFini:
00843 asym->section = bfd_make_section_old_way (abfd, ".fini");
00844 asym->value -= asym->section->vma;
00845 break;
00846 case scRConst:
00847 asym->section = bfd_make_section_old_way (abfd, ".rconst");
00848 asym->value -= asym->section->vma;
00849 break;
00850 default:
00851 break;
00852 }
00853
00854
00855
00856
00857 if (ECOFF_IS_STAB (ecoff_sym))
00858 {
00859 switch (ECOFF_UNMARK_STAB (ecoff_sym->index))
00860 {
00861 default:
00862 break;
00863
00864 case N_SETA:
00865 case N_SETT:
00866 case N_SETD:
00867 case N_SETB:
00868 {
00869
00870 asym->flags |= BSF_CONSTRUCTOR;
00871 }
00872 break;
00873 }
00874 }
00875 return TRUE;
00876 }
00877
00878
00879
00880 bfd_boolean
00881 _bfd_ecoff_slurp_symbol_table (abfd)
00882 bfd *abfd;
00883 {
00884 const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
00885 const bfd_size_type external_ext_size
00886 = backend->debug_swap.external_ext_size;
00887 const bfd_size_type external_sym_size
00888 = backend->debug_swap.external_sym_size;
00889 void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *))
00890 = backend->debug_swap.swap_ext_in;
00891 void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *))
00892 = backend->debug_swap.swap_sym_in;
00893 bfd_size_type internal_size;
00894 ecoff_symbol_type *internal;
00895 ecoff_symbol_type *internal_ptr;
00896 char *eraw_src;
00897 char *eraw_end;
00898 FDR *fdr_ptr;
00899 FDR *fdr_end;
00900
00901
00902 if (ecoff_data (abfd)->canonical_symbols != NULL)
00903 return TRUE;
00904
00905
00906 if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL,
00907 &ecoff_data (abfd)->debug_info))
00908 return FALSE;
00909 if (bfd_get_symcount (abfd) == 0)
00910 return TRUE;
00911
00912 internal_size = bfd_get_symcount (abfd);
00913 internal_size *= sizeof (ecoff_symbol_type);
00914 internal = (ecoff_symbol_type *) bfd_alloc (abfd, internal_size);
00915 if (internal == NULL)
00916 return FALSE;
00917
00918 internal_ptr = internal;
00919 eraw_src = (char *) ecoff_data (abfd)->debug_info.external_ext;
00920 eraw_end = (eraw_src
00921 + (ecoff_data (abfd)->debug_info.symbolic_header.iextMax
00922 * external_ext_size));
00923 for (; eraw_src < eraw_end; eraw_src += external_ext_size, internal_ptr++)
00924 {
00925 EXTR internal_esym;
00926
00927 (*swap_ext_in) (abfd, (PTR) eraw_src, &internal_esym);
00928 internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ssext
00929 + internal_esym.asym.iss);
00930 if (!ecoff_set_symbol_info (abfd, &internal_esym.asym,
00931 &internal_ptr->symbol, 1,
00932 internal_esym.weakext))
00933 return FALSE;
00934
00935 if (internal_esym.ifd >= 0)
00936 internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr
00937 + internal_esym.ifd);
00938 else
00939 internal_ptr->fdr = NULL;
00940 internal_ptr->local = FALSE;
00941 internal_ptr->native = (PTR) eraw_src;
00942 }
00943
00944
00945
00946 fdr_ptr = ecoff_data (abfd)->debug_info.fdr;
00947 fdr_end = fdr_ptr + ecoff_data (abfd)->debug_info.symbolic_header.ifdMax;
00948 for (; fdr_ptr < fdr_end; fdr_ptr++)
00949 {
00950 char *lraw_src;
00951 char *lraw_end;
00952
00953 lraw_src = ((char *) ecoff_data (abfd)->debug_info.external_sym
00954 + fdr_ptr->isymBase * external_sym_size);
00955 lraw_end = lraw_src + fdr_ptr->csym * external_sym_size;
00956 for (;
00957 lraw_src < lraw_end;
00958 lraw_src += external_sym_size, internal_ptr++)
00959 {
00960 SYMR internal_sym;
00961
00962 (*swap_sym_in) (abfd, (PTR) lraw_src, &internal_sym);
00963 internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ss
00964 + fdr_ptr->issBase
00965 + internal_sym.iss);
00966 if (!ecoff_set_symbol_info (abfd, &internal_sym,
00967 &internal_ptr->symbol, 0, 0))
00968 return FALSE;
00969 internal_ptr->fdr = fdr_ptr;
00970 internal_ptr->local = TRUE;
00971 internal_ptr->native = (PTR) lraw_src;
00972 }
00973 }
00974
00975 ecoff_data (abfd)->canonical_symbols = internal;
00976
00977 return TRUE;
00978 }
00979
00980
00981
00982 long
00983 _bfd_ecoff_get_symtab_upper_bound (abfd)
00984 bfd *abfd;
00985 {
00986 if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL,
00987 &ecoff_data (abfd)->debug_info))
00988 return -1;
00989
00990 if (bfd_get_symcount (abfd) == 0)
00991 return 0;
00992
00993 return (bfd_get_symcount (abfd) + 1) * (sizeof (ecoff_symbol_type *));
00994 }
00995
00996
00997
00998 long
00999 _bfd_ecoff_canonicalize_symtab (abfd, alocation)
01000 bfd *abfd;
01001 asymbol **alocation;
01002 {
01003 unsigned int counter = 0;
01004 ecoff_symbol_type *symbase;
01005 ecoff_symbol_type **location = (ecoff_symbol_type **) alocation;
01006
01007 if (! _bfd_ecoff_slurp_symbol_table (abfd))
01008 return -1;
01009 if (bfd_get_symcount (abfd) == 0)
01010 return 0;
01011
01012 symbase = ecoff_data (abfd)->canonical_symbols;
01013 while (counter < bfd_get_symcount (abfd))
01014 {
01015 *(location++) = symbase++;
01016 counter++;
01017 }
01018 *location++ = (ecoff_symbol_type *) NULL;
01019 return bfd_get_symcount (abfd);
01020 }
01021
01022
01023
01024
01025
01026
01027
01028 static void
01029 ecoff_emit_aggregate (abfd, fdr, string, rndx, isym, which)
01030 bfd *abfd;
01031 FDR *fdr;
01032 char *string;
01033 RNDXR *rndx;
01034 long isym;
01035 const char *which;
01036 {
01037 const struct ecoff_debug_swap * const debug_swap =
01038 &ecoff_backend (abfd)->debug_swap;
01039 struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info;
01040 unsigned int ifd = rndx->rfd;
01041 unsigned int indx = rndx->index;
01042 const char *name;
01043
01044 if (ifd == 0xfff)
01045 ifd = isym;
01046
01047
01048
01049 if (ifd == 0xffffffff
01050 || (rndx->rfd == 0xfff && indx == 0))
01051 name = "<undefined>";
01052 else if (indx == indexNil)
01053 name = "<no name>";
01054 else
01055 {
01056 SYMR sym;
01057
01058 if (debug_info->external_rfd == NULL)
01059 fdr = debug_info->fdr + ifd;
01060 else
01061 {
01062 RFDT rfd;
01063
01064 (*debug_swap->swap_rfd_in) (abfd,
01065 ((char *) debug_info->external_rfd
01066 + ((fdr->rfdBase + ifd)
01067 * debug_swap->external_rfd_size)),
01068 &rfd);
01069 fdr = debug_info->fdr + rfd;
01070 }
01071
01072 indx += fdr->isymBase;
01073
01074 (*debug_swap->swap_sym_in) (abfd,
01075 ((char *) debug_info->external_sym
01076 + indx * debug_swap->external_sym_size),
01077 &sym);
01078
01079 name = debug_info->ss + fdr->issBase + sym.iss;
01080 }
01081
01082 sprintf (string,
01083 "%s %s { ifd = %u, index = %lu }",
01084 which, name, ifd,
01085 ((long) indx
01086 + debug_info->symbolic_header.iextMax));
01087 }
01088
01089
01090
01091 static char *
01092 ecoff_type_to_string (abfd, fdr, indx)
01093 bfd *abfd;
01094 FDR *fdr;
01095 unsigned int indx;
01096 {
01097 union aux_ext *aux_ptr;
01098 int bigendian;
01099 AUXU u;
01100 struct qual {
01101 unsigned int type;
01102 int low_bound;
01103 int high_bound;
01104 int stride;
01105 } qualifiers[7];
01106 unsigned int basic_type;
01107 int i;
01108 char buffer1[1024];
01109 static char buffer2[1024];
01110 char *p1 = buffer1;
01111 char *p2 = buffer2;
01112 RNDXR rndx;
01113
01114 aux_ptr = ecoff_data (abfd)->debug_info.external_aux + fdr->iauxBase;
01115 bigendian = fdr->fBigendian;
01116
01117 for (i = 0; i < 7; i++)
01118 {
01119 qualifiers[i].low_bound = 0;
01120 qualifiers[i].high_bound = 0;
01121 qualifiers[i].stride = 0;
01122 }
01123
01124 if (AUX_GET_ISYM (bigendian, &aux_ptr[indx]) == (bfd_vma) -1)
01125 return "-1 (no type)";
01126 _bfd_ecoff_swap_tir_in (bigendian, &aux_ptr[indx++].a_ti, &u.ti);
01127
01128 basic_type = u.ti.bt;
01129 qualifiers[0].type = u.ti.tq0;
01130 qualifiers[1].type = u.ti.tq1;
01131 qualifiers[2].type = u.ti.tq2;
01132 qualifiers[3].type = u.ti.tq3;
01133 qualifiers[4].type = u.ti.tq4;
01134 qualifiers[5].type = u.ti.tq5;
01135 qualifiers[6].type = tqNil;
01136
01137
01138 switch (basic_type)
01139 {
01140 case btNil:
01141 strcpy (p1, "nil");
01142 break;
01143
01144 case btAdr:
01145 strcpy (p1, "address");
01146 break;
01147
01148 case btChar:
01149 strcpy (p1, "char");
01150 break;
01151
01152 case btUChar:
01153 strcpy (p1, "unsigned char");
01154 break;
01155
01156 case btShort:
01157 strcpy (p1, "short");
01158 break;
01159
01160 case btUShort:
01161 strcpy (p1, "unsigned short");
01162 break;
01163
01164 case btInt:
01165 strcpy (p1, "int");
01166 break;
01167
01168 case btUInt:
01169 strcpy (p1, "unsigned int");
01170 break;
01171
01172 case btLong:
01173 strcpy (p1, "long");
01174 break;
01175
01176 case btULong:
01177 strcpy (p1, "unsigned long");
01178 break;
01179
01180 case btFloat:
01181 strcpy (p1, "float");
01182 break;
01183
01184 case btDouble:
01185 strcpy (p1, "double");
01186 break;
01187
01188
01189
01190
01191
01192 case btStruct:
01193 _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
01194 ecoff_emit_aggregate (abfd, fdr, p1, &rndx,
01195 (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
01196 "struct");
01197 indx++;
01198 break;
01199
01200
01201
01202
01203
01204 case btUnion:
01205 _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
01206 ecoff_emit_aggregate (abfd, fdr, p1, &rndx,
01207 (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
01208 "union");
01209 indx++;
01210 break;
01211
01212
01213
01214
01215
01216 case btEnum:
01217 _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
01218 ecoff_emit_aggregate (abfd, fdr, p1, &rndx,
01219 (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
01220 "enum");
01221 indx++;
01222 break;
01223
01224 case btTypedef:
01225 strcpy (p1, "typedef");
01226 break;
01227
01228 case btRange:
01229 strcpy (p1, "subrange");
01230 break;
01231
01232 case btSet:
01233 strcpy (p1, "set");
01234 break;
01235
01236 case btComplex:
01237 strcpy (p1, "complex");
01238 break;
01239
01240 case btDComplex:
01241 strcpy (p1, "double complex");
01242 break;
01243
01244 case btIndirect:
01245 strcpy (p1, "forward/unamed typedef");
01246 break;
01247
01248 case btFixedDec:
01249 strcpy (p1, "fixed decimal");
01250 break;
01251
01252 case btFloatDec:
01253 strcpy (p1, "float decimal");
01254 break;
01255
01256 case btString:
01257 strcpy (p1, "string");
01258 break;
01259
01260 case btBit:
01261 strcpy (p1, "bit");
01262 break;
01263
01264 case btPicture:
01265 strcpy (p1, "picture");
01266 break;
01267
01268 case btVoid:
01269 strcpy (p1, "void");
01270 break;
01271
01272 default:
01273 sprintf (p1, _("Unknown basic type %d"), (int) basic_type);
01274 break;
01275 }
01276
01277 p1 += strlen (buffer1);
01278
01279
01280 if (u.ti.fBitfield)
01281 {
01282 int bitsize;
01283
01284 bitsize = AUX_GET_WIDTH (bigendian, &aux_ptr[indx++]);
01285 sprintf (p1, " : %d", bitsize);
01286 p1 += strlen (buffer1);
01287 }
01288
01289
01290 if (qualifiers[0].type != tqNil)
01291 {
01292
01293
01294
01295
01296
01297
01298
01299 for (i = 0; i < 7; i++)
01300 {
01301 if (qualifiers[i].type == tqArray)
01302 {
01303 qualifiers[i].low_bound =
01304 AUX_GET_DNLOW (bigendian, &aux_ptr[indx+2]);
01305 qualifiers[i].high_bound =
01306 AUX_GET_DNHIGH (bigendian, &aux_ptr[indx+3]);
01307 qualifiers[i].stride =
01308 AUX_GET_WIDTH (bigendian, &aux_ptr[indx+4]);
01309 indx += 5;
01310 }
01311 }
01312
01313
01314 for (i = 0; i < 6; i++)
01315 {
01316 switch (qualifiers[i].type)
01317 {
01318 case tqNil:
01319 case tqMax:
01320 break;
01321
01322 case tqPtr:
01323 strcpy (p2, "ptr to ");
01324 p2 += sizeof ("ptr to ")-1;
01325 break;
01326
01327 case tqVol:
01328 strcpy (p2, "volatile ");
01329 p2 += sizeof ("volatile ")-1;
01330 break;
01331
01332 case tqFar:
01333 strcpy (p2, "far ");
01334 p2 += sizeof ("far ")-1;
01335 break;
01336
01337 case tqProc:
01338 strcpy (p2, "func. ret. ");
01339 p2 += sizeof ("func. ret. ");
01340 break;
01341
01342 case tqArray:
01343 {
01344 int first_array = i;
01345 int j;
01346
01347
01348
01349 while (i < 5 && qualifiers[i+1].type == tqArray)
01350 i++;
01351
01352 for (j = i; j >= first_array; j--)
01353 {
01354 strcpy (p2, "array [");
01355 p2 += sizeof ("array [")-1;
01356 if (qualifiers[j].low_bound != 0)
01357 sprintf (p2,
01358 "%ld:%ld {%ld bits}",
01359 (long) qualifiers[j].low_bound,
01360 (long) qualifiers[j].high_bound,
01361 (long) qualifiers[j].stride);
01362
01363 else if (qualifiers[j].high_bound != -1)
01364 sprintf (p2,
01365 "%ld {%ld bits}",
01366 (long) (qualifiers[j].high_bound + 1),
01367 (long) (qualifiers[j].stride));
01368
01369 else
01370 sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride));
01371
01372 p2 += strlen (p2);
01373 strcpy (p2, "] of ");
01374 p2 += sizeof ("] of ")-1;
01375 }
01376 }
01377 break;
01378 }
01379 }
01380 }
01381
01382 strcpy (p2, buffer1);
01383 return buffer2;
01384 }
01385
01386
01387
01388 void
01389 _bfd_ecoff_get_symbol_info (abfd, symbol, ret)
01390 bfd *abfd ATTRIBUTE_UNUSED;
01391 asymbol *symbol;
01392 symbol_info *ret;
01393 {
01394 bfd_symbol_info (symbol, ret);
01395 }
01396
01397
01398
01399 bfd_boolean
01400 _bfd_ecoff_bfd_is_local_label_name (abfd, name)
01401 bfd *abfd ATTRIBUTE_UNUSED;
01402 const char *name;
01403 {
01404 return name[0] == '$';
01405 }
01406
01407
01408
01409 void
01410 _bfd_ecoff_print_symbol (abfd, filep, symbol, how)
01411 bfd *abfd;
01412 PTR filep;
01413 asymbol *symbol;
01414 bfd_print_symbol_type how;
01415 {
01416 const struct ecoff_debug_swap * const debug_swap
01417 = &ecoff_backend (abfd)->debug_swap;
01418 FILE *file = (FILE *)filep;
01419
01420 switch (how)
01421 {
01422 case bfd_print_symbol_name:
01423 fprintf (file, "%s", symbol->name);
01424 break;
01425 case bfd_print_symbol_more:
01426 if (ecoffsymbol (symbol)->local)
01427 {
01428 SYMR ecoff_sym;
01429
01430 (*debug_swap->swap_sym_in) (abfd, ecoffsymbol (symbol)->native,
01431 &ecoff_sym);
01432 fprintf (file, "ecoff local ");
01433 fprintf_vma (file, (bfd_vma) ecoff_sym.value);
01434 fprintf (file, " %x %x", (unsigned) ecoff_sym.st,
01435 (unsigned) ecoff_sym.sc);
01436 }
01437 else
01438 {
01439 EXTR ecoff_ext;
01440
01441 (*debug_swap->swap_ext_in) (abfd, ecoffsymbol (symbol)->native,
01442 &ecoff_ext);
01443 fprintf (file, "ecoff extern ");
01444 fprintf_vma (file, (bfd_vma) ecoff_ext.asym.value);
01445 fprintf (file, " %x %x", (unsigned) ecoff_ext.asym.st,
01446 (unsigned) ecoff_ext.asym.sc);
01447 }
01448 break;
01449 case bfd_print_symbol_all:
01450
01451 {
01452 char type;
01453 int pos;
01454 EXTR ecoff_ext;
01455 char jmptbl;
01456 char cobol_main;
01457 char weakext;
01458
01459 if (ecoffsymbol (symbol)->local)
01460 {
01461 (*debug_swap->swap_sym_in) (abfd, ecoffsymbol (symbol)->native,
01462 &ecoff_ext.asym);
01463 type = 'l';
01464 pos = ((((char *) ecoffsymbol (symbol)->native
01465 - (char *) ecoff_data (abfd)->debug_info.external_sym)
01466 / debug_swap->external_sym_size)
01467 + ecoff_data (abfd)->debug_info.symbolic_header.iextMax);
01468 jmptbl = ' ';
01469 cobol_main = ' ';
01470 weakext = ' ';
01471 }
01472 else
01473 {
01474 (*debug_swap->swap_ext_in) (abfd, ecoffsymbol (symbol)->native,
01475 &ecoff_ext);
01476 type = 'e';
01477 pos = (((char *) ecoffsymbol (symbol)->native
01478 - (char *) ecoff_data (abfd)->debug_info.external_ext)
01479 / debug_swap->external_ext_size);
01480 jmptbl = ecoff_ext.jmptbl ? 'j' : ' ';
01481 cobol_main = ecoff_ext.cobol_main ? 'c' : ' ';
01482 weakext = ecoff_ext.weakext ? 'w' : ' ';
01483 }
01484
01485 fprintf (file, "[%3d] %c ",
01486 pos, type);
01487 fprintf_vma (file, (bfd_vma) ecoff_ext.asym.value);
01488 fprintf (file, " st %x sc %x indx %x %c%c%c %s",
01489 (unsigned) ecoff_ext.asym.st,
01490 (unsigned) ecoff_ext.asym.sc,
01491 (unsigned) ecoff_ext.asym.index,
01492 jmptbl, cobol_main, weakext,
01493 symbol->name);
01494
01495 if (ecoffsymbol (symbol)->fdr != NULL
01496 && ecoff_ext.asym.index != indexNil)
01497 {
01498 FDR *fdr;
01499 unsigned int indx;
01500 int bigendian;
01501 bfd_size_type sym_base;
01502 union aux_ext *aux_base;
01503
01504 fdr = ecoffsymbol (symbol)->fdr;
01505 indx = ecoff_ext.asym.index;
01506
01507
01508
01509
01510 sym_base = fdr->isymBase;
01511 if (ecoffsymbol (symbol)->local)
01512 sym_base +=
01513 ecoff_data (abfd)->debug_info.symbolic_header.iextMax;
01514
01515
01516
01517 aux_base = (ecoff_data (abfd)->debug_info.external_aux
01518 + fdr->iauxBase);
01519
01520
01521
01522 bigendian = fdr->fBigendian;
01523
01524
01525 switch (ecoff_ext.asym.st)
01526 {
01527 case stNil:
01528 case stLabel:
01529 break;
01530
01531 case stFile:
01532 case stBlock:
01533 fprintf (file, _("\n End+1 symbol: %ld"),
01534 (long) (indx + sym_base));
01535 break;
01536
01537 case stEnd:
01538 if (ecoff_ext.asym.sc == scText
01539 || ecoff_ext.asym.sc == scInfo)
01540 fprintf (file, _("\n First symbol: %ld"),
01541 (long) (indx + sym_base));
01542 else
01543 fprintf (file, _("\n First symbol: %ld"),
01544 ((long)
01545 (AUX_GET_ISYM (bigendian,
01546 &aux_base[ecoff_ext.asym.index])
01547 + sym_base)));
01548 break;
01549
01550 case stProc:
01551 case stStaticProc:
01552 if (ECOFF_IS_STAB (&ecoff_ext.asym))
01553 ;
01554 else if (ecoffsymbol (symbol)->local)
01555 fprintf (file, _("\n End+1 symbol: %-7ld Type: %s"),
01556 ((long)
01557 (AUX_GET_ISYM (bigendian,
01558 &aux_base[ecoff_ext.asym.index])
01559 + sym_base)),
01560 ecoff_type_to_string (abfd, fdr, indx + 1));
01561 else
01562 fprintf (file, _("\n Local symbol: %ld"),
01563 ((long) indx
01564 + (long) sym_base
01565 + (ecoff_data (abfd)
01566 ->debug_info.symbolic_header.iextMax)));
01567 break;
01568
01569 case stStruct:
01570 fprintf (file, _("\n struct; End+1 symbol: %ld"),
01571 (long) (indx + sym_base));
01572 break;
01573
01574 case stUnion:
01575 fprintf (file, _("\n union; End+1 symbol: %ld"),
01576 (long) (indx + sym_base));
01577 break;
01578
01579 case stEnum:
01580 fprintf (file, _("\n enum; End+1 symbol: %ld"),
01581 (long) (indx + sym_base));
01582 break;
01583
01584 default:
01585 if (! ECOFF_IS_STAB (&ecoff_ext.asym))
01586 fprintf (file, _("\n Type: %s"),
01587 ecoff_type_to_string (abfd, fdr, indx));
01588 break;
01589 }
01590 }
01591 }
01592 break;
01593 }
01594 }
01595
01596
01597
01598 static bfd_boolean
01599 ecoff_slurp_reloc_table (abfd, section, symbols)
01600 bfd *abfd;
01601 asection *section;
01602 asymbol **symbols;
01603 {
01604 const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
01605 arelent *internal_relocs;
01606 bfd_size_type external_reloc_size;
01607 bfd_size_type amt;
01608 char *external_relocs;
01609 arelent *rptr;
01610 unsigned int i;
01611
01612 if (section->relocation != (arelent *) NULL
01613 || section->reloc_count == 0
01614 || (section->flags & SEC_CONSTRUCTOR) != 0)
01615 return TRUE;
01616
01617 if (! _bfd_ecoff_slurp_symbol_table (abfd))
01618 return FALSE;
01619
01620 amt = section->reloc_count;
01621 amt *= sizeof (arelent);
01622 internal_relocs = (arelent *) bfd_alloc (abfd, amt);
01623
01624 external_reloc_size = backend->external_reloc_size;
01625 amt = external_reloc_size * section->reloc_count;
01626 external_relocs = (char *) bfd_alloc (abfd, amt);
01627 if (internal_relocs == (arelent *) NULL
01628 || external_relocs == (char *) NULL)
01629 return FALSE;
01630 if (bfd_seek (abfd, section->rel_filepos, SEEK_SET) != 0)
01631 return FALSE;
01632 if (bfd_bread (external_relocs, amt, abfd) != amt)
01633 return FALSE;
01634
01635 for (i = 0, rptr = internal_relocs; i < section->reloc_count; i++, rptr++)
01636 {
01637 struct internal_reloc intern;
01638
01639 (*backend->swap_reloc_in) (abfd,
01640 external_relocs + i * external_reloc_size,
01641 &intern);
01642
01643 if (intern.r_extern)
01644 {
01645
01646 BFD_ASSERT (intern.r_symndx >= 0
01647 && (intern.r_symndx
01648 < (ecoff_data (abfd)
01649 ->debug_info.symbolic_header.iextMax)));
01650 rptr->sym_ptr_ptr = symbols + intern.r_symndx;
01651 rptr->addend = 0;
01652 }
01653 else if (intern.r_symndx == RELOC_SECTION_NONE
01654 || intern.r_symndx == RELOC_SECTION_ABS)
01655 {
01656 rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
01657 rptr->addend = 0;
01658 }
01659 else
01660 {
01661 const char *sec_name;
01662 asection *sec;
01663
01664
01665 switch (intern.r_symndx)
01666 {
01667 case RELOC_SECTION_TEXT: sec_name = ".text"; break;
01668 case RELOC_SECTION_RDATA: sec_name = ".rdata"; break;
01669 case RELOC_SECTION_DATA: sec_name = ".data"; break;
01670 case RELOC_SECTION_SDATA: sec_name = ".sdata"; break;
01671 case RELOC_SECTION_SBSS: sec_name = ".sbss"; break;
01672 case RELOC_SECTION_BSS: sec_name = ".bss"; break;
01673 case RELOC_SECTION_INIT: sec_name = ".init"; break;
01674 case RELOC_SECTION_LIT8: sec_name = ".lit8"; break;
01675 case RELOC_SECTION_LIT4: sec_name = ".lit4"; break;
01676 case RELOC_SECTION_XDATA: sec_name = ".xdata"; break;
01677 case RELOC_SECTION_PDATA: sec_name = ".pdata"; break;
01678 case RELOC_SECTION_FINI: sec_name = ".fini"; break;
01679 case RELOC_SECTION_LITA: sec_name = ".lita"; break;
01680 case RELOC_SECTION_RCONST: sec_name = ".rconst"; break;
01681 default: abort ();
01682 }
01683
01684 sec = bfd_get_section_by_name (abfd, sec_name);
01685 if (sec == (asection *) NULL)
01686 abort ();
01687 rptr->sym_ptr_ptr = sec->symbol_ptr_ptr;
01688
01689 rptr->addend = - bfd_get_section_vma (abfd, sec);
01690 }
01691
01692 rptr->address = intern.r_vaddr - bfd_get_section_vma (abfd, section);
01693
01694
01695
01696 (*backend->adjust_reloc_in) (abfd, &intern, rptr);
01697 }
01698
01699 bfd_release (abfd, external_relocs);
01700
01701 section->relocation = internal_relocs;
01702
01703 return TRUE;
01704 }
01705
01706
01707
01708 long
01709 _bfd_ecoff_canonicalize_reloc (abfd, section, relptr, symbols)
01710 bfd *abfd;
01711 asection *section;
01712 arelent **relptr;
01713 asymbol **symbols;
01714 {
01715 unsigned int count;
01716
01717 if (section->flags & SEC_CONSTRUCTOR)
01718 {
01719 arelent_chain *chain;
01720
01721
01722
01723
01724 for (count = 0, chain = section->constructor_chain;
01725 count < section->reloc_count;
01726 count++, chain = chain->next)
01727 *relptr++ = &chain->relent;
01728 }
01729 else
01730 {
01731 arelent *tblptr;
01732
01733 if (! ecoff_slurp_reloc_table (abfd, section, symbols))
01734 return -1;
01735
01736 tblptr = section->relocation;
01737
01738 for (count = 0; count < section->reloc_count; count++)
01739 *relptr++ = tblptr++;
01740 }
01741
01742 *relptr = (arelent *) NULL;
01743
01744 return section->reloc_count;
01745 }
01746
01747
01748
01749
01750
01751 bfd_boolean
01752 _bfd_ecoff_find_nearest_line (abfd, section, ignore_symbols, offset,
01753 filename_ptr, functionname_ptr, retline_ptr)
01754 bfd *abfd;
01755 asection *section;
01756 asymbol **ignore_symbols ATTRIBUTE_UNUSED;
01757 bfd_vma offset;
01758 const char **filename_ptr;
01759 const char **functionname_ptr;
01760 unsigned int *retline_ptr;
01761 {
01762 const struct ecoff_debug_swap * const debug_swap
01763 = &ecoff_backend (abfd)->debug_swap;
01764 struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info;
01765 struct ecoff_find_line *line_info;
01766
01767
01768 if (! _bfd_ecoff_slurp_symbolic_info (abfd, (asection *) NULL, debug_info)
01769 || bfd_get_symcount (abfd) == 0)
01770 return FALSE;
01771
01772 if (ecoff_data (abfd)->find_line_info == NULL)
01773 {
01774 bfd_size_type amt = sizeof (struct ecoff_find_line);
01775 ecoff_data (abfd)->find_line_info
01776 = (struct ecoff_find_line *) bfd_zalloc (abfd, amt);
01777 if (ecoff_data (abfd)->find_line_info == NULL)
01778 return FALSE;
01779 }
01780 line_info = ecoff_data (abfd)->find_line_info;
01781
01782 return _bfd_ecoff_locate_line (abfd, section, offset, debug_info,
01783 debug_swap, line_info, filename_ptr,
01784 functionname_ptr, retline_ptr);
01785 }
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800 bfd_boolean
01801 _bfd_ecoff_bfd_copy_private_bfd_data (ibfd, obfd)
01802 bfd *ibfd;
01803 bfd *obfd;
01804 {
01805 struct ecoff_debug_info *iinfo = &ecoff_data (ibfd)->debug_info;
01806 struct ecoff_debug_info *oinfo = &ecoff_data (obfd)->debug_info;
01807 register int i;
01808 asymbol **sym_ptr_ptr;
01809 size_t c;
01810 bfd_boolean local;
01811
01812
01813
01814 if (bfd_get_flavour (ibfd) != bfd_target_ecoff_flavour
01815 || bfd_get_flavour (obfd) != bfd_target_ecoff_flavour)
01816 return TRUE;
01817
01818
01819 ecoff_data (obfd)->gp = ecoff_data (ibfd)->gp;
01820 ecoff_data (obfd)->gprmask = ecoff_data (ibfd)->gprmask;
01821 ecoff_data (obfd)->fprmask = ecoff_data (ibfd)->fprmask;
01822 for (i = 0; i < 3; i++)
01823 ecoff_data (obfd)->cprmask[i] = ecoff_data (ibfd)->cprmask[i];
01824
01825
01826 oinfo->symbolic_header.vstamp = iinfo->symbolic_header.vstamp;
01827
01828
01829 c = bfd_get_symcount (obfd);
01830 sym_ptr_ptr = bfd_get_outsymbols (obfd);
01831 if (c == 0 || sym_ptr_ptr == (asymbol **) NULL)
01832 return TRUE;
01833
01834
01835 local = FALSE;
01836 for (; c > 0; c--, sym_ptr_ptr++)
01837 {
01838 if (ecoffsymbol (*sym_ptr_ptr)->local)
01839 {
01840 local = TRUE;
01841 break;
01842 }
01843 }
01844
01845 if (local)
01846 {
01847
01848
01849
01850
01851
01852
01853
01854
01855 oinfo->symbolic_header.ilineMax = iinfo->symbolic_header.ilineMax;
01856 oinfo->symbolic_header.cbLine = iinfo->symbolic_header.cbLine;
01857 oinfo->line = iinfo->line;
01858
01859 oinfo->symbolic_header.idnMax = iinfo->symbolic_header.idnMax;
01860 oinfo->external_dnr = iinfo->external_dnr;
01861
01862 oinfo->symbolic_header.ipdMax = iinfo->symbolic_header.ipdMax;
01863 oinfo->external_pdr = iinfo->external_pdr;
01864
01865 oinfo->symbolic_header.isymMax = iinfo->symbolic_header.isymMax;
01866 oinfo->external_sym = iinfo->external_sym;
01867
01868 oinfo->symbolic_header.ioptMax = iinfo->symbolic_header.ioptMax;
01869 oinfo->external_opt = iinfo->external_opt;
01870
01871 oinfo->symbolic_header.iauxMax = iinfo->symbolic_header.iauxMax;
01872 oinfo->external_aux = iinfo->external_aux;
01873
01874 oinfo->symbolic_header.issMax = iinfo->symbolic_header.issMax;
01875 oinfo->ss = iinfo->ss;
01876
01877 oinfo->symbolic_header.ifdMax = iinfo->symbolic_header.ifdMax;
01878 oinfo->external_fdr = iinfo->external_fdr;
01879
01880 oinfo->symbolic_header.crfd = iinfo->symbolic_header.crfd;
01881 oinfo->external_rfd = iinfo->external_rfd;
01882 }
01883 else
01884 {
01885
01886
01887
01888 c = bfd_get_symcount (obfd);
01889 sym_ptr_ptr = bfd_get_outsymbols (obfd);
01890 for (; c > 0; c--, sym_ptr_ptr++)
01891 {
01892 EXTR esym;
01893
01894 (*(ecoff_backend (obfd)->debug_swap.swap_ext_in))
01895 (obfd, ecoffsymbol (*sym_ptr_ptr)->native, &esym);
01896 esym.ifd = ifdNil;
01897 esym.asym.index = indexNil;
01898 (*(ecoff_backend (obfd)->debug_swap.swap_ext_out))
01899 (obfd, &esym, ecoffsymbol (*sym_ptr_ptr)->native);
01900 }
01901 }
01902
01903 return TRUE;
01904 }
01905
01906
01907
01908
01909
01910 bfd_boolean
01911 _bfd_ecoff_set_arch_mach (abfd, arch, machine)
01912 bfd *abfd;
01913 enum bfd_architecture arch;
01914 unsigned long machine;
01915 {
01916 bfd_default_set_arch_mach (abfd, arch, machine);
01917 return arch == ecoff_backend (abfd)->arch;
01918 }
01919
01920
01921
01922 int
01923 _bfd_ecoff_sizeof_headers (abfd, reloc)
01924 bfd *abfd;
01925 bfd_boolean reloc ATTRIBUTE_UNUSED;
01926 {
01927 asection *current;
01928 int c;
01929 int ret;
01930
01931 c = 0;
01932 for (current = abfd->sections;
01933 current != (asection *)NULL;
01934 current = current->next)
01935 ++c;
01936
01937 ret = (bfd_coff_filhsz (abfd)
01938 + bfd_coff_aoutsz (abfd)
01939 + c * bfd_coff_scnhsz (abfd));
01940 return BFD_ALIGN (ret, 16);
01941 }
01942
01943
01944
01945 bfd_boolean
01946 _bfd_ecoff_get_section_contents (abfd, section, location, offset, count)
01947 bfd *abfd;
01948 asection *section;
01949 PTR location;
01950 file_ptr offset;
01951 bfd_size_type count;
01952 {
01953 return _bfd_generic_get_section_contents (abfd, section, location,
01954 offset, count);
01955 }
01956
01957
01958
01959
01960 static int
01961 ecoff_sort_hdrs (arg1, arg2)
01962 const PTR arg1;
01963 const PTR arg2;
01964 {
01965 const asection *hdr1 = *(const asection **) arg1;
01966 const asection *hdr2 = *(const asection **) arg2;
01967
01968 if ((hdr1->flags & SEC_ALLOC) != 0)
01969 {
01970 if ((hdr2->flags & SEC_ALLOC) == 0)
01971 return -1;
01972 }
01973 else
01974 {
01975 if ((hdr2->flags & SEC_ALLOC) != 0)
01976 return 1;
01977 }
01978 if (hdr1->vma < hdr2->vma)
01979 return -1;
01980 else if (hdr1->vma > hdr2->vma)
01981 return 1;
01982 else
01983 return 0;
01984 }
01985
01986
01987
01988
01989 static bfd_boolean
01990 ecoff_compute_section_file_positions (abfd)
01991 bfd *abfd;
01992 {
01993 file_ptr sofar, file_sofar;
01994 asection **sorted_hdrs;
01995 asection *current;
01996 unsigned int i;
01997 file_ptr old_sofar;
01998 bfd_boolean rdata_in_text;
01999 bfd_boolean first_data, first_nonalloc;
02000 const bfd_vma round = ecoff_backend (abfd)->round;
02001 bfd_size_type amt;
02002
02003 sofar = _bfd_ecoff_sizeof_headers (abfd, FALSE);
02004 file_sofar = sofar;
02005
02006
02007 amt = abfd->section_count;
02008 amt *= sizeof (asection *);
02009 sorted_hdrs = (asection **) bfd_malloc (amt);
02010 if (sorted_hdrs == NULL)
02011 return FALSE;
02012 for (current = abfd->sections, i = 0;
02013 current != NULL;
02014 current = current->next, i++)
02015 sorted_hdrs[i] = current;
02016 BFD_ASSERT (i == abfd->section_count);
02017
02018 qsort (sorted_hdrs, abfd->section_count, sizeof (asection *),
02019 ecoff_sort_hdrs);
02020
02021
02022
02023 rdata_in_text = ecoff_backend (abfd)->rdata_in_text;
02024 if (rdata_in_text)
02025 {
02026 for (i = 0; i < abfd->section_count; i++)
02027 {
02028 current = sorted_hdrs[i];
02029 if (strcmp (current->name, _RDATA) == 0)
02030 break;
02031 if ((current->flags & SEC_CODE) == 0
02032 && strcmp (current->name, _PDATA) != 0
02033 && strcmp (current->name, _RCONST) != 0)
02034 {
02035 rdata_in_text = FALSE;
02036 break;
02037 }
02038 }
02039 }
02040 ecoff_data (abfd)->rdata_in_text = rdata_in_text;
02041
02042 first_data = TRUE;
02043 first_nonalloc = TRUE;
02044 for (i = 0; i < abfd->section_count; i++)
02045 {
02046 unsigned int alignment_power;
02047
02048 current = sorted_hdrs[i];
02049
02050
02051
02052
02053
02054 if (strcmp (current->name, _PDATA) == 0)
02055 current->line_filepos = current->size / 8;
02056
02057 alignment_power = current->alignment_power;
02058
02059
02060
02061
02062
02063
02064
02065 if ((abfd->flags & EXEC_P) != 0
02066 && (abfd->flags & D_PAGED) != 0
02067 && ! first_data
02068 && (current->flags & SEC_CODE) == 0
02069 && (! rdata_in_text
02070 || strcmp (current->name, _RDATA) != 0)
02071 && strcmp (current->name, _PDATA) != 0
02072 && strcmp (current->name, _RCONST) != 0)
02073 {
02074 sofar = (sofar + round - 1) &~ (round - 1);
02075 file_sofar = (file_sofar + round - 1) &~ (round - 1);
02076 first_data = FALSE;
02077 }
02078 else if (strcmp (current->name, _LIB) == 0)
02079 {
02080
02081
02082
02083
02084 sofar = (sofar + round - 1) &~ (round - 1);
02085 file_sofar = (file_sofar + round - 1) &~ (round - 1);
02086 }
02087 else if (first_nonalloc
02088 && (current->flags & SEC_ALLOC) == 0
02089 && (abfd->flags & D_PAGED) != 0)
02090 {
02091
02092
02093
02094 first_nonalloc = FALSE;
02095 sofar = (sofar + round - 1) &~ (round - 1);
02096 file_sofar = (file_sofar + round - 1) &~ (round - 1);
02097 }
02098
02099
02100
02101 sofar = BFD_ALIGN (sofar, 1 << alignment_power);
02102 if ((current->flags & SEC_HAS_CONTENTS) != 0)
02103 file_sofar = BFD_ALIGN (file_sofar, 1 << alignment_power);
02104
02105 if ((abfd->flags & D_PAGED) != 0
02106 && (current->flags & SEC_ALLOC) != 0)
02107 {
02108 sofar += (current->vma - sofar) % round;
02109 if ((current->flags & SEC_HAS_CONTENTS) != 0)
02110 file_sofar += (current->vma - file_sofar) % round;
02111 }
02112
02113 if ((current->flags & (SEC_HAS_CONTENTS | SEC_LOAD)) != 0)
02114 current->filepos = file_sofar;
02115
02116 sofar += current->size;
02117 if ((current->flags & SEC_HAS_CONTENTS) != 0)
02118 file_sofar += current->size;
02119
02120
02121 old_sofar = sofar;
02122 sofar = BFD_ALIGN (sofar, 1 << alignment_power);
02123 if ((current->flags & SEC_HAS_CONTENTS) != 0)
02124 file_sofar = BFD_ALIGN (file_sofar, 1 << alignment_power);
02125 current->size += sofar - old_sofar;
02126 }
02127
02128 free (sorted_hdrs);
02129 sorted_hdrs = NULL;
02130
02131 ecoff_data (abfd)->reloc_filepos = file_sofar;
02132
02133 return TRUE;
02134 }
02135
02136
02137
02138
02139
02140 static bfd_size_type
02141 ecoff_compute_reloc_file_positions (abfd)
02142 bfd *abfd;
02143 {
02144 const bfd_size_type external_reloc_size =
02145 ecoff_backend (abfd)->external_reloc_size;
02146 file_ptr reloc_base;
02147 bfd_size_type reloc_size;
02148 asection *current;
02149 file_ptr sym_base;
02150
02151 if (! abfd->output_has_begun)
02152 {
02153 if (! ecoff_compute_section_file_positions (abfd))
02154 abort ();
02155 abfd->output_has_begun = TRUE;
02156 }
02157
02158 reloc_base = ecoff_data (abfd)->reloc_filepos;
02159
02160 reloc_size = 0;
02161 for (current = abfd->sections;
02162 current != (asection *)NULL;
02163 current = current->next)
02164 {
02165 if (current->reloc_count == 0)
02166 current->rel_filepos = 0;
02167 else
02168 {
02169 bfd_size_type relsize;
02170
02171 current->rel_filepos = reloc_base;
02172 relsize = current->reloc_count * external_reloc_size;
02173 reloc_size += relsize;
02174 reloc_base += relsize;
02175 }
02176 }
02177
02178 sym_base = ecoff_data (abfd)->reloc_filepos + reloc_size;
02179
02180
02181
02182
02183 if ((abfd->flags & EXEC_P) != 0
02184 && (abfd->flags & D_PAGED) != 0)
02185 sym_base = ((sym_base + ecoff_backend (abfd)->round - 1)
02186 &~ (ecoff_backend (abfd)->round - 1));
02187
02188 ecoff_data (abfd)->sym_filepos = sym_base;
02189
02190 return reloc_size;
02191 }
02192
02193
02194
02195 bfd_boolean
02196 _bfd_ecoff_set_section_contents (abfd, section, location, offset, count)
02197 bfd *abfd;
02198 asection *section;
02199 const PTR location;
02200 file_ptr offset;
02201 bfd_size_type count;
02202 {
02203 file_ptr pos;
02204
02205
02206
02207 if (! abfd->output_has_begun)
02208 {
02209 if (! ecoff_compute_section_file_positions (abfd))
02210 return FALSE;
02211 }
02212
02213
02214
02215 if (strcmp (section->name, _LIB) == 0)
02216 {
02217 bfd_byte *rec, *recend;
02218
02219 rec = (bfd_byte *) location;
02220 recend = rec + count;
02221 while (rec < recend)
02222 {
02223 ++section->lma;
02224 rec += bfd_get_32 (abfd, rec) * 4;
02225 }
02226
02227 BFD_ASSERT (rec == recend);
02228 }
02229
02230 if (count == 0)
02231 return TRUE;
02232
02233 pos = section->filepos + offset;
02234 if (bfd_seek (abfd, pos, SEEK_SET) != 0
02235 || bfd_bwrite (location, count, abfd) != count)
02236 return FALSE;
02237
02238 return TRUE;
02239 }
02240
02241
02242
02243
02244 bfd_vma
02245 bfd_ecoff_get_gp_value (abfd)
02246 bfd *abfd;
02247 {
02248 if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour
02249 || bfd_get_format (abfd) != bfd_object)
02250 {
02251 bfd_set_error (bfd_error_invalid_operation);
02252 return 0;
02253 }
02254
02255 return ecoff_data (abfd)->gp;
02256 }
02257
02258
02259
02260
02261 bfd_boolean
02262 bfd_ecoff_set_gp_value (abfd, gp_value)
02263 bfd *abfd;
02264 bfd_vma gp_value;
02265 {
02266 if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour
02267 || bfd_get_format (abfd) != bfd_object)
02268 {
02269 bfd_set_error (bfd_error_invalid_operation);
02270 return FALSE;
02271 }
02272
02273 ecoff_data (abfd)->gp = gp_value;
02274
02275 return TRUE;
02276 }
02277
02278
02279
02280
02281 bfd_boolean
02282 bfd_ecoff_set_regmasks (abfd, gprmask, fprmask, cprmask)
02283 bfd *abfd;
02284 unsigned long gprmask;
02285 unsigned long fprmask;
02286 unsigned long *cprmask;
02287 {
02288 ecoff_data_type *tdata;
02289
02290 if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour
02291 || bfd_get_format (abfd) != bfd_object)
02292 {
02293 bfd_set_error (bfd_error_invalid_operation);
02294 return FALSE;
02295 }
02296
02297 tdata = ecoff_data (abfd);
02298 tdata->gprmask = gprmask;
02299 tdata->fprmask = fprmask;
02300 if (cprmask != (unsigned long *) NULL)
02301 {
02302 int i;
02303
02304 for (i = 0; i < 3; i++)
02305 tdata->cprmask[i] = cprmask[i];
02306 }
02307
02308 return TRUE;
02309 }
02310
02311
02312
02313
02314 static bfd_boolean
02315 ecoff_get_extr (sym, esym)
02316 asymbol *sym;
02317 EXTR *esym;
02318 {
02319 ecoff_symbol_type *ecoff_sym_ptr;
02320 bfd *input_bfd;
02321
02322 if (bfd_asymbol_flavour (sym) != bfd_target_ecoff_flavour
02323 || ecoffsymbol (sym)->native == NULL)
02324 {
02325
02326 if ((sym->flags & BSF_DEBUGGING) != 0
02327 || (sym->flags & BSF_LOCAL) != 0
02328 || (sym->flags & BSF_SECTION_SYM) != 0)
02329 return FALSE;
02330
02331 esym->jmptbl = 0;
02332 esym->cobol_main = 0;
02333 esym->weakext = (sym->flags & BSF_WEAK) != 0;
02334 esym->reserved = 0;
02335 esym->ifd = ifdNil;
02336
02337 esym->asym.st = stGlobal;
02338 esym->asym.sc = scAbs;
02339 esym->asym.reserved = 0;
02340 esym->asym.index = indexNil;
02341 return TRUE;
02342 }
02343
02344 ecoff_sym_ptr = ecoffsymbol (sym);
02345
02346 if (ecoff_sym_ptr->local)
02347 return FALSE;
02348
02349 input_bfd = bfd_asymbol_bfd (sym);
02350 (*(ecoff_backend (input_bfd)->debug_swap.swap_ext_in))
02351 (input_bfd, ecoff_sym_ptr->native, esym);
02352
02353
02354
02355
02356 if ((esym->asym.sc == scUndefined
02357 || esym->asym.sc == scSUndefined)
02358 && ! bfd_is_und_section (bfd_get_section (sym)))
02359 esym->asym.sc = scAbs;
02360
02361
02362
02363 if (esym->ifd != -1)
02364 {
02365 struct ecoff_debug_info *input_debug;
02366
02367 input_debug = &ecoff_data (input_bfd)->debug_info;
02368 BFD_ASSERT (esym->ifd < input_debug->symbolic_header.ifdMax);
02369 if (input_debug->ifdmap != (RFDT *) NULL)
02370 esym->ifd = input_debug->ifdmap[esym->ifd];
02371 }
02372
02373 return TRUE;
02374 }
02375
02376
02377
02378
02379 static void
02380 ecoff_set_index (sym, indx)
02381 asymbol *sym;
02382 bfd_size_type indx;
02383 {
02384 ecoff_set_sym_index (sym, indx);
02385 }
02386
02387
02388
02389 bfd_boolean
02390 _bfd_ecoff_write_object_contents (abfd)
02391 bfd *abfd;
02392 {
02393 const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
02394 const bfd_vma round = backend->round;
02395 const bfd_size_type filhsz = bfd_coff_filhsz (abfd);
02396 const bfd_size_type aoutsz = bfd_coff_aoutsz (abfd);
02397 const bfd_size_type scnhsz = bfd_coff_scnhsz (abfd);
02398 const bfd_size_type external_hdr_size
02399 = backend->debug_swap.external_hdr_size;
02400 const bfd_size_type external_reloc_size = backend->external_reloc_size;
02401 void (* const adjust_reloc_out)
02402 PARAMS ((bfd *, const arelent *, struct internal_reloc *))
02403 = backend->adjust_reloc_out;
02404 void (* const swap_reloc_out)
02405 PARAMS ((bfd *, const struct internal_reloc *, PTR))
02406 = backend->swap_reloc_out;
02407 struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info;
02408 HDRR * const symhdr = &debug->symbolic_header;
02409 asection *current;
02410 unsigned int count;
02411 bfd_size_type reloc_size;
02412 bfd_size_type text_size;
02413 bfd_vma text_start;
02414 bfd_boolean set_text_start;
02415 bfd_size_type data_size;
02416 bfd_vma data_start;
02417 bfd_boolean set_data_start;
02418 bfd_size_type bss_size;
02419 PTR buff = NULL;
02420 PTR reloc_buff = NULL;
02421 struct internal_filehdr internal_f;
02422 struct internal_aouthdr internal_a;
02423 int i;
02424
02425
02426
02427 reloc_size = ecoff_compute_reloc_file_positions (abfd);
02428
02429 count = 1;
02430 for (current = abfd->sections;
02431 current != (asection *)NULL;
02432 current = current->next)
02433 {
02434 current->target_index = count;
02435 ++count;
02436 }
02437
02438 if ((abfd->flags & D_PAGED) != 0)
02439 text_size = _bfd_ecoff_sizeof_headers (abfd, FALSE);
02440 else
02441 text_size = 0;
02442 text_start = 0;
02443 set_text_start = FALSE;
02444 data_size = 0;
02445 data_start = 0;
02446 set_data_start = FALSE;
02447 bss_size = 0;
02448
02449
02450
02451
02452
02453 {
02454 bfd_size_type siz;
02455 siz = scnhsz;
02456 if (siz < filhsz)
02457 siz = filhsz;
02458 if (siz < aoutsz)
02459 siz = aoutsz;
02460 buff = (PTR) bfd_malloc (siz);
02461 if (buff == NULL)
02462 goto error_return;
02463 }
02464
02465 internal_f.f_nscns = 0;
02466 if (bfd_seek (abfd, (file_ptr) (filhsz + aoutsz), SEEK_SET) != 0)
02467 goto error_return;
02468 for (current = abfd->sections;
02469 current != (asection *) NULL;
02470 current = current->next)
02471 {
02472 struct internal_scnhdr section;
02473 bfd_vma vma;
02474
02475 ++internal_f.f_nscns;
02476
02477 strncpy (section.s_name, current->name, sizeof section.s_name);
02478
02479
02480 vma = bfd_get_section_vma (abfd, current);
02481 if (strcmp (current->name, _LIB) == 0)
02482 section.s_vaddr = 0;
02483 else
02484 section.s_vaddr = vma;
02485
02486 section.s_paddr = current->lma;
02487 section.s_size = current->size;
02488
02489
02490 if ((current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
02491 section.s_scnptr = 0;
02492 else
02493 section.s_scnptr = current->filepos;
02494 section.s_relptr = current->rel_filepos;
02495
02496
02497
02498
02499
02500
02501
02502
02503 if (strcmp (current->name, _PDATA) != 0)
02504 section.s_lnnoptr = 0;
02505 else
02506 {
02507
02508
02509
02510
02511 section.s_lnnoptr = current->line_filepos;
02512 }
02513
02514 section.s_nreloc = current->reloc_count;
02515 section.s_nlnno = 0;
02516 section.s_flags = ecoff_sec_to_styp_flags (current->name,
02517 current->flags);
02518
02519 if (bfd_coff_swap_scnhdr_out (abfd, (PTR) §ion, buff) == 0
02520 || bfd_bwrite (buff, scnhsz, abfd) != scnhsz)
02521 goto error_return;
02522
02523 if ((section.s_flags & STYP_TEXT) != 0
02524 || ((section.s_flags & STYP_RDATA) != 0
02525 && ecoff_data (abfd)->rdata_in_text)
02526 || section.s_flags == STYP_PDATA
02527 || (section.s_flags & STYP_DYNAMIC) != 0
02528 || (section.s_flags & STYP_LIBLIST) != 0
02529 || (section.s_flags & STYP_RELDYN) != 0
02530 || section.s_flags == STYP_CONFLIC
02531 || (section.s_flags & STYP_DYNSTR) != 0
02532 || (section.s_flags & STYP_DYNSYM) != 0
02533 || (section.s_flags & STYP_HASH) != 0
02534 || (section.s_flags & STYP_ECOFF_INIT) != 0
02535 || (section.s_flags & STYP_ECOFF_FINI) != 0
02536 || section.s_flags == STYP_RCONST)
02537 {
02538 text_size += current->size;
02539 if (! set_text_start || text_start > vma)
02540 {
02541 text_start = vma;
02542 set_text_start = TRUE;
02543 }
02544 }
02545 else if ((section.s_flags & STYP_RDATA) != 0
02546 || (section.s_flags & STYP_DATA) != 0
02547 || (section.s_flags & STYP_LITA) != 0
02548 || (section.s_flags & STYP_LIT8) != 0
02549 || (section.s_flags & STYP_LIT4) != 0
02550 || (section.s_flags & STYP_SDATA) != 0
02551 || section.s_flags == STYP_XDATA
02552 || (section.s_flags & STYP_GOT) != 0)
02553 {
02554 data_size += current->size;
02555 if (! set_data_start || data_start > vma)
02556 {
02557 data_start = vma;
02558 set_data_start = TRUE;
02559 }
02560 }
02561 else if ((section.s_flags & STYP_BSS) != 0
02562 || (section.s_flags & STYP_SBSS) != 0)
02563 bss_size += current->size;
02564 else if (section.s_flags == 0
02565 || (section.s_flags & STYP_ECOFF_LIB) != 0
02566 || section.s_flags == STYP_COMMENT)
02567 ;
02568 else
02569 abort ();
02570 }
02571
02572
02573 internal_f.f_magic = ecoff_get_magic (abfd);
02574
02575
02576
02577
02578
02579
02580 internal_f.f_timdat = 0;
02581
02582 if (bfd_get_symcount (abfd) != 0)
02583 {
02584
02585
02586 internal_f.f_nsyms = external_hdr_size;
02587 internal_f.f_symptr = ecoff_data (abfd)->sym_filepos;
02588 }
02589 else
02590 {
02591 internal_f.f_nsyms = 0;
02592 internal_f.f_symptr = 0;
02593 }
02594
02595 internal_f.f_opthdr = aoutsz;
02596
02597 internal_f.f_flags = F_LNNO;
02598 if (reloc_size == 0)
02599 internal_f.f_flags |= F_RELFLG;
02600 if (bfd_get_symcount (abfd) == 0)
02601 internal_f.f_flags |= F_LSYMS;
02602 if (abfd->flags & EXEC_P)
02603 internal_f.f_flags |= F_EXEC;
02604
02605 if (bfd_little_endian (abfd))
02606 internal_f.f_flags |= F_AR32WR;
02607 else
02608 internal_f.f_flags |= F_AR32W;
02609
02610
02611 if ((abfd->flags & D_PAGED) != 0)
02612 internal_a.magic = ECOFF_AOUT_ZMAGIC;
02613 else
02614 internal_a.magic = ECOFF_AOUT_OMAGIC;
02615
02616
02617 internal_a.vstamp = symhdr->vstamp;
02618
02619
02620
02621 if ((abfd->flags & D_PAGED) != 0)
02622 {
02623 internal_a.tsize = (text_size + round - 1) &~ (round - 1);
02624 internal_a.text_start = text_start &~ (round - 1);
02625 internal_a.dsize = (data_size + round - 1) &~ (round - 1);
02626 internal_a.data_start = data_start &~ (round - 1);
02627 }
02628 else
02629 {
02630 internal_a.tsize = text_size;
02631 internal_a.text_start = text_start;
02632 internal_a.dsize = data_size;
02633 internal_a.data_start = data_start;
02634 }
02635
02636
02637
02638
02639
02640
02641 if (bss_size < internal_a.dsize - data_size)
02642 bss_size = 0;
02643 else
02644 bss_size -= internal_a.dsize - data_size;
02645 internal_a.bsize = bss_size;
02646 internal_a.bss_start = internal_a.data_start + internal_a.dsize;
02647
02648 internal_a.entry = bfd_get_start_address (abfd);
02649
02650 internal_a.gp_value = ecoff_data (abfd)->gp;
02651
02652 internal_a.gprmask = ecoff_data (abfd)->gprmask;
02653 internal_a.fprmask = ecoff_data (abfd)->fprmask;
02654 for (i = 0; i < 4; i++)
02655 internal_a.cprmask[i] = ecoff_data (abfd)->cprmask[i];
02656
02657
02658 if (backend->adjust_headers)
02659 {
02660 if (! (*backend->adjust_headers) (abfd, &internal_f, &internal_a))
02661 goto error_return;
02662 }
02663
02664
02665 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
02666 goto error_return;
02667
02668 bfd_coff_swap_filehdr_out (abfd, (PTR) &internal_f, buff);
02669 if (bfd_bwrite (buff, filhsz, abfd) != filhsz)
02670 goto error_return;
02671
02672 bfd_coff_swap_aouthdr_out (abfd, (PTR) &internal_a, buff);
02673 if (bfd_bwrite (buff, aoutsz, abfd) != aoutsz)
02674 goto error_return;
02675
02676
02677
02678
02679
02680 if (! ecoff_data (abfd)->linker)
02681 {
02682 symhdr->iextMax = 0;
02683 symhdr->issExtMax = 0;
02684 debug->external_ext = debug->external_ext_end = NULL;
02685 debug->ssext = debug->ssext_end = NULL;
02686 if (! bfd_ecoff_debug_externals (abfd, debug, &backend->debug_swap,
02687 (abfd->flags & EXEC_P) == 0,
02688 ecoff_get_extr, ecoff_set_index))
02689 goto error_return;
02690
02691
02692 for (current = abfd->sections;
02693 current != (asection *) NULL;
02694 current = current->next)
02695 {
02696 arelent **reloc_ptr_ptr;
02697 arelent **reloc_end;
02698 char *out_ptr;
02699 bfd_size_type amt;
02700
02701 if (current->reloc_count == 0)
02702 continue;
02703
02704 amt = current->reloc_count * external_reloc_size;
02705 reloc_buff = bfd_alloc (abfd, amt);
02706 if (reloc_buff == NULL)
02707 goto error_return;
02708
02709 reloc_ptr_ptr = current->orelocation;
02710 reloc_end = reloc_ptr_ptr + current->reloc_count;
02711 out_ptr = (char *) reloc_buff;
02712 for (;
02713 reloc_ptr_ptr < reloc_end;
02714 reloc_ptr_ptr++, out_ptr += external_reloc_size)
02715 {
02716 arelent *reloc;
02717 asymbol *sym;
02718 struct internal_reloc in;
02719
02720 memset ((PTR) &in, 0, sizeof in);
02721
02722 reloc = *reloc_ptr_ptr;
02723 sym = *reloc->sym_ptr_ptr;
02724
02725 in.r_vaddr = (reloc->address
02726 + bfd_get_section_vma (abfd, current));
02727 in.r_type = reloc->howto->type;
02728
02729 if ((sym->flags & BSF_SECTION_SYM) == 0)
02730 {
02731 in.r_symndx = ecoff_get_sym_index (*reloc->sym_ptr_ptr);
02732 in.r_extern = 1;
02733 }
02734 else
02735 {
02736 const char *name;
02737
02738 name = bfd_get_section_name (abfd, bfd_get_section (sym));
02739 if (strcmp (name, ".text") == 0)
02740 in.r_symndx = RELOC_SECTION_TEXT;
02741 else if (strcmp (name, ".rdata") == 0)
02742 in.r_symndx = RELOC_SECTION_RDATA;
02743 else if (strcmp (name, ".data") == 0)
02744 in.r_symndx = RELOC_SECTION_DATA;
02745 else if (strcmp (name, ".sdata") == 0)
02746 in.r_symndx = RELOC_SECTION_SDATA;
02747 else if (strcmp (name, ".sbss") == 0)
02748 in.r_symndx = RELOC_SECTION_SBSS;
02749 else if (strcmp (name, ".bss") == 0)
02750 in.r_symndx = RELOC_SECTION_BSS;
02751 else if (strcmp (name, ".init") == 0)
02752 in.r_symndx = RELOC_SECTION_INIT;
02753 else if (strcmp (name, ".lit8") == 0)
02754 in.r_symndx = RELOC_SECTION_LIT8;
02755 else if (strcmp (name, ".lit4") == 0)
02756 in.r_symndx = RELOC_SECTION_LIT4;
02757 else if (strcmp (name, ".xdata") == 0)
02758 in.r_symndx = RELOC_SECTION_XDATA;
02759 else if (strcmp (name, ".pdata") == 0)
02760 in.r_symndx = RELOC_SECTION_PDATA;
02761 else if (strcmp (name, ".fini") == 0)
02762 in.r_symndx = RELOC_SECTION_FINI;
02763 else if (strcmp (name, ".lita") == 0)
02764 in.r_symndx = RELOC_SECTION_LITA;
02765 else if (strcmp (name, "*ABS*") == 0)
02766 in.r_symndx = RELOC_SECTION_ABS;
02767 else if (strcmp (name, ".rconst") == 0)
02768 in.r_symndx = RELOC_SECTION_RCONST;
02769 else
02770 abort ();
02771 in.r_extern = 0;
02772 }
02773
02774 (*adjust_reloc_out) (abfd, reloc, &in);
02775
02776 (*swap_reloc_out) (abfd, &in, (PTR) out_ptr);
02777 }
02778
02779 if (bfd_seek (abfd, current->rel_filepos, SEEK_SET) != 0)
02780 goto error_return;
02781 amt = current->reloc_count * external_reloc_size;
02782 if (bfd_bwrite (reloc_buff, amt, abfd) != amt)
02783 goto error_return;
02784 bfd_release (abfd, reloc_buff);
02785 reloc_buff = NULL;
02786 }
02787
02788
02789 if (bfd_get_symcount (abfd) > 0)
02790 {
02791
02792 if (! bfd_ecoff_write_debug (abfd, debug, &backend->debug_swap,
02793 ecoff_data (abfd)->sym_filepos))
02794 goto error_return;
02795 }
02796 }
02797
02798
02799
02800
02801
02802 if (bfd_get_symcount (abfd) == 0
02803 && (abfd->flags & EXEC_P) != 0
02804 && (abfd->flags & D_PAGED) != 0)
02805 {
02806 char c;
02807
02808 if (bfd_seek (abfd, (file_ptr) ecoff_data (abfd)->sym_filepos - 1,
02809 SEEK_SET) != 0)
02810 goto error_return;
02811 if (bfd_bread (&c, (bfd_size_type) 1, abfd) == 0)
02812 c = 0;
02813 if (bfd_seek (abfd, (file_ptr) ecoff_data (abfd)->sym_filepos - 1,
02814 SEEK_SET) != 0)
02815 goto error_return;
02816 if (bfd_bwrite (&c, (bfd_size_type) 1, abfd) != 1)
02817 goto error_return;
02818 }
02819
02820 if (reloc_buff != NULL)
02821 bfd_release (abfd, reloc_buff);
02822 if (buff != NULL)
02823 free (buff);
02824 return TRUE;
02825 error_return:
02826 if (reloc_buff != NULL)
02827 bfd_release (abfd, reloc_buff);
02828 if (buff != NULL)
02829 free (buff);
02830 return FALSE;
02831 }
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863 #define ARMAP_BIG_ENDIAN 'B'
02864 #define ARMAP_LITTLE_ENDIAN 'L'
02865 #define ARMAP_MARKER 'E'
02866 #define ARMAP_START_LENGTH 10
02867 #define ARMAP_HEADER_MARKER_INDEX 10
02868 #define ARMAP_HEADER_ENDIAN_INDEX 11
02869 #define ARMAP_OBJECT_MARKER_INDEX 12
02870 #define ARMAP_OBJECT_ENDIAN_INDEX 13
02871 #define ARMAP_END_INDEX 14
02872 #define ARMAP_END "_ "
02873
02874
02875 #define ARMAP_HASH_MAGIC 0x9dd68ab5
02876
02877
02878
02879
02880
02881
02882 static unsigned int
02883 ecoff_armap_hash (s, rehash, size, hlog)
02884 const char *s;
02885 unsigned int *rehash;
02886 unsigned int size;
02887 unsigned int hlog;
02888 {
02889 unsigned int hash;
02890
02891 if (hlog == 0)
02892 return 0;
02893 hash = *s++;
02894 while (*s != '\0')
02895 hash = ((hash >> 27) | (hash << 5)) + *s++;
02896 hash *= ARMAP_HASH_MAGIC;
02897 *rehash = (hash & (size - 1)) | 1;
02898 return hash >> (32 - hlog);
02899 }
02900
02901
02902
02903 bfd_boolean
02904 _bfd_ecoff_slurp_armap (abfd)
02905 bfd *abfd;
02906 {
02907 char nextname[17];
02908 unsigned int i;
02909 struct areltdata *mapdata;
02910 bfd_size_type parsed_size;
02911 char *raw_armap;
02912 struct artdata *ardata;
02913 unsigned int count;
02914 char *raw_ptr;
02915 struct symdef *symdef_ptr;
02916 char *stringbase;
02917 bfd_size_type amt;
02918
02919
02920 i = bfd_bread ((PTR) nextname, (bfd_size_type) 16, abfd);
02921 if (i == 0)
02922 return TRUE;
02923 if (i != 16)
02924 return FALSE;
02925
02926 if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
02927 return FALSE;
02928
02929
02930
02931
02932
02933
02934 if (strncmp (nextname, "/ ", 16) == 0)
02935 return bfd_slurp_armap (abfd);
02936
02937
02938 if (strncmp (nextname, ecoff_backend (abfd)->armap_start,
02939 ARMAP_START_LENGTH) != 0
02940 || nextname[ARMAP_HEADER_MARKER_INDEX] != ARMAP_MARKER
02941 || (nextname[ARMAP_HEADER_ENDIAN_INDEX] != ARMAP_BIG_ENDIAN
02942 && nextname[ARMAP_HEADER_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN)
02943 || nextname[ARMAP_OBJECT_MARKER_INDEX] != ARMAP_MARKER
02944 || (nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_BIG_ENDIAN
02945 && nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN)
02946 || strncmp (nextname + ARMAP_END_INDEX,
02947 ARMAP_END, sizeof ARMAP_END - 1) != 0)
02948 {
02949 bfd_has_map (abfd) = FALSE;
02950 return TRUE;
02951 }
02952
02953
02954 if (((nextname[ARMAP_HEADER_ENDIAN_INDEX] == ARMAP_BIG_ENDIAN)
02955 ^ (bfd_header_big_endian (abfd)))
02956 || ((nextname[ARMAP_OBJECT_ENDIAN_INDEX] == ARMAP_BIG_ENDIAN)
02957 ^ (bfd_big_endian (abfd))))
02958 {
02959 bfd_set_error (bfd_error_wrong_format);
02960 return FALSE;
02961 }
02962
02963
02964 ardata = bfd_ardata (abfd);
02965 mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
02966 if (mapdata == (struct areltdata *) NULL)
02967 return FALSE;
02968 parsed_size = mapdata->parsed_size;
02969 bfd_release (abfd, (PTR) mapdata);
02970
02971 raw_armap = (char *) bfd_alloc (abfd, parsed_size);
02972 if (raw_armap == (char *) NULL)
02973 return FALSE;
02974
02975 if (bfd_bread ((PTR) raw_armap, parsed_size, abfd) != parsed_size)
02976 {
02977 if (bfd_get_error () != bfd_error_system_call)
02978 bfd_set_error (bfd_error_malformed_archive);
02979 bfd_release (abfd, (PTR) raw_armap);
02980 return FALSE;
02981 }
02982
02983 ardata->tdata = (PTR) raw_armap;
02984
02985 count = H_GET_32 (abfd, raw_armap);
02986
02987 ardata->symdef_count = 0;
02988 ardata->cache = (struct ar_cache *) NULL;
02989
02990
02991
02992 stringbase = raw_armap + count * 8 + 8;
02993
02994 #ifdef CHECK_ARMAP_HASH
02995 {
02996 unsigned int hlog;
02997
02998
02999
03000 hlog = 0;
03001 for (i = 1; i < count; i <<= 1)
03002 hlog++;
03003 BFD_ASSERT (i == count);
03004
03005 raw_ptr = raw_armap + 4;
03006 for (i = 0; i < count; i++, raw_ptr += 8)
03007 {
03008 unsigned int name_offset, file_offset;
03009 unsigned int hash, rehash, srch;
03010
03011 name_offset = H_GET_32 (abfd, raw_ptr);
03012 file_offset = H_GET_32 (abfd, (raw_ptr + 4));
03013 if (file_offset == 0)
03014 continue;
03015 hash = ecoff_armap_hash (stringbase + name_offset, &rehash, count,
03016 hlog);
03017 if (hash == i)
03018 continue;
03019
03020
03021 for (srch = (hash + rehash) & (count - 1);
03022 srch != hash && srch != i;
03023 srch = (srch + rehash) & (count - 1))
03024 BFD_ASSERT (H_GET_32 (abfd, (raw_armap + 8 + srch * 8)) != 0);
03025 BFD_ASSERT (srch == i);
03026 }
03027 }
03028
03029 #endif
03030
03031 raw_ptr = raw_armap + 4;
03032 for (i = 0; i < count; i++, raw_ptr += 8)
03033 if (H_GET_32 (abfd, (raw_ptr + 4)) != 0)
03034 ++ardata->symdef_count;
03035
03036 amt = ardata->symdef_count;
03037 amt *= sizeof (struct symdef);
03038 symdef_ptr = (struct symdef *) bfd_alloc (abfd, amt);
03039 if (!symdef_ptr)
03040 return FALSE;
03041
03042 ardata->symdefs = (carsym *) symdef_ptr;
03043
03044 raw_ptr = raw_armap + 4;
03045 for (i = 0; i < count; i++, raw_ptr += 8)
03046 {
03047 unsigned int name_offset, file_offset;
03048
03049 file_offset = H_GET_32 (abfd, (raw_ptr + 4));
03050 if (file_offset == 0)
03051 continue;
03052 name_offset = H_GET_32 (abfd, raw_ptr);
03053 symdef_ptr->s.name = stringbase + name_offset;
03054 symdef_ptr->file_offset = file_offset;
03055 ++symdef_ptr;
03056 }
03057
03058 ardata->first_file_filepos = bfd_tell (abfd);
03059
03060 ardata->first_file_filepos += ardata->first_file_filepos % 2;
03061
03062 bfd_has_map (abfd) = TRUE;
03063
03064 return TRUE;
03065 }
03066
03067
03068
03069 bfd_boolean
03070 _bfd_ecoff_write_armap (abfd, elength, map, orl_count, stridx)
03071 bfd *abfd;
03072 unsigned int elength;
03073 struct orl *map;
03074 unsigned int orl_count;
03075 int stridx;
03076 {
03077 unsigned int hashsize, hashlog;
03078 bfd_size_type symdefsize;
03079 int padit;
03080 unsigned int stringsize;
03081 unsigned int mapsize;
03082 file_ptr firstreal;
03083 struct ar_hdr hdr;
03084 struct stat statbuf;
03085 unsigned int i;
03086 bfd_byte temp[4];
03087 bfd_byte *hashtable;
03088 bfd *current;
03089 bfd *last_elt;
03090
03091
03092
03093 for (hashlog = 0; ((unsigned int) 1 << hashlog) <= 2 * orl_count; hashlog++)
03094 ;
03095 hashsize = 1 << hashlog;
03096
03097 symdefsize = hashsize * 8;
03098 padit = stridx % 2;
03099 stringsize = stridx + padit;
03100
03101
03102 mapsize = symdefsize + stringsize + 8;
03103
03104 firstreal = SARMAG + sizeof (struct ar_hdr) + mapsize + elength;
03105
03106 memset ((PTR) &hdr, 0, sizeof hdr);
03107
03108
03109 strcpy (hdr.ar_name, ecoff_backend (abfd)->armap_start);
03110 hdr.ar_name[ARMAP_HEADER_MARKER_INDEX] = ARMAP_MARKER;
03111 hdr.ar_name[ARMAP_HEADER_ENDIAN_INDEX] =
03112 (bfd_header_big_endian (abfd)
03113 ? ARMAP_BIG_ENDIAN
03114 : ARMAP_LITTLE_ENDIAN);
03115 hdr.ar_name[ARMAP_OBJECT_MARKER_INDEX] = ARMAP_MARKER;
03116 hdr.ar_name[ARMAP_OBJECT_ENDIAN_INDEX] =
03117 bfd_big_endian (abfd) ? ARMAP_BIG_ENDIAN : ARMAP_LITTLE_ENDIAN;
03118 memcpy (hdr.ar_name + ARMAP_END_INDEX, ARMAP_END, sizeof ARMAP_END - 1);
03119
03120
03121
03122
03123
03124
03125 stat (abfd->filename, &statbuf);
03126 sprintf (hdr.ar_date, "%ld", (long) (statbuf.st_mtime + 60));
03127
03128
03129
03130 hdr.ar_uid[0] = '0';
03131 hdr.ar_gid[0] = '0';
03132
03133 hdr.ar_mode[0] = '6';
03134 hdr.ar_mode[1] = '4';
03135 hdr.ar_mode[2] = '4';
03136
03137 sprintf (hdr.ar_size, "%-10d", (int) mapsize);
03138
03139 hdr.ar_fmag[0] = '`';
03140 hdr.ar_fmag[1] = '\012';
03141
03142
03143 for (i = 0; i < sizeof (struct ar_hdr); i++)
03144 if (((char *) (&hdr))[i] == '\0')
03145 (((char *) (&hdr))[i]) = ' ';
03146
03147 if (bfd_bwrite ((PTR) &hdr, (bfd_size_type) sizeof (struct ar_hdr), abfd)
03148 != sizeof (struct ar_hdr))
03149 return FALSE;
03150
03151 H_PUT_32 (abfd, hashsize, temp);
03152 if (bfd_bwrite ((PTR) temp, (bfd_size_type) 4, abfd) != 4)
03153 return FALSE;
03154
03155 hashtable = (bfd_byte *) bfd_zalloc (abfd, symdefsize);
03156 if (!hashtable)
03157 return FALSE;
03158
03159 current = abfd->archive_head;
03160 last_elt = current;
03161 for (i = 0; i < orl_count; i++)
03162 {
03163 unsigned int hash, rehash;
03164
03165
03166
03167 if (map[i].u.abfd != last_elt)
03168 {
03169 do
03170 {
03171 firstreal += arelt_size (current) + sizeof (struct ar_hdr);
03172 firstreal += firstreal % 2;
03173 current = current->next;
03174 }
03175 while (current != map[i].u.abfd);
03176 }
03177
03178 last_elt = current;
03179
03180 hash = ecoff_armap_hash (*map[i].name, &rehash, hashsize, hashlog);
03181 if (H_GET_32 (abfd, (hashtable + (hash * 8) + 4)) != 0)
03182 {
03183 unsigned int srch;
03184
03185
03186 for (srch = (hash + rehash) & (hashsize - 1);
03187 srch != hash;
03188 srch = (srch + rehash) & (hashsize - 1))
03189 if (H_GET_32 (abfd, (hashtable + (srch * 8) + 4)) == 0)
03190 break;
03191
03192 BFD_ASSERT (srch != hash);
03193
03194 hash = srch;
03195 }
03196
03197 H_PUT_32 (abfd, map[i].namidx, (hashtable + hash * 8));
03198 H_PUT_32 (abfd, firstreal, (hashtable + hash * 8 + 4));
03199 }
03200
03201 if (bfd_bwrite ((PTR) hashtable, symdefsize, abfd) != symdefsize)
03202 return FALSE;
03203
03204 bfd_release (abfd, hashtable);
03205
03206
03207 H_PUT_32 (abfd, stringsize, temp);
03208 if (bfd_bwrite ((PTR) temp, (bfd_size_type) 4, abfd) != 4)
03209 return FALSE;
03210 for (i = 0; i < orl_count; i++)
03211 {
03212 bfd_size_type len;
03213
03214 len = strlen (*map[i].name) + 1;
03215 if (bfd_bwrite ((PTR) (*map[i].name), len, abfd) != len)
03216 return FALSE;
03217 }
03218
03219
03220
03221 if (padit)
03222 {
03223 if (bfd_bwrite ("", (bfd_size_type) 1, abfd) != 1)
03224 return FALSE;
03225 }
03226
03227 return TRUE;
03228 }
03229
03230
03231
03232
03233 const bfd_target *
03234 _bfd_ecoff_archive_p (abfd)
03235 bfd *abfd;
03236 {
03237 struct artdata *tdata_hold;
03238 char armag[SARMAG + 1];
03239 bfd_size_type amt;
03240
03241 if (bfd_bread ((PTR) armag, (bfd_size_type) SARMAG, abfd) != SARMAG)
03242 {
03243 if (bfd_get_error () != bfd_error_system_call)
03244 bfd_set_error (bfd_error_wrong_format);
03245 return (const bfd_target *) NULL;
03246 }
03247
03248 if (strncmp (armag, ARMAG, SARMAG) != 0)
03249 {
03250 bfd_set_error (bfd_error_wrong_format);
03251 return NULL;
03252 }
03253
03254 tdata_hold = bfd_ardata (abfd);
03255
03256 amt = sizeof (struct artdata);
03257 bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
03258 if (bfd_ardata (abfd) == (struct artdata *) NULL)
03259 {
03260 bfd_ardata (abfd) = tdata_hold;
03261 return (const bfd_target *) NULL;
03262 }
03263
03264 bfd_ardata (abfd)->first_file_filepos = SARMAG;
03265 bfd_ardata (abfd)->cache = NULL;
03266 bfd_ardata (abfd)->archive_head = NULL;
03267 bfd_ardata (abfd)->symdefs = NULL;
03268 bfd_ardata (abfd)->extended_names = NULL;
03269 bfd_ardata (abfd)->tdata = NULL;
03270
03271 if (! _bfd_ecoff_slurp_armap (abfd)
03272 || ! _bfd_ecoff_slurp_extended_name_table (abfd))
03273 {
03274 bfd_release (abfd, bfd_ardata (abfd));
03275 bfd_ardata (abfd) = tdata_hold;
03276 return (const bfd_target *) NULL;
03277 }
03278
03279 if (bfd_has_map (abfd))
03280 {
03281 bfd *first;
03282
03283
03284
03285
03286
03287
03288
03289
03290 first = bfd_openr_next_archived_file (abfd, (bfd *) NULL);
03291 if (first != NULL)
03292 {
03293 first->target_defaulted = FALSE;
03294 if (bfd_check_format (first, bfd_object)
03295 && first->xvec != abfd->xvec)
03296 {
03297
03298
03299
03300
03301 bfd_set_error (bfd_error_wrong_object_format);
03302 bfd_ardata (abfd) = tdata_hold;
03303 return NULL;
03304 }
03305
03306 }
03307 }
03308
03309 return abfd->xvec;
03310 }
03311
03312
03313
03314 static struct bfd_hash_entry *ecoff_link_hash_newfunc
03315 PARAMS ((struct bfd_hash_entry *entry,
03316 struct bfd_hash_table *table,
03317 const char *string));
03318 static bfd_boolean ecoff_link_add_archive_symbols
03319 PARAMS ((bfd *, struct bfd_link_info *));
03320 static bfd_boolean ecoff_link_check_archive_element
03321 PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean *pneeded));
03322 static bfd_boolean ecoff_link_add_object_symbols
03323 PARAMS ((bfd *, struct bfd_link_info *));
03324 static bfd_boolean ecoff_link_add_externals
03325 PARAMS ((bfd *, struct bfd_link_info *, PTR, char *));
03326
03327
03328
03329 static struct bfd_hash_entry *
03330 ecoff_link_hash_newfunc (entry, table, string)
03331 struct bfd_hash_entry *entry;
03332 struct bfd_hash_table *table;
03333 const char *string;
03334 {
03335 struct ecoff_link_hash_entry *ret = (struct ecoff_link_hash_entry *) entry;
03336
03337
03338
03339 if (ret == (struct ecoff_link_hash_entry *) NULL)
03340 ret = ((struct ecoff_link_hash_entry *)
03341 bfd_hash_allocate (table, sizeof (struct ecoff_link_hash_entry)));
03342 if (ret == (struct ecoff_link_hash_entry *) NULL)
03343 return NULL;
03344
03345
03346 ret = ((struct ecoff_link_hash_entry *)
03347 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
03348 table, string));
03349
03350 if (ret)
03351 {
03352
03353 ret->indx = -1;
03354 ret->abfd = NULL;
03355 ret->written = 0;
03356 ret->small = 0;
03357 }
03358 memset ((PTR) &ret->esym, 0, sizeof ret->esym);
03359
03360 return (struct bfd_hash_entry *) ret;
03361 }
03362
03363
03364
03365 struct bfd_link_hash_table *
03366 _bfd_ecoff_bfd_link_hash_table_create (abfd)
03367 bfd *abfd;
03368 {
03369 struct ecoff_link_hash_table *ret;
03370 bfd_size_type amt = sizeof (struct ecoff_link_hash_table);
03371
03372 ret = (struct ecoff_link_hash_table *) bfd_malloc (amt);
03373 if (ret == NULL)
03374 return NULL;
03375 if (! _bfd_link_hash_table_init (&ret->root, abfd,
03376 ecoff_link_hash_newfunc))
03377 {
03378 free (ret);
03379 return (struct bfd_link_hash_table *) NULL;
03380 }
03381 return &ret->root;
03382 }
03383
03384
03385
03386 #define ecoff_link_hash_lookup(table, string, create, copy, follow) \
03387 ((struct ecoff_link_hash_entry *) \
03388 bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))
03389
03390
03391
03392 #define ecoff_link_hash_traverse(table, func, info) \
03393 (bfd_link_hash_traverse \
03394 (&(table)->root, \
03395 (bfd_boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func), \
03396 (info)))
03397
03398
03399
03400
03401 #define ecoff_hash_table(p) ((struct ecoff_link_hash_table *) ((p)->hash))
03402
03403
03404
03405
03406 bfd_boolean
03407 _bfd_ecoff_bfd_link_add_symbols (abfd, info)
03408 bfd *abfd;
03409 struct bfd_link_info *info;
03410 {
03411 switch (bfd_get_format (abfd))
03412 {
03413 case bfd_object:
03414 return ecoff_link_add_object_symbols (abfd, info);
03415 case bfd_archive:
03416 return ecoff_link_add_archive_symbols (abfd, info);
03417 default:
03418 bfd_set_error (bfd_error_wrong_format);
03419 return FALSE;
03420 }
03421 }
03422
03423
03424
03425
03426
03427
03428
03429
03430 static bfd_boolean
03431 ecoff_link_add_archive_symbols (abfd, info)
03432 bfd *abfd;
03433 struct bfd_link_info *info;
03434 {
03435 const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
03436 const bfd_byte *raw_armap;
03437 struct bfd_link_hash_entry **pundef;
03438 unsigned int armap_count;
03439 unsigned int armap_log;
03440 unsigned int i;
03441 const bfd_byte *hashtable;
03442 const char *stringbase;
03443
03444 if (! bfd_has_map (abfd))
03445 {
03446
03447 if (bfd_openr_next_archived_file (abfd, (bfd *) NULL) == NULL)
03448 return TRUE;
03449 bfd_set_error (bfd_error_no_armap);
03450 return FALSE;
03451 }
03452
03453
03454
03455
03456
03457 raw_armap = (const bfd_byte *) bfd_ardata (abfd)->tdata;
03458 if (raw_armap == (bfd_byte *) NULL)
03459 return (_bfd_generic_link_add_archive_symbols
03460 (abfd, info, ecoff_link_check_archive_element));
03461
03462 armap_count = H_GET_32 (abfd, raw_armap);
03463
03464 armap_log = 0;
03465 for (i = 1; i < armap_count; i <<= 1)
03466 armap_log++;
03467 BFD_ASSERT (i == armap_count);
03468
03469 hashtable = raw_armap + 4;
03470 stringbase = (const char *) raw_armap + armap_count * 8 + 8;
03471
03472
03473 pundef = &info->hash->undefs;
03474 while (*pundef != (struct bfd_link_hash_entry *) NULL)
03475 {
03476 struct bfd_link_hash_entry *h;
03477 unsigned int hash, rehash;
03478 unsigned int file_offset;
03479 const char *name;
03480 bfd *element;
03481
03482 h = *pundef;
03483
03484
03485
03486 if (h->type != bfd_link_hash_undefined
03487 && h->type != bfd_link_hash_common)
03488 {
03489
03490
03491
03492
03493
03494 if (*pundef != info->hash->undefs_tail)
03495 *pundef = (*pundef)->u.undef.next;
03496 else
03497 pundef = &(*pundef)->u.undef.next;
03498 continue;
03499 }
03500
03501
03502
03503
03504
03505 if (h->type != bfd_link_hash_undefined)
03506 {
03507 pundef = &(*pundef)->u.undef.next;
03508 continue;
03509 }
03510
03511
03512 hash = ecoff_armap_hash (h->root.string, &rehash, armap_count,
03513 armap_log);
03514
03515 file_offset = H_GET_32 (abfd, hashtable + (hash * 8) + 4);
03516 if (file_offset == 0)
03517 {
03518
03519 pundef = &(*pundef)->u.undef.next;
03520 continue;
03521 }
03522
03523 name = stringbase + H_GET_32 (abfd, hashtable + (hash * 8));
03524 if (name[0] != h->root.string[0]
03525 || strcmp (name, h->root.string) != 0)
03526 {
03527 unsigned int srch;
03528 bfd_boolean found;
03529
03530
03531 found = FALSE;
03532 for (srch = (hash + rehash) & (armap_count - 1);
03533 srch != hash;
03534 srch = (srch + rehash) & (armap_count - 1))
03535 {
03536 file_offset = H_GET_32 (abfd, hashtable + (srch * 8) + 4);
03537 if (file_offset == 0)
03538 break;
03539 name = stringbase + H_GET_32 (abfd, hashtable + (srch * 8));
03540 if (name[0] == h->root.string[0]
03541 && strcmp (name, h->root.string) == 0)
03542 {
03543 found = TRUE;
03544 break;
03545 }
03546 }
03547
03548 if (! found)
03549 {
03550 pundef = &(*pundef)->u.undef.next;
03551 continue;
03552 }
03553
03554 hash = srch;
03555 }
03556
03557 element = (*backend->get_elt_at_filepos) (abfd, (file_ptr) file_offset);
03558 if (element == (bfd *) NULL)
03559 return FALSE;
03560
03561 if (! bfd_check_format (element, bfd_object))
03562 return FALSE;
03563
03564
03565
03566
03567 if (! (*info->callbacks->add_archive_element) (info, element, name))
03568 return FALSE;
03569 if (! ecoff_link_add_object_symbols (element, info))
03570 return FALSE;
03571
03572 pundef = &(*pundef)->u.undef.next;
03573 }
03574
03575 return TRUE;
03576 }
03577
03578
03579
03580
03581 static bfd_boolean
03582 ecoff_link_check_archive_element (abfd, info, pneeded)
03583 bfd *abfd;
03584 struct bfd_link_info *info;
03585 bfd_boolean *pneeded;
03586 {
03587 const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
03588 void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *))
03589 = backend->debug_swap.swap_ext_in;
03590 HDRR *symhdr;
03591 bfd_size_type external_ext_size;
03592 PTR external_ext = NULL;
03593 bfd_size_type esize;
03594 char *ssext = NULL;
03595 char *ext_ptr;
03596 char *ext_end;
03597
03598 *pneeded = FALSE;
03599
03600 if (! ecoff_slurp_symbolic_header (abfd))
03601 goto error_return;
03602
03603
03604 if (bfd_get_symcount (abfd) == 0)
03605 goto successful_return;
03606
03607 symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
03608
03609
03610 external_ext_size = backend->debug_swap.external_ext_size;
03611 esize = symhdr->iextMax * external_ext_size;
03612 external_ext = (PTR) bfd_malloc (esize);
03613 if (external_ext == NULL && esize != 0)
03614 goto error_return;
03615
03616 if (bfd_seek (abfd, (file_ptr) symhdr->cbExtOffset, SEEK_SET) != 0
03617 || bfd_bread (external_ext, esize, abfd) != esize)
03618 goto error_return;
03619
03620 ssext = (char *) bfd_malloc ((bfd_size_type) symhdr->issExtMax);
03621 if (ssext == NULL && symhdr->issExtMax != 0)
03622 goto error_return;
03623
03624 if (bfd_seek (abfd, (file_ptr) symhdr->cbSsExtOffset, SEEK_SET) != 0
03625 || (bfd_bread (ssext, (bfd_size_type) symhdr->issExtMax, abfd)
03626 != (bfd_size_type) symhdr->issExtMax))
03627 goto error_return;
03628
03629
03630
03631 ext_ptr = (char *) external_ext;
03632 ext_end = ext_ptr + esize;
03633 for (; ext_ptr < ext_end; ext_ptr += external_ext_size)
03634 {
03635 EXTR esym;
03636 bfd_boolean def;
03637 const char *name;
03638 struct bfd_link_hash_entry *h;
03639
03640 (*swap_ext_in) (abfd, (PTR) ext_ptr, &esym);
03641
03642
03643 if (esym.asym.st != stGlobal
03644 && esym.asym.st != stLabel
03645 && esym.asym.st != stProc)
03646 continue;
03647
03648 switch (esym.asym.sc)
03649 {
03650 case scText:
03651 case scData:
03652 case scBss:
03653 case scAbs:
03654 case scSData:
03655 case scSBss:
03656 case scRData:
03657 case scCommon:
03658 case scSCommon:
03659 case scInit:
03660 case scFini:
03661 case scRConst:
03662 def = TRUE;
03663 break;
03664 default:
03665 def = FALSE;
03666 break;
03667 }
03668
03669 if (! def)
03670 continue;
03671
03672 name = ssext + esym.asym.iss;
03673 h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
03674
03675
03676
03677 if (h == (struct bfd_link_hash_entry *) NULL
03678 || h->type != bfd_link_hash_undefined)
03679 continue;
03680
03681
03682 if (! (*info->callbacks->add_archive_element) (info, abfd, name))
03683 goto error_return;
03684 if (! ecoff_link_add_externals (abfd, info, external_ext, ssext))
03685 goto error_return;
03686
03687 *pneeded = TRUE;
03688 goto successful_return;
03689 }
03690
03691 successful_return:
03692 if (external_ext != NULL)
03693 free (external_ext);
03694 if (ssext != NULL)
03695 free (ssext);
03696 return TRUE;
03697 error_return:
03698 if (external_ext != NULL)
03699 free (external_ext);
03700 if (ssext != NULL)
03701 free (ssext);
03702 return FALSE;
03703 }
03704
03705
03706
03707
03708 static bfd_boolean
03709 ecoff_link_add_object_symbols (abfd, info)
03710 bfd *abfd;
03711 struct bfd_link_info *info;
03712 {
03713 HDRR *symhdr;
03714 bfd_size_type external_ext_size;
03715 PTR external_ext = NULL;
03716 bfd_size_type esize;
03717 char *ssext = NULL;
03718 bfd_boolean result;
03719
03720 if (! ecoff_slurp_symbolic_header (abfd))
03721 return FALSE;
03722
03723
03724 if (bfd_get_symcount (abfd) == 0)
03725 return TRUE;
03726
03727 symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
03728
03729
03730 external_ext_size = ecoff_backend (abfd)->debug_swap.external_ext_size;
03731 esize = symhdr->iextMax * external_ext_size;
03732 external_ext = (PTR) bfd_malloc (esize);
03733 if (external_ext == NULL && esize != 0)
03734 goto error_return;
03735
03736 if (bfd_seek (abfd, (file_ptr) symhdr->cbExtOffset, SEEK_SET) != 0
03737 || bfd_bread (external_ext, esize, abfd) != esize)
03738 goto error_return;
03739
03740 ssext = (char *) bfd_malloc ((bfd_size_type) symhdr->issExtMax);
03741 if (ssext == NULL && symhdr->issExtMax != 0)
03742 goto error_return;
03743
03744 if (bfd_seek (abfd, (file_ptr) symhdr->cbSsExtOffset, SEEK_SET) != 0
03745 || (bfd_bread (ssext, (bfd_size_type) symhdr->issExtMax, abfd)
03746 != (bfd_size_type) symhdr->issExtMax))
03747 goto error_return;
03748
03749 result = ecoff_link_add_externals (abfd, info, external_ext, ssext);
03750
03751 if (ssext != NULL)
03752 free (ssext);
03753 if (external_ext != NULL)
03754 free (external_ext);
03755 return result;
03756
03757 error_return:
03758 if (ssext != NULL)
03759 free (ssext);
03760 if (external_ext != NULL)
03761 free (external_ext);
03762 return FALSE;
03763 }
03764
03765
03766
03767
03768
03769
03770
03771 static bfd_boolean
03772 ecoff_link_add_externals (abfd, info, external_ext, ssext)
03773 bfd *abfd;
03774 struct bfd_link_info *info;
03775 PTR external_ext;
03776 char *ssext;
03777 {
03778 const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
03779 void (* const swap_ext_in) PARAMS ((bfd *, PTR, EXTR *))
03780 = backend->debug_swap.swap_ext_in;
03781 bfd_size_type external_ext_size = backend->debug_swap.external_ext_size;
03782 unsigned long ext_count;
03783 struct bfd_link_hash_entry **sym_hash;
03784 char *ext_ptr;
03785 char *ext_end;
03786 bfd_size_type amt;
03787
03788 ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax;
03789
03790 amt = ext_count;
03791 amt *= sizeof (struct bfd_link_hash_entry *);
03792 sym_hash = (struct bfd_link_hash_entry **) bfd_alloc (abfd, amt);
03793 if (!sym_hash)
03794 return FALSE;
03795 ecoff_data (abfd)->sym_hashes = (struct ecoff_link_hash_entry **) sym_hash;
03796
03797 ext_ptr = (char *) external_ext;
03798 ext_end = ext_ptr + ext_count * external_ext_size;
03799 for (; ext_ptr < ext_end; ext_ptr += external_ext_size, sym_hash++)
03800 {
03801 EXTR esym;
03802 bfd_boolean skip;
03803 bfd_vma value;
03804 asection *section;
03805 const char *name;
03806 struct ecoff_link_hash_entry *h;
03807
03808 *sym_hash = NULL;
03809
03810 (*swap_ext_in) (abfd, (PTR) ext_ptr, &esym);
03811
03812
03813 skip = FALSE;
03814 switch (esym.asym.st)
03815 {
03816 case stGlobal:
03817 case stStatic:
03818 case stLabel:
03819 case stProc:
03820 case stStaticProc:
03821 break;
03822 default:
03823 skip = TRUE;
03824 break;
03825 }
03826
03827 if (skip)
03828 continue;
03829
03830
03831 value = esym.asym.value;
03832 switch (esym.asym.sc)
03833 {
03834 default:
03835 case scNil:
03836 case scRegister:
03837 case scCdbLocal:
03838 case scBits:
03839 case scCdbSystem:
03840 case scRegImage:
03841 case scInfo:
03842 case scUserStruct:
03843 case scVar:
03844 case scVarRegister:
03845 case scVariant:
03846 case scBasedVar:
03847 case scXData:
03848 case scPData:
03849 section = NULL;
03850 break;
03851 case scText:
03852 section = bfd_make_section_old_way (abfd, ".text");
03853 value -= section->vma;
03854 break;
03855 case scData:
03856 section = bfd_make_section_old_way (abfd, ".data");
03857 value -= section->vma;
03858 break;
03859 case scBss:
03860 section = bfd_make_section_old_way (abfd, ".bss");
03861 value -= section->vma;
03862 break;
03863 case scAbs:
03864 section = bfd_abs_section_ptr;
03865 break;
03866 case scUndefined:
03867 section = bfd_und_section_ptr;
03868 break;
03869 case scSData:
03870 section = bfd_make_section_old_way (abfd, ".sdata");
03871 value -= section->vma;
03872 break;
03873 case scSBss:
03874 section = bfd_make_section_old_way (abfd, ".sbss");
03875 value -= section->vma;
03876 break;
03877 case scRData:
03878 section = bfd_make_section_old_way (abfd, ".rdata");
03879 value -= section->vma;
03880 break;
03881 case scCommon:
03882 if (value > ecoff_data (abfd)->gp_size)
03883 {
03884 section = bfd_com_section_ptr;
03885 break;
03886 }
03887
03888 case scSCommon:
03889 if (ecoff_scom_section.name == NULL)
03890 {
03891
03892 ecoff_scom_section.name = SCOMMON;
03893 ecoff_scom_section.flags = SEC_IS_COMMON;
03894 ecoff_scom_section.output_section = &ecoff_scom_section;
03895 ecoff_scom_section.symbol = &ecoff_scom_symbol;
03896 ecoff_scom_section.symbol_ptr_ptr = &ecoff_scom_symbol_ptr;
03897 ecoff_scom_symbol.name = SCOMMON;
03898 ecoff_scom_symbol.flags = BSF_SECTION_SYM;
03899 ecoff_scom_symbol.section = &ecoff_scom_section;
03900 ecoff_scom_symbol_ptr = &ecoff_scom_symbol;
03901 }
03902 section = &ecoff_scom_section;
03903 break;
03904 case scSUndefined:
03905 section = bfd_und_section_ptr;
03906 break;
03907 case scInit:
03908 section = bfd_make_section_old_way (abfd, ".init");
03909 value -= section->vma;
03910 break;
03911 case scFini:
03912 section = bfd_make_section_old_way (abfd, ".fini");
03913 value -= section->vma;
03914 break;
03915 case scRConst:
03916 section = bfd_make_section_old_way (abfd, ".rconst");
03917 value -= section->vma;
03918 break;
03919 }
03920
03921 if (section == (asection *) NULL)
03922 continue;
03923
03924 name = ssext + esym.asym.iss;
03925
03926 if (! (_bfd_generic_link_add_one_symbol
03927 (info, abfd, name,
03928 (flagword) (esym.weakext ? BSF_WEAK : BSF_GLOBAL),
03929 section, value, (const char *) NULL, TRUE, TRUE, sym_hash)))
03930 return FALSE;
03931
03932 h = (struct ecoff_link_hash_entry *) *sym_hash;
03933
03934
03935
03936 if (info->hash->creator->flavour == bfd_get_flavour (abfd))
03937 {
03938 if (h->abfd == (bfd *) NULL
03939 || (! bfd_is_und_section (section)
03940 && (! bfd_is_com_section (section)
03941 || (h->root.type != bfd_link_hash_defined
03942 && h->root.type != bfd_link_hash_defweak))))
03943 {
03944 h->abfd = abfd;
03945 h->esym = esym;
03946 }
03947
03948
03949 if (esym.asym.sc == scSUndefined)
03950 h->small = 1;
03951
03952
03953
03954
03955
03956
03957 if (h->small
03958 && h->root.type == bfd_link_hash_common
03959 && strcmp (h->root.u.c.p->section->name, SCOMMON) != 0)
03960 {
03961 h->root.u.c.p->section = bfd_make_section_old_way (abfd,
03962 SCOMMON);
03963 h->root.u.c.p->section->flags = SEC_ALLOC;
03964 if (h->esym.asym.sc == scCommon)
03965 h->esym.asym.sc = scSCommon;
03966 }
03967 }
03968 }
03969
03970 return TRUE;
03971 }
03972
03973
03974
03975 static bfd_boolean ecoff_final_link_debug_accumulate
03976 PARAMS ((bfd *output_bfd, bfd *input_bfd, struct bfd_link_info *,
03977 PTR handle));
03978 static bfd_boolean ecoff_link_write_external
03979 PARAMS ((struct ecoff_link_hash_entry *, PTR));
03980 static bfd_boolean ecoff_indirect_link_order
03981 PARAMS ((bfd *, struct bfd_link_info *, asection *,
03982 struct bfd_link_order *));
03983 static bfd_boolean ecoff_reloc_link_order
03984 PARAMS ((bfd *, struct bfd_link_info *, asection *,
03985 struct bfd_link_order *));
03986
03987
03988
03989 struct extsym_info
03990 {
03991 bfd *abfd;
03992 struct bfd_link_info *info;
03993 };
03994
03995
03996
03997
03998
03999
04000 bfd_boolean
04001 _bfd_ecoff_bfd_final_link (abfd, info)
04002 bfd *abfd;
04003 struct bfd_link_info *info;
04004 {
04005 const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
04006 struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info;
04007 HDRR *symhdr;
04008 PTR handle;
04009 register bfd *input_bfd;
04010 asection *o;
04011 struct bfd_link_order *p;
04012 struct extsym_info einfo;
04013
04014
04015
04016 symhdr = &debug->symbolic_header;
04017 symhdr->vstamp = 0;
04018 symhdr->ilineMax = 0;
04019 symhdr->cbLine = 0;
04020 symhdr->idnMax = 0;
04021 symhdr->ipdMax = 0;
04022 symhdr->isymMax = 0;
04023 symhdr->ioptMax = 0;
04024 symhdr->iauxMax = 0;
04025 symhdr->issMax = 0;
04026 symhdr->issExtMax = 0;
04027 symhdr->ifdMax = 0;
04028 symhdr->crfd = 0;
04029 symhdr->iextMax = 0;
04030
04031
04032
04033 debug->line = NULL;
04034 debug->external_dnr = NULL;
04035 debug->external_pdr = NULL;
04036 debug->external_sym = NULL;
04037 debug->external_opt = NULL;
04038 debug->external_aux = NULL;
04039 debug->ss = NULL;
04040 debug->ssext = debug->ssext_end = NULL;
04041 debug->external_fdr = NULL;
04042 debug->external_rfd = NULL;
04043 debug->external_ext = debug->external_ext_end = NULL;
04044
04045 handle = bfd_ecoff_debug_init (abfd, debug, &backend->debug_swap, info);
04046 if (handle == (PTR) NULL)
04047 return FALSE;
04048
04049
04050 for (input_bfd = info->input_bfds;
04051 input_bfd != (bfd *) NULL;
04052 input_bfd = input_bfd->link_next)
04053 {
04054 bfd_boolean ret;
04055
04056 if (bfd_get_flavour (input_bfd) == bfd_target_ecoff_flavour)
04057 {
04058
04059
04060 if (symhdr->vstamp == 0)
04061 symhdr->vstamp
04062 = ecoff_data (input_bfd)->debug_info.symbolic_header.vstamp;
04063 ret = ecoff_final_link_debug_accumulate (abfd, input_bfd, info,
04064 handle);
04065 }
04066 else
04067 ret = bfd_ecoff_debug_accumulate_other (handle, abfd,
04068 debug, &backend->debug_swap,
04069 input_bfd, info);
04070 if (! ret)
04071 return FALSE;
04072
04073
04074 ecoff_data (abfd)->gprmask |= ecoff_data (input_bfd)->gprmask;
04075 ecoff_data (abfd)->fprmask |= ecoff_data (input_bfd)->fprmask;
04076 ecoff_data (abfd)->cprmask[0] |= ecoff_data (input_bfd)->cprmask[0];
04077 ecoff_data (abfd)->cprmask[1] |= ecoff_data (input_bfd)->cprmask[1];
04078 ecoff_data (abfd)->cprmask[2] |= ecoff_data (input_bfd)->cprmask[2];
04079 ecoff_data (abfd)->cprmask[3] |= ecoff_data (input_bfd)->cprmask[3];
04080 }
04081
04082
04083 einfo.abfd = abfd;
04084 einfo.info = info;
04085 ecoff_link_hash_traverse (ecoff_hash_table (info),
04086 ecoff_link_write_external,
04087 (PTR) &einfo);
04088
04089 if (info->relocatable)
04090 {
04091
04092
04093
04094 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
04095 {
04096 o->reloc_count = 0;
04097 for (p = o->link_order_head;
04098 p != (struct bfd_link_order *) NULL;
04099 p = p->next)
04100 if (p->type == bfd_indirect_link_order)
04101 o->reloc_count += p->u.indirect.section->reloc_count;
04102 else if (p->type == bfd_section_reloc_link_order
04103 || p->type == bfd_symbol_reloc_link_order)
04104 ++o->reloc_count;
04105 }
04106 }
04107
04108
04109 ecoff_compute_reloc_file_positions (abfd);
04110
04111
04112 if (! bfd_ecoff_write_accumulated_debug (handle, abfd, debug,
04113 &backend->debug_swap, info,
04114 ecoff_data (abfd)->sym_filepos))
04115 return FALSE;
04116
04117 bfd_ecoff_debug_free (handle, abfd, debug, &backend->debug_swap, info);
04118
04119 if (info->relocatable)
04120 {
04121
04122
04123
04124 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
04125 o->reloc_count = 0;
04126 }
04127
04128
04129 if (ecoff_data (abfd)->gp == 0)
04130 {
04131 struct bfd_link_hash_entry *h;
04132
04133 h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
04134 if (h != (struct bfd_link_hash_entry *) NULL
04135 && h->type == bfd_link_hash_defined)
04136 ecoff_data (abfd)->gp = (h->u.def.value
04137 + h->u.def.section->output_section->vma
04138 + h->u.def.section->output_offset);
04139 else if (info->relocatable)
04140 {
04141 bfd_vma lo;
04142
04143
04144 lo = (bfd_vma) -1;
04145 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
04146 {
04147 if (o->vma < lo
04148 && (strcmp (o->name, _SBSS) == 0
04149 || strcmp (o->name, _SDATA) == 0
04150 || strcmp (o->name, _LIT4) == 0
04151 || strcmp (o->name, _LIT8) == 0
04152 || strcmp (o->name, _LITA) == 0))
04153 lo = o->vma;
04154 }
04155 ecoff_data (abfd)->gp = lo + 0x8000;
04156 }
04157 else
04158 {
04159
04160
04161
04162 }
04163 }
04164
04165 for (o = abfd->sections; o != (asection *) NULL; o = o->next)
04166 {
04167 for (p = o->link_order_head;
04168 p != (struct bfd_link_order *) NULL;
04169 p = p->next)
04170 {
04171 if (p->type == bfd_indirect_link_order
04172 && (bfd_get_flavour (p->u.indirect.section->owner)
04173 == bfd_target_ecoff_flavour))
04174 {
04175 if (! ecoff_indirect_link_order (abfd, info, o, p))
04176 return FALSE;
04177 }
04178 else if (p->type == bfd_section_reloc_link_order
04179 || p->type == bfd_symbol_reloc_link_order)
04180 {
04181 if (! ecoff_reloc_link_order (abfd, info, o, p))
04182 return FALSE;
04183 }
04184 else
04185 {
04186 if (! _bfd_default_link_order (abfd, info, o, p))
04187 return FALSE;
04188 }
04189 }
04190 }
04191
04192 bfd_get_symcount (abfd) = symhdr->iextMax + symhdr->isymMax;
04193
04194 ecoff_data (abfd)->linker = TRUE;
04195
04196 return TRUE;
04197 }
04198
04199
04200
04201
04202
04203 static bfd_boolean
04204 ecoff_final_link_debug_accumulate (output_bfd, input_bfd, info, handle)
04205 bfd *output_bfd;
04206 bfd *input_bfd;
04207 struct bfd_link_info *info;
04208 PTR handle;
04209 {
04210 struct ecoff_debug_info * const debug = &ecoff_data (input_bfd)->debug_info;
04211 const struct ecoff_debug_swap * const swap =
04212 &ecoff_backend (input_bfd)->debug_swap;
04213 HDRR *symhdr = &debug->symbolic_header;
04214 bfd_boolean ret;
04215
04216 #define READ(ptr, offset, count, size, type) \
04217 if (symhdr->count == 0) \
04218 debug->ptr = NULL; \
04219 else \
04220 { \
04221 bfd_size_type amt = (bfd_size_type) size * symhdr->count; \
04222 debug->ptr = (type) bfd_malloc (amt); \
04223 if (debug->ptr == NULL) \
04224 { \
04225 ret = FALSE; \
04226 goto return_something; \
04227 } \
04228 if (bfd_seek (input_bfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
04229 || bfd_bread (debug->ptr, amt, input_bfd) != amt) \
04230 { \
04231 ret = FALSE; \
04232 goto return_something; \
04233 } \
04234 }
04235
04236
04237
04238 if (ecoff_data (input_bfd)->raw_syments == NULL)
04239 {
04240 READ (line, cbLineOffset, cbLine, sizeof (unsigned char),
04241 unsigned char *);
04242 READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, PTR);
04243 READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, PTR);
04244 READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, PTR);
04245 READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, PTR);
04246 READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
04247 union aux_ext *);
04248 READ (ss, cbSsOffset, issMax, sizeof (char), char *);
04249 READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, PTR);
04250 READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, PTR);
04251 }
04252 #undef READ
04253
04254
04255
04256 ret = (bfd_ecoff_debug_accumulate
04257 (handle, output_bfd, &ecoff_data (output_bfd)->debug_info,
04258 &ecoff_backend (output_bfd)->debug_swap,
04259 input_bfd, debug, swap, info));
04260
04261 return_something:
04262 if (ecoff_data (input_bfd)->raw_syments == NULL)
04263 {
04264 if (debug->line != NULL)
04265 free (debug->line);
04266 if (debug->external_dnr != NULL)
04267 free (debug->external_dnr);
04268 if (debug->external_pdr != NULL)
04269 free (debug->external_pdr);
04270 if (debug->external_sym != NULL)
04271 free (debug->external_sym);
04272 if (debug->external_opt != NULL)
04273 free (debug->external_opt);
04274 if (debug->external_aux != NULL)
04275 free (debug->external_aux);
04276 if (debug->ss != NULL)
04277 free (debug->ss);
04278 if (debug->external_fdr != NULL)
04279 free (debug->external_fdr);
04280 if (debug->external_rfd != NULL)
04281 free (debug->external_rfd);
04282
04283
04284
04285 debug->line = NULL;
04286 debug->external_dnr = NULL;
04287 debug->external_pdr = NULL;
04288 debug->external_sym = NULL;
04289 debug->external_opt = NULL;
04290 debug->external_aux = NULL;
04291 debug->ss = NULL;
04292 debug->external_fdr = NULL;
04293 debug->external_rfd = NULL;
04294 }
04295
04296 return ret;
04297 }
04298
04299
04300
04301
04302 static bfd_boolean
04303 ecoff_link_write_external (h, data)
04304 struct ecoff_link_hash_entry *h;
04305 PTR data;
04306 {
04307 struct extsym_info *einfo = (struct extsym_info *) data;
04308 bfd *output_bfd = einfo->abfd;
04309 bfd_boolean strip;
04310
04311 if (h->root.type == bfd_link_hash_warning)
04312 {
04313 h = (struct ecoff_link_hash_entry *) h->root.u.i.link;
04314 if (h->root.type == bfd_link_hash_new)
04315 return TRUE;
04316 }
04317
04318
04319 if (h->root.type == bfd_link_hash_undefined
04320 || h->root.type == bfd_link_hash_undefweak)
04321 strip = FALSE;
04322 else if (einfo->info->strip == strip_all
04323 || (einfo->info->strip == strip_some
04324 && bfd_hash_lookup (einfo->info->keep_hash,
04325 h->root.root.string,
04326 FALSE, FALSE) == NULL))
04327 strip = TRUE;
04328 else
04329 strip = FALSE;
04330
04331 if (strip || h->written)
04332 return TRUE;
04333
04334 if (h->abfd == (bfd *) NULL)
04335 {
04336 h->esym.jmptbl = 0;
04337 h->esym.cobol_main = 0;
04338 h->esym.weakext = 0;
04339 h->esym.reserved = 0;
04340 h->esym.ifd = ifdNil;
04341 h->esym.asym.value = 0;
04342 h->esym.asym.st = stGlobal;
04343
04344 if (h->root.type != bfd_link_hash_defined
04345 && h->root.type != bfd_link_hash_defweak)
04346 h->esym.asym.sc = scAbs;
04347 else
04348 {
04349 asection *output_section;
04350 const char *name;
04351
04352 output_section = h->root.u.def.section->output_section;
04353 name = bfd_section_name (output_section->owner, output_section);
04354
04355 if (strcmp (name, _TEXT) == 0)
04356 h->esym.asym.sc = scText;
04357 else if (strcmp (name, _DATA) == 0)
04358 h->esym.asym.sc = scData;
04359 else if (strcmp (name, _SDATA) == 0)
04360 h->esym.asym.sc = scSData;
04361 else if (strcmp (name, _RDATA) == 0)
04362 h->esym.asym.sc = scRData;
04363 else if (strcmp (name, _BSS) == 0)
04364 h->esym.asym.sc = scBss;
04365 else if (strcmp (name, _SBSS) == 0)
04366 h->esym.asym.sc = scSBss;
04367 else if (strcmp (name, _INIT) == 0)
04368 h->esym.asym.sc = scInit;
04369 else if (strcmp (name, _FINI) == 0)
04370 h->esym.asym.sc = scFini;
04371 else if (strcmp (name, _PDATA) == 0)
04372 h->esym.asym.sc = scPData;
04373 else if (strcmp (name, _XDATA) == 0)
04374 h->esym.asym.sc = scXData;
04375 else if (strcmp (name, _RCONST) == 0)
04376 h->esym.asym.sc = scRConst;
04377 else
04378 h->esym.asym.sc = scAbs;
04379 }
04380
04381 h->esym.asym.reserved = 0;
04382 h->esym.asym.index = indexNil;
04383 }
04384 else if (h->esym.ifd != -1)
04385 {
04386 struct ecoff_debug_info *debug;
04387
04388
04389
04390 debug = &ecoff_data (h->abfd)->debug_info;
04391 BFD_ASSERT (h->esym.ifd >= 0
04392 && h->esym.ifd < debug->symbolic_header.ifdMax);
04393 h->esym.ifd = debug->ifdmap[h->esym.ifd];
04394 }
04395
04396 switch (h->root.type)
04397 {
04398 default:
04399 case bfd_link_hash_warning:
04400 case bfd_link_hash_new:
04401 abort ();
04402 case bfd_link_hash_undefined:
04403 case bfd_link_hash_undefweak:
04404 if (h->esym.asym.sc != scUndefined
04405 && h->esym.asym.sc != scSUndefined)
04406 h->esym.asym.sc = scUndefined;
04407 break;
04408 case bfd_link_hash_defined:
04409 case bfd_link_hash_defweak:
04410 if (h->esym.asym.sc == scUndefined
04411 || h->esym.asym.sc == scSUndefined)
04412 h->esym.asym.sc = scAbs;
04413 else if (h->esym.asym.sc == scCommon)
04414 h->esym.asym.sc = scBss;
04415 else if (h->esym.asym.sc == scSCommon)
04416 h->esym.asym.sc = scSBss;
04417 h->esym.asym.value = (h->root.u.def.value
04418 + h->root.u.def.section->output_section->vma
04419 + h->root.u.def.section->output_offset);
04420 break;
04421 case bfd_link_hash_common:
04422 if (h->esym.asym.sc != scCommon
04423 && h->esym.asym.sc != scSCommon)
04424 h->esym.asym.sc = scCommon;
04425 h->esym.asym.value = h->root.u.c.size;
04426 break;
04427 case bfd_link_hash_indirect:
04428
04429
04430 return TRUE;
04431 }
04432
04433
04434
04435 h->indx = ecoff_data (output_bfd)->debug_info.symbolic_header.iextMax;
04436 h->written = 1;
04437
04438 return (bfd_ecoff_debug_one_external
04439 (output_bfd, &ecoff_data (output_bfd)->debug_info,
04440 &ecoff_backend (output_bfd)->debug_swap, h->root.root.string,
04441 &h->esym));
04442 }
04443
04444
04445
04446 static bfd_boolean
04447 ecoff_indirect_link_order (output_bfd, info, output_section, link_order)
04448 bfd *output_bfd;
04449 struct bfd_link_info *info;
04450 asection *output_section;
04451 struct bfd_link_order *link_order;
04452 {
04453 asection *input_section;
04454 bfd *input_bfd;
04455 bfd_byte *contents = NULL;
04456 bfd_size_type external_reloc_size;
04457 bfd_size_type external_relocs_size;
04458 PTR external_relocs = NULL;
04459
04460 BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0);
04461
04462 if (link_order->size == 0)
04463 return TRUE;
04464
04465 input_section = link_order->u.indirect.section;
04466 input_bfd = input_section->owner;
04467
04468 BFD_ASSERT (input_section->output_section == output_section);
04469 BFD_ASSERT (input_section->output_offset == link_order->offset);
04470 BFD_ASSERT (input_section->size == link_order->size);
04471
04472
04473 if (!bfd_malloc_and_get_section (input_bfd, input_section, &contents))
04474 goto error_return;
04475
04476
04477
04478 external_reloc_size = ecoff_backend (input_bfd)->external_reloc_size;
04479 external_relocs_size = external_reloc_size * input_section->reloc_count;
04480
04481 external_relocs = (PTR) bfd_malloc (external_relocs_size);
04482 if (external_relocs == NULL && external_relocs_size != 0)
04483 goto error_return;
04484
04485 if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
04486 || (bfd_bread (external_relocs, external_relocs_size, input_bfd)
04487 != external_relocs_size))
04488 goto error_return;
04489
04490
04491 if (! ((*ecoff_backend (input_bfd)->relocate_section)
04492 (output_bfd, info, input_bfd, input_section, contents,
04493 external_relocs)))
04494 goto error_return;
04495
04496
04497 if (! bfd_set_section_contents (output_bfd,
04498 output_section,
04499 contents,
04500 input_section->output_offset,
04501 input_section->size))
04502 goto error_return;
04503
04504
04505
04506
04507
04508 if (info->relocatable)
04509 {
04510 file_ptr pos = (output_section->rel_filepos
04511 + output_section->reloc_count * external_reloc_size);
04512 if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
04513 || (bfd_bwrite (external_relocs, external_relocs_size, output_bfd)
04514 != external_relocs_size))
04515 goto error_return;
04516 output_section->reloc_count += input_section->reloc_count;
04517 }
04518
04519 if (contents != NULL)
04520 free (contents);
04521 if (external_relocs != NULL)
04522 free (external_relocs);
04523 return TRUE;
04524
04525 error_return:
04526 if (contents != NULL)
04527 free (contents);
04528 if (external_relocs != NULL)
04529 free (external_relocs);
04530 return FALSE;
04531 }
04532
04533
04534
04535
04536
04537
04538 static bfd_boolean
04539 ecoff_reloc_link_order (output_bfd, info, output_section, link_order)
04540 bfd *output_bfd;
04541 struct bfd_link_info *info;
04542 asection *output_section;
04543 struct bfd_link_order *link_order;
04544 {
04545 enum bfd_link_order_type type;
04546 asection *section;
04547 bfd_vma addend;
04548 arelent rel;
04549 struct internal_reloc in;
04550 bfd_size_type external_reloc_size;
04551 bfd_byte *rbuf;
04552 bfd_boolean ok;
04553 file_ptr pos;
04554
04555 type = link_order->type;
04556 section = NULL;
04557 addend = link_order->u.reloc.p->addend;
04558
04559
04560
04561 rel.address = link_order->offset;
04562
04563 rel.howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc);
04564 if (rel.howto == 0)
04565 {
04566 bfd_set_error (bfd_error_bad_value);
04567 return FALSE;
04568 }
04569
04570 if (type == bfd_section_reloc_link_order)
04571 {
04572 section = link_order->u.reloc.p->u.section;
04573 rel.sym_ptr_ptr = section->symbol_ptr_ptr;
04574 }
04575 else
04576 {
04577 struct bfd_link_hash_entry *h;
04578
04579
04580
04581 h = bfd_wrapped_link_hash_lookup (output_bfd, info,
04582 link_order->u.reloc.p->u.name,
04583 FALSE, FALSE, FALSE);
04584 if (h != NULL
04585 && (h->type == bfd_link_hash_defined
04586 || h->type == bfd_link_hash_defweak))
04587 {
04588 type = bfd_section_reloc_link_order;
04589 section = h->u.def.section->output_section;
04590
04591
04592
04593 addend += section->vma + h->u.def.section->output_offset;
04594 }
04595 else
04596 {
04597
04598
04599
04600 rel.sym_ptr_ptr = (asymbol **) NULL;
04601 }
04602 }
04603
04604
04605
04606
04607 BFD_ASSERT (rel.howto->partial_inplace);
04608 if (addend != 0)
04609 {
04610 bfd_size_type size;
04611 bfd_reloc_status_type rstat;
04612 bfd_byte *buf;
04613
04614 size = bfd_get_reloc_size (rel.howto);
04615 buf = (bfd_byte *) bfd_zmalloc (size);
04616 if (buf == (bfd_byte *) NULL)
04617 return FALSE;
04618 rstat = _bfd_relocate_contents (rel.howto, output_bfd,
04619 (bfd_vma) addend, buf);
04620 switch (rstat)
04621 {
04622 case bfd_reloc_ok:
04623 break;
04624 default:
04625 case bfd_reloc_outofrange:
04626 abort ();
04627 case bfd_reloc_overflow:
04628 if (! ((*info->callbacks->reloc_overflow)
04629 (info, NULL,
04630 (link_order->type == bfd_section_reloc_link_order
04631 ? bfd_section_name (output_bfd, section)
04632 : link_order->u.reloc.p->u.name),
04633 rel.howto->name, addend, (bfd *) NULL,
04634 (asection *) NULL, (bfd_vma) 0)))
04635 {
04636 free (buf);
04637 return FALSE;
04638 }
04639 break;
04640 }
04641 ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf,
04642 (file_ptr) link_order->offset, size);
04643 free (buf);
04644 if (! ok)
04645 return FALSE;
04646 }
04647
04648 rel.addend = 0;
04649
04650
04651 in.r_vaddr = (rel.address
04652 + bfd_get_section_vma (output_bfd, output_section));
04653 in.r_type = rel.howto->type;
04654
04655 if (type == bfd_symbol_reloc_link_order)
04656 {
04657 struct ecoff_link_hash_entry *h;
04658
04659 h = ((struct ecoff_link_hash_entry *)
04660 bfd_wrapped_link_hash_lookup (output_bfd, info,
04661 link_order->u.reloc.p->u.name,
04662 FALSE, FALSE, TRUE));
04663 if (h != (struct ecoff_link_hash_entry *) NULL
04664 && h->indx != -1)
04665 in.r_symndx = h->indx;
04666 else
04667 {
04668 if (! ((*info->callbacks->unattached_reloc)
04669 (info, link_order->u.reloc.p->u.name, (bfd *) NULL,
04670 (asection *) NULL, (bfd_vma) 0)))
04671 return FALSE;
04672 in.r_symndx = 0;
04673 }
04674 in.r_extern = 1;
04675 }
04676 else
04677 {
04678 const char *name;
04679
04680 name = bfd_get_section_name (output_bfd, section);
04681 if (strcmp (name, ".text") == 0)
04682 in.r_symndx = RELOC_SECTION_TEXT;
04683 else if (strcmp (name, ".rdata") == 0)
04684 in.r_symndx = RELOC_SECTION_RDATA;
04685 else if (strcmp (name, ".data") == 0)
04686 in.r_symndx = RELOC_SECTION_DATA;
04687 else if (strcmp (name, ".sdata") == 0)
04688 in.r_symndx = RELOC_SECTION_SDATA;
04689 else if (strcmp (name, ".sbss") == 0)
04690 in.r_symndx = RELOC_SECTION_SBSS;
04691 else if (strcmp (name, ".bss") == 0)
04692 in.r_symndx = RELOC_SECTION_BSS;
04693 else if (strcmp (name, ".init") == 0)
04694 in.r_symndx = RELOC_SECTION_INIT;
04695 else if (strcmp (name, ".lit8") == 0)
04696 in.r_symndx = RELOC_SECTION_LIT8;
04697 else if (strcmp (name, ".lit4") == 0)
04698 in.r_symndx = RELOC_SECTION_LIT4;
04699 else if (strcmp (name, ".xdata") == 0)
04700 in.r_symndx = RELOC_SECTION_XDATA;
04701 else if (strcmp (name, ".pdata") == 0)
04702 in.r_symndx = RELOC_SECTION_PDATA;
04703 else if (strcmp (name, ".fini") == 0)
04704 in.r_symndx = RELOC_SECTION_FINI;
04705 else if (strcmp (name, ".lita") == 0)
04706 in.r_symndx = RELOC_SECTION_LITA;
04707 else if (strcmp (name, "*ABS*") == 0)
04708 in.r_symndx = RELOC_SECTION_ABS;
04709 else if (strcmp (name, ".rconst") == 0)
04710 in.r_symndx = RELOC_SECTION_RCONST;
04711 else
04712 abort ();
04713 in.r_extern = 0;
04714 }
04715
04716
04717 (*ecoff_backend (output_bfd)->adjust_reloc_out) (output_bfd, &rel, &in);
04718
04719
04720 external_reloc_size = ecoff_backend (output_bfd)->external_reloc_size;
04721 rbuf = (bfd_byte *) bfd_malloc (external_reloc_size);
04722 if (rbuf == (bfd_byte *) NULL)
04723 return FALSE;
04724
04725 (*ecoff_backend (output_bfd)->swap_reloc_out) (output_bfd, &in, (PTR) rbuf);
04726
04727 pos = (output_section->rel_filepos
04728 + output_section->reloc_count * external_reloc_size);
04729 ok = (bfd_seek (output_bfd, pos, SEEK_SET) == 0
04730 && (bfd_bwrite ((PTR) rbuf, external_reloc_size, output_bfd)
04731 == external_reloc_size));
04732
04733 if (ok)
04734 ++output_section->reloc_count;
04735
04736 free (rbuf);
04737
04738 return ok;
04739 }