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