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 #define __XCOFF_HYBRID__
00036
00037 #include <regex.h>
00038
00039 #include "symtabAPI/h/Symtab.h"
00040 #include "symtabAPI/src/Object.h"
00041 #include "common/h/pathName.h"
00042
00043 #include "Collections.h"
00044 #include "Symtab.h"
00045 #include "Module.h"
00046
00047 using namespace Dyninst;
00048 using namespace Dyninst::SymtabAPI;
00049
00050 #include "debug.h"
00051
00052 #include <procinfo.h>
00053
00054 #include <sys/ioctl.h>
00055 #include <sys/types.h>
00056 #include <fcntl.h>
00057 #include <assert.h>
00058 #include <stdlib.h>
00059 #include <fcntl.h>
00060 #include <unistd.h>
00061 #include <stdio.h>
00062 #include <string.h>
00063 #include <sys/time.h>
00064 #include <sys/reg.h>
00065 #include <sys/user.h>
00066 #include <sys/wait.h>
00067 #include <procinfo.h>
00068 #include <sys/types.h>
00069 #include <sys/param.h>
00070 #include <set>
00071 using namespace std;
00072 #include <iomanip>
00073
00074 #include <xcoff.h>
00075 #include <exceptab.h>
00076 #define __AR_BIG__
00077 #define __AR_SMALL__
00078 #include <ar.h>
00079 #include <scnhdr.h>
00080
00081 #include <dlfcn.h>
00082 #include "common/h/debugOstream.h"
00083
00084
00085 #if !defined(C_WEAKEXT)
00086 #define C_WEAKEXT 0
00087 #endif
00088
00089 char errorLine[100];
00090 std::string symt_current_func_name;
00091 std::string symt_current_mangled_func_name;
00092 Symbol *symt_current_func = NULL;
00093
00094
00095
00096
00097 #define Bop 18
00098 #define Lop 32
00099 #define BCLRop 19
00100 #define BCCTRxop 528
00101
00102 struct iform {
00103 unsigned op : 6;
00104 signed li : 24;
00105 unsigned aa : 1;
00106 unsigned lk : 1;
00107
00108 };
00109
00110 struct dform {
00111 unsigned op : 6;
00112 unsigned rt : 5;
00113 unsigned ra : 5;
00114 signed d_or_si : 16;
00115 };
00116
00117 struct xlform {
00118 unsigned op : 6;
00119 unsigned bt : 5;
00120 unsigned ba : 5;
00121 unsigned bb : 5;
00122 unsigned xo : 10;
00123 unsigned lk : 1;
00124 };
00125
00126 typedef union {
00127 struct iform iform;
00128 struct dform dform;
00129 struct xlform xlform;
00130 unsigned int raw;
00131 } instructUnion;
00132
00133 unsigned long roundup4(unsigned long val) {
00134 val += 3;
00135 return val - (val % 4);
00136 }
00137
00138
00139
00140
00141 int xcoffArchive_32::read_arhdr()
00142 {
00143 char tmpstring[13];
00144
00145 if (!fo_->set(0))
00146 return -1;
00147 if (!fo_->read(&filehdr, sizeof(struct fl_hdr)))
00148 return -1;
00149 if (strncmp(filehdr.fl_magic, AIAMAG, SAIAMAG))
00150 return -1;
00151 strncpy(tmpstring, filehdr.fl_fstmoff, 12);
00152 tmpstring[12] = 0; first_offset = atol(tmpstring);
00153 if (first_offset % 2) first_offset++;
00154 strncpy(tmpstring, filehdr.fl_lstmoff, 12);
00155 tmpstring[12] = 0; last_offset = atol(tmpstring);
00156 if (last_offset % 2) last_offset++;
00157 next_offset = first_offset;
00158
00159 return 0;
00160 }
00161
00162 int xcoffArchive_64::read_arhdr()
00163 {
00164 char tmpstring[22];
00165
00166 if (!fo_->set(0))
00167 return -1;
00168
00169 if (!fo_->read(&filehdr, sizeof(struct fl_hdr_big)))
00170 return -1;
00171
00172 if (strncmp(filehdr.fl_magic, AIAMAGBIG, SAIAMAG))
00173 return -1;
00174 strncpy(tmpstring, filehdr.fl_fstmoff, 21);
00175 tmpstring[21] = 0; first_offset = atol(tmpstring);
00176 if (first_offset % 2) first_offset++;
00177 strncpy(tmpstring, filehdr.fl_lstmoff, 21);
00178 tmpstring[21] = 0; last_offset = atol(tmpstring);
00179 if (last_offset % 2) last_offset++;
00180 next_offset = first_offset;
00181
00182 return 0;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 int xcoffArchive_32::read_mbrhdr()
00196 {
00197 char tmpstring[13];
00198
00199 if (next_offset == 0) return -1;
00200
00201 if (!fo_->set(next_offset))
00202 return -1;
00203
00204 if (!fo_->read(&memberhdr, sizeof(struct ar_hdr) - 2))
00205 return -1;
00206
00207 strncpy(tmpstring, memberhdr.ar_namlen, 4);
00208 tmpstring[4] = 0; member_len = atol(tmpstring);
00209 if (member_name) free(member_name);
00210 member_name = (char *)malloc(member_len+1);
00211
00212 if (!fo_->read(member_name, member_len))
00213 return -1;
00214
00215 member_name[member_len] = 0;
00216
00217
00218 aout_offset = next_offset + sizeof(struct ar_hdr) + member_len;
00219 if (aout_offset % 2) aout_offset += 1;
00220
00221
00222 if (next_offset == last_offset)
00223 next_offset = 0;
00224 else {
00225 strncpy(tmpstring, memberhdr.ar_nxtmem, 12);
00226 tmpstring[12] = 0; next_offset = atol(tmpstring);
00227 if (next_offset % 2) next_offset++;
00228 }
00229
00230 return 0;
00231 }
00232
00233
00234 int xcoffArchive_64::read_mbrhdr()
00235 {
00236 char tmpstring[21];
00237
00238 if (next_offset == 0) return -1;
00239
00240 if (!fo_->set(next_offset))
00241 return -1;
00242
00243 if (!fo_->read(&memberhdr, sizeof(struct ar_hdr_big) - 2))
00244 return -1;
00245
00246 strncpy(tmpstring, memberhdr.ar_namlen, 4);
00247 tmpstring[4] = 0; member_len = atol(tmpstring);
00248 if (member_name) free(member_name);
00249 member_name = (char *)malloc(member_len+1);
00250
00251 if (!fo_->read(member_name, member_len))
00252 return -1;
00253
00254 member_name[member_len] = 0;
00255
00256
00257 aout_offset = next_offset + sizeof(struct ar_hdr_big) + member_len;
00258 if (aout_offset % 2) aout_offset += 1;
00259
00260
00261 if (next_offset == last_offset)
00262 next_offset = 0;
00263 else {
00264 strncpy(tmpstring, memberhdr.ar_nxtmem, 20);
00265 tmpstring[20] = 0; next_offset = atol(tmpstring);
00266 if (next_offset % 2) next_offset++;
00267 }
00268
00269 return 0;
00270 }
00271
00272
00273
00274 std::vector<fileOpener *> fileOpener::openedFiles;
00275
00276 fileOpener *fileOpener::openFile(void *ptr, unsigned size)
00277 {
00278
00279
00280
00281
00282
00283 for (unsigned i = 0; i < openedFiles.size(); i++)
00284 {
00285 if ((openedFiles[i]->mem_image() == ptr) && (openedFiles[i]->size() == size)){
00286 openedFiles[i]->refcount_++;
00287 return openedFiles[i];
00288 }
00289 }
00290
00291
00292 fileOpener *newFO = new fileOpener(ptr,size);
00293 assert(newFO);
00294
00295 openedFiles.push_back(newFO);
00296
00297 return newFO;
00298 }
00299
00300 void fileOpener::closeFile()
00301 {
00302 refcount_--;
00303
00304 if (refcount_ > 0) return;
00305
00306
00307 std::vector<fileOpener *>::iterator iter = openedFiles.begin();
00308 for (; iter!=openedFiles.end(); iter++)
00309 {
00310 if (*iter == this)
00311 openedFiles.erase(iter);
00312 }
00313
00314
00315
00316
00317
00318
00319 if (file()!="")
00320 {
00321 ::munmap(mmapStart_, size_);
00322
00323 ::close(fd_);
00324 }
00325 mmapStart_ = 0;
00326 fd_ = 0;
00327 size_ = 0;
00328
00329 delete this;
00330 }
00331
00332 fileOpener::~fileOpener() {
00333
00334 assert(fd_ == 0);
00335 assert(mmapStart_ == 0);
00336 assert(size_ == 0);
00337 }
00338
00339 bool fileOpener::set(unsigned addr)
00340 {
00341
00342 assert(size_);
00343 assert(mmapStart_);
00344
00345 if (addr >= size_) {
00346 fprintf(stderr, "%s[%d]: Warning: attempting to set offset to address %d (0x%x) greater than size %d (0x%x)\n", FILE__, __LINE__,
00347 addr, addr,
00348 size_, size_);
00349 return false;
00350 }
00351 offset_ = addr;
00352 return true;
00353 }
00354
00355 bool fileOpener::read(void *buf, unsigned size)
00356 {
00357
00358 assert(size_);
00359 assert(mmapStart_);
00360
00361 if ((offset_ + size) >= size_)
00362 return false;
00363
00364 memcpy(buf, ptr(), size);
00365
00366 offset_ += size;
00367 return true;
00368 }
00369
00370 bool fileOpener::seek(int offset) {
00371 if ((((int) offset_ + offset) < 0) ||
00372 ((offset_ + offset) >= size_))
00373 return false;
00374 offset_ += offset;
00375 return true;
00376 }
00377
00378 void *fileOpener::ptr() const {
00379
00380 char *tmpPtr = (char *)mmapStart_ + offset_;
00381 return (void *)tmpPtr;
00382 }
00383
00384 void *fileOpener::getPtrAtOffset(unsigned offset) const
00385 {
00386 char *tmpPtr = (char *)mmapStart_ + offset;
00387 return (void *)tmpPtr;
00388 }
00389
00390 Region::perm_t getRegionPerms(unsigned flags){
00391 if(flags & STYP_TEXT)
00392 return Region::RP_RX;
00393 else if(flags & STYP_DATA)
00394 return Region::RP_RW;
00395 else if(flags & STYP_DATA)
00396 return Region::RP_RW;
00397 else if(flags & STYP_DATA)
00398 return Region::RP_RW;
00399 else
00400 return Region::RP_R;
00401 }
00402
00403 Region::RegionType getRegionType(unsigned flags){
00404 if(flags & STYP_TEXT)
00405 return Region::RT_TEXT;
00406 else if(flags & STYP_DATA)
00407 return Region::RT_DATA;
00408 else if(flags & STYP_DATA)
00409 return Region::RT_BSS;
00410 else if(flags & STYP_DATA)
00411 return Region::RT_DATA;
00412 else if(flags & STYP_DEBUG)
00413 return Region::RT_SYMTAB;
00414 else
00415 return Region::RT_OTHER;
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 #define PARSE_AOUT_DIE(errType, errCode) { \
00432 fprintf(stderr,"warning:parsing a.out file %s(%s): %s \n", \
00433 mf->filename().c_str(), member_.c_str(), errType); \
00434 err_func_(errType); \
00435 return; \
00436 }
00437
00438
00439
00440
00441
00442
00443 #define SCNH_NAME(i) (char *)(scnh_base + scn_size * (i) + s_name_off)
00444 #define SCNH_PADDR(i) ((*(uint64_t *)(scnh_base + scn_size * (i) + s_paddr_off)) >> word_shift)
00445 #define SCNH_VADDR(i) ((*(uint64_t *)(scnh_base + scn_size * (i) + s_vaddr_off)) >> word_shift)
00446 #define SCNH_SIZE(i) ((*(uint64_t *)(scnh_base + scn_size * (i) + s_size_off)) >> word_shift)
00447 #define SCNH_SCNPTR(i) ((*(uint64_t *)(scnh_base + scn_size * (i) + s_scnptr_off)) >> word_shift)
00448 #define SCNH_RELPTR(i) ((*(uint64_t *)(scnh_base + scn_size * (i) + s_relptr_off)) >> word_shift)
00449 #define SCNH_LNNOPTR(i) ((*(uint64_t *)(scnh_base + scn_size * (i) + s_lnnoptr_off)) >> word_shift)
00450 #define SCNH_EXCEPTPTR(i) ((*(uint64_t *)(scnh_base + scn_size * (i) + s_exceptptr_off)) >> word_shift)
00451 #define SCNH_NRELOC(i) ((*(uint32_t *)(scnh_base + scn_size * (i) + s_nreloc_off)) >> half_shift)
00452 #define SCNH_NLNNO(i) ((*(uint32_t *)(scnh_base + scn_size * (i) + s_nlnno_off)) >> half_shift)
00453 #define SCNH_FLAGS(i) (*(uint32_t *)(scnh_base + scn_size * (i) + s_flags_off))
00454
00455
00456
00457
00458
00459
00460
00461 bool Object::fillExceptionTable(struct exceptab *etab, unsigned int etab_size, bool is64,
00462 struct syment *symbols)
00463
00464 {
00465
00466
00467
00468 if (!etab)
00469 {
00470 fprintf(stderr, "%s[%d]: FIXME!\n", FILE__, __LINE__);
00471 return false;
00472 }
00473
00474 for (unsigned int i = 0; i < etab_size; ++i)
00475 {
00476 struct exceptab *tabentry = ((struct exceptab *)etab) + i;
00477 if (!tabentry)
00478 {
00479 fprintf(stderr, "%s[%d]: bad table entry!\n", FILE__, __LINE__);
00480 continue;
00481 }
00482
00483
00484 if (is64)
00485 {
00486
00487 char reason = tabentry->_u._s64._reason64;
00488 if (reason == 0)
00489 {
00490
00491
00492
00493
00494
00495
00496
00497 }
00498 else
00499 {
00500
00501 }
00502
00503 }
00504 else
00505 {
00506
00507 char reason = tabentry->_u._s32._reason32;
00508 if (reason == 0)
00509 {
00510
00511
00512
00513
00514
00515
00516
00517 }
00518 else
00519 {
00520
00521 }
00522 }
00523 }
00524 return true;
00525 }
00526
00527 void Object::parse_aout(int offset, bool , bool alloc_syms)
00528 {
00529
00530
00531 long i,j;
00532 std::string name;
00533 unsigned long value;
00534 unsigned secno;
00535 unsigned textSecNo = 0, dataSecNo = 0, loaderSecNo = 0, exceptSecNo = 0;
00536 union auxent *aux = NULL;
00537 struct filehdr hdr;
00538 struct aouthdr aout;
00539 struct syment *sym = NULL;
00540 union auxent *csect = NULL;
00541 Symbol::SymbolType type;
00542 stringPool = NULL;
00543 bool foundDebug = false;
00544 bool foundLoader = false;
00545 bool foundData = false;
00546 bool foundText = false;
00547
00548 unsigned exceptab_size_ = 0;
00549 #if 0
00550 struct exceptab * exceptab_ = NULL;
00551 #endif
00552
00553 stabs_ = NULL;
00554 nstabs_ = 0;
00555 stringpool_ = NULL;
00556 stabstr_ = NULL;
00557 linesptr_ = NULL;
00558 nlines_ = 0;
00559 linesfdptr_ = 0;
00560
00561 struct syment *symbols = NULL;
00562 unsigned char *scnh_base = NULL;
00563 Symbol::SymbolLinkage linkage = Symbol::SL_UNKNOWN;
00564 Symbol::SymbolVisibility visibility = Symbol::SV_DEFAULT;
00565 unsigned toc_offset = 0;
00566 std::string modName;
00567 baseAddress_ = (Offset)fo_->getPtrAtOffset(offset);
00568
00569 int linesfdptr=0;
00570 struct lineno* lines=NULL;
00571
00572
00573 if (!fo_->set(offset))
00574 PARSE_AOUT_DIE("Seeking to correct offset", 49);
00575
00576
00577
00578
00579 uint16_t magic;
00580 if (!fo_->read(&magic, 2))
00581 PARSE_AOUT_DIE("Reading magic number", 49);
00582
00583
00584 bool is64 = false;
00585 if (magic == 0x1EF ||
00586 magic == 0x1F7 ) {
00587 is64 = true;
00588 addressWidth_nbytes = 8;
00589
00590 } else if (magic != 0x1DF ) {
00591 PARSE_AOUT_DIE("possible problem, invalid magic number", 49);
00592
00593
00594 }
00595 is64_ = is64;
00596
00597
00598
00599
00600 uint64_t scn_size;
00601 uint64_t s_name_off, s_paddr_off, s_vaddr_off, s_size_off, s_scnptr_off;
00602 uint64_t s_relptr_off, s_lnnoptr_off;
00603 uint64_t s_nreloc_off, s_nlnno_off, s_flags_off;
00604 uint64_t word_shift, half_shift;
00605
00606 if (is64) {
00607 scn_size = SCNHSZ_64;
00608 s_name_off = offsetof(struct scnhdr, s_name);
00609 s_paddr_off = offsetof(struct scnhdr, s_paddr64);
00610 s_vaddr_off = offsetof(struct scnhdr, s_vaddr64);
00611 s_size_off = offsetof(struct scnhdr, s_size64);
00612 s_scnptr_off = offsetof(struct scnhdr, s_scnptr64);
00613 s_relptr_off = offsetof(struct scnhdr, s_relptr64);
00614 s_lnnoptr_off = offsetof(struct scnhdr, s_lnnoptr64);
00615 s_nreloc_off = offsetof(struct scnhdr, s_nreloc64);
00616 s_nlnno_off = offsetof(struct scnhdr, s_nlnno64);
00617 s_flags_off = offsetof(struct scnhdr, s_flags64);
00618 word_shift = 0;
00619 half_shift = 0;
00620
00621 } else {
00622 scn_size = SCNHSZ_32;
00623 s_name_off = offsetof(struct scnhdr, s_name);
00624 s_paddr_off = offsetof(struct scnhdr, s_paddr32);
00625 s_vaddr_off = offsetof(struct scnhdr, s_vaddr32);
00626 s_size_off = offsetof(struct scnhdr, s_size32);
00627 s_scnptr_off = offsetof(struct scnhdr, s_scnptr32);
00628 s_relptr_off = offsetof(struct scnhdr, s_relptr32);
00629 s_lnnoptr_off = offsetof(struct scnhdr, s_lnnoptr32);
00630 s_nreloc_off = offsetof(struct scnhdr, s_nreloc32);
00631 s_nlnno_off = offsetof(struct scnhdr, s_nlnno32);
00632 s_flags_off = offsetof(struct scnhdr, s_flags32);
00633 word_shift = 32;
00634 half_shift = 16;
00635 }
00636
00637
00638 if (!fo_->set(offset))
00639 PARSE_AOUT_DIE("Seeking to correct offset", 49);
00640
00641
00642
00643
00644 if (!fo_->read(&hdr, (is64 ? FILHSZ_64 : FILHSZ_32)))
00645 PARSE_AOUT_DIE("Reading file header", 49);
00646
00647 uint64_t symptr, nsyms;
00648 if (is64) {
00649 symptr = hdr.f_symptr64;
00650 nsyms = hdr.f_nsyms64;
00651
00652 } else {
00653 symptr = hdr.f_symptr32;
00654 nsyms = hdr.f_nsyms32;
00655 }
00656 is_aout_ = !(hdr.f_flags & F_SHROBJ);
00657
00658 #if 0
00659 if (hdr.f_opthdr == 0)
00660 cout << "no aout header" << endl;
00661 if (hdr.f_opthdr == _AOUTHSZ_SHORT)
00662 cout << "short header" << endl;
00663 #endif
00664
00665
00666
00667
00668 if (!fo_->read(&aout, hdr.f_opthdr))
00669 PARSE_AOUT_DIE("Reading a.out header", 49);
00670
00671 uint64_t text_start, tsize;
00672 uint64_t data_start, dsize;
00673 uint64_t entry;
00674
00675 if (is64) {
00676 text_start = aout.o_text_start64;
00677 data_start = aout.o_data_start64;
00678 tsize = aout.o_tsize64;
00679 dsize = aout.o_dsize64;
00680 entry = aout.o_entry64;
00681
00682 } else {
00683 text_start = aout.o_text_start32;
00684 data_start = aout.o_data_start32;
00685 tsize = aout.o_tsize32;
00686 dsize = aout.o_dsize32;
00687 entry = aout.o_entry32;
00688 }
00689
00690 scnh_base = (unsigned char *)fo_->ptr();
00691 if (!scnh_base)
00692 PARSE_AOUT_DIE("Reading section headers", 49);
00693
00694 fo_->seek((is64 ? SCNHSZ_64 : SCNHSZ_32) * hdr.f_nscns);
00695
00696
00697 if ( symptr ) {
00698 fo_->set(offset + symptr);
00699 symbols = (struct syment *) fo_->ptr();
00700 fo_->seek(nsyms * SYMESZ);
00701
00702 if (!symbols)
00703 PARSE_AOUT_DIE("Reading symbol table", 49);
00704 }
00705
00706
00707 if (hdr.f_opthdr == (is64 ? _AOUTHSZ_EXEC_64 : _AOUTHSZ_EXEC_32))
00708 {
00709
00710 if ( text_start != SCNH_PADDR(aout.o_sntext-1))
00711 PARSE_AOUT_DIE("Checking text address", 49);
00712 if ( data_start != SCNH_PADDR(aout.o_sndata-1))
00713 PARSE_AOUT_DIE("Checking data address", 49);
00714 if ( tsize != SCNH_SIZE(aout.o_sntext-1))
00715 PARSE_AOUT_DIE("Checking text size", 49);
00716 if ( dsize != SCNH_SIZE(aout.o_sndata-1))
00717 PARSE_AOUT_DIE("Checking data size", 49);
00718 }
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 if (hdr.f_opthdr != 0)
00731 entryAddress_ = entry;
00732
00733
00734
00735
00736 if ( nsyms )
00737 {
00738
00739 if (!fo_->set(offset + symptr + (nsyms*SYMESZ)))
00740 PARSE_AOUT_DIE("Could not seek to string pool", 49);
00741
00742 stringPool = (char *)fo_->ptr();
00743 if (!stringPool)
00744 PARSE_AOUT_DIE("Getting pointer to string pool", 49);
00745
00746
00747 Offset stringPoolSize;
00748 fo_->read(&stringPoolSize, 4);
00749 }
00750
00751
00752 nlines_ = 0;
00753 no_of_sections_ = hdr.f_nscns;
00754 foundLoader = false;
00755 foundData = false;
00756
00757 for (i=0; i < hdr.f_nscns; i++)
00758 {
00759 if(SCNH_FLAGS(i) & STYP_DATA)
00760 {
00761 dataSecNo = i;
00762 foundData = true;
00763 }
00764 else if(SCNH_FLAGS(i) & STYP_LOADER)
00765 {
00766 loaderSecNo = i;
00767 foundLoader = true;
00768 }
00769 if (SCNH_FLAGS(i) & STYP_TEXT) {
00770 textSecNo = i;
00771 foundText = true;
00772 nlines_ = SCNH_NLNNO(i);
00773
00774
00775 if (!is64 && nlines_ == 65535)
00776 for (j=0; j < hdr.f_nscns; j++)
00777 if ((SCNH_FLAGS(j) & STYP_OVRFLO) &&
00778 ((long) SCNH_NLNNO(j) == (i+1))) {
00779 nlines_ = (unsigned int)(SCNH_VADDR(j));
00780 break;
00781 }
00782
00783
00784 if (nlines_ == 0)
00785 continue;
00786
00787
00788 if (!fo_->set(offset + SCNH_LNNOPTR(i)))
00789 PARSE_AOUT_DIE("Seeking to line information table", 49);
00790 lines = (struct lineno *)fo_->ptr();
00791 if (!lines)
00792 PARSE_AOUT_DIE("Reading line information table", 49);
00793 fo_->seek(nlines_ * (is64 ? LINESZ_64 : LINESZ_32));
00794
00795 linesfdptr = offset + SCNH_LNNOPTR(i);
00796
00797 }
00798 if (SCNH_FLAGS(i) & STYP_BSS) {
00799 bss_size_ = SCNH_SIZE(i);
00800 }
00801 if (SCNH_FLAGS(i) & STYP_EXCEPT) {
00802 exceptSecNo = i;
00803 exceptab_size_ = SCNH_SIZE(i);
00804 #if 0
00805 if (!fo_->set(offset + SCNH_SCNPTR(i)))
00806 PARSE_AOUT_DIE("Seeking to exception table", 49);
00807 exceptab_ = (struct exceptab *)fo_->ptr();
00808 if (!exceptab_)
00809 PARSE_AOUT_DIE("Reading line information table", 49);
00810 if (!fillExceptionTable(exceptab_, exceptab_size_, is64, symbols))
00811 {
00812 fprintf(stderr, "%s[%d]: WARNING: failed to read exceptions\n", FILE__, __LINE__);
00813 }
00814 #endif
00815 }
00816 }
00817
00818 if (alloc_syms)
00819 for (i=0; i < hdr.f_nscns; i++) {
00820
00821 Region::RegionType regionType = getRegionType(SCNH_FLAGS(i));
00822 bool isLoadable = regionType == Region::RT_TEXT ||
00823 regionType == Region::RT_DATA;
00824 regions_.push_back(new Region(i, SCNH_NAME(i), SCNH_PADDR(i), SCNH_SIZE(i), SCNH_PADDR(i), SCNH_SIZE(i), (char *)fo_->getPtrAtOffset(offset+SCNH_SCNPTR(i)), getRegionPerms(SCNH_FLAGS(i)), regionType, isLoadable));
00825
00826
00827
00828 }
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845 Offset fileTextOffset;
00846 Offset fileDataOffset;
00847
00848 fileDataOffset = foundData ? roundup4(SCNH_SCNPTR(dataSecNo)) : (Offset) -1;
00849 fileTextOffset = foundText ? roundup4(SCNH_SCNPTR(textSecNo)) : (Offset) -1;
00850 code_off_ = foundText ? roundup4(SCNH_PADDR(textSecNo)) : (Offset) -1;
00851 data_off_ = foundData ? roundup4(SCNH_PADDR(dataSecNo)) : (Offset) -1;
00852 code_len_ = foundText ? SCNH_SIZE(textSecNo) : 0;
00853 data_len_ = foundData ? SCNH_SIZE(dataSecNo) : 0;
00854 text_reloc_ = fileTextOffset;
00855 data_reloc_ = fileDataOffset;
00856
00857 if (foundText)
00858 {
00859 if (!fo_->set(fileTextOffset + offset))
00860 PARSE_AOUT_DIE("Seeking to start of text segment", 49);
00861 code_ptr_ = (char *)fo_->ptr();
00862 if (!code_ptr_)
00863 PARSE_AOUT_DIE("Reading text segment", 49);
00864 }
00865 else
00866 code_ptr_ = NULL;
00867
00868 if(foundData)
00869 {
00870 if (!fo_->set(fileDataOffset + offset))
00871 PARSE_AOUT_DIE("Seeking to start of data segment", 49);
00872 data_ptr_ = (char *)fo_->ptr();
00873 if (!data_ptr_)
00874 PARSE_AOUT_DIE("Reading data segment", 49);
00875 }
00876 else
00877 data_ptr_ = NULL;
00878
00879 if(foundLoader)
00880 {
00881
00882 loader_off_ = SCNH_SCNPTR(loaderSecNo);
00883
00884 loadAddress_ = loader_off_;
00885 loader_len_ = SCNH_SIZE(loaderSecNo);
00886
00887 }
00888
00889
00890 object_printf("Text offset in file: 0x%x (0x%x + 0x%x), virtual address 0x%x, size %d (0x%x) bytes\n",
00891 fileTextOffset + offset, fileTextOffset, offset, code_off_, code_len_, code_len_);
00892 object_printf("Data offset in file: 0x%x (0x%x + 0x%x), virtual address 0x%x, size %d (0x%x) bytes\n",
00893 fileDataOffset + offset, fileDataOffset, offset, data_off_, data_len_, data_len_);
00894
00895 foundDebug = false;
00896
00897
00898 for (i=0; i < hdr.f_nscns; i++)
00899 {
00900 if (SCNH_FLAGS(i) & STYP_DEBUG)
00901 {
00902 foundDebug = true;
00903 break;
00904 }
00905 }
00906 if ( foundDebug )
00907 {
00908 stabs_ = (void *) symbols;
00909 nstabs_ = nsyms;
00910 stringpool_ = (void *) stringPool;
00911 if( nsyms ) {
00912 if (!fo_->set(SCNH_SCNPTR(i) + offset))
00913 PARSE_AOUT_DIE("Seeking to initialized debug section", 49);
00914
00915 stabstr_ = fo_->ptr();
00916 if (!stabstr_)
00917 PARSE_AOUT_DIE("Reading initialized debug section", 49);
00918 }
00919
00920 linesptr_ = (void *) lines;
00921 linesfdptr_ = linesfdptr + offset;
00922 }
00923 else
00924 {
00925
00926 stabs_ = NULL;
00927 nstabs_ = 0;
00928 stringpool_ = NULL;
00929 stabstr_ = NULL;
00930 linesptr_ = NULL;
00931 nlines_ = 0;
00932 linesfdptr_ = 0;
00933 }
00934
00935 no_of_symbols_ = nsyms;
00936
00937 if (alloc_syms) {
00938 object_printf("%d symbols present in file\n", nsyms);
00939 for (i=0; i < (signed)nsyms; i++)
00940 {
00941
00942
00943 sym = (struct syment *) (((char *)symbols) + i * SYMESZ);
00944 unsigned long sym_value = (is64 ? sym->n_value64 : sym->n_value32);
00945
00946 if (sym->n_sclass & DBXMASK) {
00947 object_printf("Skipping DBXMASK symbol %s\n", name.c_str());
00948 continue;
00949 }
00950
00951 secno = sym->n_scnum;
00952 if ((C_WEAKEXT && (sym->n_sclass == C_WEAKEXT)) ||
00953 (sym->n_sclass == C_HIDEXT) ||
00954 (sym->n_sclass == C_EXT) ||
00955 (sym->n_sclass == C_FILE)) {
00956
00957 if (is64) {
00958 name = std::string( &stringPool[ sym->n_offset64 ] );
00959 } else if (!sym->n_zeroes32) {
00960 name = std::string( &stringPool[ sym->n_offset32 ] );
00961 } else {
00962 char tempName[9];
00963 memset(tempName, 0, 9);
00964 strncpy(tempName, sym->n_name32, 8);
00965 name = std::string(tempName);
00966 }
00967 }
00968
00969 unsigned long size = 0;
00970 if ((C_WEAKEXT && (sym->n_sclass == C_WEAKEXT)) ||
00971 (sym->n_sclass == C_HIDEXT) ||
00972 (sym->n_sclass == C_EXT)) {
00973 if (sym->n_sclass == C_HIDEXT) {
00974 linkage = Symbol::SL_LOCAL;
00975 } else {
00976 linkage = Symbol::SL_GLOBAL;
00977 }
00978
00979 if (sym->n_scnum == aout.o_sntext) {
00980 type = Symbol::ST_FUNCTION;
00981 value = sym_value;
00982
00983
00984
00985
00986 } else {
00987
00988 csect = (union auxent *)
00989 ((char *) sym + sym->n_numaux * SYMESZ);
00990
00991
00992 unsigned smtyp = csect->x_csect.x_smtyp & 0x3;
00993 if (smtyp == XTY_SD || smtyp == XTY_CM) {
00994 size = csect->x_csect.x_scnlen32;
00995 if (is64) size &= csect->x_csect.x_scnlen_hi64 * 0x10000;
00996 }
00997
00998 if (csect->x_csect.x_smclas == XMC_TC0)
00999 {
01000
01001
01002 toc_offset = sym_value;
01003 object_printf("Found TOC offset: 0x%lx\n", toc_offset);
01004 continue;
01005 }
01006
01007 if ((csect->x_csect.x_smclas == XMC_TC) ||
01008 (csect->x_csect.x_smclas == XMC_DS)) {
01009
01010
01011 object_printf("TOC entry (%s/%d), ignoring (%s)\n", name.c_str(),sym_value,
01012 (csect->x_csect.x_smclas == XMC_TC) ? "TC" : "DS");
01013 continue;
01014 }
01015 type = Symbol::ST_OBJECT;
01016
01017 if (foundData && sym_value < SCNH_PADDR(dataSecNo)) {
01018
01019 object_printf("Skipping odd case of data symbol not in data section (%s)\n", name.c_str());
01020 continue;
01021 }
01022
01023 value = sym_value;
01024
01025
01026
01027
01028
01029 }
01030
01031
01032 if (name == ".text") {
01033 object_printf("Skipping .text symbol\n");
01034 continue;
01035 }
01036
01037 if (name[0] == '.' ) {
01038
01039 name = std::string(name.c_str()+1);
01040 }
01041 else if (type == Symbol::ST_FUNCTION) {
01042
01043
01044 object_printf("Skipping text symbol without leading .\n");
01045 continue;
01046 }
01047
01048 if (type == Symbol::ST_FUNCTION) {
01049
01050
01051 size = 0;
01052 Word *inst = (Word *)((char *)code_ptr_ + value - code_off_);
01053
01054
01055 instructUnion instr;
01056 instr.raw = inst[0];
01057 if ((instr.iform.op == Bop) &&
01058 (instr.iform.lk == 0))
01059 size = 4;
01060 else {
01061 while (inst[size] != 0) size++;
01062 size *= sizeof(Word);
01063 }
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082 if (size == 0x18) {
01083
01084
01085 Word *inst = (Word *)((char *)code_ptr_ + value - code_off_);
01086 instructUnion lr12, lr0, bctr;
01087 lr12.raw = inst[0];
01088 lr0.raw = inst[2];
01089 bctr.raw = inst[5];
01090
01091 if ((lr12.dform.op == Lop) && (lr12.dform.rt == 12) && (lr12.dform.ra == 2) &&
01092 (lr0.dform.op == Lop) && (lr0.dform.rt == 0) &&
01093 (lr0.dform.ra == 1 || lr0.dform.ra == 12) &&
01094 (bctr.xlform.op == BCLRop) && (bctr.xlform.xo == BCCTRxop))
01095 {
01096 int sourceSize = strlen(name.c_str());
01097 char tempLinkName[sourceSize + 9];
01098 memset(tempLinkName, 0, sourceSize+8);
01099 strncpy(tempLinkName, name.c_str(),sourceSize);
01100 strcat(tempLinkName,"_linkage");
01101 name = std::string(tempLinkName);
01102 }
01103 }
01104 }
01105
01106 Region *sec;
01107 if(secno >= 1 && secno <= regions_.size())
01108 sec = regions_[secno-1];
01109 else
01110 sec = NULL;
01111
01112
01113
01114
01115 Symbol *sym = new Symbol(name,
01116 type,
01117 linkage,
01118 Symbol::SV_DEFAULT,
01119 value,
01120 NULL,
01121 sec,
01122 size);
01123
01124 symbols_[name].push_back(sym);
01125 symsByOffset_[value].push_back(sym);
01126 symsToModules_[sym] = modName;
01127
01128 if (symbols_.find(modName)!=symbols_.end()) {
01129
01130
01131
01132 std::vector< Symbol *> & mod_symbols = symbols_[modName];
01133
01134 Symbol *mod_symbol = mod_symbols[ 0 ];
01135
01136 for (unsigned i = 0; i < mod_symbols.size(); i++) {
01137 if (mod_symbols[i]->getType() == Symbol::ST_MODULE) {
01138 mod_symbol->offset_ = value;
01139 }
01140 }
01141 }
01142 } else if (sym->n_sclass == C_FILE) {
01143 if (!strcmp(name.c_str(), ".file")) {
01144 int j;
01145
01146 for (j=1; j <= sym->n_numaux; j++) {
01147 aux = (union auxent *) ((char *) sym + j * SYMESZ);
01148 if (aux->x_file._x.x_ftype == XFT_FN) {
01149
01150 if (!aux->x_file._x.x_zeroes) {
01151 name = std::string(&stringPool[aux->x_file._x.x_offset]);
01152 } else {
01153
01154 char tempName[15];
01155 memset(tempName, 0, 15);
01156 strncpy(tempName, aux->x_file.x_fname, 14);
01157 name = std::string(tempName);
01158 }
01159 }
01160 }
01161 }
01162
01163
01164
01165
01166
01167
01168
01169 std::string::size_type len = mf->pathname().length();
01170 if (((len>2)&&(mf->pathname().substr(len-2,2)==".a")) ||
01171 ((len>3)&&(mf->pathname().substr(len-3,3)==".so")) ||
01172 ((len>5)&&(mf->pathname().substr(len-5,5)==".so.1")))
01173 modName = mf->pathname();
01174 else if (name == "glink.s")
01175 modName = std::string("Global_Linkage");
01176 else {
01177 modName = name;
01178 }
01179 Symbol *modSym = new Symbol(modName,
01180 Symbol::ST_MODULE,
01181 linkage,
01182 visibility,
01183 UINT_MAX);
01184
01185
01186 if ( symbols_[modName].size() == 0 ) {
01187 symbols_[modName].push_back( modSym );
01188 } else {
01189
01190
01191 delete (symbols_[modName][0]);
01192 symbols_[modName][0] = modSym;
01193 }
01194
01195 continue;
01196 }
01197 }
01198 }
01199
01200 toc_offset_ = toc_offset;
01201
01202 code_vldS_ = code_off_;
01203 code_vldE_ = code_off_ + code_len_;
01204 data_vldS_ = data_off_;
01205 data_vldE_ = data_off_ + data_len_;
01206
01207 return;
01208 }
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228 #define PARSE_AR_DIE(errType, errCode) { \
01229 sprintf(errorLine, "Error parsing archive file %s: %s\n", \
01230 mf->pathname().c_str(), errType); \
01231 err_func_(errType); \
01232 return; \
01233 }
01234
01235 void Object::load_archive(bool is_aout, bool alloc_syms)
01236 {
01237 xcoffArchive *archive;
01238
01239
01240
01241 if (!fo_->set(0))
01242 PARSE_AR_DIE("Seeking to file start", 49);
01243
01244 char magic_number[SAIAMAG];
01245 if (!fo_->read(magic_number, SAIAMAG))
01246 PARSE_AR_DIE("Reading magic number", 49);
01247
01248 if (!strncmp(magic_number, AIAMAG, SAIAMAG))
01249 archive = (xcoffArchive *) new xcoffArchive_32(fo_);
01250 else if (!strncmp(magic_number, AIAMAGBIG, SAIAMAG))
01251 archive = (xcoffArchive *) new xcoffArchive_64(fo_);
01252 else
01253 PARSE_AR_DIE("Unknown magic number", 49);
01254
01255 if (archive->read_arhdr())
01256 PARSE_AR_DIE("Reading file header", 49);
01257
01258 bool found = false;
01259
01260 while (archive->next_offset != 0)
01261 {
01262 if (archive->read_mbrhdr())
01263 PARSE_AR_DIE("Reading member header", 49);
01264
01265 if (!strncmp(archive->member_name,
01266 member_.c_str(),
01267 archive->member_len - 1))
01268 {
01269 found = true;
01270 break;
01271 }
01272 }
01273 if (found)
01274 {
01275
01276
01277 parse_aout(archive->aout_offset, is_aout, alloc_syms);
01278 }
01279 else
01280 {
01281
01282
01283 }
01284 }
01285
01286
01287
01288
01289
01290
01291 void Object::load_object(bool alloc_syms)
01292 {
01293
01294
01295 assert(fo_);
01296
01297 unsigned char magic_number[2];
01298 unsigned short f_flags;
01299
01300 if (!fo_->set(0)) {
01301 sprintf(errorLine, "Error reading file %s\n",
01302 mf->pathname().c_str());
01303 err_func_(errorLine);
01304
01305
01306 return;
01307 }
01308
01309 if (!fo_->read((void *)magic_number, 2)) {
01310 sprintf(errorLine, "Error reading file %s\n",
01311 mf->pathname().c_str());
01312 err_func_(errorLine);
01313
01314
01315 return;
01316 }
01317
01318 if (!fo_->set(18)){
01319 sprintf(errorLine, "Error moving to the offset 18 file %s\n",
01320 mf->pathname().c_str());
01321 err_func_(errorLine);
01322
01323
01324 }
01325
01326 if (!fo_->read((void *)(&f_flags), 2)) {
01327 sprintf(errorLine, "Error reading file %s\n",
01328 mf->pathname().c_str());
01329 err_func_(errorLine);
01330
01331
01332 return;
01333 }
01334
01335 if (magic_number[0] == 0x01) {
01336 if (magic_number[1] == 0xdf ||
01337 magic_number[1] == 0xef ||
01338 magic_number[1] == 0xf7)
01339 {
01340 parse_aout(0, is_aout_, alloc_syms);
01341 }
01342 }
01343 else if (magic_number[0] == '<')
01344 {
01345
01346
01347 is_aout_ = !(f_flags & F_SHROBJ);
01348 parse_aout(offset_, true, alloc_syms);
01349 }
01350 else {
01351 sprintf(errorLine, "Bad magic number in file %s\n",
01352 mf->pathname().c_str());
01353 err_func_(errorLine);
01354
01355
01356 }
01357 return;
01358 }
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368 Object::Object(const Object& obj) :
01369 AObject(obj)
01370 {
01371 fo_ = fileOpener::openFile((void *)obj.fo_->mem_image(), obj.fo_->size());
01372 }
01373
01374
01375 Object::Object(MappedFile *mf_, MappedFile *mfd, bool, void (*err_func)(const char *), Offset offset, bool alloc_syms) :
01376 AObject(mf_, mfd, err_func), offset_(offset)
01377 {
01378 fo_ = fileOpener::openFile((void *)mf_->base_addr(), mf_->size());
01379 fo_->set_file(mf_->filename());
01380 load_object(alloc_syms);
01381 }
01382
01383 Object::Object(MappedFile *mf_, MappedFile *mfd, std::string &member_name, Offset offset, void (*err_func)(const char *), void *) :
01384 AObject(mf_, mfd, err_func), member_(member_name), offset_(offset)
01385 {
01386 fo_ = fileOpener::openFile((void *)mf_->base_addr(), mf_->size());
01387 fo_->set_file(member_name);
01388 load_object(true);
01389 }
01390
01391 Object& Object::operator=(const Object& obj)
01392 {
01393 (void) AObject::operator=(obj);
01394 fo_ = fileOpener::openFile((void *)obj.fo_->mem_image(), obj.fo_->size());
01395 return *this;
01396 }
01397
01398
01399 void Object::get_stab_info(char *&stabstr, int &nstabs, void *&stabs, char *&stringpool) const {
01400 stabstr = (char *) stabstr_;
01401 nstabs = nstabs_;
01402 stabs = stabs_;
01403 stringpool = (char *) stringpool_;
01404 }
01405
01406
01407
01408
01409
01410
01411
01412 bool parseCompilerType(Object *objPtr)
01413 {
01414 bool is64 = (objPtr->getAddressWidth() == 8);
01415 SYMENT *syms;
01416 int stab_nsyms;
01417 char *stringPool;
01418 union auxent *aux;
01419 char *stabstr=NULL;
01420 void *syms_void = NULL;
01421
01422 objPtr->get_stab_info(stabstr, stab_nsyms, syms_void, stringPool);
01423 syms = static_cast<SYMENT *>(syms_void);
01424 for (int i=0;i<stab_nsyms;i++) {
01425 SYMENT *sym = (SYMENT *) (((char *) syms) + i * SYMESZ);
01426 char tempName[15];
01427 char *compilerName = NULL;
01428
01429 std::string name;
01430 if (sym->n_sclass == C_FILE) {
01431 if (is64) {
01432 name = std::string( &stringPool[ sym->n_offset64 ] );
01433
01434 } else if (!sym->n_zeroes32) {
01435 name = std::string( &stringPool[ sym->n_offset32 ] );
01436
01437 } else {
01438 char tempName[9];
01439 memset(tempName, 0, 9);
01440 strncpy(tempName, sym->n_name32, 8);
01441 name = std::string(tempName);
01442 }
01443 if (!strcmp(name.c_str(), ".file")) {
01444 int j;
01445
01446 for (j=1; j <= sym->n_numaux; j++) {
01447 aux = (union auxent *) ((char *) sym + j * SYMESZ);
01448 if (aux->x_file._x.x_ftype == XFT_CV) {
01449
01450 if (!aux->x_file._x.x_zeroes) {
01451 compilerName = &stringPool[aux->x_file._x.x_offset];
01452 } else {
01453
01454 memset(tempName, 0, 15);
01455 strncpy(tempName, aux->x_file.x_fname, 14);
01456 compilerName = tempName;
01457 }
01458 }
01459 }
01460
01461
01462
01463
01464 const char * const compiler_strings[] = {
01465 "IBM.*VisualAge.*C\\+\\+",
01466 "IBM.* XL .*C\\+\\+",
01467 NULL};
01468
01469 for (const char * const *cpp = compiler_strings; *cpp != NULL; cpp++) {
01470 regex_t reg;
01471 if (regcomp(®, *cpp, REG_NOSUB))
01472 break;
01473 if (!regexec(®, compilerName, 0, NULL, 0)) {
01474 regfree(®);
01475 return true;
01476 }
01477 regfree(®);
01478 }
01479 }
01480 }
01481 }
01482
01483 return false;
01484 }
01485
01486
01487 void Object::getModuleLanguageInfo(dyn_hash_map<std::string, supportedLanguages> *)
01488 {
01489 }
01490
01491 ObjectType Object::objType() const {
01492 return is_aout() ? obj_Executable : obj_SharedLib;
01493 }
01494
01495 bool Object::emitDriver(Symtab * ,
01496 string ,
01497 std::vector<Symbol *>&,
01498 unsigned )
01499 {
01500 return true;
01501 }
01502
01503 bool AObject::getSegments(vector<Segment> &) const
01504 {
01505 return true;
01506 }
01507
01508
01509 Offset trueBaseAddress = 0;
01510
01511 void Object::parseFileLineInfo(Symtab *, dyn_hash_map<std::string, LineInformation> &li)
01512 {
01513 static set<std::string> haveParsedFileMap;
01514
01515
01516
01517 if ( haveParsedFileMap.count(mf->pathname()) != 0 ) { return; }
01518
01519
01520
01521
01522
01523
01524
01525
01526 if (is_aout())
01527 trueBaseAddress = 0;
01528 else
01529 trueBaseAddress = baseAddress_;
01530
01531
01532
01533 char * stabstr = NULL;
01534 int nstabs = 0;
01535 SYMENT * syms = 0;
01536 char * stringpool = NULL;
01537 void *syms_void = NULL;
01538 get_stab_info( stabstr, nstabs, syms_void, stringpool );
01539 syms = (SYMENT *) syms_void;
01540 int nlines = 0;
01541 char * lines = NULL;
01542 unsigned long linesfdptr;
01543 get_line_info( nlines, lines, linesfdptr );
01544
01545
01546 char temporaryName[256];
01547 char * funcName = NULL;
01548 char * currentSourceFile = NULL;
01549 char * moduleName = NULL;
01550
01551
01552
01553 for ( int i = 0; i < nstabs; i++ )
01554 {
01555
01556
01557 SYMENT * sym = (SYMENT *)( (char *)syms + (i * SYMESZ) );
01558
01559
01560
01561 if (is64_)
01562 {
01563 moduleName = &stringpool[ sym->n_offset64 ];
01564 }
01565 else if (!sym->n_zeroes32)
01566 {
01567 moduleName = &stringpool[ sym->n_offset32 ];
01568 }
01569 else
01570 {
01571 memset(temporaryName, 0, 9);
01572 strncpy(temporaryName, sym->n_name32, 8);
01573 moduleName = temporaryName;
01574 }
01575
01576
01577
01578 if ( sym->n_sclass == C_FILE )
01579 {
01580
01581 if (!strcmp(moduleName, ".file"))
01582 {
01583
01584 int j;
01585
01586
01587
01588 for (j=1; j <= sym->n_numaux; j++)
01589 {
01590
01591 union auxent *aux = (union auxent *) ((char *) sym + j * SYMESZ);
01592
01593 if (aux->x_file._x.x_ftype == XFT_FN)
01594 {
01595
01596 if (!aux->x_file._x.x_zeroes)
01597 {
01598 moduleName = &stringpool[aux->x_file._x.x_offset];
01599 }
01600 else
01601 {
01602
01603 memset(temporaryName, 0, 15);
01604 strncpy(temporaryName, aux->x_file.x_fname, 14);
01605 moduleName = temporaryName;
01606 }
01607 }
01608 }
01609 }
01610
01611 currentSourceFile = strrchr( moduleName, '/' );
01612
01613 if ( currentSourceFile == NULL )
01614 {
01615 currentSourceFile = moduleName;
01616 }
01617 else
01618 {
01619 ++currentSourceFile;
01620 }
01621
01622
01623 continue;
01624 }
01625
01626
01627
01628 char * nmPtr = NULL;
01629
01630 if (!sym->n_zeroes32 && ( ( sym->n_sclass & DBXMASK ) ||
01631 ( sym->n_sclass == C_BINCL ) ||
01632 ( sym->n_sclass == C_EINCL ) ) )
01633 {
01634 long sym_offset = (is64_ ? sym->n_offset64 : sym->n_offset32);
01635
01636 if ( sym_offset < 3 )
01637 {
01638 if ( sym_offset == 2 && stabstr[ 0 ] )
01639 {
01640 nmPtr = & stabstr[ 0 ];
01641 }
01642 else
01643 {
01644 nmPtr = & stabstr[ sym_offset ];
01645 }
01646 }
01647 else if( ! stabstr[ sym_offset - 3 ] )
01648 {
01649 nmPtr = & stabstr[ sym_offset ];
01650 }
01651 else
01652 {
01653
01654 nmPtr = & stabstr[ sym_offset - 2 ];
01655 }
01656 }
01657 else if (is64_)
01658 {
01659 nmPtr = &stringpool[sym->n_offset64];
01660
01661 }
01662 else if (!sym->n_zeroes32)
01663 {
01664 nmPtr = &stringpool[sym->n_offset32];
01665 }
01666 else
01667 {
01668
01669 memset( temporaryName, 0, 9 );
01670 strncpy( temporaryName, sym->n_name32, 8 );
01671 nmPtr = temporaryName;
01672 }
01673
01674
01675
01676 if ( ( sym->n_sclass == C_BINCL ) ||
01677 ( sym->n_sclass == C_EINCL ) ||
01678 ( sym->n_sclass == C_FUN ) )
01679 {
01680
01681 if ( funcName )
01682 {
01683 free( funcName );
01684 funcName = NULL;
01685 }
01686
01687 funcName = strdup( nmPtr );
01688
01689 std::string pdCSF( currentSourceFile );
01690 parseLineInformation(li, & pdCSF, funcName, (SYMENT *)sym, linesfdptr, lines, nlines );
01691 }
01692 }
01693
01694 if ( funcName != NULL )
01695 {
01696 free( funcName );
01697 }
01698
01699 haveParsedFileMap.insert(mf->pathname());
01700 }
01701
01702 void Object::parseLineInformation(dyn_hash_map<std::string, LineInformation> &lineInfo_,
01703 std::string * currentSourceFile,
01704 char * symbolName,
01705 SYMENT * sym,
01706 Offset linesfdptr,
01707 char * lines,
01708 int nlines )
01709 {
01710 union auxent * aux;
01711 std::vector<IncludeFileInfo> includeFiles;
01712 unsigned long value = (is64_ ? sym->n_value64 : sym->n_value32);
01713 unsigned long LINESZ = (is64_ ? LINESZ_64 : LINESZ_32);
01714
01715
01716
01717
01718
01719 if ( sym->n_sclass == C_BINCL )
01720 {
01721 includeFiles.push_back( IncludeFileInfo( (value - linesfdptr)/LINESZ, symbolName ) );
01722 }
01723
01724
01725
01726
01727 else if (sym->n_sclass == C_EINCL)
01728 {
01729 if (includeFiles.size() > 0)
01730 {
01731 includeFiles[includeFiles.size()-1].end = (value - linesfdptr)/LINESZ;
01732 }
01733 }
01734 else if ( sym->n_sclass == C_FUN )
01735 {
01736
01737
01738
01739
01740
01741
01742 int initialLine = 0;
01743 int initialLineIndex = 0;
01744 Offset funcStartAddress = 0;
01745 Offset funcEndAddress = 0;
01746
01747 for (int j = -1; ; --j)
01748 {
01749 SYMENT * extSym = (SYMENT *)( ((char *)sym) + (j * SYMESZ) );
01750
01751 if ( extSym->n_sclass == C_EXT || extSym->n_sclass == C_HIDEXT )
01752 {
01753 aux = (union auxent *)( ((char *)extSym) + SYMESZ );
01754
01755 initialLineIndex = (is64_ ? aux->x_fcn64.x_lnnoptr
01756 : aux->x_sym32.x_fcnary.x_fcn.x_lnnoptr);
01757 initialLineIndex = (initialLineIndex - linesfdptr )/LINESZ;
01758
01759 funcStartAddress = (is64_ ? extSym->n_value64 : extSym->n_value32);
01760 break;
01761 }
01762
01763 }
01764
01765
01766
01767 SYMENT * bfSym = (SYMENT *)( ((char *)sym) + SYMESZ );
01768
01769 if ( bfSym->n_sclass != C_FCN )
01770 {
01771
01772 return;
01773 }
01774
01775 SYMENT * efSym = (SYMENT *)( ((char *)bfSym) + (2 * SYMESZ) );
01776
01777 while (efSym->n_sclass != C_FCN)
01778 {
01779 efSym = (SYMENT *) ( ((Offset)efSym) + SYMESZ );
01780 }
01781
01782 funcEndAddress = (is64_ ? efSym->n_value64 : efSym->n_value32);
01783
01784 aux = (union auxent *)( ((char *)bfSym) + SYMESZ );
01785
01786 initialLine = (is64_ ? aux->x_sym64.x_misc.x_lnsz.x_lnno
01787 : aux->x_sym32.x_misc.x_lnsz.x_lnno);
01788
01789 std::string whichFile = *currentSourceFile;
01790
01791 for (unsigned int j = 0; j < includeFiles.size(); j++)
01792 {
01793 if ( (includeFiles[j].begin <= (unsigned)initialLineIndex) &&
01794 (includeFiles[j].end >= (unsigned)initialLineIndex) )
01795 {
01796 whichFile = includeFiles[j].name;
01797 break;
01798 }
01799 }
01800
01801 unsigned int previousLineNo = 0;
01802 Offset previousLineAddr = 0;
01803 bool isPreviousValid = false;
01804
01805
01806
01807 for (int j = initialLineIndex + 1; j < nlines; j++ )
01808 {
01809 LINENO * lptr = (LINENO *)( lines + (j * LINESZ) );
01810 unsigned long lnno = (is64_ ? lptr->l_lnno64 : lptr->l_lnno32);
01811 unsigned long paddr = (is64_ ? lptr->l_addr64.l_paddr : lptr->l_addr32.l_paddr);
01812
01813 if (! lnno)
01814 {
01815 break;
01816 }
01817
01818 unsigned int lineNo = lnno + initialLine - 1;
01819 Offset lineAddr = paddr + trueBaseAddress;
01820
01821 if (isPreviousValid)
01822 {
01823
01824
01825 unsigned current_col = 0;
01826
01827
01828
01829
01830
01831
01832
01833 lineInfo_[whichFile].addLine(whichFile.c_str(), previousLineNo, current_col, previousLineAddr, lineAddr );
01834
01835
01836 }
01837
01838 previousLineNo = lineNo;
01839 previousLineAddr = lineAddr;
01840 isPreviousValid = true;
01841 }
01842
01843 if (isPreviousValid)
01844 {
01845
01846
01847
01848
01849
01850 while (previousLineAddr < funcEndAddress)
01851 {
01852 unsigned current_col = 0;
01853
01854
01855
01856
01857 lineInfo_[whichFile].addLine(whichFile.c_str(), previousLineNo, current_col, previousLineAddr, previousLineAddr + 4);
01858
01859
01860
01861 previousLineAddr += 4;
01862 }
01863 }
01864 }
01865 }
01866
01867
01868
01869
01870 void Object::parseTypeInfo(Symtab *obj)
01871 {
01872 int i, j;
01873 int nstabs;
01874 SYMENT *syms;
01875 SYMENT *tsym;
01876 char *stringPool;
01877 char tempName[9];
01878 char *stabstr=NULL;
01879 union auxent *aux;
01880 std::string funcName;
01881 Offset staticBlockBaseAddr = 0;
01882 typeCommon *commonBlock = NULL;
01883 Symbol *commonBlockVar = NULL;
01884 std::string currentSourceFile;
01885 bool inCommonBlock = false;
01886 Module *mod = NULL;
01887
01888 void *syms_void = NULL;
01889 get_stab_info(stabstr, nstabs, syms_void, stringPool);
01890 syms = (SYMENT *) syms_void;
01891
01892 for (i=0; i < nstabs; i++) {
01893
01894
01895 SYMENT *sym = (SYMENT *) (((char *) syms) + i * SYMESZ);
01896 unsigned long sym_value = (is64_ ? sym->n_value64 : sym->n_value32);
01897
01898 if (sym->n_sclass == C_FILE) {
01899 char *moduleName;
01900 if (is64_) {
01901 moduleName = &stringPool[sym->n_offset64];
01902 } else if (!sym->n_zeroes32) {
01903 moduleName = &stringPool[sym->n_offset32];
01904 } else {
01905 memset(tempName, 0, 9);
01906 strncpy(tempName, sym->n_name32, 8);
01907 moduleName = tempName;
01908 }
01909
01910 for (j=1; j <= sym->n_numaux; j++) {
01911 aux = (union auxent *) ((char *) sym + j * SYMESZ);
01912 if (aux->x_file._x.x_ftype == XFT_FN) {
01913 if (!aux->x_file._x.x_zeroes) {
01914 moduleName = &stringPool[aux->x_file._x.x_offset];
01915 } else {
01916 memset(moduleName, 0, 15);
01917 strncpy(moduleName, aux->x_file.x_fname, 14);
01918 }
01919 }
01920 }
01921 currentSourceFile = std::string(moduleName);
01922 typeCollection *tc = typeCollection::getModTypeCollection(mod);
01923 assert(tc);
01924 tc->clearNumberedTypes();
01925 if(!obj->findModuleByName(mod, currentSourceFile) &&
01926 !obj->findModuleByName(mod,extract_pathname_tail(currentSourceFile)))
01927 {
01928 mod = NULL;
01929 }
01930 }
01931
01932 if (!mod)
01933 mod = obj->getDefaultModule();
01934
01935
01936 char *nmPtr;
01937 if (!sym->n_zeroes32 && ((sym->n_sclass & DBXMASK) ||
01938 (sym->n_sclass == C_BINCL) ||
01939 (sym->n_sclass == C_EINCL))) {
01940 long sym_offset = (is64_ ? sym->n_offset64 : sym->n_offset32);
01941
01942
01943 if(sym_offset < 3) {
01944 if (sym_offset == 2 && stabstr[0]) {
01945 nmPtr = &stabstr[0];
01946 } else {
01947 nmPtr = &stabstr[sym_offset];
01948 }
01949 } else if (!stabstr[sym_offset-3]) {
01950 nmPtr = &stabstr[sym_offset];
01951 } else {
01952
01953 nmPtr = &stabstr[sym_offset-2];
01954 }
01955 #if 0
01956 bperr("using nmPtr = %s\n", nmPtr);
01957 bperr("got n_offset = (%d) %s\n", sym_offset, &stabstr[sym_offset]);
01958 if (sym_offset>=2)
01959 bperr("got n_offset-2 = %s\n", &stabstr[sym_offset-2]);
01960 if (sym_offset>=3)
01961 bperr("got n_offset-3 = %x\n", stabstr[sym_offset-3]);
01962 if (sym_offset>=4)
01963 bperr("got n_offset-4 = %x\n", stabstr[sym_offset-4]);
01964 #endif
01965 } else if (is64_) {
01966 nmPtr = &stringPool[sym->n_offset64];
01967 } else if (!sym->n_zeroes32) {
01968 nmPtr = &stringPool[sym->n_offset32];
01969 } else {
01970
01971 memset(tempName, 0, 9);
01972 strncpy(tempName, sym->n_name32, 8);
01973 nmPtr = tempName;
01974 }
01975
01976 if ((sym->n_sclass == C_BINCL) ||
01977 (sym->n_sclass == C_EINCL) ||
01978 (sym->n_sclass == C_FUN))
01979 {
01980 funcName = nmPtr;
01981
01982 if (funcName.find(":") < funcName.length())
01983 funcName = funcName.substr(0,funcName.find(":"));
01984 }
01985 if (sym->n_sclass & DBXMASK) {
01986 if (sym->n_sclass == C_BCOMM) {
01987 char *commonBlockName;
01988
01989 inCommonBlock = true;
01990 commonBlockName = nmPtr;
01991
01992 std::vector<Symbol *>vars;
01993 if(!obj->findSymbolByType(vars, commonBlockName, Symbol::ST_OBJECT, mangledName)) {
01994 if(!obj->findSymbolByType(vars, commonBlockName, Symbol::ST_OBJECT, prettyName))
01995 commonBlockVar = NULL;
01996 else
01997 commonBlockVar = vars[0];
01998 }
01999 else
02000 commonBlockVar = vars[0];
02001
02002 std::string cbName = commonBlockName;
02003 if (!commonBlockVar) {
02004
02005 } else {
02006 typeCollection *tc = typeCollection::getModTypeCollection(mod);
02007 assert(tc);
02008 commonBlock = dynamic_cast<typeCommon *>(tc->findVariableType(cbName));
02009 if (commonBlock == NULL) {
02010
02011
02012 commonBlock = new typeCommon(cbName);
02013 tc->addGlobalVariable(cbName, commonBlock);
02014 }
02015
02016 commonBlock->beginCommonBlock();
02017 }
02018 } else if (sym->n_sclass == C_ECOMM) {
02019 inCommonBlock = false;
02020 if (commonBlock == NULL)
02021 continue;
02022
02023
02024 std::vector<Symbol *> bpmv;
02025 if (obj->findSymbolByType(bpmv, funcName, Symbol::ST_FUNCTION, mangledName) || !bpmv.size()) {
02026 string newName = "." + funcName;
02027 if (obj->findSymbolByType(bpmv, newName, Symbol::ST_FUNCTION, mangledName) || !bpmv.size()) {
02028
02029 }
02030 else{
02031 Symbol *func = bpmv[0];
02032 commonBlock->endCommonBlock(func, (void *)commonBlockVar->getAddr());
02033 }
02034 } else {
02035 Symbol *func = bpmv[0];
02036 commonBlock->endCommonBlock(func, (void *)commonBlockVar->getAddr());
02037 }
02038
02039
02040
02041
02042
02043 commonBlockVar = NULL;
02044 commonBlock = NULL;
02045 } else if (sym->n_sclass == C_BSTAT) {
02046
02047
02048 tsym = (SYMENT *) (((char *) syms) + sym_value * SYMESZ);
02049
02050
02051
02052
02053
02054
02055 staticBlockBaseAddr = (is64_ ? tsym->n_value64 : tsym->n_value32);
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078 } else if (sym->n_sclass == C_ESTAT) {
02079 staticBlockBaseAddr = 0;
02080 }
02081
02082
02083
02084
02085
02086 if (inCommonBlock && commonBlock == NULL)
02087 continue;
02088
02089 if(!mod){
02090 std::string modName = currentSourceFile;
02091 std::string fName = extract_pathname_tail(modName);
02092 if(!obj->findModuleByName(mod, fName))
02093 {
02094 modName = obj->file();
02095 if(!obj->findModuleByName(mod, modName))
02096 continue;
02097 }
02098 }
02099
02100 if (staticBlockBaseAddr && (sym->n_sclass == C_STSYM)) {
02101 parseStabString(mod, 0, nmPtr,
02102 sym_value+staticBlockBaseAddr, commonBlock);
02103 } else {
02104 parseStabString(mod, 0, nmPtr, sym_value, commonBlock);
02105 }
02106 }
02107 }
02108 #if defined(TIMED_PARSE)
02109 struct timeval endtime;
02110 gettimeofday(&endtime, NULL);
02111 unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
02112 unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
02113 unsigned long difftime = lendtime - lstarttime;
02114 double dursecs = difftime/(1000 );
02115 cout << __FILE__ << ":" << __LINE__ <<": parseTypes("<< obj->exec()->file()
02116 <<") took "<<dursecs <<" msecs" << endl;
02117 #endif
02118
02119
02120 }
02121
02122 bool Region::isStandardCode()
02123 {
02124 return (getRegionPermissions() == RP_RX ||
02125 getRegionPermissions() == RP_RWX);
02126 }
02127
02128 Dyninst::Architecture Object::getArch()
02129 {
02130 if (getAddressWidth() == 4)
02131 return Dyninst::Arch_ppc32;
02132 return Dyninst::Arch_ppc64;
02133 }