addrtranslate-aix.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 "common/h/addrtranslate.h"
00032 #include "common/h/headers.h"
00033 #include "common/h/pathName.h"
00034 
00035 #include "symtabAPI/h/Symtab.h"
00036 #include "symtabAPI/h/Archive.h"
00037 
00038 #include <sys/procfs.h>
00039 #include <string.h>
00040 #include <string>
00041 #include <vector>
00042 #include <map>
00043 
00044 namespace Dyninst {
00045 
00046 class AddressTranslateAIX : public AddressTranslate
00047 {
00048 public:
00049    AddressTranslateAIX(SymbolReaderFactory *fact_);
00050    AddressTranslateAIX(PID pid, SymbolReaderFactory *fact_);
00051 
00052    virtual bool refresh();
00053    virtual ~AddressTranslateAIX();
00054    Address getLibraryTrapAddrSysV();
00055 };
00056 
00057 class LoadedLibAIX : public LoadedLib {
00058 protected:
00059    string object;
00060 
00061    mutable Address real_codeBase;
00062    mutable Address real_dataBase;
00063    mutable Address imageOffset;
00064    mutable Address dataOffset;   
00065    mutable bool reals_set;
00066    void setReals() const;
00067 public:
00068    LoadedLibAIX(string name, Address load_addr, string object);
00069    
00070    virtual ~LoadedLibAIX();
00071 
00072    virtual Address offToAddress(Offset off);
00073    virtual Offset addrToOffset(Address addr);
00074 
00075    virtual Address getCodeLoadAddr() const;
00076    virtual Address getDataLoadAddr() const;
00077    virtual void getOutputs(string &filename, Address &code, Address &data);
00078 };
00079 
00080 static int open_map_fd(PID pid)
00081 {
00082    char file[64];
00083    snprintf(file, 64, "/proc/%d/map", pid);
00084    int fd = P_open(file, O_RDONLY, pid);
00085    return fd;
00086 }
00087 
00088 bool AddressTranslateAIX::refresh()
00089 {
00090    unsigned iter = 0;
00091    bool is_aout = true;
00092    int map_fd = -1;
00093    int result;
00094    if (!pid)
00095       return true;
00096    
00097    for (unsigned i=0; i<libs.size(); i++) {
00098       if (libs[i])
00099          delete libs[i];
00100    }
00101    libs.clear();
00102    
00103    map_fd = open_map_fd(pid);
00104    if (map_fd == -1)
00105       return false;
00106 
00107    prmap_t mapEntry;
00108 
00109 #if defined(DEBUG_PRINT)
00110    for (;;) {
00111       result = pread(map_fd, &mapEntry, sizeof(prmap_t), iter * sizeof(prmap_t));
00112       if (result != sizeof(prmap_t))
00113          break;
00114       if (mapEntry.pr_size == 0)
00115          break;
00116 
00117       char buf[512];
00118       if (mapEntry.pr_pathoff) {
00119          pread(map_fd, buf, 512, mapEntry.pr_pathoff);
00120       }
00121       
00122       printf("%lu\n" 
00123              "\taddr = %llx +%llu\n"
00124              "\tmapname = %s\n"
00125              "\toffset = %llu, flags = %d\n"
00126              "\tpr_pathoff = %d (%s)\n"
00127              "\tobject = %s\n"
00128              "\talias = %llx, gp = %llx\n",
00129              iter * sizeof(prmap_t), 
00130              mapEntry.pr_vaddr, mapEntry.pr_size, 
00131              mapEntry.pr_mapname,
00132              mapEntry.pr_off, mapEntry.pr_mflags,
00133              mapEntry.pr_pathoff, mapEntry.pr_pathoff ? buf : "NONE",
00134              mapEntry.pr_pathoff ? buf + strlen(buf) + 1 : "NONE",
00135              mapEntry.pr_alias, mapEntry.pr_gp);
00136       if (mapEntry.pr_pathoff) {
00137          string filename = buf;
00138          string object_name = buf + strlen(buf) + 1;
00139          LoadedLib *ll = new LoadedLibAIX(filename, 0, object_name);
00140          Symtab *s = ll->getSymtab();
00141          printf("\timageOffset = %ld, length = %lu\n"
00142                 "\tdataOffset = %ld, length = %lu\n",
00143                 s->imageOffset(), s->imageLength(),
00144                 s->dataOffset(), s->dataLength());
00145       }
00146 
00147       printf("\n");
00148       iter++;
00149    }
00150 #endif
00151 
00152    iter = 0;
00153 
00154    for (;;) {
00155       result = pread(map_fd, &mapEntry, sizeof(prmap_t), iter * sizeof(prmap_t));
00156       if (result != sizeof(prmap_t))
00157          break;
00158       if (mapEntry.pr_size == 0)
00159          break;
00160       
00161       string filename;
00162       string object_name;
00163       if (mapEntry.pr_pathoff) {
00164          char buf[512];
00165          pread(map_fd, buf, 256, mapEntry.pr_pathoff);
00166          filename = resolve_file_path(buf);
00167          object_name = buf + strlen(buf) + 1;
00168       }
00169       else {
00170          filename = resolve_file_path(mapEntry.pr_mapname);
00171       }
00172               
00173       is_aout = false;
00174       
00175       LoadedLib *ll = new LoadedLibAIX(filename, (unsigned long)mapEntry.pr_vaddr, object_name);
00176 
00177       iter++;
00178       ll->add_mapped_region((unsigned long)mapEntry.pr_vaddr, mapEntry.pr_size);
00179       libs.push_back(ll);
00180 
00181       prmap_t next;
00182       result = pread(map_fd, &next, sizeof(prmap_t), iter * sizeof(prmap_t));
00183       if (result != sizeof(prmap_t))
00184          break;
00185       if (strcmp(mapEntry.pr_mapname, next.pr_mapname))
00186          continue;
00187 
00188       iter++;
00189       ll->add_mapped_region((unsigned long)next.pr_vaddr, next.pr_size);
00190       ll->setDataLoadAddr((unsigned long)next.pr_vaddr);
00191    }
00192    
00193    P_close(map_fd);
00194    return true;
00195 }
00196 
00197 AddressTranslate *AddressTranslate::createAddressTranslator(PID pid_, 
00198                                                             ProcessReader *,
00199                                                             SymbolReaderFactory *fact,
00200                                                             PROC_HANDLE, 
00201                                                             std::string,
00202                                                             Address)
00203 {
00204    AddressTranslate *at = new AddressTranslateAIX(pid_, fact);
00205    
00206    if (!at) {
00207       return NULL;
00208    }
00209    else if (at->creation_error) {
00210       delete at;
00211       return NULL;
00212    }
00213    return at;
00214 }
00215 
00216 AddressTranslate *AddressTranslate::createAddressTranslator(ProcessReader *, SymbolReaderFactory *fact, std::string exename, Address)
00217 {
00218    return createAddressTranslator(getpid(), NULL, fact);
00219 }
00220 
00221 AddressTranslateAIX::AddressTranslateAIX(SymbolReaderFactory *fact)
00222    : AddressTranslate(0)
00223 {
00224    symfactory = fact;
00225 }
00226    
00227 AddressTranslateAIX::AddressTranslateAIX(PID pid, SymbolReaderFactory *fact)
00228    : AddressTranslate(pid)
00229 {
00230    symfactory = fact;
00231    refresh();
00232 }
00233 
00234 AddressTranslateAIX::~AddressTranslateAIX()
00235 {
00236 }
00237 
00238 vector< pair<Address, unsigned long> > *LoadedLib::getMappedRegions()
00239 {
00240    return &mapped_regions;
00241 }
00242 
00243 LoadedLibAIX::LoadedLibAIX(string name, Address load_addr, string obj)
00244    : LoadedLib(name, load_addr),
00245      object(obj),
00246      real_codeBase(0),
00247      real_dataBase(0),
00248      imageOffset(0),
00249      dataOffset(0),
00250      reals_set(false)
00251 {
00252 }
00253 
00254 LoadedLibAIX::~LoadedLibAIX()
00255 {
00256 }
00257 
00258 void LoadedLibAIX::setReals() const
00259 {
00260    if (reals_set)
00261       return;
00262 
00263    SymReader *sreader = symreader_factory->openSymbolReader(name);
00264    imageOffset = sreader->imageOffset();
00265    dataOffset = sreader->dataOffset();
00266    real_codeBase = 0;
00267    real_dataBase = 0;
00268    /*
00269    Symtab *sym = getSymtab();
00270    if (!sym)
00271       return;
00272 
00273    if (imageOffset > load_addr)
00274       real_codeBase = 0;
00275    else {
00276       real_codeBase = load_addr;
00277       if (imageOffset < 0x20000000)
00278          real_codeBase -= imageOffset;
00279       Region *sec;
00280       bool result = sym->findRegion(sec, ".text");
00281       if (result && sec)
00282          real_codeBase += (Address) sec->getPtrToRawData() - sym->getBaseOffset();
00283    }
00284 
00285    if (dataOffset >= data_load_addr)
00286       real_dataBase = 0;
00287    else if (dataOffset < 0x30000000) {
00288       real_dataBase = data_load_addr - dataOffset;
00289    }
00290    */
00291    reals_set = true;
00292 }
00293 
00294 Address LoadedLibAIX::offToAddress(Offset off)
00295 {
00296    setReals();
00297    
00298    Address addr = off;
00299 
00300    if ((imageOffset < dataOffset && addr >= imageOffset && addr < dataOffset) ||
00301        (imageOffset > dataOffset && addr > imageOffset))
00302    {
00303       return addr + real_codeBase;
00304    }
00305    else 
00306    {
00307       return addr + real_dataBase;
00308    }
00309 }
00310 
00311 Offset LoadedLibAIX::addrToOffset(Address addr)
00312 {
00313    setReals();
00314 
00315    if (addr >= mapped_regions[0].first && 
00316        addr < mapped_regions[0].first + mapped_regions[0].second)
00317       return addr - real_codeBase;
00318    else
00319       return addr - real_dataBase;  
00320 }
00321 
00322 Address LoadedLibAIX::getCodeLoadAddr() const
00323 {
00324    setReals();
00325    return real_codeBase;
00326 }
00327 
00328 Address LoadedLibAIX::getDataLoadAddr() const
00329 {
00330    setReals();
00331    return real_dataBase;
00332 }
00333 
00334 void LoadedLibAIX::getOutputs(string &filename, Address &code, Address &data)
00335 {
00336    if (object.length())
00337       filename = name + ":" + object;
00338    else
00339       filename = name;
00340    code = load_addr;
00341    data = data_load_addr;
00342 }
00343 
00344 Address AddressTranslateAIX::getLibraryTrapAddrSysV()
00345 {
00346    return 0x0;
00347 }
00348 
00349 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1