SymtabReader.C

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 #include "symtabAPI/h/SymtabReader.h"
00032 #include "symtabAPI/h/Symtab.h"
00033 #include "symtabAPI/h/Symbol.h"
00034 #include "symtabAPI/h/Function.h"
00035 
00036 #include "symtabAPI/src/Object.h"
00037 #include <queue>
00038 #include <iostream>
00039 using namespace std;
00040 
00041 #include <sstream>
00042 using std::stringstream;
00043 
00044 using namespace Dyninst;
00045 using namespace SymtabAPI;
00046 
00047 SymtabReader::SymtabReader(std::string file_) :
00048    symtab(NULL),
00049    ref_count(1),
00050    ownsSymtab(true)
00051 {
00052   // We'd throw, but...
00053   (void)Symtab::openFile(symtab, file_);
00054 }
00055 
00056 SymtabReader::SymtabReader(const char *buffer, unsigned long size) :
00057    symtab(NULL),
00058    ref_count(1),
00059    ownsSymtab(true)
00060 {
00061    stringstream memName;
00062    memName << "memory_" << (unsigned long)(buffer) << "_" << size;
00063    Symtab::openFile(symtab, const_cast<char *>(buffer), 
00064                     size, memName.str());
00065 }
00066 
00067 SymtabReader::SymtabReader(Symtab *s) :
00068     symtab(s),
00069     ref_count(1),
00070     ownsSymtab(false)
00071 {}
00072 
00073 SymtabReader::~SymtabReader()
00074 {
00075    if (symtab && ownsSymtab)
00076       Symtab::closeSymtab(symtab);
00077    symtab = NULL;
00078 }
00079 
00080 
00081 #define DEFN_SYMBOL_T(name) Symbol_t name; name.v1 = name.v2 = NULL; name.i1 = name.i2 = 0
00082 
00083 Symbol_t SymtabReader::getSymbolByName(std::string symname)
00084 {
00085    assert(symtab);
00086    DEFN_SYMBOL_T(ret);
00087 
00088    std::vector<Symbol *> syms;
00089    bool result = symtab->findSymbol(syms, symname);
00090    if (!result || syms.empty()) {
00091       return ret;
00092    }
00093 
00094    ret.v1 = symtab;
00095    ret.v2 = syms[0];
00096    return ret;
00097 }
00098 
00099 Symbol_t SymtabReader::getContainingSymbol(Dyninst::Offset offset)
00100 {
00101    assert(symtab);
00102    DEFN_SYMBOL_T(ret);
00103 
00104    Function *f = NULL;
00105    bool result = symtab->getContainingFunction(offset, f);
00106    if (!result || !f) {
00107       return ret;
00108    }
00109 
00110    ret.v1 = symtab;
00111    ret.v2 = f->getFirstSymbol();
00112    return ret;
00113 }
00114 
00115 std::string SymtabReader::getInterpreterName()
00116 {
00117    assert(symtab);
00118    const char *interp = NULL;
00119    interp = symtab->getInterpreterName();
00120 
00121    if (!interp)
00122       return std::string();
00123    return std::string(interp);
00124 }
00125 
00126 unsigned SymtabReader::getAddressWidth()
00127 {
00128    assert(symtab);
00129    return symtab->getAddressWidth();
00130 }
00131    
00132 unsigned SymtabReader::numSegments()
00133 {
00134    buildSegments();
00135    return segments.size();
00136 }
00137 
00138 bool SymtabReader::getSegment(unsigned num, SymSegment &seg)
00139 {
00140    buildSegments();
00141    if (num >= segments.size()) return false;
00142    seg = segments[num];
00143 
00144    return true;
00145 }
00146 
00147 void SymtabReader::buildSegments() {
00148    if (!segments.empty()) return;
00149 
00150    // We want ELF segments; contiguous areas of the 
00151    // binary loaded into memory. 
00152    symtab->getSegmentsSymReader(segments);
00153 }
00154 
00155 
00156 Dyninst::Offset SymtabReader::getSymbolOffset(const Symbol_t &sym)
00157 {
00158    assert(sym.v2);
00159    Symbol *symbol = (Symbol *) sym.v2;
00160    return symbol->getOffset();
00161 }
00162 
00163 Dyninst::Offset SymtabReader::getSymbolTOC(const Symbol_t &sym)
00164 {
00165    assert(sym.v2);
00166    Symbol *symbol = (Symbol *) sym.v2;
00167    return symbol->getSymtab()->getTOCoffset(symbol->getOffset());
00168 }
00169 
00170 std::string SymtabReader::getSymbolName(const Symbol_t &sym)
00171 {
00172    assert(sym.v2);
00173    Symbol *symbol = (Symbol *) sym.v2;
00174    return symbol->getMangledName();
00175 }
00176 
00177 std::string SymtabReader::getDemangledName(const Symbol_t &sym) {
00178    assert(sym.v2);
00179    Symbol *symbol = (Symbol *) sym.v2;
00180    return symbol->getTypedName();
00181 }
00182 
00183 unsigned long SymtabReader::getSymbolSize(const Symbol_t &sym)
00184 {
00185    assert(sym.v2);
00186    Symbol *symbol = (Symbol *) sym.v2;
00187    return symbol->getSize();
00188 }
00189 
00190 bool SymtabReader::isValidSymbol(const Symbol_t &sym)
00191 {
00192    return (sym.v1 != NULL) && (sym.v2 != NULL);
00193 }
00194 
00195 Dyninst::Offset SymtabReader::imageOffset()
00196 {
00197    return symtab->imageOffset();
00198 }
00199 
00200 Dyninst::Offset SymtabReader::dataOffset()
00201 {
00202    return symtab->dataOffset();
00203 }
00204 
00205 Section_t SymtabReader::getSectionByName(std::string name)
00206 {
00207    Region *region;
00208    Section_t ret;
00209    ret.v1 = NULL;
00210    bool result = symtab->findRegion(region, name);
00211    if (!result) {
00212       return ret;
00213    }
00214    ret.v1 = (void *) region;
00215    return ret;
00216 }
00217 
00218 Section_t SymtabReader::getSectionByAddress(Dyninst::Address addr)
00219 {
00220    Region *region = symtab->findEnclosingRegion(addr);
00221    Section_t ret;
00222    ret.v1 = (void *) region;
00223    return ret;
00224 }
00225 
00226 Dyninst::Address SymtabReader::getSectionAddress(Section_t sec)
00227 {
00228    Region *region = (Region *) sec.v1;
00229    assert(region);
00230    return region->getMemOffset();
00231 }
00232 
00233 std::string SymtabReader::getSectionName(Section_t sec)
00234 {
00235    Region *region = (Region *) sec.v1;
00236    assert(region);
00237    return region->getRegionName();
00238 }
00239 
00240 bool SymtabReader::isValidSection(Section_t sec)
00241 {
00242    return (sec.v1 != NULL);
00243 }
00244 
00245 void *SymtabReader::getElfHandle()
00246 {
00247 #if defined(os_solaris) || defined(os_linux) || defined(os_bg) || defined(os_freebsd) || defined(os_vxworks)
00248    Object *obj = symtab->getObject();
00249    return obj->getElfHandle();
00250 #else
00251    return NULL;
00252 #endif
00253 }
00254 
00255 SymtabReaderFactory::SymtabReaderFactory()
00256 {
00257 }
00258 
00259 SymtabReaderFactory::~SymtabReaderFactory()
00260 {
00261 }
00262 
00263 SymReader *SymtabReaderFactory::openSymbolReader(std::string pathname)
00264 {
00265    std::map<std::string, SymReader *>::iterator i = open_syms.find(pathname);
00266    if (i != open_syms.end()) {
00267       SymtabReader *symtabreader = dynamic_cast<SymtabReader *>(i->second);
00268       symtabreader->ref_count++;
00269       return symtabreader;
00270    }
00271    SymtabReader *symtabreader = new SymtabReader(pathname);
00272    if (!symtabreader) { 
00273       return NULL;
00274    }
00275    open_syms[pathname] = symtabreader;
00276 
00277    return symtabreader;
00278 }
00279 
00280 SymReader *SymtabReaderFactory::openSymbolReader(const char *buffer, unsigned long size)
00281 {
00282    SymtabReader *symtabreader = new SymtabReader(buffer, size);
00283    if (!symtabreader) 
00284       return NULL;
00285    return symtabreader;
00286 }
00287 
00288 bool SymtabReaderFactory::closeSymbolReader(SymReader *sr)
00289 {
00290    SymtabReader *symreader = static_cast<SymtabReader *>(sr);
00291    assert(symreader->ref_count >= 1);
00292    symreader->ref_count--;
00293    if (symreader->ref_count == 0) {
00294      // We need to remove this from the big map, but we don't 
00295      // store the path. So crawl and look. 
00296      std::queue<std::string> toDelete;
00297      std::map<std::string, SymReader *>::iterator i;
00298      for (i = open_syms.begin(); i != open_syms.end(); ++i) {
00299        if (i->second == symreader) {
00300      toDelete.push(i->first);
00301        }
00302      }
00303      while (!toDelete.empty()) {
00304        open_syms.erase(toDelete.front());
00305        toDelete.pop();
00306      }
00307 
00308       delete symreader;
00309    }
00310    return true;
00311 }
00312 
00313 SymbolReaderFactory *Dyninst::SymtabAPI::getSymtabReaderFactory()
00314 {
00315    static SymtabReaderFactory *fact = NULL;
00316    if (!fact)
00317       fact = new SymtabReaderFactory();
00318    return static_cast<SymbolReaderFactory *>(fact);
00319 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1