A working (but not thoroughly tested) version of the static binary rewriter
[dyninst.git] / symtabAPI / src / LinkMap.C
1 /*
2  * Copyright (c) 1996-2010 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 "LinkMap.h"
33 #include <iostream>
34
35 using namespace Dyninst;
36 using namespace SymtabAPI;
37
38 LinkMap::LinkMap() :
39     allocatedData(NULL), allocatedSize(0), commonStorage(NULL),
40     bssRegionOffset(0), bssSize(0), bssRegionAlign(0),
41     dataRegionOffset(0), dataSize(0), dataRegionAlign(0),
42     codeRegionOffset(0), codeSize(0), codeRegionAlign(0),
43     tlsRegionOffset(0), tlsSize(0), tlsRegionAlign(0),
44     gotRegionOffset(0), gotSize(0), gotRegionAlign(0),
45     ctorDtorHandler(NULL), ctorRegionOffset(0), ctorSize(0),
46     ctorRegionAlign(0), originalCtorRegion(NULL), dtorRegionOffset(0),
47     dtorSize(0), dtorRegionAlign(0), originalDtorRegion(NULL) 
48 {
49 }
50
51 LinkMap::~LinkMap() {
52     if( commonStorage ) delete commonStorage;
53 }
54
55 ostream & operator<<(ostream &os, LinkMap &lm) {
56      lm.printAll(os, 0);
57      return os;
58 }
59
60 void LinkMap::print(Offset globalOffset) {
61     printAll(std::cout, globalOffset);
62 }
63
64 void LinkMap::printAll(ostream &os, Offset globalOffset) {
65     os << "Size of allocated space = 0x" << hex << allocatedSize << dec << endl;
66
67     if( codeRegions.size() > 0 ) {
68         os << "New CODE Region: Offset: 0x" << hex << (globalOffset + codeRegionOffset) << dec
69            << " Size: 0x" << hex << codeSize << dec 
70            << " Alignment: 0x" << hex << codeRegionAlign << dec
71            << endl;
72         printRegions(os, codeRegions, globalOffset);
73         os << endl;
74     }
75
76     if( dataRegions.size() > 0 ) {
77         os << "New DATA Region: Offset: 0x" << hex << (globalOffset + dataRegionOffset) << dec
78            << " Size: 0x" << hex << dataSize << dec 
79            << " Alignment: 0x" << hex << dataRegionAlign << dec
80            << endl;
81         printRegions(os, dataRegions, globalOffset);
82         os << endl;
83     }
84
85     if( tlsRegions.size() > 0 ) {
86         os << "New TLS Region: Offset: 0x" << hex << (globalOffset + tlsRegionOffset) << dec
87            << " Size: 0x" << hex << tlsSize << dec 
88            << " Alignment: 0x" << hex << tlsRegionAlign << dec
89            << endl;
90         printRegions(os, tlsRegions, globalOffset);
91
92         os << endl;
93
94         // Print each symbol ordered by its offset from the TCB
95         map<Offset, Symbol *> off2Sym;
96         vector<Symbol *>::iterator sym_it;
97         for(sym_it = tlsSymbols.begin(); sym_it != tlsSymbols.end(); ++sym_it) {
98             off2Sym.insert(make_pair((*sym_it)->getOffset(), *sym_it));
99         }
100
101         map<Offset, Symbol *>::iterator off_it;
102         for(off_it = off2Sym.begin(); off_it != off2Sym.end(); ++off_it) {
103             os << "\tSymbol: " << off_it->second->getMangledName() 
104                << " Offset: 0x" << hex << off_it->first << dec 
105                << endl;
106         }
107
108         os << endl;
109     }
110
111     if( gotSize > 0 ) {
112         os << "New GOT Region: Offset: 0x" << hex << (globalOffset + gotRegionOffset) << dec
113            << " Size: 0x" << hex << gotSize << dec 
114            << " Alignment: 0x" << hex << gotRegionAlign << dec
115            << endl;
116
117         // Print out GOT entries in order
118         map<Offset, Symbol *> gotByEntry;
119         map<Symbol *, Offset>::iterator sym_it;
120         for(sym_it = gotSymbols.begin(); sym_it != gotSymbols.end(); ++sym_it) {
121             gotByEntry.insert(make_pair(sym_it->second, sym_it->first));
122         }
123
124         map<Offset, Symbol *>::iterator off_it;
125         for(off_it = gotByEntry.begin(); off_it != gotByEntry.end(); ++off_it) {
126             os << "\tGOT Offset: 0x" << hex << off_it->first << dec
127                << " Symbol: " << off_it->second->getMangledName()
128                << " Offset: 0x" << hex << off_it->second->getOffset() << dec << endl;
129         }
130
131         os << endl;
132     }
133
134     if( newCtorRegions.size() > 0 ) {
135         os << "New .ctors region: Offset: 0x" << hex << (globalOffset + ctorRegionOffset) << dec
136            << " Size: 0x" << hex << ctorSize << dec
137            << " Alignment: 0x" << hex << ctorRegionAlign << dec
138            << endl;
139
140         if( originalCtorRegion != NULL ) {
141             printRegionFromInfo(os, originalCtorRegion, 0, 0);
142         }
143
144         vector<Region *>::iterator reg_it;
145         for(reg_it = newCtorRegions.begin(); reg_it != newCtorRegions.end(); ++reg_it) {
146             printRegion(os, *reg_it, globalOffset);
147         }
148
149         os << endl;
150     }
151
152     if( newDtorRegions.size() > 0 ) {
153          os << "New .dtors region: Offset: 0x" << hex << (globalOffset + dtorRegionOffset) << dec
154            << " Size: 0x" << hex << dtorSize << dec
155            << " Alignment: 0x" << hex << dtorRegionAlign << dec
156            << endl;
157
158         if( originalDtorRegion != NULL ) {
159             printRegionFromInfo(os, originalDtorRegion, 0, 0);
160         }
161
162         vector<Region *>::iterator reg_it;
163         for(reg_it = newDtorRegions.begin(); reg_it != newDtorRegions.end(); ++reg_it) {
164             printRegion(os, *reg_it, globalOffset);
165         }
166
167         os << endl;
168         
169     }
170
171     if( bssRegions.size() > 0 ) {
172         os << "New BSS Region: Offset: 0x" << hex << (globalOffset + bssRegionOffset) << dec
173            << " Size: 0x" << hex << bssSize << dec 
174            << " Alignment: 0x" << hex << bssRegionAlign << dec
175            << endl;
176         printRegions(os, bssRegions, globalOffset);
177         os << endl;
178     }
179
180 }
181
182 void LinkMap::printBySymtab(ostream &os, vector<Symtab *> &symtabs, Offset globalOffset) {
183     vector<Symtab *>::iterator symtab_it;
184     for(symtab_it = symtabs.begin(); symtab_it != symtabs.end(); ++symtab_it) {
185         os << "Object: " << (*symtab_it)->memberName() << endl;
186
187         // Print the location of all the Regions
188         vector<Region *> regions;
189         if( !(*symtab_it)->getAllRegions(regions) ) continue;
190
191         vector<Region *>::iterator reg_it;
192         for(reg_it = regions.begin(); reg_it != regions.end(); ++reg_it) {
193             printRegion(os, *reg_it, globalOffset);
194         }
195
196         os << endl;
197
198         // Print the location of all the Functions
199         vector<Function *> funcs;
200         if( !(*symtab_it)->getAllFunctions(funcs) ) continue;
201
202         vector<Function *>::iterator func_it;
203         for(func_it = funcs.begin(); func_it != funcs.end(); ++func_it) {
204             Symbol *symbol = (*func_it)->getFirstSymbol();
205             os << "\tFunction: " << symbol->getPrettyName()
206                << " Offset: 0x" << hex << symbol->getOffset() << dec
207                << " - 0x" << hex << (symbol->getOffset() + symbol->getSize() - 1) << dec
208                << " Size: 0x" << hex << symbol->getSize() << dec
209                << endl;
210         }
211
212         os << endl;
213     }
214 }
215
216 void LinkMap::printRegions(ostream &os, deque<Region *> &regions, Offset globalOffset) {
217     deque<Region *>::iterator reg_it;
218     for(reg_it = regions.begin(); reg_it != regions.end(); ++reg_it) {
219         printRegion(os, *reg_it, globalOffset);
220     }
221 }
222
223 void LinkMap::printRegion(ostream &os, Region *region, Offset globalOffset) {
224     map<Region *, AllocPair>::iterator result;
225     result = regionAllocs.find(region);
226     if( result != regionAllocs.end() ) {
227         AllocPair pair = result->second;
228         printRegionFromInfo(os, region, globalOffset + pair.second,
229                 pair.first);
230     }
231 }
232
233 void LinkMap::printRegionFromInfo(ostream &os, Region *region, Offset regionOffset, Offset padding)
234 {
235     os << "\tRegion " << region->getRegionName() 
236            << " Padding: 0x" << hex << padding << dec
237            << " Offset: 0x" << hex << regionOffset << dec
238            << " - 0x" << hex << (regionOffset + region->getRegionSize() - 1) << dec
239            << " Size: 0x" << hex << region->getRegionSize() << dec
240            << " Alignment: 0x" << hex << region->getMemAlignment() << dec
241            << endl;
242 }