Fix compilation errors with RHEL 5 systems
[dyninst.git] / symtabAPI / src / emitElfStatic.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  * XXX
33  *
34  * This class is unnecessary. However, at the time of writing, emitElf was
35  * split into two different classes (one for 32-bit and 64-bit). Instead of
36  * duplicating code, this class was created to share code between the
37  * two emitElf classes.
38  *
39  * Once the emitElf classes are merged, this class can be merged with the new
40  * emitElf class.
41  */
42
43 #include <cstdlib>
44 #include <cstdio>
45 #include <iostream>
46
47 #include <algorithm>
48
49 #include "emitElfStatic.h"
50 #include "debug.h"
51 #include "Object-elf.h"
52
53 #if defined(os_freebsd)
54 #define R_X86_64_JUMP_SLOT R_X86_64_JMP_SLOT
55 #endif
56
57 using namespace Dyninst;
58 using namespace SymtabAPI;
59
60 // Section names
61 static const string CODE_NAME(".dyninstCode");
62 static const string STUB_NAME(".dyninstStub");
63 static const string DATA_NAME(".dyninstData");
64 static const string BSS_NAME(".dyninstBss");
65 static const string GOT_NAME(".dyninstGot");
66 static const string CTOR_NAME(".dyninstCtors");
67 static const string DTOR_NAME(".dyninstDtors");
68 static const string TLS_DATA_NAME(".dyninstTdata");
69 static const string DEFAULT_COM_NAME(".common");
70 static const string PLT_NAME(".dyninstPLT");
71 static const string REL_NAME(".dyninstRELA");
72 static const string REL_GOT_NAME(".dyninstRELAgot");
73
74 /* Used by architecture specific functions, but not architecture specific */
75 const string Dyninst::SymtabAPI::SYMTAB_CTOR_LIST_REL("__SYMTABAPI_CTOR_LIST__");
76 const string Dyninst::SymtabAPI::SYMTAB_DTOR_LIST_REL("__SYMTABAPI_DTOR_LIST__");
77 const string Dyninst::SymtabAPI::SYMTAB_IREL_START("__SYMTABAPI_IREL_START__");
78 const string Dyninst::SymtabAPI::SYMTAB_IREL_END("__SYMTABAPI_IREL_END__");
79
80 emitElfStatic::emitElfStatic(unsigned addressWidth, bool isStripped) :
81     addressWidth_(addressWidth),
82     isStripped_(isStripped),
83     hasRewrittenTLS_(false)
84 {
85
86 }
87
88 /**
89  * NOTE:
90  * Most of these functions take a reference to a StaticLinkError and a string
91  * for error reporting purposes. These should prove useful in identifying the
92  * cause of an error
93  */
94
95 /**
96  * Statically links relocatable files into the specified Symtab object, 
97  * as specified by state in the Symtab object
98  *
99  * target       relocatable files will be linked into this Symtab
100  *
101  * Returns a pointer to a block of data containing the results of the link
102  * The caller is responsible for delete'ing this block of data
103  */
104 char *emitElfStatic::linkStatic(Symtab *target, 
105         StaticLinkError &err, string &errMsg) 
106 {
107     /* 
108      * Basic algorithm is:
109      * - locate defined versions of symbols for undefined symbols in 
110      *   either the target or relocatable code, produces a list
111      *   of Symtab objects that contain the defined versions
112      *
113      * - Allocate space for all new code and data to be linked into 
114      *   the target, populates a LinkMap with all allocation 
115      *   information
116      *
117      * - Compute relocations and set their targets to these values
118      */
119
120     // Holds all information necessary to work with the block of data created by createLinkMap
121     LinkMap lmap;
122
123     rewrite_printf("START link map output\n");
124     
125     // Determine starting location of new Regions
126     Offset globalOffset = 0;
127     vector<Region *> newRegs;
128     if( target->getAllNewRegions(newRegs) ) {
129         // This is true, only if other regions have already been added
130         vector<Region *>::iterator newReg_it;
131         for(newReg_it = newRegs.begin(); newReg_it != newRegs.end(); ++newReg_it) {
132             Offset newRegEndAddr = (*newReg_it)->getMemSize() + (*newReg_it)->getDiskOffset();
133             if( newRegEndAddr > globalOffset ) {
134                 globalOffset = newRegEndAddr;
135             }
136         }
137     }
138
139     if( globalOffset == 0 ) {
140         err = Link_Location_Error;
141         errMsg = "failed to find location for new code and data.";
142         return NULL;
143     }
144
145     // Holds all necessary dependencies, as determined by resolveSymbols
146     vector<Symtab *> relocatableObjects;
147     if( !resolveSymbols(target, relocatableObjects, lmap, err, errMsg) ) {
148         return NULL;
149     }
150
151     // Lays out all relocatable files into a single contiguous block of data
152     if( !createLinkMap(target, relocatableObjects, globalOffset, lmap, err, errMsg) ) {
153         return NULL;
154     }
155
156     // Copies the data from the relocatable files into the new block of data
157     if( !addNewRegions(target, globalOffset, lmap) ) {
158         err = Storage_Allocation_Failure;
159         errMsg = "Failed to create new Regions in original binary";
160         return NULL;
161     }
162
163     if (!updateTOC(target, lmap, globalOffset)) {
164       return NULL;
165     }
166
167     // Print out the link map for debugging
168     rewrite_printf("Global Offset = 0x%lx\n", globalOffset);
169     if( sym_debug_rewrite ) {
170         lmap.printAll(cerr, globalOffset);
171         lmap.printBySymtab(cerr, relocatableObjects, globalOffset);
172     }
173
174     // Now that all symbols are at their final locations, compute and apply relocations
175     if( !applyRelocations(target, relocatableObjects, globalOffset, lmap, err, errMsg) ) {
176         if( lmap.allocatedData ) delete lmap.allocatedData;
177         return NULL;
178     }
179
180     if (!buildPLT(target, globalOffset, lmap, err, errMsg)) {
181       if (lmap.allocatedData) delete lmap.allocatedData;
182       return NULL;
183     } 
184
185     if (!buildRela(target, globalOffset, lmap, err, errMsg)) {
186       if (lmap.allocatedData) delete lmap.allocatedData;
187       return NULL;
188     }
189
190     // Restore the offset of the modified symbols
191     vector< pair<Symbol *, Offset> >::iterator symOff_it;
192     for(symOff_it = lmap.origSymbols.begin();
193         symOff_it != lmap.origSymbols.end();
194         ++symOff_it)
195     {
196         symOff_it->first->setOffset(symOff_it->second);
197     }
198
199     // Restore the symbols of the modified relocations
200    vector< pair<relocationEntry *, Symbol *> >::iterator relSym_it;
201    for(relSym_it = lmap.origRels.begin();
202        relSym_it != lmap.origRels.end();
203        ++relSym_it)
204    {
205        relSym_it->first->addDynSym(relSym_it->second);
206    }
207
208     rewrite_printf("\n*** Finished static linking\n\n");
209
210     rewrite_printf("END link map output\n");
211
212     err = No_Static_Link_Error;
213     errMsg = "";
214     return lmap.allocatedData;
215 }
216
217 /**
218  * Resolves undefined symbols in the specified Symtab object, usually due
219  * to the addition of new Symbols to the Symtab object. The target Symtab
220  * object must have a collection of Archives associated with it. These
221  * Archives will be searched for the defined versions of the undefined 
222  * symbols in the specified Symtab objects.
223  *
224  * target               the Symtab containing the undefined symbols
225  * relocatableObjects   populated by this function, this collection specifies
226  *                      all the Symtabs needed to ensure that the target has
227  *                      no undefined Symbols once the link is performed
228  */
229 bool emitElfStatic::resolveSymbols(Symtab *target, 
230         vector<Symtab *> &relocatableObjects,
231         LinkMap &lmap,
232         StaticLinkError &err, string &errMsg) 
233 {
234     // Collection of Symtabs that currently need their symbols resolved
235     set<Symtab *> workSet;
236
237     // Collection of Symtabs that have already had their symbols resolved
238     // this is necessary to avoid errors related to circular dependencies
239     set<Symtab *> linkedSet;
240
241     set<string> excludeSymNames;
242     getExcludedSymbolNames(excludeSymNames);
243
244     // Establish list of libraries to search for symbols
245     vector<Archive *> libraries;
246     target->getLinkingResources(libraries);
247
248     // Add all relocatable files explicitly referenced by new symbols, these
249     // essentially fuel the symbol resolution process
250     set<Symtab *> explicitRefs;
251     target->getExplicitSymtabRefs(explicitRefs);
252
253     set<Symtab *>::iterator expObj_it;
254     for(expObj_it = explicitRefs.begin(); expObj_it != explicitRefs.end();
255             ++expObj_it) 
256     {
257         relocatableObjects.push_back(*expObj_it);
258         workSet.insert(*expObj_it);
259         linkedSet.insert(*expObj_it);
260     }
261
262     set<Symtab *>::iterator curObjFilePtr = workSet.begin();
263     while( curObjFilePtr != workSet.end() ) {
264         // Take a relocatable file off the working set
265         Symtab *curObjFile = *curObjFilePtr;
266         workSet.erase(curObjFile);
267
268         rewrite_printf("\n*** Resolving symbols for: %s\n\n",
269                 curObjFile->memberName().c_str());
270
271         // Build the map of symbols to their relocations
272         map<Symbol *, vector<relocationEntry *> > symToRels;
273         vector<Region *> allRegions;
274         curObjFile->getAllRegions(allRegions);
275
276         vector<Region *>::iterator region_it;
277         for(region_it = allRegions.begin(); region_it != allRegions.end();
278                 ++region_it)
279         {
280             vector<relocationEntry> &region_rels = (*region_it)->getRelocations();
281             vector<relocationEntry>::iterator rel_it;
282             for( rel_it = region_rels.begin(); rel_it != region_rels.end(); ++rel_it) {
283                 symToRels[rel_it->getDynSym()].push_back(&(*rel_it));
284                 lmap.origRels.push_back(make_pair(&(*rel_it), rel_it->getDynSym()));
285             }
286         }
287
288         // Iterate over all undefined symbols, attempting to resolve them
289         vector<Symbol *> undefSyms;
290         curObjFile->getAllUndefinedSymbols(undefSyms);
291
292         vector<Symbol *>::iterator undefSym_it;
293         for(undefSym_it = undefSyms.begin(); undefSym_it != undefSyms.end();
294                 ++undefSym_it) 
295         {
296             Symbol *curUndefSym = *undefSym_it;
297
298             // Skip symbols that are don't cares
299             if( excludeSymNames.count(curUndefSym->getPrettyName()) ) continue;
300
301             if( !checkSpecialCaseSymbols(curObjFile, curUndefSym) ) {
302                 err = Symbol_Resolution_Failure;
303                 errMsg = "special case check failed for symbol: " +
304                     curUndefSym->getMangledName();
305                 return false;
306             }
307
308             Symbol *extSymbol = NULL;
309
310             // First, attempt to search the target for the symbol
311             if( !isStripped_ ) {
312                  vector<Symbol *> foundSyms;
313                  if( target->findSymbol(foundSyms, curUndefSym->getMangledName(),
314                     curUndefSym->getType()) )
315                  {
316                     if( foundSyms.size() > 1 ) {
317                         err = Symbol_Resolution_Failure;
318                         errMsg = "ambiguous symbol definition: " + 
319                             curUndefSym->getMangledName();
320                         return false;
321                     }
322
323                     extSymbol = foundSyms[0];
324
325                     rewrite_printf("Found external symbol %s in target with address = 0x%lx\n",
326                             extSymbol->getPrettyName().c_str(), extSymbol->getOffset());
327                  }
328             }
329
330             if( extSymbol == NULL ) {
331                 // search loaded libraries and add any new reloctable files
332                 vector<Symtab *> possibleSymtabs;
333
334                 for(auto lib_it = libraries.begin(); lib_it != libraries.end(); ++lib_it) {
335                    (*lib_it)->getMembersBySymbol(curUndefSym->getMangledName(), possibleSymtabs);
336                 }
337
338                 // Look through the possibleSymtabs for symbol hits
339                 // Options are:
340                 // 1) A lot of weak symbols; pick one
341                 // 2) A lot of weak symbols and a strong symbol: pick strong
342                 // 3) Multiple strong symbols: fail
343                 // 4) ... no symbols. Also fail.
344
345                 for (auto iter = possibleSymtabs.begin(); iter != possibleSymtabs.end(); ++iter) {                   
346                    std::vector<Symbol *> syms;
347                    (*iter)->findSymbol(syms, curUndefSym->getMangledName(), curUndefSym->getType());
348                    if (syms.empty()) {
349                       // Problem: mismatch between the Archive table and Symtab
350                       err = Symbol_Resolution_Failure;
351                       errMsg = "inconsistency found between archive's symbol table and member's symbol table";
352                       return false;
353                    }
354
355                    for (auto iter2 = syms.begin(); iter2 != syms.end(); ++iter2) {
356                      // We include UNKNOWN symbols in the find; unfortunately that's
357                      // not what we want here. Skip. 
358                      if ((*iter2)->getType() == Symbol::ST_UNKNOWN) {
359                        continue;
360                      }
361
362                       if (extSymbol == NULL || extSymbol->getLinkage() == Symbol::SL_WEAK) {
363                          extSymbol = *iter2;
364                       }
365                       else if ((*iter2)->getLinkage() == Symbol::SL_WEAK) {
366                          continue;
367                       }
368                       else {
369                          // Two strong symbols: bad
370                          err = Symbol_Resolution_Failure;
371                          errMsg = "ambiguous symbol definition: " + 
372                             curUndefSym->getMangledName();
373                          return false;
374                       }
375                    }
376                 }
377                 
378                 if( extSymbol == NULL ) {
379                    // If it is a weak symbol, it isn't an error that the symbol wasn't resolved
380                    if( curUndefSym->getLinkage() == Symbol::SL_WEAK ) {
381                       continue;
382                    }
383                    
384                    err = Symbol_Resolution_Failure;
385                    errMsg = "failed to locate symbol '" + curUndefSym->getMangledName()
386                       + "' for object '" + curObjFile->memberName() + "'";
387                    rewrite_printf(" failed to locate symbol %s for %s  \n" , curUndefSym->getMangledName().c_str(), curObjFile->memberName().c_str());
388                    return false;
389                 }
390                 Symtab *containingSymtab = extSymbol->getSymtab();
391
392                 if( !linkedSet.count(containingSymtab) ) {
393                    // Consistency check                                                                                            
394                    if( containingSymtab->getAddressWidth() != addressWidth_ ) {
395                       err = Symbol_Resolution_Failure;
396                       errMsg = "symbol (" + curUndefSym->getMangledName() +
397                          ") found in relocatable file that is not compatible"
398                          + " with the target binary";
399                       return false;
400                    }
401                    
402                    relocatableObjects.push_back(containingSymtab);
403                    
404                    // Resolve all symbols for this new Symtab, if it hasn't already                                                
405                    // been done                                                                                                    
406                    
407                    workSet.insert(containingSymtab);
408                    linkedSet.insert(containingSymtab);
409                 }
410                                 
411                 rewrite_printf("Found external symbol %s in object %s(%s)\n",
412                                extSymbol->getPrettyName().c_str(),
413                                containingSymtab->getParentArchive()->name().c_str(),
414                                containingSymtab->memberName().c_str());
415             }
416
417             if (extSymbol->getType() == Symbol::ST_INDIRECT) {
418               addIndirectSymbol(extSymbol, lmap);
419             }
420             
421             // Store the found symbol with the related relocations
422             map<Symbol *, vector<relocationEntry *> >::iterator relMap_it;
423             relMap_it = symToRels.find(curUndefSym);
424             if( relMap_it != symToRels.end() ) {
425                 vector<relocationEntry *>::iterator rel_it;
426                 for(rel_it = relMap_it->second.begin(); rel_it != relMap_it->second.end();
427                         ++rel_it)
428                 {
429                     (*rel_it)->addDynSym(extSymbol);
430                 }
431             }   /* else
432                  *
433                  * Some libraries define a reference to a symbol and then never
434                  * use it in order to ensure that the object that defines the
435                  * symbol is linked. Therefore, it is not an error if a symbol doesn't
436                  * have a relocation.
437                  */
438         }
439
440         curObjFilePtr = workSet.begin();
441     }
442     
443     return true;
444 }
445
446 /**
447  * Given a collection of Symtab objects, combines the code, data, bss and
448  * other miscellaneous Regions into groups and places them in a new block
449  * of data.
450  * 
451  * Allocates COMMON symbols in the collection of Symtab objects
452  * as bss
453  *
454  * Creates a new TLS initialization image, combining the target image
455  * and the image that exists in the collection of Symtab objects
456  *
457  * Creates a GOT used for indirect memory accesses that is required by some
458  * relocations
459  *
460  * Creates a new global constructor and/or destructor table if necessary,
461  * combining tables from the target and collection of Symtab objects
462  *
463  * target               New code/data/etc. will be linked into this Symtab
464  * relocatableObjects   The new code/data/etc.
465  * globalOffset         The location of the new block of data in the target
466  * lmap                 The LinkMap to be populated by this function
467  */
468 bool emitElfStatic::createLinkMap(Symtab *target,
469         vector<Symtab *> &relocatableObjects, 
470         Offset & globalOffset, 
471         LinkMap &lmap,
472         StaticLinkError &err, string &errMsg) 
473 {
474     rewrite_printf("\n*** Allocating storage for relocatable objects\n\n");
475
476     // Used to create a new COMMON block
477     multimap<Offset, Symbol *> commonAlignments;
478     Offset commonRegionAlign = 0;
479
480     // Collect all Regions that should be allocated in the new data block
481     vector<Symtab *>::iterator obj_it;
482     for(obj_it = relocatableObjects.begin(); obj_it != relocatableObjects.end(); ++obj_it) {
483         vector<Region *> regs;
484         if( !(*obj_it)->getAllRegions(regs) ) {
485             err = Storage_Allocation_Failure;
486             errMsg = "failed to locate regions in relocatable object";
487             return false;
488         }
489
490         vector<Region *>::iterator reg_it;
491         for(reg_it = regs.begin(); reg_it != regs.end(); ++reg_it) {
492             string regionName = (*reg_it)->getRegionName();
493             if( (*reg_it)->isLoadable() && (*reg_it)->getMemSize() > 0) {
494                 if( (*reg_it)->isTLS() ) {
495                     switch((*reg_it)->getRegionType()) {
496                         case Region::RT_DATA:
497                         case Region::RT_BSS:
498                             lmap.tlsRegions.push_back(*reg_it);
499                             // Determine alignment of combined region
500                             if( (*reg_it)->getMemAlignment() > lmap.tlsRegionAlign ) {
501                                 lmap.tlsRegionAlign = (*reg_it)->getMemAlignment();
502                             }
503                             break;
504                         default:
505                             // ignore any other regions
506                             break;
507                     }
508                 }else if( isConstructorRegion(*reg_it) ) {
509                     lmap.newCtorRegions.push_back(*reg_it);
510                     if( (*reg_it)->getMemAlignment() > lmap.ctorRegionAlign ) {
511                         lmap.ctorRegionAlign = (*reg_it)->getMemAlignment();
512                     }
513                 }else if( isDestructorRegion(*reg_it) ) {
514                     lmap.newDtorRegions.push_back(*reg_it);
515                     if( (*reg_it)->getMemAlignment() > lmap.dtorRegionAlign ) {
516                         lmap.dtorRegionAlign = (*reg_it)->getMemAlignment();
517                     }
518                 } else if( isGOTRegion(*reg_it) ) {
519                   lmap.gotRegions.push_back(*reg_it);
520                   if( (*reg_it)->getMemAlignment() > lmap.gotRegionAlign ) {
521                     lmap.gotRegionAlign = (*reg_it)->getMemAlignment();
522                   }
523                 }else{
524                     switch((*reg_it)->getRegionType()) {
525                         case Region::RT_TEXT:
526                             lmap.codeRegions.push_back(*reg_it);
527                             // Determine alignment of combined region
528                             if( (*reg_it)->getMemAlignment() > lmap.codeRegionAlign ) {
529                                 lmap.codeRegionAlign = (*reg_it)->getMemAlignment();
530                             }
531                             break;
532                         case Region::RT_DATA:
533                             lmap.dataRegions.push_back(*reg_it);
534                             // Determine alignment of combined region
535                             if( (*reg_it)->getMemAlignment() > lmap.dataRegionAlign ) {
536                                 lmap.dataRegionAlign = (*reg_it)->getMemAlignment();
537                             }
538
539                             break;
540                         case Region::RT_BSS:
541                             lmap.bssRegions.push_back(*reg_it);
542                             // Determine alignment of combined region
543                             if( (*reg_it)->getMemAlignment() > lmap.bssRegionAlign ) {
544                                 lmap.bssRegionAlign = (*reg_it)->getMemAlignment();
545                             }
546                             break;
547                         case Region::RT_TEXTDATA:
548                             lmap.codeRegions.push_back(*reg_it);
549                             // Determine alignment of combined region
550                             if( (*reg_it)->getMemAlignment() > lmap.codeRegionAlign ) {
551                                 lmap.codeRegionAlign = (*reg_it)->getMemAlignment();
552                             }
553                             break;
554                         default:
555                             // skip other regions
556                             continue;
557                     }
558                 }
559
560                 // Find symbols that need to be put in the GOT
561
562 #if defined(arch_power) && defined(arch_64bit)
563                 // If statically linked binary, we need to put all the entries in region toc to GOT
564                 if(target->isStaticBinary() && (regionName.compare(".toc") == 0)) {
565                    // For every symbol in toc
566                    // Get data of the region and split it into symbols
567                    char *rawRegionData = reinterpret_cast<char *>((*reg_it)->getPtrToRawData());
568                    unsigned long numSymbols = (*reg_it)->getMemSize()/8;
569                    for (Offset entry = 0; entry < numSymbols; entry++ ) {       
570                       // If symbol has relocation, add that 
571                       bool relExist = false;
572                       vector<relocationEntry> &region_rels = (*reg_it)->getRelocations();
573                       vector<relocationEntry>::iterator rel_it;
574                       for( rel_it = region_rels.begin(); rel_it != region_rels.end(); ++rel_it) {
575                          if(entry*8 == rel_it->rel_addr()) {
576                             lmap.gotSymbolTable.push_back(make_pair(rel_it->getDynSym(), rel_it->addend()));  
577                             lmap.gotSymbols.insert(make_pair(rel_it->getDynSym(), rel_it->addend()));
578                             relExist = true;
579                             
580                             break;
581                          }
582                       }
583                       if(!relExist) {
584                          // else create a new symbol 
585                          // Offset and name is all we care - offset should be value of the symbol
586                          Offset soffset = *((unsigned long *) (rawRegionData + entry*8));
587                          Symbol *newsym = new Symbol("dyntoc_entry",
588                                                      Symbol::ST_UNKNOWN,
589                                                      Symbol::SL_UNKNOWN,
590                                                      Symbol::SV_UNKNOWN,
591                                                      soffset);
592                          
593                          lmap.gotSymbolTable.push_back(make_pair(newsym, 0));  
594                          lmap.gotSymbols.insert(make_pair(newsym, 0));
595                          
596                       }
597                    }
598                    
599                 }
600 #endif
601                 vector<relocationEntry> &region_rels = (*reg_it)->getRelocations();
602                 vector<relocationEntry>::iterator rel_it;
603                 for( rel_it = region_rels.begin(); rel_it != region_rels.end(); ++rel_it) {
604                   
605                   if(isGOTRelocation(rel_it->getRelType()) ) {
606                     lmap.gotSymbolTable.push_back(make_pair(rel_it->getDynSym(), rel_it->addend()));
607                     lmap.gotSymbols.insert(make_pair(rel_it->getDynSym(), 0));
608                     
609                   }
610                   
611                 }
612             } // isLoadable
613            
614         } //for regions
615
616         vector<Symbol *> definedSyms;
617         if( (*obj_it)->getAllDefinedSymbols(definedSyms) ) {
618             vector<Symbol *>::iterator sym_it;
619             for(sym_it = definedSyms.begin(); sym_it != definedSyms.end(); ++sym_it) {
620                 // Note: the assumption is made that a Symbol cannot 
621                 // be both TLS and COMMON
622                 if( (*sym_it)->isCommonStorage() ) {
623                     // For a symbol in common storage, the offset/value is the alignment
624                     commonAlignments.insert(make_pair((*sym_it)->getOffset(), *sym_it));
625
626                     // The alignment of a COMMON Region is the maximum alignment
627                     // needed by one of its symbols
628                     if( (*sym_it)->getOffset() > commonRegionAlign ) {
629                         commonRegionAlign = (*sym_it)->getOffset();
630                     }
631                 }else if( (*sym_it)->getType() == Symbol::ST_TLS ) {
632                     lmap.tlsSymbols.push_back(*sym_it);
633                 }
634             }
635         }
636     }
637
638     // Determine how all the Regions in the relocatable objects will be 
639     // placed in the rewritten target
640     Offset currentOffset = 0;
641
642     // Allocate code regions 
643
644     // Since this is the first new Region, the actual globalOffset should be 
645     // the passed globalOffset plus the padding for this Region
646     
647     Offset maxAlign = getGOTAlign(lmap);
648     if(maxAlign < lmap.codeRegionAlign) maxAlign = lmap.codeRegionAlign;
649
650     globalOffset += computePadding(globalOffset + currentOffset,
651             maxAlign);
652
653     // Handle PLT entries generated by GNU indirect functions
654     lmap.pltRegionAlign = lmap.codeRegionAlign;
655     lmap.pltRegionOffset = currentOffset;
656     lmap.pltRegionOffset += computePadding(globalOffset + lmap.pltRegionOffset,
657                                            lmap.pltRegionAlign);
658     currentOffset = allocatePLTEntries(lmap.pltEntries, lmap.pltRegionOffset, lmap.pltSize);
659
660     lmap.relRegionAlign = lmap.pltRegionAlign;
661     lmap.relRegionOffset = currentOffset;
662     lmap.relRegionOffset += computePadding(globalOffset + lmap.relRegionOffset,
663                                           lmap.relRegionAlign);
664     currentOffset = allocateRelocationSection(lmap.pltEntries, lmap.relRegionOffset,
665                                               lmap.relSize, target);
666
667     lmap.relGotRegionAlign = lmap.pltRegionAlign;
668     lmap.relGotRegionOffset = currentOffset;
669     lmap.relGotRegionOffset += computePadding(globalOffset + lmap.relGotRegionOffset,
670                                               lmap.relGotRegionAlign);
671     currentOffset = allocateRelGOTSection(lmap.pltEntries, lmap.relGotRegionOffset,
672                                           lmap.relGotSize);
673
674     // Allocate space for a GOT Region, if necessary
675     Offset gotLayoutOffset = 0;
676     lmap.gotSize = getGOTSize(target, lmap, gotLayoutOffset);
677     if( lmap.gotSize > 0 ) {
678       // We may copy the original GOT over; in this case, we have to be sure we skip it
679       // when we lay out new GOT entries. That's the gotLayoutOffset value. 
680         lmap.gotRegionAlign = getGOTAlign(lmap);
681         lmap.gotRegionOffset = currentOffset;
682         currentOffset += lmap.gotSize;
683         layoutRegions(lmap.gotRegions, lmap.regionAllocs,
684                       lmap.gotRegionOffset + gotLayoutOffset, globalOffset);
685         calculateTOCs(target, lmap.gotRegions, lmap.gotRegionOffset, gotLayoutOffset, globalOffset);
686     } 
687
688     // Calculate the space necessary for stub code; normally this will be 0,
689     // but we may need to add code later on. Make room for it now. 
690     // Note we use code region alignment here. 
691     lmap.stubRegionOffset = currentOffset;
692     lmap.stubRegionOffset += computePadding(globalOffset + lmap.stubRegionOffset,
693                                             lmap.codeRegionAlign);
694     rewrite_printf("Before allocStubRegions, currentOffset is 0x%lx\n", currentOffset);
695     currentOffset = allocStubRegions(lmap, globalOffset);
696     rewrite_printf("After allocStubRegions, currentOffset is 0x%lx\n", currentOffset);
697     if( currentOffset == ~0UL ) {
698         err = Storage_Allocation_Failure;
699         errMsg = "assumption failed while creating link map";
700         return false;
701     }
702     lmap.stubSize = currentOffset - lmap.stubRegionOffset;
703
704     lmap.codeRegionOffset = currentOffset;
705     lmap.codeRegionOffset += computePadding(globalOffset + lmap.codeRegionOffset,
706                                             lmap.codeRegionAlign);
707     currentOffset = layoutRegions(lmap.codeRegions, lmap.regionAllocs,
708                                   lmap.codeRegionOffset, globalOffset);
709     if( currentOffset == ~0UL ) {
710         err = Storage_Allocation_Failure;
711         errMsg = "assumption failed while creating link map";
712         return false;
713     }
714     lmap.codeSize = currentOffset - lmap.codeRegionOffset;
715
716     // Allocate data regions 
717     lmap.dataRegionOffset = currentOffset;
718     lmap.dataRegionOffset += computePadding(globalOffset + lmap.dataRegionOffset,
719             lmap.dataRegionAlign);
720     currentOffset = layoutRegions(lmap.dataRegions, lmap.regionAllocs, 
721             lmap.dataRegionOffset, globalOffset);
722     if( currentOffset == ~0UL ) {
723         err = Storage_Allocation_Failure;
724         errMsg = "assumption failed while creating link map";
725         return false;
726     }
727     lmap.dataSize = currentOffset - lmap.dataRegionOffset;
728
729     /* 
730      * Find current TLS Regions in target, also check for multiple TLS Regions
731      * of the same type => knowing how to construct the TLS image would be
732      * undefined for multiple TLS Regions of the same type
733      *
734      * Find current constructor Regions and destructor Regions.
735      */
736     Region *dataTLS = NULL, *bssTLS = NULL;
737     lmap.tlsSize = 0;
738     
739     vector<Region *> regions;
740     if( !target->getAllRegions(regions) ) {
741         err = Storage_Allocation_Failure;
742         errMsg = "failed to retrieve regions from target";
743         return false;
744     }
745     
746     vector<Region *>::iterator reg_it;
747     for(reg_it = regions.begin(); reg_it != regions.end(); ++reg_it) {
748         if( (*reg_it)->isTLS() ) {
749             if( (*reg_it)->getRegionType() == Region::RT_DATA ) {
750                 if( dataTLS != NULL ) {
751                     err = Storage_Allocation_Failure;
752                     errMsg = "found more than one TLS data region";
753                     return false;
754                 }
755                 dataTLS = *reg_it;
756                 lmap.tlsSize += dataTLS->getMemSize();
757                 if( dataTLS->getMemAlignment() > lmap.tlsRegionAlign ) {
758                     lmap.tlsRegionAlign = dataTLS->getMemAlignment();
759                 }
760             }else if( (*reg_it)->getRegionType() == Region::RT_BSS ) {
761                 if( bssTLS != NULL ) {
762                     err = Storage_Allocation_Failure;
763                     errMsg = "found more than one TLS bss region";
764                     return false;
765                 }
766                 bssTLS = *reg_it;
767                 lmap.tlsSize += bssTLS->getMemSize();
768                 if( bssTLS->getMemAlignment() > lmap.tlsRegionAlign ) {
769                     lmap.tlsRegionAlign = bssTLS->getMemAlignment();
770                 }
771             }
772         }else if( isConstructorRegion(*reg_it) ) {
773             lmap.originalCtorRegion = *reg_it;
774         }else if( isDestructorRegion(*reg_it) ){
775             lmap.originalDtorRegion = *reg_it;
776         }
777     }
778 #if defined(arch_x86) || defined(arch_x86_64) || defined(arch_power)
779     // Allocate the new TLS region, if necessary
780     if( lmap.tlsRegions.size() > 0 ) {
781         lmap.tlsRegionOffset = currentOffset;
782
783         lmap.tlsRegionOffset += computePadding(lmap.tlsRegionOffset + globalOffset,
784                 lmap.tlsRegionAlign);
785         currentOffset = layoutTLSImage(globalOffset, dataTLS, bssTLS, lmap);
786
787         if( currentOffset == lmap.tlsRegionOffset ) {
788             err = Storage_Allocation_Failure;
789             errMsg = "failed to create TLS initialization image";
790             return false;
791         }
792
793         /*
794          *  The size of this Region is counted twice: once when collecting the
795          *  original TLS Regions and once when laying out the image. This is
796          *  necessary to maintain consistency with the case where there are no
797          *  new TLS regions in the relocatable objects but existing TLS symbols
798          *  are used.
799          */
800         if( dataTLS != NULL ) {
801             lmap.tlsSize -= dataTLS->getMemSize();
802         }
803
804         lmap.tlsSize += currentOffset - lmap.tlsRegionOffset;
805
806         // Adjust offsets for all existing TLS symbols, as their offset
807         // in the TLS block could have changed
808         vector<Symbol *> definedSyms;
809         if( target->getAllDefinedSymbols(definedSyms) ) {
810             vector<Symbol *>::iterator sym_it;
811             for(sym_it = definedSyms.begin(); sym_it != definedSyms.end(); ++sym_it) {
812                 if( (*sym_it)->getType() == Symbol::ST_TLS ) {
813
814                     map<Region *, LinkMap::AllocPair>::iterator result;
815                     result = lmap.regionAllocs.find((*sym_it)->getRegion());
816
817                     if( result != lmap.regionAllocs.end() ) {
818                         Offset regionOffset = result->second.second;
819                         Offset symbolOffset = (*sym_it)->getOffset();
820                         lmap.origSymbols.push_back(make_pair(*sym_it, symbolOffset));
821
822                         symbolOffset += regionOffset - lmap.tlsRegionOffset;
823                         symbolOffset = adjustTLSOffset(symbolOffset, lmap.tlsSize);
824
825                         (*sym_it)->setOffset(symbolOffset);
826                     }
827                 }
828             }
829         }
830
831         cleanupTLSRegionOffsets(lmap.regionAllocs, dataTLS, bssTLS);
832         if( bssTLS != NULL ) lmap.tlsSize -= bssTLS->getMemSize();
833
834         hasRewrittenTLS_ = true;
835     }else{
836         // Adjust offsets for all existing TLS symbols, as the offsets required
837         // by relocation processing are TLS variant dependent
838         vector<Symbol *> definedSyms;
839         if( target->getAllDefinedSymbols(definedSyms) ) {
840             vector<Symbol *>::iterator sym_it;
841             for(sym_it = definedSyms.begin(); sym_it != definedSyms.end(); ++sym_it) {
842                 if( (*sym_it)->getType() == Symbol::ST_TLS ) {
843                     Offset symbolOffset = (*sym_it)->getOffset();
844                     lmap.origSymbols.push_back(make_pair(*sym_it, symbolOffset));
845
846                     symbolOffset = adjustTLSOffset(symbolOffset, lmap.tlsSize);
847                     (*sym_it)->setOffset(symbolOffset);
848                 }
849             }
850         }
851
852         // The size of the original TLS image is no longer needed
853         lmap.tlsSize = 0;
854     }
855
856 #endif
857     // Allocate space for a new constructor region, if necessary
858     if( lmap.newCtorRegions.size() > 0 ) {
859         lmap.ctorRegionOffset = currentOffset;
860         lmap.ctorRegionOffset += computePadding(globalOffset + lmap.ctorRegionOffset,
861                 lmap.ctorRegionAlign);
862         currentOffset = layoutNewCtorRegion(lmap);
863         if( currentOffset == ~0UL ) {
864             err = Storage_Allocation_Failure;
865             errMsg = "assumption failed while creating link map";
866             return false;
867         }
868         lmap.ctorSize = currentOffset - lmap.ctorRegionOffset;
869     }
870
871     // Allocate space for a new destructor region, if necessary
872     if( lmap.newDtorRegions.size() > 0 ) {
873         lmap.dtorRegionOffset = currentOffset;
874         lmap.dtorRegionOffset += computePadding(globalOffset + lmap.dtorRegionOffset,
875                 lmap.dtorRegionAlign);
876         currentOffset = layoutNewDtorRegion(lmap);
877         if( currentOffset == ~0UL ) {
878             err = Storage_Allocation_Failure;
879             errMsg = "assumption failed while creating link map";
880             return false;
881         }
882         lmap.dtorSize = currentOffset - lmap.dtorRegionOffset;
883     }
884
885     /* Combine all COMMON symbols into a single block */
886     if( commonAlignments.size() > 0 ) {
887         // The alignment of the COMMON Region could be the alignment 
888         // for the bss Region
889         if( commonRegionAlign > lmap.bssRegionAlign ) {
890             lmap.bssRegionAlign = commonRegionAlign;
891         }
892
893         // The following approach to laying out the COMMON symbols is greedy and
894         // suboptimal (in terms of space in the target), but it's quick...
895         Offset commonOffset = currentOffset;
896
897         // Make sure the COMMON Region's alignment is satisfied
898         commonOffset += computePadding(globalOffset + commonOffset, lmap.bssRegionAlign);
899         Offset commonStartOffset = commonOffset;
900
901         multimap<Offset, Symbol *>::iterator align_it;
902         for(align_it = commonAlignments.begin(); 
903             align_it != commonAlignments.end(); ++align_it)
904         {
905             commonOffset += computePadding(commonOffset, align_it->first);
906             lmap.origSymbols.push_back(make_pair(align_it->second, align_it->first));
907
908             // Update symbol with place in new linked data
909             align_it->second->setOffset(globalOffset + commonOffset);
910             commonOffset += align_it->second->getSize();
911         }
912
913         // Update the size of COMMON storage
914         if( commonAlignments.size() > 0 ) {
915             // A COMMON region is not really complete
916             lmap.commonStorage = Region::createRegion(0, Region::RP_RW,
917                     Region::RT_BSS, commonOffset - commonStartOffset, 0, 
918                     commonOffset - commonStartOffset,
919                     DEFAULT_COM_NAME, NULL, true, false, commonRegionAlign);
920             lmap.bssRegions.push_front(lmap.commonStorage);
921         }
922     }
923
924     // Allocate bss regions
925     lmap.bssRegionOffset = currentOffset;
926     lmap.bssRegionOffset += computePadding(globalOffset + lmap.bssRegionOffset,
927             lmap.bssRegionAlign);
928     currentOffset = layoutRegions(lmap.bssRegions, lmap.regionAllocs,
929             lmap.bssRegionOffset, globalOffset);
930     if( currentOffset == ~0UL ) {
931         err = Storage_Allocation_Failure;
932         errMsg = "assumption failed while creating link map";
933         return false;
934     }
935
936     lmap.bssSize = currentOffset - lmap.bssRegionOffset;
937
938     // Update all relevant symbols with their offsets in the new target
939     for(obj_it = relocatableObjects.begin(); obj_it != relocatableObjects.end(); ++obj_it) {
940         vector<Symbol *> definedSyms;
941         if( (*obj_it)->getAllDefinedSymbols(definedSyms) ) {
942             vector<Symbol *>::iterator sym_it;
943             for(sym_it = definedSyms.begin(); sym_it != definedSyms.end(); ++sym_it) {
944                 if(    !(*sym_it)->isCommonStorage() 
945                     && (*sym_it)->getType() != Symbol::ST_TLS) 
946                 {
947                     map<Region *, LinkMap::AllocPair>::iterator result;
948                     result = lmap.regionAllocs.find((*sym_it)->getRegion());
949                     if( result != lmap.regionAllocs.end() ) {
950                         Offset regionOffset = result->second.second;
951                         Offset symbolOffset = (*sym_it)->getOffset();
952                         lmap.origSymbols.push_back(make_pair(*sym_it, symbolOffset));
953
954                         symbolOffset += globalOffset + regionOffset;
955 // If region has relocations, set offset to got 
956                         vector<relocationEntry> region_rels = result->first->getRelocations();
957                         if(region_rels.size() > 0) {
958 //                      printf(" region %s has relocations %d \n", result->first->getRegionName().c_str(), region_rels.size()); 
959 /*
960                                 result = lmap.regionAllocs.find((*sym_it)->getRegion());
961                                 regionOffset = result->second.second;
962 */
963                         }
964                         
965                 
966                         (*sym_it)->setOffset(symbolOffset);
967                     }
968                 }
969             }
970         }
971     }
972
973     /* ASSUMPTION
974      * At this point, the layout of the new regions is fixed, and
975      * addresses of all symbols are known (excluding Constructor/Destructor Regions)
976      */
977
978     // Allocate storage space
979     lmap.allocatedData = new char[currentOffset];
980     lmap.allocatedSize = currentOffset;
981
982     // Copy the Regions from the relocatable objects into the new storage space
983     copyRegions(lmap);
984
985     return true;
986 }
987
988 /**
989  * Lays out the specified regions, storing the layout info in the 
990  * passed map.
991  *
992  * regions              A collection of Regions to layout
993  * regionAllocs         A map of Regions to their layout information
994  * currentOffset        The starting offset for the passed Regions in
995  *                      the new storage space
996  * globalOffset         The location of the new storage space in the
997  *                      target (used for padding calculation)
998  */
999 Offset emitElfStatic::layoutRegions(deque<Region *> &regions, 
1000                                     map<Region *, LinkMap::AllocPair> &regionAllocs,
1001                                     Offset currentOffset, Offset globalOffset) 
1002 {
1003     Offset retOffset = currentOffset;
1004
1005     deque<Region *>::iterator copyReg_it;
1006     for(copyReg_it = regions.begin(); copyReg_it != regions.end(); ++copyReg_it) {
1007         // Skip empty Regions
1008         if( (*copyReg_it)->getMemSize() == 0 ) continue;
1009
1010         // Make sure the Region is aligned correctly in the new aggregate Region
1011         Offset padding = computePadding(globalOffset + retOffset, (*copyReg_it)->getMemAlignment());
1012         retOffset += padding;
1013
1014         // Set up mapping for a new Region in the specified storage space
1015         pair<map<Region *, LinkMap::AllocPair>::iterator, bool> result;
1016         result = regionAllocs.insert(make_pair(*copyReg_it, make_pair(padding, retOffset)));
1017
1018         // If the map already contains this Region, this is a logic error
1019         if( !result.second ) {
1020             retOffset = ~0UL;
1021             break;
1022         }
1023                        
1024         retOffset += (*copyReg_it)->getMemSize();
1025     }
1026
1027     return retOffset;
1028 }
1029
1030 /*
1031  * Adds new combined Regions to the target at the specified globalOffset
1032  *
1033  * target       The Symtab object to which the new Regions will be added
1034  * globalOffset The offset of the first new Region in the target
1035  * lmap         Contains all the information about the LinkMap
1036  */
1037 bool emitElfStatic::addNewRegions(Symtab *target, Offset globalOffset, LinkMap &lmap) {
1038     char *newTargetData = lmap.allocatedData;
1039  
1040 #if defined(arch_x86) || defined(arch_x86_64)  || (defined(arch_power) && defined(arch_64bit))
1041     if( lmap.gotSize > 0 ) {
1042        buildGOT(target, lmap);
1043         target->addRegion(globalOffset + lmap.gotRegionOffset,
1044                 reinterpret_cast<void *>(&newTargetData[lmap.gotRegionOffset]),
1045                 static_cast<unsigned int>(lmap.gotSize),
1046                 GOT_NAME, Region::RT_DATA, true, lmap.gotRegionAlign);
1047     }   
1048 #endif
1049     if( lmap.pltSize > 0 ) {
1050       target->addRegion(globalOffset + lmap.pltRegionOffset,
1051                         reinterpret_cast<void *>(&newTargetData[lmap.pltRegionOffset]),
1052                         static_cast<unsigned int>(lmap.pltSize),
1053                         PLT_NAME, Region::RT_TEXTDATA, true, lmap.pltRegionAlign);
1054     } 
1055
1056     if (lmap.relSize > 0) {
1057       Region::RegionType type;
1058       if (addressWidth_ == 8) {
1059         type = Region::RT_RELA;
1060         cerr << "Adding region with type rela" << endl;
1061       }
1062       else {
1063         cerr << "Adding region with type rel" << endl;
1064         type = Region::RT_REL;
1065       }
1066       target->addRegion(globalOffset + lmap.relRegionOffset,
1067                         reinterpret_cast<void *>(&newTargetData[lmap.relRegionOffset]),
1068                         static_cast<unsigned int>(lmap.relSize),
1069                         REL_NAME, type, true, lmap.relRegionAlign);
1070       
1071     }
1072
1073     if (lmap.relGotSize > 0) {
1074       target->addRegion(globalOffset + lmap.relGotRegionOffset,
1075                         reinterpret_cast<void *>(&newTargetData[lmap.relGotRegionOffset]),
1076                         static_cast<unsigned int>(lmap.relGotSize),
1077                         REL_GOT_NAME, Region::RT_TEXTDATA, true, lmap.relGotRegionAlign);
1078     }    
1079
1080     if( lmap.codeSize > 0 ) {
1081         target->addRegion(globalOffset + lmap.codeRegionOffset,
1082                 reinterpret_cast<void *>(&newTargetData[lmap.codeRegionOffset]),
1083                 static_cast<unsigned int>(lmap.codeSize),
1084                 CODE_NAME, Region::RT_TEXTDATA, true, lmap.codeRegionAlign);
1085     }
1086     if (lmap.stubSize > 0) {
1087         target->addRegion(globalOffset + lmap.stubRegionOffset,
1088                           reinterpret_cast<void *>(&newTargetData[lmap.stubRegionOffset]),
1089                           static_cast<unsigned int>(lmap.stubSize),
1090                           STUB_NAME, Region::RT_TEXTDATA, true, lmap.codeRegionAlign);
1091     }      
1092
1093     if( lmap.dataSize > 0 ) {
1094         target->addRegion(globalOffset + lmap.dataRegionOffset, 
1095                 reinterpret_cast<void *>(&newTargetData[lmap.dataRegionOffset]),
1096                 static_cast<unsigned int>(lmap.dataSize),
1097                 DATA_NAME, Region::RT_DATA, true, lmap.dataRegionAlign);
1098     }
1099
1100 #if defined(arch_x86) || defined(arch_x86_64)  || defined(arch_power) 
1101     if( lmap.tlsSize > 0 ) {
1102         target->addRegion(globalOffset + lmap.tlsRegionOffset,
1103                 reinterpret_cast<void *>(&newTargetData[lmap.tlsRegionOffset]),
1104                 static_cast<unsigned int>(lmap.tlsSize),
1105                 TLS_DATA_NAME, Region::RT_DATA, true, lmap.tlsRegionAlign, true);
1106     }
1107 #endif
1108     if( lmap.newCtorRegions.size() > 0 ) {
1109         if( !createNewCtorRegion(lmap) ) {
1110             return false;
1111         }
1112
1113         target->addRegion(globalOffset + lmap.ctorRegionOffset,
1114                 reinterpret_cast<void *>(&newTargetData[lmap.ctorRegionOffset]),
1115                 static_cast<unsigned int>(lmap.ctorSize),
1116                 CTOR_NAME, Region::RT_DATA, true, 
1117                 lmap.ctorRegionAlign);
1118     }
1119
1120     if( lmap.newDtorRegions.size() > 0 ) {
1121         if( !createNewDtorRegion(lmap) ) {
1122             return false;
1123         }
1124
1125         target->addRegion(globalOffset + lmap.dtorRegionOffset,
1126                 reinterpret_cast<void *>(&newTargetData[lmap.dtorRegionOffset]),
1127                 static_cast<unsigned int>(lmap.dtorSize),
1128                 DTOR_NAME, Region::RT_DATA, true,
1129                 lmap.dtorRegionAlign);
1130     }
1131
1132     if( lmap.bssSize > 0 ) {
1133         target->addRegion(globalOffset + lmap.bssRegionOffset, 
1134                 reinterpret_cast<void *>(&newTargetData[lmap.bssRegionOffset]),
1135                 static_cast<unsigned int>(lmap.bssSize),
1136                 BSS_NAME, Region::RT_BSS, true, lmap.bssRegionAlign);
1137     }
1138
1139     return true;
1140 }
1141
1142 /**
1143  * Copys the new Regions, as indicated by the LinkMap, into the
1144  * allocated storage space
1145  *
1146  * lmap         Contains all the information necessary to perform the copy
1147  */
1148 void emitElfStatic::copyRegions(LinkMap &lmap) {
1149     char *targetData = lmap.allocatedData;
1150
1151     map<Region *, LinkMap::AllocPair>::iterator regOff_it;
1152     for(regOff_it = lmap.regionAllocs.begin(); regOff_it != lmap.regionAllocs.end(); ++regOff_it) {
1153         Region *depRegion = regOff_it->first;
1154         Offset regionOffset = regOff_it->second.second;
1155         Offset padding = regOff_it->second.first;
1156
1157         // Copy in the Region data
1158         char *rawRegionData = reinterpret_cast<char *>(depRegion->getPtrToRawData());
1159
1160         if( !depRegion->isBSS() ) {
1161             memcpy(&targetData[regionOffset], rawRegionData, depRegion->getMemSize());
1162         }
1163
1164         // Set the padded space to a meaningful value
1165         memset(&targetData[regionOffset - padding], getPaddingValue(depRegion->getRegionType()), padding);
1166     }
1167 }
1168
1169 /**
1170  * Computes the padding necessary to satisfy the specified alignment
1171  *
1172  * candidateOffset      A possible offset for an item
1173  * alignment            The alignment for an item
1174  */
1175 inline
1176 Offset emitElfStatic::computePadding(Offset candidateOffset, Offset alignment) {
1177     Offset padding = 0;
1178     if( alignment != 0 && (candidateOffset % alignment) != 0 ) {
1179         padding = alignment - (candidateOffset % alignment);
1180     }
1181     return padding;
1182 }
1183
1184 /**
1185  * Given a collection of newly allocated regions in the specified storage space, 
1186  * computes relocations and places the values at the location specified by the
1187  * relocation entry (stored with the Regions)
1188  *
1189  * target               The Symtab object being rewritten
1190  * relocatableObjects   A list of relocatable files being linked into target
1191  * globalOffset         The location of the new storage space in target
1192  * lmap                 Contains all the information necessary to apply relocations
1193  */
1194 bool emitElfStatic::applyRelocations(Symtab *target, vector<Symtab *> &relocatableObjects,
1195                                      Offset globalOffset, LinkMap &lmap,
1196                                      StaticLinkError &err, string &errMsg) 
1197 {
1198     // Iterate over all relocations in all relocatable files
1199     vector<Symtab *>::iterator depObj_it;
1200     for(depObj_it = relocatableObjects.begin(); depObj_it != relocatableObjects.end(); ++depObj_it) {
1201         vector<Region *> allRegions;
1202         (*depObj_it)->getAllRegions(allRegions);
1203
1204         // Relocations are stored with the Region to which they will be applied
1205         // As an ELF example, .rel.text relocations are stored with the Region .text
1206         vector<Region *>::iterator region_it;
1207         for(region_it = allRegions.begin(); region_it != allRegions.end(); ++region_it) {
1208            // Only compute relocations for the new Regions
1209            bool isText = ((*region_it)->getRegionType() == Region::RT_TEXT);
1210            bool isTOC = false;
1211
1212            string regionName = (*region_it)->getRegionName();           
1213            if (regionName.compare(0, 4, ".toc") == 0) isTOC = true;
1214
1215            if (!isText && !isTOC) {
1216               continue;
1217            }
1218         map<Region *, LinkMap::AllocPair>::iterator result;
1219         result = lmap.regionAllocs.find(*region_it);
1220         if( result != lmap.regionAllocs.end() ) { 
1221
1222                 Offset regionOffset = result->second.second;
1223                 vector<relocationEntry> region_rels = (*region_it)->getRelocations();
1224
1225                 vector<relocationEntry>::iterator rel_it;
1226                 for(rel_it = region_rels.begin(); rel_it != region_rels.end(); ++rel_it) {
1227                     // Compute destination of relocation
1228                     Offset dest = regionOffset + rel_it->rel_addr();
1229                     Offset relOffset = globalOffset + dest;
1230
1231                     rewrite_printf("Computing relocations to apply to region: %s (%s) @ 0x%lx reloffset 0x%lx dest 0x%lx  \n\n",
1232                                    (*region_it)->getRegionName().c_str(), 
1233                                    (*region_it)->symtab()->file().c_str(),
1234                                    regionOffset, 
1235                                    relOffset,
1236                                    dest);
1237                     rewrite_printf("\t RelOffset computed as region 0x%lx + rel_addr 0x%lx + globalOffset 0x%lx\n",
1238                                    regionOffset, rel_it->rel_addr(), globalOffset);
1239                     
1240                     char *targetData = lmap.allocatedData;
1241                     
1242                     if( !archSpecificRelocation(target, *depObj_it, 
1243                                                 targetData, *rel_it, dest, 
1244                                                 relOffset, globalOffset, lmap, errMsg) ) 
1245                     {
1246                         err = Relocation_Computation_Failure;
1247                         errMsg = "Failed to compute relocation: " + errMsg;
1248                         return false;
1249                     }
1250 /*
1251                    if((*region_it)->getRegionName().compare(".toc") == 0){
1252                         Offset regOffset = lmap.gotRegionOffset; 
1253                         dest = regOffset + rel_it->rel_addr();
1254                         relOffset = globalOffset + dest;
1255
1256                     if((*rel_it).name().compare("__SYMTABAPI_CTOR_LIST__") == 0) 
1257                         {
1258                         printf("\n\tComputing relocations to apply to region: %s @ 0x%lx reloffset %d 0x%lx dest %d 0x%lx  \n\n",
1259                         (*region_it)->getRegionName().c_str(), regOffset, relOffset,relOffset, dest,dest);
1260                     if( !archSpecificRelocation(target, *depObj_it, targetData, *rel_it, dest, 
1261                                 relOffset, globalOffset, lmap, errMsg) ) 
1262                     {
1263                         err = Relocation_Computation_Failure;
1264                         errMsg = "Failed to compute relocation: " + errMsg;
1265                         return false;
1266                     }
1267                         }
1268                 
1269                    }  
1270 */
1271                 }
1272             }
1273         }
1274     }
1275
1276     rewrite_printf("\n*** Computing relocations added to target.\n\n");
1277
1278     // Compute relocations added to target 
1279     vector<Region *> allRegions;
1280     target->getAllRegions(allRegions);
1281
1282     vector<Region *>::iterator reg_it;
1283     for(reg_it = allRegions.begin(); reg_it != allRegions.end(); ++reg_it) {
1284           
1285         char *regionData = reinterpret_cast<char *>((*reg_it)->getPtrToRawData());
1286         
1287         vector<relocationEntry>::iterator rel_it;
1288         for(rel_it = (*reg_it)->getRelocations().begin();
1289             rel_it != (*reg_it)->getRelocations().end();
1290             ++rel_it)
1291           {
1292             // Don't process relocations for other sections; those get handled by the
1293             // stub code.
1294             if ((rel_it->rel_addr() < (*reg_it)->getMemOffset()) ||
1295                 (rel_it->rel_addr() >= ((*reg_it)->getMemOffset() + (*reg_it)->getMemSize()))) continue;
1296             if( !archSpecificRelocation(target, target, regionData, *rel_it,
1297                         rel_it->rel_addr() - (*reg_it)->getDiskOffset(),
1298                         rel_it->rel_addr(), globalOffset, lmap, errMsg) )
1299             {
1300                 err = Relocation_Computation_Failure;
1301                 errMsg = "Failed to compute relocation: " + errMsg;
1302                 return false;
1303             }
1304           }
1305     }
1306     return true;
1307 }
1308
1309 /**
1310  * A string representation of the StaticLinkError returned by
1311  * other functions
1312  */
1313 string emitElfStatic::printStaticLinkError(StaticLinkError err) {
1314     switch(err) {
1315         CASE_RETURN_STR(No_Static_Link_Error);
1316         CASE_RETURN_STR(Symbol_Resolution_Failure);
1317         CASE_RETURN_STR(Relocation_Computation_Failure);
1318         CASE_RETURN_STR(Storage_Allocation_Failure);
1319         default:
1320             return "unknown error";
1321     }
1322 }
1323
1324 /**
1325  * Indicates if a new TLS initialization image has been created
1326  */
1327 bool emitElfStatic::hasRewrittenTLS() const {
1328     return hasRewrittenTLS_;
1329 }
1330
1331 /** The following functions are all somewhat architecture-specific */
1332
1333 /* TLS Info
1334  *
1335  * TLS handling is pseudo-architecture dependent. The implementation of the TLS
1336  * functions depend on the implementation of TLS on a specific architecture.
1337  *
1338  * The following material is documented in more detail in the 
1339  * "ELF Handling For TLS" white paper. According to this paper, their are 
1340  * two variants w.r.t. creating a TLS initialization image.
1341  *
1342  * ======================
1343  *
1344  * The first is:
1345  *
1346  *            beginning of image
1347  *            |
1348  *            V                              high address
1349  * +----+-----+----------+---------+---------+
1350  * |    | TCB | image 1  | image 2 | image 3 |
1351  * +----+---- +----------+---------+---------+
1352  *
1353  * where TCB = thread control block, and each image is the
1354  * TLS initialization image for an object (in this context an executable or 
1355  * shared library).
1356  *
1357  * ========================
1358  *
1359  * The second is:
1360  * 
1361  * beginning of image
1362  * | 
1363  * V                                        high address
1364  * +---------+----------+---------+---------+
1365  * | image 3 | image 2  | image 1 |  TCB    |
1366  * +---------+----------+---------+---------+
1367  *
1368  * An image is:
1369  *
1370  * +--------+--------+
1371  * | DATA   |  BSS   |
1372  * +--------+--------+
1373  *
1374  * New TLS data and bss is added to the original initialization image as follows:
1375  *
1376  * +----------+------------------+-------------+------------+-----+
1377  * | NEW DATA | EXPANDED NEW BSS | TARGET DATA | TARGET BSS | TCB |
1378  * +----------+------------------+-------------+------------+-----+
1379  *
1380  * It is important to note that the TARGET DATA and TARGET BSS blocks are not moved.
1381  * This ensures that the modifications to the TLS image are safe.
1382  *
1383  * ==========================
1384  * 
1385  * These are the two variants one would see when working with ELF files. So, an
1386  * architecture either uses variant 1 or 2.
1387  *
1388  */
1389
1390 /* See architecture specific functions that call these for descriptions of function interface */
1391
1392 Offset emitElfStatic::tlsLayoutVariant1(Offset globalOffset, Region *dataTLS, Region *bssTLS, LinkMap &lmap)
1393 {
1394     // The original init. image needs to remain in the image 1 slot because
1395     // the TLS data references are relative to that position
1396     unsigned long tlsBssSize = 0;
1397     if( dataTLS != NULL ) lmap.tlsRegions.push_back(dataTLS);
1398     if( bssTLS != NULL ) tlsBssSize = bssTLS->getMemSize();
1399     deque<Region *> tlsRegionsVar;
1400
1401     deque<Region *>::iterator copyReg_it;
1402     for(copyReg_it = lmap.tlsRegions.begin(); copyReg_it != lmap.tlsRegions.end(); ++copyReg_it) {
1403          tlsRegionsVar.push_front(*copyReg_it);
1404     }
1405
1406     // Create the image, note new BSS regions are expanded
1407     Offset endOffset = layoutRegions(lmap.tlsRegions,
1408             lmap.regionAllocs, lmap.tlsRegionOffset, globalOffset);
1409     if( endOffset == ~0UL ) return lmap.tlsRegionOffset;
1410     Offset adjustedEnd = endOffset - lmap.tlsRegionOffset;
1411
1412     // This is necessary so the offsets of existing TLS symbols can be updated
1413     // in a uniform, architecture independent way
1414     if( bssTLS != NULL ) {
1415         if( dataTLS != NULL ) {
1416             lmap.regionAllocs.insert(make_pair(bssTLS, lmap.regionAllocs[dataTLS]));
1417         }else{
1418             lmap.regionAllocs.insert(make_pair(bssTLS, make_pair(0, endOffset)));
1419         }
1420     }
1421
1422     // Update the symbols with their offsets relative to the TCB address
1423     vector<Symbol *>::iterator sym_it;
1424     for(sym_it = lmap.tlsSymbols.begin(); sym_it != lmap.tlsSymbols.end(); ++sym_it) {
1425         map<Region *, LinkMap::AllocPair>::iterator result;
1426         result = lmap.regionAllocs.find((*sym_it)->getRegion());
1427
1428         // It is a programming error if the region for the symbol
1429         // was not passed to this function
1430         if( result == lmap.regionAllocs.end() ) {
1431             endOffset = lmap.tlsRegionOffset;
1432             break;
1433         }
1434
1435         Offset regionOffset = result->second.second;
1436         Offset symbolOffset = (*sym_it)->getOffset();
1437         lmap.origSymbols.push_back(make_pair((*sym_it), symbolOffset));
1438
1439         symbolOffset += (regionOffset - lmap.tlsRegionOffset) - (adjustedEnd + tlsBssSize);
1440         (*sym_it)->setOffset(symbolOffset);
1441     }
1442
1443     return endOffset;
1444 }
1445
1446 Offset emitElfStatic::tlsLayoutVariant2(Offset globalOffset, Region *dataTLS, Region *bssTLS,
1447         LinkMap &lmap)
1448 {
1449     // The original init. image needs to remain in the image 1 slot because
1450     // the TLS data references are relative to that position
1451     unsigned long tlsBssSize = 0;
1452     if( dataTLS != NULL ) lmap.tlsRegions.push_back(dataTLS);
1453     if( bssTLS != NULL ) tlsBssSize = bssTLS->getMemSize();
1454
1455     // Create the image, note new BSS regions are expanded
1456     Offset endOffset = layoutRegions(lmap.tlsRegions,
1457             lmap.regionAllocs, lmap.tlsRegionOffset, globalOffset);
1458     if( endOffset == ~0UL ) return lmap.tlsRegionOffset;
1459     Offset adjustedEnd = endOffset - lmap.tlsRegionOffset;
1460
1461     // This is necessary so the offsets of existing TLS symbols can be updated
1462     // in a uniform, architecture independent way
1463     if( bssTLS != NULL ) {
1464         if( dataTLS != NULL ) {
1465             lmap.regionAllocs.insert(make_pair(bssTLS, lmap.regionAllocs[dataTLS]));
1466         }else{
1467             lmap.regionAllocs.insert(make_pair(bssTLS, make_pair(0, endOffset)));
1468         }
1469     }
1470
1471     // Update the symbols with their offsets relative to the TCB address
1472     vector<Symbol *>::iterator sym_it;
1473     for(sym_it = lmap.tlsSymbols.begin(); sym_it != lmap.tlsSymbols.end(); ++sym_it) {
1474         map<Region *, LinkMap::AllocPair>::iterator result;
1475         result = lmap.regionAllocs.find((*sym_it)->getRegion());
1476
1477         // It is a programming error if the region for the symbol
1478         // was not passed to this function
1479         if( result == lmap.regionAllocs.end() ) {
1480             endOffset = lmap.tlsRegionOffset;
1481             break;
1482         }
1483
1484         Offset regionOffset = result->second.second;
1485         Offset symbolOffset = (*sym_it)->getOffset();
1486         lmap.origSymbols.push_back(make_pair((*sym_it), symbolOffset));
1487
1488         symbolOffset += (regionOffset - lmap.tlsRegionOffset) - (adjustedEnd + tlsBssSize);
1489         (*sym_it)->setOffset(symbolOffset);
1490     }
1491
1492     return endOffset;
1493 }
1494
1495 // Note: Variant 1 does not require any modifications, so a separate
1496 // function is not necessary
1497 Offset emitElfStatic::tlsAdjustVariant2(Offset curOffset, Offset tlsSize) {
1498     // For Variant 2, offsets relative to the TCB need to be negative
1499     Offset retOffset = curOffset;
1500     retOffset -= tlsSize;
1501     return retOffset;
1502 }
1503
1504 void emitElfStatic::tlsCleanupVariant1(map<Region *, LinkMap::AllocPair> &regionAllocs,
1505         Region *, Region *bssTLS) 
1506 {
1507     // Existing BSS TLS region is not copied to the new target data
1508     if( bssTLS != NULL ) regionAllocs.erase(bssTLS);
1509 }
1510
1511 void emitElfStatic::tlsCleanupVariant2(map<Region *, LinkMap::AllocPair> &regionAllocs,
1512         Region *, Region *bssTLS) 
1513 {
1514     // Existing BSS TLS region is not copied to the new target data
1515     if( bssTLS != NULL ) regionAllocs.erase(bssTLS);
1516 }
1517
1518 bool 
1519 emitElfUtils::sort_reg(const Region* a, const Region* b)
1520 {   
1521     if (a->getMemOffset() == b->getMemOffset())
1522         return a->getMemSize() < b->getMemSize();
1523     return a->getMemOffset() < b->getMemOffset();
1524 }
1525
1526 /*
1527  * Sort the sections array so that sections with a non-zero
1528  * memory offset come first (and are sorted in increasing
1529  * order of offset). Preserves the ordering of zero-offset
1530  * sections.
1531  *
1532  * If no section has a non-zero offset, the return value will
1533  * be an address in the virtual memory space big enough to
1534  * hold all the loadable sections. Otherwise it will be the
1535  * address of the first non-zero offset section.
1536  *
1537  * NB if we need to create a new segment to hold these sections,
1538  * it needs to be clear up to the next page boundary to avoid
1539  * potentially clobbering other loadable segments.
1540  */
1541 Address 
1542 emitElfUtils::orderLoadableSections(Symtab *obj, vector<Region*> & sections)
1543 {
1544     Address ret = 0;
1545     Address sz = 0;
1546     vector<Region*> nonzero;
1547     vector<Region*> copy(sections);
1548     unsigned insert = sections.size()-1;
1549
1550     for(int i=copy.size()-1;i>=0;--i) {
1551         if(!copy[i]->getMemOffset())
1552             sections[insert--] = copy[i];
1553         else
1554             nonzero.push_back(copy[i]);
1555         sz += copy[i]->getMemSize();
1556     }
1557
1558     assert(nonzero.size() == (insert+1));
1559
1560     std::sort(nonzero.begin(),nonzero.end(),sort_reg);
1561     for(unsigned i=0;i<nonzero.size();++i)
1562         sections[i] = nonzero[i];
1563
1564     if(nonzero.size() > 0)
1565         ret = nonzero[0]->getMemOffset();
1566     else {
1567         // find a `hole' of appropriate size
1568         sz = (sz + 4096 - 1) & ~(4096-1);
1569         ret = obj->getFreeOffset(sz);
1570         if(!ret) {
1571             fprintf(stderr,"Failed to finde hole of size %lx, bailing\n",sz);
1572         }
1573     }
1574     return ret;
1575 }
1576
1577 // There are also some known variables that point to the heap 
1578 bool emitElfUtils::updateHeapVariables(Symtab *obj, unsigned long newSecsEndAddress ) {
1579     unsigned pgSize = (unsigned)getpagesize();
1580     const std::string minbrk(".minbrk");
1581     const std::string curbrk(".curbrk");
1582     std::vector<Symbol *> heapSyms;
1583     obj->findSymbol(heapSyms, minbrk, Symbol::ST_NOTYPE);
1584     obj->findSymbol(heapSyms, curbrk, Symbol::ST_NOTYPE);
1585
1586     std::vector<Symbol *>::iterator heapSymsIter;
1587     for(heapSymsIter = heapSyms.begin();
1588       heapSymsIter != heapSyms.end();
1589       ++heapSymsIter)
1590     {
1591         Region *symRegion = (*heapSymsIter)->getRegion();
1592         Offset symOffset = (*heapSymsIter)->getOffset(); 
1593         if( symOffset < symRegion->getDiskOffset() ) continue;
1594
1595         Offset regOffset = symOffset - symRegion->getDiskOffset();
1596         unsigned char *regData = reinterpret_cast<unsigned char *>(symRegion->getPtrToRawData());
1597         Offset heapAddr;
1598         memcpy(&heapAddr, &regData[regOffset], sizeof(Offset));
1599
1600         heapAddr = (newSecsEndAddress & ~(pgSize-1)) + pgSize;
1601
1602         if( !symRegion->patchData(regOffset, &heapAddr, sizeof(Offset)) ) {
1603             rewrite_printf("Failed to update heap address\n");
1604             return false;
1605         }
1606     }
1607
1608     return true;
1609 }
1610
1611 inline
1612 static bool adjustValInRegion(Region *reg, Offset offInReg, Offset addressWidth, int adjust) {
1613     Offset newValue;
1614     unsigned char *oldValues;
1615
1616     oldValues = reinterpret_cast<unsigned char *>(reg->getPtrToRawData());
1617     memcpy(&newValue, &oldValues[offInReg], addressWidth);
1618     newValue += adjust;
1619     return reg->patchData(offInReg, &newValue, addressWidth);
1620 }
1621
1622 bool emitElfUtils::updateRelocation(Symtab *obj, relocationEntry &rel, int library_adjust) {
1623     // Currently, only verified on x86 and x86_64 -- this may work on other architectures
1624 #if defined(arch_x86) || defined(arch_x86_64)
1625     Region *targetRegion = obj->findEnclosingRegion(rel.rel_addr());
1626     if( NULL == targetRegion ) {
1627         rewrite_printf("Failed to find enclosing Region for relocation");
1628         return false;
1629     }
1630
1631     // Used to update a Region
1632     unsigned addressWidth = obj->getAddressWidth();
1633     if( addressWidth == 8 ) {
1634         switch(rel.getRelType()) {
1635             case R_X86_64_RELATIVE:
1636                 rel.setAddend(rel.addend() + library_adjust);
1637                 break;
1638             case R_X86_64_JUMP_SLOT:
1639                 if( !adjustValInRegion(targetRegion, 
1640                            rel.rel_addr() - targetRegion->getDiskOffset(),
1641                            addressWidth, library_adjust) )
1642                 {
1643                     rewrite_printf("Failed to update relocation\n");
1644                     return false;
1645                 }
1646                 break;
1647             default:
1648                 // Do nothing
1649                 break;
1650         }
1651     }else{
1652         switch(rel.getRelType()) {
1653             case R_386_RELATIVE:
1654                 // On x86, addends are stored in their target location
1655                 if( !adjustValInRegion(targetRegion, 
1656                            rel.rel_addr() - targetRegion->getDiskOffset(),
1657                            addressWidth, library_adjust) )
1658                 {
1659                     rewrite_printf("Failed to update relocation\n");
1660                     return false;
1661                 }
1662                 break;
1663             case R_386_JMP_SLOT:
1664                 if( !adjustValInRegion(targetRegion, 
1665                            rel.rel_addr() - targetRegion->getDiskOffset(),
1666                            addressWidth, library_adjust) )
1667                 {
1668                     rewrite_printf("Failed to update relocation\n");
1669                     return false;
1670                 }
1671                 break;
1672             default:
1673                 // Do nothing
1674                 break;
1675         }
1676     }
1677
1678     // XXX The GOT also holds a pointer to the DYNAMIC segment -- this is currently not
1679     // updated. However, this appears to be unneeded for regular shared libraries.
1680     
1681     // From the SYS V ABI x86 supplement
1682     // "The table's entry zero is reserved to hold the address of the dynamic structure,
1683     // referenced with the symbol _DYNAMIC. This allows a program, such as the
1684     // dynamic linker, to find its own dynamic structure without having yet processed
1685     // its relocation entries. This is especially important for the dynamic linker, because
1686     // it must initialize itself without relying on other programs to relocate its memory
1687     // image."
1688     
1689     // In order to implement this, would have determine the final address of a new .dynamic
1690     // section before outputting the patched GOT data -- this will require some refactoring.
1691 #else
1692     rewrite_printf("WARNING: updateRelocation is not implemented on this architecture\n");
1693 #endif
1694
1695     return true;
1696 }
1697
1698 bool emitElfStatic::calculateTOCs(Symtab *target, deque<Region *> &regions, Offset GOTstart, Offset newStart, Offset globalOffset) {
1699   rewrite_printf("Calculating TOCs for merged GOT sections, base is 0x%lx, new regions at 0x%lx\n", 
1700                  GOTstart + globalOffset,
1701                  GOTstart + newStart + globalOffset);
1702
1703   Offset GOTbase = GOTstart + globalOffset;
1704   Offset current = GOTbase + newStart;
1705   Offset currentTOC = target->getTOCoffset((Offset) 0);
1706   rewrite_printf("\tBase TOC is 0x%lx\n", currentTOC);
1707
1708   for (deque<Region *>::iterator iter = regions.begin(); iter != regions.end(); ++iter) {
1709     Region *reg = *iter;
1710     Symtab *symtab = reg->symtab();
1711     
1712     Offset end = current + reg->getDiskSize();
1713
1714     // We'd like the TOC to be GOTbase + 0x8000, so long as that can address the end of the current
1715     // region. 
1716     if ((currentTOC + 0x7ff0) < end) {
1717       // Crud...
1718       // OTOH, we can't reference anything outside the current GOT, so just rebase it
1719       currentTOC = current + 0x8000;
1720     }
1721     // Recheck
1722     if ((currentTOC + 0x7ff0) < end) {
1723       assert(0 && "Need to implement -bbigtoc equivalent to rewrite this binary!");
1724     }
1725     symtab->setTOCOffset(currentTOC);
1726     current = end;
1727   }
1728   return true;
1729 }
1730
1731 Offset emitElfStatic::allocatePLTEntries(std::map<Symbol *, std::pair<Offset, Offset> > &pltEntries,
1732                                        Offset pltOffset,
1733                                        Offset &size) {
1734   // For each Symtab
1735   //   For each indirect symbol
1736   //     Allocate a PLT entry for it
1737   //     Add it to entries
1738 #if defined(arch_x86)
1739   unsigned entry_size = 16;
1740 #elif defined(arch_x86_64)
1741   unsigned entry_size = 16;
1742 #elif defined(arch_power)
1743   unsigned entry_size = 0;
1744 #else
1745 #error "Unknown architecture"
1746 #endif
1747
1748   Offset cur = pltOffset;
1749   for (auto iter = pltEntries.begin(); iter != pltEntries.end(); ++iter) {
1750     iter->second.first = cur;
1751     cur += entry_size;
1752   }
1753
1754   size = cur - pltOffset;
1755   return cur;
1756 }
1757
1758 bool emitElfStatic::addIndirectSymbol(Symbol *sym, LinkMap &lmap) {
1759   // Existence is what we care about at this point
1760   lmap.pltEntries[sym] = make_pair(0,0);
1761   return true;
1762 }
1763
1764   
1765 bool emitElfStatic::buildPLT(Symtab *target, Offset globalOffset, 
1766                              LinkMap &lmap, StaticLinkError &err,
1767                              string &errMsg) {
1768 #if !defined(arch_x86_64)
1769   return lmap.pltEntries.empty();
1770 #else
1771   unsigned char pltEntry[] = {0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *<offset>, %rip
1772                      0x68, 0x00, 0x00, 0x00, 0x00, // pushq $0x0
1773                      0xe9, 0x00, 0x00, 0x00, 0x00}; // jmpq
1774   unsigned pltEntrySize = 16;
1775   unsigned gotOffset = 2;
1776   // Size of the first instruction for x86 platforms so the math works out right
1777   unsigned magicOffset = 6;
1778
1779   char *data = lmap.allocatedData;
1780
1781   unsigned index = 0;
1782   for (auto iter = lmap.pltEntries.begin(); iter != lmap.pltEntries.end(); ++iter) {
1783     char *entry = &(data[iter->second.first]);
1784
1785     memcpy(entry, pltEntry, pltEntrySize);
1786
1787     iter->second.second = lmap.relGotRegionOffset + (index * sizeof(void *)) + globalOffset;
1788     Offset curOffset = globalOffset + iter->second.first;
1789     int val = (int) (iter->second.second - curOffset - magicOffset);
1790
1791     memcpy(entry+gotOffset, &val, sizeof(int));
1792     ++index;
1793   }
1794   return true;
1795 #endif
1796 }
1797
1798 Offset emitElfStatic::allocateRelocationSection(std::map<Symbol *, std::pair<Offset, Offset> > &entries,
1799                                                 Offset relocOffset, Offset &size,
1800                                                 Symtab *target) {
1801 #if defined(arch_x86_64)
1802   unsigned relocSize;
1803   if (addressWidth_ == 8)
1804     relocSize = sizeof(Elf64_Rela);
1805   else
1806     relocSize = sizeof(Elf32_Rel);
1807 #elif defined(arch_x86)
1808   // 32-bit only uses REL types
1809   unsigned relocSize = sizeof(Elf32_Rel);
1810 #else
1811   size = 0;
1812   unsigned relocSize = 0;
1813   return relocOffset;
1814 #endif
1815
1816   Offset cur = relocOffset;
1817   Object *obj = target->getObject();
1818
1819   Region *rela = NULL;
1820   if (addressWidth_ == 8)
1821     target->findRegion(rela, ".rela.plt");
1822   else
1823     target->findRegion(rela, ".rel.plt");
1824
1825   unsigned relocEntries = entries.size() + (rela ? rela->getRelocations().size() : 0);
1826   cur += relocEntries * relocSize;
1827
1828   size = cur - relocOffset;
1829   return cur;
1830 }
1831
1832 Offset emitElfStatic::allocateRelGOTSection(const std::map<Symbol *, std::pair<Offset, Offset> > &entries,
1833                                             Offset relocOffset, Offset &size) {
1834 #if defined(arch_x86_64)
1835   unsigned relocSize = sizeof(Elf64_Rela);
1836 #else
1837   size = 0;
1838   return relocOffset;
1839 #endif
1840
1841   size = entries.size() * sizeof(void *);
1842   return relocOffset + size;
1843 }
1844
1845
1846 #if !defined(R_X86_64_IRELATIVE)
1847 #define R_X86_64_IRELATIVE 37
1848 #endif
1849 #if !defined(R_386_IRELATIVE)
1850 #define R_386_IRELATIVE 42
1851 #endif
1852
1853 bool emitElfStatic::buildRela(Symtab *target, Offset globalOffset, 
1854                              LinkMap &lmap, StaticLinkError &err,
1855                              string &errMsg) {
1856   if (lmap.relSize == 0) return true;
1857
1858 #if !defined(arch_x86_64)
1859   // TODO: implementation
1860   return false;
1861 #endif
1862
1863   if (addressWidth_ == 8) {
1864     // 64-bit uses RELA
1865     unsigned copied = 0;
1866     
1867     char *data = lmap.allocatedData;
1868     Elf64_Rela *relas = (Elf64_Rela *) &(data[lmap.relRegionOffset]);
1869     
1870     Region *rela = NULL;
1871     target->findRegion(rela, ".rela.plt");
1872     if (rela) {
1873       memcpy(relas, rela->getPtrToRawData(), rela->getDiskSize());
1874       copied += rela->getDiskSize();
1875       relas = (Elf64_Rela *) &(data[lmap.relRegionOffset + rela->getDiskSize()]);
1876     }
1877     
1878     unsigned index = 0;
1879     for (auto iter = lmap.pltEntries.begin(); iter != lmap.pltEntries.end(); ++iter) {
1880       // Grab a GOT location
1881       relas[index].r_offset = iter->second.second;
1882       relas[index].r_info = ELF64_R_INFO((unsigned long) STN_UNDEF, R_X86_64_IRELATIVE);
1883       relas[index].r_addend = iter->first->getOffset();
1884       copied += sizeof(Elf64_Rela);
1885       ++index;
1886     }
1887     assert(copied == lmap.relSize);
1888   }
1889   else {
1890     // 32 bit uses REL
1891     unsigned copied = 0;
1892     
1893     char *data = lmap.allocatedData;
1894     Elf32_Rel *rels = (Elf32_Rel *) &(data[lmap.relRegionOffset]);
1895     
1896     Region *rel = NULL;
1897     target->findRegion(rel, ".rel.plt");
1898     if (rel) {
1899       memcpy(rels, rel->getPtrToRawData(), rel->getDiskSize());
1900       copied += rel->getDiskSize();
1901       rels = (Elf32_Rel *) &(data[lmap.relRegionOffset + rel->getDiskSize()]);
1902     }
1903     
1904     unsigned index = 0;
1905     for (auto iter = lmap.pltEntries.begin(); iter != lmap.pltEntries.end(); ++iter) {
1906       // Grab a GOT location
1907       rels[index].r_offset = iter->second.second;
1908       rels[index].r_info = ELF32_R_INFO((unsigned long) STN_UNDEF, R_386_IRELATIVE);
1909       // For a REL relocation, the addend goes in *offset instead of its own 
1910       // slot...
1911
1912       // So find the data address for rels[index].r_offset
1913       // and set it to iter->first->getOffset(), AKA the symbol address
1914
1915       // We should be writing into .dyninstRELAgot; just have to figure out how. 
1916       long *got = (long *) &(data[rels[index].r_offset - globalOffset]);
1917       *got = iter->first->getOffset();
1918
1919       copied += sizeof(Elf32_Rel);
1920       ++index;
1921     }
1922     assert(copied == lmap.relSize);
1923   }
1924
1925   return true;
1926 }