2 * Copyright (c) 1996-2009 Barton P. Miller
4 * We provide the Paradyn Parallel Performance Tools (below
5 * described as "Paradyn") on an AS IS basis, and do not warrant its
6 * validity or performance. We reserve the right to update, modify,
7 * or discontinue this software at any time. We shall have no
8 * obligation to supply such updates or modifications or any other
9 * form of support to you.
11 * By your use of Paradyn, you understand and agree that we (or any
12 * other person or entity with proprietary rights in Paradyn) are
13 * under no obligation to provide either maintenance services,
14 * update services, notices of latent defects, or correction of
15 * defects for Paradyn.
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License as published by the Free Software Foundation; either
20 * version 2.1 of the License, or (at your option) any later version.
22 * This library is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * Lesser General Public License for more details.
27 * You should have received a copy of the GNU Lesser General Public
28 * License along with this library; if not, write to the Free Software
29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
36 #include <sys/types.h>
40 #include <sys/types.h>
49 #include "common/h/parseauxv.h"
50 #include "common/h/headers.h"
52 #include "common/h/addrtranslate.h"
53 #include "common/src/addrtranslate-sysv.h"
55 #if defined(os_linux) || defined(os_bg)
56 #define R_DEBUG_NAME "_r_debug"
58 #define R_DEBUG_NAME "r_debug"
62 using namespace Dyninst;
64 FileCache Dyninst::files;
67 class ProcessReaderSelf : public ProcessReader {
71 bool ReadMem(Address inTraced, void *inSelf, unsigned amount);
72 bool GetReg(MachRegister reg, MachRegisterVal &val);
75 virtual ~ProcessReaderSelf();
83 uint32_t l_next, l_prev;
103 virtual size_t size() = 0;
104 virtual uint64_t l_addr() = 0;
105 virtual char *l_name() = 0;
106 virtual void *l_ld() = 0;
107 virtual bool is_last() = 0;
108 virtual bool load_next() = 0;
109 virtual bool is_valid() = 0;
110 virtual bool load_link(Address addr) = 0;
111 virtual ~link_map_xplat() {};
114 template<class link_map_X>
115 class link_map_dyn : public link_map_xplat
118 link_map_dyn(ProcessReader *proc_, Address addr);
120 virtual size_t size();
121 virtual uint64_t l_addr();
122 virtual char *l_name();
123 virtual void *l_ld();
124 virtual bool is_last();
125 virtual bool load_next();
126 virtual bool is_valid();
127 virtual bool load_link(Address addr);
137 template<class r_debug_X>
140 r_debug_dyn(ProcessReader *proc_, Address addr);
152 template<class r_debug_X>
153 r_debug_dyn<r_debug_X>::r_debug_dyn(ProcessReader *proc_, Address addr)
156 valid = proc->ReadMem(addr, &debug_elm, sizeof(debug_elm));
158 translate_printf("[%s:%u] - Read rdebug structure. Values were:\n", __FILE__, __LINE__);
159 translate_printf("[%s:%u] - r_brk: %lx\n", __FILE__, __LINE__, (unsigned long)debug_elm.r_brk);
160 translate_printf("[%s:%u] - r_map: %lx\n", __FILE__, __LINE__, (unsigned long)debug_elm.r_map);
161 #if !defined(os_freebsd)
162 translate_printf("[%s:%u] - r_ldbase: %lx\n", __FILE__, __LINE__, (unsigned long)debug_elm.r_ldbase);
166 template<class r_debug_X>
167 r_debug_dyn<r_debug_X>::~r_debug_dyn()
171 template<class r_debug_X>
172 bool r_debug_dyn<r_debug_X>::is_valid() {
173 if (0 == r_map()) return false;
177 template<class r_debug_X>
178 Address r_debug_dyn<r_debug_X>::r_map() {
179 return (Address) debug_elm.r_map;
182 template<class r_debug_X>
183 void *r_debug_dyn<r_debug_X>::r_brk() {
184 return reinterpret_cast<void *>(debug_elm.r_brk);
187 template<class r_debug_X>
188 int r_debug_dyn<r_debug_X>::r_state() {
189 return (int)debug_elm.r_state;
192 template<class link_map_X>
193 link_map_dyn<link_map_X>::link_map_dyn(ProcessReader *proc_, Address addr_) :
197 valid = load_link(addr_);
200 template<class link_map_X>
201 link_map_dyn<link_map_X>::~link_map_dyn() {
204 template<class link_map_X>
205 bool link_map_dyn<link_map_X>::is_valid() {
209 template<class link_map_X>
210 size_t link_map_dyn<link_map_X>::size()
212 return sizeof(link_elm);
215 template<class link_map_X>
216 uint64_t link_map_dyn<link_map_X>::l_addr()
218 return (uint64_t)link_elm.l_addr;
221 template<class link_map_X>
222 char *link_map_dyn<link_map_X>::l_name()
224 if (loaded_name) return link_name;
226 for (unsigned int i = 0; i < sizeof(link_name); ++i) {
227 if (!proc->ReadMem((Address) (link_elm.l_name + i),
228 link_name + i, sizeof(char)))
233 if (link_name[i] == '\0') break;
235 link_name[sizeof(link_name) - 1] = '\0';
241 template<class link_map_X>
242 void *link_map_dyn<link_map_X>::l_ld()
244 return const_cast<void *>(reinterpret_cast<const void *>(link_elm.l_ld));
247 template<class link_map_X>
248 bool link_map_dyn<link_map_X>::is_last()
250 return (link_elm.l_next == 0);
253 template<class link_map_X>
254 bool link_map_dyn<link_map_X>::load_next()
259 if (load_link((Address) link_elm.l_next)) {
266 template<class link_map_X>
267 bool link_map_dyn<link_map_X>::load_link(Address addr)
269 return proc->ReadMem(addr, &link_elm, sizeof(link_elm));
272 static const char *deref_link(const char *path)
274 static char buffer[PATH_MAX], *p;
275 buffer[PATH_MAX-1] = '\0';
276 p = realpath(path, buffer);
282 ProcessReaderSelf::ProcessReaderSelf() :
287 ProcessReaderSelf::~ProcessReaderSelf()
291 bool ProcessReaderSelf::start() {
295 bool ProcessReaderSelf::done() {
299 bool ProcessReaderSelf::ReadMem(Address inTraced, void *inSelf, unsigned amount)
301 memcpy(inSelf, (void *) inTraced, amount);
305 bool ProcessReaderSelf::GetReg(MachRegister /*reg*/, MachRegisterVal &/*val*/)
312 vector< pair<Address, unsigned long> > *LoadedLib::getMappedRegions()
314 if (mapped_regions.size())
316 return &mapped_regions;
319 FCNode *fc = files.getNode(name, symreader_factory);
323 vector<SymRegion> regs;
324 fc->getRegions(regs);
326 for (unsigned i=0; i<regs.size(); i++) {
327 pair<Address, unsigned long> p(load_addr + regs[i].mem_addr,
329 mapped_regions.push_back(p);
332 return &mapped_regions;
335 AddressTranslate *AddressTranslate::createAddressTranslator(int pid_,
336 ProcessReader *reader_,
337 SymbolReaderFactory *symfactory_,
340 translate_printf("[%s:%u] - Creating AddressTranslateSysV\n", __FILE__, __LINE__);
341 AddressTranslate *at = new AddressTranslateSysV(pid_, reader_, symfactory_);
342 translate_printf("[%s:%u] - Created: %lx\n", __FILE__, __LINE__, (long)at);
347 else if (at->creation_error) {
354 AddressTranslate *AddressTranslate::createAddressTranslator(ProcessReader *reader_,
355 SymbolReaderFactory *factory_)
357 return createAddressTranslator(getpid(), reader_, factory_, INVALID_HANDLE_VALUE);
360 AddressTranslateSysV::AddressTranslateSysV() :
361 AddressTranslate(NULL_PID),
374 AddressTranslateSysV::AddressTranslateSysV(int pid, ProcessReader *reader_,
375 SymbolReaderFactory *reader_fact) :
376 AddressTranslate(pid),
390 reader = new ProcessReaderSelf();
392 reader = createDefaultDebugger(pid);
394 symfactory = reader_fact;
397 creation_error = true;
402 bool AddressTranslateSysV::parseDTDebug() {
403 //TODO this could possibly be used on other platforms
404 #if !defined(os_freebsd)
407 if( !setAddressSize() ) {
408 translate_printf("[%s:%u] - Failed to set address size.\n", __FILE__, __LINE__);
412 // This information is derived from the DT_DEBUG field in the
413 // executable's program headers -- however, the value needs to
414 // be read from the loaded executable image so determine the
415 // address of the DT_DEBUG field and then read it from the
418 const char *l_err = "Failed to determine trap address.";
421 if( exec_name.empty() ) {
422 translate_printf("[%s:%u] - %s\n", __FILE__, __LINE__, l_err);
426 SymReader *exe = symfactory->openSymbolReader(exec_name);
428 translate_printf("[%s:%u] - %s\n", __FILE__, __LINE__, l_err);
432 // Need to get the address of the DYNAMIC segment
433 Address dynAddress = 0;
435 unsigned numRegs = exe->numRegions();
436 for(unsigned i = 0; i < numRegs; ++i) {
438 exe->getRegion(i, reg);
440 if( PT_DYNAMIC == reg.type ) {
441 dynAddress = reg.mem_addr;
442 dynSize = reg.mem_size;
446 symfactory->closeSymbolReader(exe);
448 if( !dynAddress || !dynSize ) {
449 // This is okay for static binaries
453 if( !reader->start() ) {
454 translate_printf("[%s:%u] - %s\n", __FILE__, __LINE__, l_err);
458 // Read the DYNAMIC segment from the process
459 void *dynData = malloc(dynSize);
460 if( !dynData || !reader->ReadMem(dynAddress, dynData, dynSize) ) {
461 translate_printf("[%s:%u] - %s\n", __FILE__, __LINE__, l_err);
462 if( dynData ) free(dynData);
466 if( address_size == 8 ) {
467 Elf64_Dyn *dynDataElf = (Elf64_Dyn *)dynData;
468 for(unsigned i = 0; i < (dynSize / sizeof(Elf64_Dyn)); ++i) {
469 if( DT_DEBUG == dynDataElf[i].d_tag ) {
470 r_debug_addr = (Address) dynDataElf[i].d_un.d_ptr;
475 Elf32_Dyn *dynDataElf = (Elf32_Dyn *)dynData;
476 for(unsigned i = 0; i < (dynSize / sizeof(Elf32_Dyn)); ++i) {
477 if( DT_DEBUG == dynDataElf[i].d_tag ) {
478 r_debug_addr = (Address) dynDataElf[i].d_un.d_ptr;
485 // When a process is initializing, the DT_DEBUG value could be zero
486 // This function needs to indicate an error so the trap address can
487 // be parsed from other sources (i.e., the interpreter)
490 trap_addr = getTrapAddrFromRdebug();
495 return ( r_debug_addr != 0 );
499 bool AddressTranslateSysV::parseInterpreter() {
502 result = setInterpreter();
504 translate_printf("[%s:%u] - Failed to set interpreter.\n", __FILE__, __LINE__);
508 result = setAddressSize();
510 translate_printf("[%s:%u] - Failed to set address size.\n", __FILE__, __LINE__);
514 result = setInterpreterBase();
516 translate_printf("[%s:%u] - Failed to set interpreter base.\n", __FILE__, __LINE__);
521 if( interpreter->get_r_debug() ) {
522 r_debug_addr = interpreter->get_r_debug() + interpreter_base;
523 trap_addr = getTrapAddrFromRdebug();
526 trap_addr = interpreter->get_r_trap() + interpreter_base;
536 bool AddressTranslateSysV::init() {
537 translate_printf("[%s:%u] - Initing AddressTranslateSysV\n", __FILE__, __LINE__);
539 // Try to use DT_DEBUG first, falling back to parsing the interpreter binary if possible
540 if( !parseDTDebug() ) {
541 if( !parseInterpreter() ) {
542 translate_printf("[%s:%u] - Failed to determine r_debug address\n",
548 translate_printf("[%s:%u] - trap_addr = 0x%x, r_debug_addr = 0x%x\n", __FILE__, __LINE__, trap_addr, r_debug_addr);
549 translate_printf("[%s:%u] - Done with AddressTranslateSysV::init()\n", __FILE__, __LINE__);
554 LoadedLib *AddressTranslateSysV::getLoadedLibByNameAddr(Address addr, std::string name)
556 std::pair<Address, std::string> p(addr, name);
557 sorted_libs_t::iterator i = sorted_libs.find(p);
558 LoadedLib *ll = NULL;
559 if (i != sorted_libs.end()) {
563 ll = new LoadedLib(name, addr);
564 ll->setFactory(symfactory);
568 ll->setShouldClean(false);
572 Address AddressTranslateSysV::getTrapAddrFromRdebug() {
574 assert( r_debug_addr && address_size );
576 if( address_size == sizeof(void *) ) {
577 r_debug_dyn<r_debug> *r_debug_native = new r_debug_dyn<r_debug>(reader, r_debug_addr);
578 if( !r_debug_native ) {
579 translate_printf("[%s:%u] - Failed to parse r_debug struct.\n", __FILE__, __LINE__);
582 retVal = (Address) r_debug_native->r_brk();
583 delete r_debug_native;
585 r_debug_dyn<r_debug_dyn32> *r_debug_32 = new r_debug_dyn<r_debug_dyn32>(reader, r_debug_addr);
587 translate_printf("[%s:%u] - Failed to parse r_debug struct.\n", __FILE__, __LINE__);
590 retVal = (Address) r_debug_32->r_brk();
597 bool AddressTranslateSysV::refresh()
599 link_map_xplat *link_elm = NULL;
600 r_debug_dyn<r_debug_dyn32> *r_debug_32 = NULL;
601 r_debug_dyn<r_debug> *r_debug_native = NULL;
602 map_entries *maps = NULL;
604 size_t loaded_lib_count = 0;
606 translate_printf("[%s:%u] - Refreshing Libraries\n", __FILE__, __LINE__);
611 // On systems that use DT_DEBUG to determine r_debug_addr, DT_DEBUG might
612 // not be set right away -- read DT_DEBUG now and see if it is set
613 if( !parseDTDebug() && !interpreter ) {
614 translate_printf("[%s:%u] - Working with static binary, no libraries to refresh\n",
625 std::vector<LoadedLib *>::iterator i;
626 for (i = libs.begin(); i != libs.end(); i++)
627 (*i)->setShouldClean(true);
633 exec->setShouldClean(false);
634 libs.push_back(exec);
637 if( !reader->start() ) {
638 translate_printf("[%s:%u] - Failed to refresh libraries\n", __FILE__, __LINE__);
642 translate_printf("[%s:%u] - Starting refresh.\n", __FILE__, __LINE__);
643 translate_printf("[%s:%u] - trap_addr: %lx\n", __FILE__, __LINE__, trap_addr);
644 translate_printf("[%s:%u] - r_debug_addr: %lx\n", __FILE__, __LINE__, r_debug_addr);
646 if (address_size == sizeof(void*)) {
647 r_debug_native = new r_debug_dyn<r_debug>(reader, r_debug_addr);
648 if (!r_debug_native) {
651 } else if (!r_debug_native->is_valid()) {
653 libs.push_back(getLoadedLibByNameAddr(interpreter_base,
654 interpreter->getFilename()));
659 link_elm = new link_map_dyn<link_map>(reader, r_debug_native->r_map());
660 }else{ //64-bit mutator, 32-bit mutatee
661 r_debug_32 = new r_debug_dyn<r_debug_dyn32>(reader, r_debug_addr);
665 } else if (!r_debug_32->is_valid()) {
667 libs.push_back(getLoadedLibByNameAddr(interpreter_base,
668 interpreter->getFilename()));
673 link_elm = new link_map_dyn<link_map_dyn32>(reader, r_debug_32->r_map());
676 if (!link_elm->is_valid()) {
682 if (!link_elm->l_name())
684 string obj_name(link_elm->l_name());
686 // Don't re-add the executable, it has already been added
687 if( getExecName() == string(deref_link(obj_name.c_str())) )
690 Address text = (Address) link_elm->l_addr();
691 if (obj_name == "" && !text)
693 if (!link_elm->is_valid())
696 #if defined(os_linux)
698 if (obj_name == "") { //Augment using maps
700 maps = getLinuxMaps(pid, maps_size);
701 for (unsigned i=0; maps && i<maps_size; i++) {
702 if (text == maps[i].start) {
703 obj_name = maps[i].path;
708 if (obj_name.c_str()[0] == '[')
712 string s(deref_link(obj_name.c_str()));
713 LoadedLib *ll = getLoadedLibByNameAddr(text, s);
715 translate_printf("[%s:%u] - New Loaded Library: %s(%lx)\n", __FILE__, __LINE__, s.c_str(), text);
718 } while (link_elm->load_next());
720 translate_printf("[%s:%u] - Found %d libraries.\n", __FILE__, __LINE__, loaded_lib_count);
726 //Erase old elements from the sorted_libs
728 for (vector<LoadedLib *>::iterator i = libs.begin(); i != libs.end(); i++)
731 sorted_libs[pair<Address, string>(ll->getCodeLoadAddr(), ll->getName())] = ll;
739 delete r_debug_native;
746 FCNode::FCNode(string f, dev_t d, ino_t i, SymbolReaderFactory *factory_) :
751 is_interpreter(false),
757 filename = deref_link(f.c_str());
760 string FCNode::getFilename() {
764 string FCNode::getInterpreter() {
767 return interpreter_name;
770 void FCNode::getRegions(vector<SymRegion> ®s) {
776 unsigned FCNode::getAddrSize() {
782 Offset FCNode::get_r_debug() {
785 return r_debug_offset;
788 Offset FCNode::get_r_trap() {
791 return r_trap_offset;
794 void FCNode::markInterpreter() {
798 assert(!parsed_file);
799 is_interpreter = true;
802 #define NUM_DBG_BREAK_NAMES 3
803 const char *dbg_break_names[] = { "_dl_debug_state",
807 void FCNode::parsefile()
809 if (parsed_file || parse_error)
814 symreader = factory->openSymbolReader(filename);
817 translate_printf("[%s:%u] - Failed to open %s\n", __FILE__, __LINE__,
822 if (is_interpreter) {
823 #if !defined(os_freebsd)
824 //We're parsing the interpreter, don't confuse this with
825 // parsing the interpreter link info (which happens below).
826 Symbol_t r_debug_sym = symreader->getSymbolByName(R_DEBUG_NAME);
827 if (!symreader->isValidSymbol(r_debug_sym)) {
828 translate_printf("[%s:%u] - Failed to find r_debug symbol in %s\n",
829 __FILE__, __LINE__, filename.c_str());
832 r_debug_offset = symreader->getSymbolOffset(r_debug_sym);
835 for(unsigned i = 0; i < NUM_DBG_BREAK_NAMES; ++i) {
836 Symbol_t r_trap_sym = symreader->getSymbolByName(dbg_break_names[i]);
837 if( symreader->isValidSymbol(r_trap_sym) ) {
838 r_trap_offset = symreader->getSymbolOffset(r_trap_sym);
843 if( !r_trap_offset ) {
844 translate_printf("[%s:%u] - Failed to find debugging trap symbol in %s\n",
845 __FILE__, __LINE__, filename.c_str());
851 addr_size = symreader->getAddressWidth();
852 interpreter_name = symreader->getInterpreterName();
854 unsigned num_regions = symreader->numRegions();
855 for (unsigned i=0; i<num_regions; i++) {
857 bool result = symreader->getRegion(i, sr);
859 translate_printf("[%s:%u] - Failed to get region info\n",
865 regions.push_back(sr);
867 /*factory->closeSymbolReader(symreader);
871 FCNode *FileCache::getNode(const string &filename, SymbolReaderFactory *factory)
874 int result = stat(filename.c_str(), &buf);
877 if (!filename.length())
880 for (unsigned i=0; i<nodes.size(); i++)
882 if (nodes[i]->inode == buf.st_ino &&
883 nodes[i]->device == buf.st_dev)
889 FCNode *fc = new FCNode(filename, buf.st_dev, buf.st_ino, factory);
895 FileCache::FileCache()
899 Address AddressTranslateSysV::getLibraryTrapAddrSysV() {