Region.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 "Region.h"
00032 #include "Symtab.h"
00033 #include "common/h/serialize.h"
00034 #include <iostream>
00035 
00036 using namespace Dyninst;
00037 using namespace Dyninst::SymtabAPI;
00038 using namespace std;
00039 
00040 
00041 Region *Region::createRegion( Offset diskOff, perm_t perms, RegionType regType,
00042                               unsigned long diskSize, Offset memOff, 
00043                               unsigned long memSize, std::string name, 
00044                               char *rawDataPtr, bool isLoadable, bool isTLS,
00045                               unsigned long memAlign)
00046 {
00047    Region *newreg = new Region(0, name, diskOff, 
00048                                diskSize, memOff, memSize, 
00049                                rawDataPtr, perms, regType, isLoadable, isTLS,
00050                                memAlign);
00051    return newreg;
00052 }
00053 
00054 Region::Region(): rawDataPtr_(NULL), buffer_(NULL)
00055 {
00056 }
00057 
00058 Region::Region(unsigned regnum, std::string name, Offset diskOff,
00059                     unsigned long diskSize, Offset memOff, unsigned long memSize,
00060                     char *rawDataPtr, perm_t perms, RegionType regType, bool isLoadable,
00061                     bool isThreadLocal, unsigned long memAlignment) :
00062     regNum_(regnum), name_(name), diskOff_(diskOff), diskSize_(diskSize), memOff_(memOff),
00063     memSize_(memSize), rawDataPtr_(rawDataPtr), permissions_(perms), rType_(regType),
00064     isDirty_(false), buffer_(NULL), isLoadable_(isLoadable), isTLS_(isThreadLocal),
00065     memAlign_(memAlignment)
00066 {
00067    if (memOff)
00068       isLoadable_ = true;
00069 }
00070 
00071 Region::Region(const Region &reg) :
00072 #if !defined(SERIALIZATION_DISABLED)
00073    Serializable(),
00074 #endif
00075    regNum_(reg.regNum_), name_(reg.name_),
00076    diskOff_(reg.diskOff_), diskSize_(reg.diskSize_), memOff_(reg.memOff_),
00077    memSize_(reg.memSize_), rawDataPtr_(reg.rawDataPtr_), permissions_(reg.permissions_),
00078    rType_(reg.rType_), isDirty_(reg.isDirty_), rels_(reg.rels_), buffer_(reg.buffer_),
00079    isLoadable_(reg.isLoadable_), isTLS_(reg.isTLS_), memAlign_(reg.memAlign_)
00080 {
00081 }
00082 
00083 Region& Region::operator=(const Region &reg)
00084 {
00085     regNum_ = reg.regNum_;
00086     name_ = reg.name_;
00087     diskOff_ = reg.diskOff_;
00088     diskSize_ = reg.diskSize_;
00089     memOff_ = reg.memOff_;
00090     memSize_ = reg.memSize_;
00091     rawDataPtr_ = reg.rawDataPtr_;
00092     permissions_ = reg.permissions_;
00093     rType_ = reg.rType_;
00094     isDirty_ = reg.isDirty_;
00095     rels_ = reg.rels_;
00096     buffer_ = reg.buffer_;
00097     isLoadable_ = reg.isLoadable_;
00098     isTLS_ = reg.isTLS_;
00099     memAlign_ = reg.memAlign_;
00100 
00101     return *this;
00102 }
00103 
00104 bool Region::operator==(const Region &reg)
00105 {
00106             //(rawDataPtr_ == reg.rawDataPtr_) &&
00107             //(buffer_ == reg.buffer_));
00108 
00109     if (rels_.size() != reg.rels_.size()) return false;
00110 
00111     for (unsigned int i = 0; i < rels_.size(); ++i)
00112     {
00113         if (!(rels_[i]== reg.rels_[i])) return false;
00114     }
00115 
00116     return ((regNum_== reg.regNum_) &&
00117             (name_ == reg.name_) &&
00118             (diskOff_ == reg.diskOff_) &&
00119             (diskSize_ == reg.diskSize_) &&
00120             (memOff_ == reg.memOff_) &&
00121             (memSize_ == reg.memSize_) &&
00122             (permissions_ == reg.permissions_) &&
00123             (rType_ == reg.rType_) &&
00124             (isDirty_ == reg.isDirty_) &&
00125             (isLoadable_ == reg.isLoadable_) &&
00126             (isTLS_ == reg.isTLS_) &&
00127             (memAlign_ == reg.memAlign_));
00128 }
00129 
00130 ostream& Region::operator<< (ostream &os)
00131 {
00132     return os   << "{"
00133                 << " Region Number="      << regNum_
00134                 << " name="    << name_
00135                 << " disk offset="    << diskOff_
00136                 << " disk size="    << diskSize_
00137                 << " memory offset="    << memOff_
00138                 << " memory size="    << memSize_
00139                 << " Permissions=" << permissions_
00140                         << " region type " << rType_
00141                 << " }" << endl;
00142 }
00143 
00144 Region::~Region() 
00145 {
00146     if (buffer_)
00147         free(buffer_);
00148 }
00149 
00150 const char *Region::permissions2Str(perm_t p)
00151 {
00152    switch(p) 
00153    {
00154       CASE_RETURN_STR(RP_R);
00155       CASE_RETURN_STR(RP_RW);
00156       CASE_RETURN_STR(RP_RX);
00157       CASE_RETURN_STR(RP_RWX);
00158    };
00159    return "bad_permissions";
00160 }
00161 
00162 const char *Region::regionType2Str(RegionType rt)
00163 {
00164    switch(rt) 
00165    {
00166       CASE_RETURN_STR(RT_TEXT);
00167       CASE_RETURN_STR(RT_DATA);
00168       CASE_RETURN_STR(RT_TEXTDATA);
00169       CASE_RETURN_STR(RT_SYMTAB);
00170       CASE_RETURN_STR(RT_STRTAB);
00171       CASE_RETURN_STR(RT_BSS);
00172       CASE_RETURN_STR(RT_SYMVERSIONS);
00173       CASE_RETURN_STR(RT_SYMVERDEF);
00174       CASE_RETURN_STR(RT_SYMVERNEEDED);
00175       CASE_RETURN_STR(RT_REL);
00176       CASE_RETURN_STR(RT_RELA);
00177       CASE_RETURN_STR(RT_PLTREL);
00178       CASE_RETURN_STR(RT_PLTRELA);
00179       CASE_RETURN_STR(RT_DYNAMIC);
00180       CASE_RETURN_STR(RT_HASH);
00181       CASE_RETURN_STR(RT_GNU_HASH);
00182       CASE_RETURN_STR(RT_OTHER);
00183       CASE_RETURN_STR(RT_INVALID);
00184    };
00185    return "bad_RegionTypeype";
00186 };
00187 
00188 #if !defined(SERIALIZATION_DISABLED)
00189 Serializable * Region::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
00190 {
00191    ifxml_start_element(sb, tag);
00192    gtranslate(sb, regNum_, "RegionNumber");
00193    gtranslate(sb, name_, "RegionName");
00194    gtranslate(sb, diskOff_, "DiskOffset");
00195    gtranslate(sb, diskSize_, "RegionDiskSize");
00196    gtranslate(sb, memOff_, "MemoryOffset");
00197    gtranslate(sb, memSize_, "RegionMemorySize");
00198    gtranslate(sb, permissions_, permissions2Str, "Permissions");
00199    gtranslate(sb, rType_, regionType2Str, "RegionType");
00200    gtranslate(sb, isDirty_, "Dirty");
00201    gtranslate(sb, rels_, "Relocations", "Relocation");
00202    gtranslate(sb, isLoadable_, "isLoadable");
00203    gtranslate(sb, isTLS_, "isTLS");
00204    gtranslate(sb, memAlign_, "memAlign");
00205    ifxml_end_element(sb, tag);
00206    if (sb->isInput())
00207    {
00208        //  Might need to put in checks in region-using code for these
00209        //  conditions -- i.e. re-initialize elf, or whatever else for
00210        //  other platforms
00211        buffer_ = NULL;
00212        rawDataPtr_ = NULL;
00213    }
00214    return NULL;
00215 }
00216 #else
00217 Serializable *Region::serialize_impl(SerializerBase *, const char *) THROW_SPEC (SerializerError)
00218 {
00219    return NULL;
00220 }
00221 #endif
00222 
00223 unsigned Region::getRegionNumber() const
00224 {
00225     return regNum_;
00226 }
00227 
00228 bool Region::setRegionNumber(unsigned regnumber)
00229 {
00230     regNum_ = regnumber;
00231     return true;
00232 }
00233 
00234 std::string Region::getRegionName() const
00235 {
00236     return name_;
00237 }
00238 
00239 Offset Region::getDiskOffset() const
00240 {
00241     return diskOff_;
00242 }
00243 
00244 unsigned long Region::getDiskSize() const
00245 {
00246     return diskSize_;
00247 }
00248 
00249 unsigned long Region::getFileOffset()
00250 {
00251     return fileOff_;
00252 }
00253 
00254 Offset Region::getMemOffset() const
00255 {
00256     return memOff_;
00257 }
00258 
00259 unsigned long Region::getMemSize() const
00260 {
00261     return memSize_;
00262 }
00263 
00264 unsigned long Region::getMemAlignment() const
00265 {
00266     return memAlign_;
00267 }
00268 
00269 void Region::setMemOffset(Offset newoff)
00270 {
00271     memOff_ = newoff;
00272 }
00273 
00274 void Region::setFileOffset(Offset newoff)
00275 {
00276     fileOff_ = newoff;
00277 }
00278 
00279 void Region::setMemSize(unsigned long newsize)
00280 {
00281     memSize_ = newsize;
00282 }
00283 
00284 void Region::setDiskSize(unsigned long newsize)
00285 {
00286     diskSize_ = newsize;
00287 }
00288 
00289 void *Region::getPtrToRawData() const
00290 {
00291     return rawDataPtr_;
00292 }
00293 
00294 bool Region::setPtrToRawData(void *buf, unsigned long newsize)
00295 {
00296    rawDataPtr_ = buf;
00297     diskSize_ = newsize;
00298     isDirty_ = true;
00299     return true;
00300 }
00301 
00302 bool Region::isBSS() const 
00303 {
00304     return rType_==RT_BSS;
00305 }
00306 
00307 bool Region::isText() const
00308 {
00309     return rType_==RT_TEXT;
00310 }
00311 
00312 bool Region::isData() const
00313 {
00314     return rType_ == RT_DATA;
00315 }
00316 
00317 bool Region::isTLS() const
00318 {
00319     return isTLS_;
00320 }
00321 
00322 bool Region::isOffsetInRegion(const Offset &offset) const 
00323 {
00324     return (offset >= diskOff_ && offset<(diskOff_+diskSize_));
00325 }
00326 
00327 bool Region::isLoadable() const
00328 {
00329     if (isLoadable_)
00330         return true;
00331     return (memOff_ != 0);
00332 }
00333 
00334 bool Region::isDirty() const
00335 {
00336     return isDirty_;
00337 }
00338 
00339 std::vector<relocationEntry> &Region::getRelocations()
00340 {
00341     return rels_;
00342 }
00343 
00344 bool Region::patchData(Offset off, void *buf, unsigned size)
00345 {
00346     if (off+size > diskSize_)
00347         return false;
00348 
00349     if (!buffer_) {
00350         buffer_ = (char *)malloc(diskSize_*sizeof(char));
00351         memcpy(buffer_, rawDataPtr_, diskSize_);
00352     }
00353 
00354     memcpy(&buffer_[off], buf, size);
00355 
00356     return setPtrToRawData(buffer_, diskSize_);
00357 }
00358 
00359 bool Region::addRelocationEntry(Offset ra, Symbol *dynref, unsigned long relType, 
00360       Region::RegionType rtype)
00361 {
00362     rels_.push_back(relocationEntry(ra, dynref->getMangledName(), dynref, relType, rtype));
00363     return true;
00364 }
00365 
00366 bool Region::addRelocationEntry(const relocationEntry& rel) {
00367     rels_.push_back(rel);
00368     return true;
00369 }
00370 
00371 Region::perm_t Region::getRegionPermissions() const 
00372 {
00373     return permissions_;
00374 }
00375 
00376 
00377 bool Region::setRegionPermissions(Region::perm_t newPerms)
00378 {
00379     permissions_ = newPerms;
00380     return true;
00381 }
00382 
00383 Region::RegionType Region::getRegionType() const 
00384 {
00385     return rType_;
00386 }
00387 
00388 bool Region::updateRelocations(Address start,
00389                                Address end,
00390                                Symbol *oldsym,
00391                                Symbol *newsym) {
00392    
00393    for (unsigned i = 0; i < rels_.size(); ++i) {
00394       // If the relocation entry matches, update the symbol. We
00395       // have an address range and an old symbol...
00396       relocationEntry &e = rels_[i];
00397       if (!e.getDynSym()) continue;
00398 
00399       if (e.getDynSym()->getMangledName() != oldsym->getMangledName()) {
00400          continue;
00401       }
00402       if (e.rel_addr() < start) {
00403          continue;
00404       }
00405       if (e.rel_addr() > end) {
00406          continue;
00407       }
00408       e.addDynSym(newsym);
00409    }
00410    return true;
00411 }
00412 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1