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