00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 #include "bfd.h"
00315 #include "sysdep.h"
00316 #include "libbfd.h"
00317 #include "safe-ctype.h"
00318 #include "bfdlink.h"
00319 #include "aout/stab_gnu.h"
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 bfd_boolean
00357 bfd_is_local_label (bfd *abfd, asymbol *sym)
00358 {
00359
00360
00361
00362 if ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_FILE | BSF_SECTION_SYM)) != 0)
00363 return FALSE;
00364 if (sym->name == NULL)
00365 return FALSE;
00366 return bfd_is_local_label_name (abfd, sym->name);
00367 }
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 bfd_boolean
00435 bfd_set_symtab (bfd *abfd, asymbol **location, unsigned int symcount)
00436 {
00437 if (abfd->format != bfd_object || bfd_read_p (abfd))
00438 {
00439 bfd_set_error (bfd_error_invalid_operation);
00440 return FALSE;
00441 }
00442
00443 bfd_get_outsymbols (abfd) = location;
00444 bfd_get_symcount (abfd) = symcount;
00445 return TRUE;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 void
00460 bfd_print_symbol_vandf (bfd *abfd, void *arg, asymbol *symbol)
00461 {
00462 FILE *file = arg;
00463
00464 flagword type = symbol->flags;
00465
00466 if (symbol->section != NULL)
00467 bfd_fprintf_vma (abfd, file, symbol->value + symbol->section->vma);
00468 else
00469 bfd_fprintf_vma (abfd, file, symbol->value);
00470
00471
00472
00473
00474 fprintf (file, " %c%c%c%c%c%c%c",
00475 ((type & BSF_LOCAL)
00476 ? (type & BSF_GLOBAL) ? '!' : 'l'
00477 : (type & BSF_GLOBAL) ? 'g' : ' '),
00478 (type & BSF_WEAK) ? 'w' : ' ',
00479 (type & BSF_CONSTRUCTOR) ? 'C' : ' ',
00480 (type & BSF_WARNING) ? 'W' : ' ',
00481 (type & BSF_INDIRECT) ? 'I' : ' ',
00482 (type & BSF_DEBUGGING) ? 'd' : (type & BSF_DYNAMIC) ? 'D' : ' ',
00483 ((type & BSF_FUNCTION)
00484 ? 'F'
00485 : ((type & BSF_FILE)
00486 ? 'f'
00487 : ((type & BSF_OBJECT) ? 'O' : ' '))));
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 asymbol *
00523 _bfd_generic_make_empty_symbol (bfd *abfd)
00524 {
00525 bfd_size_type amt = sizeof (asymbol);
00526 asymbol *new = bfd_zalloc (abfd, amt);
00527 if (new)
00528 new->the_bfd = abfd;
00529 return new;
00530 }
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 struct section_to_type
00547 {
00548 const char *section;
00549 char type;
00550 };
00551
00552
00553
00554
00555 static const struct section_to_type stt[] =
00556 {
00557 {".bss", 'b'},
00558 {"code", 't'},
00559 {".data", 'd'},
00560 {"*DEBUG*", 'N'},
00561 {".debug", 'N'},
00562 {".drectve", 'i'},
00563 {".edata", 'e'},
00564 {".fini", 't'},
00565 {".idata", 'i'},
00566 {".init", 't'},
00567 {".pdata", 'p'},
00568 {".rdata", 'r'},
00569 {".rodata", 'r'},
00570 {".sbss", 's'},
00571 {".scommon", 'c'},
00572 {".sdata", 'g'},
00573 {".text", 't'},
00574 {"vars", 'd'},
00575 {"zerovars", 'b'},
00576 {0, 0}
00577 };
00578
00579
00580
00581
00582
00583
00584
00585 static char
00586 coff_section_type (const char *s)
00587 {
00588 const struct section_to_type *t;
00589
00590 for (t = &stt[0]; t->section; t++)
00591 if (!strncmp (s, t->section, strlen (t->section)))
00592 return t->type;
00593
00594 return '?';
00595 }
00596
00597
00598
00599
00600
00601
00602
00603
00604 static char
00605 decode_section_type (const struct bfd_section *section)
00606 {
00607 if (section->flags & SEC_CODE)
00608 return 't';
00609 if (section->flags & SEC_DATA)
00610 {
00611 if (section->flags & SEC_READONLY)
00612 return 'r';
00613 else if (section->flags & SEC_SMALL_DATA)
00614 return 'g';
00615 else
00616 return 'd';
00617 }
00618 if ((section->flags & SEC_HAS_CONTENTS) == 0)
00619 {
00620 if (section->flags & SEC_SMALL_DATA)
00621 return 's';
00622 else
00623 return 'b';
00624 }
00625 if (section->flags & SEC_DEBUGGING)
00626 return 'N';
00627 if ((section->flags & SEC_HAS_CONTENTS) && (section->flags & SEC_READONLY))
00628 return 'n';
00629
00630 return '?';
00631 }
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 int
00645 bfd_decode_symclass (asymbol *symbol)
00646 {
00647 char c;
00648
00649 if (bfd_is_com_section (symbol->section))
00650 return 'C';
00651 if (bfd_is_und_section (symbol->section))
00652 {
00653 if (symbol->flags & BSF_WEAK)
00654 {
00655
00656
00657 if (symbol->flags & BSF_OBJECT)
00658 return 'v';
00659 else
00660 return 'w';
00661 }
00662 else
00663 return 'U';
00664 }
00665 if (bfd_is_ind_section (symbol->section))
00666 return 'I';
00667 if (symbol->flags & BSF_WEAK)
00668 {
00669
00670
00671 if (symbol->flags & BSF_OBJECT)
00672 return 'V';
00673 else
00674 return 'W';
00675 }
00676 if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL)))
00677 return '?';
00678
00679 if (bfd_is_abs_section (symbol->section))
00680 c = 'a';
00681 else if (symbol->section)
00682 {
00683 c = coff_section_type (symbol->section->name);
00684 if (c == '?')
00685 c = decode_section_type (symbol->section);
00686 }
00687 else
00688 return '?';
00689 if (symbol->flags & BSF_GLOBAL)
00690 c = TOUPPER (c);
00691 return c;
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 bfd_boolean
00717 bfd_is_undefined_symclass (int symclass)
00718 {
00719 return symclass == 'U' || symclass == 'w' || symclass == 'v';
00720 }
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 void
00736 bfd_symbol_info (asymbol *symbol, symbol_info *ret)
00737 {
00738 ret->type = bfd_decode_symclass (symbol);
00739
00740 if (bfd_is_undefined_symclass (ret->type))
00741 ret->value = 0;
00742 else
00743 ret->value = symbol->value + symbol->section->vma;
00744
00745 ret->name = symbol->name;
00746 }
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775 long
00776 _bfd_generic_read_minisymbols (bfd *abfd,
00777 bfd_boolean dynamic,
00778 void **minisymsp,
00779 unsigned int *sizep)
00780 {
00781 long storage;
00782 asymbol **syms = NULL;
00783 long symcount;
00784
00785 if (dynamic)
00786 storage = bfd_get_dynamic_symtab_upper_bound (abfd);
00787 else
00788 storage = bfd_get_symtab_upper_bound (abfd);
00789 if (storage < 0)
00790 goto error_return;
00791 if (storage == 0)
00792 return 0;
00793
00794 syms = bfd_malloc (storage);
00795 if (syms == NULL)
00796 goto error_return;
00797
00798 if (dynamic)
00799 symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
00800 else
00801 symcount = bfd_canonicalize_symtab (abfd, syms);
00802 if (symcount < 0)
00803 goto error_return;
00804
00805 *minisymsp = syms;
00806 *sizep = sizeof (asymbol *);
00807 return symcount;
00808
00809 error_return:
00810 bfd_set_error (bfd_error_no_symbols);
00811 if (syms != NULL)
00812 free (syms);
00813 return -1;
00814 }
00815
00816
00817
00818
00819
00820 asymbol *
00821 _bfd_generic_minisymbol_to_symbol (bfd *abfd ATTRIBUTE_UNUSED,
00822 bfd_boolean dynamic ATTRIBUTE_UNUSED,
00823 const void *minisym,
00824 asymbol *sym ATTRIBUTE_UNUSED)
00825 {
00826 return *(asymbol **) minisym;
00827 }
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 #define ENABLE_CACHING
00841
00842
00843
00844
00845
00846 struct indexentry
00847 {
00848 bfd_vma val;
00849 bfd_byte *stab;
00850 bfd_byte *str;
00851 char *directory_name;
00852 char *file_name;
00853 char *function_name;
00854 };
00855
00856
00857
00858 static int
00859 cmpindexentry (const void *a, const void *b)
00860 {
00861 const struct indexentry *contestantA = a;
00862 const struct indexentry *contestantB = b;
00863
00864 if (contestantA->val < contestantB->val)
00865 return -1;
00866 else if (contestantA->val > contestantB->val)
00867 return 1;
00868 else
00869 return 0;
00870 }
00871
00872
00873
00874 struct stab_find_info
00875 {
00876
00877 asection *stabsec;
00878
00879 asection *strsec;
00880
00881 bfd_byte *stabs;
00882
00883 bfd_byte *strs;
00884
00885
00886 struct indexentry *indextable;
00887
00888 int indextablesize;
00889
00890 #ifdef ENABLE_CACHING
00891
00892 struct indexentry *cached_indexentry;
00893 bfd_vma cached_offset;
00894 bfd_byte *cached_stab;
00895 char *cached_file_name;
00896 #endif
00897
00898
00899 char *filename;
00900 };
00901
00902 bfd_boolean
00903 _bfd_stab_section_find_nearest_line (bfd *abfd,
00904 asymbol **symbols,
00905 asection *section,
00906 bfd_vma offset,
00907 bfd_boolean *pfound,
00908 const char **pfilename,
00909 const char **pfnname,
00910 unsigned int *pline,
00911 void **pinfo)
00912 {
00913 struct stab_find_info *info;
00914 bfd_size_type stabsize, strsize;
00915 bfd_byte *stab, *str;
00916 bfd_byte *last_stab = NULL;
00917 bfd_size_type stroff;
00918 struct indexentry *indexentry;
00919 char *file_name;
00920 char *directory_name;
00921 int saw_fun;
00922 bfd_boolean saw_line, saw_func;
00923
00924 *pfound = FALSE;
00925 *pfilename = bfd_get_filename (abfd);
00926 *pfnname = NULL;
00927 *pline = 0;
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942 #define STRDXOFF (0)
00943 #define TYPEOFF (4)
00944 #define OTHEROFF (5)
00945 #define DESCOFF (6)
00946 #define VALOFF (8)
00947 #define STABSIZE (12)
00948
00949 info = *pinfo;
00950 if (info != NULL)
00951 {
00952 if (info->stabsec == NULL || info->strsec == NULL)
00953 {
00954
00955 return TRUE;
00956 }
00957
00958 stabsize = (info->stabsec->rawsize
00959 ? info->stabsec->rawsize
00960 : info->stabsec->size);
00961 strsize = (info->strsec->rawsize
00962 ? info->strsec->rawsize
00963 : info->strsec->size);
00964 }
00965 else
00966 {
00967 long reloc_size, reloc_count;
00968 arelent **reloc_vector;
00969 int i;
00970 char *name;
00971 char *function_name;
00972 bfd_size_type amt = sizeof *info;
00973
00974 info = bfd_zalloc (abfd, amt);
00975 if (info == NULL)
00976 return FALSE;
00977
00978
00979
00980
00981
00982 info->stabsec = bfd_get_section_by_name (abfd, ".stab");
00983 info->strsec = bfd_get_section_by_name (abfd, ".stabstr");
00984
00985 if (info->stabsec == NULL || info->strsec == NULL)
00986 {
00987
00988
00989 *pinfo = info;
00990 return TRUE;
00991 }
00992
00993 stabsize = (info->stabsec->rawsize
00994 ? info->stabsec->rawsize
00995 : info->stabsec->size);
00996 strsize = (info->strsec->rawsize
00997 ? info->strsec->rawsize
00998 : info->strsec->size);
00999
01000 info->stabs = bfd_alloc (abfd, stabsize);
01001 info->strs = bfd_alloc (abfd, strsize);
01002 if (info->stabs == NULL || info->strs == NULL)
01003 return FALSE;
01004
01005 if (! bfd_get_section_contents (abfd, info->stabsec, info->stabs,
01006 0, stabsize)
01007 || ! bfd_get_section_contents (abfd, info->strsec, info->strs,
01008 0, strsize))
01009 return FALSE;
01010
01011
01012
01013
01014
01015 reloc_size = bfd_get_reloc_upper_bound (abfd, info->stabsec);
01016 if (reloc_size < 0)
01017 return FALSE;
01018 reloc_vector = bfd_malloc (reloc_size);
01019 if (reloc_vector == NULL && reloc_size != 0)
01020 return FALSE;
01021 reloc_count = bfd_canonicalize_reloc (abfd, info->stabsec, reloc_vector,
01022 symbols);
01023 if (reloc_count < 0)
01024 {
01025 if (reloc_vector != NULL)
01026 free (reloc_vector);
01027 return FALSE;
01028 }
01029 if (reloc_count > 0)
01030 {
01031 arelent **pr;
01032
01033 for (pr = reloc_vector; *pr != NULL; pr++)
01034 {
01035 arelent *r;
01036 unsigned long val;
01037 asymbol *sym;
01038
01039 r = *pr;
01040
01041 if (r->howto->dst_mask == 0)
01042 continue;
01043
01044 if (r->howto->rightshift != 0
01045 || r->howto->size != 2
01046 || r->howto->bitsize != 32
01047 || r->howto->pc_relative
01048 || r->howto->bitpos != 0
01049 || r->howto->dst_mask != 0xffffffff)
01050 {
01051 (*_bfd_error_handler)
01052 (_("Unsupported .stab relocation"));
01053 bfd_set_error (bfd_error_invalid_operation);
01054 if (reloc_vector != NULL)
01055 free (reloc_vector);
01056 return FALSE;
01057 }
01058
01059 val = bfd_get_32 (abfd, info->stabs + r->address);
01060 val &= r->howto->src_mask;
01061 sym = *r->sym_ptr_ptr;
01062 val += sym->value + sym->section->vma + r->addend;
01063 bfd_put_32 (abfd, (bfd_vma) val, info->stabs + r->address);
01064 }
01065 }
01066
01067 if (reloc_vector != NULL)
01068 free (reloc_vector);
01069
01070
01071
01072
01073
01074
01075
01076 info->indextablesize = 0;
01077 saw_fun = 1;
01078 for (stab = info->stabs; stab < info->stabs + stabsize; stab += STABSIZE)
01079 {
01080 if (stab[TYPEOFF] == (bfd_byte) N_SO)
01081 {
01082
01083 if (bfd_get_32 (abfd, stab + STRDXOFF) == 0)
01084 continue;
01085
01086
01087 if (saw_fun == 0)
01088 ++info->indextablesize;
01089
01090 saw_fun = 0;
01091
01092
01093 if (stab + STABSIZE < info->stabs + stabsize
01094 && *(stab + STABSIZE + TYPEOFF) == (bfd_byte) N_SO)
01095 {
01096 stab += STABSIZE;
01097 }
01098 }
01099 else if (stab[TYPEOFF] == (bfd_byte) N_FUN)
01100 {
01101 saw_fun = 1;
01102 ++info->indextablesize;
01103 }
01104 }
01105
01106 if (saw_fun == 0)
01107 ++info->indextablesize;
01108
01109 if (info->indextablesize == 0)
01110 return TRUE;
01111 ++info->indextablesize;
01112
01113 amt = info->indextablesize;
01114 amt *= sizeof (struct indexentry);
01115 info->indextable = bfd_alloc (abfd, amt);
01116 if (info->indextable == NULL)
01117 return FALSE;
01118
01119 file_name = NULL;
01120 directory_name = NULL;
01121 saw_fun = 1;
01122
01123 for (i = 0, stroff = 0, stab = info->stabs, str = info->strs;
01124 i < info->indextablesize && stab < info->stabs + stabsize;
01125 stab += STABSIZE)
01126 {
01127 switch (stab[TYPEOFF])
01128 {
01129 case 0:
01130
01131 if ((bfd_size_type) ((info->strs + strsize) - str) < stroff)
01132 break;
01133 str += stroff;
01134 stroff = bfd_get_32 (abfd, stab + VALOFF);
01135 break;
01136
01137 case N_SO:
01138
01139
01140
01141
01142
01143
01144
01145 if (saw_fun == 0)
01146 {
01147 info->indextable[i].val = bfd_get_32 (abfd, last_stab + VALOFF);
01148 info->indextable[i].stab = last_stab;
01149 info->indextable[i].str = str;
01150 info->indextable[i].directory_name = directory_name;
01151 info->indextable[i].file_name = file_name;
01152 info->indextable[i].function_name = NULL;
01153 ++i;
01154 }
01155 saw_fun = 0;
01156
01157 file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
01158 if (*file_name == '\0')
01159 {
01160 directory_name = NULL;
01161 file_name = NULL;
01162 saw_fun = 1;
01163 }
01164 else
01165 {
01166 last_stab = stab;
01167 if (stab + STABSIZE >= info->stabs + stabsize
01168 || *(stab + STABSIZE + TYPEOFF) != (bfd_byte) N_SO)
01169 {
01170 directory_name = NULL;
01171 }
01172 else
01173 {
01174
01175
01176 stab += STABSIZE;
01177 directory_name = file_name;
01178 file_name = ((char *) str
01179 + bfd_get_32 (abfd, stab + STRDXOFF));
01180 }
01181 }
01182 break;
01183
01184 case N_SOL:
01185
01186 file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
01187 break;
01188
01189 case N_FUN:
01190
01191 saw_fun = 1;
01192 name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
01193
01194 if (*name == '\0')
01195 name = NULL;
01196
01197 function_name = name;
01198
01199 if (name == NULL)
01200 continue;
01201
01202 info->indextable[i].val = bfd_get_32 (abfd, stab + VALOFF);
01203 info->indextable[i].stab = stab;
01204 info->indextable[i].str = str;
01205 info->indextable[i].directory_name = directory_name;
01206 info->indextable[i].file_name = file_name;
01207 info->indextable[i].function_name = function_name;
01208 ++i;
01209 break;
01210 }
01211 }
01212
01213 if (saw_fun == 0)
01214 {
01215 info->indextable[i].val = bfd_get_32 (abfd, last_stab + VALOFF);
01216 info->indextable[i].stab = last_stab;
01217 info->indextable[i].str = str;
01218 info->indextable[i].directory_name = directory_name;
01219 info->indextable[i].file_name = file_name;
01220 info->indextable[i].function_name = NULL;
01221 ++i;
01222 }
01223
01224 info->indextable[i].val = (bfd_vma) -1;
01225 info->indextable[i].stab = info->stabs + stabsize;
01226 info->indextable[i].str = str;
01227 info->indextable[i].directory_name = NULL;
01228 info->indextable[i].file_name = NULL;
01229 info->indextable[i].function_name = NULL;
01230 ++i;
01231
01232 info->indextablesize = i;
01233 qsort (info->indextable, (size_t) i, sizeof (struct indexentry),
01234 cmpindexentry);
01235
01236 *pinfo = info;
01237 }
01238
01239
01240
01241 offset += bfd_get_section_vma (abfd, section);
01242
01243 #ifdef ENABLE_CACHING
01244 if (info->cached_indexentry != NULL
01245 && offset >= info->cached_offset
01246 && offset < (info->cached_indexentry + 1)->val)
01247 {
01248 stab = info->cached_stab;
01249 indexentry = info->cached_indexentry;
01250 file_name = info->cached_file_name;
01251 }
01252 else
01253 #endif
01254 {
01255 long low, high;
01256 long mid = -1;
01257
01258
01259
01260 indexentry = NULL;
01261
01262 low = 0;
01263 high = info->indextablesize - 1;
01264 while (low != high)
01265 {
01266 mid = (high + low) / 2;
01267 if (offset >= info->indextable[mid].val
01268 && offset < info->indextable[mid + 1].val)
01269 {
01270 indexentry = &info->indextable[mid];
01271 break;
01272 }
01273
01274 if (info->indextable[mid].val > offset)
01275 high = mid;
01276 else
01277 low = mid + 1;
01278 }
01279
01280 if (indexentry == NULL)
01281 return TRUE;
01282
01283 stab = indexentry->stab + STABSIZE;
01284 file_name = indexentry->file_name;
01285 }
01286
01287 directory_name = indexentry->directory_name;
01288 str = indexentry->str;
01289
01290 saw_line = FALSE;
01291 saw_func = FALSE;
01292 for (; stab < (indexentry+1)->stab; stab += STABSIZE)
01293 {
01294 bfd_boolean done;
01295 bfd_vma val;
01296
01297 done = FALSE;
01298
01299 switch (stab[TYPEOFF])
01300 {
01301 case N_SOL:
01302
01303 val = bfd_get_32 (abfd, stab + VALOFF);
01304 if (val <= offset)
01305 {
01306 file_name = (char *) str + bfd_get_32 (abfd, stab + STRDXOFF);
01307 *pline = 0;
01308 }
01309 break;
01310
01311 case N_SLINE:
01312 case N_DSLINE:
01313 case N_BSLINE:
01314
01315
01316
01317 val = ((indexentry->function_name ? indexentry->val : 0)
01318 + bfd_get_32 (abfd, stab + VALOFF));
01319
01320
01321
01322
01323 if (!saw_line || val <= offset)
01324 {
01325 *pline = bfd_get_16 (abfd, stab + DESCOFF);
01326
01327 #ifdef ENABLE_CACHING
01328 info->cached_stab = stab;
01329 info->cached_offset = val;
01330 info->cached_file_name = file_name;
01331 info->cached_indexentry = indexentry;
01332 #endif
01333 }
01334 if (val > offset)
01335 done = TRUE;
01336 saw_line = TRUE;
01337 break;
01338
01339 case N_FUN:
01340 case N_SO:
01341 if (saw_func || saw_line)
01342 done = TRUE;
01343 saw_func = TRUE;
01344 break;
01345 }
01346
01347 if (done)
01348 break;
01349 }
01350
01351 *pfound = TRUE;
01352
01353 if (file_name == NULL || IS_ABSOLUTE_PATH (file_name)
01354 || directory_name == NULL)
01355 *pfilename = file_name;
01356 else
01357 {
01358 size_t dirlen;
01359
01360 dirlen = strlen (directory_name);
01361 if (info->filename == NULL
01362 || strncmp (info->filename, directory_name, dirlen) != 0
01363 || strcmp (info->filename + dirlen, file_name) != 0)
01364 {
01365 size_t len;
01366
01367 if (info->filename != NULL)
01368 free (info->filename);
01369 len = strlen (file_name) + 1;
01370 info->filename = bfd_malloc (dirlen + len);
01371 if (info->filename == NULL)
01372 return FALSE;
01373 memcpy (info->filename, directory_name, dirlen);
01374 memcpy (info->filename + dirlen, file_name, len);
01375 }
01376
01377 *pfilename = info->filename;
01378 }
01379
01380 if (indexentry->function_name != NULL)
01381 {
01382 char *s;
01383
01384
01385
01386
01387 s = strchr (indexentry->function_name, ':');
01388 if (s != NULL)
01389 *s = '\0';
01390
01391 *pfnname = indexentry->function_name;
01392 }
01393
01394 return TRUE;
01395 }