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