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 #include "bfd.h"
00027 #include "sysdep.h"
00028 #include "bfdlink.h"
00029 #include "libbfd.h"
00030 #include "objalloc.h"
00031 #include "aout/stab_gnu.h"
00032 #include "coff/internal.h"
00033 #include "coff/sym.h"
00034 #include "coff/symconst.h"
00035 #include "coff/ecoff.h"
00036 #include "libcoff.h"
00037 #include "libecoff.h"
00038
00039 static bfd_boolean ecoff_add_bytes
00040 PARAMS ((char **buf, char **bufend, size_t need));
00041 static struct bfd_hash_entry *string_hash_newfunc
00042 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
00043 const char *));
00044 static void ecoff_align_debug
00045 PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
00046 const struct ecoff_debug_swap *swap));
00047 static bfd_boolean ecoff_write_symhdr
00048 PARAMS ((bfd *, struct ecoff_debug_info *, const struct ecoff_debug_swap *,
00049 file_ptr where));
00050 static int cmp_fdrtab_entry
00051 PARAMS ((const PTR, const PTR));
00052 static bfd_boolean mk_fdrtab
00053 PARAMS ((bfd *, struct ecoff_debug_info * const,
00054 const struct ecoff_debug_swap * const, struct ecoff_find_line *));
00055 static long fdrtab_lookup
00056 PARAMS ((struct ecoff_find_line *, bfd_vma));
00057 static bfd_boolean lookup_line
00058 PARAMS ((bfd *, struct ecoff_debug_info * const,
00059 const struct ecoff_debug_swap * const, struct ecoff_find_line *));
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 void
00070 _bfd_ecoff_swap_tir_in (bigend, ext_copy, intern)
00071 int bigend;
00072 const struct tir_ext *ext_copy;
00073 TIR *intern;
00074 {
00075 struct tir_ext ext[1];
00076
00077 *ext = *ext_copy;
00078
00079
00080 if (bigend) {
00081 intern->fBitfield = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_BIG);
00082 intern->continued = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_BIG);
00083 intern->bt = (ext->t_bits1[0] & TIR_BITS1_BT_BIG)
00084 >> TIR_BITS1_BT_SH_BIG;
00085 intern->tq4 = (ext->t_tq45[0] & TIR_BITS_TQ4_BIG)
00086 >> TIR_BITS_TQ4_SH_BIG;
00087 intern->tq5 = (ext->t_tq45[0] & TIR_BITS_TQ5_BIG)
00088 >> TIR_BITS_TQ5_SH_BIG;
00089 intern->tq0 = (ext->t_tq01[0] & TIR_BITS_TQ0_BIG)
00090 >> TIR_BITS_TQ0_SH_BIG;
00091 intern->tq1 = (ext->t_tq01[0] & TIR_BITS_TQ1_BIG)
00092 >> TIR_BITS_TQ1_SH_BIG;
00093 intern->tq2 = (ext->t_tq23[0] & TIR_BITS_TQ2_BIG)
00094 >> TIR_BITS_TQ2_SH_BIG;
00095 intern->tq3 = (ext->t_tq23[0] & TIR_BITS_TQ3_BIG)
00096 >> TIR_BITS_TQ3_SH_BIG;
00097 } else {
00098 intern->fBitfield = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_LITTLE);
00099 intern->continued = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_LITTLE);
00100 intern->bt = (ext->t_bits1[0] & TIR_BITS1_BT_LITTLE)
00101 >> TIR_BITS1_BT_SH_LITTLE;
00102 intern->tq4 = (ext->t_tq45[0] & TIR_BITS_TQ4_LITTLE)
00103 >> TIR_BITS_TQ4_SH_LITTLE;
00104 intern->tq5 = (ext->t_tq45[0] & TIR_BITS_TQ5_LITTLE)
00105 >> TIR_BITS_TQ5_SH_LITTLE;
00106 intern->tq0 = (ext->t_tq01[0] & TIR_BITS_TQ0_LITTLE)
00107 >> TIR_BITS_TQ0_SH_LITTLE;
00108 intern->tq1 = (ext->t_tq01[0] & TIR_BITS_TQ1_LITTLE)
00109 >> TIR_BITS_TQ1_SH_LITTLE;
00110 intern->tq2 = (ext->t_tq23[0] & TIR_BITS_TQ2_LITTLE)
00111 >> TIR_BITS_TQ2_SH_LITTLE;
00112 intern->tq3 = (ext->t_tq23[0] & TIR_BITS_TQ3_LITTLE)
00113 >> TIR_BITS_TQ3_SH_LITTLE;
00114 }
00115
00116 #ifdef TEST
00117 if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
00118 abort ();
00119 #endif
00120 }
00121
00122
00123
00124
00125
00126 void
00127 _bfd_ecoff_swap_tir_out (bigend, intern_copy, ext)
00128 int bigend;
00129 const TIR *intern_copy;
00130 struct tir_ext *ext;
00131 {
00132 TIR intern[1];
00133
00134 *intern = *intern_copy;
00135
00136
00137 if (bigend) {
00138 ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_BIG : 0)
00139 | (intern->continued ? TIR_BITS1_CONTINUED_BIG : 0)
00140 | ((intern->bt << TIR_BITS1_BT_SH_BIG)
00141 & TIR_BITS1_BT_BIG));
00142 ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_BIG)
00143 & TIR_BITS_TQ4_BIG)
00144 | ((intern->tq5 << TIR_BITS_TQ5_SH_BIG)
00145 & TIR_BITS_TQ5_BIG));
00146 ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_BIG)
00147 & TIR_BITS_TQ0_BIG)
00148 | ((intern->tq1 << TIR_BITS_TQ1_SH_BIG)
00149 & TIR_BITS_TQ1_BIG));
00150 ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_BIG)
00151 & TIR_BITS_TQ2_BIG)
00152 | ((intern->tq3 << TIR_BITS_TQ3_SH_BIG)
00153 & TIR_BITS_TQ3_BIG));
00154 } else {
00155 ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_LITTLE : 0)
00156 | (intern->continued ? TIR_BITS1_CONTINUED_LITTLE : 0)
00157 | ((intern->bt << TIR_BITS1_BT_SH_LITTLE)
00158 & TIR_BITS1_BT_LITTLE));
00159 ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_LITTLE)
00160 & TIR_BITS_TQ4_LITTLE)
00161 | ((intern->tq5 << TIR_BITS_TQ5_SH_LITTLE)
00162 & TIR_BITS_TQ5_LITTLE));
00163 ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_LITTLE)
00164 & TIR_BITS_TQ0_LITTLE)
00165 | ((intern->tq1 << TIR_BITS_TQ1_SH_LITTLE)
00166 & TIR_BITS_TQ1_LITTLE));
00167 ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_LITTLE)
00168 & TIR_BITS_TQ2_LITTLE)
00169 | ((intern->tq3 << TIR_BITS_TQ3_SH_LITTLE)
00170 & TIR_BITS_TQ3_LITTLE));
00171 }
00172
00173 #ifdef TEST
00174 if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
00175 abort ();
00176 #endif
00177 }
00178
00179
00180
00181
00182 void
00183 _bfd_ecoff_swap_rndx_in (bigend, ext_copy, intern)
00184 int bigend;
00185 const struct rndx_ext *ext_copy;
00186 RNDXR *intern;
00187 {
00188 struct rndx_ext ext[1];
00189
00190 *ext = *ext_copy;
00191
00192
00193 if (bigend) {
00194 intern->rfd = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_BIG)
00195 | ((ext->r_bits[1] & RNDX_BITS1_RFD_BIG)
00196 >> RNDX_BITS1_RFD_SH_BIG);
00197 intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_BIG)
00198 << RNDX_BITS1_INDEX_SH_LEFT_BIG)
00199 | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_BIG)
00200 | (ext->r_bits[3] << RNDX_BITS3_INDEX_SH_LEFT_BIG);
00201 } else {
00202 intern->rfd = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_LITTLE)
00203 | ((ext->r_bits[1] & RNDX_BITS1_RFD_LITTLE)
00204 << RNDX_BITS1_RFD_SH_LEFT_LITTLE);
00205 intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_LITTLE)
00206 >> RNDX_BITS1_INDEX_SH_LITTLE)
00207 | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_LITTLE)
00208 | ((unsigned int) ext->r_bits[3]
00209 << RNDX_BITS3_INDEX_SH_LEFT_LITTLE);
00210 }
00211
00212 #ifdef TEST
00213 if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
00214 abort ();
00215 #endif
00216 }
00217
00218
00219
00220
00221 void
00222 _bfd_ecoff_swap_rndx_out (bigend, intern_copy, ext)
00223 int bigend;
00224 const RNDXR *intern_copy;
00225 struct rndx_ext *ext;
00226 {
00227 RNDXR intern[1];
00228
00229 *intern = *intern_copy;
00230
00231
00232 if (bigend) {
00233 ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_BIG;
00234 ext->r_bits[1] = (((intern->rfd << RNDX_BITS1_RFD_SH_BIG)
00235 & RNDX_BITS1_RFD_BIG)
00236 | ((intern->index >> RNDX_BITS1_INDEX_SH_LEFT_BIG)
00237 & RNDX_BITS1_INDEX_BIG));
00238 ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_BIG;
00239 ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_BIG;
00240 } else {
00241 ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_LITTLE;
00242 ext->r_bits[1] = (((intern->rfd >> RNDX_BITS1_RFD_SH_LEFT_LITTLE)
00243 & RNDX_BITS1_RFD_LITTLE)
00244 | ((intern->index << RNDX_BITS1_INDEX_SH_LITTLE)
00245 & RNDX_BITS1_INDEX_LITTLE));
00246 ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_LITTLE;
00247 ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_LITTLE;
00248 }
00249
00250 #ifdef TEST
00251 if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
00252 abort ();
00253 #endif
00254 }
00255
00256
00257 #define ALLOC_SIZE (4064)
00258
00259
00260
00261 static bfd_boolean
00262 ecoff_add_bytes (buf, bufend, need)
00263 char **buf;
00264 char **bufend;
00265 size_t need;
00266 {
00267 size_t have;
00268 size_t want;
00269 char *newbuf;
00270
00271 have = *bufend - *buf;
00272 if (have > need)
00273 want = ALLOC_SIZE;
00274 else
00275 {
00276 want = need - have;
00277 if (want < ALLOC_SIZE)
00278 want = ALLOC_SIZE;
00279 }
00280 newbuf = (char *) bfd_realloc (*buf, (bfd_size_type) have + want);
00281 if (newbuf == NULL)
00282 return FALSE;
00283 *buf = newbuf;
00284 *bufend = *buf + have + want;
00285 return TRUE;
00286 }
00287
00288
00289
00290
00291
00292 struct string_hash_entry
00293 {
00294 struct bfd_hash_entry root;
00295
00296 long val;
00297
00298 struct string_hash_entry *next;
00299 };
00300
00301 struct string_hash_table
00302 {
00303 struct bfd_hash_table table;
00304 };
00305
00306
00307
00308 static struct bfd_hash_entry *
00309 string_hash_newfunc (entry, table, string)
00310 struct bfd_hash_entry *entry;
00311 struct bfd_hash_table *table;
00312 const char *string;
00313 {
00314 struct string_hash_entry *ret = (struct string_hash_entry *) entry;
00315
00316
00317
00318 if (ret == (struct string_hash_entry *) NULL)
00319 ret = ((struct string_hash_entry *)
00320 bfd_hash_allocate (table, sizeof (struct string_hash_entry)));
00321 if (ret == (struct string_hash_entry *) NULL)
00322 return NULL;
00323
00324
00325 ret = ((struct string_hash_entry *)
00326 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
00327
00328 if (ret)
00329 {
00330
00331 ret->val = -1;
00332 ret->next = NULL;
00333 }
00334
00335 return (struct bfd_hash_entry *) ret;
00336 }
00337
00338
00339
00340 #define string_hash_lookup(t, string, create, copy) \
00341 ((struct string_hash_entry *) \
00342 bfd_hash_lookup (&(t)->table, (string), (create), (copy)))
00343
00344
00345
00346
00347
00348 struct shuffle
00349 {
00350
00351 struct shuffle *next;
00352
00353 unsigned long size;
00354
00355 bfd_boolean filep;
00356 union
00357 {
00358 struct
00359 {
00360
00361 bfd *input_bfd;
00362
00363 file_ptr offset;
00364 } file;
00365
00366 PTR memory;
00367 } u;
00368 };
00369
00370
00371
00372
00373 struct accumulate
00374 {
00375
00376 struct string_hash_table fdr_hash;
00377
00378 struct string_hash_table str_hash;
00379
00380
00381
00382 struct shuffle *line;
00383 struct shuffle *line_end;
00384 struct shuffle *pdr;
00385 struct shuffle *pdr_end;
00386 struct shuffle *sym;
00387 struct shuffle *sym_end;
00388 struct shuffle *opt;
00389 struct shuffle *opt_end;
00390 struct shuffle *aux;
00391 struct shuffle *aux_end;
00392 struct shuffle *ss;
00393 struct shuffle *ss_end;
00394 struct string_hash_entry *ss_hash;
00395 struct string_hash_entry *ss_hash_end;
00396 struct shuffle *fdr;
00397 struct shuffle *fdr_end;
00398 struct shuffle *rfd;
00399 struct shuffle *rfd_end;
00400
00401 unsigned long largest_file_shuffle;
00402
00403 struct objalloc *memory;
00404 };
00405
00406
00407
00408 static bfd_boolean add_file_shuffle
00409 PARAMS ((struct accumulate *, struct shuffle **, struct shuffle **,
00410 bfd *, file_ptr, unsigned long));
00411
00412 static bfd_boolean
00413 add_file_shuffle (ainfo, head, tail, input_bfd, offset, size)
00414 struct accumulate *ainfo;
00415 struct shuffle **head;
00416 struct shuffle **tail;
00417 bfd *input_bfd;
00418 file_ptr offset;
00419 unsigned long size;
00420 {
00421 struct shuffle *n;
00422
00423 if (*tail != (struct shuffle *) NULL
00424 && (*tail)->filep
00425 && (*tail)->u.file.input_bfd == input_bfd
00426 && (*tail)->u.file.offset + (*tail)->size == (unsigned long) offset)
00427 {
00428
00429 (*tail)->size += size;
00430 if ((*tail)->size > ainfo->largest_file_shuffle)
00431 ainfo->largest_file_shuffle = (*tail)->size;
00432 return TRUE;
00433 }
00434
00435 n = (struct shuffle *) objalloc_alloc (ainfo->memory,
00436 sizeof (struct shuffle));
00437 if (!n)
00438 {
00439 bfd_set_error (bfd_error_no_memory);
00440 return FALSE;
00441 }
00442 n->next = NULL;
00443 n->size = size;
00444 n->filep = TRUE;
00445 n->u.file.input_bfd = input_bfd;
00446 n->u.file.offset = offset;
00447 if (*head == (struct shuffle *) NULL)
00448 *head = n;
00449 if (*tail != (struct shuffle *) NULL)
00450 (*tail)->next = n;
00451 *tail = n;
00452 if (size > ainfo->largest_file_shuffle)
00453 ainfo->largest_file_shuffle = size;
00454 return TRUE;
00455 }
00456
00457
00458
00459 static bfd_boolean add_memory_shuffle
00460 PARAMS ((struct accumulate *, struct shuffle **head, struct shuffle **tail,
00461 bfd_byte *data, unsigned long size));
00462
00463 static bfd_boolean
00464 add_memory_shuffle (ainfo, head, tail, data, size)
00465 struct accumulate *ainfo;
00466 struct shuffle **head;
00467 struct shuffle **tail;
00468 bfd_byte *data;
00469 unsigned long size;
00470 {
00471 struct shuffle *n;
00472
00473 n = (struct shuffle *) objalloc_alloc (ainfo->memory,
00474 sizeof (struct shuffle));
00475 if (!n)
00476 {
00477 bfd_set_error (bfd_error_no_memory);
00478 return FALSE;
00479 }
00480 n->next = NULL;
00481 n->size = size;
00482 n->filep = FALSE;
00483 n->u.memory = (PTR) data;
00484 if (*head == (struct shuffle *) NULL)
00485 *head = n;
00486 if (*tail != (struct shuffle *) NULL)
00487 (*tail)->next = n;
00488 *tail = n;
00489 return TRUE;
00490 }
00491
00492
00493
00494
00495 PTR
00496 bfd_ecoff_debug_init (output_bfd, output_debug, output_swap, info)
00497 bfd *output_bfd ATTRIBUTE_UNUSED;
00498 struct ecoff_debug_info *output_debug;
00499 const struct ecoff_debug_swap *output_swap ATTRIBUTE_UNUSED;
00500 struct bfd_link_info *info;
00501 {
00502 struct accumulate *ainfo;
00503 bfd_size_type amt = sizeof (struct accumulate);
00504
00505 ainfo = (struct accumulate *) bfd_malloc (amt);
00506 if (!ainfo)
00507 return NULL;
00508 if (! bfd_hash_table_init_n (&ainfo->fdr_hash.table, string_hash_newfunc,
00509 1021))
00510 return NULL;
00511
00512 ainfo->line = NULL;
00513 ainfo->line_end = NULL;
00514 ainfo->pdr = NULL;
00515 ainfo->pdr_end = NULL;
00516 ainfo->sym = NULL;
00517 ainfo->sym_end = NULL;
00518 ainfo->opt = NULL;
00519 ainfo->opt_end = NULL;
00520 ainfo->aux = NULL;
00521 ainfo->aux_end = NULL;
00522 ainfo->ss = NULL;
00523 ainfo->ss_end = NULL;
00524 ainfo->ss_hash = NULL;
00525 ainfo->ss_hash_end = NULL;
00526 ainfo->fdr = NULL;
00527 ainfo->fdr_end = NULL;
00528 ainfo->rfd = NULL;
00529 ainfo->rfd_end = NULL;
00530
00531 ainfo->largest_file_shuffle = 0;
00532
00533 if (! info->relocatable)
00534 {
00535 if (! bfd_hash_table_init (&ainfo->str_hash.table, string_hash_newfunc))
00536 return NULL;
00537
00538
00539 output_debug->symbolic_header.issMax = 1;
00540 }
00541
00542 ainfo->memory = objalloc_create ();
00543 if (ainfo->memory == NULL)
00544 {
00545 bfd_set_error (bfd_error_no_memory);
00546 return NULL;
00547 }
00548
00549 return (PTR) ainfo;
00550 }
00551
00552
00553
00554 void
00555 bfd_ecoff_debug_free (handle, output_bfd, output_debug, output_swap, info)
00556 PTR handle;
00557 bfd *output_bfd ATTRIBUTE_UNUSED;
00558 struct ecoff_debug_info *output_debug ATTRIBUTE_UNUSED;
00559 const struct ecoff_debug_swap *output_swap ATTRIBUTE_UNUSED;
00560 struct bfd_link_info *info;
00561 {
00562 struct accumulate *ainfo = (struct accumulate *) handle;
00563
00564 bfd_hash_table_free (&ainfo->fdr_hash.table);
00565
00566 if (! info->relocatable)
00567 bfd_hash_table_free (&ainfo->str_hash.table);
00568
00569 objalloc_free (ainfo->memory);
00570
00571 free (ainfo);
00572 }
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582 bfd_boolean
00583 bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap,
00584 input_bfd, input_debug, input_swap,
00585 info)
00586 PTR handle;
00587 bfd *output_bfd;
00588 struct ecoff_debug_info *output_debug;
00589 const struct ecoff_debug_swap *output_swap;
00590 bfd *input_bfd;
00591 struct ecoff_debug_info *input_debug;
00592 const struct ecoff_debug_swap *input_swap;
00593 struct bfd_link_info *info;
00594 {
00595 struct accumulate *ainfo = (struct accumulate *) handle;
00596 void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *))
00597 = input_swap->swap_sym_in;
00598 void (* const swap_rfd_in) PARAMS ((bfd *, PTR, RFDT *))
00599 = input_swap->swap_rfd_in;
00600 void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))
00601 = output_swap->swap_sym_out;
00602 void (* const swap_fdr_out) PARAMS ((bfd *, const FDR *, PTR))
00603 = output_swap->swap_fdr_out;
00604 void (* const swap_rfd_out) PARAMS ((bfd *, const RFDT *, PTR))
00605 = output_swap->swap_rfd_out;
00606 bfd_size_type external_pdr_size = output_swap->external_pdr_size;
00607 bfd_size_type external_sym_size = output_swap->external_sym_size;
00608 bfd_size_type external_opt_size = output_swap->external_opt_size;
00609 bfd_size_type external_fdr_size = output_swap->external_fdr_size;
00610 bfd_size_type external_rfd_size = output_swap->external_rfd_size;
00611 HDRR * const output_symhdr = &output_debug->symbolic_header;
00612 HDRR * const input_symhdr = &input_debug->symbolic_header;
00613 bfd_vma section_adjust[scMax];
00614 asection *sec;
00615 bfd_byte *fdr_start;
00616 bfd_byte *fdr_ptr;
00617 bfd_byte *fdr_end;
00618 bfd_size_type fdr_add;
00619 unsigned int copied;
00620 RFDT i;
00621 unsigned long sz;
00622 bfd_byte *rfd_out;
00623 bfd_byte *rfd_in;
00624 bfd_byte *rfd_end;
00625 long newrfdbase = 0;
00626 long oldrfdbase = 0;
00627 bfd_byte *fdr_out;
00628 bfd_size_type amt;
00629
00630
00631
00632 memset ((PTR) section_adjust, 0, sizeof section_adjust);
00633
00634 #define SET(name, indx) \
00635 sec = bfd_get_section_by_name (input_bfd, name); \
00636 if (sec != NULL) \
00637 section_adjust[indx] = (sec->output_section->vma \
00638 + sec->output_offset \
00639 - sec->vma);
00640
00641 SET (".text", scText);
00642 SET (".data", scData);
00643 SET (".bss", scBss);
00644 SET (".sdata", scSData);
00645 SET (".sbss", scSBss);
00646
00647 SET (".rdata", scRData);
00648 SET (".rodata", scRData);
00649 SET (".init", scInit);
00650 SET (".fini", scFini);
00651 SET (".rconst", scRConst);
00652
00653 #undef SET
00654
00655
00656
00657 if (input_debug->fdr != (FDR *) NULL)
00658 {
00659 fdr_start = (bfd_byte *) input_debug->fdr;
00660 fdr_add = sizeof (FDR);
00661 }
00662 else
00663 {
00664 fdr_start = (bfd_byte *) input_debug->external_fdr;
00665 fdr_add = input_swap->external_fdr_size;
00666 }
00667 fdr_end = fdr_start + input_symhdr->ifdMax * fdr_add;
00668
00669 amt = input_symhdr->ifdMax;
00670 amt *= sizeof (RFDT);
00671 input_debug->ifdmap = (RFDT *) bfd_alloc (input_bfd, amt);
00672
00673 sz = (input_symhdr->crfd + input_symhdr->ifdMax) * external_rfd_size;
00674 rfd_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
00675 if (!input_debug->ifdmap || !rfd_out)
00676 {
00677 bfd_set_error (bfd_error_no_memory);
00678 return FALSE;
00679 }
00680 if (!add_memory_shuffle (ainfo, &ainfo->rfd, &ainfo->rfd_end, rfd_out, sz))
00681 return FALSE;
00682
00683 copied = 0;
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693 for (fdr_ptr = fdr_start, i = 0;
00694 fdr_ptr < fdr_end;
00695 fdr_ptr += fdr_add, i++, rfd_out += external_rfd_size)
00696 {
00697 FDR fdr;
00698
00699 if (input_debug->fdr != (FDR *) NULL)
00700 fdr = *(FDR *) fdr_ptr;
00701 else
00702 (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr);
00703
00704
00705 if (fdr.cbLine == 0 && fdr.rss != -1 && fdr.fMerge)
00706 {
00707 const char *name;
00708 char *lookup;
00709 struct string_hash_entry *fh;
00710
00711
00712
00713
00714
00715
00716
00717
00718 name = input_debug->ss + fdr.issBase + fdr.rss;
00719
00720 lookup = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 20);
00721 if (lookup == NULL)
00722 return FALSE;
00723 sprintf (lookup, "%s %lx %lx", name, fdr.csym, fdr.caux);
00724
00725 fh = string_hash_lookup (&ainfo->fdr_hash, lookup, TRUE, TRUE);
00726 free (lookup);
00727 if (fh == (struct string_hash_entry *) NULL)
00728 return FALSE;
00729
00730 if (fh->val != -1)
00731 {
00732 input_debug->ifdmap[i] = fh->val;
00733 (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i,
00734 (PTR) rfd_out);
00735
00736
00737 continue;
00738 }
00739
00740 fh->val = output_symhdr->ifdMax + copied;
00741 }
00742
00743 input_debug->ifdmap[i] = output_symhdr->ifdMax + copied;
00744 (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, (PTR) rfd_out);
00745 ++copied;
00746 }
00747
00748 newrfdbase = output_symhdr->crfd;
00749 output_symhdr->crfd += input_symhdr->ifdMax;
00750
00751
00752
00753
00754 rfd_in = (bfd_byte *) input_debug->external_rfd;
00755 rfd_end = rfd_in + input_symhdr->crfd * input_swap->external_rfd_size;
00756 for (;
00757 rfd_in < rfd_end;
00758 rfd_in += input_swap->external_rfd_size)
00759 {
00760 RFDT rfd;
00761
00762 (*swap_rfd_in) (input_bfd, (PTR) rfd_in, &rfd);
00763 BFD_ASSERT (rfd >= 0 && rfd < input_symhdr->ifdMax);
00764 rfd = input_debug->ifdmap[rfd];
00765 (*swap_rfd_out) (output_bfd, &rfd, (PTR) rfd_out);
00766 rfd_out += external_rfd_size;
00767 }
00768
00769 oldrfdbase = output_symhdr->crfd;
00770 output_symhdr->crfd += input_symhdr->crfd;
00771
00772
00773
00774 sz = copied * external_fdr_size;
00775 fdr_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
00776 if (!fdr_out)
00777 {
00778 bfd_set_error (bfd_error_no_memory);
00779 return FALSE;
00780 }
00781 if (!add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, fdr_out, sz))
00782 return FALSE;
00783 for (fdr_ptr = fdr_start, i = 0;
00784 fdr_ptr < fdr_end;
00785 fdr_ptr += fdr_add, i++)
00786 {
00787 FDR fdr;
00788 bfd_vma fdr_adr;
00789 bfd_byte *sym_out;
00790 bfd_byte *lraw_src;
00791 bfd_byte *lraw_end;
00792 bfd_boolean fgotfilename;
00793
00794 if (input_debug->ifdmap[i] < output_symhdr->ifdMax)
00795 {
00796
00797 continue;
00798 }
00799
00800 if (input_debug->fdr != (FDR *) NULL)
00801 fdr = *(FDR *) fdr_ptr;
00802 else
00803 (*input_swap->swap_fdr_in) (input_bfd, (PTR) fdr_ptr, &fdr);
00804
00805 fdr_adr = fdr.adr;
00806
00807
00808
00809
00810 fdr.adr += section_adjust[scText];
00811
00812
00813
00814 fgotfilename = FALSE;
00815 sz = fdr.csym * external_sym_size;
00816 sym_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
00817 if (!sym_out)
00818 {
00819 bfd_set_error (bfd_error_no_memory);
00820 return FALSE;
00821 }
00822 if (!add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, sym_out,
00823 sz))
00824 return FALSE;
00825 lraw_src = ((bfd_byte *) input_debug->external_sym
00826 + fdr.isymBase * input_swap->external_sym_size);
00827 lraw_end = lraw_src + fdr.csym * input_swap->external_sym_size;
00828 for (; lraw_src < lraw_end; lraw_src += input_swap->external_sym_size)
00829 {
00830 SYMR internal_sym;
00831
00832 (*swap_sym_in) (input_bfd, (PTR) lraw_src, &internal_sym);
00833
00834 BFD_ASSERT (internal_sym.sc != scCommon
00835 && internal_sym.sc != scSCommon);
00836
00837
00838 switch (internal_sym.st)
00839 {
00840 case stNil:
00841 if (ECOFF_IS_STAB (&internal_sym))
00842 break;
00843
00844 case stGlobal:
00845 case stStatic:
00846 case stLabel:
00847 case stProc:
00848 case stStaticProc:
00849 internal_sym.value += section_adjust[internal_sym.sc];
00850 break;
00851
00852 default:
00853 break;
00854 }
00855
00856
00857
00858
00859
00860
00861 if (! info->relocatable)
00862 {
00863 bfd_boolean ffilename;
00864 const char *name;
00865
00866 if (! fgotfilename && internal_sym.iss == fdr.rss)
00867 ffilename = TRUE;
00868 else
00869 ffilename = FALSE;
00870
00871
00872 name = input_debug->ss + fdr.issBase + internal_sym.iss;
00873 if (*name == '\0')
00874 internal_sym.iss = 0;
00875 else
00876 {
00877 struct string_hash_entry *sh;
00878
00879 sh = string_hash_lookup (&ainfo->str_hash, name, TRUE, TRUE);
00880 if (sh == (struct string_hash_entry *) NULL)
00881 return FALSE;
00882 if (sh->val == -1)
00883 {
00884 sh->val = output_symhdr->issMax;
00885 output_symhdr->issMax += strlen (name) + 1;
00886 if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
00887 ainfo->ss_hash = sh;
00888 if (ainfo->ss_hash_end
00889 != (struct string_hash_entry *) NULL)
00890 ainfo->ss_hash_end->next = sh;
00891 ainfo->ss_hash_end = sh;
00892 }
00893 internal_sym.iss = sh->val;
00894 }
00895
00896 if (ffilename)
00897 {
00898 fdr.rss = internal_sym.iss;
00899 fgotfilename = TRUE;
00900 }
00901 }
00902
00903 (*swap_sym_out) (output_bfd, &internal_sym, sym_out);
00904 sym_out += external_sym_size;
00905 }
00906
00907 fdr.isymBase = output_symhdr->isymMax;
00908 output_symhdr->isymMax += fdr.csym;
00909
00910
00911
00912
00913
00914
00915
00916 if (fdr.cbLine > 0)
00917 {
00918 file_ptr pos = input_symhdr->cbLineOffset + fdr.cbLineOffset;
00919 if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,
00920 input_bfd, pos, (unsigned long) fdr.cbLine))
00921 return FALSE;
00922 fdr.ilineBase = output_symhdr->ilineMax;
00923 fdr.cbLineOffset = output_symhdr->cbLine;
00924 output_symhdr->ilineMax += fdr.cline;
00925 output_symhdr->cbLine += fdr.cbLine;
00926 }
00927 if (fdr.caux > 0)
00928 {
00929 file_ptr pos = (input_symhdr->cbAuxOffset
00930 + fdr.iauxBase * sizeof (union aux_ext));
00931 if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,
00932 input_bfd, pos,
00933 fdr.caux * sizeof (union aux_ext)))
00934 return FALSE;
00935 fdr.iauxBase = output_symhdr->iauxMax;
00936 output_symhdr->iauxMax += fdr.caux;
00937 }
00938 if (! info->relocatable)
00939 {
00940
00941
00942
00943
00944
00945 fdr.issBase = 0;
00946 fdr.cbSs = output_symhdr->issMax;
00947 }
00948 else if (fdr.cbSs > 0)
00949 {
00950 file_ptr pos = input_symhdr->cbSsOffset + fdr.issBase;
00951 if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
00952 input_bfd, pos, (unsigned long) fdr.cbSs))
00953 return FALSE;
00954 fdr.issBase = output_symhdr->issMax;
00955 output_symhdr->issMax += fdr.cbSs;
00956 }
00957
00958 if (output_bfd->xvec->header_byteorder
00959 == input_bfd->xvec->header_byteorder)
00960 {
00961
00962
00963
00964 BFD_ASSERT (external_pdr_size == input_swap->external_pdr_size);
00965 if (fdr.cpd > 0)
00966 {
00967 file_ptr pos = (input_symhdr->cbPdOffset
00968 + fdr.ipdFirst * external_pdr_size);
00969 unsigned long size = fdr.cpd * external_pdr_size;
00970 if (!add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end,
00971 input_bfd, pos, size))
00972 return FALSE;
00973 }
00974 BFD_ASSERT (external_opt_size == input_swap->external_opt_size);
00975 if (fdr.copt > 0)
00976 {
00977 file_ptr pos = (input_symhdr->cbOptOffset
00978 + fdr.ioptBase * external_opt_size);
00979 unsigned long size = fdr.copt * external_opt_size;
00980 if (!add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end,
00981 input_bfd, pos, size))
00982 return FALSE;
00983 }
00984 }
00985 else
00986 {
00987 bfd_size_type outsz, insz;
00988 bfd_byte *in;
00989 bfd_byte *end;
00990 bfd_byte *out;
00991
00992
00993
00994
00995 outsz = external_pdr_size;
00996 insz = input_swap->external_pdr_size;
00997 in = ((bfd_byte *) input_debug->external_pdr
00998 + fdr.ipdFirst * insz);
00999 end = in + fdr.cpd * insz;
01000 sz = fdr.cpd * outsz;
01001 out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
01002 if (!out)
01003 {
01004 bfd_set_error (bfd_error_no_memory);
01005 return FALSE;
01006 }
01007 if (!add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out,
01008 sz))
01009 return FALSE;
01010 for (; in < end; in += insz, out += outsz)
01011 {
01012 PDR pdr;
01013
01014 (*input_swap->swap_pdr_in) (input_bfd, (PTR) in, &pdr);
01015 (*output_swap->swap_pdr_out) (output_bfd, &pdr, (PTR) out);
01016 }
01017
01018
01019 outsz = external_opt_size;
01020 insz = input_swap->external_opt_size;
01021 in = ((bfd_byte *) input_debug->external_opt
01022 + fdr.ioptBase * insz);
01023 end = in + fdr.copt * insz;
01024 sz = fdr.copt * outsz;
01025 out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
01026 if (!out)
01027 {
01028 bfd_set_error (bfd_error_no_memory);
01029 return FALSE;
01030 }
01031 if (!add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out,
01032 sz))
01033 return FALSE;
01034 for (; in < end; in += insz, out += outsz)
01035 {
01036 OPTR opt;
01037
01038 (*input_swap->swap_opt_in) (input_bfd, (PTR) in, &opt);
01039 (*output_swap->swap_opt_out) (output_bfd, &opt, (PTR) out);
01040 }
01041 }
01042
01043 fdr.ipdFirst = output_symhdr->ipdMax;
01044 output_symhdr->ipdMax += fdr.cpd;
01045 fdr.ioptBase = output_symhdr->ioptMax;
01046 output_symhdr->ioptMax += fdr.copt;
01047
01048 if (fdr.crfd <= 0)
01049 {
01050
01051 fdr.rfdBase = newrfdbase;
01052 fdr.crfd = input_symhdr->ifdMax;
01053 }
01054 else
01055 {
01056
01057 fdr.rfdBase += oldrfdbase;
01058 }
01059
01060 (*swap_fdr_out) (output_bfd, &fdr, fdr_out);
01061 fdr_out += external_fdr_size;
01062 ++output_symhdr->ifdMax;
01063 }
01064
01065 return TRUE;
01066 }
01067
01068
01069
01070
01071 static long ecoff_add_string
01072 PARAMS ((struct accumulate *, struct bfd_link_info *,
01073 struct ecoff_debug_info *, FDR *fdr, const char *string));
01074
01075 static long
01076 ecoff_add_string (ainfo, info, debug, fdr, string)
01077 struct accumulate *ainfo;
01078 struct bfd_link_info *info;
01079 struct ecoff_debug_info *debug;
01080 FDR *fdr;
01081 const char *string;
01082 {
01083 HDRR *symhdr;
01084 size_t len;
01085 bfd_size_type ret;
01086
01087 symhdr = &debug->symbolic_header;
01088 len = strlen (string);
01089 if (info->relocatable)
01090 {
01091 if (!add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end, (PTR) string,
01092 len + 1))
01093 return -1;
01094 ret = symhdr->issMax;
01095 symhdr->issMax += len + 1;
01096 fdr->cbSs += len + 1;
01097 }
01098 else
01099 {
01100 struct string_hash_entry *sh;
01101
01102 sh = string_hash_lookup (&ainfo->str_hash, string, TRUE, TRUE);
01103 if (sh == (struct string_hash_entry *) NULL)
01104 return -1;
01105 if (sh->val == -1)
01106 {
01107 sh->val = symhdr->issMax;
01108 symhdr->issMax += len + 1;
01109 if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
01110 ainfo->ss_hash = sh;
01111 if (ainfo->ss_hash_end
01112 != (struct string_hash_entry *) NULL)
01113 ainfo->ss_hash_end->next = sh;
01114 ainfo->ss_hash_end = sh;
01115 }
01116 ret = sh->val;
01117 }
01118
01119 return ret;
01120 }
01121
01122
01123
01124 bfd_boolean
01125 bfd_ecoff_debug_accumulate_other (handle, output_bfd, output_debug,
01126 output_swap, input_bfd, info)
01127 PTR handle;
01128 bfd *output_bfd;
01129 struct ecoff_debug_info *output_debug;
01130 const struct ecoff_debug_swap *output_swap;
01131 bfd *input_bfd;
01132 struct bfd_link_info *info;
01133 {
01134 struct accumulate *ainfo = (struct accumulate *) handle;
01135 void (* const swap_sym_out) PARAMS ((bfd *, const SYMR *, PTR))
01136 = output_swap->swap_sym_out;
01137 HDRR *output_symhdr = &output_debug->symbolic_header;
01138 FDR fdr;
01139 asection *sec;
01140 asymbol **symbols;
01141 asymbol **sym_ptr;
01142 asymbol **sym_end;
01143 long symsize;
01144 long symcount;
01145 PTR external_fdr;
01146
01147 memset ((PTR) &fdr, 0, sizeof fdr);
01148
01149 sec = bfd_get_section_by_name (input_bfd, ".text");
01150 if (sec != NULL)
01151 fdr.adr = sec->output_section->vma + sec->output_offset;
01152 else
01153 {
01154
01155 fdr.adr = 0;
01156 }
01157
01158 fdr.issBase = output_symhdr->issMax;
01159 fdr.cbSs = 0;
01160 fdr.rss = ecoff_add_string (ainfo, info, output_debug, &fdr,
01161 input_bfd->filename);
01162 if (fdr.rss == -1)
01163 return FALSE;
01164 fdr.isymBase = output_symhdr->isymMax;
01165
01166
01167 symsize = bfd_get_symtab_upper_bound (input_bfd);
01168 if (symsize < 0)
01169 return FALSE;
01170 symbols = (asymbol **) bfd_alloc (output_bfd, (bfd_size_type) symsize);
01171 if (symbols == (asymbol **) NULL)
01172 return FALSE;
01173 symcount = bfd_canonicalize_symtab (input_bfd, symbols);
01174 if (symcount < 0)
01175 return FALSE;
01176 sym_end = symbols + symcount;
01177
01178
01179
01180 fdr.csym = 0;
01181 for (sym_ptr = symbols; sym_ptr != sym_end; sym_ptr++)
01182 {
01183 SYMR internal_sym;
01184 PTR external_sym;
01185
01186 if (((*sym_ptr)->flags & BSF_EXPORT) != 0)
01187 continue;
01188 memset ((PTR) &internal_sym, 0, sizeof internal_sym);
01189 internal_sym.iss = ecoff_add_string (ainfo, info, output_debug, &fdr,
01190 (*sym_ptr)->name);
01191
01192 if (internal_sym.iss == -1)
01193 return FALSE;
01194 if (bfd_is_com_section ((*sym_ptr)->section)
01195 || bfd_is_und_section ((*sym_ptr)->section))
01196 internal_sym.value = (*sym_ptr)->value;
01197 else
01198 internal_sym.value = ((*sym_ptr)->value
01199 + (*sym_ptr)->section->output_offset
01200 + (*sym_ptr)->section->output_section->vma);
01201 internal_sym.st = stNil;
01202 internal_sym.sc = scUndefined;
01203 internal_sym.index = indexNil;
01204
01205 external_sym = (PTR) objalloc_alloc (ainfo->memory,
01206 output_swap->external_sym_size);
01207 if (!external_sym)
01208 {
01209 bfd_set_error (bfd_error_no_memory);
01210 return FALSE;
01211 }
01212 (*swap_sym_out) (output_bfd, &internal_sym, external_sym);
01213 add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end,
01214 external_sym,
01215 (unsigned long) output_swap->external_sym_size);
01216 ++fdr.csym;
01217 ++output_symhdr->isymMax;
01218 }
01219
01220 bfd_release (output_bfd, (PTR) symbols);
01221
01222
01223
01224
01225
01226 external_fdr = (PTR) objalloc_alloc (ainfo->memory,
01227 output_swap->external_fdr_size);
01228 if (!external_fdr)
01229 {
01230 bfd_set_error (bfd_error_no_memory);
01231 return FALSE;
01232 }
01233 (*output_swap->swap_fdr_out) (output_bfd, &fdr, external_fdr);
01234 add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end,
01235 external_fdr,
01236 (unsigned long) output_swap->external_fdr_size);
01237
01238 ++output_symhdr->ifdMax;
01239
01240 return TRUE;
01241 }
01242
01243
01244
01245
01246
01247
01248 bfd_boolean
01249 bfd_ecoff_debug_externals (abfd, debug, swap, relocatable, get_extr,
01250 set_index)
01251 bfd *abfd;
01252 struct ecoff_debug_info *debug;
01253 const struct ecoff_debug_swap *swap;
01254 bfd_boolean relocatable;
01255 bfd_boolean (*get_extr) PARAMS ((asymbol *, EXTR *));
01256 void (*set_index) PARAMS ((asymbol *, bfd_size_type));
01257 {
01258 HDRR * const symhdr = &debug->symbolic_header;
01259 asymbol **sym_ptr_ptr;
01260 size_t c;
01261
01262 sym_ptr_ptr = bfd_get_outsymbols (abfd);
01263 if (sym_ptr_ptr == NULL)
01264 return TRUE;
01265
01266 for (c = bfd_get_symcount (abfd); c > 0; c--, sym_ptr_ptr++)
01267 {
01268 asymbol *sym_ptr;
01269 EXTR esym;
01270
01271 sym_ptr = *sym_ptr_ptr;
01272
01273
01274 if (! (*get_extr) (sym_ptr, &esym))
01275 continue;
01276
01277
01278
01279 if (! relocatable)
01280 {
01281 if (esym.asym.sc == scCommon)
01282 esym.asym.sc = scBss;
01283 else if (esym.asym.sc == scSCommon)
01284 esym.asym.sc = scSBss;
01285 }
01286
01287 if (bfd_is_com_section (sym_ptr->section)
01288 || bfd_is_und_section (sym_ptr->section)
01289 || sym_ptr->section->output_section == (asection *) NULL)
01290 {
01291
01292
01293
01294 if (esym.asym.sc != scSUndefined
01295 || esym.asym.value == 0
01296 || sym_ptr->value != 0)
01297 esym.asym.value = sym_ptr->value;
01298 }
01299 else
01300 esym.asym.value = (sym_ptr->value
01301 + sym_ptr->section->output_offset
01302 + sym_ptr->section->output_section->vma);
01303
01304 if (set_index)
01305 (*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax);
01306
01307 if (! bfd_ecoff_debug_one_external (abfd, debug, swap,
01308 sym_ptr->name, &esym))
01309 return FALSE;
01310 }
01311
01312 return TRUE;
01313 }
01314
01315
01316
01317 bfd_boolean
01318 bfd_ecoff_debug_one_external (abfd, debug, swap, name, esym)
01319 bfd *abfd;
01320 struct ecoff_debug_info *debug;
01321 const struct ecoff_debug_swap *swap;
01322 const char *name;
01323 EXTR *esym;
01324 {
01325 const bfd_size_type external_ext_size = swap->external_ext_size;
01326 void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR))
01327 = swap->swap_ext_out;
01328 HDRR * const symhdr = &debug->symbolic_header;
01329 size_t namelen;
01330
01331 namelen = strlen (name);
01332
01333 if ((size_t) (debug->ssext_end - debug->ssext)
01334 < symhdr->issExtMax + namelen + 1)
01335 {
01336 if (! ecoff_add_bytes ((char **) &debug->ssext,
01337 (char **) &debug->ssext_end,
01338 symhdr->issExtMax + namelen + 1))
01339 return FALSE;
01340 }
01341 if ((size_t) ((char *) debug->external_ext_end
01342 - (char *) debug->external_ext)
01343 < (symhdr->iextMax + 1) * external_ext_size)
01344 {
01345 if (! ecoff_add_bytes ((char **) &debug->external_ext,
01346 (char **) &debug->external_ext_end,
01347 (symhdr->iextMax + 1) * (size_t) external_ext_size))
01348 return FALSE;
01349 }
01350
01351 esym->asym.iss = symhdr->issExtMax;
01352
01353 (*swap_ext_out) (abfd, esym,
01354 ((char *) debug->external_ext
01355 + symhdr->iextMax * swap->external_ext_size));
01356
01357 ++symhdr->iextMax;
01358
01359 strcpy (debug->ssext + symhdr->issExtMax, name);
01360 symhdr->issExtMax += namelen + 1;
01361
01362 return TRUE;
01363 }
01364
01365
01366
01367 static void
01368 ecoff_align_debug (abfd, debug, swap)
01369 bfd *abfd ATTRIBUTE_UNUSED;
01370 struct ecoff_debug_info *debug;
01371 const struct ecoff_debug_swap *swap;
01372 {
01373 HDRR * const symhdr = &debug->symbolic_header;
01374 bfd_size_type debug_align, aux_align, rfd_align;
01375 size_t add;
01376
01377
01378 debug_align = swap->debug_align;
01379 aux_align = debug_align / sizeof (union aux_ext);
01380 rfd_align = debug_align / swap->external_rfd_size;
01381
01382 add = debug_align - (symhdr->cbLine & (debug_align - 1));
01383 if (add != debug_align)
01384 {
01385 if (debug->line != (unsigned char *) NULL)
01386 memset ((PTR) (debug->line + symhdr->cbLine), 0, add);
01387 symhdr->cbLine += add;
01388 }
01389
01390 add = debug_align - (symhdr->issMax & (debug_align - 1));
01391 if (add != debug_align)
01392 {
01393 if (debug->ss != (char *) NULL)
01394 memset ((PTR) (debug->ss + symhdr->issMax), 0, add);
01395 symhdr->issMax += add;
01396 }
01397
01398 add = debug_align - (symhdr->issExtMax & (debug_align - 1));
01399 if (add != debug_align)
01400 {
01401 if (debug->ssext != (char *) NULL)
01402 memset ((PTR) (debug->ssext + symhdr->issExtMax), 0, add);
01403 symhdr->issExtMax += add;
01404 }
01405
01406 add = aux_align - (symhdr->iauxMax & (aux_align - 1));
01407 if (add != aux_align)
01408 {
01409 if (debug->external_aux != (union aux_ext *) NULL)
01410 memset ((PTR) (debug->external_aux + symhdr->iauxMax), 0,
01411 add * sizeof (union aux_ext));
01412 symhdr->iauxMax += add;
01413 }
01414
01415 add = rfd_align - (symhdr->crfd & (rfd_align - 1));
01416 if (add != rfd_align)
01417 {
01418 if (debug->external_rfd != (PTR) NULL)
01419 memset ((PTR) ((char *) debug->external_rfd
01420 + symhdr->crfd * swap->external_rfd_size),
01421 0, (size_t) (add * swap->external_rfd_size));
01422 symhdr->crfd += add;
01423 }
01424 }
01425
01426
01427
01428 bfd_size_type
01429 bfd_ecoff_debug_size (abfd, debug, swap)
01430 bfd *abfd;
01431 struct ecoff_debug_info *debug;
01432 const struct ecoff_debug_swap *swap;
01433 {
01434 bfd_size_type tot;
01435
01436 ecoff_align_debug (abfd, debug, swap);
01437 tot = swap->external_hdr_size;
01438
01439 #define ADD(count, size) \
01440 tot += debug->symbolic_header.count * size
01441
01442 ADD (cbLine, sizeof (unsigned char));
01443 ADD (idnMax, swap->external_dnr_size);
01444 ADD (ipdMax, swap->external_pdr_size);
01445 ADD (isymMax, swap->external_sym_size);
01446 ADD (ioptMax, swap->external_opt_size);
01447 ADD (iauxMax, sizeof (union aux_ext));
01448 ADD (issMax, sizeof (char));
01449 ADD (issExtMax, sizeof (char));
01450 ADD (ifdMax, swap->external_fdr_size);
01451 ADD (crfd, swap->external_rfd_size);
01452 ADD (iextMax, swap->external_ext_size);
01453
01454 #undef ADD
01455
01456 return tot;
01457 }
01458
01459
01460
01461
01462
01463 static bfd_boolean
01464 ecoff_write_symhdr (abfd, debug, swap, where)
01465 bfd *abfd;
01466 struct ecoff_debug_info *debug;
01467 const struct ecoff_debug_swap *swap;
01468 file_ptr where;
01469 {
01470 HDRR * const symhdr = &debug->symbolic_header;
01471 char *buff = NULL;
01472
01473 ecoff_align_debug (abfd, debug, swap);
01474
01475
01476 if (bfd_seek (abfd, where, SEEK_SET) != 0)
01477 return FALSE;
01478
01479 where += swap->external_hdr_size;
01480
01481 symhdr->magic = swap->sym_magic;
01482
01483
01484 #define SET(offset, count, size) \
01485 if (symhdr->count == 0) \
01486 symhdr->offset = 0; \
01487 else \
01488 { \
01489 symhdr->offset = where; \
01490 where += symhdr->count * size; \
01491 }
01492
01493 SET (cbLineOffset, cbLine, sizeof (unsigned char));
01494 SET (cbDnOffset, idnMax, swap->external_dnr_size);
01495 SET (cbPdOffset, ipdMax, swap->external_pdr_size);
01496 SET (cbSymOffset, isymMax, swap->external_sym_size);
01497 SET (cbOptOffset, ioptMax, swap->external_opt_size);
01498 SET (cbAuxOffset, iauxMax, sizeof (union aux_ext));
01499 SET (cbSsOffset, issMax, sizeof (char));
01500 SET (cbSsExtOffset, issExtMax, sizeof (char));
01501 SET (cbFdOffset, ifdMax, swap->external_fdr_size);
01502 SET (cbRfdOffset, crfd, swap->external_rfd_size);
01503 SET (cbExtOffset, iextMax, swap->external_ext_size);
01504 #undef SET
01505
01506 buff = (PTR) bfd_malloc (swap->external_hdr_size);
01507 if (buff == NULL && swap->external_hdr_size != 0)
01508 goto error_return;
01509
01510 (*swap->swap_hdr_out) (abfd, symhdr, buff);
01511 if (bfd_bwrite (buff, swap->external_hdr_size, abfd)
01512 != swap->external_hdr_size)
01513 goto error_return;
01514
01515 if (buff != NULL)
01516 free (buff);
01517 return TRUE;
01518 error_return:
01519 if (buff != NULL)
01520 free (buff);
01521 return FALSE;
01522 }
01523
01524
01525
01526
01527
01528
01529
01530 bfd_boolean
01531 bfd_ecoff_write_debug (abfd, debug, swap, where)
01532 bfd *abfd;
01533 struct ecoff_debug_info *debug;
01534 const struct ecoff_debug_swap *swap;
01535 file_ptr where;
01536 {
01537 HDRR * const symhdr = &debug->symbolic_header;
01538
01539 if (! ecoff_write_symhdr (abfd, debug, swap, where))
01540 return FALSE;
01541
01542 #define WRITE(ptr, count, size, offset) \
01543 BFD_ASSERT (symhdr->offset == 0 \
01544 || (bfd_vma) bfd_tell (abfd) == symhdr->offset); \
01545 if (bfd_bwrite ((PTR) debug->ptr, (bfd_size_type) size * symhdr->count, abfd)\
01546 != size * symhdr->count) \
01547 return FALSE;
01548
01549 WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset);
01550 WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset);
01551 WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset);
01552 WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset);
01553 WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset);
01554 WRITE (external_aux, iauxMax, (bfd_size_type) sizeof (union aux_ext),
01555 cbAuxOffset);
01556 WRITE (ss, issMax, sizeof (char), cbSsOffset);
01557 WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset);
01558 WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset);
01559 WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset);
01560 WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);
01561 #undef WRITE
01562
01563 return TRUE;
01564 }
01565
01566
01567
01568 static bfd_boolean ecoff_write_shuffle
01569 PARAMS ((bfd *, const struct ecoff_debug_swap *, struct shuffle *,
01570 PTR space));
01571
01572 static bfd_boolean
01573 ecoff_write_shuffle (abfd, swap, shuffle, space)
01574 bfd *abfd;
01575 const struct ecoff_debug_swap *swap;
01576 struct shuffle *shuffle;
01577 PTR space;
01578 {
01579 register struct shuffle *l;
01580 unsigned long total;
01581
01582 total = 0;
01583 for (l = shuffle; l != (struct shuffle *) NULL; l = l->next)
01584 {
01585 if (! l->filep)
01586 {
01587 if (bfd_bwrite (l->u.memory, (bfd_size_type) l->size, abfd)
01588 != l->size)
01589 return FALSE;
01590 }
01591 else
01592 {
01593 if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
01594 || bfd_bread (space, (bfd_size_type) l->size,
01595 l->u.file.input_bfd) != l->size
01596 || bfd_bwrite (space, (bfd_size_type) l->size, abfd) != l->size)
01597 return FALSE;
01598 }
01599 total += l->size;
01600 }
01601
01602 if ((total & (swap->debug_align - 1)) != 0)
01603 {
01604 unsigned int i;
01605 bfd_byte *s;
01606
01607 i = swap->debug_align - (total & (swap->debug_align - 1));
01608 s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
01609 if (s == NULL && i != 0)
01610 return FALSE;
01611
01612 if (bfd_bwrite ((PTR) s, (bfd_size_type) i, abfd) != i)
01613 {
01614 free (s);
01615 return FALSE;
01616 }
01617 free (s);
01618 }
01619
01620 return TRUE;
01621 }
01622
01623
01624
01625
01626 bfd_boolean
01627 bfd_ecoff_write_accumulated_debug (handle, abfd, debug, swap, info, where)
01628 PTR handle;
01629 bfd *abfd;
01630 struct ecoff_debug_info *debug;
01631 const struct ecoff_debug_swap *swap;
01632 struct bfd_link_info *info;
01633 file_ptr where;
01634 {
01635 struct accumulate *ainfo = (struct accumulate *) handle;
01636 PTR space = NULL;
01637 bfd_size_type amt;
01638
01639 if (! ecoff_write_symhdr (abfd, debug, swap, where))
01640 goto error_return;
01641
01642 amt = ainfo->largest_file_shuffle;
01643 space = (PTR) bfd_malloc (amt);
01644 if (space == NULL && ainfo->largest_file_shuffle != 0)
01645 goto error_return;
01646
01647 if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space)
01648 || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space)
01649 || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space)
01650 || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space)
01651 || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space))
01652 goto error_return;
01653
01654
01655
01656 if (info->relocatable)
01657 {
01658 BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL);
01659 if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space))
01660 goto error_return;
01661 }
01662 else
01663 {
01664 unsigned long total;
01665 bfd_byte null;
01666 struct string_hash_entry *sh;
01667
01668 BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
01669 null = 0;
01670 if (bfd_bwrite ((PTR) &null, (bfd_size_type) 1, abfd) != 1)
01671 goto error_return;
01672 total = 1;
01673 BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
01674 for (sh = ainfo->ss_hash;
01675 sh != (struct string_hash_entry *) NULL;
01676 sh = sh->next)
01677 {
01678 size_t len;
01679
01680 len = strlen (sh->root.string);
01681 amt = len + 1;
01682 if (bfd_bwrite ((PTR) sh->root.string, amt, abfd) != amt)
01683 goto error_return;
01684 total += len + 1;
01685 }
01686
01687 if ((total & (swap->debug_align - 1)) != 0)
01688 {
01689 unsigned int i;
01690 bfd_byte *s;
01691
01692 i = swap->debug_align - (total & (swap->debug_align - 1));
01693 s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
01694 if (s == NULL && i != 0)
01695 goto error_return;
01696
01697 if (bfd_bwrite ((PTR) s, (bfd_size_type) i, abfd) != i)
01698 {
01699 free (s);
01700 goto error_return;
01701 }
01702 free (s);
01703 }
01704 }
01705
01706
01707
01708 amt = debug->symbolic_header.issExtMax;
01709 if (bfd_bwrite (debug->ssext, amt, abfd) != amt)
01710 goto error_return;
01711 if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0)
01712 {
01713 unsigned int i;
01714 bfd_byte *s;
01715
01716 i = (swap->debug_align
01717 - (debug->symbolic_header.issExtMax & (swap->debug_align - 1)));
01718 s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
01719 if (s == NULL && i != 0)
01720 goto error_return;
01721
01722 if (bfd_bwrite ((PTR) s, (bfd_size_type) i, abfd) != i)
01723 {
01724 free (s);
01725 goto error_return;
01726 }
01727 free (s);
01728 }
01729
01730 if (! ecoff_write_shuffle (abfd, swap, ainfo->fdr, space)
01731 || ! ecoff_write_shuffle (abfd, swap, ainfo->rfd, space))
01732 goto error_return;
01733
01734 BFD_ASSERT (debug->symbolic_header.cbExtOffset == 0
01735 || (debug->symbolic_header.cbExtOffset
01736 == (bfd_vma) bfd_tell (abfd)));
01737
01738 amt = debug->symbolic_header.iextMax * swap->external_ext_size;
01739 if (bfd_bwrite (debug->external_ext, amt, abfd) != amt)
01740 goto error_return;
01741
01742 if (space != NULL)
01743 free (space);
01744 return TRUE;
01745
01746 error_return:
01747 if (space != NULL)
01748 free (space);
01749 return FALSE;
01750 }
01751
01752
01753
01754
01755
01756
01757 static int
01758 cmp_fdrtab_entry (leftp, rightp)
01759 const PTR leftp;
01760 const PTR rightp;
01761 {
01762 const struct ecoff_fdrtab_entry *lp =
01763 (const struct ecoff_fdrtab_entry *) leftp;
01764 const struct ecoff_fdrtab_entry *rp =
01765 (const struct ecoff_fdrtab_entry *) rightp;
01766
01767 if (lp->base_addr < rp->base_addr)
01768 return -1;
01769 if (lp->base_addr > rp->base_addr)
01770 return 1;
01771 return 0;
01772 }
01773
01774
01775
01776
01777
01778
01779
01780 static bfd_boolean
01781 mk_fdrtab (abfd, debug_info, debug_swap, line_info)
01782 bfd *abfd;
01783 struct ecoff_debug_info * const debug_info;
01784 const struct ecoff_debug_swap * const debug_swap;
01785 struct ecoff_find_line *line_info;
01786 {
01787 struct ecoff_fdrtab_entry *tab;
01788 FDR *fdr_ptr;
01789 FDR *fdr_start;
01790 FDR *fdr_end;
01791 bfd_boolean stabs;
01792 long len;
01793 bfd_size_type amt;
01794
01795 fdr_start = debug_info->fdr;
01796 fdr_end = fdr_start + debug_info->symbolic_header.ifdMax;
01797
01798
01799 for (len = 0, fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
01800 {
01801 if (fdr_ptr->cpd == 0)
01802 continue;
01803 ++len;
01804 }
01805
01806
01807 amt = (bfd_size_type) len * sizeof (struct ecoff_fdrtab_entry);
01808 line_info->fdrtab = (struct ecoff_fdrtab_entry*) bfd_zalloc (abfd, amt);
01809 if (line_info->fdrtab == NULL)
01810 return FALSE;
01811 line_info->fdrtab_len = len;
01812
01813 tab = line_info->fdrtab;
01814 for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
01815 {
01816 if (fdr_ptr->cpd == 0)
01817 continue;
01818
01819
01820
01821
01822 stabs = FALSE;
01823 if (fdr_ptr->csym >= 2)
01824 {
01825 char *sym_ptr;
01826 SYMR sym;
01827
01828 sym_ptr = ((char *) debug_info->external_sym
01829 + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size);
01830 (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
01831 if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
01832 STABS_SYMBOL) == 0)
01833 stabs = TRUE;
01834 }
01835
01836 if (!stabs)
01837 {
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848 tab->base_addr = fdr_ptr->adr;
01849 }
01850 else
01851 {
01852
01853
01854 tab->base_addr = fdr_ptr->adr;
01855 }
01856 tab->fdr = fdr_ptr;
01857 ++tab;
01858 }
01859
01860
01861
01862
01863
01864 qsort ((PTR) line_info->fdrtab, (size_t) len,
01865 sizeof (struct ecoff_fdrtab_entry), cmp_fdrtab_entry);
01866
01867 return TRUE;
01868 }
01869
01870
01871
01872 static long
01873 fdrtab_lookup (line_info, offset)
01874 struct ecoff_find_line *line_info;
01875 bfd_vma offset;
01876 {
01877 long low, high, len;
01878 long mid = -1;
01879 struct ecoff_fdrtab_entry *tab;
01880
01881 len = line_info->fdrtab_len;
01882 if (len == 0)
01883 return -1;
01884
01885 tab = line_info->fdrtab;
01886 for (low = 0, high = len - 1 ; low != high ;)
01887 {
01888 mid = (high + low) / 2;
01889 if (offset >= tab[mid].base_addr && offset < tab[mid + 1].base_addr)
01890 goto find_min;
01891
01892 if (tab[mid].base_addr > offset)
01893 high = mid;
01894 else
01895 low = mid + 1;
01896 }
01897
01898
01899
01900
01901
01902
01903 ++mid;
01904
01905
01906 if (offset < tab[mid].base_addr)
01907 return -1;
01908
01909 find_min:
01910
01911
01912
01913 while (mid > 0 && tab[mid - 1].base_addr == tab[mid].base_addr)
01914 --mid;
01915
01916 return mid;
01917 }
01918
01919
01920
01921
01922 static bfd_boolean
01923 lookup_line (abfd, debug_info, debug_swap, line_info)
01924 bfd *abfd;
01925 struct ecoff_debug_info * const debug_info;
01926 const struct ecoff_debug_swap * const debug_swap;
01927 struct ecoff_find_line *line_info;
01928 {
01929 struct ecoff_fdrtab_entry *tab;
01930 bfd_vma offset;
01931 bfd_boolean stabs;
01932 FDR *fdr_ptr;
01933 int i;
01934
01935
01936 offset = line_info->cache.start;
01937
01938
01939
01940 if (line_info->fdrtab == NULL
01941 && !mk_fdrtab (abfd, debug_info, debug_swap, line_info))
01942 return FALSE;
01943
01944 tab = line_info->fdrtab;
01945
01946
01947 i = fdrtab_lookup (line_info, offset);
01948 if (i < 0)
01949 return FALSE;
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020 fdr_ptr = tab[i].fdr;
02021
02022
02023
02024
02025 stabs = FALSE;
02026 if (fdr_ptr->csym >= 2)
02027 {
02028 char *sym_ptr;
02029 SYMR sym;
02030
02031 sym_ptr = ((char *) debug_info->external_sym
02032 + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size);
02033 (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
02034 if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
02035 STABS_SYMBOL) == 0)
02036 stabs = TRUE;
02037 }
02038
02039 if (!stabs)
02040 {
02041 bfd_size_type external_pdr_size;
02042 char *pdr_ptr;
02043 char *best_pdr = NULL;
02044 FDR *best_fdr;
02045 bfd_signed_vma best_dist = -1;
02046 PDR pdr;
02047 unsigned char *line_ptr;
02048 unsigned char *line_end;
02049 int lineno;
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105 external_pdr_size = debug_swap->external_pdr_size;
02106
02107
02108
02109
02110
02111
02112
02113
02114 i = 0;
02115
02116
02117
02118 best_fdr = NULL;
02119 do
02120 {
02121
02122
02123
02124 bfd_signed_vma dist = -1, min_dist = -1;
02125 char *pdr_hold;
02126 char *pdr_end;
02127
02128 fdr_ptr = tab[i].fdr;
02129
02130 pdr_ptr = ((char *) debug_info->external_pdr
02131 + fdr_ptr->ipdFirst * external_pdr_size);
02132 pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size;
02133 (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
02134
02135
02136
02137
02138
02139 for (pdr_hold = NULL;
02140 pdr_ptr < pdr_end;
02141 (pdr_ptr += external_pdr_size,
02142 (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr)))
02143 {
02144 if (offset >= (pdr.adr - 0x10 * pdr.prof))
02145 {
02146 dist = offset - (pdr.adr - 0x10 * pdr.prof);
02147
02148
02149
02150 if (!pdr_hold || (dist >= 0 && dist < min_dist))
02151 {
02152 min_dist = dist;
02153 pdr_hold = pdr_ptr;
02154 }
02155 }
02156 }
02157
02158 if (!best_pdr || (min_dist >= 0 && min_dist < best_dist))
02159 {
02160 best_dist = (bfd_vma) min_dist;
02161 best_fdr = fdr_ptr;
02162 best_pdr = pdr_hold;
02163 }
02164
02165 }
02166
02167
02168 while (++i < line_info->fdrtab_len);
02169
02170 if (!best_fdr || !best_pdr)
02171 return FALSE;
02172
02173
02174 fdr_ptr = best_fdr;
02175 pdr_ptr = best_pdr;
02176 (*debug_swap->swap_pdr_in) (abfd, (PTR) pdr_ptr, &pdr);
02177
02178
02179
02180
02181 line_end = debug_info->line + fdr_ptr->cbLineOffset + fdr_ptr->cbLine;
02182
02183
02184 offset -= pdr.adr - 0x10 * pdr.prof;
02185 lineno = pdr.lnLow;
02186 line_ptr = debug_info->line + fdr_ptr->cbLineOffset + pdr.cbLineOffset;
02187 while (line_ptr < line_end)
02188 {
02189 int delta;
02190 unsigned int count;
02191
02192 delta = *line_ptr >> 4;
02193 if (delta >= 0x8)
02194 delta -= 0x10;
02195 count = (*line_ptr & 0xf) + 1;
02196 ++line_ptr;
02197 if (delta == -8)
02198 {
02199 delta = (((line_ptr[0]) & 0xff) << 8) + ((line_ptr[1]) & 0xff);
02200 if (delta >= 0x8000)
02201 delta -= 0x10000;
02202 line_ptr += 2;
02203 }
02204 lineno += delta;
02205 if (offset < count * 4)
02206 {
02207 line_info->cache.stop += count * 4 - offset;
02208 break;
02209 }
02210 offset -= count * 4;
02211 }
02212
02213
02214
02215 if (fdr_ptr->rss == -1)
02216 {
02217 line_info->cache.filename = NULL;
02218 if (pdr.isym == -1)
02219 line_info->cache.functionname = NULL;
02220 else
02221 {
02222 EXTR proc_ext;
02223
02224 (*debug_swap->swap_ext_in)
02225 (abfd,
02226 ((char *) debug_info->external_ext
02227 + pdr.isym * debug_swap->external_ext_size),
02228 &proc_ext);
02229 line_info->cache.functionname = (debug_info->ssext
02230 + proc_ext.asym.iss);
02231 }
02232 }
02233 else
02234 {
02235 SYMR proc_sym;
02236
02237 line_info->cache.filename = (debug_info->ss
02238 + fdr_ptr->issBase
02239 + fdr_ptr->rss);
02240 (*debug_swap->swap_sym_in)
02241 (abfd,
02242 ((char *) debug_info->external_sym
02243 + ((fdr_ptr->isymBase + pdr.isym)
02244 * debug_swap->external_sym_size)),
02245 &proc_sym);
02246 line_info->cache.functionname = (debug_info->ss
02247 + fdr_ptr->issBase
02248 + proc_sym.iss);
02249 }
02250 if (lineno == ilineNil)
02251 lineno = 0;
02252 line_info->cache.line_num = lineno;
02253 }
02254 else
02255 {
02256 bfd_size_type external_sym_size;
02257 const char *directory_name;
02258 const char *main_file_name;
02259 const char *current_file_name;
02260 const char *function_name;
02261 const char *line_file_name;
02262 bfd_vma low_func_vma;
02263 bfd_vma low_line_vma;
02264 bfd_boolean past_line;
02265 bfd_boolean past_fn;
02266 char *sym_ptr, *sym_ptr_end;
02267 size_t len, funclen;
02268 char *buffer = NULL;
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280 line_info->cache.filename = NULL;
02281 line_info->cache.functionname = NULL;
02282 line_info->cache.line_num = 0;
02283
02284 directory_name = NULL;
02285 main_file_name = NULL;
02286 current_file_name = NULL;
02287 function_name = NULL;
02288 line_file_name = NULL;
02289 low_func_vma = 0;
02290 low_line_vma = 0;
02291 past_line = FALSE;
02292 past_fn = FALSE;
02293
02294 external_sym_size = debug_swap->external_sym_size;
02295
02296 sym_ptr = ((char *) debug_info->external_sym
02297 + (fdr_ptr->isymBase + 2) * external_sym_size);
02298 sym_ptr_end = sym_ptr + (fdr_ptr->csym - 2) * external_sym_size;
02299 for (;
02300 sym_ptr < sym_ptr_end && (! past_line || ! past_fn);
02301 sym_ptr += external_sym_size)
02302 {
02303 SYMR sym;
02304
02305 (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
02306
02307 if (ECOFF_IS_STAB (&sym))
02308 {
02309 switch (ECOFF_UNMARK_STAB (sym.index))
02310 {
02311 case N_SO:
02312 main_file_name = current_file_name =
02313 debug_info->ss + fdr_ptr->issBase + sym.iss;
02314
02315
02316
02317 if (sym_ptr + external_sym_size < sym_ptr_end)
02318 {
02319 SYMR nextsym;
02320
02321 (*debug_swap->swap_sym_in) (abfd,
02322 sym_ptr + external_sym_size,
02323 &nextsym);
02324 if (ECOFF_IS_STAB (&nextsym)
02325 && ECOFF_UNMARK_STAB (nextsym.index) == N_SO)
02326 {
02327 directory_name = current_file_name;
02328 main_file_name = current_file_name =
02329 debug_info->ss + fdr_ptr->issBase + nextsym.iss;
02330 sym_ptr += external_sym_size;
02331 }
02332 }
02333 break;
02334
02335 case N_SOL:
02336 current_file_name =
02337 debug_info->ss + fdr_ptr->issBase + sym.iss;
02338 break;
02339
02340 case N_FUN:
02341 if (sym.value > offset)
02342 past_fn = TRUE;
02343 else if (sym.value >= low_func_vma)
02344 {
02345 low_func_vma = sym.value;
02346 function_name =
02347 debug_info->ss + fdr_ptr->issBase + sym.iss;
02348 }
02349 break;
02350 }
02351 }
02352 else if (sym.st == stLabel && sym.index != indexNil)
02353 {
02354 if (sym.value > offset)
02355 past_line = TRUE;
02356 else if (sym.value >= low_line_vma)
02357 {
02358 low_line_vma = sym.value;
02359 line_file_name = current_file_name;
02360 line_info->cache.line_num = sym.index;
02361 }
02362 }
02363 }
02364
02365 if (line_info->cache.line_num != 0)
02366 main_file_name = line_file_name;
02367
02368
02369
02370
02371 if (function_name == NULL)
02372 len = funclen = 0;
02373 else
02374 len = funclen = strlen (function_name) + 1;
02375
02376 if (main_file_name != NULL
02377 && directory_name != NULL
02378 && main_file_name[0] != '/')
02379 len += strlen (directory_name) + strlen (main_file_name) + 1;
02380
02381 if (len != 0)
02382 {
02383 if (line_info->find_buffer != NULL)
02384 free (line_info->find_buffer);
02385 buffer = (char *) bfd_malloc ((bfd_size_type) len);
02386 if (buffer == NULL)
02387 return FALSE;
02388 line_info->find_buffer = buffer;
02389 }
02390
02391 if (function_name != NULL)
02392 {
02393 char *colon;
02394
02395 strcpy (buffer, function_name);
02396 colon = strchr (buffer, ':');
02397 if (colon != NULL)
02398 *colon = '\0';
02399 line_info->cache.functionname = buffer;
02400 }
02401
02402 if (main_file_name != NULL)
02403 {
02404 if (directory_name == NULL || main_file_name[0] == '/')
02405 line_info->cache.filename = main_file_name;
02406 else
02407 {
02408 sprintf (buffer + funclen, "%s%s", directory_name,
02409 main_file_name);
02410 line_info->cache.filename = buffer + funclen;
02411 }
02412 }
02413 }
02414
02415 return TRUE;
02416 }
02417
02418
02419
02420 bfd_boolean
02421 _bfd_ecoff_locate_line (abfd, section, offset, debug_info, debug_swap,
02422 line_info, filename_ptr, functionname_ptr, retline_ptr)
02423 bfd *abfd;
02424 asection *section;
02425 bfd_vma offset;
02426 struct ecoff_debug_info * const debug_info;
02427 const struct ecoff_debug_swap * const debug_swap;
02428 struct ecoff_find_line *line_info;
02429 const char **filename_ptr;
02430 const char **functionname_ptr;
02431 unsigned int *retline_ptr;
02432 {
02433 offset += section->vma;
02434
02435 if (line_info->cache.sect == NULL
02436 || line_info->cache.sect != section
02437 || offset < line_info->cache.start
02438 || offset >= line_info->cache.stop)
02439 {
02440 line_info->cache.sect = section;
02441 line_info->cache.start = offset;
02442 line_info->cache.stop = offset;
02443 if (! lookup_line (abfd, debug_info, debug_swap, line_info))
02444 {
02445 line_info->cache.sect = NULL;
02446 return FALSE;
02447 }
02448 }
02449
02450 *filename_ptr = line_info->cache.filename;
02451 *functionname_ptr = line_info->cache.functionname;
02452 *retline_ptr = line_info->cache.line_num;
02453
02454 return TRUE;
02455 }
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467 static bfd_boolean ecoff_collect_shuffle
02468 PARAMS ((struct shuffle *, bfd_byte *));
02469
02470 static bfd_boolean
02471 ecoff_collect_shuffle (l, buff)
02472 struct shuffle *l;
02473 bfd_byte *buff;
02474 {
02475 unsigned long total;
02476
02477 total = 0;
02478 for (; l != (struct shuffle *) NULL; l = l->next)
02479 {
02480 if (! l->filep)
02481 memcpy (buff, l->u.memory, l->size);
02482 else
02483 {
02484 if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
02485 || (bfd_bread (buff, (bfd_size_type) l->size, l->u.file.input_bfd)
02486 != l->size))
02487 return FALSE;
02488 }
02489 total += l->size;
02490 buff += l->size;
02491 }
02492
02493 return TRUE;
02494 }
02495
02496
02497
02498 bfd_boolean
02499 _bfd_ecoff_get_accumulated_pdr (handle, buff)
02500 PTR handle;
02501 bfd_byte *buff;
02502 {
02503 struct accumulate *ainfo = (struct accumulate *) handle;
02504
02505 return ecoff_collect_shuffle (ainfo->pdr, buff);
02506 }
02507
02508
02509
02510 bfd_boolean
02511 _bfd_ecoff_get_accumulated_sym (handle, buff)
02512 PTR handle;
02513 bfd_byte *buff;
02514 {
02515 struct accumulate *ainfo = (struct accumulate *) handle;
02516
02517 return ecoff_collect_shuffle (ainfo->sym, buff);
02518 }
02519
02520
02521
02522 bfd_boolean
02523 _bfd_ecoff_get_accumulated_ss (handle, buff)
02524 PTR handle;
02525 bfd_byte *buff;
02526 {
02527 struct accumulate *ainfo = (struct accumulate *) handle;
02528 struct string_hash_entry *sh;
02529 unsigned long total;
02530
02531
02532
02533 BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
02534 *buff++ = '\0';
02535 total = 1;
02536 BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
02537 for (sh = ainfo->ss_hash;
02538 sh != (struct string_hash_entry *) NULL;
02539 sh = sh->next)
02540 {
02541 size_t len;
02542
02543 len = strlen (sh->root.string);
02544 memcpy (buff, (PTR) sh->root.string, len + 1);
02545 total += len + 1;
02546 buff += len + 1;
02547 }
02548
02549 return TRUE;
02550 }