Allow dyninst to be compiled using clang
[dyninst.git] / symtabAPI / src / emitElf-64.C
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
32 #include <algorithm>
33 #include "emitElf-64.h"
34 #include "emitElfStatic.h"
35 #include "common/src/pathName.h"
36
37
38 #if defined(os_freebsd)
39 #include "common/src/freebsdKludges.h"
40 #endif
41
42
43 #if defined(os_linux)
44
45 #include "common/src/linuxKludges.h"
46
47 #endif
48
49 extern void symtab_log_perror(const char *msg);
50 using namespace Dyninst;
51 using namespace Dyninst::SymtabAPI;
52 using namespace std;
53
54 extern void setSymtabError(SymtabError new_err);
55
56 unsigned int elfHash(const char *name) {
57     unsigned int h = 0, g;
58
59     while (*name) {
60         h = (h << 4) + *name++;
61         if ((g = h & 0xf0000000))
62             h ^= g >> 24;
63         h &= ~g;
64     }
65     return h;
66 }
67 unsigned long bgq_sh_flags = SHF_EXECINSTR | SHF_ALLOC | SHF_WRITE;;
68
69
70
71 static bool libelfso0Flag;
72 static bool libelfso1Flag;
73 static int libelfso1version_major;
74 static int libelfso1version_minor;
75
76
77 void setVersion() {
78     libelfso0Flag = false;
79     libelfso1Flag = false;
80     libelfso1version_major = 0;
81     libelfso1version_minor = 0;
82 #if defined(os_linux) || defined(os_freebsd)
83     unsigned nEntries;
84     map_entries *maps = getVMMaps(getpid(), nEntries);
85     for (unsigned i = 0; i < nEntries; i++) {
86         if (!strstr(maps[i].path, "libelf"))
87             continue;
88         std::string real_file = resolve_file_path(maps[i].path);
89         const char *libelf_start = strstr(real_file.c_str(), "libelf");
90         int num_read, major, minor;
91         num_read = sscanf(libelf_start, "libelf-%d.%d.so", &major, &minor);
92         if (num_read == 2) {
93             libelfso1Flag = true;
94             libelfso1version_major = major;
95             libelfso1version_minor = minor;
96         }
97         else {
98             libelfso0Flag = true;
99         }
100     }
101     if (libelfso0Flag && libelfso1Flag) {
102         fprintf(stderr, "WARNING: SymtabAPI is linked with libelf.so.0 and "
103                 "libelf.so.1!  SymtabAPI likely going to be unable to read "
104                 "and write elf files!\n");
105     }
106
107 #if defined(os_freebsd)
108     if( libelfso1Flag ) {
109       fprintf(stderr, "WARNING: SymtabAPI on FreeBSD is known to function "
110               "incorrectly when linked with libelf.so.1\n");
111   }
112 #endif
113 #endif
114 }
115
116
117 template<class ElfTypes>
118 emitElf64<ElfTypes>::emitElf64(Elf_X *oldElfHandle_, bool isStripped_, Object *obj_, void (*err_func)(const char *),
119                                Symtab *st) :
120         oldElfHandle(oldElfHandle_), newElf(NULL), oldElf(NULL),
121         obj(st),
122         newEhdr(NULL), oldEhdr(NULL),
123         newPhdr(NULL), oldPhdr(NULL), phdr_offset(0),
124         textData(NULL), symStrData(NULL), dynStrData(NULL),
125         olddynStrData(NULL), olddynStrSize(0),
126         symTabData(NULL), dynsymData(NULL), dynData(NULL),
127         phdrs_scn(NULL), verneednum(0), verdefnum(0),
128         newSegmentStart(0), firstNewLoadSec(NULL),
129         dataSegEnd(0), dynSegOff(0), dynSegAddr(0),
130         phdrSegOff(0), phdrSegAddr(0), dynSegSize(0),
131         secNameIndex(0), currEndOffset(0), currEndAddress(0),
132         linkedStaticData(NULL), loadSecTotalSize(0),
133         isStripped(isStripped_), library_adjust(0),
134         object(obj_), err_func_(err_func),
135         hasRewrittenTLS(false), TLSExists(false), newTLSData(NULL) {
136     oldElf = oldElfHandle->e_elfp();
137     curVersionNum = 2;
138     setVersion();
139
140     //Set variable based on the mechanism to add new load segment
141     // 1) createNewPhdr (Total program headers + 1) - default
142     //  (a) movePHdrsFirst
143     //    (b) create new section called dynphdrs and change pointers (createNewPhdrRegion)
144     //    (c) library_adjust - create room for a new program header in a position-indepdent library
145     //                         by increasing all virtual addresses for the library
146     // 2) Use existing Phdr (used in bleugene - will be handled in function fixPhdrs)
147     //    (a) replaceNOTE section - if NOTE exists
148     //    (b) BSSExpandFlag - expand BSS section - default option
149
150     // default
151     createNewPhdr = true;
152     BSSExpandFlag = false;
153     replaceNOTE = false;
154
155     //If we're dealing with a library that can be loaded anywhere,
156     // then load the program headers into the later part of the binary,
157     // this may trigger a kernel bug that was fixed in Summer 2007,
158     // but is the only reliable way to modify these libraries.
159     //If we're dealing with a library/executable that loads at a specific
160     // address we'll put the phdrs into the page before that address.  This
161     // works and will avoid the kernel bug.
162
163     isBlueGeneQ = obj_->isBlueGeneQ();
164     isStaticBinary = obj_->isStaticBinary();
165     if (isBlueGeneQ) {
166         movePHdrsFirst = false;
167     } else {
168         movePHdrsFirst = createNewPhdr && object && object->getLoadAddress();
169     }
170
171     //If we want to try a mode where we add the program headers to a library
172     // that can be loaded anywhere, and put the program headers in the first
173     // page (avoiding the kernel bug), then set library_adjust to getpagesize().
174     // This will shift all addresses in the library down by a page, accounting
175     // for the extra page for program headers.  This causes some significant
176     // changes to the binary, and isn't well tested.
177     library_adjust = 0;
178     if (cannotRelocatePhdrs() && !movePHdrsFirst) {
179         movePHdrsFirst = true;
180         library_adjust = getpagesize();
181     }
182 }
183
184 template<class ElfTypes>
185 bool emitElf64<ElfTypes>::hasPHdrSectionBug()
186 {
187    if (movePHdrsFirst)
188       return false;
189    if (!libelfso1Flag)
190       return false;
191    return (libelfso1version_major == 0 && libelfso1version_minor <= 137);
192 }
193
194 template<typename ElfTypes>
195 bool emitElf64<ElfTypes>::cannotRelocatePhdrs()
196 {
197 //#if defined(bug_phdrs_first_page)
198     return true;
199 //#else
200     //  return false;
201 //#endif
202 }
203
204 static int elfSymType(Symbol *sym)
205 {
206   switch (sym->getType()) {
207      case Symbol::ST_MODULE: return STT_FILE;
208      case Symbol::ST_SECTION: return STT_SECTION;
209      case Symbol::ST_OBJECT: return STT_OBJECT;
210      case Symbol::ST_FUNCTION: return STT_FUNC;
211      case Symbol::ST_TLS: return STT_TLS;
212      case Symbol::ST_NOTYPE : return STT_NOTYPE;
213      case Symbol::ST_UNKNOWN: return sym->getInternalType();
214 #if defined(STT_GNU_IFUNC)
215      case Symbol::ST_INDIRECT: return STT_GNU_IFUNC;
216 #endif
217      default: return STT_SECTION;
218   }
219 }
220
221 static int elfSymBind(Symbol::SymbolLinkage sLinkage)
222 {
223   switch (sLinkage) {
224   case Symbol::SL_LOCAL: return STB_LOCAL;
225   case Symbol::SL_WEAK: return STB_WEAK;
226   case Symbol::SL_GLOBAL: return STB_GLOBAL;
227   default: return STB_LOPROC;
228   }
229 }
230
231 static int elfSymVisibility(Symbol::SymbolVisibility sVisibility)
232 {
233   switch (sVisibility) {
234   case Symbol::SV_DEFAULT: return STV_DEFAULT;
235   case Symbol::SV_INTERNAL: return STV_INTERNAL;
236   case Symbol::SV_HIDDEN: return STV_HIDDEN;
237   case Symbol::SV_PROTECTED: return STV_PROTECTED;
238   default: return STV_DEFAULT;
239   }
240 }
241
242 std::string phdrTypeStr(Elf64_Word phdr_type) {
243     switch (phdr_type) {
244         case PT_NULL:
245             return "NULL";
246         case PT_LOAD:
247             return "LOAD";
248         case PT_DYNAMIC:
249             return "DYNAMIC";
250         case PT_INTERP:
251             return "INTERP";
252         case PT_NOTE:
253             return "NOTE";
254         case PT_SHLIB:
255             return "SHLIB";
256         case PT_PHDR:
257             return "PHDR";
258         case PT_TLS:
259             return "TLS";
260         case PT_GNU_EH_FRAME:
261             return "EH_FRAME";
262         case PT_GNU_STACK:
263             return "STACK";
264         case PT_GNU_RELRO:
265             return "RELRO";
266         case PT_PAX_FLAGS:
267             return "PAX";
268         default:
269             assert(0);
270             return "<UNKNOWN>";
271             break;
272
273     }
274
275 }
276
277 template<class ElfTypes>
278 bool emitElf64<ElfTypes>::createElfSymbol(Symbol *symbol, unsigned strIndex, vector<Elf_Sym *> &symbols,
279                                           bool dynSymFlag) {
280     Elf_Sym *sym = new Elf_Sym();
281     sym->st_name = strIndex;
282
283     // OPD-based systems
284     if (symbol->getPtrOffset()) {
285         sym->st_value = symbol->getPtrOffset() + library_adjust;
286     }
287     else if (symbol->getOffset()) {
288         sym->st_value = symbol->getOffset() + library_adjust;
289     }
290
291     sym->st_size = symbol->getSize();
292     sym->st_other = ELF64_ST_VISIBILITY(elfSymVisibility(symbol->getVisibility()));
293     sym->st_info = (unsigned char) ELF64_ST_INFO(elfSymBind(symbol->getLinkage()), elfSymType(symbol));
294
295     if (symbol->getRegion()) {
296 #if defined(os_freebsd)
297         sym->st_shndx = (Elf_Half) symbol->getRegion()->getRegionNumber();
298 #else
299         sym->st_shndx = (Elf_Section) symbol->getRegion()->getRegionNumber();
300 #endif
301     }
302     else if (symbol->isAbsolute()) {
303         sym->st_shndx = SHN_ABS;
304     }
305     else {
306         sym->st_shndx = 0;
307     }
308
309     symbols.push_back(sym);
310
311     if (dynSymFlag) {
312         //printf("dynamic symbol: %s\n", symbol->getMangledName().c_str());
313
314         char msg[2048];
315         char *mpos = msg;
316         msg[0] = '\0';
317         string fileName;
318
319         if (!symbol->getVersionFileName(fileName)) {
320             //verdef entry
321             vector<string> *vers;
322             if (!symbol->getVersions(vers)) {
323                 if (symbol->getLinkage() == Symbol::SL_GLOBAL) {
324                     versionSymTable.push_back(1);
325
326                 }
327                 else {
328                     versionSymTable.push_back(0);
329                     mpos += sprintf(mpos, "  local\n");
330                 }
331             }
332             else {
333                 if (vers->size() > 0) {
334                     // new verdef entry
335                     mpos += sprintf(mpos, "verdef: symbol=%s  version=%s ", symbol->getMangledName().c_str(),
336                                     (*vers)[0].c_str());
337                     if (verdefEntries.find((*vers)[0]) != verdefEntries.end()) {
338                         unsigned short index = verdefEntries[(*vers)[0]];
339                         if (symbol->getVersionHidden()) index += 0x8000;
340                         versionSymTable.push_back(index);
341                     }
342                     else {
343                         unsigned short index = curVersionNum;
344                         if (symbol->getVersionHidden()) index += 0x8000;
345                         versionSymTable.push_back(index);
346
347                         verdefEntries[(*vers)[0]] = curVersionNum;
348                         curVersionNum++;
349                     }
350                 }
351                 // add all versions to the verdef entry
352                 for (unsigned i = 0; i < vers->size(); i++) {
353                     mpos += sprintf(mpos, "  {%s}", (*vers)[i].c_str());
354                     if (versionNames.find((*vers)[i]) == versionNames.end()) {
355                         versionNames[(*vers)[i]] = 0;
356                     }
357
358                     if (find(verdauxEntries[verdefEntries[(*vers)[0]]].begin(),
359                              verdauxEntries[verdefEntries[(*vers)[0]]].end(),
360                              (*vers)[i]) == verdauxEntries[verdefEntries[(*vers)[0]]].end()) {
361                         verdauxEntries[verdefEntries[(*vers)[0]]].push_back((*vers)[i]);
362                     }
363                 }
364                 mpos += sprintf(mpos, "\n");
365             }
366         }
367         else {
368             //verneed entry
369             mpos += sprintf(mpos, "need: symbol=%s    filename=%s\n",
370                             symbol->getMangledName().c_str(), fileName.c_str());
371
372             vector<string> *vers;
373
374             if (!symbol->getVersions(vers) || (vers && vers->size() != 1)) {
375                 // add an unversioned dependency
376                 if (fileName != "") {
377                     // If the file is not an executable, then add to unversioned entries
378                     if (!symbol->getReferringSymbol()->getSymtab()->isExec()) {
379                         if (find(unversionedNeededEntries.begin(),
380                                  unversionedNeededEntries.end(),
381                                  fileName) == unversionedNeededEntries.end()) {
382                             mpos += sprintf(mpos, "  new unversioned: %s\n", fileName.c_str());
383                             unversionedNeededEntries.push_back(fileName);
384                         }
385                     }
386
387                     if (symbol->getLinkage() == Symbol::SL_GLOBAL) {
388                         mpos += sprintf(mpos, "  global (w/ filename)\n");
389                         versionSymTable.push_back(1);
390                     }
391                     else {
392
393                         versionSymTable.push_back(0);
394                     }
395                 }
396             }
397             else {
398                 if (vers) {
399                     // There should only be one version string by this time
400                     //If the verison name already exists then add the same version number to the version symbol table
401                     //Else give a new number and add it to the mapping.
402                     if (versionNames.find((*vers)[0]) == versionNames.end()) {
403                         mpos += sprintf(mpos, "  new version name: %s\n", (*vers)[0].c_str());
404                         versionNames[(*vers)[0]] = 0;
405                     }
406
407                     if (verneedEntries.find(fileName) != verneedEntries.end()) {
408                         if (verneedEntries[fileName].find((*vers)[0]) != verneedEntries[fileName].end()) {
409                             mpos += sprintf(mpos, "  vernum: %d\n", verneedEntries[fileName][(*vers)[0]]);
410                             versionSymTable.push_back((unsigned short) verneedEntries[fileName][(*vers)[0]]);
411                         }
412                         else {
413                             mpos += sprintf(mpos, "  new entry #%d: %s [%s]\n",
414                                             curVersionNum, (*vers)[0].c_str(), fileName.c_str());
415                             versionSymTable.push_back((unsigned short) curVersionNum);
416                             verneedEntries[fileName][(*vers)[0]] = curVersionNum;
417                             curVersionNum++;
418                         }
419                     }
420                     else {
421                         mpos += sprintf(mpos, "  new entry #%d: %s [%s]\n",
422                                         curVersionNum, (*vers)[0].c_str(), fileName.c_str());
423                         versionSymTable.push_back((unsigned short) curVersionNum);
424                         verneedEntries[fileName][(*vers)[0]] = curVersionNum;
425                         curVersionNum++;
426                     }
427                 }
428             }
429         }
430 #ifdef BINEDIT_DEBUG
431         printf("%s", msg);
432 #endif
433     }
434
435     return true;
436 }
437
438 // Find the end of data/text segment
439 template<class ElfTypes>
440 void emitElf64<ElfTypes>::findSegmentEnds() {
441     Elf_Phdr *tmp = ElfTypes::elf_getphdr(oldElf);
442     // Find the offset of the start of the text & the data segment
443     // The first LOAD segment is the text & the second LOAD segment
444     // is the data
445     dataSegEnd = 0;
446     for (unsigned i = 0; i < oldEhdr->e_phnum; i++) {
447         if (tmp->p_type == PT_LOAD) {
448             if (dataSegEnd < tmp->p_vaddr + tmp->p_memsz)
449                 dataSegEnd = tmp->p_vaddr + tmp->p_memsz;
450         } else if (PT_TLS == tmp->p_type) {
451             TLSExists = true;
452         }
453         tmp++;
454     }
455 }
456
457 // Rename an old section. Lengths of old and new names must match.
458 // Only renames the FIRST matching section encountered.
459 template<class ElfTypes>
460 void emitElf64<ElfTypes>::renameSection(const std::string &oldStr, const std::string &newStr, bool renameAll) {
461     assert(oldStr.length() == newStr.length());
462     for (unsigned k = 0; k < secNames.size(); k++) {
463         if (secNames[k] == oldStr) {
464             secNames[k].replace(0, oldStr.length(), newStr);
465             if (!renameAll)
466                 break;
467         }
468     }
469 }
470
471 template<class ElfTypes>
472 bool emitElf64<ElfTypes>::driver(std::string fName) {
473     vector<ExceptionBlock *> exceptions;
474     obj->getAllExceptions(exceptions);
475     //  cerr << "Dumping exception info: " << endl;
476
477     for (auto eb = exceptions.begin();
478          eb != exceptions.end();
479          ++eb) {
480         //cerr << **eb << endl;
481     }
482
483
484     int newfd;
485     Region *foundSec = NULL;
486     unsigned pgSize = getpagesize();
487     rewrite_printf("::driver for emitElf64\n");
488
489     string strtmpl = fName + "XXXXXX";
490     char buf[strtmpl.length() + 1];
491     strncpy(buf, strtmpl.c_str(), strtmpl.length() + 1);
492
493     newfd = mkstemp(buf);
494
495     if (newfd == -1) {
496         log_elferror(err_func_, "error opening file to write symbols");
497         return false;
498     }
499     strtmpl = buf;
500
501     fchmod(newfd, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP);
502     rewrite_printf("Emitting to temporary file %s\n", buf);
503
504 #if 0
505     //open ELF File for writing
506   if((newfd = (open(fName.c_str(), O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP)))==-1){
507     log_elferror(err_func_, "error opening file to write symbols");
508     return false;
509   }
510 #endif
511
512     if ((newElf = elf_begin(newfd, ELF_C_WRITE, NULL)) == NULL) {
513         log_elferror(err_func_, "NEWELF_BEGIN_FAIL");
514         fflush(stdout);
515         cerr << "Failed to elf_begin" << endl;
516         return false;
517     }
518
519     //Section name index for all sections
520     secNames.push_back("");
521     secNameIndex = 1;
522     //Section name index for new sections
523     loadSecTotalSize = 0;
524     unsigned NOBITStotalsize = 0;
525     int dirtySecsChange = 0;
526     unsigned extraAlignSize = 0;
527
528     // ".shstrtab" section: string table for section header names
529     const char *shnames = pdelf_get_shnames(oldElfHandle);
530     if (shnames == NULL) {
531         log_elferror(err_func_, ".shstrtab section");
532         return false;
533     }
534
535     // Write the Elf header first!
536     newEhdr = ElfTypes::elf_newehdr(
537             newElf);
538     if (!newEhdr) {
539         log_elferror(err_func_, "newEhdr failed\n");
540         return false;
541     }
542     oldEhdr = ElfTypes::elf_getehdr(
543             oldElf);
544     memcpy(newEhdr, oldEhdr, sizeof(Elf_Ehdr));
545
546     newEhdr->e_shnum += newSecs.size();
547
548     // Find the end of text and data segments
549     findSegmentEnds();
550     unsigned insertPoint = oldEhdr->e_shnum;
551     unsigned insertPointOffset = 0;
552     unsigned NOBITSstartPoint = oldEhdr->e_shnum;
553
554     if (movePHdrsFirst) {
555         newEhdr->e_phoff = sizeof(Elf_Ehdr);
556     }
557     newEhdr->e_entry += library_adjust;
558
559     /* flag the file for no auto-layout */
560     elf_flagelf(newElf, ELF_C_SET, ELF_F_LAYOUT);
561
562     Elf_Scn *scn = NULL, *newscn = NULL;
563     Elf_Data *newdata = NULL, *olddata = NULL;
564     Elf_Shdr *newshdr = NULL, *shdr = NULL;
565     dyn_hash_map<unsigned, unsigned> secLinkMapping;
566     dyn_hash_map<unsigned, unsigned> secInfoMapping;
567     dyn_hash_map<unsigned, unsigned> changeMapping;
568     dyn_hash_map<string, unsigned> newNameIndexMapping;
569     dyn_hash_map<unsigned, string> oldIndexNameMapping;
570
571     bool createdLoadableSections = false;
572     unsigned scncount;
573     unsigned sectionNumber = 0;
574
575     bool startMovingSections = false;
576     for (scncount = 0; (scn = elf_nextscn(oldElf, scn)); scncount++) {
577         //copy sections from oldElf to newElf
578         shdr = ElfTypes::elf_getshdr(scn);
579
580         // resolve section name
581         const char *name = &shnames[shdr->sh_name];
582         bool result = obj->findRegion(foundSec, shdr->sh_addr, shdr->sh_size);
583         if (!result || foundSec->isDirty()) {
584             result = obj->findRegion(foundSec, name);
585         }
586
587         // write the shstrtabsection at the end
588         if (!strcmp(name, ".shstrtab"))
589             continue;
590
591         sectionNumber++;
592         changeMapping[sectionNumber] = 0;
593         oldIndexNameMapping[scncount + 1] = string(name);
594         newNameIndexMapping[string(name)] = sectionNumber;
595
596         newscn = elf_newscn(newElf);
597         newshdr = ElfTypes::elf_getshdr(newscn);
598         newdata = elf_newdata(newscn);
599         olddata = elf_getdata(scn, NULL);
600         memcpy(newshdr, shdr, sizeof(Elf_Shdr));
601         memcpy(newdata, olddata, sizeof(Elf_Data));
602
603
604         secNames.push_back(name);
605         newshdr->sh_name = secNameIndex;
606         secNameIndex += strlen(name) + 1;
607
608         if (newshdr->sh_addr) {
609             newshdr->sh_addr += library_adjust;
610         }
611
612         if (foundSec->isDirty()) {
613             newdata->d_buf = (char *) malloc(foundSec->getDiskSize());
614             memcpy(newdata->d_buf, foundSec->getPtrToRawData(), foundSec->getDiskSize());
615             newdata->d_size = foundSec->getDiskSize();
616             newshdr->sh_size = foundSec->getDiskSize();
617         }
618         else if (olddata->d_buf)     //copy the data buffer from oldElf
619         {
620             newdata->d_buf = (char *) malloc(olddata->d_size);
621             memcpy(newdata->d_buf, olddata->d_buf, olddata->d_size);
622         }
623
624         if (newshdr->sh_entsize && (newshdr->sh_size % newshdr->sh_entsize != 0)) {
625             newshdr->sh_entsize = 0x0;
626         }
627
628         if (BSSExpandFlag) {
629             // Add the expanded SHT_NOBITS section size if the section comes after those sections
630             if (scncount > NOBITSstartPoint)
631                 newshdr->sh_offset += NOBITStotalsize;
632
633             // Expand the NOBITS sections in file & and change the type from SHT_NOBITS to SHT_PROGBITS
634             if (shdr->sh_type == SHT_NOBITS) {
635                 newshdr->sh_type = SHT_PROGBITS;
636                 newdata->d_buf = (char *) malloc(shdr->sh_size);
637                 memset(newdata->d_buf, '\0', shdr->sh_size);
638                 newdata->d_size = shdr->sh_size;
639                 if (NOBITSstartPoint == oldEhdr->e_shnum)
640                     NOBITSstartPoint = scncount;
641                 NOBITStotalsize += shdr->sh_size;
642             }
643         }
644
645         vector<vector<unsigned long> > moveSecAddrRange = obj->getObject()->getMoveSecAddrRange();
646
647         for (unsigned i = 0; i != moveSecAddrRange.size(); i++) {
648             if ((moveSecAddrRange[i][0] == shdr->sh_addr) ||
649                 (shdr->sh_addr >= moveSecAddrRange[i][0] && shdr->sh_addr < moveSecAddrRange[i][1])) {
650                 newshdr->sh_type = SHT_PROGBITS;
651                 changeMapping[sectionNumber] = 1;
652                 string newName = ".o";
653                 newName.append(name, 2, strlen(name));
654                 renameSection((string) name, newName, false);
655             }
656         }
657
658         if ((obj->getObject()->getStrtabAddr() != 0 &&
659              obj->getObject()->getStrtabAddr() == shdr->sh_addr) ||
660             !strcmp(name, STRTAB_NAME)) {
661             symStrData = newdata;
662             updateSymbols(symTabData, symStrData, loadSecTotalSize);
663         }
664
665         //Change sh_link for .symtab to point to .strtab
666         if ((obj->getObject()->getSymtabAddr() != 0 &&
667              obj->getObject()->getSymtabAddr() == shdr->sh_addr) ||
668             !strcmp(name, SYMTAB_NAME)) {
669             newshdr->sh_link = secNames.size();
670             changeMapping[sectionNumber] = 1;
671             symTabData = newdata;
672         }
673
674
675         if (obj->getObject()->getTextAddr() != 0 &&
676             obj->getObject()->getTextAddr() == shdr->sh_addr) {
677             textData = newdata;
678         }
679
680         if (obj->getObject()->getDynamicAddr() != 0 &&
681             obj->getObject()->getDynamicAddr() == shdr->sh_addr) {
682             dynData = newdata;
683             dynSegOff = newshdr->sh_offset;
684             dynSegAddr = newshdr->sh_addr;
685             // Change the data to update the relocation addr
686             newshdr->sh_type = SHT_PROGBITS;
687             changeMapping[sectionNumber] = 1;
688             string newName = ".o";
689             newName.append(name, 2, strlen(name));
690             renameSection((string) name, newName, false);
691         }
692
693         // Only need to rewrite data section
694         if (hasRewrittenTLS && foundSec->isTLS()
695             && foundSec->getRegionType() == Region::RT_DATA) {
696             // Clear TLS flag
697             newshdr->sh_flags &= ~SHF_TLS;
698
699             string newName = ".o";
700             newName.append(name, 2, strlen(name));
701             renameSection((string) name, newName, false);
702         }
703
704 #if defined(arch_power) && defined(arch_64bit)
705         // DISABLED
706     if (0 && isStaticBinary && strcmp(name, ".got") == 0) {
707       string newName = ".o";
708       newName.append(name, 2, strlen(name));
709       renameSection((string) name, newName, false);
710     }
711 #endif
712
713         if (isStaticBinary && (strcmp(name, ".rela.plt") == 0)) {
714             string newName = ".o";
715             newName.append(name, 2, strlen(name));
716             renameSection(name, newName, false);
717         }
718
719         if (isStaticBinary && (strcmp(name, ".rela.plt") == 0)) {
720             string newName = ".o";
721             newName.append(name, 2, strlen(name));
722             renameSection(name, newName, false);
723             // Clear the PLT type; use PROGBITS
724             newshdr->sh_type = SHT_PROGBITS;
725         }
726
727         // Change offsets of sections based on the newly added sections
728         if (movePHdrsFirst) {
729             /* This special case is specific to FreeBSD but there is no hurt in
730              * handling it on other platforms.
731              *
732              * This is necessary because the INTERP header must be located within in
733              * the first page of the file -- if the section is moved to the next
734              * page the object file will not be parsed correctly by the kernel.
735              *
736              * However, the initial sections still need to be shifted, but just
737              * by the difference in size of the new PHDR segment.
738              */
739             if (newshdr->sh_offset > 0) {
740                 if (startMovingSections || obj->isStaticBinary()
741                     || obj->getObjectType() == obj_SharedLib)
742                     newshdr->sh_offset += pgSize;
743                 //else if (createNewPhdr) newshdr->sh_offset += pgSize; //oldEhdr->e_phentsize;
744             }
745         }
746
747         if (scncount > insertPoint && newshdr->sh_offset >= insertPointOffset)
748             newshdr->sh_offset += loadSecTotalSize;
749
750         if (newshdr->sh_offset > 0)
751             newshdr->sh_offset += dirtySecsChange;
752
753         if (BSSExpandFlag) {
754             if (newshdr->sh_offset > 0) {
755                 newshdr->sh_offset += extraAlignSize;
756             }
757         } else if (newshdr->sh_offset >= insertPointOffset) {
758             newshdr->sh_offset += extraAlignSize;
759         }
760
761         if (foundSec->isDirty())
762             dirtySecsChange += newshdr->sh_size - shdr->sh_size;
763
764         if (BSSExpandFlag && newshdr->sh_addr) {
765             unsigned newOff =
766                     newshdr->sh_offset - (newshdr->sh_offset & (pgSize - 1)) + (newshdr->sh_addr & (pgSize - 1));
767             if (newOff < newshdr->sh_offset)
768                 newOff += pgSize;
769             extraAlignSize += newOff - newshdr->sh_offset;
770             newshdr->sh_offset = newOff;
771         }
772
773         secLinkMapping[sectionNumber] = shdr->sh_link;
774         secInfoMapping[sectionNumber] = shdr->sh_info;
775
776         rewrite_printf("section %s addr = %lx off = %lx size = %lx\n",
777                        name, newshdr->sh_addr, newshdr->sh_offset, newshdr->sh_size);
778
779         //Insert new loadable sections at the end of data segment
780         if (shdr->sh_addr + shdr->sh_size == dataSegEnd && !createdLoadableSections) {
781             createdLoadableSections = true;
782             insertPoint = scncount;
783             if (SHT_NOBITS == shdr->sh_type) {
784                 insertPointOffset = shdr->sh_offset;
785             } else {
786                 insertPointOffset = shdr->sh_offset + shdr->sh_size;
787             }
788
789             if (!createLoadableSections(newshdr, extraAlignSize, newNameIndexMapping, sectionNumber))
790                 return false;
791             if (createNewPhdr && !movePHdrsFirst) {
792                 sectionNumber++;
793                 createNewPhdrRegion(newNameIndexMapping);
794             }
795
796             // Update the heap symbols, now that loadSecTotalSize is set
797             updateSymbols(dynsymData, dynStrData, loadSecTotalSize);
798
799         }
800
801         if (0 > elf_update(newElf, ELF_C_NULL)) {
802             return false;
803         }
804
805         if (!strcmp(name, INTERP_NAME)) {
806             startMovingSections = true;
807         }
808     }
809
810     // Add non-loadable sections at the end of object file
811     if (!createNonLoadableSections(newshdr))
812         return false;
813
814     if (0 > elf_update(newElf, ELF_C_NULL)) {
815         return false;
816     }
817
818     //Add the section header table right at the end
819     addSectionHeaderTable(newshdr);
820
821     // Second iteration to fix the link fields to point to the correct section
822     scn = NULL;
823
824     for (scncount = 0; (scn = elf_nextscn(newElf, scn)); scncount++) {
825         shdr = ElfTypes::elf_getshdr(scn);
826         if (changeMapping[scncount + 1] == 0 && secLinkMapping[scncount + 1] != 0) {
827             unsigned linkIndex = secLinkMapping[scncount + 1];
828             string secName = oldIndexNameMapping[linkIndex];
829             unsigned newLinkIndex = newNameIndexMapping[secName];
830             shdr->sh_link = newLinkIndex;
831         }
832
833         if (changeMapping[scncount + 1] == 0 && secInfoMapping[scncount + 1] != 0) {
834             // For REL and RELA section, info field is a section index - hence of the index changes, the info field must change.
835             // For SYMTAB and DYNSYM, info field is OS specific - so just copy it.
836             // For others, info field is 0, so just copy it
837             if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) {
838                 unsigned infoIndex = secInfoMapping[scncount + 1];
839                 string secName = oldIndexNameMapping[infoIndex];
840                 unsigned newInfoIndex = newNameIndexMapping[secName];
841                 shdr->sh_info = newInfoIndex;
842             }
843         }
844     }
845
846     newEhdr->e_shstrndx = scncount;
847
848     // Move the section header to the end
849     newEhdr->e_shoff = shdr->sh_offset + shdr->sh_size;
850     if (newEhdr->e_shoff % 8)
851         newEhdr->e_shoff += 8 - (
852                 newEhdr->e_shoff % 8);
853
854     //copy program headers
855     oldPhdr = ElfTypes::elf_getphdr(
856             oldElf);
857     fixPhdrs(extraAlignSize);
858
859     //Write the new Elf file
860     if (elf_update(newElf, ELF_C_WRITE) < 0) {
861         log_elferror(err_func_, "elf_update failed");
862         return false;
863     }
864     elf_end(newElf);
865     if (hasPHdrSectionBug()) {
866         unsigned long ehdr_off = (unsigned long) &(((Elf_Ehdr *) 0x0)->e_phoff);
867         lseek(newfd, ehdr_off, SEEK_SET);
868         Elf_Off offset = (Elf_Off) phdr_offset;
869         if(write(newfd, &offset, sizeof(Elf_Off)) < 0) {
870             close(newfd);
871             return false;
872         }
873     }
874     close(newfd);
875
876     if (rename(strtmpl.c_str(), fName.c_str())) {
877         return false;
878     }
879
880     return true;
881 }
882
883
884 template<class ElfTypes>
885 void emitElf64<ElfTypes>::createNewPhdrRegion(dyn_hash_map<std::string, unsigned> &newNameIndexMapping) {
886     assert(!movePHdrsFirst);
887
888     unsigned phdr_size = oldEhdr->e_phnum * oldEhdr->e_phentsize;
889     if (createNewPhdr)
890         phdr_size += oldEhdr->e_phentsize;
891
892     unsigned align = 0;
893     if (currEndOffset % 8)
894         align = 8 - (currEndOffset % 8);
895
896     newEhdr->e_phoff = currEndOffset + align;
897     phdr_offset = newEhdr->e_phoff;
898
899     Address endaddr = currEndAddress;
900     currEndAddress += phdr_size + align;
901     currEndOffset += phdr_size + align;
902     loadSecTotalSize += phdr_size + align;
903
904     //libelf.so.1 is annoying.  It'll overwrite the data
905     // between sections with 0's, even if we've stuck the
906     // program headers in there.  Create a dummy section
907     // to contain the program headers.
908     phdrs_scn = elf_newscn(newElf);
909     Elf_Shdr *newshdr = ElfTypes::elf_getshdr(phdrs_scn);
910     const char *newname = ".dynphdrs";
911
912     secNames.push_back(newname);
913     newNameIndexMapping[newname] = secNames.size() - 1;
914     newshdr->sh_name = secNameIndex;
915     secNameIndex += strlen(newname) + 1;
916     newshdr->sh_flags = SHF_ALLOC;
917     if (isBlueGeneQ) newshdr->sh_flags = bgq_sh_flags;
918     newshdr->sh_type = SHT_PROGBITS;
919     newshdr->sh_offset = newEhdr->e_phoff;
920     newshdr->sh_addr = endaddr + align;
921     newshdr->sh_size = phdr_size;
922     newshdr->sh_link = SHN_UNDEF;
923     newshdr->sh_info = 0;
924     newshdr->sh_addralign = 4;
925     newshdr->sh_entsize = newEhdr->e_phentsize;
926     phdrSegOff = newshdr->sh_offset;
927     phdrSegAddr = newshdr->sh_addr;
928
929 }
930
931 template<class ElfTypes>
932 void emitElf64<ElfTypes>::fixPhdrs(unsigned &extraAlignSize) {
933     unsigned pgSize = getpagesize();
934     Elf_Phdr *old = oldPhdr;
935
936     newEhdr->e_phnum = oldEhdr->e_phnum;
937     newEhdr->e_phentsize = oldEhdr->e_phentsize;
938
939     if (createNewPhdr) {
940         newEhdr->e_phnum++;
941         if (hasRewrittenTLS && !TLSExists) newEhdr->e_phnum++;
942     }
943
944     bool added_new_sec = false;
945     bool replaced = false;
946
947     if (!hasPHdrSectionBug())
948         newPhdr = ElfTypes::elf_newphdr(newElf, newEhdr->e_phnum);
949     else {
950         newPhdr = (Elf_Phdr *) malloc(sizeof(Elf_Phdr) * newEhdr->e_phnum);
951     }
952     void *phdr_data = (void *) newPhdr;
953
954     Elf_Phdr newSeg;
955     bool last_load_segment = false;
956     for (unsigned i = 0; i < oldEhdr->e_phnum; i++) {
957         /*
958          * If we've created a new loadable segment, we need to insert a new
959          * program header amidst the other loadable segments.
960          *
961          * ELF format says:
962          *
963          * `Loadable segment entries in the program header table appear in
964          * ascending order, sorted on the p_vaddr member.'
965          *
966          * Note: replacing NOTE with LOAD section for bluegene systems
967          * does not follow this rule.
968          */
969
970         Elf_Phdr *insert_phdr = NULL;
971         if (createNewPhdr && !added_new_sec && firstNewLoadSec) {
972             if (i + 1 == oldEhdr->e_phnum) {
973                 insert_phdr = newPhdr + 1;
974
975             }
976             else if (old->p_type == PT_LOAD && (old + 1)->p_type != PT_LOAD) {
977                 // insert at end of loadable phdrs
978                 insert_phdr = newPhdr + 1;
979                 last_load_segment = true;
980             }
981             else if (old->p_type != PT_LOAD &&
982                      (old + 1)->p_type == PT_LOAD &&
983                      newSegmentStart < (old + 1)->p_vaddr) {
984                 // insert at beginning of loadable list (after the
985                 // current phdr)
986                 insert_phdr = newPhdr + 1;
987             }
988             else if (old->p_type == PT_LOAD &&
989                      (old + 1)->p_type == PT_LOAD &&
990                      newSegmentStart >= old->p_vaddr &&
991                      newSegmentStart < (old + 1)->p_vaddr) {
992                 // insert in middle of loadable list, after current
993                 insert_phdr = newPhdr + 1;
994             }
995             else if (i == 0 &&
996                      old->p_type == PT_LOAD &&
997                      newSegmentStart < old->p_vaddr) {
998                 // insert BEFORE current phdr
999                 insert_phdr = newPhdr;
1000                 newPhdr++;
1001             }
1002         }
1003
1004         if (insert_phdr) {
1005             newSeg.p_type = PT_LOAD;
1006             newSeg.p_offset = firstNewLoadSec->sh_offset;
1007             newSeg.p_vaddr = newSegmentStart;
1008             newSeg.p_paddr = newSeg.p_vaddr;
1009             newSeg.p_filesz = loadSecTotalSize - (newSegmentStart - firstNewLoadSec->sh_addr);
1010             newSeg.p_memsz = (currEndAddress - firstNewLoadSec->sh_addr) - (newSegmentStart - firstNewLoadSec->sh_addr);
1011             newSeg.p_flags = PF_R + PF_W + PF_X;
1012             newSeg.p_align = pgSize;
1013             memcpy(insert_phdr, &newSeg, oldEhdr->e_phentsize);
1014             added_new_sec = true;
1015             rewrite_printf("Added New program header : offset 0x%lx,addr 0x%lx file Size 0x%lx memsize 0x%lx \n",
1016                            newSeg.p_paddr, newSeg.p_vaddr, newSeg.p_filesz, newSeg.p_memsz);
1017         }
1018
1019         memcpy(newPhdr, old, oldEhdr->e_phentsize);
1020
1021         // Expand the data segment to include the new loadable sections
1022         // Also add a executable permission to the segment
1023
1024         if (old->p_type == PT_DYNAMIC) {
1025             newPhdr->p_vaddr = dynSegAddr;
1026             newPhdr->p_paddr = dynSegAddr;
1027             newPhdr->p_offset = dynSegOff;
1028             newPhdr->p_memsz = dynSegSize;
1029             newPhdr->p_filesz = newPhdr->p_memsz;
1030         }
1031         else if (old->p_type == PT_PHDR) {
1032             if (createNewPhdr && !movePHdrsFirst)
1033                 newPhdr->p_vaddr = phdrSegAddr;
1034             else if (createNewPhdr && movePHdrsFirst)
1035                 newPhdr->p_vaddr = old->p_vaddr - pgSize + library_adjust;
1036             else
1037                 newPhdr->p_vaddr = old->p_vaddr;
1038             newPhdr->p_offset = newEhdr->e_phoff;
1039             newPhdr->p_paddr = newPhdr->p_vaddr;
1040             newPhdr->p_filesz = sizeof(Elf_Phdr) * newEhdr->e_phnum;
1041             newPhdr->p_memsz = newPhdr->p_filesz;
1042         } else if (hasRewrittenTLS && old->p_type == PT_TLS) {
1043             newPhdr->p_offset = newTLSData->sh_offset;
1044             newPhdr->p_vaddr = newTLSData->sh_addr;
1045             newPhdr->p_paddr = newTLSData->sh_addr;
1046             newPhdr->p_filesz = newTLSData->sh_size;
1047             newPhdr->p_memsz = newTLSData->sh_size + old->p_memsz - old->p_filesz;
1048             newPhdr->p_align = newTLSData->sh_addralign;
1049         } else if (old->p_type == PT_LOAD) {
1050             if (!createNewPhdr && newPhdr->p_align > pgSize) { //not on bluegene
1051                 newPhdr->p_align = pgSize;
1052             }
1053             if (BSSExpandFlag) {
1054                 if (old->p_flags == 6 || old->p_flags == 7) {
1055                     newPhdr->p_memsz += loadSecTotalSize + extraAlignSize;
1056                     newPhdr->p_filesz = newPhdr->p_memsz;
1057                     newPhdr->p_flags = 7;
1058                 }
1059             }
1060
1061             if (movePHdrsFirst) {
1062                 if (!old->p_offset) {
1063                     if (newPhdr->p_vaddr) {
1064                         newPhdr->p_vaddr = old->p_vaddr - pgSize;
1065                         newPhdr->p_align = pgSize;
1066                     }
1067
1068                     newPhdr->p_paddr = newPhdr->p_vaddr;
1069                     newPhdr->p_filesz += pgSize;
1070                     newPhdr->p_memsz = newPhdr->p_filesz;
1071                 } else {
1072                     newPhdr->p_offset += pgSize;
1073                     newPhdr->p_align = pgSize;
1074                 }
1075                 if (newPhdr->p_vaddr) {
1076                     newPhdr->p_vaddr += library_adjust;
1077                     newPhdr->p_paddr += library_adjust;
1078                 }
1079             }
1080         } else if (replaceNOTE && old->p_type == PT_NOTE && !replaced) {
1081             replaced = true;
1082             newPhdr->p_type = PT_LOAD;
1083             newPhdr->p_offset = firstNewLoadSec->sh_offset;
1084             newPhdr->p_vaddr = newSegmentStart;
1085             newPhdr->p_paddr = newPhdr->p_vaddr;
1086             newPhdr->p_filesz = loadSecTotalSize - (newSegmentStart - firstNewLoadSec->sh_addr);
1087             newPhdr->p_memsz =
1088                     (currEndAddress - firstNewLoadSec->sh_addr) - (newSegmentStart - firstNewLoadSec->sh_addr);
1089             newPhdr->p_flags = PF_R + PF_W + PF_X;
1090             newPhdr->p_align = pgSize;
1091         }
1092         else if (old->p_type == PT_INTERP && movePHdrsFirst
1093                  && old->p_offset && newEhdr->e_phnum >= oldEhdr->e_phnum) {
1094             Elf_Off interp_shift = library_adjust; //(Elf_Off) oldEhdr->e_phentsize * (Elf_Off)(newEhdr->e_phnum - oldEhdr->e_phnum);
1095             newPhdr->p_offset += interp_shift;
1096             newPhdr->p_vaddr += interp_shift;
1097             newPhdr->p_paddr += interp_shift;
1098         }
1099         else if (movePHdrsFirst && old->p_offset) {
1100             newPhdr->p_offset += pgSize;
1101             if (newPhdr->p_vaddr) {
1102                 newPhdr->p_vaddr += library_adjust;
1103                 newPhdr->p_paddr += library_adjust;
1104             }
1105         }
1106
1107         /* For BlueGeneQ statically linked binary, we cannot create a new LOAD section,
1108             hence we extend existing LOAD section to include instrmentation.
1109                A new LOAD section must be aligned to 1MB in BlueGene.
1110              But if we create a LOAD segment after 1MB, the TOC pointer will no longer be able to reach the new segment,
1111              as we have only 4 byte offset from TOC */
1112
1113         if (0 && isBlueGeneQ && isStaticBinary && last_load_segment) {
1114
1115             // add new load to this segment
1116             newPhdr->p_filesz = (newSeg.p_offset - newPhdr->p_offset) + loadSecTotalSize -
1117                                 (newSegmentStart - firstNewLoadSec->sh_addr);
1118             newPhdr->p_memsz = (newSegmentStart - newPhdr->p_vaddr) + (currEndAddress - firstNewLoadSec->sh_addr) -
1119                                (newSegmentStart - firstNewLoadSec->sh_addr);
1120             newPhdr->p_flags = PF_R + PF_W + PF_X;
1121             last_load_segment = false;
1122
1123             // add new load to this segment
1124         } else {
1125             if (insert_phdr)
1126                 newPhdr++;
1127         }
1128
1129         rewrite_printf("Existing program header: type %u (%s), offset 0x%lx, addr 0x%lx\n",
1130                        newPhdr->p_type, phdrTypeStr(newPhdr->p_type).c_str(), newPhdr->p_offset, newPhdr->p_vaddr);
1131
1132         newPhdr++;
1133
1134         old++;
1135     }
1136
1137     if (hasRewrittenTLS && !TLSExists) {
1138         newPhdr->p_type = PT_TLS;
1139         newPhdr->p_offset = newTLSData->sh_offset;
1140         newPhdr->p_vaddr = newTLSData->sh_addr;
1141         newPhdr->p_filesz = newTLSData->sh_size;
1142         newPhdr->p_memsz = newTLSData->sh_size;
1143         newPhdr->p_align = newTLSData->sh_addralign;
1144     }
1145
1146     if (!phdrs_scn)
1147         return;
1148     //We made a new section to contain the program headers--keeps
1149     // libelf from overwriting the program headers data when outputing
1150     // sections.  Fill in the new section's data with what we just wrote.
1151     Elf_Data *data = elf_newdata(phdrs_scn);
1152     size_t total_size = (size_t) newEhdr->e_phnum * (size_t) newEhdr->e_phentsize;
1153     data->d_buf = malloc(total_size);
1154     memcpy(data->d_buf, phdr_data, total_size);
1155     data->d_size = total_size;
1156     data->d_align = 0;
1157     data->d_off = 0;
1158     data->d_type = ELF_T_BYTE;
1159     data->d_version = 1;
1160 }
1161
1162 #if !defined(DT_GNU_HASH)
1163 #define DT_GNU_HASH 0x6ffffef5
1164 #endif
1165 #if !defined(DT_GNU_CONFLICT)
1166 #define DT_GNU_CONFLICT 0x6ffffef8
1167 #endif
1168
1169 //This method updates the .dynamic section to reflect the changes to the relocation section
1170 template<class ElfTypes>
1171 void emitElf64<ElfTypes>::updateDynamic(unsigned tag, Elf_Addr val) {
1172     if (isStaticBinary) return;
1173     // This is for REL/RELA if it doesnt already exist in the original binary;
1174     dynamicSecData[tag][0]->d_tag = tag;
1175     switch (dynamicSecData[tag][0]->d_tag) {
1176         case DT_STRSZ:
1177         case DT_RELSZ:
1178         case DT_RELASZ:
1179         case DT_PLTRELSZ:
1180         case DT_RELACOUNT:
1181         case DT_RELENT:
1182         case DT_RELAENT:
1183             dynamicSecData[tag][0]->d_un.d_val = val;
1184             break;
1185         case DT_HASH:
1186         case DT_GNU_HASH:
1187         case DT_SYMTAB:
1188         case DT_STRTAB:
1189         case DT_REL:
1190         case DT_RELA:
1191         case DT_VERSYM:
1192         case DT_JMPREL:
1193             dynamicSecData[tag][0]->d_un.d_ptr = val;
1194             break;
1195         case DT_VERNEED:
1196             dynamicSecData[tag][0]->d_un.d_ptr = val;
1197             dynamicSecData[DT_VERNEEDNUM][0]->d_un.d_val = verneednum;
1198             break;
1199         case DT_VERDEF:
1200             dynamicSecData[tag][0]->d_un.d_ptr = val;
1201             dynamicSecData[DT_VERDEFNUM][0]->d_un.d_val = verdefnum;
1202             break;
1203     }
1204 }
1205
1206 /* This method sets _end and _END_ to the starting position of the heap in the
1207  * new binary. 
1208  */
1209 template<class ElfTypes>
1210 void emitElf64<ElfTypes>::updateSymbols(Elf_Data *symtabData, Elf_Data *strData, unsigned long loadSecsSize) {
1211     unsigned pgSize = (unsigned) getpagesize();
1212     if (symtabData && strData && loadSecsSize) {
1213         Elf_Sym *symPtr = (Elf_Sym *) symtabData->d_buf;
1214         for (unsigned int i = 0; i < symtabData->d_size / (sizeof(Elf_Sym)); i++, symPtr++) {
1215             if (!(strcmp("_end", (char *) strData->d_buf + symPtr->st_name))) {
1216                 if (newSegmentStart >= symPtr->st_value) {
1217                     symPtr->st_value += ((newSegmentStart - symPtr->st_value) + loadSecsSize);
1218
1219                     // Advance the location to the next page boundary
1220                     symPtr->st_value = (symPtr->st_value & ~(pgSize - 1)) + pgSize;
1221                 }
1222             }
1223             if (!(strcmp("_END_", (char *) strData->d_buf + symPtr->st_name))) {
1224                 if (newSegmentStart > symPtr->st_value) {
1225                     symPtr->st_value += (newSegmentStart - symPtr->st_value) + loadSecsSize;
1226
1227                     // Advance the location to the next page boundary
1228                     symPtr->st_value = (symPtr->st_value & ~(pgSize - 1)) + pgSize;
1229                 }
1230             }
1231         }
1232     }
1233 }
1234
1235 template<class ElfTypes>
1236 bool emitElf64<ElfTypes>::createLoadableSections(Elf_Shdr *&shdr, unsigned &extraAlignSize,
1237                                                  dyn_hash_map<std::string, unsigned> &newNameIndexMapping,
1238                                                  unsigned &sectionNumber) {
1239     Elf_Scn *newscn;
1240     Elf_Data *newdata = NULL;
1241
1242     Elf_Shdr *newshdr;
1243     std::vector<Elf_Shdr *> updateDynLinkShdr;
1244     std::vector<Elf_Shdr *> updateStrLinkShdr;
1245     firstNewLoadSec = NULL;
1246     unsigned pgSize = getpagesize();
1247     unsigned strtabIndex = 0;
1248     unsigned dynsymIndex = 0;
1249     Elf_Shdr *prevshdr = NULL;
1250
1251     /*
1252      * Order the new sections such that those with explicit
1253      * memory offsets come before those without (that will be placed
1254      * after the non-zero sections).
1255      *
1256      * zstart is used to place the first zero-offset section if
1257      * no non-zero-offset sections exist.
1258      */
1259     Address zstart = emitElfUtils::orderLoadableSections(obj, newSecs);
1260
1261     for (unsigned i = 0; i < newSecs.size(); i++) {
1262         if (!newSecs[i]->isLoadable()) {
1263             nonLoadableSecs.push_back(newSecs[i]);
1264             continue;
1265         }
1266         secNames.push_back(newSecs[i]->getRegionName());
1267         newNameIndexMapping[newSecs[i]->getRegionName()] = secNames.size() - 1;
1268         sectionNumber++;
1269         // Add a new loadable section
1270         if ((newscn = elf_newscn(newElf)) == NULL) {
1271             log_elferror(err_func_, "unable to create new function");
1272             return false;
1273         }
1274         if ((newdata = elf_newdata(newscn)) == NULL) {
1275             log_elferror(err_func_, "unable to create section data");
1276             return false;
1277         }
1278         memset(newdata, 0, sizeof(Elf_Data));
1279
1280         // Fill out the new section header
1281         newshdr = ElfTypes::elf_getshdr(newscn);
1282         newshdr->sh_name = secNameIndex;
1283         newshdr->sh_flags = 0;
1284         newshdr->sh_type = SHT_PROGBITS;
1285         switch (newSecs[i]->getRegionType()) {
1286             case Region::RT_TEXTDATA:
1287                 newshdr->sh_flags = SHF_EXECINSTR | SHF_ALLOC | SHF_WRITE;
1288                 break;
1289             case Region::RT_TEXT:
1290                 newshdr->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
1291                 break;
1292             case Region::RT_BSS:
1293                 newshdr->sh_type = SHT_NOBITS;
1294                 //FALLTHROUGH
1295             case Region::RT_DATA:
1296                 newshdr->sh_flags = SHF_WRITE | SHF_ALLOC;
1297                 break;
1298             default:
1299                 break;
1300         }
1301
1302         if (shdr->sh_type == SHT_NOBITS) {
1303             newshdr->sh_offset = shdr->sh_offset;
1304         } else if (!firstNewLoadSec || !newSecs[i]->getDiskOffset()) {
1305             newshdr->sh_offset = shdr->sh_offset + shdr->sh_size;
1306         } else {
1307             // The offset can be computed by determing the difference from
1308             // the first new loadable section
1309             newshdr->sh_offset = firstNewLoadSec->sh_offset +
1310                                  (newSecs[i]->getDiskOffset() - firstNewLoadSec->sh_addr);
1311
1312             // Account for inter-section spacing due to alignment constraints
1313             loadSecTotalSize += newshdr->sh_offset - (shdr->sh_offset + shdr->sh_size);
1314         }
1315
1316         if (newSecs[i]->getDiskOffset())
1317             newshdr->sh_addr = newSecs[i]->getDiskOffset() + library_adjust;
1318         else if (!prevshdr) {
1319             newshdr->sh_addr = zstart + library_adjust;
1320         }
1321         else {
1322             newshdr->sh_addr = prevshdr->sh_addr + prevshdr->sh_size;
1323         }
1324
1325         newshdr->sh_link = SHN_UNDEF;
1326         newshdr->sh_info = 0;
1327         newshdr->sh_addralign = newSecs[i]->getMemAlignment();
1328         newshdr->sh_entsize = 0;
1329
1330         // TLS section
1331         if (newSecs[i]->isTLS()) {
1332             newTLSData = newshdr;
1333             newshdr->sh_flags |= SHF_TLS;
1334         }
1335
1336         if (newSecs[i]->getRegionType() == Region::RT_REL ||
1337             newSecs[i]->getRegionType() == Region::RT_PLTREL)    //Relocation section
1338         {
1339             newshdr->sh_type = SHT_REL;
1340             newshdr->sh_flags = SHF_ALLOC;
1341             newshdr->sh_entsize = sizeof(Elf_Rel);
1342             updateDynLinkShdr.push_back(newshdr);
1343             newdata->d_type = ELF_T_REL;
1344             newdata->d_align = 4;
1345             if (newSecs[i]->getRegionType() == Region::RT_REL)
1346                 updateDynamic(DT_REL, newshdr->sh_addr);
1347             else if (newSecs[i]->getRegionType() == Region::RT_PLTREL)
1348                 updateDynamic(DT_JMPREL, newshdr->sh_addr);
1349         }
1350         else if (newSecs[i]->getRegionType() == Region::RT_RELA ||
1351                  newSecs[i]->getRegionType() == Region::RT_PLTRELA) //Relocation section
1352         {
1353             newshdr->sh_type = SHT_RELA;
1354             newshdr->sh_flags = SHF_ALLOC;
1355             newshdr->sh_entsize = sizeof(Elf_Rela);
1356             updateDynLinkShdr.push_back(newshdr);
1357             newdata->d_type = ELF_T_RELA;
1358             newdata->d_align = 4;
1359             if (newSecs[i]->getRegionType() == Region::RT_RELA)
1360                 updateDynamic(DT_RELA, newshdr->sh_addr);
1361             else if (newSecs[i]->getRegionType() == Region::RT_PLTRELA)
1362                 updateDynamic(DT_JMPREL, newshdr->sh_addr);
1363         }
1364         else if (newSecs[i]->getRegionType() == Region::RT_STRTAB)    //String table Section
1365         {
1366             newshdr->sh_type = SHT_STRTAB;
1367             newshdr->sh_entsize = 1;
1368             newdata->d_type = ELF_T_BYTE;
1369             newshdr->sh_link = SHN_UNDEF;
1370             newshdr->sh_flags = SHF_ALLOC;
1371             newdata->d_align = 1;
1372             dynStrData = newdata;
1373             strtabIndex = secNames.size() - 1;
1374             newshdr->sh_addralign = 1;
1375             updateDynamic(DT_STRTAB, newshdr->sh_addr);
1376             updateDynamic(DT_STRSZ, newSecs[i]->getDiskSize());
1377         }
1378         else if (newSecs[i]->getRegionType() == Region::RT_SYMTAB) {
1379             newshdr->sh_type = SHT_DYNSYM;
1380             newshdr->sh_entsize = sizeof(Elf_Sym);
1381             newdata->d_type = ELF_T_SYM;
1382             newdata->d_align = 4;
1383             dynsymData = newdata;
1384             newshdr->sh_link = secNames.size();   //.symtab section should have sh_link = index of .strtab for .dynsym
1385             newshdr->sh_flags = SHF_ALLOC;
1386             dynsymIndex = secNames.size() - 1;
1387             updateDynamic(DT_SYMTAB, newshdr->sh_addr);
1388         }
1389         else if (newSecs[i]->getRegionType() == Region::RT_DYNAMIC) {
1390             newshdr->sh_entsize = sizeof(Elf_Dyn);
1391             newshdr->sh_type = SHT_DYNAMIC;
1392             newdata->d_type = ELF_T_DYN;
1393             newdata->d_align = 4;
1394             updateStrLinkShdr.push_back(newshdr);
1395             newshdr->sh_flags = SHF_ALLOC | SHF_WRITE;
1396             dynSegOff = newshdr->sh_offset;
1397             dynSegAddr = newshdr->sh_addr;
1398             dynSegSize = newSecs[i]->getDiskSize();
1399         }
1400         else if (newSecs[i]->getRegionType() == Region::RT_HASH) {
1401             newshdr->sh_entsize = sizeof(Elf_Word);
1402             newshdr->sh_type = SHT_HASH;
1403             newdata->d_type = ELF_T_WORD;
1404             newdata->d_align = 4;
1405             updateDynLinkShdr.push_back(newshdr);
1406             newshdr->sh_flags = SHF_ALLOC;
1407             newshdr->sh_info = 0;
1408             updateDynamic(DT_HASH, newshdr->sh_addr);
1409         }
1410         else if (newSecs[i]->getRegionType() == Region::RT_SYMVERSIONS) {
1411             newshdr->sh_type = SHT_GNU_versym;
1412             newshdr->sh_entsize = sizeof(Elf_Half);
1413             newshdr->sh_addralign = 2;
1414             newdata->d_type = ELF_T_HALF;
1415             newdata->d_align = 2;
1416             updateDynLinkShdr.push_back(newshdr);
1417             newshdr->sh_flags = SHF_ALLOC;
1418             updateDynamic(DT_VERSYM, newshdr->sh_addr);
1419         }
1420         else if (newSecs[i]->getRegionType() == Region::RT_SYMVERNEEDED) {
1421             newshdr->sh_type = SHT_GNU_verneed;
1422             newshdr->sh_entsize = 0;
1423             newshdr->sh_addralign = 4;
1424             newdata->d_type = ELF_T_VNEED;
1425             newdata->d_align = 4;
1426             updateStrLinkShdr.push_back(newshdr);
1427             newshdr->sh_flags = SHF_ALLOC;
1428             newshdr->sh_info = 2;
1429             updateDynamic(DT_VERNEED, newshdr->sh_addr);
1430         }
1431         else if (newSecs[i]->getRegionType() == Region::RT_SYMVERDEF) {
1432             newshdr->sh_type = SHT_GNU_verdef;
1433             newshdr->sh_entsize = 0;
1434             newdata->d_type = ELF_T_VDEF;
1435             newdata->d_align = 4;
1436             updateStrLinkShdr.push_back(newshdr);
1437             newshdr->sh_flags = SHF_ALLOC;
1438             updateDynamic(DT_VERDEF, newshdr->sh_addr);
1439         }
1440
1441         if (isBlueGeneQ) newshdr->sh_flags = bgq_sh_flags;
1442
1443         // Check to make sure the (vaddr for the start of the new segment - the offset) is page aligned
1444         if (!firstNewLoadSec) {
1445             Offset newoff =
1446                     newshdr->sh_offset - (newshdr->sh_offset & (pgSize - 1)) + (newshdr->sh_addr & (pgSize - 1));
1447             if (newoff < newshdr->sh_offset)
1448                 newoff += pgSize;
1449             extraAlignSize += newoff - newshdr->sh_offset;
1450             newshdr->sh_offset = newoff;
1451
1452             // For now, bluegene is the only system for which createNewPhdr is false.
1453             // Bluegene compute nodes have a 1MB alignment restructions on PT_LOAD section
1454             // When we are replaceing PT_NOTE with PT_LOAD, we need to make sure the new PT_LOAD is 1MB aligned
1455             if (!createNewPhdr && replaceNOTE) {
1456                 Offset newaddr = newshdr->sh_addr - (newshdr->sh_addr & (0x100000 - 1));
1457                 if (newaddr < newshdr->sh_addr)
1458                     newaddr += 0x100000;
1459                 newshdr->sh_addr = newaddr;
1460             }
1461             newSegmentStart = newshdr->sh_addr;
1462         }
1463
1464         //Set up the data
1465         newdata->d_buf = malloc(newSecs[i]->getDiskSize());
1466         memcpy(newdata->d_buf, newSecs[i]->getPtrToRawData(), newSecs[i]->getDiskSize());
1467         newdata->d_off = 0;
1468         newdata->d_size = newSecs[i]->getDiskSize();
1469         if (!newdata->d_align)
1470             newdata->d_align = newshdr->sh_addralign;
1471         newshdr->sh_size = newdata->d_size;
1472
1473         if (newshdr->sh_type == SHT_NOBITS) {
1474             currEndOffset = newshdr->sh_offset;
1475         } else {
1476             loadSecTotalSize += newshdr->sh_size;
1477             currEndOffset = newshdr->sh_offset + newshdr->sh_size;
1478         }
1479         currEndAddress = newshdr->sh_addr + newshdr->sh_size;
1480
1481         rewrite_printf("new section %s addr = %lx off = %lx size = %lx\n",
1482                        newSecs[i]->getRegionName().c_str(), newshdr->sh_addr, newshdr->sh_offset,
1483                        newshdr->sh_size);
1484
1485         newdata->d_version = 1;
1486         if (newshdr->sh_addralign < newdata->d_align) {
1487             newshdr->sh_addralign = newdata->d_align;
1488         }
1489
1490         if (0 > elf_update(newElf, ELF_C_NULL)) {
1491             return false;
1492         }
1493
1494         shdr = newshdr;
1495         if (!firstNewLoadSec)
1496             firstNewLoadSec = shdr;
1497         secNameIndex += newSecs[i]->getRegionName().size() + 1;
1498         prevshdr = newshdr;
1499     }
1500
1501     for (unsigned i = 0; i < updateDynLinkShdr.size(); i++) {
1502         newshdr = updateDynLinkShdr[i];
1503         newshdr->sh_link = dynsymIndex;
1504     }
1505
1506     for (unsigned i = 0; i < updateStrLinkShdr.size(); i++) {
1507         newshdr = updateStrLinkShdr[i];
1508         newshdr->sh_link = strtabIndex;
1509     }
1510
1511
1512     return true;
1513 }
1514
1515 template<class ElfTypes>
1516 bool emitElf64<ElfTypes>::addSectionHeaderTable(Elf_Shdr *shdr) {
1517     Elf_Scn *newscn;
1518     Elf_Data *newdata = NULL;
1519     Elf_Shdr *newshdr;
1520
1521     if ((newscn = elf_newscn(newElf)) == NULL) {
1522         log_elferror(err_func_, "unable to create new function");
1523         return false;
1524     }
1525     if ((newdata = elf_newdata(newscn)) == NULL) {
1526         log_elferror(err_func_, "unable to create section data");
1527         return false;
1528     }
1529     //Fill out the new section header
1530     newshdr = ElfTypes::elf_getshdr(newscn);
1531     newshdr->sh_name = secNameIndex;
1532     secNames.push_back(".shstrtab");
1533     secNameIndex += 10;
1534     newshdr->sh_type = SHT_STRTAB;
1535     newshdr->sh_entsize = 1;
1536     newdata->d_type = ELF_T_BYTE;
1537     newshdr->sh_link = SHN_UNDEF;
1538     newshdr->sh_flags = 0;
1539
1540     newshdr->sh_offset = shdr->sh_offset + shdr->sh_size;
1541     newshdr->sh_addr = 0;
1542     newshdr->sh_info = 0;
1543     newshdr->sh_addralign = 4;
1544
1545     //Set up the data
1546     newdata->d_buf = (char *) malloc(secNameIndex);
1547     char *ptr = (char *) newdata->d_buf;
1548     for (unsigned i = 0; i < secNames.size(); i++) {
1549         memcpy(ptr, secNames[i].c_str(), secNames[i].length());
1550         memcpy(ptr + secNames[i].length(), "\0", 1);
1551         ptr += secNames[i].length() + 1;
1552     }
1553
1554     newdata->d_size = secNameIndex;
1555     newshdr->sh_size = newdata->d_size;
1556     //elf_update(newElf, ELF_C_NULL);
1557
1558     newdata->d_align = 4;
1559     newdata->d_version = 1;
1560     return true;
1561 }
1562
1563 template<class ElfTypes>
1564 bool emitElf64<ElfTypes>::createNonLoadableSections(Elf_Shdr *&shdr) {
1565     Elf_Scn *newscn;
1566     Elf_Data *newdata = NULL;
1567     Elf_Shdr *newshdr;
1568
1569     Elf_Shdr *prevshdr = shdr;
1570     //All of them that are left are non-loadable. stack'em up at the end.
1571     for (unsigned i = 0; i < nonLoadableSecs.size(); i++) {
1572         secNames.push_back(nonLoadableSecs[i]->getRegionName());
1573         // Add a new non-loadable section
1574         if ((newscn = elf_newscn(newElf)) == NULL) {
1575             log_elferror(err_func_, "unable to create new function");
1576             return false;
1577         }
1578         if ((newdata = elf_newdata(newscn)) == NULL) {
1579             log_elferror(err_func_, "unable to create section data");
1580             return false;
1581         }
1582
1583         //Fill out the new section header
1584         newshdr = ElfTypes::elf_getshdr(newscn);
1585         newshdr->sh_name = secNameIndex;
1586         secNameIndex += nonLoadableSecs[i]->getRegionName().length() + 1;
1587         if (nonLoadableSecs[i]->getRegionType() == Region::RT_TEXT)        //Text Section
1588         {
1589             newshdr->sh_type = SHT_PROGBITS;
1590             newshdr->sh_flags = SHF_EXECINSTR | SHF_WRITE;
1591             newshdr->sh_entsize = 1;
1592             newdata->d_type = ELF_T_BYTE;
1593         }
1594         else if (nonLoadableSecs[i]->getRegionType() == Region::RT_DATA)    //Data Section
1595         {
1596             newshdr->sh_type = SHT_PROGBITS;
1597             newshdr->sh_flags = SHF_WRITE;
1598             newshdr->sh_entsize = 1;
1599             newdata->d_type = ELF_T_BYTE;
1600         }
1601         else if (nonLoadableSecs[i]->getRegionType() == Region::RT_REL)    //Relocations section
1602         {
1603             newshdr->sh_type = SHT_REL;
1604             newshdr->sh_flags = SHF_WRITE;
1605             newshdr->sh_entsize = sizeof(Elf_Rel);
1606             newdata->d_type = ELF_T_BYTE;
1607         }
1608         else if (nonLoadableSecs[i]->getRegionType() == Region::RT_RELA)    //Relocations section
1609         {
1610             newshdr->sh_type = SHT_RELA;
1611             newshdr->sh_flags = SHF_WRITE;
1612             newshdr->sh_entsize = sizeof(Elf_Rela);
1613             newdata->d_type = ELF_T_BYTE;
1614         }
1615         else if (nonLoadableSecs[i]->getRegionType() == Region::RT_SYMTAB) {
1616             newshdr->sh_type = SHT_SYMTAB;
1617             newshdr->sh_entsize = sizeof(Elf_Sym);
1618             newdata->d_type = ELF_T_SYM;
1619             newshdr->sh_link = secNames.size();   //.symtab section should have sh_link = index of .strtab
1620             newshdr->sh_flags = 0;
1621         }
1622         else if (nonLoadableSecs[i]->getRegionType() == Region::RT_STRTAB)    //String table Section
1623         {
1624             newshdr->sh_type = SHT_STRTAB;
1625             newshdr->sh_entsize = 1;
1626             newdata->d_type = ELF_T_BYTE;
1627             newshdr->sh_link = SHN_UNDEF;
1628             newshdr->sh_flags = 0;
1629         }
1630         /*
1631           else if(nonLoadableSecs[i]->getFlags() & Section::dynsymtabSection)
1632           {
1633       newshdr->sh_type = SHT_DYNSYM;
1634       newshdr->sh_entsize = sizeof(Elf_Sym);
1635       newdata->d_type = ELF_T_SYM;
1636       //newshdr->sh_link = newSecSize+i+1;   //.symtab section should have sh_link = index of .strtab
1637       newshdr->sh_flags=  SHF_ALLOC | SHF_WRITE;
1638           }*/
1639         newshdr->sh_offset = prevshdr->sh_offset + prevshdr->sh_size;
1640         if (prevshdr->sh_type == SHT_NOBITS) {
1641             newshdr->sh_offset = prevshdr->sh_offset;
1642         } else {
1643             newshdr->sh_offset = prevshdr->sh_offset + prevshdr->sh_size;
1644         }
1645         if (newshdr->sh_offset < currEndOffset) {
1646             newshdr->sh_offset = currEndOffset;
1647         }
1648         newshdr->sh_addr = 0;
1649         newshdr->sh_info = 0;
1650         newshdr->sh_addralign = 4;
1651
1652         //Set up the data
1653         newdata->d_buf = nonLoadableSecs[i]->getPtrToRawData();
1654         newdata->d_size = nonLoadableSecs[i]->getDiskSize();
1655         newshdr->sh_size = newdata->d_size;
1656         //elf_update(newElf, ELF_C_NULL);
1657
1658         newdata->d_align = 4;
1659         newdata->d_off = 0;
1660         newdata->d_version = 1;
1661         currEndOffset = newshdr->sh_offset + newshdr->sh_size;
1662         //currEndAddress = newshdr->sh_addr + newshdr->sh_size;
1663         /* DEBUG */
1664
1665         prevshdr = newshdr;
1666     }
1667     shdr = prevshdr;
1668     return true;
1669 }
1670
1671 /* Regenerates the .symtab, .strtab sections from the symbols
1672  * Add new .dynsym, .dynstr sections for the newly added dynamic symbols
1673  * Method - For every symbol call createElfSymbol to get a Elf_Sym corresposnding
1674  *          to a Symbol object. Accumulate all and their names to form the sections
1675  *          and add them to the list of new sections
1676  */
1677 template<class ElfTypes>
1678 bool emitElf64<ElfTypes>::createSymbolTables(vector<Symbol *> &allSymbols) {
1679     rewrite_printf(" createSymbolTables for %s \n", obj->name().c_str());
1680     unsigned i;
1681
1682     //Symbol table(.symtab) symbols
1683     vector<Elf_Sym *> symbols;
1684
1685     //Symbol table(.dynsymtab) symbols
1686     vector<Elf_Sym *> dynsymbols;
1687
1688     unsigned symbolNamesLength = 1, dynsymbolNamesLength = 1;
1689     dyn_hash_map<string, unsigned long> dynSymNameMapping;
1690     vector<string> symbolStrs, dynsymbolStrs;
1691     vector<Symbol *> dynsymVector;
1692     vector<Symbol *> allDynSymbols;
1693     vector<Symbol *> allSymSymbols;
1694
1695     dyn_hash_map<int, Region *> secTagRegionMapping = obj->getObject()->getTagRegionMapping();
1696
1697     Region *sec;
1698     auto foundRegion = secTagRegionMapping.find(DT_STRTAB);
1699     if ((foundRegion != secTagRegionMapping.end()) && (foundRegion->second != NULL)) {
1700         // .dynstr
1701         sec = foundRegion->second;
1702         olddynStrData = (char *) (sec->getPtrToRawData());
1703         olddynStrSize = sec->getMemSize();
1704         dynsymbolNamesLength = olddynStrSize + 1;
1705     }
1706
1707     // Copy over the previous library dependencies
1708     vector<string> elibs;
1709     obj->getObject()->getDependencies(elibs);
1710     for (auto iter = elibs.begin();
1711          iter != elibs.end(); ++iter) {
1712         addDTNeeded(*iter);
1713     }
1714
1715     //Initialize the list of new prereq libraries
1716     set<string> &plibs = obj->getObject()->prereq_libs;
1717     for (auto i = plibs.begin(); i != plibs.end(); i++) {
1718         addDTNeeded(*i);
1719     }
1720     new_dynamic_entries = obj->getObject()->new_dynamic_entries;
1721     Object *object = obj->getObject();
1722     // recreate a "dummy symbol"
1723     Elf_Sym *sym = new Elf_Sym();
1724     symbolStrs.push_back("");
1725     // We should increment this here, but for reasons I don't understand we create it with a size of
1726     // 1.
1727     //symbolNamesLength++;
1728     sym->st_name = 0;
1729     sym->st_value = 0;
1730     sym->st_size = 0;
1731     sym->st_other = 0;
1732     sym->st_info = ELF64_ST_INFO(STB_LOCAL, STT_NOTYPE);
1733     sym->st_shndx = SHN_UNDEF;
1734
1735     symbols.push_back(sym);
1736     if (!obj->isStaticBinary()) {
1737         dynsymbols.push_back(sym);
1738         dynsymVector.push_back(Symbol::magicEmitElfSymbol());
1739         versionSymTable.push_back(0);
1740     }
1741
1742     if (obj->isStaticBinary()) {
1743         // Static binary case
1744         vector<Region *> newRegs;
1745         obj->getAllNewRegions(newRegs);
1746         if (newRegs.size()) {
1747             emitElfStatic linker(obj->getAddressWidth(), isStripped);
1748
1749             emitElfStatic::StaticLinkError err;
1750             std::string errMsg;
1751             linkedStaticData = linker.linkStatic(obj, err, errMsg);
1752             if (!linkedStaticData) {
1753                 std::string linkStaticError =
1754                         std::string("Failed to link to static library code into the binary: ") +
1755                         emitElfStatic::printStaticLinkError(err) + std::string(" = ")
1756                         + errMsg;
1757                 setSymtabError(Emit_Error);
1758                 symtab_log_perror(linkStaticError.c_str());
1759                 return false;
1760             }
1761
1762             hasRewrittenTLS = linker.hasRewrittenTLS();
1763
1764             // Find the end of the new Regions
1765             obj->getAllNewRegions(newRegs);
1766
1767             Offset lastRegionAddr = 0, lastRegionSize = 0;
1768             vector<Region *>::iterator newRegIter;
1769             for (newRegIter = newRegs.begin(); newRegIter != newRegs.end();
1770                  ++newRegIter) {
1771                 if ((*newRegIter)->getDiskOffset() > lastRegionAddr) {
1772                     lastRegionAddr = (*newRegIter)->getDiskOffset();
1773                     lastRegionSize = (*newRegIter)->getDiskSize();
1774                 }
1775             }
1776
1777             if (!emitElfUtils::updateHeapVariables(obj, lastRegionAddr + lastRegionSize)) {
1778                 return false;
1779             }
1780         }
1781     }
1782
1783     for (i = 0; i < allSymbols.size(); i++) {
1784         if (allSymbols[i]->isInSymtab()) {
1785             allSymSymbols.push_back(allSymbols[i]);
1786         }
1787         if (!obj->isStaticBinary()) {
1788             if (allSymbols[i]->isInDynSymtab()) {
1789                 allDynSymbols.push_back(allSymbols[i]);
1790             }
1791         }
1792     }
1793
1794     int max_index = -1;
1795     for (i = 0; i < allDynSymbols.size(); i++) {
1796         if (max_index < allDynSymbols[i]->getIndex())
1797             max_index = allDynSymbols[i]->getIndex();
1798     }
1799     for (i = 0; i < allDynSymbols.size(); i++) {
1800         if (allDynSymbols[i]->getIndex() == -1) {
1801             max_index++;
1802             allDynSymbols[i]->setIndex(max_index);
1803         }
1804
1805         if (allDynSymbols[i]->getStrIndex() == -1) {
1806             // New Symbol - append to the list of strings
1807             dynsymbolStrs.push_back(allDynSymbols[i]->getMangledName().c_str());
1808             allDynSymbols[i]->setStrIndex(dynsymbolNamesLength);
1809             dynsymbolNamesLength += allDynSymbols[i]->getMangledName().length() + 1;
1810         }
1811
1812     }
1813     // reorder allSymbols based on index
1814     std::sort(allDynSymbols.begin(), allDynSymbols.end(), sortByIndex());
1815
1816     max_index = -1;
1817     for (i = 0; i < allSymSymbols.size(); i++) {
1818         if (max_index < allSymSymbols[i]->getIndex())
1819             max_index = allSymSymbols[i]->getIndex();
1820     }
1821
1822     for (i = 0; i < allSymSymbols.size(); i++) {
1823         if (allSymSymbols[i]->getIndex() == -1) {
1824             max_index++;
1825             allSymSymbols[i]->setIndex(max_index);
1826         }
1827     }
1828
1829     std::sort(allSymSymbols.begin(), allSymSymbols.end(), sortByIndex());
1830
1831     /* We regenerate symtab and symstr section. We do not
1832        maintain the order of the strings and symbols as it was in
1833        the original binary. Hence, the strings in symstr have new order and
1834        new index.
1835        On the other hand, we do not regenerate dynsym and dynstr section. We copy over
1836        old symbols and string in the original order as it was in the
1837        original binary. We preserve sh_index of Elf symbols (from Symbol's strIndex). We append
1838        new symbols and string that we create for the new binary (targ*, versions etc).
1839     */
1840
1841     for (i = 0; i < allSymSymbols.size(); i++) {
1842         //allSymSymbols[i]->setStrIndex(symbolNamesLength);
1843         createElfSymbol(allSymSymbols[i], symbolNamesLength, symbols);
1844         symbolStrs.push_back(allSymSymbols[i]->getMangledName());
1845         symbolNamesLength += allSymSymbols[i]->getMangledName().length() + 1;
1846     }
1847     for (i = 0; i < allDynSymbols.size(); i++) {
1848         createElfSymbol(allDynSymbols[i], allDynSymbols[i]->getStrIndex(), dynsymbols, true);
1849         dynSymNameMapping[allDynSymbols[i]->getMangledName().c_str()] = allDynSymbols[i]->getIndex();
1850         dynsymVector.push_back(allDynSymbols[i]);
1851     }
1852
1853     //reconstruct .symtab section
1854     Elf_Sym *syms = (Elf_Sym *) malloc(symbols.size() * sizeof(Elf_Sym));
1855     for (i = 0; i < symbols.size(); i++)
1856         syms[i] = *(symbols[i]);
1857
1858     char *str = (char *) malloc(symbolNamesLength);
1859     unsigned cur = 0;
1860     for (i = 0; i < symbolStrs.size(); i++) {
1861         strcpy(&str[cur], symbolStrs[i].c_str());
1862         cur += symbolStrs[i].length() + 1;
1863     }
1864
1865     if (!isStripped) {
1866         Region *sec;
1867         if (obj->findRegion(sec, ".symtab"))
1868             sec->setPtrToRawData(syms, symbols.size() * sizeof(Elf_Sym));
1869         else
1870             obj->addRegion(0, syms, symbols.size() * sizeof(Elf_Sym), ".symtab", Region::RT_SYMTAB);
1871     }
1872     else
1873         obj->addRegion(0, syms, symbols.size() * sizeof(Elf_Sym), ".symtab", Region::RT_SYMTAB);
1874
1875     //reconstruct .strtab section
1876     if (!isStripped) {
1877         Region *sec;
1878         if (obj->findRegion(sec, ".strtab"))
1879             sec->setPtrToRawData(str, symbolNamesLength);
1880         else
1881             obj->addRegion(0, str, symbolNamesLength, ".strtab", Region::RT_STRTAB);
1882     }
1883     else
1884         obj->addRegion(0, str, symbolNamesLength, ".strtab", Region::RT_STRTAB);
1885
1886     if (!obj->getAllNewRegions(newSecs))
1887         log_elferror(err_func_, "No new sections to add");
1888
1889     if (dynsymbols.size() == 1)
1890         return true;
1891
1892     if (!obj->isStaticBinary()) {
1893         //reconstruct .dynsym section
1894         Elf_Sym *dynsyms = (Elf_Sym *) malloc(dynsymbols.size() * sizeof(Elf_Sym));
1895         for (i = 0; i < dynsymbols.size(); i++)
1896             dynsyms[i] = *(dynsymbols[i]);
1897
1898         Elf_Half *symVers;
1899         char *verneedSecData, *verdefSecData;
1900         unsigned verneedSecSize = 0, verdefSecSize = 0;
1901
1902         createSymbolVersions(symVers, verneedSecData, verneedSecSize, verdefSecData, verdefSecSize,
1903                              dynsymbolNamesLength, dynsymbolStrs);
1904         // build new .hash section
1905         Elf_Word *hashsecData;
1906         unsigned hashsecSize = 0;
1907         createHashSection(hashsecData, hashsecSize, dynsymVector);
1908         if (hashsecSize) {
1909             string name;
1910             if (secTagRegionMapping.find(DT_HASH) != secTagRegionMapping.end()) {
1911                 name = secTagRegionMapping[DT_HASH]->getRegionName();
1912                 obj->addRegion(0, hashsecData, hashsecSize * sizeof(Elf_Word), name, Region::RT_HASH, true);
1913             } else if (secTagRegionMapping.find(0x6ffffef5) != secTagRegionMapping.end()) {
1914                 name = secTagRegionMapping[0x6ffffef5]->getRegionName();
1915                 obj->addRegion(0, hashsecData, hashsecSize * sizeof(Elf_Word), name, Region::RT_HASH, true);
1916             } else {
1917                 name = ".hash";
1918                 obj->addRegion(0, hashsecData, hashsecSize * sizeof(Elf_Word), name, Region::RT_HASH, true);
1919             }
1920         }
1921
1922         Elf_Dyn *dynsecData;
1923         unsigned dynsecSize = 0;
1924         if (obj->findRegion(sec, ".dynamic")) {
1925             // Need to ensure that DT_REL and related fields added to .dynamic
1926             // The values of these fields will be set
1927 /*
1928         if( !object->hasReldyn() && !object->hasReladyn() ) {
1929             if( object->getRelType() == Region::RT_REL ) {
1930                 new_dynamic_entries.push_back(make_pair(DT_REL,0));
1931                 new_dynamic_entries.push_back(make_pair(DT_RELSZ,0));
1932             }else if( object->getRelType() == Region::RT_RELA ) {
1933                 new_dynamic_entries.push_back(make_pair(DT_RELA,0));
1934                 new_dynamic_entries.push_back(make_pair(DT_RELASZ,0));
1935             }else{
1936                 assert(!"Relocation type not set to known RT_REL or RT_RELA.");
1937             }
1938         }
1939 */
1940             createDynamicSection(sec->getPtrToRawData(), sec->getDiskSize(), dynsecData, dynsecSize,
1941                                  dynsymbolNamesLength, dynsymbolStrs);
1942         }
1943
1944         if (!dynsymbolNamesLength)
1945             return true;
1946
1947         char *dynstr = (char *) malloc(dynsymbolNamesLength);
1948         memcpy((void *) dynstr, (void *) olddynStrData, olddynStrSize);
1949         cur = olddynStrSize + 1;
1950         for (i = 0; i < dynsymbolStrs.size(); i++) {
1951             strcpy(&dynstr[cur], dynsymbolStrs[i].c_str());
1952             cur += dynsymbolStrs[i].length() + 1;
1953             if (dynSymNameMapping.find(dynsymbolStrs[i]) == dynSymNameMapping.end()) {
1954                 dynSymNameMapping[dynsymbolStrs[i]] = allDynSymbols.size() + i;
1955             }
1956         }
1957
1958         string name;
1959         if (secTagRegionMapping.find(DT_SYMTAB) != secTagRegionMapping.end()) {
1960             name = secTagRegionMapping[DT_SYMTAB]->getRegionName();
1961         } else {
1962             name = ".dynsym";
1963         }
1964         obj->addRegion(0, dynsyms, dynsymbols.size() * sizeof(Elf_Sym), name, Region::RT_SYMTAB, true);
1965
1966         if (secTagRegionMapping.find(DT_STRTAB) != secTagRegionMapping.end()) {
1967             name = secTagRegionMapping[DT_STRTAB]->getRegionName();
1968         } else {
1969             name = ".dynstr";
1970         }
1971         obj->addRegion(0, dynstr, dynsymbolNamesLength, name, Region::RT_STRTAB, true);
1972
1973         //add .gnu.version, .gnu.version_r, and .gnu.version_d sections
1974         if (secTagRegionMapping.find(DT_VERSYM) != secTagRegionMapping.end()) {
1975             name = secTagRegionMapping[DT_VERSYM]->getRegionName();
1976         } else {
1977             name = ".gnu.version";
1978         }
1979         obj->addRegion(0, symVers, versionSymTable.size() * sizeof(Elf_Half), name, Region::RT_SYMVERSIONS, true);
1980
1981         if (verneedSecSize) {
1982             if (secTagRegionMapping.find(DT_VERNEED) != secTagRegionMapping.end()) {
1983                 name = secTagRegionMapping[DT_VERNEED]->getRegionName();
1984             } else {
1985                 name = ".gnu.version_r";
1986             }
1987             obj->addRegion(0, verneedSecData, verneedSecSize, name, Region::RT_SYMVERNEEDED, true);
1988         }
1989
1990         if (verdefSecSize) {
1991             obj->addRegion(0, verdefSecData, verdefSecSize, ".gnu.version_d", Region::RT_SYMVERDEF, true);
1992         }
1993
1994         //Always create a dyn section, it may get our new relocations.
1995         //If both exist, then just try to maintain order.
1996         bool has_plt = object->hasRelaplt() || object->hasRelplt();
1997         bool has_dyn = object->hasReladyn() || object->hasReldyn();
1998         if (!has_plt) {
1999             createRelocationSections(object->getDynRelocs(), true, dynSymNameMapping);
2000         }
2001         else if (!has_dyn) {
2002             createRelocationSections(object->getPLTRelocs(), false, dynSymNameMapping);
2003             createRelocationSections(object->getDynRelocs(), true, dynSymNameMapping);
2004         }
2005         else if (object->getRelPLTAddr() < object->getRelDynAddr()) {
2006             createRelocationSections(object->getPLTRelocs(), false, dynSymNameMapping);
2007             createRelocationSections(object->getDynRelocs(), true, dynSymNameMapping);
2008         }
2009         else {
2010             createRelocationSections(object->getDynRelocs(), true, dynSymNameMapping);
2011             createRelocationSections(object->getPLTRelocs(), false, dynSymNameMapping);
2012         }
2013
2014         //add .dynamic section
2015         if (dynsecSize)
2016             obj->addRegion(0, dynsecData, dynsecSize * sizeof(Elf_Dyn), ".dynamic", Region::RT_DYNAMIC, true);
2017     }
2018
2019     if (!obj->getAllNewRegions(newSecs))
2020         log_elferror(err_func_, "No new sections to add");
2021
2022     return true;
2023 }
2024
2025 template<class ElfTypes>
2026 void emitElf64<ElfTypes>::createRelocationSections(std::vector<relocationEntry> &relocation_table, bool isDynRelocs,
2027                                                    dyn_hash_map<std::string, unsigned long> &dynSymNameMapping) {
2028     vector<relocationEntry> newRels;
2029     if (isDynRelocs && newSecs.size()) {
2030         std::vector<Region *>::iterator i;
2031         for (i = newSecs.begin(); i != newSecs.end(); i++) {
2032             std::copy((*i)->getRelocations().begin(),
2033                       (*i)->getRelocations().end(),
2034                       std::back_inserter(newRels));
2035         }
2036     }
2037
2038     unsigned i, j, k, l, m;
2039
2040     Elf_Rel *rels = (Elf_Rel *) malloc(sizeof(Elf_Rel) * (relocation_table.size() + newRels.size()));
2041     Elf_Rela *relas = (Elf_Rela *) malloc(sizeof(Elf_Rela) * (relocation_table.size() + newRels.size()));
2042     j = 0;
2043     k = 0;
2044     l = 0;
2045     m = 0;
2046     //reconstruct .rel
2047     for (i = 0; i < relocation_table.size(); i++) {
2048
2049         if (library_adjust) {
2050             // If we are shifting the library down in memory, we need to update
2051             // any relative offsets in the library. These relative offsets are 
2052             // found via relocations
2053
2054             // XXX ...ignore the return value
2055             emitElfUtils::updateRelocation(obj, relocation_table[i], library_adjust);
2056         }
2057
2058         if ((object->getRelType() == Region::RT_REL) && (relocation_table[i].regionType() == Region::RT_REL)) {
2059             rels[j].r_offset = relocation_table[i].rel_addr() + library_adjust;
2060             unsigned long sym_offset = 0;
2061             std::string sym_name = relocation_table[i].name();
2062             if (!sym_name.empty()) {
2063                 dyn_hash_map<string, unsigned long>::iterator j = dynSymNameMapping.find(sym_name);
2064                 if (j != dynSymNameMapping.end())
2065                     sym_offset = j->second;
2066                 else {
2067                     Symbol *sym = relocation_table[i].getDynSym();
2068                     if (sym)
2069                         sym_offset = sym->getIndex();
2070                 }
2071             }
2072
2073             if (sym_offset) {
2074                 rels[j].r_info = ElfTypes::makeRelocInfo(sym_offset, relocation_table[i].getRelType());
2075             } else {
2076                 rels[j].r_info = ElfTypes::makeRelocInfo((unsigned long) STN_UNDEF, relocation_table[i].getRelType());
2077             }
2078             j++;
2079         } else if ((object->getRelType() == Region::RT_RELA) && (relocation_table[i].regionType() == Region::RT_RELA)) {
2080             relas[k].r_offset = relocation_table[i].rel_addr() + library_adjust;
2081             relas[k].r_addend = relocation_table[i].addend();
2082             //if (relas[k].r_addend)
2083             //   relas[k].r_addend += library_adjust;
2084             unsigned long sym_offset = 0;
2085             std::string sym_name = relocation_table[i].name();
2086             if (!sym_name.empty()) {
2087                 dyn_hash_map<string, unsigned long>::iterator j = dynSymNameMapping.find(sym_name);
2088                 if (j != dynSymNameMapping.end()) {
2089                     sym_offset = j->second;
2090                 }
2091                 else {
2092                     Symbol *sym = relocation_table[i].getDynSym();
2093                     if (sym) {
2094                         j = dynSymNameMapping.find(sym->getMangledName());
2095                         if (j != dynSymNameMapping.end())
2096                             sym_offset = j->second;
2097                     }
2098                 }
2099             }
2100             if (sym_offset) {
2101                 relas[k].r_info = ElfTypes::makeRelocInfo(sym_offset, relocation_table[i].getRelType());
2102             } else {
2103                 relas[k].r_info = ElfTypes::makeRelocInfo((unsigned long) STN_UNDEF, relocation_table[i].getRelType());
2104             }
2105             k++;
2106         }
2107     }
2108     for (i = 0; i < newRels.size(); i++) {
2109         if ((object->getRelType() == Region::RT_REL) && (newRels[i].regionType() == Region::RT_REL)) {
2110             rels[j].r_offset = newRels[i].rel_addr() + library_adjust;
2111             if (dynSymNameMapping.find(newRels[i].name()) != dynSymNameMapping.end()) {
2112                 rels[j].r_info = ElfTypes::makeRelocInfo(dynSymNameMapping[newRels[i].name()],
2113                                                          relocationEntry::getGlobalRelType(obj->getAddressWidth()));
2114             } else {
2115                 rels[j].r_info = ElfTypes::makeRelocInfo((unsigned long) (STN_UNDEF),
2116                                                          relocationEntry::getGlobalRelType(obj->getAddressWidth()));
2117             }
2118             j++;
2119             l++;
2120         } else if ((object->getRelType() == Region::RT_RELA) && (newRels[i].regionType() == Region::RT_RELA)) {
2121             relas[k].r_offset = newRels[i].rel_addr() + library_adjust;
2122             relas[k].r_addend = newRels[i].addend();
2123             //if( relas[k].r_addend ) relas[k].r_addend += library_adjust;
2124             if (dynSymNameMapping.find(newRels[i].name()) != dynSymNameMapping.end()) {
2125                 relas[k].r_info = ElfTypes::makeRelocInfo(dynSymNameMapping[newRels[i].name()],
2126                                                           relocationEntry::getGlobalRelType(obj->getAddressWidth()));
2127             } else {
2128                 relas[k].r_info = ElfTypes::makeRelocInfo((unsigned long) (STN_UNDEF),
2129                                                           relocationEntry::getGlobalRelType(obj->getAddressWidth()));
2130             }
2131             k++;
2132             m++;
2133         }
2134     }
2135
2136     dyn_hash_map<int, Region *> secTagRegionMapping = obj->getObject()->getTagRegionMapping();
2137     int reloc_size, old_reloc_size, dynamic_reloc_size;
2138     const char *new_name;
2139     Region::RegionType rtype;
2140     int dtype;
2141     int dsize_type;
2142     void *buffer = NULL;
2143
2144     reloc_size = j * sizeof(Elf_Rel) + k * sizeof(Elf_Rela);
2145     if (!reloc_size) {
2146         return;
2147     }
2148     if (isDynRelocs
2149         && object->getRelType() == Region::RT_REL) {
2150         new_name = ".rel.dyn";
2151         dtype = DT_REL;
2152         rtype = Region::RT_REL;
2153         dsize_type = DT_RELSZ;
2154         buffer = rels;
2155     }
2156     if (isDynRelocs
2157         && object->getRelType() == Region::RT_RELA) {
2158         new_name = ".rela.dyn";
2159         dtype = DT_RELA;
2160         rtype = Region::RT_RELA;
2161         dsize_type = DT_RELASZ;
2162         buffer = relas;
2163         updateDynamic(DT_RELAENT, sizeof(Elf_Rela));
2164     }
2165
2166     if (!isDynRelocs
2167         && object->getRelType() == Region::RT_REL) {
2168         new_name = ".rel.plt";
2169         dtype = DT_JMPREL;
2170         rtype = Region::RT_PLTREL;
2171         dsize_type = DT_PLTRELSZ;
2172         buffer = rels;
2173     }
2174     if (!isDynRelocs
2175         && object->getRelType() == Region::RT_RELA) {
2176         new_name = ".rela.plt";
2177         dtype = DT_JMPREL;
2178         rtype = Region::RT_PLTRELA;
2179         dsize_type = DT_PLTRELSZ;
2180         buffer = relas;
2181     }
2182
2183     if (buffer == NULL) {
2184         log_elferror(err_func_, "Unknown relocation type encountered");
2185         return;
2186     }
2187
2188     if (dynamicSecData.find(dsize_type) != dynamicSecData.end())
2189         old_reloc_size = dynamicSecData[dsize_type][0]->d_un.d_val;
2190     else
2191         old_reloc_size = 0;
2192     dynamic_reloc_size = old_reloc_size + l * sizeof(Elf64_Rel) + m * sizeof(Elf64_Rela);
2193     string name;
2194     if (secTagRegionMapping.find(dtype) != secTagRegionMapping.end())
2195         name = secTagRegionMapping[dtype]->getRegionName();
2196     else
2197         name = std::string(new_name);
2198     obj->addRegion(0, buffer, reloc_size, name, rtype, true);
2199     updateDynamic(dsize_type, dynamic_reloc_size);
2200
2201 }
2202
2203 template<class ElfTypes>
2204 void emitElf64<ElfTypes>::createSymbolVersions(Elf_Half *&symVers, char *&verneedSecData, unsigned &verneedSecSize,
2205                                                char *&verdefSecData,
2206                                                unsigned &verdefSecSize, unsigned &dynSymbolNamesLength,
2207                                                std::vector<std::string> &dynStrs) {
2208
2209     //Add all names to the new .dynstr section
2210     map<string, unsigned>::iterator iter = versionNames.begin();
2211     for (; iter != versionNames.end(); iter++) {
2212         iter->second = dynSymbolNamesLength;
2213         dynStrs.push_back(iter->first);
2214         dynSymbolNamesLength += iter->first.size() + 1;
2215     }
2216
2217     //reconstruct .gnu_version section
2218     symVers = (Elf_Half *) malloc(versionSymTable.size() * sizeof(Elf_Half));
2219     for (unsigned i = 0; i < versionSymTable.size(); i++)
2220         symVers[i] = versionSymTable[i];
2221
2222     //reconstruct .gnu.version_r section
2223     verneedSecSize = 0;
2224     map<string, map<string, unsigned> >::iterator it = verneedEntries.begin();
2225     for (; it != verneedEntries.end(); it++)
2226         verneedSecSize += sizeof(Elf_Verneed) + sizeof(Elf_Vernaux) * it->second.size();
2227
2228     verneedSecData = (char *) malloc(verneedSecSize);
2229     unsigned curpos = 0;
2230     verneednum = 0;
2231     std::vector<std::string>::iterator dit;
2232     for (dit = unversionedNeededEntries.begin(); dit != unversionedNeededEntries.end(); dit++) {
2233         // account for any substitutions due to rewriting a shared lib
2234         std::string name = obj->getDynLibSubstitution(*dit);
2235         // no need for self-references
2236         if (!(obj->name() == name)) {
2237             versionNames[name] = dynSymbolNamesLength;
2238             dynStrs.push_back(name);
2239             dynSymbolNamesLength += (name).size() + 1;
2240             addDTNeeded(name);
2241         }
2242     }
2243     for (it = verneedEntries.begin(); it != verneedEntries.end(); it++) {
2244         Elf_Verneed *verneed = reinterpret_cast<Elf_Verneed *>(verneedSecData + curpos);
2245         verneed->vn_version = 1;
2246         verneed->vn_cnt = it->second.size();
2247         verneed->vn_file = dynSymbolNamesLength;
2248         versionNames[it->first] = dynSymbolNamesLength;
2249         dynStrs.push_back(it->first);
2250         dynSymbolNamesLength += it->first.size() + 1;
2251         addDTNeeded(it->first);
2252         verneed->vn_aux = sizeof(Elf_Verneed);
2253         verneed->vn_next = sizeof(Elf_Verneed) + it->second.size() * sizeof(Elf_Vernaux);
2254         if (curpos + verneed->vn_next == verneedSecSize)
2255             verneed->vn_next = 0;
2256         verneednum++;
2257         int i = 0;
2258         for (iter = it->second.begin(); iter != it->second.end(); iter++) {
2259             Elf_Vernaux *vernaux = reinterpret_cast<Elf_Vernaux *>(
2260                     verneedSecData + curpos + verneed->vn_aux + i * sizeof(Elf_Vernaux));
2261             vernaux->vna_hash = elfHash(iter->first.c_str());
2262             vernaux->vna_flags = 0;
2263             vernaux->vna_other = iter->second;
2264             vernaux->vna_name = versionNames[iter->first];
2265             if (i == verneed->vn_cnt - 1)
2266                 vernaux->vna_next = 0;
2267             else
2268                 vernaux->vna_next = sizeof(Elf_Vernaux);
2269             i++;
2270         }
2271         curpos += verneed->vn_next;
2272     }
2273
2274     //reconstruct .gnu.version_d section
2275     verdefSecSize = 0;
2276     for (iter = verdefEntries.begin(); iter != verdefEntries.end(); iter++)
2277         verdefSecSize += sizeof(Elf_Verdef) + sizeof(Elf_Verdaux) * verdauxEntries[iter->second].size();
2278
2279     verdefSecData = (char *) malloc(verdefSecSize);
2280     curpos = 0;
2281     verdefnum = 0;
2282     for (iter = verdefEntries.begin(); iter != verdefEntries.end(); iter++) {
2283         Elf_Verdef *verdef = reinterpret_cast<Elf_Verdef *>(verdefSecData + curpos);
2284         verdef->vd_version = 1;
2285         verdef->vd_flags = 0;
2286         verdef->vd_ndx = iter->second;
2287         verdef->vd_cnt = verdauxEntries[iter->second].size();
2288         verdef->vd_hash = elfHash(iter->first.c_str());
2289         verdef->vd_aux = sizeof(Elf_Verdef);
2290         verdef->vd_next = sizeof(Elf_Verdef) + verdauxEntries[iter->second].size() * sizeof(Elf_Verdaux);
2291         if (curpos + verdef->vd_next == verdefSecSize)
2292             verdef->vd_next = 0;
2293         verdefnum++;
2294         for (unsigned i = 0; i < verdauxEntries[iter->second].size(); i++) {
2295             Elf_Verdaux *verdaux = reinterpret_cast<Elf_Verdaux *>(
2296                     verdefSecData + curpos + verdef->vd_aux + i * sizeof(Elf_Verdaux));
2297             verdaux->vda_name = versionNames[verdauxEntries[iter->second][0]];
2298             if ((signed) i == verdef->vd_cnt - 1)
2299                 verdaux->vda_next = 0;
2300             else
2301                 verdaux->vda_next = sizeof(Elf_Verdaux);
2302         }
2303         curpos += verdef->vd_next;
2304     }
2305     return;
2306 }
2307
2308 template<class ElfTypes>
2309 void emitElf64<ElfTypes>::createHashSection(Elf_Word *&hashsecData, unsigned &hashsecSize,
2310                                             std::vector<Symbol *> &dynSymbols) {
2311
2312     /* Save the original hash table entries */
2313     std::vector<unsigned> originalHashEntries;
2314     Offset dynsymSize = obj->getObject()->getDynsymSize();
2315
2316     Elf_Scn *scn = NULL;
2317     Elf_Shdr *shdr = NULL;
2318     for (unsigned scncount = 0; (scn = elf_nextscn(oldElf, scn)); scncount++) {
2319         shdr = ElfTypes::elf_getshdr(scn);
2320         if (obj->getObject()->getElfHashAddr() != 0 &&
2321             obj->getObject()->getElfHashAddr() == shdr->sh_addr) {
2322             Elf_Data *hashData = elf_getdata(scn, NULL);
2323             Elf_Word *oldHashSec = (Elf_Word *) hashData->d_buf;
2324             unsigned original_nbuckets, original_nchains;
2325             original_nbuckets = oldHashSec[0];
2326             original_nchains = oldHashSec[1];
2327             for (unsigned i = 0; i < original_nbuckets + original_nchains; i++) {
2328                 if (oldHashSec[2 + i] != 0) {
2329                     originalHashEntries.push_back(oldHashSec[2 + i]);
2330                     //printf(" ELF HASH pushing hash entry %d \n", oldHashSec[2+i] );
2331                 }
2332             }
2333         }
2334
2335         if (obj->getObject()->getGnuHashAddr() != 0 &&
2336             obj->getObject()->getGnuHashAddr() == shdr->sh_addr) {
2337             Elf_Data *hashData = elf_getdata(scn, NULL);
2338             Elf_Word *oldHashSec = (Elf_Word *) hashData->d_buf;
2339             unsigned symndx = oldHashSec[1];
2340             if (dynsymSize != 0)
2341                 for (unsigned i = symndx; i < dynsymSize; i++) {
2342                     originalHashEntries.push_back(i);
2343                     //printf(" GNU HASH pushing hash entry %d \n", i);
2344                 }
2345         }
2346     }
2347
2348     vector<Symbol *>::iterator iter;
2349     dyn_hash_map<unsigned, unsigned> lastHash; // bucket number to symbol index
2350     unsigned nbuckets = (unsigned) dynSymbols.size() * 2 / 3;
2351     if (nbuckets % 2 == 0)
2352         nbuckets--;
2353     if (nbuckets < 1)
2354         nbuckets = 1;
2355     unsigned nchains = (unsigned) dynSymbols.size();
2356     hashsecSize = 2 + nbuckets + nchains;
2357     hashsecData = (Elf_Word *) malloc(hashsecSize * sizeof(Elf_Word));
2358     unsigned i = 0, key;
2359     for (i = 0; i < hashsecSize; i++) {
2360         hashsecData[i] = STN_UNDEF;
2361     }
2362     hashsecData[0] = (Elf_Word) nbuckets;
2363     hashsecData[1] = (Elf_Word) nchains;
2364     i = 0;
2365     for (iter = dynSymbols.begin(); iter != dynSymbols.end(); iter++, i++) {
2366         if ((*iter)->getMangledName().empty()) continue;
2367         unsigned index = (*iter)->getIndex();
2368         if ((find(originalHashEntries.begin(), originalHashEntries.end(), index) == originalHashEntries.end()) &&
2369             (index < obj->getObject()->getDynsymSize())) {
2370             continue;
2371         }
2372         key = elfHash((*iter)->getMangledName().c_str()) % nbuckets;
2373         if (lastHash.find(key) != lastHash.end()) {
2374             hashsecData[2 + nbuckets + lastHash[key]] = i;
2375         }
2376         else {
2377             hashsecData[2 + key] = i;
2378         }
2379         lastHash[key] = i;
2380         hashsecData[2 + nbuckets + i] = STN_UNDEF;
2381     }
2382 }
2383
2384 template<class ElfTypes>
2385 void emitElf64<ElfTypes>::createDynamicSection(void *dynData, unsigned size, Elf_Dyn *&dynsecData, unsigned &dynsecSize,
2386                                                unsigned &dynSymbolNamesLength, std::vector<std::string> &dynStrs) {
2387     dynamicSecData.clear();
2388     Elf_Dyn *dyns = (Elf_Dyn *) dynData;
2389     unsigned count = size / sizeof(Elf_Dyn);
2390     vector<string> &libs_rmd = object->libsRMd();
2391     dynsecSize = 2 * (count + DT_NEEDEDEntries.size() + new_dynamic_entries.size());
2392     dynsecData = (Elf_Dyn *) malloc(dynsecSize * sizeof(Elf_Dyn));
2393     unsigned curpos = 0;
2394     string rpathstr;
2395     for (unsigned i = 0; i < DT_NEEDEDEntries.size(); i++) {
2396         dynsecData[curpos].d_tag = DT_NEEDED;
2397         dynStrs.push_back(DT_NEEDEDEntries[i]);
2398         dynsecData[curpos].d_un.d_val = dynSymbolNamesLength;
2399         dynSymbolNamesLength += DT_NEEDEDEntries[i].size() + 1;
2400         dynamicSecData[DT_NEEDED].push_back(dynsecData + curpos);
2401         curpos++;
2402     }
2403     for (unsigned i = 0; i < new_dynamic_entries.size(); i++) {
2404         long name = new_dynamic_entries[i].first;
2405         long value = new_dynamic_entries[i].second;
2406         dynsecData[curpos].d_tag = name;
2407         dynsecData[curpos].d_un.d_val = value;
2408         dynamicSecData[name].push_back(dynsecData + curpos);
2409         curpos++;
2410     }
2411
2412     // There may be multiple HASH (ELF, GNU etc) sections in the original binary. We consolidate all of them into one.
2413     bool foundHashSection = false;
2414
2415     for (unsigned i = 0; i < count; i++) {
2416         switch (dyns[i].d_tag) {
2417             case DT_NULL:
2418                 break;
2419             case 0x6ffffef5: // DT_GNU_HASH (not defined on all platforms)
2420                 if (!foundHashSection) {
2421                     dynsecData[curpos].d_tag = DT_HASH;
2422                     dynsecData[curpos].d_un.d_ptr = dyns[i].d_un.d_ptr;
2423                     dynamicSecData[DT_HASH].push_back(dynsecData + curpos);
2424                     curpos++;
2425                     foundHashSection = true;
2426                 }
2427                 break;
2428             case DT_HASH:
2429                 if (!foundHashSection) {
2430                     dynsecData[curpos].d_tag = dyns[i].d_tag;
2431                     dynsecData[curpos].d_un.d_ptr = dyns[i].d_un.d_ptr;
2432                     dynamicSecData[dyns[i].d_tag].push_back(dynsecData + curpos);
2433                     curpos++;
2434                     foundHashSection = true;
2435                 }
2436                 break;
2437             case DT_NEEDED:
2438                 rpathstr = &olddynStrData[dyns[i].d_un.d_val];
2439                 if (find(DT_NEEDEDEntries.begin(), DT_NEEDEDEntries.end(), rpathstr) != DT_NEEDEDEntries.end()) {
2440                     break;
2441                 }
2442                 if (find(libs_rmd.begin(), libs_rmd.end(), rpathstr) != libs_rmd.end())
2443                     break;
2444                 dynsecData[curpos].d_tag = dyns[i].d_tag;
2445                 dynsecData[curpos].d_un.d_val = dynSymbolNamesLength;
2446                 dynStrs.push_back(rpathstr);
2447                 dynSymbolNamesLength += rpathstr.size() + 1;
2448                 dynamicSecData[dyns[i].d_tag].push_back(dynsecData + curpos);
2449                 curpos++;
2450                 break;
2451             case DT_RPATH:
2452             case DT_RUNPATH:
2453                 dynsecData[curpos].d_tag = dyns[i].d_tag;
2454                 dynsecData[curpos].d_un.d_val = dynSymbolNamesLength;
2455                 rpathstr = &olddynStrData[dyns[i].d_un.d_val];
2456                 dynStrs.push_back(rpathstr);
2457                 dynSymbolNamesLength += rpathstr.size() + 1;
2458                 dynamicSecData[dyns[i].d_tag].push_back(dynsecData + curpos);
2459                 curpos++;
2460                 break;
2461             case DT_INIT:
2462             case DT_FINI:
2463             case DT_GNU_CONFLICT:
2464             case DT_JMPREL:
2465             case DT_PLTGOT:
2466             case DT_INIT_ARRAY:
2467             case DT_FINI_ARRAY:
2468                 /**
2469                  * List every dynamic entry that references an address and isn't already
2470                  * updated here.  library_adjust will be a page size if
2471                  * we're dealing with a library without a fixed load address.  We'll be shifting
2472                  * the addresses of that library by a page.
2473                  **/
2474                 memcpy(dynsecData + curpos, dyns + i, sizeof(Elf_Dyn));
2475                 dynsecData[curpos].d_un.d_ptr += library_adjust;
2476                 dynamicSecData[dyns[i].d_tag].push_back(dynsecData + curpos);
2477                 curpos++;
2478                 break;
2479             default:
2480                 memcpy(dynsecData + curpos, dyns + i, sizeof(Elf_Dyn));
2481                 dynamicSecData[dyns[i].d_tag].push_back(dynsecData + curpos);
2482                 curpos++;
2483                 break;
2484         }
2485     }
2486     // Need to ensure that DT_REL and related fields added to .dynamic
2487     // The values of these fields will be set
2488
2489     if (!object->hasReldyn() && !object->hasReladyn()) {
2490         if (object->getRelType() == Region::RT_REL) {
2491             new_dynamic_entries.push_back(make_pair(DT_REL, 0));
2492             new_dynamic_entries.push_back(make_pair(DT_RELSZ, 0));
2493
2494             dynamicSecData[DT_REL].push_back(dynsecData + curpos);
2495             dynsecData[curpos].d_tag = DT_NULL;
2496             dynsecData[curpos].d_un.d_val = 0;
2497             curpos++;
2498             dynamicSecData[DT_RELSZ].push_back(dynsecData + curpos);
2499             dynsecData[curpos].d_tag = DT_NULL;
2500             dynsecData[curpos].d_un.d_val = 0;
2501             curpos++;
2502             dynamicSecData[DT_RELENT].push_back(dynsecData + curpos);
2503             dynsecData[curpos].d_tag = DT_NULL;
2504             dynsecData[curpos].d_un.d_val = 0;
2505             curpos++;
2506
2507         } else if (object->getRelType() == Region::RT_RELA) {
2508
2509             dynamicSecData[DT_RELA].push_back(dynsecData + curpos);
2510             dynsecData[curpos].d_tag = DT_NULL;
2511             dynsecData[curpos].d_un.d_val = 0;
2512             curpos++;
2513             dynamicSecData[DT_RELASZ].push_back(dynsecData + curpos);
2514             dynsecData[curpos].d_tag = DT_NULL;
2515             dynsecData[curpos].d_un.d_val = 0;
2516             curpos++;
2517             dynamicSecData[DT_RELAENT].push_back(dynsecData + curpos);
2518             dynsecData[curpos].d_tag = DT_NULL;
2519             dynsecData[curpos].d_un.d_val = 0;
2520             curpos++;
2521
2522         }
2523     }
2524
2525
2526     dynsecData[curpos].d_tag = DT_NULL;
2527     dynsecData[curpos].d_un.d_val = 0;
2528     curpos++;
2529     dynsecSize = curpos;
2530 }
2531
2532
2533 template<class ElfTypes>
2534 void emitElf64<ElfTypes>::log_elferror(void (*err_func)(const char *), const char *msg) {
2535     const char *err = elf_errmsg(elf_errno());
2536     err = err ? err : "(bad elf error)";
2537     string str = string(err) + string(msg);
2538     err_func(str.c_str());
2539 }
2540
2541 template<class ElfTypes>
2542 void emitElf64<ElfTypes>::addDTNeeded(string s) {
2543     if (find(DT_NEEDEDEntries.begin(), DT_NEEDEDEntries.end(), s) != DT_NEEDEDEntries.end())
2544         return;
2545     vector<string> &libs_rmd = object->libsRMd();
2546     if (find(libs_rmd.begin(), libs_rmd.end(), s) != libs_rmd.end())
2547         return;
2548     DT_NEEDEDEntries.push_back(s);
2549 }
2550
2551
2552 namespace Dyninst {
2553     namespace SymtabAPI {
2554         template class emitElf64<ElfTypes32>;
2555         template class emitElf64<ElfTypes64>;
2556     } // namespace SymtabAPI
2557 } // namespace Dyninst