Remove examples (#764)
[dyninst.git] / symtabAPI / src / emitElf.h
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 #if !defined(_emit_Elf_64_h_)
32 #define _emit_Elf_64_h_
33
34 #include "Object.h"
35 #include "debug.h"
36 #include <iostream>
37
38 #include <unordered_map>
39 #include <unordered_set>
40 #include <vector>
41
42 using std::cerr;
43 using std::cout;
44 using std::endl;
45 using std::vector;
46
47 extern const char *STRTAB_NAME;
48 extern const char *SYMTAB_NAME;
49 extern const char *INTERP_NAME;
50
51 extern const char *pdelf_get_shnames(Elf_X *elf);
52
53 #define PT_PAX_FLAGS  (PT_LOOS + 0x5041580) /* PaX flags */
54
55 namespace Dyninst {
56     namespace SymtabAPI {
57 // Error reporting
58
59         struct sortByOffsetNewIndices {
60             bool operator()(Symbol *lhs, Symbol *rhs) {
61                 auto lIndex = lhs->getIndex();
62                 auto rIndex = rhs->getIndex();
63                 if(lIndex==-1 && rIndex==-1)
64                     return lhs->getOffset() < rhs->getOffset(); 
65                 lIndex = ULONG_MAX ? lIndex==-1 : lIndex;  
66                 rIndex = ULONG_MAX ? rIndex==-1 : rIndex;  
67                 return lIndex < rIndex;
68             }
69         };
70         struct sortByIndex {
71             bool operator()(Symbol *lhs, Symbol *rhs) {
72                 return lhs->getIndex() < rhs->getIndex();
73             }
74         };
75
76         struct ElfTypes32 {
77             typedef Elf32_Ehdr Elf_Ehdr;
78             typedef Elf32_Phdr Elf_Phdr;
79             typedef Elf32_Shdr Elf_Shdr;
80             typedef Elf32_Dyn Elf_Dyn;
81             typedef Elf32_Half Elf_Half;
82             typedef Elf32_Addr Elf_Addr;
83             typedef Elf32_Off Elf_Off;
84             typedef Elf32_Word Elf_Word;
85             typedef Elf32_Sym Elf_Sym;
86             typedef Elf32_Section Elf_Section;
87             typedef Elf32_Rel Elf_Rel;
88             typedef Elf32_Rela Elf_Rela;
89             typedef Elf32_Verneed Elf_Verneed;
90             typedef Elf32_Vernaux Elf_Vernaux;
91             typedef Elf32_Verdef Elf_Verdef;
92             typedef Elf32_Verdaux Elf_Verdaux;
93
94             Elf_Ehdr *elf_newehdr(Elf *elf) { return elf32_newehdr(elf); }
95
96             Elf_Phdr *elf_newphdr(Elf *elf, size_t num) { return elf32_newphdr(elf, num); }
97
98             Elf_Ehdr *elf_getehdr(Elf *elf) { return elf32_getehdr(elf); }
99
100             Elf_Phdr *elf_getphdr(Elf *elf) { return elf32_getphdr(elf); }
101
102             Elf_Shdr *elf_getshdr(Elf_Scn *scn) { return elf32_getshdr(scn); }
103
104             Elf32_Word makeRelocInfo(Elf32_Word sym, Elf32_Word type) { return ELF32_R_INFO(sym, type); }
105         };
106
107         struct ElfTypes64 {
108             typedef Elf64_Ehdr Elf_Ehdr;
109             typedef Elf64_Phdr Elf_Phdr;
110             typedef Elf64_Shdr Elf_Shdr;
111             typedef Elf64_Dyn Elf_Dyn;
112             typedef Elf64_Half Elf_Half;
113             typedef Elf64_Addr Elf_Addr;
114             typedef Elf64_Off Elf_Off;
115             typedef Elf64_Word Elf_Word;
116             typedef Elf64_Sym Elf_Sym;
117             typedef Elf64_Section Elf_Section;
118             typedef Elf64_Rel Elf_Rel;
119             typedef Elf64_Rela Elf_Rela;
120             typedef Elf64_Verneed Elf_Verneed;
121             typedef Elf64_Vernaux Elf_Vernaux;
122             typedef Elf64_Verdef Elf_Verdef;
123             typedef Elf64_Verdaux Elf_Verdaux;
124
125             Elf_Ehdr *elf_newehdr(Elf *elf) { return elf64_newehdr(elf); }
126
127             Elf_Phdr *elf_newphdr(Elf *elf, size_t num) { return elf64_newphdr(elf, num); }
128
129             Elf_Ehdr *elf_getehdr(Elf *elf) { return elf64_getehdr(elf); }
130
131             Elf_Phdr *elf_getphdr(Elf *elf) { return elf64_getphdr(elf); }
132
133             Elf_Shdr *elf_getshdr(Elf_Scn *scn) { return elf64_getshdr(scn); }
134
135             Elf64_Xword makeRelocInfo(Elf64_Word sym, Elf64_Word type) { return ELF64_R_INFO(sym, type); }
136         };
137
138         template<class ElfTypes = ElfTypes64> class emitElf : public ElfTypes {
139         public:
140             emitElf(Elf_X *pX, bool i, Object *pObject, void (*pFunction)(const char *), Symtab *pSymtab);
141
142             typedef typename ElfTypes::Elf_Ehdr Elf_Ehdr;
143             typedef typename ElfTypes::Elf_Phdr Elf_Phdr;
144             typedef typename ElfTypes::Elf_Shdr Elf_Shdr;
145             typedef typename ElfTypes::Elf_Dyn Elf_Dyn;
146             typedef typename ElfTypes::Elf_Half Elf_Half;
147             typedef typename ElfTypes::Elf_Addr Elf_Addr;
148             typedef typename ElfTypes::Elf_Off Elf_Off;
149             typedef typename ElfTypes::Elf_Word Elf_Word;
150             typedef typename ElfTypes::Elf_Sym Elf_Sym;
151             typedef typename ElfTypes::Elf_Section Elf_Section;
152             typedef typename ElfTypes::Elf_Rel Elf_Rel;
153             typedef typename ElfTypes::Elf_Rela Elf_Rela;
154             typedef typename ElfTypes::Elf_Verneed Elf_Verneed;
155             typedef typename ElfTypes::Elf_Vernaux Elf_Vernaux;
156             typedef typename ElfTypes::Elf_Verdef Elf_Verdef;
157             typedef typename ElfTypes::Elf_Verdaux Elf_Verdaux;
158
159             ~emitElf() {
160                 if( linkedStaticData ) delete linkedStaticData;
161             }
162
163             bool createSymbolTables(std::set<Symbol *> &allSymbols);
164
165             bool driver(std::string fName);
166
167         private:
168             Elf_X *oldElfHandle;
169             Elf *newElf;
170             Elf *oldElf;
171             Symtab *obj;
172             //New Section & Program Headers
173             Elf_Ehdr *newEhdr;
174             Elf_Ehdr *oldEhdr;
175
176             Elf_Phdr *newPhdr;
177             Elf_Phdr *oldPhdr;
178             Offset phdr_offset;
179
180             //important data sections in the
181             //new Elf that need updated
182             Elf_Data *textData;
183             Elf_Data *symStrData;
184             Elf_Data *dynStrData;
185             char *olddynStrData;
186             unsigned olddynStrSize;
187             Elf_Data *symTabData;
188             Elf_Data *dynsymData;
189             Elf_Data *dynData;
190
191             Elf_Scn *phdrs_scn;
192
193             std::vector<Region *>nonLoadableSecs;
194             std::vector<Region *> newSecs;
195             std::map<unsigned, std::vector<Elf_Dyn *> > dynamicSecData;
196             std::vector<std::string> DT_NEEDEDEntries;
197             std::vector<std::pair<long, long> > new_dynamic_entries;
198             std::vector<std::string> unversionedNeededEntries;
199
200             // Symbol version table data
201             std::map<std::string, std::map<std::string, unsigned> >verneedEntries;    //verneed entries
202             std::map<std::string, unsigned> verdefEntries;                            //verdef entries
203             std::map<unsigned, std::vector<std::string> > verdauxEntries;
204             std::map<std::string, unsigned> versionNames;
205             std::vector<Elf_Half> versionSymTable;
206             int curVersionNum, verneednum, verdefnum, dynsym_info;
207
208             // Needed when adding a new segment
209             Elf_Off newSegmentStart;
210             Elf_Shdr *firstNewLoadSec;// initialize to NULL
211
212             // data segment end
213             Elf_Off dataSegEnd;
214             Elf_Off dynSegOff, dynSegAddr, phdrSegOff, phdrSegAddr;
215             unsigned dynSegSize;
216
217             //Section Names for all sections
218             vector<std::string> secNames;
219             unsigned secNameIndex;
220             Offset currEndOffset;
221             Address currEndAddress;
222
223             // Pointer to all relocatable code and data allocated during a static link,
224             // to be deleted after written out
225             char *linkedStaticData;
226
227             //flags
228             // Expand NOBITS sections within the object file to their size
229             bool BSSExpandFlag;
230             bool movePHdrsFirst;
231             bool createNewPhdr;
232             bool replaceNOTE;
233             unsigned loadSecTotalSize;
234
235             bool isStripped;
236             int library_adjust;
237             Object *object;
238
239             void (*err_func_)(const char*);
240
241             bool createElfSymbol(Symbol *symbol, unsigned strIndex, vector<Elf_Sym *> &symbols,
242                                  bool dynSymFlag = false);
243             void findSegmentEnds();
244             void renameSection(const std::string &oldStr, const std::string &newStr, bool renameAll=true);
245             void fixPhdrs(unsigned &);
246             void createNewPhdrRegion(std::unordered_map<std::string, unsigned> &newNameIndexMapping);
247
248             bool addSectionHeaderTable(Elf_Shdr *shdr);
249
250             bool createNonLoadableSections(Elf_Shdr *&shdr);
251
252             bool createLoadableSections(Elf_Shdr *&shdr, unsigned &extraAlignSize,
253                                         std::unordered_map<std::string, unsigned> &newIndexMapping,
254                                         unsigned &sectionNumber);
255
256             void createRelocationSections(std::vector<relocationEntry> &relocation_table, bool isDynRelocs,
257                                           std::unordered_map<std::string, unsigned long> &dynSymNameMapping);
258
259             void updateSymbols(Elf_Data* symtabData,Elf_Data* strData, unsigned long loadSecsSize);
260
261             bool hasRewrittenTLS;
262             bool TLSExists;
263             Elf_Shdr *newTLSData;
264
265             void updateDynamic(unsigned tag, Elf_Addr val);
266
267             void createSymbolVersions(Elf_Half *&symVers, char *&verneedSecData, unsigned &verneedSecSize,
268                                       char *&verdefSecData,
269                                       unsigned &verdefSecSize, unsigned &dynSymbolNamesLength,
270                                       std::vector<std::string> &dynStrs);
271
272             void createHashSection(Elf_Word *&hashsecData, unsigned &hashsecSize, std::vector<Symbol *> &dynSymbols);
273
274             void createDynamicSection(void *dynData, unsigned size, Elf_Dyn *&dynsecData, unsigned &dynsecSize,
275                                       unsigned &dynSymbolNamesLength, std::vector<std::string> &dynStrs);
276
277             void addDTNeeded(std::string s);
278
279             void log_elferror(void (*err_func)(const char *), const char* msg);
280             bool cannotRelocatePhdrs();
281
282             bool isBlueGeneQ;
283             bool isStaticBinary;
284
285         };
286         extern template class emitElf<ElfTypes32>;
287         extern template class emitElf<ElfTypes64>;
288
289     } // namespace SymtabAPI
290 } // namespace Dyninst
291
292 #endif