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