Compile fix after removing deprecated SymtabAPI methods.
[dyninst.git] / symtabAPI / src / Region.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #include "Region.h"
32 #include "Symtab.h"
33 #include "common/h/serialize.h"
34 #include <iostream>
35
36 using namespace Dyninst;
37 using namespace Dyninst::SymtabAPI;
38 using namespace std;
39
40
41 Region *Region::createRegion( Offset diskOff, perm_t perms, RegionType regType,
42                               unsigned long diskSize, Offset memOff, 
43                               unsigned long memSize, std::string name, 
44                               char *rawDataPtr, bool isLoadable, bool isTLS,
45                               unsigned long memAlign)
46 {
47    Region *newreg = new Region(0, name, diskOff, 
48                                diskSize, memOff, memSize, 
49                                rawDataPtr, perms, regType, isLoadable, isTLS,
50                                memAlign);
51    return newreg;
52 }
53
54 Region::Region(): rawDataPtr_(NULL), buffer_(NULL)
55 {
56 }
57
58 Region::Region(unsigned regnum, std::string name, Offset diskOff,
59                     unsigned long diskSize, Offset memOff, unsigned long memSize,
60                     char *rawDataPtr, perm_t perms, RegionType regType, bool isLoadable,
61                     bool isThreadLocal, unsigned long memAlignment) :
62     regNum_(regnum), name_(name), diskOff_(diskOff), diskSize_(diskSize), memOff_(memOff),
63     memSize_(memSize), rawDataPtr_(rawDataPtr), permissions_(perms), rType_(regType),
64     isDirty_(false), buffer_(NULL), isLoadable_(isLoadable), isTLS_(isThreadLocal),
65     memAlign_(memAlignment)
66 {
67    if (memOff)
68       isLoadable_ = true;
69 }
70
71 Region::Region(const Region &reg) :
72 #if !defined(SERIALIZATION_DISABLED)
73    Serializable(),
74 #endif
75    regNum_(reg.regNum_), name_(reg.name_),
76    diskOff_(reg.diskOff_), diskSize_(reg.diskSize_), memOff_(reg.memOff_),
77    memSize_(reg.memSize_), rawDataPtr_(reg.rawDataPtr_), permissions_(reg.permissions_),
78    rType_(reg.rType_), isDirty_(reg.isDirty_), rels_(reg.rels_), buffer_(reg.buffer_),
79    isLoadable_(reg.isLoadable_), isTLS_(reg.isTLS_), memAlign_(reg.memAlign_)
80 {
81 }
82
83 Region& Region::operator=(const Region &reg)
84 {
85     regNum_ = reg.regNum_;
86     name_ = reg.name_;
87     diskOff_ = reg.diskOff_;
88     diskSize_ = reg.diskSize_;
89     memOff_ = reg.memOff_;
90     memSize_ = reg.memSize_;
91     rawDataPtr_ = reg.rawDataPtr_;
92     permissions_ = reg.permissions_;
93     rType_ = reg.rType_;
94     isDirty_ = reg.isDirty_;
95     rels_ = reg.rels_;
96     buffer_ = reg.buffer_;
97     isLoadable_ = reg.isLoadable_;
98     isTLS_ = reg.isTLS_;
99     memAlign_ = reg.memAlign_;
100
101     return *this;
102 }
103
104 bool Region::operator==(const Region &reg)
105 {
106             //(rawDataPtr_ == reg.rawDataPtr_) &&
107             //(buffer_ == reg.buffer_));
108
109         if (rels_.size() != reg.rels_.size()) return false;
110
111         for (unsigned int i = 0; i < rels_.size(); ++i)
112         {
113                 if (!(rels_[i]== reg.rels_[i])) return false;
114         }
115
116     return ((regNum_== reg.regNum_) &&
117             (name_ == reg.name_) &&
118             (diskOff_ == reg.diskOff_) &&
119             (diskSize_ == reg.diskSize_) &&
120             (memOff_ == reg.memOff_) &&
121             (memSize_ == reg.memSize_) &&
122             (permissions_ == reg.permissions_) &&
123             (rType_ == reg.rType_) &&
124             (isDirty_ == reg.isDirty_) &&
125             (isLoadable_ == reg.isLoadable_) &&
126             (isTLS_ == reg.isTLS_) &&
127             (memAlign_ == reg.memAlign_));
128 }
129
130 ostream& Region::operator<< (ostream &os)
131 {
132     return os   << "{"
133                 << " Region Number="      << regNum_
134                 << " name="    << name_
135                 << " disk offset="    << diskOff_
136                 << " disk size="    << diskSize_
137                 << " memory offset="    << memOff_
138                 << " memory size="    << memSize_
139                 << " Permissions=" << permissions_
140                         << " region type " << rType_
141                 << " }" << endl;
142 }
143
144 Region::~Region() 
145 {
146     if (buffer_)
147         free(buffer_);
148 }
149
150 const char *Region::permissions2Str(perm_t p)
151 {
152    switch(p) 
153    {
154       CASE_RETURN_STR(RP_R);
155       CASE_RETURN_STR(RP_RW);
156       CASE_RETURN_STR(RP_RX);
157       CASE_RETURN_STR(RP_RWX);
158    };
159    return "bad_permissions";
160 }
161
162 const char *Region::regionType2Str(RegionType rt)
163 {
164    switch(rt) 
165    {
166       CASE_RETURN_STR(RT_TEXT);
167       CASE_RETURN_STR(RT_DATA);
168       CASE_RETURN_STR(RT_TEXTDATA);
169       CASE_RETURN_STR(RT_SYMTAB);
170       CASE_RETURN_STR(RT_STRTAB);
171       CASE_RETURN_STR(RT_BSS);
172       CASE_RETURN_STR(RT_SYMVERSIONS);
173       CASE_RETURN_STR(RT_SYMVERDEF);
174       CASE_RETURN_STR(RT_SYMVERNEEDED);
175       CASE_RETURN_STR(RT_REL);
176       CASE_RETURN_STR(RT_RELA);
177       CASE_RETURN_STR(RT_PLTREL);
178       CASE_RETURN_STR(RT_PLTRELA);
179       CASE_RETURN_STR(RT_DYNAMIC);
180       CASE_RETURN_STR(RT_HASH);
181       CASE_RETURN_STR(RT_GNU_HASH);
182       CASE_RETURN_STR(RT_OTHER);
183       CASE_RETURN_STR(RT_INVALID);
184    };
185    return "bad_RegionTypeype";
186 };
187
188 #if !defined(SERIALIZATION_DISABLED)
189 Serializable * Region::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
190 {
191    ifxml_start_element(sb, tag);
192    gtranslate(sb, regNum_, "RegionNumber");
193    gtranslate(sb, name_, "RegionName");
194    gtranslate(sb, diskOff_, "DiskOffset");
195    gtranslate(sb, diskSize_, "RegionDiskSize");
196    gtranslate(sb, memOff_, "MemoryOffset");
197    gtranslate(sb, memSize_, "RegionMemorySize");
198    gtranslate(sb, permissions_, permissions2Str, "Permissions");
199    gtranslate(sb, rType_, regionType2Str, "RegionType");
200    gtranslate(sb, isDirty_, "Dirty");
201    gtranslate(sb, rels_, "Relocations", "Relocation");
202    gtranslate(sb, isLoadable_, "isLoadable");
203    gtranslate(sb, isTLS_, "isTLS");
204    gtranslate(sb, memAlign_, "memAlign");
205    ifxml_end_element(sb, tag);
206    if (sb->isInput())
207    {
208            //  Might need to put in checks in region-using code for these
209            //  conditions -- i.e. re-initialize elf, or whatever else for
210            //  other platforms
211            buffer_ = NULL;
212            rawDataPtr_ = NULL;
213    }
214    return NULL;
215 }
216 #else
217 Serializable *Region::serialize_impl(SerializerBase *, const char *) THROW_SPEC (SerializerError)
218 {
219    return NULL;
220 }
221 #endif
222
223 unsigned Region::getRegionNumber() const
224 {
225     return regNum_;
226 }
227
228 bool Region::setRegionNumber(unsigned regnumber)
229 {
230     regNum_ = regnumber;
231     return true;
232 }
233
234 std::string Region::getRegionName() const
235 {
236     return name_;
237 }
238
239 Offset Region::getDiskOffset() const
240 {
241     return diskOff_;
242 }
243
244 unsigned long Region::getDiskSize() const
245 {
246     return diskSize_;
247 }
248
249 unsigned long Region::getFileOffset()
250 {
251     return fileOff_;
252 }
253
254 Offset Region::getMemOffset() const
255 {
256     return memOff_;
257 }
258
259 unsigned long Region::getMemSize() const
260 {
261     return memSize_;
262 }
263
264 unsigned long Region::getMemAlignment() const
265 {
266     return memAlign_;
267 }
268
269 void Region::setMemOffset(Offset newoff)
270 {
271     memOff_ = newoff;
272 }
273
274 void Region::setFileOffset(Offset newoff)
275 {
276     fileOff_ = newoff;
277 }
278
279 void Region::setMemSize(unsigned long newsize)
280 {
281     memSize_ = newsize;
282 }
283
284 void Region::setDiskSize(unsigned long newsize)
285 {
286     diskSize_ = newsize;
287 }
288
289 void *Region::getPtrToRawData() const
290 {
291     return rawDataPtr_;
292 }
293
294 bool Region::setPtrToRawData(void *buf, unsigned long newsize)
295 {
296    rawDataPtr_ = buf;
297     diskSize_ = newsize;
298     isDirty_ = true;
299     return true;
300 }
301
302 bool Region::isBSS() const 
303 {
304     return rType_==RT_BSS;
305 }
306
307 bool Region::isText() const
308 {
309     return rType_==RT_TEXT;
310 }
311
312 bool Region::isData() const
313 {
314     return rType_ == RT_DATA;
315 }
316
317 bool Region::isTLS() const
318 {
319     return isTLS_;
320 }
321
322 bool Region::isOffsetInRegion(const Offset &offset) const 
323 {
324     return (offset >= diskOff_ && offset<(diskOff_+diskSize_));
325 }
326
327 bool Region::isLoadable() const
328 {
329     if (isLoadable_)
330         return true;
331     return (memOff_ != 0);
332 }
333
334 bool Region::isDirty() const
335 {
336     return isDirty_;
337 }
338
339 std::vector<relocationEntry> &Region::getRelocations()
340 {
341     return rels_;
342 }
343
344 bool Region::patchData(Offset off, void *buf, unsigned size)
345 {
346     if (off+size > diskSize_)
347         return false;
348
349     if (!buffer_) {
350         buffer_ = (char *)malloc(diskSize_*sizeof(char));
351         memcpy(buffer_, rawDataPtr_, diskSize_);
352     }
353
354     memcpy(&buffer_[off], buf, size);
355
356     return setPtrToRawData(buffer_, diskSize_);
357 }
358
359 bool Region::addRelocationEntry(Offset ra, Symbol *dynref, unsigned long relType, 
360       Region::RegionType rtype)
361 {
362     rels_.push_back(relocationEntry(ra, dynref->getMangledName(), dynref, relType, rtype));
363     return true;
364 }
365
366 bool Region::addRelocationEntry(const relocationEntry& rel) {
367     rels_.push_back(rel);
368     return true;
369 }
370
371 Region::perm_t Region::getRegionPermissions() const 
372 {
373     return permissions_;
374 }
375
376
377 bool Region::setRegionPermissions(Region::perm_t newPerms)
378 {
379     permissions_ = newPerms;
380     return true;
381 }
382
383 Region::RegionType Region::getRegionType() const 
384 {
385     return rType_;
386 }
387
388 bool Region::updateRelocations(Address start,
389                                Address end,
390                                Symbol *oldsym,
391                                Symbol *newsym) {
392    
393    for (unsigned i = 0; i < rels_.size(); ++i) {
394       // If the relocation entry matches, update the symbol. We
395       // have an address range and an old symbol...
396       relocationEntry &e = rels_[i];
397       if (e.getDynSym()->getMangledName() != oldsym->getMangledName()) {
398          continue;
399       }
400       if (e.rel_addr() < start) {
401          continue;
402       }
403       if (e.rel_addr() > end) {
404          continue;
405       }
406       e.addDynSym(newsym);
407    }
408    return true;
409 }
410