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 "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 ®) :
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 ®)
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 ®)
00105 {
00106
00107
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
00209
00210
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
00395
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