windows build fixes and some more work on symtab serialization
[dyninst.git] / symtabAPI / src / Region.C
1 /*
2  * Copyright (c) 1996-2007 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 * 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(): rawDataPtr_(NULL), buffer_(NULL)
42 {
43 }
44
45 Region::Region(unsigned regnum, std::string name, Offset diskOff,
46                     unsigned long diskSize, Offset memOff, unsigned long memSize,
47                     char *rawDataPtr, perm_t perms, RegionType regType, bool isLoadable):
48     regNum_(regnum), name_(name), diskOff_(diskOff), diskSize_(diskSize), memOff_(memOff),
49     memSize_(memSize), rawDataPtr_(rawDataPtr), permissions_(perms), rType_(regType),
50     isDirty_(false), buffer_(NULL), isLoadable_(isLoadable)
51 {
52    if (memOff)
53       isLoadable_ = true;
54 }
55
56 Region::Region(const Region &reg) :
57    Serializable(),
58    regNum_(reg.regNum_), name_(reg.name_),
59    diskOff_(reg.diskOff_), diskSize_(reg.diskSize_), memOff_(reg.memOff_),
60    memSize_(reg.memSize_), rawDataPtr_(reg.rawDataPtr_), permissions_(reg.permissions_),
61    rType_(reg.rType_), isDirty_(reg.isDirty_), rels_(reg.rels_), buffer_(reg.buffer_)
62 {
63 }
64
65 Region& Region::operator=(const Region &reg)
66 {
67     regNum_ = reg.regNum_;
68     name_ = reg.name_;
69     diskOff_ = reg.diskOff_;
70     diskSize_ = reg.diskSize_;
71     memOff_ = reg.memOff_;
72     memSize_ = reg.memSize_;
73     rawDataPtr_ = reg.rawDataPtr_;
74     permissions_ = reg.permissions_;
75     rType_ = reg.rType_;
76     isDirty_ = reg.isDirty_;
77     rels_ = reg.rels_;
78     buffer_ = reg.buffer_;
79
80     return *this;
81 }
82
83 bool Region::operator==(const Region &reg)
84 {
85     return ((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             (buffer_ == reg.buffer_));
96 }
97
98 ostream& Region::operator<< (ostream &os)
99 {
100     return os   << "{"
101                 << " Region Number="      << regNum_
102                 << " name="    << name_
103                 << " disk offset="    << diskOff_
104                 << " disk size="    << diskSize_
105                 << " memory offset="    << memOff_
106                 << " memory size="    << memSize_
107                 << " Permissions=" << permissions_
108                         << " region type " << rType_
109                 << " }" << endl;
110 }
111
112 Region::~Region() 
113 {
114     if (buffer_)
115         free(buffer_);
116 }
117
118 const char *Region::permissions2Str(perm_t p)
119 {
120    switch(p) 
121    {
122       CASE_RETURN_STR(RP_R);
123       CASE_RETURN_STR(RP_RW);
124       CASE_RETURN_STR(RP_RX);
125       CASE_RETURN_STR(RP_RWX);
126    };
127    return "bad_permissions";
128 }
129
130 const char *Region::regionType2Str(RegionType rt)
131 {
132    switch(rt) 
133    {
134       CASE_RETURN_STR(RT_TEXT);
135       CASE_RETURN_STR(RT_DATA);
136       CASE_RETURN_STR(RT_TEXTDATA);
137       CASE_RETURN_STR(RT_SYMTAB);
138       CASE_RETURN_STR(RT_STRTAB);
139       CASE_RETURN_STR(RT_BSS);
140       CASE_RETURN_STR(RT_SYMVERSIONS);
141       CASE_RETURN_STR(RT_SYMVERDEF);
142       CASE_RETURN_STR(RT_SYMVERNEEDED);
143       CASE_RETURN_STR(RT_REL);
144       CASE_RETURN_STR(RT_RELA);
145       CASE_RETURN_STR(RT_DYNAMIC);
146       CASE_RETURN_STR(RT_HASH);
147       CASE_RETURN_STR(RT_OTHER);
148    };
149    return "bad_RegionTypeype";
150 };
151
152 void Region::serialize(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
153 {
154    ifxml_start_element(sb, tag);
155    gtranslate(sb, regNum_, "RegionNumber");
156    gtranslate(sb, name_, "RegionName");
157    gtranslate(sb, diskOff_, "DiskOffset");
158    gtranslate(sb, diskSize_, "RegionDiskSize");
159    gtranslate(sb, memOff_, "MemoryOffset");
160    gtranslate(sb, memSize_, "RegionMemorySize");
161    gtranslate(sb, permissions_, permissions2Str, "Permissions");
162    gtranslate(sb, rType_, regionType2Str, "RegionType");
163    gtranslate(sb, isDirty_, "Dirty");
164    gtranslate(sb, rels_, "Relocations", "Relocation");
165    gtranslate(sb, buffer_, "Buffer");
166    gtranslate(sb, isLoadable_, "isLoadable");
167    ifxml_end_element(sb, tag);
168 }
169
170 unsigned Region::getRegionNumber() const
171 {
172     return regNum_;
173 }
174
175 bool Region::setRegionNumber(unsigned regnumber)
176 {
177     regNum_ = regnumber;
178     return true;
179 }
180
181 std::string Region::getRegionName() const
182 {
183     return name_;
184 }
185
186 Offset Region::getRegionAddr() const
187 {
188 #if defined(_MSC_VER)
189         return memOff_;
190 #else
191         return diskOff_;
192 #endif
193 }
194
195 Offset Region::getRegionSize() const
196 {
197 #if defined(_MSC_VER)
198         return memSize_;
199 #else
200         return diskSize_;
201 #endif
202 }
203
204 Offset Region::getDiskOffset() const
205 {
206     return diskOff_;
207 }
208
209 unsigned long Region::getDiskSize() const
210 {
211     return diskSize_;
212 }
213
214 Offset Region::getMemOffset() const
215 {
216     return memOff_;
217 }
218
219 unsigned long Region::getMemSize() const
220 {
221     return memSize_;
222 }
223
224 void *Region::getPtrToRawData() const
225 {
226     return rawDataPtr_;
227 }
228
229 bool Region::setPtrToRawData(void *buf, unsigned long newsize)
230 {
231     rawDataPtr_ = buf;
232     diskSize_ = newsize;
233     isDirty_ = true;
234     return true;
235 }
236
237 bool Region::isBSS() const 
238 {
239     return rType_==RT_BSS;
240 }
241
242 bool Region::isText() const
243 {
244     return rType_==RT_TEXT;
245 }
246
247 bool Region::isData() const
248 {
249     return rType_ == RT_DATA;
250 }
251
252 bool Region::isOffsetInRegion(const Offset &offset) const 
253 {
254     return (offset >= diskOff_ && offset<=(diskOff_+diskSize_));
255 }
256
257 bool Region::isLoadable() const
258 {
259     if (isLoadable_)
260         return true;
261     return (memOff_ != 0);
262 }
263
264 bool Region::isDirty() const
265 {
266     return isDirty_;
267 }
268
269 std::vector<relocationEntry> &Region::getRelocations()
270 {
271     return rels_;
272 }
273
274 bool Region::patchData(Offset off, void *buf, unsigned size)
275 {
276     if (off+size > diskSize_)
277         return false;
278
279     if (!buffer_)
280         memcpy(buffer_, rawDataPtr_, diskSize_);
281
282     memcpy((char *)buffer_+off, buf, size);
283
284     return setPtrToRawData(buffer_, diskSize_);
285 }
286
287 bool Region::addRelocationEntry(Offset ra, Symbol *dynref, unsigned long relType, 
288       Region::RegionType rtype)
289 {
290     rels_.push_back(relocationEntry(ra, dynref->getPrettyName(), dynref, relType, rtype));
291     return true;
292 }
293
294 Region::perm_t Region::getRegionPermissions() const 
295 {
296     return permissions_;
297 }
298
299
300 bool Region::setRegionPermissions(Region::perm_t newPerms)
301 {
302     permissions_ = newPerms;
303     return true;
304 }
305
306 Region::RegionType Region::getRegionType() const 
307 {
308     return rType_;
309 }
310