00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include "bfd.h"
00045 #include "sysdep.h"
00046 #include "libbfd.h"
00047 #include "coff/internal.h"
00048 #include "libcoff.h"
00049
00050 static void coff_fix_symbol_name
00051 PARAMS ((bfd *, asymbol *, combined_entry_type *, bfd_size_type *,
00052 asection **, bfd_size_type *));
00053 static bfd_boolean coff_write_symbol
00054 PARAMS ((bfd *, asymbol *, combined_entry_type *, bfd_vma *,
00055 bfd_size_type *, asection **, bfd_size_type *));
00056 static bfd_boolean coff_write_alien_symbol
00057 PARAMS ((bfd *, asymbol *, bfd_vma *, bfd_size_type *,
00058 asection **, bfd_size_type *));
00059 static bfd_boolean coff_write_native_symbol
00060 PARAMS ((bfd *, coff_symbol_type *, bfd_vma *, bfd_size_type *,
00061 asection **, bfd_size_type *));
00062 static void coff_pointerize_aux
00063 PARAMS ((bfd *, combined_entry_type *, combined_entry_type *,
00064 unsigned int, combined_entry_type *));
00065 static bfd_boolean make_a_section_from_file
00066 PARAMS ((bfd *, struct internal_scnhdr *, unsigned int));
00067 static const bfd_target *coff_real_object_p
00068 PARAMS ((bfd *, unsigned, struct internal_filehdr *,
00069 struct internal_aouthdr *));
00070 static void fixup_symbol_value
00071 PARAMS ((bfd *, coff_symbol_type *, struct internal_syment *));
00072 static char *build_debug_section
00073 PARAMS ((bfd *));
00074 static char *copy_name
00075 PARAMS ((bfd *, char *, size_t));
00076
00077 #define STRING_SIZE_SIZE (4)
00078
00079
00080
00081 static bfd_boolean
00082 make_a_section_from_file (abfd, hdr, target_index)
00083 bfd *abfd;
00084 struct internal_scnhdr *hdr;
00085 unsigned int target_index;
00086 {
00087 asection *return_section;
00088 char *name;
00089 bfd_boolean result = TRUE;
00090 flagword flags;
00091
00092 name = NULL;
00093
00094
00095 if (bfd_coff_long_section_names (abfd)
00096 && hdr->s_name[0] == '/')
00097 {
00098 char buf[SCNNMLEN];
00099 long strindex;
00100 char *p;
00101 const char *strings;
00102
00103 memcpy (buf, hdr->s_name + 1, SCNNMLEN - 1);
00104 buf[SCNNMLEN - 1] = '\0';
00105 strindex = strtol (buf, &p, 10);
00106 if (*p == '\0' && strindex >= 0)
00107 {
00108 strings = _bfd_coff_read_string_table (abfd);
00109 if (strings == NULL)
00110 return FALSE;
00111
00112
00113
00114 strings += strindex;
00115 name = bfd_alloc (abfd, (bfd_size_type) strlen (strings) + 1);
00116 if (name == NULL)
00117 return FALSE;
00118 strcpy (name, strings);
00119 }
00120 }
00121
00122 if (name == NULL)
00123 {
00124
00125 name = bfd_alloc (abfd, (bfd_size_type) sizeof (hdr->s_name) + 1);
00126 if (name == NULL)
00127 return FALSE;
00128 strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name));
00129 name[sizeof (hdr->s_name)] = 0;
00130 }
00131
00132 return_section = bfd_make_section_anyway (abfd, name);
00133 if (return_section == NULL)
00134 return FALSE;
00135
00136 return_section->vma = hdr->s_vaddr;
00137 return_section->lma = hdr->s_paddr;
00138 return_section->size = hdr->s_size;
00139 return_section->filepos = hdr->s_scnptr;
00140 return_section->rel_filepos = hdr->s_relptr;
00141 return_section->reloc_count = hdr->s_nreloc;
00142
00143 bfd_coff_set_alignment_hook (abfd, return_section, hdr);
00144
00145 return_section->line_filepos = hdr->s_lnnoptr;
00146
00147 return_section->lineno_count = hdr->s_nlnno;
00148 return_section->userdata = NULL;
00149 return_section->next = (asection *) NULL;
00150 return_section->target_index = target_index;
00151
00152 if (! bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name, return_section,
00153 & flags))
00154 result = FALSE;
00155
00156 return_section->flags = flags;
00157
00158
00159
00160 if ((return_section->flags & SEC_COFF_SHARED_LIBRARY) != 0)
00161 return_section->lineno_count = 0;
00162
00163 if (hdr->s_nreloc != 0)
00164 return_section->flags |= SEC_RELOC;
00165
00166 if (hdr->s_scnptr != 0)
00167 return_section->flags |= SEC_HAS_CONTENTS;
00168
00169 return result;
00170 }
00171
00172
00173
00174
00175 static const bfd_target *
00176 coff_real_object_p (abfd, nscns, internal_f, internal_a)
00177 bfd *abfd;
00178 unsigned nscns;
00179 struct internal_filehdr *internal_f;
00180 struct internal_aouthdr *internal_a;
00181 {
00182 flagword oflags = abfd->flags;
00183 bfd_vma ostart = bfd_get_start_address (abfd);
00184 PTR tdata;
00185 PTR tdata_save;
00186 bfd_size_type readsize;
00187 unsigned int scnhsz;
00188 char *external_sections;
00189
00190 if (!(internal_f->f_flags & F_RELFLG))
00191 abfd->flags |= HAS_RELOC;
00192 if ((internal_f->f_flags & F_EXEC))
00193 abfd->flags |= EXEC_P;
00194 if (!(internal_f->f_flags & F_LNNO))
00195 abfd->flags |= HAS_LINENO;
00196 if (!(internal_f->f_flags & F_LSYMS))
00197 abfd->flags |= HAS_LOCALS;
00198
00199
00200 if ((internal_f->f_flags & F_EXEC) != 0)
00201 abfd->flags |= D_PAGED;
00202
00203 bfd_get_symcount (abfd) = internal_f->f_nsyms;
00204 if (internal_f->f_nsyms)
00205 abfd->flags |= HAS_SYMS;
00206
00207 if (internal_a != (struct internal_aouthdr *) NULL)
00208 bfd_get_start_address (abfd) = internal_a->entry;
00209 else
00210 bfd_get_start_address (abfd) = 0;
00211
00212
00213
00214 tdata_save = abfd->tdata.any;
00215 tdata = bfd_coff_mkobject_hook (abfd, (PTR) internal_f, (PTR) internal_a);
00216 if (tdata == NULL)
00217 goto fail2;
00218
00219 scnhsz = bfd_coff_scnhsz (abfd);
00220 readsize = (bfd_size_type) nscns * scnhsz;
00221 external_sections = (char *) bfd_alloc (abfd, readsize);
00222 if (!external_sections)
00223 goto fail;
00224
00225 if (bfd_bread ((PTR) external_sections, readsize, abfd) != readsize)
00226 goto fail;
00227
00228
00229
00230 if (! bfd_coff_set_arch_mach_hook (abfd, (PTR) internal_f))
00231 goto fail;
00232
00233
00234 if (nscns != 0)
00235 {
00236 unsigned int i;
00237 for (i = 0; i < nscns; i++)
00238 {
00239 struct internal_scnhdr tmp;
00240 bfd_coff_swap_scnhdr_in (abfd,
00241 (PTR) (external_sections + i * scnhsz),
00242 (PTR) & tmp);
00243 if (! make_a_section_from_file (abfd, &tmp, i + 1))
00244 goto fail;
00245 }
00246 }
00247
00248 return abfd->xvec;
00249
00250 fail:
00251 bfd_release (abfd, tdata);
00252 fail2:
00253 abfd->tdata.any = tdata_save;
00254 abfd->flags = oflags;
00255 bfd_get_start_address (abfd) = ostart;
00256 return (const bfd_target *) NULL;
00257 }
00258
00259
00260
00261
00262 const bfd_target *
00263 coff_object_p (abfd)
00264 bfd *abfd;
00265 {
00266 bfd_size_type filhsz;
00267 bfd_size_type aoutsz;
00268 unsigned int nscns;
00269 PTR filehdr;
00270 struct internal_filehdr internal_f;
00271 struct internal_aouthdr internal_a;
00272
00273
00274 filhsz = bfd_coff_filhsz (abfd);
00275 aoutsz = bfd_coff_aoutsz (abfd);
00276
00277 filehdr = bfd_alloc (abfd, filhsz);
00278 if (filehdr == NULL)
00279 return NULL;
00280 if (bfd_bread (filehdr, filhsz, abfd) != filhsz)
00281 {
00282 if (bfd_get_error () != bfd_error_system_call)
00283 bfd_set_error (bfd_error_wrong_format);
00284 bfd_release (abfd, filehdr);
00285 return NULL;
00286 }
00287 bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f);
00288 bfd_release (abfd, filehdr);
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 if (! bfd_coff_bad_format_hook (abfd, &internal_f)
00299 || internal_f.f_opthdr > aoutsz)
00300 {
00301 bfd_set_error (bfd_error_wrong_format);
00302 return NULL;
00303 }
00304 nscns = internal_f.f_nscns;
00305
00306 if (internal_f.f_opthdr)
00307 {
00308 PTR opthdr;
00309
00310 opthdr = bfd_alloc (abfd, aoutsz);
00311 if (opthdr == NULL)
00312 return NULL;
00313 if (bfd_bread (opthdr, (bfd_size_type) internal_f.f_opthdr, abfd)
00314 != internal_f.f_opthdr)
00315 {
00316 bfd_release (abfd, opthdr);
00317 return NULL;
00318 }
00319 bfd_coff_swap_aouthdr_in (abfd, opthdr, (PTR) &internal_a);
00320 bfd_release (abfd, opthdr);
00321 }
00322
00323 return coff_real_object_p (abfd, nscns, &internal_f,
00324 (internal_f.f_opthdr != 0
00325 ? &internal_a
00326 : (struct internal_aouthdr *) NULL));
00327 }
00328
00329
00330
00331 asection *
00332 coff_section_from_bfd_index (abfd, index)
00333 bfd *abfd;
00334 int index;
00335 {
00336 struct bfd_section *answer = abfd->sections;
00337
00338 if (index == N_ABS)
00339 return bfd_abs_section_ptr;
00340 if (index == N_UNDEF)
00341 return bfd_und_section_ptr;
00342 if (index == N_DEBUG)
00343 return bfd_abs_section_ptr;
00344
00345 while (answer)
00346 {
00347 if (answer->target_index == index)
00348 return answer;
00349 answer = answer->next;
00350 }
00351
00352
00353
00354 return bfd_und_section_ptr;
00355 }
00356
00357
00358
00359 long
00360 coff_get_symtab_upper_bound (abfd)
00361 bfd *abfd;
00362 {
00363 if (!bfd_coff_slurp_symbol_table (abfd))
00364 return -1;
00365
00366 return (bfd_get_symcount (abfd) + 1) * (sizeof (coff_symbol_type *));
00367 }
00368
00369
00370
00371 long
00372 coff_canonicalize_symtab (abfd, alocation)
00373 bfd *abfd;
00374 asymbol **alocation;
00375 {
00376 unsigned int counter;
00377 coff_symbol_type *symbase;
00378 coff_symbol_type **location = (coff_symbol_type **) alocation;
00379
00380 if (!bfd_coff_slurp_symbol_table (abfd))
00381 return -1;
00382
00383 symbase = obj_symbols (abfd);
00384 counter = bfd_get_symcount (abfd);
00385 while (counter-- > 0)
00386 *location++ = symbase++;
00387
00388 *location = NULL;
00389
00390 return bfd_get_symcount (abfd);
00391 }
00392
00393
00394
00395
00396 const char *
00397 _bfd_coff_internal_syment_name (abfd, sym, buf)
00398 bfd *abfd;
00399 const struct internal_syment *sym;
00400 char *buf;
00401 {
00402
00403
00404 if (sym->_n._n_n._n_zeroes != 0
00405 || sym->_n._n_n._n_offset == 0)
00406 {
00407 memcpy (buf, sym->_n._n_name, SYMNMLEN);
00408 buf[SYMNMLEN] = '\0';
00409 return buf;
00410 }
00411 else
00412 {
00413 const char *strings;
00414
00415 BFD_ASSERT (sym->_n._n_n._n_offset >= STRING_SIZE_SIZE);
00416 strings = obj_coff_strings (abfd);
00417 if (strings == NULL)
00418 {
00419 strings = _bfd_coff_read_string_table (abfd);
00420 if (strings == NULL)
00421 return NULL;
00422 }
00423 return strings + sym->_n._n_n._n_offset;
00424 }
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 struct internal_reloc *
00437 _bfd_coff_read_internal_relocs (abfd, sec, cache, external_relocs,
00438 require_internal, internal_relocs)
00439 bfd *abfd;
00440 asection *sec;
00441 bfd_boolean cache;
00442 bfd_byte *external_relocs;
00443 bfd_boolean require_internal;
00444 struct internal_reloc *internal_relocs;
00445 {
00446 bfd_size_type relsz;
00447 bfd_byte *free_external = NULL;
00448 struct internal_reloc *free_internal = NULL;
00449 bfd_byte *erel;
00450 bfd_byte *erel_end;
00451 struct internal_reloc *irel;
00452 bfd_size_type amt;
00453
00454 if (coff_section_data (abfd, sec) != NULL
00455 && coff_section_data (abfd, sec)->relocs != NULL)
00456 {
00457 if (! require_internal)
00458 return coff_section_data (abfd, sec)->relocs;
00459 memcpy (internal_relocs, coff_section_data (abfd, sec)->relocs,
00460 sec->reloc_count * sizeof (struct internal_reloc));
00461 return internal_relocs;
00462 }
00463
00464 relsz = bfd_coff_relsz (abfd);
00465
00466 amt = sec->reloc_count * relsz;
00467 if (external_relocs == NULL)
00468 {
00469 free_external = (bfd_byte *) bfd_malloc (amt);
00470 if (free_external == NULL && sec->reloc_count > 0)
00471 goto error_return;
00472 external_relocs = free_external;
00473 }
00474
00475 if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
00476 || bfd_bread (external_relocs, amt, abfd) != amt)
00477 goto error_return;
00478
00479 if (internal_relocs == NULL)
00480 {
00481 amt = sec->reloc_count;
00482 amt *= sizeof (struct internal_reloc);
00483 free_internal = (struct internal_reloc *) bfd_malloc (amt);
00484 if (free_internal == NULL && sec->reloc_count > 0)
00485 goto error_return;
00486 internal_relocs = free_internal;
00487 }
00488
00489
00490 erel = external_relocs;
00491 erel_end = erel + relsz * sec->reloc_count;
00492 irel = internal_relocs;
00493 for (; erel < erel_end; erel += relsz, irel++)
00494 bfd_coff_swap_reloc_in (abfd, (PTR) erel, (PTR) irel);
00495
00496 if (free_external != NULL)
00497 {
00498 free (free_external);
00499 free_external = NULL;
00500 }
00501
00502 if (cache && free_internal != NULL)
00503 {
00504 if (coff_section_data (abfd, sec) == NULL)
00505 {
00506 amt = sizeof (struct coff_section_tdata);
00507 sec->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
00508 if (sec->used_by_bfd == NULL)
00509 goto error_return;
00510 coff_section_data (abfd, sec)->contents = NULL;
00511 }
00512 coff_section_data (abfd, sec)->relocs = free_internal;
00513 }
00514
00515 return internal_relocs;
00516
00517 error_return:
00518 if (free_external != NULL)
00519 free (free_external);
00520 if (free_internal != NULL)
00521 free (free_internal);
00522 return NULL;
00523 }
00524
00525
00526
00527 int
00528 coff_count_linenumbers (abfd)
00529 bfd *abfd;
00530 {
00531 unsigned int limit = bfd_get_symcount (abfd);
00532 unsigned int i;
00533 int total = 0;
00534 asymbol **p;
00535 asection *s;
00536
00537 if (limit == 0)
00538 {
00539
00540
00541 for (s = abfd->sections; s != NULL; s = s->next)
00542 total += s->lineno_count;
00543 return total;
00544 }
00545
00546 for (s = abfd->sections; s != NULL; s = s->next)
00547 BFD_ASSERT (s->lineno_count == 0);
00548
00549 for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
00550 {
00551 asymbol *q_maybe = *p;
00552
00553 if (bfd_family_coff (bfd_asymbol_bfd (q_maybe)))
00554 {
00555 coff_symbol_type *q = coffsymbol (q_maybe);
00556
00557
00558
00559
00560 if (q->lineno != NULL
00561 && q->symbol.section->owner != NULL)
00562 {
00563
00564
00565 alent *l = q->lineno;
00566
00567 do
00568 {
00569 asection * sec = q->symbol.section->output_section;
00570
00571
00572 if (! bfd_is_const_section (sec))
00573 sec->lineno_count ++;
00574
00575 ++total;
00576 ++l;
00577 }
00578 while (l->line_number != 0);
00579 }
00580 }
00581 }
00582
00583 return total;
00584 }
00585
00586
00587
00588
00589 coff_symbol_type *
00590 coff_symbol_from (ignore_abfd, symbol)
00591 bfd *ignore_abfd ATTRIBUTE_UNUSED;
00592 asymbol *symbol;
00593 {
00594 if (!bfd_family_coff (bfd_asymbol_bfd (symbol)))
00595 return (coff_symbol_type *) NULL;
00596
00597 if (bfd_asymbol_bfd (symbol)->tdata.coff_obj_data == (coff_data_type *) NULL)
00598 return (coff_symbol_type *) NULL;
00599
00600 return (coff_symbol_type *) symbol;
00601 }
00602
00603 static void
00604 fixup_symbol_value (abfd, coff_symbol_ptr, syment)
00605 bfd *abfd;
00606 coff_symbol_type *coff_symbol_ptr;
00607 struct internal_syment *syment;
00608 {
00609
00610
00611 if (bfd_is_com_section (coff_symbol_ptr->symbol.section))
00612 {
00613
00614 syment->n_scnum = N_UNDEF;
00615 syment->n_value = coff_symbol_ptr->symbol.value;
00616 }
00617 else if ((coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) != 0
00618 && (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING_RELOC) == 0)
00619 {
00620 syment->n_value = coff_symbol_ptr->symbol.value;
00621 }
00622 else if (bfd_is_und_section (coff_symbol_ptr->symbol.section))
00623 {
00624 syment->n_scnum = N_UNDEF;
00625 syment->n_value = 0;
00626 }
00627
00628 else
00629 {
00630 if (coff_symbol_ptr->symbol.section)
00631 {
00632 syment->n_scnum =
00633 coff_symbol_ptr->symbol.section->output_section->target_index;
00634
00635 syment->n_value = (coff_symbol_ptr->symbol.value
00636 + coff_symbol_ptr->symbol.section->output_offset);
00637 if (! obj_pe (abfd))
00638 {
00639 syment->n_value += (syment->n_sclass == C_STATLAB)
00640 ? coff_symbol_ptr->symbol.section->output_section->lma
00641 : coff_symbol_ptr->symbol.section->output_section->vma;
00642 }
00643 }
00644 else
00645 {
00646 BFD_ASSERT (0);
00647
00648 syment->n_scnum = N_ABS;
00649 syment->n_value = coff_symbol_ptr->symbol.value;
00650 }
00651 }
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661 bfd_boolean
00662 coff_renumber_symbols (bfd_ptr, first_undef)
00663 bfd *bfd_ptr;
00664 int *first_undef;
00665 {
00666 unsigned int symbol_count = bfd_get_symcount (bfd_ptr);
00667 asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
00668 unsigned int native_index = 0;
00669 struct internal_syment *last_file = (struct internal_syment *) NULL;
00670 unsigned int symbol_index;
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 {
00683 asymbol **newsyms;
00684 unsigned int i;
00685 bfd_size_type amt;
00686
00687 amt = sizeof (asymbol *) * ((bfd_size_type) symbol_count + 1);
00688 newsyms = (asymbol **) bfd_alloc (bfd_ptr, amt);
00689 if (!newsyms)
00690 return FALSE;
00691 bfd_ptr->outsymbols = newsyms;
00692 for (i = 0; i < symbol_count; i++)
00693 if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0
00694 || (!bfd_is_und_section (symbol_ptr_ptr[i]->section)
00695 && !bfd_is_com_section (symbol_ptr_ptr[i]->section)
00696 && ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) != 0
00697 || ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK))
00698 == 0))))
00699 *newsyms++ = symbol_ptr_ptr[i];
00700
00701 for (i = 0; i < symbol_count; i++)
00702 if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0
00703 && !bfd_is_und_section (symbol_ptr_ptr[i]->section)
00704 && (bfd_is_com_section (symbol_ptr_ptr[i]->section)
00705 || ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) == 0
00706 && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK))
00707 != 0))))
00708 *newsyms++ = symbol_ptr_ptr[i];
00709
00710 *first_undef = newsyms - bfd_ptr->outsymbols;
00711
00712 for (i = 0; i < symbol_count; i++)
00713 if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0
00714 && bfd_is_und_section (symbol_ptr_ptr[i]->section))
00715 *newsyms++ = symbol_ptr_ptr[i];
00716 *newsyms = (asymbol *) NULL;
00717 symbol_ptr_ptr = bfd_ptr->outsymbols;
00718 }
00719
00720 for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
00721 {
00722 coff_symbol_type *coff_symbol_ptr = coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]);
00723 symbol_ptr_ptr[symbol_index]->udata.i = symbol_index;
00724 if (coff_symbol_ptr && coff_symbol_ptr->native)
00725 {
00726 combined_entry_type *s = coff_symbol_ptr->native;
00727 int i;
00728
00729 if (s->u.syment.n_sclass == C_FILE)
00730 {
00731 if (last_file != (struct internal_syment *) NULL)
00732 last_file->n_value = native_index;
00733 last_file = &(s->u.syment);
00734 }
00735 else
00736 {
00737
00738
00739
00740
00741 fixup_symbol_value (bfd_ptr, coff_symbol_ptr, &(s->u.syment));
00742 }
00743 for (i = 0; i < s->u.syment.n_numaux + 1; i++)
00744 s[i].offset = native_index++;
00745 }
00746 else
00747 {
00748 native_index++;
00749 }
00750 }
00751 obj_conv_table_size (bfd_ptr) = native_index;
00752
00753 return TRUE;
00754 }
00755
00756
00757
00758
00759
00760 void
00761 coff_mangle_symbols (bfd_ptr)
00762 bfd *bfd_ptr;
00763 {
00764 unsigned int symbol_count = bfd_get_symcount (bfd_ptr);
00765 asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
00766 unsigned int symbol_index;
00767
00768 for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
00769 {
00770 coff_symbol_type *coff_symbol_ptr =
00771 coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]);
00772
00773 if (coff_symbol_ptr && coff_symbol_ptr->native)
00774 {
00775 int i;
00776 combined_entry_type *s = coff_symbol_ptr->native;
00777
00778 if (s->fix_value)
00779 {
00780
00781 s->u.syment.n_value =
00782 (bfd_vma)((combined_entry_type *)
00783 ((unsigned long) s->u.syment.n_value))->offset;
00784 s->fix_value = 0;
00785 }
00786 if (s->fix_line)
00787 {
00788
00789
00790
00791 s->u.syment.n_value =
00792 (coff_symbol_ptr->symbol.section->output_section->line_filepos
00793 + s->u.syment.n_value * bfd_coff_linesz (bfd_ptr));
00794 coff_symbol_ptr->symbol.section =
00795 coff_section_from_bfd_index (bfd_ptr, N_DEBUG);
00796 BFD_ASSERT (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING);
00797 }
00798 for (i = 0; i < s->u.syment.n_numaux; i++)
00799 {
00800 combined_entry_type *a = s + i + 1;
00801 if (a->fix_tag)
00802 {
00803 a->u.auxent.x_sym.x_tagndx.l =
00804 a->u.auxent.x_sym.x_tagndx.p->offset;
00805 a->fix_tag = 0;
00806 }
00807 if (a->fix_end)
00808 {
00809 a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l =
00810 a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset;
00811 a->fix_end = 0;
00812 }
00813 if (a->fix_scnlen)
00814 {
00815 a->u.auxent.x_csect.x_scnlen.l =
00816 a->u.auxent.x_csect.x_scnlen.p->offset;
00817 a->fix_scnlen = 0;
00818 }
00819 }
00820 }
00821 }
00822 }
00823
00824 static void
00825 coff_fix_symbol_name (abfd, symbol, native, string_size_p,
00826 debug_string_section_p, debug_string_size_p)
00827 bfd *abfd;
00828 asymbol *symbol;
00829 combined_entry_type *native;
00830 bfd_size_type *string_size_p;
00831 asection **debug_string_section_p;
00832 bfd_size_type *debug_string_size_p;
00833 {
00834 unsigned int name_length;
00835 union internal_auxent *auxent;
00836 char *name = (char *) (symbol->name);
00837
00838 if (name == (char *) NULL)
00839 {
00840
00841 symbol->name = "strange";
00842 name = (char *) symbol->name;
00843 }
00844 name_length = strlen (name);
00845
00846 if (native->u.syment.n_sclass == C_FILE
00847 && native->u.syment.n_numaux > 0)
00848 {
00849 unsigned int filnmlen;
00850
00851 if (bfd_coff_force_symnames_in_strings (abfd))
00852 {
00853 native->u.syment._n._n_n._n_offset =
00854 (*string_size_p + STRING_SIZE_SIZE);
00855 native->u.syment._n._n_n._n_zeroes = 0;
00856 *string_size_p += 6;
00857 }
00858 else
00859 strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN);
00860
00861 auxent = &(native + 1)->u.auxent;
00862
00863 filnmlen = bfd_coff_filnmlen (abfd);
00864
00865 if (bfd_coff_long_filenames (abfd))
00866 {
00867 if (name_length <= filnmlen)
00868 {
00869 strncpy (auxent->x_file.x_fname, name, filnmlen);
00870 }
00871 else
00872 {
00873 auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE;
00874 auxent->x_file.x_n.x_zeroes = 0;
00875 *string_size_p += name_length + 1;
00876 }
00877 }
00878 else
00879 {
00880 strncpy (auxent->x_file.x_fname, name, filnmlen);
00881 if (name_length > filnmlen)
00882 name[filnmlen] = '\0';
00883 }
00884 }
00885 else
00886 {
00887 if (name_length <= SYMNMLEN && !bfd_coff_force_symnames_in_strings (abfd))
00888 {
00889
00890 strncpy (native->u.syment._n._n_name, symbol->name, SYMNMLEN);
00891 }
00892 else if (!bfd_coff_symname_in_debug (abfd, &native->u.syment))
00893 {
00894 native->u.syment._n._n_n._n_offset = (*string_size_p
00895 + STRING_SIZE_SIZE);
00896 native->u.syment._n._n_n._n_zeroes = 0;
00897 *string_size_p += name_length + 1;
00898 }
00899 else
00900 {
00901 file_ptr filepos;
00902 bfd_byte buf[4];
00903 int prefix_len = bfd_coff_debug_string_prefix_length (abfd);
00904
00905
00906
00907
00908
00909
00910 if (*debug_string_section_p == (asection *) NULL)
00911 *debug_string_section_p = bfd_get_section_by_name (abfd, ".debug");
00912 filepos = bfd_tell (abfd);
00913 if (prefix_len == 4)
00914 bfd_put_32 (abfd, (bfd_vma) (name_length + 1), buf);
00915 else
00916 bfd_put_16 (abfd, (bfd_vma) (name_length + 1), buf);
00917
00918 if (!bfd_set_section_contents (abfd,
00919 *debug_string_section_p,
00920 (PTR) buf,
00921 (file_ptr) *debug_string_size_p,
00922 (bfd_size_type) prefix_len)
00923 || !bfd_set_section_contents (abfd,
00924 *debug_string_section_p,
00925 (PTR) symbol->name,
00926 (file_ptr) (*debug_string_size_p
00927 + prefix_len),
00928 (bfd_size_type) name_length + 1))
00929 abort ();
00930 if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
00931 abort ();
00932 native->u.syment._n._n_n._n_offset =
00933 *debug_string_size_p + prefix_len;
00934 native->u.syment._n._n_n._n_zeroes = 0;
00935 *debug_string_size_p += name_length + 1 + prefix_len;
00936 }
00937 }
00938 }
00939
00940
00941
00942
00943
00944 #define set_index(symbol, idx) ((symbol)->udata.i = (idx))
00945
00946
00947
00948 static bfd_boolean
00949 coff_write_symbol (abfd, symbol, native, written, string_size_p,
00950 debug_string_section_p, debug_string_size_p)
00951 bfd *abfd;
00952 asymbol *symbol;
00953 combined_entry_type *native;
00954 bfd_vma *written;
00955 bfd_size_type *string_size_p;
00956 asection **debug_string_section_p;
00957 bfd_size_type *debug_string_size_p;
00958 {
00959 unsigned int numaux = native->u.syment.n_numaux;
00960 int type = native->u.syment.n_type;
00961 int class = native->u.syment.n_sclass;
00962 PTR buf;
00963 bfd_size_type symesz;
00964
00965 if (native->u.syment.n_sclass == C_FILE)
00966 symbol->flags |= BSF_DEBUGGING;
00967
00968 if (symbol->flags & BSF_DEBUGGING
00969 && bfd_is_abs_section (symbol->section))
00970 {
00971 native->u.syment.n_scnum = N_DEBUG;
00972 }
00973 else if (bfd_is_abs_section (symbol->section))
00974 {
00975 native->u.syment.n_scnum = N_ABS;
00976 }
00977 else if (bfd_is_und_section (symbol->section))
00978 {
00979 native->u.syment.n_scnum = N_UNDEF;
00980 }
00981 else
00982 {
00983 native->u.syment.n_scnum =
00984 symbol->section->output_section->target_index;
00985 }
00986
00987 coff_fix_symbol_name (abfd, symbol, native, string_size_p,
00988 debug_string_section_p, debug_string_size_p);
00989
00990 symesz = bfd_coff_symesz (abfd);
00991 buf = bfd_alloc (abfd, symesz);
00992 if (!buf)
00993 return FALSE;
00994 bfd_coff_swap_sym_out (abfd, &native->u.syment, buf);
00995 if (bfd_bwrite (buf, symesz, abfd) != symesz)
00996 return FALSE;
00997 bfd_release (abfd, buf);
00998
00999 if (native->u.syment.n_numaux > 0)
01000 {
01001 bfd_size_type auxesz;
01002 unsigned int j;
01003
01004 auxesz = bfd_coff_auxesz (abfd);
01005 buf = bfd_alloc (abfd, auxesz);
01006 if (!buf)
01007 return FALSE;
01008 for (j = 0; j < native->u.syment.n_numaux; j++)
01009 {
01010 bfd_coff_swap_aux_out (abfd,
01011 &((native + j + 1)->u.auxent),
01012 type,
01013 class,
01014 (int) j,
01015 native->u.syment.n_numaux,
01016 buf);
01017 if (bfd_bwrite (buf, auxesz, abfd) != auxesz)
01018 return FALSE;
01019 }
01020 bfd_release (abfd, buf);
01021 }
01022
01023
01024 set_index (symbol, *written);
01025
01026 *written += numaux + 1;
01027 return TRUE;
01028 }
01029
01030
01031
01032
01033
01034 static bfd_boolean
01035 coff_write_alien_symbol (abfd, symbol, written, string_size_p,
01036 debug_string_section_p, debug_string_size_p)
01037 bfd *abfd;
01038 asymbol *symbol;
01039 bfd_vma *written;
01040 bfd_size_type *string_size_p;
01041 asection **debug_string_section_p;
01042 bfd_size_type *debug_string_size_p;
01043 {
01044 combined_entry_type *native;
01045 combined_entry_type dummy;
01046
01047 native = &dummy;
01048 native->u.syment.n_type = T_NULL;
01049 native->u.syment.n_flags = 0;
01050 if (bfd_is_und_section (symbol->section))
01051 {
01052 native->u.syment.n_scnum = N_UNDEF;
01053 native->u.syment.n_value = symbol->value;
01054 }
01055 else if (bfd_is_com_section (symbol->section))
01056 {
01057 native->u.syment.n_scnum = N_UNDEF;
01058 native->u.syment.n_value = symbol->value;
01059 }
01060 else if (symbol->flags & BSF_DEBUGGING)
01061 {
01062
01063
01064
01065
01066 symbol->name = "";
01067 return TRUE;
01068 }
01069 else
01070 {
01071 native->u.syment.n_scnum =
01072 symbol->section->output_section->target_index;
01073 native->u.syment.n_value = (symbol->value
01074 + symbol->section->output_offset);
01075 if (! obj_pe (abfd))
01076 native->u.syment.n_value += symbol->section->output_section->vma;
01077
01078
01079
01080 {
01081 coff_symbol_type *c = coff_symbol_from (abfd, symbol);
01082 if (c != (coff_symbol_type *) NULL)
01083 native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags;
01084 }
01085 }
01086
01087 native->u.syment.n_type = 0;
01088 if (symbol->flags & BSF_LOCAL)
01089 native->u.syment.n_sclass = C_STAT;
01090 else if (symbol->flags & BSF_WEAK)
01091 native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
01092 else
01093 native->u.syment.n_sclass = C_EXT;
01094 native->u.syment.n_numaux = 0;
01095
01096 return coff_write_symbol (abfd, symbol, native, written, string_size_p,
01097 debug_string_section_p, debug_string_size_p);
01098 }
01099
01100
01101
01102 static bfd_boolean
01103 coff_write_native_symbol (abfd, symbol, written, string_size_p,
01104 debug_string_section_p, debug_string_size_p)
01105 bfd *abfd;
01106 coff_symbol_type *symbol;
01107 bfd_vma *written;
01108 bfd_size_type *string_size_p;
01109 asection **debug_string_section_p;
01110 bfd_size_type *debug_string_size_p;
01111 {
01112 combined_entry_type *native = symbol->native;
01113 alent *lineno = symbol->lineno;
01114
01115
01116
01117
01118 if (lineno && !symbol->done_lineno && symbol->symbol.section->owner != NULL)
01119 {
01120 unsigned int count = 0;
01121 lineno[count].u.offset = *written;
01122 if (native->u.syment.n_numaux)
01123 {
01124 union internal_auxent *a = &((native + 1)->u.auxent);
01125
01126 a->x_sym.x_fcnary.x_fcn.x_lnnoptr =
01127 symbol->symbol.section->output_section->moving_line_filepos;
01128 }
01129
01130
01131 count++;
01132 while (lineno[count].line_number != 0)
01133 {
01134 lineno[count].u.offset +=
01135 (symbol->symbol.section->output_section->vma
01136 + symbol->symbol.section->output_offset);
01137 count++;
01138 }
01139 symbol->done_lineno = TRUE;
01140
01141 if (! bfd_is_const_section (symbol->symbol.section->output_section))
01142 symbol->symbol.section->output_section->moving_line_filepos +=
01143 count * bfd_coff_linesz (abfd);
01144 }
01145
01146 return coff_write_symbol (abfd, &(symbol->symbol), native, written,
01147 string_size_p, debug_string_section_p,
01148 debug_string_size_p);
01149 }
01150
01151
01152
01153 bfd_boolean
01154 coff_write_symbols (abfd)
01155 bfd *abfd;
01156 {
01157 bfd_size_type string_size;
01158 asection *debug_string_section;
01159 bfd_size_type debug_string_size;
01160 unsigned int i;
01161 unsigned int limit = bfd_get_symcount (abfd);
01162 bfd_vma written = 0;
01163 asymbol **p;
01164
01165 string_size = 0;
01166 debug_string_section = NULL;
01167 debug_string_size = 0;
01168
01169
01170
01171
01172
01173 if (bfd_coff_long_section_names (abfd))
01174 {
01175 asection *o;
01176
01177 for (o = abfd->sections; o != NULL; o = o->next)
01178 {
01179 size_t len;
01180
01181 len = strlen (o->name);
01182 if (len > SCNNMLEN)
01183 string_size += len + 1;
01184 }
01185 }
01186
01187
01188 if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
01189 return FALSE;
01190
01191
01192
01193 written = 0;
01194 for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
01195 {
01196 asymbol *symbol = *p;
01197 coff_symbol_type *c_symbol = coff_symbol_from (abfd, symbol);
01198
01199 if (c_symbol == (coff_symbol_type *) NULL
01200 || c_symbol->native == (combined_entry_type *) NULL)
01201 {
01202 if (!coff_write_alien_symbol (abfd, symbol, &written, &string_size,
01203 &debug_string_section,
01204 &debug_string_size))
01205 return FALSE;
01206 }
01207 else
01208 {
01209 if (!coff_write_native_symbol (abfd, c_symbol, &written,
01210 &string_size, &debug_string_section,
01211 &debug_string_size))
01212 return FALSE;
01213 }
01214 }
01215
01216 obj_raw_syment_count (abfd) = written;
01217
01218
01219
01220 if (string_size != 0)
01221 {
01222 unsigned int size = string_size + STRING_SIZE_SIZE;
01223 bfd_byte buffer[STRING_SIZE_SIZE];
01224
01225 #if STRING_SIZE_SIZE == 4
01226 H_PUT_32 (abfd, size, buffer);
01227 #else
01228 #error Change H_PUT_32
01229 #endif
01230 if (bfd_bwrite ((PTR) buffer, (bfd_size_type) sizeof (buffer), abfd)
01231 != sizeof (buffer))
01232 return FALSE;
01233
01234
01235
01236 if (bfd_coff_long_section_names (abfd))
01237 {
01238 asection *o;
01239
01240 for (o = abfd->sections; o != NULL; o = o->next)
01241 {
01242 size_t len;
01243
01244 len = strlen (o->name);
01245 if (len > SCNNMLEN)
01246 {
01247 if (bfd_bwrite (o->name, (bfd_size_type) (len + 1), abfd)
01248 != len + 1)
01249 return FALSE;
01250 }
01251 }
01252 }
01253
01254 for (p = abfd->outsymbols, i = 0;
01255 i < limit;
01256 i++, p++)
01257 {
01258 asymbol *q = *p;
01259 size_t name_length = strlen (q->name);
01260 coff_symbol_type *c_symbol = coff_symbol_from (abfd, q);
01261 size_t maxlen;
01262
01263
01264
01265
01266
01267
01268
01269
01270 if (c_symbol == NULL
01271 || c_symbol->native == NULL)
01272 {
01273
01274
01275 maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
01276 }
01277 else if (bfd_coff_symname_in_debug (abfd,
01278 &c_symbol->native->u.syment))
01279 {
01280
01281
01282 maxlen = name_length;
01283 }
01284 else if (c_symbol->native->u.syment.n_sclass == C_FILE
01285 && c_symbol->native->u.syment.n_numaux > 0)
01286 {
01287 if (bfd_coff_force_symnames_in_strings (abfd))
01288 {
01289 if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6)
01290 return FALSE;
01291 }
01292 maxlen = bfd_coff_filnmlen (abfd);
01293 }
01294 else
01295 maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
01296
01297 if (name_length > maxlen)
01298 {
01299 if (bfd_bwrite ((PTR) (q->name), (bfd_size_type) name_length + 1,
01300 abfd) != name_length + 1)
01301 return FALSE;
01302 }
01303 }
01304 }
01305 else
01306 {
01307
01308
01309
01310 unsigned int size = STRING_SIZE_SIZE;
01311 bfd_byte buffer[STRING_SIZE_SIZE];
01312
01313 #if STRING_SIZE_SIZE == 4
01314 H_PUT_32 (abfd, size, buffer);
01315 #else
01316 #error Change H_PUT_32
01317 #endif
01318 if (bfd_bwrite ((PTR) buffer, (bfd_size_type) STRING_SIZE_SIZE, abfd)
01319 != STRING_SIZE_SIZE)
01320 return FALSE;
01321 }
01322
01323
01324
01325
01326
01327
01328 BFD_ASSERT (debug_string_size == 0
01329 || (debug_string_section != (asection *) NULL
01330 && (BFD_ALIGN (debug_string_size,
01331 1 << debug_string_section->alignment_power)
01332 == debug_string_section->size)));
01333
01334 return TRUE;
01335 }
01336
01337 bfd_boolean
01338 coff_write_linenumbers (abfd)
01339 bfd *abfd;
01340 {
01341 asection *s;
01342 bfd_size_type linesz;
01343 PTR buff;
01344
01345 linesz = bfd_coff_linesz (abfd);
01346 buff = bfd_alloc (abfd, linesz);
01347 if (!buff)
01348 return FALSE;
01349 for (s = abfd->sections; s != (asection *) NULL; s = s->next)
01350 {
01351 if (s->lineno_count)
01352 {
01353 asymbol **q = abfd->outsymbols;
01354 if (bfd_seek (abfd, s->line_filepos, SEEK_SET) != 0)
01355 return FALSE;
01356
01357 while (*q)
01358 {
01359 asymbol *p = *q;
01360 if (p->section->output_section == s)
01361 {
01362 alent *l =
01363 BFD_SEND (bfd_asymbol_bfd (p), _get_lineno,
01364 (bfd_asymbol_bfd (p), p));
01365 if (l)
01366 {
01367
01368 struct internal_lineno out;
01369 memset ((PTR) & out, 0, sizeof (out));
01370 out.l_lnno = 0;
01371 out.l_addr.l_symndx = l->u.offset;
01372 bfd_coff_swap_lineno_out (abfd, &out, buff);
01373 if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd)
01374 != linesz)
01375 return FALSE;
01376 l++;
01377 while (l->line_number)
01378 {
01379 out.l_lnno = l->line_number;
01380 out.l_addr.l_symndx = l->u.offset;
01381 bfd_coff_swap_lineno_out (abfd, &out, buff);
01382 if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd)
01383 != linesz)
01384 return FALSE;
01385 l++;
01386 }
01387 }
01388 }
01389 q++;
01390 }
01391 }
01392 }
01393 bfd_release (abfd, buff);
01394 return TRUE;
01395 }
01396
01397 alent *
01398 coff_get_lineno (ignore_abfd, symbol)
01399 bfd *ignore_abfd ATTRIBUTE_UNUSED;
01400 asymbol *symbol;
01401 {
01402 return coffsymbol (symbol)->lineno;
01403 }
01404
01405
01406
01407
01408 static void
01409 coff_pointerize_aux (abfd, table_base, symbol, indaux, auxent)
01410 bfd *abfd;
01411 combined_entry_type *table_base;
01412 combined_entry_type *symbol;
01413 unsigned int indaux;
01414 combined_entry_type *auxent;
01415 {
01416 unsigned int type = symbol->u.syment.n_type;
01417 unsigned int class = symbol->u.syment.n_sclass;
01418
01419 if (coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook)
01420 {
01421 if ((*coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook)
01422 (abfd, table_base, symbol, indaux, auxent))
01423 return;
01424 }
01425
01426
01427 if (class == C_STAT && type == T_NULL)
01428 return;
01429 if (class == C_FILE)
01430 return;
01431
01432
01433 #define N_TMASK coff_data (abfd)->local_n_tmask
01434 #define N_BTSHFT coff_data (abfd)->local_n_btshft
01435 if ((ISFCN (type) || ISTAG (class) || class == C_BLOCK || class == C_FCN)
01436 && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0)
01437 {
01438 auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p =
01439 table_base + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
01440 auxent->fix_end = 1;
01441 }
01442
01443
01444 if (auxent->u.auxent.x_sym.x_tagndx.l > 0)
01445 {
01446 auxent->u.auxent.x_sym.x_tagndx.p =
01447 table_base + auxent->u.auxent.x_sym.x_tagndx.l;
01448 auxent->fix_tag = 1;
01449 }
01450 }
01451
01452
01453
01454
01455
01456 static char *
01457 build_debug_section (abfd)
01458 bfd *abfd;
01459 {
01460 char *debug_section;
01461 file_ptr position;
01462 bfd_size_type sec_size;
01463
01464 asection *sect = bfd_get_section_by_name (abfd, ".debug");
01465
01466 if (!sect)
01467 {
01468 bfd_set_error (bfd_error_no_debug_section);
01469 return NULL;
01470 }
01471
01472 sec_size = sect->size;
01473 debug_section = (PTR) bfd_alloc (abfd, sec_size);
01474 if (debug_section == NULL)
01475 return NULL;
01476
01477
01478
01479
01480
01481 position = bfd_tell (abfd);
01482 if (bfd_seek (abfd, sect->filepos, SEEK_SET) != 0
01483 || bfd_bread (debug_section, sec_size, abfd) != sec_size
01484 || bfd_seek (abfd, position, SEEK_SET) != 0)
01485 return NULL;
01486 return debug_section;
01487 }
01488
01489
01490
01491
01492 static char *
01493 copy_name (abfd, name, maxlen)
01494 bfd *abfd;
01495 char *name;
01496 size_t maxlen;
01497 {
01498 size_t len;
01499 char *newname;
01500
01501 for (len = 0; len < maxlen; ++len)
01502 {
01503 if (name[len] == '\0')
01504 {
01505 break;
01506 }
01507 }
01508
01509 if ((newname = (PTR) bfd_alloc (abfd, (bfd_size_type) len + 1)) == NULL)
01510 return (NULL);
01511 strncpy (newname, name, len);
01512 newname[len] = '\0';
01513 return newname;
01514 }
01515
01516
01517
01518 bfd_boolean
01519 _bfd_coff_get_external_symbols (abfd)
01520 bfd *abfd;
01521 {
01522 bfd_size_type symesz;
01523 bfd_size_type size;
01524 PTR syms;
01525
01526 if (obj_coff_external_syms (abfd) != NULL)
01527 return TRUE;
01528
01529 symesz = bfd_coff_symesz (abfd);
01530
01531 size = obj_raw_syment_count (abfd) * symesz;
01532
01533 syms = (PTR) bfd_malloc (size);
01534 if (syms == NULL && size != 0)
01535 return FALSE;
01536
01537 if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
01538 || bfd_bread (syms, size, abfd) != size)
01539 {
01540 if (syms != NULL)
01541 free (syms);
01542 return FALSE;
01543 }
01544
01545 obj_coff_external_syms (abfd) = syms;
01546
01547 return TRUE;
01548 }
01549
01550
01551
01552
01553
01554 const char *
01555 _bfd_coff_read_string_table (abfd)
01556 bfd *abfd;
01557 {
01558 char extstrsize[STRING_SIZE_SIZE];
01559 bfd_size_type strsize;
01560 char *strings;
01561 file_ptr pos;
01562
01563 if (obj_coff_strings (abfd) != NULL)
01564 return obj_coff_strings (abfd);
01565
01566 if (obj_sym_filepos (abfd) == 0)
01567 {
01568 bfd_set_error (bfd_error_no_symbols);
01569 return NULL;
01570 }
01571
01572 pos = obj_sym_filepos (abfd);
01573 pos += obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd);
01574 if (bfd_seek (abfd, pos, SEEK_SET) != 0)
01575 return NULL;
01576
01577 if (bfd_bread (extstrsize, (bfd_size_type) sizeof extstrsize, abfd)
01578 != sizeof extstrsize)
01579 {
01580 if (bfd_get_error () != bfd_error_file_truncated)
01581 return NULL;
01582
01583
01584 strsize = STRING_SIZE_SIZE;
01585 }
01586 else
01587 {
01588 #if STRING_SIZE_SIZE == 4
01589 strsize = H_GET_32 (abfd, extstrsize);
01590 #else
01591 #error Change H_GET_32
01592 #endif
01593 }
01594
01595 if (strsize < STRING_SIZE_SIZE)
01596 {
01597 (*_bfd_error_handler)
01598 (_("%B: bad string table size %lu"), abfd, (unsigned long) strsize);
01599 bfd_set_error (bfd_error_bad_value);
01600 return NULL;
01601 }
01602
01603 strings = (char *) bfd_malloc (strsize);
01604 if (strings == NULL)
01605 return NULL;
01606
01607 if (bfd_bread (strings + STRING_SIZE_SIZE, strsize - STRING_SIZE_SIZE, abfd)
01608 != strsize - STRING_SIZE_SIZE)
01609 {
01610 free (strings);
01611 return NULL;
01612 }
01613
01614 obj_coff_strings (abfd) = strings;
01615
01616 return strings;
01617 }
01618
01619
01620
01621 bfd_boolean
01622 _bfd_coff_free_symbols (abfd)
01623 bfd *abfd;
01624 {
01625 if (obj_coff_external_syms (abfd) != NULL
01626 && ! obj_coff_keep_syms (abfd))
01627 {
01628 free (obj_coff_external_syms (abfd));
01629 obj_coff_external_syms (abfd) = NULL;
01630 }
01631 if (obj_coff_strings (abfd) != NULL
01632 && ! obj_coff_keep_strings (abfd))
01633 {
01634 free (obj_coff_strings (abfd));
01635 obj_coff_strings (abfd) = NULL;
01636 }
01637 return TRUE;
01638 }
01639
01640
01641
01642
01643
01644
01645 combined_entry_type *
01646 coff_get_normalized_symtab (abfd)
01647 bfd *abfd;
01648 {
01649 combined_entry_type *internal;
01650 combined_entry_type *internal_ptr;
01651 combined_entry_type *symbol_ptr;
01652 combined_entry_type *internal_end;
01653 size_t symesz;
01654 char *raw_src;
01655 char *raw_end;
01656 const char *string_table = NULL;
01657 char *debug_section = NULL;
01658 bfd_size_type size;
01659
01660 if (obj_raw_syments (abfd) != NULL)
01661 return obj_raw_syments (abfd);
01662
01663 size = obj_raw_syment_count (abfd) * sizeof (combined_entry_type);
01664 internal = (combined_entry_type *) bfd_zalloc (abfd, size);
01665 if (internal == NULL && size != 0)
01666 return NULL;
01667 internal_end = internal + obj_raw_syment_count (abfd);
01668
01669 if (! _bfd_coff_get_external_symbols (abfd))
01670 return NULL;
01671
01672 raw_src = (char *) obj_coff_external_syms (abfd);
01673
01674
01675 symesz = bfd_coff_symesz (abfd);
01676 raw_end = (char *) raw_src + obj_raw_syment_count (abfd) * symesz;
01677
01678
01679
01680
01681
01682 for (internal_ptr = internal;
01683 raw_src < raw_end;
01684 raw_src += symesz, internal_ptr++)
01685 {
01686
01687 unsigned int i;
01688 bfd_coff_swap_sym_in (abfd, (PTR) raw_src,
01689 (PTR) & internal_ptr->u.syment);
01690 symbol_ptr = internal_ptr;
01691
01692 for (i = 0;
01693 i < symbol_ptr->u.syment.n_numaux;
01694 i++)
01695 {
01696 internal_ptr++;
01697 raw_src += symesz;
01698 bfd_coff_swap_aux_in (abfd, (PTR) raw_src,
01699 symbol_ptr->u.syment.n_type,
01700 symbol_ptr->u.syment.n_sclass,
01701 (int) i, symbol_ptr->u.syment.n_numaux,
01702 &(internal_ptr->u.auxent));
01703 coff_pointerize_aux (abfd, internal, symbol_ptr, i,
01704 internal_ptr);
01705 }
01706 }
01707
01708
01709 obj_coff_keep_strings (abfd) = TRUE;
01710 if (! _bfd_coff_free_symbols (abfd))
01711 return NULL;
01712
01713 for (internal_ptr = internal; internal_ptr < internal_end;
01714 internal_ptr++)
01715 {
01716 if (internal_ptr->u.syment.n_sclass == C_FILE
01717 && internal_ptr->u.syment.n_numaux > 0)
01718 {
01719
01720
01721 if ((internal_ptr + 1)->u.auxent.x_file.x_n.x_zeroes == 0)
01722 {
01723
01724 if (string_table == NULL)
01725 {
01726 string_table = _bfd_coff_read_string_table (abfd);
01727 if (string_table == NULL)
01728 return NULL;
01729 }
01730
01731 internal_ptr->u.syment._n._n_n._n_offset =
01732 ((long)
01733 (string_table
01734 + (internal_ptr + 1)->u.auxent.x_file.x_n.x_offset));
01735 }
01736 else
01737 {
01738
01739
01740
01741 if (internal_ptr->u.syment.n_numaux > 1
01742 && coff_data (abfd)->pe)
01743 {
01744 internal_ptr->u.syment._n._n_n._n_offset =
01745 ((long)
01746 copy_name (abfd,
01747 (internal_ptr + 1)->u.auxent.x_file.x_fname,
01748 internal_ptr->u.syment.n_numaux * symesz));
01749 }
01750 else
01751 {
01752 internal_ptr->u.syment._n._n_n._n_offset =
01753 ((long)
01754 copy_name (abfd,
01755 (internal_ptr + 1)->u.auxent.x_file.x_fname,
01756 (size_t) bfd_coff_filnmlen (abfd)));
01757 }
01758 }
01759 }
01760 else
01761 {
01762 if (internal_ptr->u.syment._n._n_n._n_zeroes != 0)
01763 {
01764
01765 size_t i;
01766 char *newstring;
01767
01768
01769
01770 for (i = 0; i < 8; ++i)
01771 if (internal_ptr->u.syment._n._n_name[i] == '\0')
01772 break;
01773
01774 newstring = (PTR) bfd_zalloc (abfd, (bfd_size_type) (i + 1));
01775 if (newstring == NULL)
01776 return (NULL);
01777 strncpy (newstring, internal_ptr->u.syment._n._n_name, i);
01778 internal_ptr->u.syment._n._n_n._n_offset = (long int) newstring;
01779 internal_ptr->u.syment._n._n_n._n_zeroes = 0;
01780 }
01781 else if (internal_ptr->u.syment._n._n_n._n_offset == 0)
01782 internal_ptr->u.syment._n._n_n._n_offset = (long int) "";
01783 else if (!bfd_coff_symname_in_debug (abfd, &internal_ptr->u.syment))
01784 {
01785
01786
01787 if (string_table == NULL)
01788 {
01789 string_table = _bfd_coff_read_string_table (abfd);
01790 if (string_table == NULL)
01791 return NULL;
01792 }
01793 internal_ptr->u.syment._n._n_n._n_offset =
01794 ((long int)
01795 (string_table
01796 + internal_ptr->u.syment._n._n_n._n_offset));
01797 }
01798 else
01799 {
01800
01801 if (debug_section == NULL)
01802 debug_section = build_debug_section (abfd);
01803 internal_ptr->u.syment._n._n_n._n_offset = (long int)
01804 (debug_section + internal_ptr->u.syment._n._n_n._n_offset);
01805 }
01806 }
01807 internal_ptr += internal_ptr->u.syment.n_numaux;
01808 }
01809
01810 obj_raw_syments (abfd) = internal;
01811 BFD_ASSERT (obj_raw_syment_count (abfd)
01812 == (unsigned int) (internal_ptr - internal));
01813
01814 return (internal);
01815 }
01816
01817 long
01818 coff_get_reloc_upper_bound (abfd, asect)
01819 bfd *abfd;
01820 sec_ptr asect;
01821 {
01822 if (bfd_get_format (abfd) != bfd_object)
01823 {
01824 bfd_set_error (bfd_error_invalid_operation);
01825 return -1;
01826 }
01827 return (asect->reloc_count + 1) * sizeof (arelent *);
01828 }
01829
01830 asymbol *
01831 coff_make_empty_symbol (abfd)
01832 bfd *abfd;
01833 {
01834 bfd_size_type amt = sizeof (coff_symbol_type);
01835 coff_symbol_type *new = (coff_symbol_type *) bfd_zalloc (abfd, amt);
01836 if (new == NULL)
01837 return (NULL);
01838 new->symbol.section = 0;
01839 new->native = 0;
01840 new->lineno = (alent *) NULL;
01841 new->done_lineno = FALSE;
01842 new->symbol.the_bfd = abfd;
01843 return &new->symbol;
01844 }
01845
01846
01847
01848 asymbol *
01849 coff_bfd_make_debug_symbol (abfd, ptr, sz)
01850 bfd *abfd;
01851 PTR ptr ATTRIBUTE_UNUSED;
01852 unsigned long sz ATTRIBUTE_UNUSED;
01853 {
01854 bfd_size_type amt = sizeof (coff_symbol_type);
01855 coff_symbol_type *new = (coff_symbol_type *) bfd_alloc (abfd, amt);
01856 if (new == NULL)
01857 return (NULL);
01858
01859
01860 amt = sizeof (combined_entry_type) * 10;
01861 new->native = (combined_entry_type *) bfd_zalloc (abfd, amt);
01862 if (!new->native)
01863 return (NULL);
01864 new->symbol.section = bfd_abs_section_ptr;
01865 new->symbol.flags = BSF_DEBUGGING;
01866 new->lineno = (alent *) NULL;
01867 new->done_lineno = FALSE;
01868 new->symbol.the_bfd = abfd;
01869 return &new->symbol;
01870 }
01871
01872 void
01873 coff_get_symbol_info (abfd, symbol, ret)
01874 bfd *abfd;
01875 asymbol *symbol;
01876 symbol_info *ret;
01877 {
01878 bfd_symbol_info (symbol, ret);
01879 if (coffsymbol (symbol)->native != NULL
01880 && coffsymbol (symbol)->native->fix_value)
01881 {
01882 ret->value = coffsymbol (symbol)->native->u.syment.n_value -
01883 (unsigned long) obj_raw_syments (abfd);
01884 }
01885 }
01886
01887
01888
01889 bfd_boolean
01890 bfd_coff_get_syment (abfd, symbol, psyment)
01891 bfd *abfd;
01892 asymbol *symbol;
01893 struct internal_syment *psyment;
01894 {
01895 coff_symbol_type *csym;
01896
01897 csym = coff_symbol_from (abfd, symbol);
01898 if (csym == NULL || csym->native == NULL)
01899 {
01900 bfd_set_error (bfd_error_invalid_operation);
01901 return FALSE;
01902 }
01903
01904 *psyment = csym->native->u.syment;
01905
01906 if (csym->native->fix_value)
01907 psyment->n_value = psyment->n_value -
01908 (unsigned long) obj_raw_syments (abfd);
01909
01910
01911
01912 return TRUE;
01913 }
01914
01915
01916
01917 bfd_boolean
01918 bfd_coff_get_auxent (abfd, symbol, indx, pauxent)
01919 bfd *abfd;
01920 asymbol *symbol;
01921 int indx;
01922 union internal_auxent *pauxent;
01923 {
01924 coff_symbol_type *csym;
01925 combined_entry_type *ent;
01926
01927 csym = coff_symbol_from (abfd, symbol);
01928
01929 if (csym == NULL
01930 || csym->native == NULL
01931 || indx >= csym->native->u.syment.n_numaux)
01932 {
01933 bfd_set_error (bfd_error_invalid_operation);
01934 return FALSE;
01935 }
01936
01937 ent = csym->native + indx + 1;
01938
01939 *pauxent = ent->u.auxent;
01940
01941 if (ent->fix_tag)
01942 pauxent->x_sym.x_tagndx.l =
01943 ((combined_entry_type *) pauxent->x_sym.x_tagndx.p
01944 - obj_raw_syments (abfd));
01945
01946 if (ent->fix_end)
01947 pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l =
01948 ((combined_entry_type *) pauxent->x_sym.x_fcnary.x_fcn.x_endndx.p
01949 - obj_raw_syments (abfd));
01950
01951 if (ent->fix_scnlen)
01952 pauxent->x_csect.x_scnlen.l =
01953 ((combined_entry_type *) pauxent->x_csect.x_scnlen.p
01954 - obj_raw_syments (abfd));
01955
01956 return TRUE;
01957 }
01958
01959
01960
01961 void
01962 coff_print_symbol (abfd, filep, symbol, how)
01963 bfd *abfd;
01964 PTR filep;
01965 asymbol *symbol;
01966 bfd_print_symbol_type how;
01967 {
01968 FILE *file = (FILE *) filep;
01969
01970 switch (how)
01971 {
01972 case bfd_print_symbol_name:
01973 fprintf (file, "%s", symbol->name);
01974 break;
01975
01976 case bfd_print_symbol_more:
01977 fprintf (file, "coff %s %s",
01978 coffsymbol (symbol)->native ? "n" : "g",
01979 coffsymbol (symbol)->lineno ? "l" : " ");
01980 break;
01981
01982 case bfd_print_symbol_all:
01983 if (coffsymbol (symbol)->native)
01984 {
01985 bfd_vma val;
01986 unsigned int aux;
01987 combined_entry_type *combined = coffsymbol (symbol)->native;
01988 combined_entry_type *root = obj_raw_syments (abfd);
01989 struct lineno_cache_entry *l = coffsymbol (symbol)->lineno;
01990
01991 fprintf (file, "[%3ld]", (long) (combined - root));
01992
01993 if (! combined->fix_value)
01994 val = (bfd_vma) combined->u.syment.n_value;
01995 else
01996 val = combined->u.syment.n_value - (unsigned long) root;
01997
01998 #ifndef XCOFF64
01999 fprintf (file,
02000 "(sec %2d)(fl 0x%02x)(ty %3x)(scl %3d) (nx %d) 0x%08lx %s",
02001 combined->u.syment.n_scnum,
02002 combined->u.syment.n_flags,
02003 combined->u.syment.n_type,
02004 combined->u.syment.n_sclass,
02005 combined->u.syment.n_numaux,
02006 (unsigned long) val,
02007 symbol->name);
02008 #else
02009
02010 fprintf (file,
02011 "(sec %2d)(fl 0x%02x)(ty %3x)(scl %3d) (nx %d) 0x%016llx %s",
02012 combined->u.syment.n_scnum,
02013 combined->u.syment.n_flags,
02014 combined->u.syment.n_type,
02015 combined->u.syment.n_sclass,
02016 combined->u.syment.n_numaux,
02017 val,
02018 symbol->name);
02019 #endif
02020
02021 for (aux = 0; aux < combined->u.syment.n_numaux; aux++)
02022 {
02023 combined_entry_type *auxp = combined + aux + 1;
02024 long tagndx;
02025
02026 if (auxp->fix_tag)
02027 tagndx = auxp->u.auxent.x_sym.x_tagndx.p - root;
02028 else
02029 tagndx = auxp->u.auxent.x_sym.x_tagndx.l;
02030
02031 fprintf (file, "\n");
02032
02033 if (bfd_coff_print_aux (abfd, file, root, combined, auxp, aux))
02034 continue;
02035
02036 switch (combined->u.syment.n_sclass)
02037 {
02038 case C_FILE:
02039 fprintf (file, "File ");
02040 break;
02041
02042 case C_STAT:
02043 if (combined->u.syment.n_type == T_NULL)
02044
02045 {
02046 fprintf (file, "AUX scnlen 0x%lx nreloc %d nlnno %d",
02047 (long) auxp->u.auxent.x_scn.x_scnlen,
02048 auxp->u.auxent.x_scn.x_nreloc,
02049 auxp->u.auxent.x_scn.x_nlinno);
02050 if (auxp->u.auxent.x_scn.x_checksum != 0
02051 || auxp->u.auxent.x_scn.x_associated != 0
02052 || auxp->u.auxent.x_scn.x_comdat != 0)
02053 fprintf (file, " checksum 0x%lx assoc %d comdat %d",
02054 auxp->u.auxent.x_scn.x_checksum,
02055 auxp->u.auxent.x_scn.x_associated,
02056 auxp->u.auxent.x_scn.x_comdat);
02057 break;
02058 }
02059
02060 case C_EXT:
02061 if (ISFCN (combined->u.syment.n_type))
02062 {
02063 long next, llnos;
02064
02065 if (auxp->fix_end)
02066 next = (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p
02067 - root);
02068 else
02069 next = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
02070 llnos = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr;
02071 fprintf (file,
02072 "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld",
02073 tagndx, auxp->u.auxent.x_sym.x_misc.x_fsize,
02074 llnos, next);
02075 break;
02076 }
02077
02078 default:
02079 fprintf (file, "AUX lnno %d size 0x%x tagndx %ld",
02080 auxp->u.auxent.x_sym.x_misc.x_lnsz.x_lnno,
02081 auxp->u.auxent.x_sym.x_misc.x_lnsz.x_size,
02082 tagndx);
02083 if (auxp->fix_end)
02084 fprintf (file, " endndx %ld",
02085 ((long)
02086 (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p
02087 - root)));
02088 break;
02089 }
02090 }
02091
02092 if (l)
02093 {
02094 fprintf (file, "\n%s :", l->u.sym->name);
02095 l++;
02096 while (l->line_number)
02097 {
02098 fprintf (file, "\n%4d : 0x%lx",
02099 l->line_number,
02100 ((unsigned long)
02101 (l->u.offset + symbol->section->vma)));
02102 l++;
02103 }
02104 }
02105 }
02106 else
02107 {
02108 bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
02109 fprintf (file, " %-5s %s %s %s",
02110 symbol->section->name,
02111 coffsymbol (symbol)->native ? "n" : "g",
02112 coffsymbol (symbol)->lineno ? "l" : " ",
02113 symbol->name);
02114 }
02115 }
02116 }
02117
02118
02119
02120
02121
02122
02123 bfd_boolean
02124 _bfd_coff_is_local_label_name (abfd, name)
02125 bfd *abfd ATTRIBUTE_UNUSED;
02126 const char *name;
02127 {
02128 return name[0] == '.' && name[1] == 'L';
02129 }
02130
02131
02132
02133
02134
02135 bfd_boolean
02136 coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
02137 functionname_ptr, line_ptr)
02138 bfd *abfd;
02139 asection *section;
02140 asymbol **symbols;
02141 bfd_vma offset;
02142 const char **filename_ptr;
02143 const char **functionname_ptr;
02144 unsigned int *line_ptr;
02145 {
02146 bfd_boolean found;
02147 unsigned int i;
02148 unsigned int line_base;
02149 coff_data_type *cof = coff_data (abfd);
02150
02151 combined_entry_type *p;
02152 combined_entry_type *pend;
02153 alent *l;
02154 struct coff_section_tdata *sec_data;
02155 bfd_size_type amt;
02156
02157
02158
02159 if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
02160 &found, filename_ptr,
02161 functionname_ptr, line_ptr,
02162 &coff_data(abfd)->line_info))
02163 return FALSE;
02164
02165 if (found)
02166 return TRUE;
02167
02168
02169 if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
02170 filename_ptr, functionname_ptr,
02171 line_ptr, 0,
02172 &coff_data(abfd)->dwarf2_find_line_info))
02173 return TRUE;
02174
02175 *filename_ptr = 0;
02176 *functionname_ptr = 0;
02177 *line_ptr = 0;
02178
02179
02180 if (!bfd_family_coff (abfd))
02181 return FALSE;
02182
02183 if (cof == NULL)
02184 return FALSE;
02185
02186
02187 p = cof->raw_syments;
02188 if (!p)
02189 return FALSE;
02190
02191 pend = p + cof->raw_syment_count;
02192 while (p < pend)
02193 {
02194 if (p->u.syment.n_sclass == C_FILE)
02195 break;
02196 p += 1 + p->u.syment.n_numaux;
02197 }
02198
02199 if (p < pend)
02200 {
02201 bfd_vma sec_vma;
02202 bfd_vma maxdiff;
02203
02204
02205 sec_vma = bfd_get_section_vma (abfd, section);
02206 *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
02207 maxdiff = (bfd_vma) 0 - (bfd_vma) 1;
02208 while (1)
02209 {
02210 combined_entry_type *p2;
02211
02212 for (p2 = p + 1 + p->u.syment.n_numaux;
02213 p2 < pend;
02214 p2 += 1 + p2->u.syment.n_numaux)
02215 {
02216 if (p2->u.syment.n_scnum > 0
02217 && (section
02218 == coff_section_from_bfd_index (abfd,
02219 p2->u.syment.n_scnum)))
02220 break;
02221 if (p2->u.syment.n_sclass == C_FILE)
02222 {
02223 p2 = pend;
02224 break;
02225 }
02226 }
02227
02228
02229
02230 if (p2 < pend
02231 && offset + sec_vma >= (bfd_vma) p2->u.syment.n_value
02232 && offset + sec_vma - (bfd_vma) p2->u.syment.n_value <= maxdiff)
02233 {
02234 *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
02235 maxdiff = offset + sec_vma - p2->u.syment.n_value;
02236 }
02237
02238
02239
02240 if (p >= cof->raw_syments + p->u.syment.n_value)
02241 break;
02242
02243 p = cof->raw_syments + p->u.syment.n_value;
02244 if (p > pend || p->u.syment.n_sclass != C_FILE)
02245 break;
02246 }
02247 }
02248
02249
02250
02251
02252 sec_data = coff_section_data (abfd, section);
02253 if (sec_data != NULL
02254 && sec_data->i > 0
02255 && offset >= sec_data->offset)
02256 {
02257 i = sec_data->i;
02258 *functionname_ptr = sec_data->function;
02259 line_base = sec_data->line_base;
02260 }
02261 else
02262 {
02263 i = 0;
02264 line_base = 0;
02265 }
02266
02267 if (section->lineno != NULL)
02268 {
02269 bfd_vma last_value = 0;
02270
02271 l = §ion->lineno[i];
02272
02273 for (; i < section->lineno_count; i++)
02274 {
02275 if (l->line_number == 0)
02276 {
02277
02278 coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
02279 if (coff->symbol.value > offset)
02280 break;
02281 *functionname_ptr = coff->symbol.name;
02282 last_value = coff->symbol.value;
02283 if (coff->native)
02284 {
02285 combined_entry_type *s = coff->native;
02286 s = s + 1 + s->u.syment.n_numaux;
02287
02288
02289
02290 if (s->u.syment.n_scnum == N_DEBUG)
02291 s = s + 1 + s->u.syment.n_numaux;
02292
02293
02294 if (s->u.syment.n_numaux)
02295 {
02296
02297 union internal_auxent *a = &((s + 1)->u.auxent);
02298 line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
02299 *line_ptr = line_base;
02300 }
02301 }
02302 }
02303 else
02304 {
02305 if (l->u.offset > offset)
02306 break;
02307 *line_ptr = l->line_number + line_base - 1;
02308 }
02309 l++;
02310 }
02311
02312
02313
02314
02315
02316
02317
02318 if (i >= section->lineno_count
02319 && last_value != 0
02320 && offset - last_value > 0x100)
02321 {
02322 *functionname_ptr = NULL;
02323 *line_ptr = 0;
02324 }
02325 }
02326
02327
02328 if (sec_data == NULL && section->owner == abfd)
02329 {
02330 amt = sizeof (struct coff_section_tdata);
02331 section->used_by_bfd = (PTR) bfd_zalloc (abfd, amt);
02332 sec_data = (struct coff_section_tdata *) section->used_by_bfd;
02333 }
02334 if (sec_data != NULL)
02335 {
02336 sec_data->offset = offset;
02337 sec_data->i = i;
02338 sec_data->function = *functionname_ptr;
02339 sec_data->line_base = line_base;
02340 }
02341
02342 return TRUE;
02343 }
02344
02345 int
02346 coff_sizeof_headers (abfd, reloc)
02347 bfd *abfd;
02348 bfd_boolean reloc;
02349 {
02350 size_t size;
02351
02352 if (! reloc)
02353 {
02354 size = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
02355 }
02356 else
02357 {
02358 size = bfd_coff_filhsz (abfd);
02359 }
02360
02361 size += abfd->section_count * bfd_coff_scnhsz (abfd);
02362 return size;
02363 }
02364
02365
02366 bfd_boolean
02367 bfd_coff_set_symbol_class (abfd, symbol, class)
02368 bfd * abfd;
02369 asymbol * symbol;
02370 unsigned int class;
02371 {
02372 coff_symbol_type * csym;
02373
02374 csym = coff_symbol_from (abfd, symbol);
02375 if (csym == NULL)
02376 {
02377 bfd_set_error (bfd_error_invalid_operation);
02378 return FALSE;
02379 }
02380 else if (csym->native == NULL)
02381 {
02382
02383
02384
02385
02386
02387 combined_entry_type * native;
02388 bfd_size_type amt = sizeof (* native);
02389
02390 native = (combined_entry_type *) bfd_zalloc (abfd, amt);
02391 if (native == NULL)
02392 return FALSE;
02393
02394 native->u.syment.n_type = T_NULL;
02395 native->u.syment.n_sclass = class;
02396
02397 if (bfd_is_und_section (symbol->section))
02398 {
02399 native->u.syment.n_scnum = N_UNDEF;
02400 native->u.syment.n_value = symbol->value;
02401 }
02402 else if (bfd_is_com_section (symbol->section))
02403 {
02404 native->u.syment.n_scnum = N_UNDEF;
02405 native->u.syment.n_value = symbol->value;
02406 }
02407 else
02408 {
02409 native->u.syment.n_scnum =
02410 symbol->section->output_section->target_index;
02411 native->u.syment.n_value = (symbol->value
02412 + symbol->section->output_offset);
02413 if (! obj_pe (abfd))
02414 native->u.syment.n_value += symbol->section->output_section->vma;
02415
02416
02417
02418 native->u.syment.n_flags = bfd_asymbol_bfd (& csym->symbol)->flags;
02419 }
02420
02421 csym->native = native;
02422 }
02423 else
02424 {
02425 csym->native->u.syment.n_sclass = class;
02426 }
02427
02428 return TRUE;
02429 }
02430
02431 struct coff_comdat_info *
02432 bfd_coff_get_comdat_section (bfd *abfd, struct bfd_section *sec)
02433 {
02434 if (bfd_get_flavour (abfd) == bfd_target_coff_flavour
02435 && coff_section_data (abfd, sec) != NULL)
02436 return coff_section_data (abfd, sec)->comdat;
02437 else
02438 return NULL;
02439 }