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 #include <assert.h>
00032 #include <link.h>
00033 #include <stdio.h>
00034 #include <errno.h>
00035 #include <sys/types.h>
00036 #include <sys/wait.h>
00037 #include <string.h>
00038
00039 #include <sys/types.h>
00040 #include <sys/stat.h>
00041 #include <unistd.h>
00042 #include <fcntl.h>
00043 #include <limits.h>
00044
00045 #include <vector>
00046 #include <string>
00047
00048 #include <iostream>
00049
00050 #include "common/h/parseauxv.h"
00051 #include "common/h/headers.h"
00052 #include "common/h/pathName.h"
00053
00054 #include "common/h/addrtranslate.h"
00055 #include "common/src/addrtranslate-sysv.h"
00056
00057 #if defined(os_linux) || defined(os_bg)
00058 #define R_DEBUG_NAME "_r_debug"
00059 #else
00060 #define R_DEBUG_NAME "r_debug"
00061 #endif
00062
00063 #if defined(os_linux)
00064 #include "common/h/linuxKludges.h"
00065 #endif
00066
00067 using namespace std;
00068 using namespace Dyninst;
00069
00070 FileCache Dyninst::files;
00071
00072
00073 class ProcessReaderSelf : public ProcessReader {
00074 public:
00075 ProcessReaderSelf();
00076 bool start();
00077 bool ReadMem(Address inTraced, void *inSelf, unsigned amount);
00078 bool GetReg(MachRegister reg, MachRegisterVal &val);
00079 bool done();
00080
00081 virtual ~ProcessReaderSelf();
00082 };
00083
00084 struct link_map_dyn32
00085 {
00086 Elf32_Addr l_addr;
00087 uint32_t l_name;
00088 uint32_t l_ld;
00089 uint32_t l_next, l_prev;
00090 };
00091
00092 struct r_debug_dyn32
00093 {
00094 int r_version;
00095 uint32_t r_map;
00096 Elf32_Addr r_brk;
00097 enum
00098 {
00099 RT_CONSISTENT,
00100 RT_ADD,
00101 RT_DELETE
00102 } r_state;
00103 Elf32_Addr r_ldbase;
00104 };
00105
00106 class link_map_xplat
00107 {
00108 public:
00109 virtual size_t size() = 0;
00110 virtual uint64_t l_addr() = 0;
00111 virtual char *l_name() = 0;
00112 virtual void *l_ld() = 0;
00113 virtual bool is_last() = 0;
00114 virtual bool load_next() = 0;
00115 virtual bool is_valid() = 0;
00116 virtual bool load_link(Address addr) = 0;
00117 virtual ~link_map_xplat() {};
00118 };
00119
00120 template<class link_map_X>
00121 class link_map_dyn : public link_map_xplat
00122 {
00123 public:
00124 link_map_dyn(ProcessReader *proc_, Address addr);
00125 ~link_map_dyn();
00126 virtual size_t size();
00127 virtual uint64_t l_addr();
00128 virtual char *l_name();
00129 virtual void *l_ld();
00130 virtual bool is_last();
00131 virtual bool load_next();
00132 virtual bool is_valid();
00133 virtual bool load_link(Address addr);
00134
00135 protected:
00136 ProcessReader *proc;
00137 char link_name[256];
00138 bool loaded_name;
00139 bool valid;
00140 link_map_X link_elm;
00141 };
00142
00143 template<class r_debug_X>
00144 class r_debug_dyn {
00145 public:
00146 r_debug_dyn(ProcessReader *proc_, Address addr);
00147 ~r_debug_dyn();
00148 void *r_brk();
00149 Address r_map();
00150 int r_state();
00151 bool is_valid();
00152 protected:
00153 ProcessReader *proc;
00154 bool valid;
00155 r_debug_X debug_elm;
00156 };
00157
00158 template<class r_debug_X>
00159 r_debug_dyn<r_debug_X>::r_debug_dyn(ProcessReader *proc_, Address addr)
00160 : proc(proc_)
00161 {
00162 translate_printf("r_debug_dyn constructor, reading from 0x%lx\n", addr);
00163 valid = proc->ReadMem(addr, &debug_elm, sizeof(debug_elm));
00164 if (!valid) {
00165 translate_printf("\t Warning: read failed, setting not valid\n");
00166 return;
00167 }
00168
00169 translate_printf("r_debug_dyn valid = %d\n", valid?1:0);
00170 translate_printf(" Read rdebug structure. Values were:\n", __FILE__, __LINE__);
00171 translate_printf(" r_brk: %lx\n", (unsigned long)debug_elm.r_brk);
00172 translate_printf(" r_map: %lx\n", (unsigned long)debug_elm.r_map);
00173 #if !defined(os_freebsd)
00174 translate_printf(" r_ldbase: %lx\n", (unsigned long)debug_elm.r_ldbase);
00175 #endif
00176 }
00177
00178 template<class r_debug_X>
00179 r_debug_dyn<r_debug_X>::~r_debug_dyn()
00180 {
00181 }
00182
00183 template<class r_debug_X>
00184 bool r_debug_dyn<r_debug_X>::is_valid() {
00185 if (!valid) {
00186 translate_printf("\tr_debug_dyn::is_valid ret false\n");
00187 return false;
00188 }
00189 if (0 == r_map()) {
00190 translate_printf("\tr_debug_dyn::is_valid; r_map() == 0, ret false\n");
00191 return false;
00192 }
00193
00194 translate_printf("\tr_debug_dyn::is_valid; valid == %s, ret %s\n",
00195 (valid ? "true" : "false"),
00196 (valid ? "true" : "false"));
00197 return valid;
00198 }
00199
00200 template<class r_debug_X>
00201 Address r_debug_dyn<r_debug_X>::r_map() {
00202 return (Address) debug_elm.r_map;
00203 }
00204
00205 template<class r_debug_X>
00206 void *r_debug_dyn<r_debug_X>::r_brk() {
00207 return reinterpret_cast<void *>(debug_elm.r_brk);
00208 }
00209
00210 template<class r_debug_X>
00211 int r_debug_dyn<r_debug_X>::r_state() {
00212 return (int)debug_elm.r_state;
00213 }
00214
00215 template<class link_map_X>
00216 link_map_dyn<link_map_X>::link_map_dyn(ProcessReader *proc_, Address addr_) :
00217 proc(proc_),
00218 loaded_name(false)
00219 {
00220 valid = load_link(addr_);
00221 }
00222
00223 template<class link_map_X>
00224 link_map_dyn<link_map_X>::~link_map_dyn() {
00225 }
00226
00227 template<class link_map_X>
00228 bool link_map_dyn<link_map_X>::is_valid() {
00229 return valid;
00230 }
00231
00232 template<class link_map_X>
00233 size_t link_map_dyn<link_map_X>::size()
00234 {
00235 return sizeof(link_elm);
00236 }
00237
00238 template<class link_map_X>
00239 uint64_t link_map_dyn<link_map_X>::l_addr()
00240 {
00241 return (uint64_t)link_elm.l_addr;
00242 }
00243
00244 template<class link_map_X>
00245 char *link_map_dyn<link_map_X>::l_name()
00246 {
00247 if (loaded_name) return link_name;
00248
00249 for (unsigned int i = 0; i < sizeof(link_name); ++i) {
00250 if (!proc->ReadMem((Address) (link_elm.l_name + i),
00251 link_name + i, sizeof(char)))
00252 {
00253 valid = false;
00254 return NULL;
00255 }
00256 if (link_name[i] == '\0') break;
00257 }
00258 link_name[sizeof(link_name) - 1] = '\0';
00259
00260 loaded_name = true;
00261 return link_name;
00262 }
00263
00264 template<class link_map_X>
00265 void *link_map_dyn<link_map_X>::l_ld()
00266 {
00267 return const_cast<void *>(reinterpret_cast<const void *>(link_elm.l_ld));
00268 }
00269
00270 template<class link_map_X>
00271 bool link_map_dyn<link_map_X>::is_last()
00272 {
00273 return (link_elm.l_next == 0);
00274 }
00275
00276 template<class link_map_X>
00277 bool link_map_dyn<link_map_X>::load_next()
00278 {
00279 if (is_last()) {
00280 return false;
00281 }
00282 if (load_link((Address) link_elm.l_next)) {
00283 loaded_name = false;
00284 return true;
00285 }
00286 return false;
00287 }
00288
00289 template<class link_map_X>
00290 bool link_map_dyn<link_map_X>::load_link(Address addr)
00291 {
00292 return proc->ReadMem(addr, &link_elm, sizeof(link_elm));
00293 }
00294
00295 static const char *deref_link(const char *path)
00296 {
00297 static char buffer[PATH_MAX], *p;
00298 buffer[PATH_MAX-1] = '\0';
00299 p = realpath(path, buffer);
00300 if (!p)
00301 return path;
00302 return p;
00303 }
00304
00305
00306 ProcessReaderSelf::ProcessReaderSelf() :
00307 ProcessReader()
00308 {
00309 }
00310
00311 ProcessReaderSelf::~ProcessReaderSelf()
00312 {
00313 }
00314
00315 bool ProcessReaderSelf::start() {
00316 return true;
00317 }
00318
00319 bool ProcessReaderSelf::done() {
00320 return true;
00321 }
00322
00323 bool ProcessReaderSelf::ReadMem(Address inTraced, void *inSelf, unsigned amount)
00324 {
00325 memcpy(inSelf, (void *) inTraced, amount);
00326 return true;
00327 }
00328
00329 bool ProcessReaderSelf::GetReg(MachRegister , MachRegisterVal &)
00330 {
00331 assert(0);
00332 return false;
00333 }
00334
00335
00336 vector< pair<Address, unsigned long> > *LoadedLib::getMappedRegions()
00337 {
00338 if (mapped_regions.size())
00339 {
00340 return &mapped_regions;
00341 }
00342
00343 FCNode *fc = files.getNode(name, symreader_factory);
00344 if (!fc)
00345 return false;
00346
00347 vector<SymSegment> segs;
00348 fc->getSegments(segs);
00349
00350 for (unsigned i=0; i<segs.size(); i++) {
00351 pair<Address, unsigned long> p(load_addr + segs[i].mem_addr,
00352 segs[i].mem_size);
00353 mapped_regions.push_back(p);
00354 }
00355
00356 return &mapped_regions;
00357 }
00358
00359 AddressTranslate *AddressTranslate::createAddressTranslator(int pid_,
00360 ProcessReader *reader_,
00361 SymbolReaderFactory *symfactory_,
00362 PROC_HANDLE,
00363 std::string exename,
00364 Address interp_base)
00365 {
00366 translate_printf("Creating AddressTranslateSysV\n", __FILE__, __LINE__);
00367 AddressTranslate *at = new AddressTranslateSysV(pid_, reader_, symfactory_, exename, interp_base);
00368 translate_printf("Created: %lx\n", (long)at);
00369
00370 if (!at) {
00371 return NULL;
00372 }
00373 else if (at->creation_error) {
00374 delete at;
00375 return NULL;
00376 }
00377 return at;
00378 }
00379
00380 AddressTranslate *AddressTranslate::createAddressTranslator(ProcessReader *reader_,
00381 SymbolReaderFactory *factory_,
00382 std::string exename,
00383 Address interp_base)
00384 {
00385 return createAddressTranslator(getpid(), reader_, factory_, INVALID_HANDLE_VALUE, exename, interp_base);
00386 }
00387
00388 AddressTranslateSysV::AddressTranslateSysV() :
00389 AddressTranslate(NULL_PID),
00390 reader(NULL),
00391 interpreter_base(0),
00392 program_base(0),
00393 page_size(0),
00394 set_interp_base(0),
00395 address_size(0),
00396 interpreter(NULL),
00397 previous_r_state(0),
00398 current_r_state(0),
00399 r_debug_addr(0),
00400 trap_addr(0),
00401 real_trap_addr(0)
00402 {
00403 }
00404
00405 AddressTranslateSysV::AddressTranslateSysV(int pid, ProcessReader *reader_,
00406 SymbolReaderFactory *reader_fact,
00407 std::string exename, Address interp_base) :
00408 AddressTranslate(pid, INVALID_HANDLE_VALUE, exename),
00409 reader(reader_),
00410 interpreter_base(0),
00411 set_interp_base(false),
00412 address_size(0),
00413 interpreter(NULL),
00414 previous_r_state(0),
00415 current_r_state(0),
00416 r_debug_addr(0),
00417 trap_addr(0),
00418 real_trap_addr(0)
00419 {
00420 bool result;
00421 if (interp_base != (Address) -1) {
00422 interpreter_base = interp_base;
00423 set_interp_base = true;
00424 }
00425 if (!reader) {
00426 if (pid == getpid()) {
00427 reader = new ProcessReaderSelf();
00428 }
00429 else {
00430 reader = createDefaultDebugger(pid);
00431 }
00432 }
00433 symfactory = reader_fact;
00434 result = init();
00435 if (!result) {
00436 creation_error = true;
00437 return;
00438 }
00439 }
00440
00441 bool AddressTranslateSysV::parseDTDebug() {
00442
00443 #if !defined(os_freebsd)
00444 return false;
00445 #else
00446 translate_printf("Entering parseDTDebug\n");
00447 if( !setAddressSize() ) {
00448 translate_printf("Failed to set address size.\n", __FILE__, __LINE__);
00449 return false;
00450 }
00451
00452
00453
00454
00455
00456
00457
00458 const char *l_err = "Failed to determine trap address.";
00459
00460 getExecName();
00461 if( exec_name.empty() ) {
00462 translate_printf("%s\n", l_err);
00463 return false;
00464 }
00465
00466 SymReader *exe = symfactory->openSymbolReader(exec_name);
00467 if( !exe ) {
00468 translate_printf("%s\n", l_err);
00469 return false;
00470 }
00471
00472
00473 Address dynAddress = 0;
00474 size_t dynSize = 0;
00475 unsigned numRegs = exe->numSegments();
00476 translate_printf("Checking %d regions for address/size information\n", numRegs);
00477 for(unsigned i = 0; i < numRegs; ++i) {
00478 SymSegment seg;
00479 exe->getSegment(i, seg);
00480 translate_printf("Found segment type %d for 0x%lx - 0x%lx, want %d\n",
00481 seg.type, seg.mem_addr, seg.mem_addr + seg.mem_size, PT_DYNAMIC);
00482 if( PT_DYNAMIC == seg.type ) {
00483 dynAddress = seg.mem_addr;
00484 dynSize = seg.mem_size;
00485 break;
00486 }
00487 }
00488 symfactory->closeSymbolReader(exe);
00489
00490 if( !dynAddress || !dynSize ) {
00491
00492 translate_printf("No dyn address or size, assuming static binary\n");
00493 return false;
00494 }
00495
00496 if( !reader->start() ) {
00497 translate_printf("%s\n", l_err);
00498 return false;
00499 }
00500
00501
00502 void *dynData = malloc(dynSize);
00503 if( !dynData || !reader->ReadMem(dynAddress, dynData, dynSize) ) {
00504 translate_printf("%s\n", l_err);
00505 if( dynData ) free(dynData);
00506 return false;
00507 }
00508
00509 if( address_size == 8 ) {
00510 Elf64_Dyn *dynDataElf = (Elf64_Dyn *)dynData;
00511 for(unsigned i = 0; i < (dynSize / sizeof(Elf64_Dyn)); ++i) {
00512 translate_printf("Comparing symbol tag %d to wanted %d\n",
00513 dynDataElf[i].d_tag, DT_DEBUG);
00514 if( DT_DEBUG == dynDataElf[i].d_tag ) {
00515 r_debug_addr = (Address) dynDataElf[i].d_un.d_ptr;
00516 break;
00517 }
00518 }
00519 }else{
00520 Elf32_Dyn *dynDataElf = (Elf32_Dyn *)dynData;
00521 for(unsigned i = 0; i < (dynSize / sizeof(Elf32_Dyn)); ++i) {
00522 if( DT_DEBUG == dynDataElf[i].d_tag ) {
00523 r_debug_addr = (Address) dynDataElf[i].d_un.d_ptr;
00524 break;
00525 }
00526 }
00527 }
00528 free(dynData);
00529
00530
00531
00532
00533
00534 if( r_debug_addr ) {
00535 trap_addr = getTrapAddrFromRdebug();
00536 if( trap_addr == 0 ) {
00537 reader->done();
00538 return false;
00539 }
00540 }
00541
00542 reader->done();
00543
00544 return ( r_debug_addr != 0 );
00545 #endif
00546 }
00547
00548 bool AddressTranslateSysV::parseInterpreter() {
00549 bool result;
00550
00551 result = setInterpreter();
00552 if (!result) {
00553 translate_printf("Failed to set interpreter--static binary.\n", __FILE__, __LINE__);
00554 return true;
00555 }
00556
00557 result = setAddressSize();
00558 if (!result) {
00559 translate_printf("Failed to set address size.\n", __FILE__, __LINE__);
00560 return false;
00561 }
00562
00563 result = setInterpreterBase();
00564 if (!result) {
00565 translate_printf("Failed to set interpreter base.\n", __FILE__, __LINE__);
00566 return false;
00567 }
00568
00569 if (interpreter) {
00570 if( interpreter->get_r_debug() ) {
00571 r_debug_addr = interpreter->get_r_debug() + interpreter_base;
00572
00573 if( !reader->start() ) {
00574 translate_printf("Failed to initialize process reader\n", __FILE__, __LINE__);
00575 return false;
00576 }
00577
00578 trap_addr = getTrapAddrFromRdebug();
00579
00580 if( !reader->done() ) {
00581 translate_printf("Failed to finalize process reader\n", __FILE__, __LINE__);
00582 return false;
00583 }
00584
00585 if( trap_addr == 0 ) {
00586 trap_addr = interpreter->get_r_trap() + interpreter_base;
00587 }
00588 }
00589 else
00590 {
00591 r_debug_addr = 0;
00592 trap_addr = interpreter->get_r_trap() + interpreter_base;
00593 }
00594 } else {
00595 r_debug_addr = 0;
00596 trap_addr = 0;
00597 }
00598
00599 return true;
00600 }
00601
00602 bool AddressTranslateSysV::init() {
00603 translate_printf("Initing AddressTranslateSysV\n", __FILE__, __LINE__);
00604
00605
00606 if( !parseDTDebug() ) {
00607 if( !parseInterpreter() ) {
00608 translate_printf("Failed to determine r_debug address\n",
00609 __FILE__, __LINE__);
00610 return false;
00611 }
00612 }
00613
00614 translate_printf("trap_addr = 0x%lx, r_debug_addr = 0x%lx\n", trap_addr, r_debug_addr);
00615 translate_printf("Done with AddressTranslateSysV::init()\n", __FILE__, __LINE__);
00616
00617 return true;
00618 }
00619
00620 LoadedLib *AddressTranslateSysV::getLoadedLibByNameAddr(Address addr, std::string name)
00621 {
00622 Address wrappedAddr = adjustForAddrSpaceWrap(addr, name);
00623
00624 std::pair<Address, std::string> p(wrappedAddr, name);
00625 sorted_libs_t::iterator i = sorted_libs.find(p);
00626 LoadedLib *ll = NULL;
00627 if (i != sorted_libs.end()) {
00628 ll = i->second;
00629 }
00630 else {
00631
00632 ll = new LoadedLib(name, wrappedAddr);
00633
00634 ll->setFactory(symfactory);
00635 assert(ll);
00636 sorted_libs[p] = ll;
00637 }
00638 ll->setShouldClean(false);
00639 return ll;
00640 }
00641
00642
00643 Address AddressTranslateSysV::getTrapAddrFromRdebug() {
00644 Address retVal = 0;
00645 assert( r_debug_addr && address_size );
00646
00647 if( address_size == sizeof(void *) ) {
00648 r_debug_dyn<r_debug> *r_debug_native = new r_debug_dyn<r_debug>(reader, r_debug_addr);
00649 if( !r_debug_native ) {
00650 translate_printf("Failed to parse r_debug struct.\n", __FILE__, __LINE__);
00651 return 0;
00652 }
00653 if( !r_debug_native->is_valid() ) {
00654 return 0;
00655 }
00656 retVal = (Address) r_debug_native->r_brk();
00657 delete r_debug_native;
00658 }else{
00659 r_debug_dyn<r_debug_dyn32> *r_debug_32 = new r_debug_dyn<r_debug_dyn32>(reader, r_debug_addr);
00660 if( !r_debug_32 ) {
00661 translate_printf("Failed to parse r_debug struct.\n", __FILE__, __LINE__);
00662 return 0;
00663 }
00664 if( !r_debug_32->is_valid() ) {
00665 return 0;
00666 }
00667 retVal = (Address) r_debug_32->r_brk();
00668 delete r_debug_32;
00669 }
00670
00671 return retVal;
00672 }
00673
00674 bool AddressTranslateSysV::refresh()
00675 {
00676 link_map_xplat *link_elm = NULL;
00677 r_debug_dyn<r_debug_dyn32> *r_debug_32 = NULL;
00678 r_debug_dyn<r_debug> *r_debug_native = NULL;
00679 map_entries *maps = NULL;
00680 bool result = false;
00681 size_t loaded_lib_count = 0;
00682
00683 translate_printf("Refreshing Libraries\n");
00684 if (pid == NULL_PID)
00685 return true;
00686
00687 if (!r_debug_addr) {
00688
00689
00690 if( !parseDTDebug() && !interpreter ) {
00691 translate_printf("Working with static binary, no libraries to refresh\n",
00692 __FILE__, __LINE__);
00693 libs.clear();
00694 if (!exec) {
00695 exec = getAOut();
00696 }
00697 libs.push_back(exec);
00698 getArchLibs(libs);
00699 return true;
00700 }
00701 }
00702 std::vector<LoadedLib *>::iterator i;
00703 for (i = libs.begin(); i != libs.end(); i++)
00704 (*i)->setShouldClean(true);
00705 libs.clear();
00706
00707 if (!exec) {
00708 exec = getAOut();
00709 }
00710 exec->setShouldClean(false);
00711 libs.push_back(exec);
00712 getArchLibs(libs);
00713
00714 if( !reader->start() ) {
00715 translate_printf("Failed to refresh libraries\n", __FILE__, __LINE__);
00716 return false;
00717 }
00718
00719 translate_printf(" Starting refresh.\n", __FILE__, __LINE__);
00720 translate_printf(" trap_addr: %lx\n", trap_addr);
00721 translate_printf(" r_debug_addr: %lx\n", r_debug_addr);
00722
00723 if (address_size == sizeof(void*)) {
00724 r_debug_native = new r_debug_dyn<r_debug>(reader, r_debug_addr);
00725 if (!r_debug_native)
00726 {
00727 translate_printf("No r_debug_native, done\n");
00728 result = true;
00729 goto done;
00730 }
00731 else if (!r_debug_native->is_valid() && read_abort)
00732 {
00733 translate_printf("r_debug_native is not valid and aborting read, done\n");
00734 result = false;
00735 goto all_done;
00736 }
00737 else if (!r_debug_native->is_valid())
00738 {
00739 translate_printf("r_debug_native is not valid, done\n");
00740 if (interpreter) {
00741 libs.push_back(getLoadedLibByNameAddr(interpreter_base,
00742 interpreter->getFilename()));
00743 }
00744 result = true;
00745 goto done;
00746 }
00747 link_elm = new link_map_dyn<link_map>(reader, r_debug_native->r_map());
00748 }
00749 else {
00750 r_debug_32 = new r_debug_dyn<r_debug_dyn32>(reader, r_debug_addr);
00751 if (!r_debug_32)
00752 {
00753 result = true;
00754 goto done;
00755 }
00756 else if (!r_debug_32->is_valid() && read_abort)
00757 {
00758 result = false;
00759 goto all_done;
00760 }
00761 else if (!r_debug_32->is_valid())
00762 {
00763 if (interpreter) {
00764 libs.push_back(getLoadedLibByNameAddr(interpreter_base,
00765 interpreter->getFilename()));
00766 }
00767 result = true;
00768 goto done;
00769 }
00770 link_elm = new link_map_dyn<link_map_dyn32>(reader, r_debug_32->r_map());
00771 }
00772
00773 if (!link_elm->is_valid() && read_abort) {
00774 result = false;
00775 goto all_done;
00776 }
00777 if (!link_elm->is_valid()) {
00778 result = true;
00779 goto done;
00780 }
00781
00782 do {
00783 if (!link_elm->l_name()) {
00784 if (read_abort) {
00785 result = false;
00786 goto all_done;
00787 }
00788 continue;
00789 }
00790 string obj_name(link_elm->l_name());
00791
00792 if( getExecName() == string(deref_link(obj_name.c_str())) ) {
00793 if (exec)
00794 exec->dynamic_addr = (Address) link_elm->l_ld();
00795 continue;
00796 }
00797
00798 Address text = (Address) link_elm->l_addr();
00799 if (obj_name.empty()) {
00800 if (!text && exec) {
00801 exec->dynamic_addr = (Address) link_elm->l_ld();
00802 }
00803 continue;
00804 }
00805 if (!link_elm->is_valid())
00806 goto done;
00807
00808 #if defined(os_linux)
00809 unsigned maps_size;
00810 if (obj_name == "") {
00811 if (!maps)
00812 maps = getLinuxMaps(pid, maps_size);
00813 for (unsigned i=0; maps && i<maps_size; i++) {
00814 if (text == maps[i].start) {
00815 obj_name = maps[i].path;
00816 break;
00817 }
00818 }
00819 }
00820 if (obj_name.c_str()[0] == '[')
00821 continue;
00822 #endif
00823
00824 string s(deref_link(obj_name.c_str()));
00825 LoadedLib *ll = getLoadedLibByNameAddr(text, s);
00826 ll->dynamic_addr = (Address) link_elm->l_ld();
00827 loaded_lib_count++;
00828 translate_printf(" New Loaded Library: %s(%lx)\n", s.c_str(), text);
00829
00830 libs.push_back(ll);
00831 } while (link_elm->load_next());
00832
00833
00834 if (read_abort) {
00835 result = false;
00836 goto all_done;
00837 }
00838
00839 translate_printf("Found %d libraries.\n", loaded_lib_count);
00840
00841 result = true;
00842 done:
00843 reader->done();
00844
00845
00846 sorted_libs.clear();
00847 for (vector<LoadedLib *>::iterator i = libs.begin(); i != libs.end(); i++)
00848 {
00849 LoadedLib *ll = *i;
00850 sorted_libs[pair<Address, string>(ll->getCodeLoadAddr(), ll->getName())] = ll;
00851 }
00852
00853 all_done:
00854
00855 if (read_abort) {
00856 translate_printf("refresh aborted due to async read\n", __FILE__, __LINE__);
00857 }
00858 if (link_elm)
00859 delete link_elm;
00860 if (r_debug_32)
00861 delete r_debug_32;
00862 if (r_debug_native)
00863 delete r_debug_native;
00864 if (maps)
00865 free(maps);
00866
00867 return result;
00868 }
00869
00870 FCNode::FCNode(string f, dev_t d, ino_t i, SymbolReaderFactory *factory_) :
00871 device(d),
00872 inode(i),
00873 parsed_file(false),
00874 parse_error(false),
00875 is_interpreter(false),
00876 r_debug_offset(0),
00877 r_trap_offset(0),
00878 symreader(NULL),
00879 factory(factory_)
00880 {
00881 filename = resolve_file_path(f.c_str());
00882 }
00883
00884 string FCNode::getFilename() {
00885 return filename;
00886 }
00887
00888 string FCNode::getInterpreter() {
00889 parsefile();
00890
00891 return interpreter_name;
00892 }
00893
00894 void FCNode::getSegments(vector<SymSegment> &segs) {
00895 parsefile();
00896
00897 segs = segments;
00898 }
00899
00900 unsigned FCNode::getAddrSize() {
00901 parsefile();
00902
00903 return addr_size;
00904 }
00905
00906 Offset FCNode::get_r_debug() {
00907 parsefile();
00908
00909 return r_debug_offset;
00910 }
00911
00912 Offset FCNode::get_r_trap() {
00913 parsefile();
00914
00915 return r_trap_offset;
00916 }
00917
00918 void FCNode::markInterpreter() {
00919 if (is_interpreter)
00920 return;
00921
00922 assert(!parsed_file);
00923 is_interpreter = true;
00924 }
00925
00926 #define NUM_DBG_BREAK_NAMES 4
00927 const char *dbg_break_names[] = { "_dl_debug_fast_state",
00928 "_dl_debug_state",
00929 "r_debug_state",
00930 "_r_debug_state" };
00931
00932 void FCNode::parsefile()
00933 {
00934 if (parsed_file || parse_error)
00935 return;
00936 parsed_file = true;
00937
00938 assert(!symreader);
00939 symreader = factory->openSymbolReader(filename);
00940 if (!symreader) {
00941 parse_error = true;
00942 translate_printf("Failed to open %s\n",
00943 filename.c_str());
00944 return;
00945 }
00946
00947 if (is_interpreter) {
00948 #if !defined(os_freebsd)
00949
00950
00951 Symbol_t r_debug_sym = symreader->getSymbolByName(R_DEBUG_NAME);
00952 if (!symreader->isValidSymbol(r_debug_sym)) {
00953 translate_printf("Failed to find r_debug symbol in %s\n",
00954 filename.c_str());
00955 parse_error = true;
00956 }
00957 r_debug_offset = symreader->getSymbolOffset(r_debug_sym);
00958 #endif
00959 r_trap_offset = 0;
00960 for(unsigned i = 0; i < NUM_DBG_BREAK_NAMES; ++i) {
00961 Symbol_t r_trap_sym = symreader->getSymbolByName(dbg_break_names[i]);
00962 if( symreader->isValidSymbol(r_trap_sym) ) {
00963 r_trap_offset = symreader->getSymbolOffset(r_trap_sym);
00964 break;
00965 }
00966 }
00967
00968 if( !r_trap_offset ) {
00969 translate_printf("Failed to find debugging trap symbol in %s\n",
00970 filename.c_str());
00971 parse_error = true;
00972 }
00973 }
00974
00975 addr_size = symreader->getAddressWidth();
00976 interpreter_name = symreader->getInterpreterName();
00977
00978 unsigned num_s = symreader->numSegments();
00979 for (unsigned i=0; i<num_s; i++) {
00980 SymSegment sr;
00981 bool result = symreader->getSegment(i, sr);
00982 if (!result) {
00983 translate_printf("Failed to get region info\n",
00984 __FILE__, __LINE__);
00985 parse_error = true;
00986 break;
00987 }
00988
00989 segments.push_back(sr);
00990 }
00991
00992
00993 }
00994
00995 FCNode *FileCache::getNode(const string &filename, SymbolReaderFactory *factory)
00996 {
00997 struct stat buf;
00998 int result = stat(filename.c_str(), &buf);
00999 if (result == -1)
01000 return NULL;
01001 if (!filename.length())
01002 return NULL;
01003
01004 for (unsigned i=0; i<nodes.size(); i++)
01005 {
01006 if (nodes[i]->inode == buf.st_ino &&
01007 nodes[i]->device == buf.st_dev)
01008 {
01009 return nodes[i];
01010 }
01011 }
01012
01013 FCNode *fc = new FCNode(filename, buf.st_dev, buf.st_ino, factory);
01014 nodes.push_back(fc);
01015
01016 return fc;
01017 }
01018
01019 FileCache::FileCache()
01020 {
01021 }
01022
01023 Address AddressTranslateSysV::getLibraryTrapAddrSysV() {
01024 if (real_trap_addr == 0)
01025 plat_getTrapAddr();
01026 return real_trap_addr;
01027 }
01028
01029 bool AddressTranslateSysV::plat_getTrapAddr() {
01030 real_trap_addr = trap_addr;
01031 return true;
01032 }
01033
01034 Address AddressTranslateSysV::adjustForAddrSpaceWrap(Address base, std::string name) {
01035 #if !defined(arch_64bit)
01036 return base;
01037 #else
01038 if (sizeof(long) != 8) return base;
01039 if (address_size != 4) return base;
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052 translate_printf("Opening %s with base of 0x%lx\n", name.c_str(), base);
01053 int fd = open(name.c_str(), O_RDONLY);
01054 if (fd == -1) return base;
01055
01056 lseek(fd, 0, SEEK_SET);
01057 Elf32_Ehdr e_hdr;
01058 if (read(fd, &e_hdr, sizeof(e_hdr)) != sizeof(e_hdr)) return base;
01059
01060 if (e_hdr.e_phoff == 0) return base;
01061
01062 lseek(fd, e_hdr.e_phoff, SEEK_SET);
01063
01064 Address codeOffset = 0;
01065 while (true) {
01066 Elf32_Phdr p_hdr;
01067 if (read(fd, &p_hdr, sizeof(p_hdr)) != sizeof(p_hdr)) return base;
01068
01069 Address p_vaddr = p_hdr.p_vaddr;
01070 unsigned type = p_hdr.p_type;
01071 if (type == PT_LOAD) {
01072 codeOffset = p_vaddr;
01073 break;
01074 }
01075 if (type == PT_PHDR ||
01076 type == PT_NULL ||
01077 type == PT_DYNAMIC ||
01078 type == PT_INTERP ||
01079 type == PT_NOTE ||
01080 type == PT_SHLIB ||
01081 type == PT_TLS) continue;
01082
01083 close(fd);
01084 return base;
01085 }
01086
01087 Address aspace32 = 0x00000000ffffffff;
01088
01089 translate_printf("\t Comparing base + offset of 0x%lx with 32-bit 0x%lx\n",
01090 base+codeOffset + aspace32);
01091
01092 close(fd);
01093
01094 if ((base + codeOffset) < aspace32) {
01095
01096 translate_printf("\t No wrapping detected\n");
01097 return base;
01098 }
01099 else {
01100
01101 translate_printf("\t Address space wrapping detected, returning modified base of 0x%lx\n",
01102 base | 0xffffffff00000000);
01103 return base | 0xffffffff00000000;
01104 }
01105 #endif
01106 }