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