Build fix
[dyninst.git] / symtabAPI / src / emitElfStatic.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
30  */
31
32 /*
33  * XXX
34  *
35  * This class is unnecessary. However, at the time of writing, emitElf was
36  * split into two different classes (one for 32-bit and 64-bit). Instead of
37  * duplicating code, this class was created to share code between the
38  * two emitElf classes.
39  *
40  * Once the emitElf classes are merged, this class can be merged with the new
41  * emitElf class.
42  */
43
44 #include <cstdlib>
45 #include <cstdio>
46 #include <iostream>
47
48 #include <algorithm>
49
50 #include "emitElfStatic.h"
51 #include "debug.h"
52
53 using namespace Dyninst;
54 using namespace SymtabAPI;
55
56 // Section names
57 static const string CODE_NAME(".dyninstCode");
58 static const string DATA_NAME(".dyninstData");
59 static const string BSS_NAME(".dyninstBss");
60 static const string GOT_NAME(".dyninstGot");
61 static const string CTOR_NAME(".dyninstCtors");
62 static const string DTOR_NAME(".dyninstDtors");
63 static const string TLS_DATA_NAME(".dyninstTdata");
64 static const string DEFAULT_COM_NAME(".common");
65
66 /* Used by architecture specific functions, but not architecture specific */
67 const string Dyninst::SymtabAPI::SYMTAB_CTOR_LIST_REL("__SYMTABAPI_CTOR_LIST__");
68 const string Dyninst::SymtabAPI::SYMTAB_DTOR_LIST_REL("__SYMTABAPI_DTOR_LIST__");
69
70 emitElfStatic::emitElfStatic(unsigned addressWidth, bool isStripped) :
71     addressWidth_(addressWidth),
72     isStripped_(isStripped),
73     hasRewrittenTLS_(false)
74 {}
75
76 /**
77  * NOTE:
78  * Most of these functions take a reference to a StaticLinkError and a string
79  * for error reporting purposes. These should prove useful in identifying the
80  * cause of an error
81  */
82
83 /**
84  * Statically links relocatable files into the specified Symtab object, 
85  * as specified by state in the Symtab object
86  *
87  * target       relocatable files will be linked into this Symtab
88  *
89  * Returns a pointer to a block of data containing the results of the link
90  * The caller is responsible for delete'ing this block of data
91  */
92 char *emitElfStatic::linkStatic(Symtab *target, 
93         StaticLinkError &err, string &errMsg) 
94 {
95     /* 
96      * Basic algorithm is:
97      * - locate defined versions of symbols for undefined symbols in 
98      *   either the target or relocatable code, produces a list
99      *   of Symtab objects that contain the defined versions
100      *
101      * - Allocate space for all new code and data to be linked into 
102      *   the target, populates a LinkMap with all allocation 
103      *   information
104      *
105      * - Compute relocations and set their targets to these values
106      */
107
108     // Holds all information necessary to work with the block of data created by createLinkMap
109     LinkMap lmap;
110
111     rewrite_printf("START link map output\n");
112     
113     // Determine starting location of new Regions
114     Offset globalOffset = 0;
115     vector<Region *> newRegs;
116     if( target->getAllNewRegions(newRegs) ) {
117         // This is true, only if other regions have already been added
118         vector<Region *>::iterator newReg_it;
119         for(newReg_it = newRegs.begin(); newReg_it != newRegs.end(); ++newReg_it) {
120             Offset newRegEndAddr = (*newReg_it)->getRegionSize() + (*newReg_it)->getRegionAddr();
121             if( newRegEndAddr > globalOffset ) {
122                 globalOffset = newRegEndAddr;
123             }
124         }
125     }
126
127     if( globalOffset == 0 ) {
128         err = Link_Location_Error;
129         errMsg = "failed to find location for new code and data.";
130         return NULL;
131     }
132
133     // Holds all necessary dependencies, as determined by resolveSymbols
134     vector<Symtab *> relocatableObjects;
135     if( !resolveSymbols(target, relocatableObjects, lmap, err, errMsg) ) {
136         return NULL;
137     }
138
139     // Lays out all relocatable files into a single contiguous block of data
140     if( !createLinkMap(target, relocatableObjects, globalOffset, lmap, err, errMsg) ) {
141         return NULL;
142     }
143
144     // Copies the data from the relocatable files into the new block of data
145     if( !addNewRegions(target, globalOffset, lmap) ) {
146         err = Storage_Allocation_Failure;
147         errMsg = "Failed to create new Regions in original binary";
148         return NULL;
149     }
150
151     // Print out the link map for debugging
152     rewrite_printf("Global Offset = 0x%lx\n", globalOffset);
153     if( sym_debug_rewrite ) {
154         lmap.printAll(cerr, globalOffset);
155         lmap.printBySymtab(cerr, relocatableObjects, globalOffset);
156     }
157
158     // Now that all symbols are at their final locations, compute and apply relocations
159     if( !applyRelocations(target, relocatableObjects, globalOffset, lmap, err, errMsg) ) {
160         if( lmap.allocatedData ) delete lmap.allocatedData;
161         return NULL;
162     }
163
164     // Restore the offset of the modified symbols
165     vector< pair<Symbol *, Offset> >::iterator symOff_it;
166     for(symOff_it = lmap.origSymbols.begin();
167         symOff_it != lmap.origSymbols.end();
168         ++symOff_it)
169     {
170         symOff_it->first->setOffset(symOff_it->second);
171     }
172
173     // Restore the symbols of the modified relocations
174    vector< pair<relocationEntry *, Symbol *> >::iterator relSym_it;
175    for(relSym_it = lmap.origRels.begin();
176        relSym_it != lmap.origRels.end();
177        ++relSym_it)
178    {
179        relSym_it->first->addDynSym(relSym_it->second);
180    }
181
182     rewrite_printf("\n*** Finished static linking\n\n");
183
184     rewrite_printf("END link map output\n");
185
186     err = No_Static_Link_Error;
187     errMsg = "";
188     return lmap.allocatedData;
189 }
190
191 /**
192  * Resolves undefined symbols in the specified Symtab object, usually due
193  * to the addition of new Symbols to the Symtab object. The target Symtab
194  * object must have a collection of Archives associated with it. These
195  * Archives will be searched for the defined versions of the undefined 
196  * symbols in the specified Symtab objects.
197  *
198  * target               the Symtab containing the undefined symbols
199  * relocatableObjects   populated by this function, this collection specifies
200  *                      all the Symtabs needed to ensure that the target has
201  *                      no undefined Symbols once the link is performed
202  */
203 bool emitElfStatic::resolveSymbols(Symtab *target, 
204         vector<Symtab *> &relocatableObjects,
205         LinkMap &lmap,
206         StaticLinkError &err, string &errMsg) 
207 {
208     // Collection of Symtabs that currently need their symbols resolved
209     set<Symtab *> workSet;
210
211     // Collection of Symtabs that have already had their symbols resolved
212     // this is necessary to avoid errors related to circular dependencies
213     set<Symtab *> linkedSet;
214
215     set<string> excludeSymNames;
216     getExcludedSymbolNames(excludeSymNames);
217
218     // Establish list of libraries to search for symbols
219     vector<Archive *> libraries;
220     target->getLinkingResources(libraries);
221
222     // Add all relocatable files explicitly referenced by new symbols, these
223     // essentially fuel the symbol resolution process
224     set<Symtab *> explicitRefs;
225     target->getExplicitSymtabRefs(explicitRefs);
226
227     set<Symtab *>::iterator expObj_it;
228     for(expObj_it = explicitRefs.begin(); expObj_it != explicitRefs.end();
229             ++expObj_it) 
230     {
231         relocatableObjects.push_back(*expObj_it);
232         workSet.insert(*expObj_it);
233         linkedSet.insert(*expObj_it);
234     }
235
236     set<Symtab *>::iterator curObjFilePtr = workSet.begin();
237     while( curObjFilePtr != workSet.end() ) {
238         // Take a relocatable file off the working set
239         Symtab *curObjFile = *curObjFilePtr;
240         workSet.erase(curObjFile);
241
242         rewrite_printf("\n*** Resolving symbols for: %s\n\n",
243                 curObjFile->memberName().c_str());
244
245         // Build the map of symbols to their relocations
246         map<Symbol *, vector<relocationEntry *> > symToRels;
247         vector<Region *> allRegions;
248         curObjFile->getAllRegions(allRegions);
249
250         vector<Region *>::iterator region_it;
251         for(region_it = allRegions.begin(); region_it != allRegions.end();
252                 ++region_it)
253         {
254             vector<relocationEntry> &region_rels = (*region_it)->getRelocations();
255             vector<relocationEntry>::iterator rel_it;
256             for( rel_it = region_rels.begin(); rel_it != region_rels.end(); ++rel_it) {
257                 symToRels[rel_it->getDynSym()].push_back(&(*rel_it));
258                 lmap.origRels.push_back(make_pair(&(*rel_it), rel_it->getDynSym()));
259             }
260         }
261
262         // Iterate over all undefined symbols, attempting to resolve them
263         vector<Symbol *> undefSyms;
264         curObjFile->getAllUndefinedSymbols(undefSyms);
265
266         vector<Symbol *>::iterator undefSym_it;
267         for(undefSym_it = undefSyms.begin(); undefSym_it != undefSyms.end();
268                 ++undefSym_it) 
269         {
270             Symbol *curUndefSym = *undefSym_it;
271
272             // Skip symbols that are don't cares
273             if( excludeSymNames.count(curUndefSym->getPrettyName()) ) continue;
274
275             if( !checkSpecialCaseSymbols(curObjFile, curUndefSym) ) {
276                 err = Symbol_Resolution_Failure;
277                 errMsg = "special case check failed for symbol: " +
278                     curUndefSym->getMangledName();
279                 return false;
280             }
281
282             Symbol *extSymbol = NULL;
283
284             // First, attempt to search the target for the symbol
285             if( !isStripped_ ) {
286                  vector<Symbol *> foundSyms;
287                  if( target->findSymbol(foundSyms, curUndefSym->getMangledName(),
288                     curUndefSym->getType()) )
289                  {
290                     if( foundSyms.size() > 1 ) {
291                         err = Symbol_Resolution_Failure;
292                         errMsg = "ambiguous symbol definition: " + 
293                             curUndefSym->getMangledName();
294                         return false;
295                     }
296
297                     extSymbol = foundSyms[0];
298
299                     rewrite_printf("Found external symbol %s in target with address = 0x%lx\n",
300                             extSymbol->getPrettyName().c_str(), extSymbol->getOffset());
301                  }
302             }
303
304             if( extSymbol == NULL ) {
305                 // search loaded libraries and add any new reloctable files
306                 vector<Archive *>::iterator lib_it;
307                 Symtab *containingSymtab = NULL;
308                 for(lib_it = libraries.begin(); lib_it != libraries.end(); ++lib_it) {
309                     Symtab *tmpSymtab;
310                     if( (*lib_it)->getMemberByGlobalSymbol(tmpSymtab, 
311                                 const_cast<string&>(curUndefSym->getMangledName())) ) 
312                     {
313                         /** 
314                          * The GNU approach is to use the symbol that is defined first
315                          * in the list of libraries (in the order specified to the linker)
316                          *
317                          * I am choosing to use that same behavior here.
318                          */
319                         containingSymtab = tmpSymtab;
320                         break;
321                     }else{
322                         /* Regarding duplicate symbols in Archives:
323                          *
324                          * gcc/ld appear to ignore the case where an Archive
325                          * contains the same symbol in different members and
326                          * chooses the symbol that occurs first in the
327                          * Archive's symbol table. This could produce
328                          * unexpected results so it is better to alert the user
329                          * of this error
330                          */
331                         if( Archive::getLastError() == Duplicate_Symbol ) {
332                             err = Symbol_Resolution_Failure;
333                             errMsg = Archive::printError(Duplicate_Symbol);
334                             return false;
335                         }
336                     }
337                 }
338
339                 if( containingSymtab != NULL ) {
340                     vector<Symbol *> foundSyms;
341                     if( containingSymtab->findSymbol(foundSyms, curUndefSym->getMangledName(),
342                         curUndefSym->getType()) )
343                     {
344                         if( foundSyms.size() > 1 ) {
345                             err = Symbol_Resolution_Failure;
346                             errMsg = "ambiguous symbol definition: " + 
347                                 curUndefSym->getMangledName();
348                             return false;
349                         }
350
351                         extSymbol = foundSyms[0];
352                         if( !linkedSet.count(containingSymtab) ) {
353                             // Consistency check 
354                             if( containingSymtab->getAddressWidth() != addressWidth_ ) {
355                                 err = Symbol_Resolution_Failure;
356                                 errMsg = "symbol (" + curUndefSym->getMangledName() +
357                                     ") found in relocatable file that is not compatible"
358                                     + " with the target binary";
359                                 return false;
360                             }
361
362                             relocatableObjects.push_back(containingSymtab);
363
364                             // Resolve all symbols for this new Symtab, if it hasn't already
365                             // been done
366
367                             workSet.insert(containingSymtab);
368                             linkedSet.insert(containingSymtab);
369                         }
370
371                         rewrite_printf("Found external symbol %s in module %s(%s)\n",
372                                 extSymbol->getPrettyName().c_str(),
373                                 containingSymtab->getParentArchive()->name().c_str(),
374                                 containingSymtab->memberName().c_str());
375                     }else{
376                         err = Symbol_Resolution_Failure;
377                         errMsg = "inconsistency found between archive's symbol table and member's symbol table";
378                         return false;   
379                     }
380                 }
381             }
382
383             if( extSymbol == NULL ) {
384                 // If it is a weak symbol, it isn't an error that the symbol wasn't resolved
385                 if( curUndefSym->getLinkage() == Symbol::SL_WEAK ) {
386                     continue;
387                 }
388
389                 err = Symbol_Resolution_Failure;
390                 errMsg = "failed to locate symbol '" + curUndefSym->getMangledName()
391                     + "' for module '" + curObjFile->memberName() + "'";
392                 return false;
393             }
394
395             // Store the found symbol with the related relocations
396             map<Symbol *, vector<relocationEntry *> >::iterator relMap_it;
397             relMap_it = symToRels.find(curUndefSym);
398             if( relMap_it != symToRels.end() ) {
399                 vector<relocationEntry *>::iterator rel_it;
400                 for(rel_it = relMap_it->second.begin(); rel_it != relMap_it->second.end();
401                         ++rel_it)
402                 {
403                     (*rel_it)->addDynSym(extSymbol);
404                 }
405             }   /* else
406                  *
407                  * Some libraries define a reference to a symbol and then never
408                  * use it in order to ensure that the module that defines the
409                  * symbol is linked. Therefore, it is not an error if a symbol doesn't
410                  * have a relocation.
411                  */
412         }
413
414         curObjFilePtr = workSet.begin();
415     }
416     
417     return true;
418 }
419
420 /**
421  * Given a collection of Symtab objects, combines the code, data, bss and
422  * other miscellaneous Regions into groups and places them in a new block
423  * of data.
424  * 
425  * Allocates COMMON symbols in the collection of Symtab objects
426  * as bss
427  *
428  * Creates a new TLS initialization image, combining the target image
429  * and the image that exists in the collection of Symtab objects
430  *
431  * Creates a GOT used for indirect memory accesses that is required by some
432  * relocations
433  *
434  * Creates a new global constructor and/or destructor table if necessary,
435  * combining tables from the target and collection of Symtab objects
436  *
437  * target               New code/data/etc. will be linked into this Symtab
438  * relocatableObjects   The new code/data/etc.
439  * globalOffset         The location of the new block of data in the target
440  * lmap                 The LinkMap to be populated by this function
441  */
442 bool emitElfStatic::createLinkMap(Symtab *target,
443         vector<Symtab *> &relocatableObjects, 
444         Offset & globalOffset, 
445         LinkMap &lmap,
446         StaticLinkError &err, string &errMsg) 
447 {
448     rewrite_printf("\n*** Allocating storage for relocatable objects\n\n");
449
450     // Used to create a new COMMON block
451     multimap<Offset, Symbol *> commonAlignments;
452     Offset commonRegionAlign = 0;
453
454     // Collect all Regions that should be allocated in the new data block
455     vector<Symtab *>::iterator obj_it;
456     for(obj_it = relocatableObjects.begin(); obj_it != relocatableObjects.end(); ++obj_it) {
457         vector<Region *> regs;
458         if( !(*obj_it)->getAllRegions(regs) ) {
459             err = Storage_Allocation_Failure;
460             errMsg = "failed to locate regions in relocatable object";
461             return false;
462         }
463
464         vector<Region *>::iterator reg_it;
465         for(reg_it = regs.begin(); reg_it != regs.end(); ++reg_it) {
466             string regionName = (*reg_it)->getRegionName();
467             if( (*reg_it)->isLoadable() && (*reg_it)->getRegionSize() > 0) {
468                 if( (*reg_it)->isTLS() ) {
469                     switch((*reg_it)->getRegionType()) {
470                         case Region::RT_DATA:
471                         case Region::RT_BSS:
472                             lmap.tlsRegions.push_back(*reg_it);
473                             // Determine alignment of combined region
474                             if( (*reg_it)->getMemAlignment() > lmap.tlsRegionAlign ) {
475                                 lmap.tlsRegionAlign = (*reg_it)->getMemAlignment();
476                             }
477                             break;
478                         default:
479                             // ignore any other regions
480                             break;
481                     }
482                 }else if( isConstructorRegion(*reg_it) ) {
483                     lmap.newCtorRegions.push_back(*reg_it);
484                     if( (*reg_it)->getMemAlignment() > lmap.ctorRegionAlign ) {
485                         lmap.ctorRegionAlign = (*reg_it)->getMemAlignment();
486                     }
487                 }else if( isDestructorRegion(*reg_it) ) {
488                     lmap.newDtorRegions.push_back(*reg_it);
489                     if( (*reg_it)->getMemAlignment() > lmap.dtorRegionAlign ) {
490                         lmap.dtorRegionAlign = (*reg_it)->getMemAlignment();
491                     }
492                 }else{
493                     switch((*reg_it)->getRegionType()) {
494                         case Region::RT_TEXT:
495                             lmap.codeRegions.push_back(*reg_it);
496                             // Determine alignment of combined region
497                             if( (*reg_it)->getMemAlignment() > lmap.codeRegionAlign ) {
498                                 lmap.codeRegionAlign = (*reg_it)->getMemAlignment();
499                             }
500                             break;
501                         case Region::RT_DATA:
502                             lmap.dataRegions.push_back(*reg_it);
503                             // Determine alignment of combined region
504                             if( (*reg_it)->getMemAlignment() > lmap.dataRegionAlign ) {
505                                 lmap.dataRegionAlign = (*reg_it)->getMemAlignment();
506                             }
507                             break;
508                         case Region::RT_BSS:
509                             lmap.bssRegions.push_back(*reg_it);
510                             // Determine alignment of combined region
511                             if( (*reg_it)->getMemAlignment() > lmap.bssRegionAlign ) {
512                                 lmap.bssRegionAlign = (*reg_it)->getMemAlignment();
513                             }
514                             break;
515                         case Region::RT_TEXTDATA:
516                             lmap.codeRegions.push_back(*reg_it);
517                             // Determine alignment of combined region
518                             if( (*reg_it)->getMemAlignment() > lmap.codeRegionAlign ) {
519                                 lmap.codeRegionAlign = (*reg_it)->getMemAlignment();
520                             }
521                             break;
522                         default:
523                             // skip other regions
524                             continue;
525                     }
526                 }
527
528                 // Find symbols that need to be put in the GOT
529                 vector<relocationEntry> &region_rels = (*reg_it)->getRelocations();
530                 vector<relocationEntry>::iterator rel_it;
531                 for( rel_it = region_rels.begin(); rel_it != region_rels.end(); ++rel_it) {
532                     if( isGOTRelocation(rel_it->getRelType()) ) {
533                         // initialize mapping
534                         lmap.gotSymbols.insert(make_pair(rel_it->getDynSym(), 0));
535                     }
536                 }
537             }
538         }
539
540         vector<Symbol *> definedSyms;
541         if( (*obj_it)->getAllDefinedSymbols(definedSyms) ) {
542             vector<Symbol *>::iterator sym_it;
543             for(sym_it = definedSyms.begin(); sym_it != definedSyms.end(); ++sym_it) {
544                 // Note: the assumption is made that a Symbol cannot 
545                 // be both TLS and COMMON
546                 if( (*sym_it)->isCommonStorage() ) {
547                     // For a symbol in common storage, the offset/value is the alignment
548                     commonAlignments.insert(make_pair((*sym_it)->getOffset(), *sym_it));
549
550                     // The alignment of a COMMON Region is the maximum alignment
551                     // needed by one of its symbols
552                     if( (*sym_it)->getOffset() > commonRegionAlign ) {
553                         commonRegionAlign = (*sym_it)->getOffset();
554                     }
555                 }else if( (*sym_it)->getType() == Symbol::ST_TLS ) {
556                     lmap.tlsSymbols.push_back(*sym_it);
557                 }
558             }
559         }
560     }
561
562     // Determine how all the Regions in the relocatable objects will be 
563     // placed in the rewritten target
564     Offset currentOffset = 0;
565
566     // Allocate code regions 
567     
568     // Since this is the first new Region, the actual globalOffset should be 
569     // the passed globalOffset plus the padding for this Region
570     lmap.codeRegionOffset = currentOffset;
571     globalOffset += computePadding(globalOffset + lmap.codeRegionOffset,
572             lmap.codeRegionAlign);
573
574     currentOffset = layoutRegions(lmap.codeRegions, lmap.regionAllocs,
575             lmap.codeRegionOffset, globalOffset);
576     if( currentOffset == ~0UL ) {
577         err = Storage_Allocation_Failure;
578         errMsg = "assumption failed while creating link map";
579         return false;
580     }
581     lmap.codeSize = currentOffset - lmap.codeRegionOffset;
582
583     // Allocate data regions 
584     lmap.dataRegionOffset = currentOffset;
585     lmap.dataRegionOffset += computePadding(globalOffset + lmap.dataRegionOffset,
586             lmap.dataRegionAlign);
587     currentOffset = layoutRegions(lmap.dataRegions, lmap.regionAllocs, 
588             lmap.dataRegionOffset, globalOffset);
589     if( currentOffset == ~0UL ) {
590         err = Storage_Allocation_Failure;
591         errMsg = "assumption failed while creating link map";
592         return false;
593     }
594     lmap.dataSize = currentOffset - lmap.dataRegionOffset;
595
596     // Allocate space for a GOT Region, if necessary
597     lmap.gotSize = getGOTSize(lmap);
598     if( lmap.gotSize > 0 ) {
599         lmap.gotRegionAlign = getGOTAlign(lmap);
600         currentOffset += computePadding(globalOffset + currentOffset,
601                 lmap.gotRegionAlign);
602         lmap.gotRegionOffset = currentOffset;
603         currentOffset += lmap.gotSize;
604     }
605
606     /* 
607      * Find current TLS Regions in target, also check for multiple TLS Regions
608      * of the same type => knowing how to construct the TLS image would be
609      * undefined for multiple TLS Regions of the same type
610      *
611      * Find current constructor Regions and destructor Regions.
612      */
613     Region *dataTLS = NULL, *bssTLS = NULL;
614     lmap.tlsSize = 0;
615     
616     vector<Region *> regions;
617     if( !target->getAllRegions(regions) ) {
618         err = Storage_Allocation_Failure;
619         errMsg = "failed to retrieve regions from target";
620         return false;
621     }
622     
623     vector<Region *>::iterator reg_it;
624     for(reg_it = regions.begin(); reg_it != regions.end(); ++reg_it) {
625         if( (*reg_it)->isTLS() ) {
626             if( (*reg_it)->getRegionType() == Region::RT_DATA ) {
627                 if( dataTLS != NULL ) {
628                     err = Storage_Allocation_Failure;
629                     errMsg = "found more than one TLS data region";
630                     return false;
631                 }
632                 dataTLS = *reg_it;
633                 lmap.tlsSize += dataTLS->getRegionSize();
634                 if( dataTLS->getMemAlignment() > lmap.tlsRegionAlign ) {
635                     lmap.tlsRegionAlign = dataTLS->getMemAlignment();
636                 }
637             }else if( (*reg_it)->getRegionType() == Region::RT_BSS ) {
638                 if( bssTLS != NULL ) {
639                     err = Storage_Allocation_Failure;
640                     errMsg = "found more than one TLS bss region";
641                     return false;
642                 }
643                 bssTLS = *reg_it;
644                 lmap.tlsSize += bssTLS->getRegionSize();
645                 if( bssTLS->getMemAlignment() > lmap.tlsRegionAlign ) {
646                     lmap.tlsRegionAlign = bssTLS->getMemAlignment();
647                 }
648             }
649         }else if( isConstructorRegion(*reg_it) ) {
650             lmap.originalCtorRegion = *reg_it;
651         }else if( isDestructorRegion(*reg_it) ){
652             lmap.originalDtorRegion = *reg_it;
653         }
654     }
655
656     // Allocate the new TLS region, if necessary
657     if( lmap.tlsRegions.size() > 0 ) {
658         lmap.tlsRegionOffset = currentOffset;
659
660         lmap.tlsRegionOffset += computePadding(lmap.tlsRegionOffset + globalOffset,
661                 lmap.tlsRegionAlign);
662         currentOffset = layoutTLSImage(globalOffset, dataTLS, bssTLS, lmap);
663
664         if( currentOffset == lmap.tlsRegionOffset ) {
665             err = Storage_Allocation_Failure;
666             errMsg = "failed to create TLS initialization image";
667             return false;
668         }
669
670         /*
671          *  The size of this Region is counted twice: once when collecting the
672          *  original TLS Regions and once when laying out the image. This is
673          *  necessary to maintain consistency with the case where there are no
674          *  new TLS regions in the relocatable objects but existing TLS symbols
675          *  are used.
676          */
677         if( dataTLS != NULL ) {
678             lmap.tlsSize -= dataTLS->getRegionSize();
679         }
680
681         lmap.tlsSize += currentOffset - lmap.tlsRegionOffset;
682
683         // Adjust offsets for all existing TLS symbols, as their offset
684         // in the TLS block could have changed
685         vector<Symbol *> definedSyms;
686         if( target->getAllDefinedSymbols(definedSyms) ) {
687             vector<Symbol *>::iterator sym_it;
688             for(sym_it = definedSyms.begin(); sym_it != definedSyms.end(); ++sym_it) {
689                 if( (*sym_it)->getType() == Symbol::ST_TLS ) {
690
691                     map<Region *, LinkMap::AllocPair>::iterator result;
692                     result = lmap.regionAllocs.find((*sym_it)->getRegion());
693
694                     if( result != lmap.regionAllocs.end() ) {
695                         Offset regionOffset = result->second.second;
696                         Offset symbolOffset = (*sym_it)->getOffset();
697                         lmap.origSymbols.push_back(make_pair(*sym_it, symbolOffset));
698
699                         symbolOffset += regionOffset - lmap.tlsRegionOffset;
700                         symbolOffset = adjustTLSOffset(symbolOffset, lmap.tlsSize);
701
702                         (*sym_it)->setOffset(symbolOffset);
703                     }
704                 }
705             }
706         }
707
708         cleanupTLSRegionOffsets(lmap.regionAllocs, dataTLS, bssTLS);
709         if( bssTLS != NULL ) lmap.tlsSize -= bssTLS->getRegionSize();
710
711         hasRewrittenTLS_ = true;
712     }else{
713         // Adjust offsets for all existing TLS symbols, as the offsets required
714         // by relocation processing are TLS variant dependent
715         vector<Symbol *> definedSyms;
716         if( target->getAllDefinedSymbols(definedSyms) ) {
717             vector<Symbol *>::iterator sym_it;
718             for(sym_it = definedSyms.begin(); sym_it != definedSyms.end(); ++sym_it) {
719                 if( (*sym_it)->getType() == Symbol::ST_TLS ) {
720                     Offset symbolOffset = (*sym_it)->getOffset();
721                     lmap.origSymbols.push_back(make_pair(*sym_it, symbolOffset));
722
723                     symbolOffset = adjustTLSOffset(symbolOffset, lmap.tlsSize);
724                     (*sym_it)->setOffset(symbolOffset);
725                 }
726             }
727         }
728
729         // The size of the original TLS image is no longer needed
730         lmap.tlsSize = 0;
731     }
732
733     // Allocate space for a new constructor region, if necessary
734     if( lmap.newCtorRegions.size() > 0 ) {
735         lmap.ctorRegionOffset = currentOffset;
736         lmap.ctorRegionOffset += computePadding(globalOffset + lmap.ctorRegionOffset,
737                 lmap.ctorRegionAlign);
738         currentOffset = layoutNewCtorRegion(lmap);
739         if( currentOffset == ~0UL ) {
740             err = Storage_Allocation_Failure;
741             errMsg = "assumption failed while creating link map";
742             return false;
743         }
744         lmap.ctorSize = currentOffset - lmap.ctorRegionOffset;
745     }
746
747     // Allocate space for a new destructor region, if necessary
748     if( lmap.newDtorRegions.size() > 0 ) {
749         lmap.dtorRegionOffset = currentOffset;
750         lmap.dtorRegionOffset += computePadding(globalOffset + lmap.dtorRegionOffset,
751                 lmap.dtorRegionAlign);
752         currentOffset = layoutNewDtorRegion(lmap);
753         if( currentOffset == ~0UL ) {
754             err = Storage_Allocation_Failure;
755             errMsg = "assumption failed while creating link map";
756             return false;
757         }
758         lmap.dtorSize = currentOffset - lmap.dtorRegionOffset;
759     }
760
761     /* Combine all COMMON symbols into a single block */
762     if( commonAlignments.size() > 0 ) {
763         // The alignment of the COMMON Region could be the alignment 
764         // for the bss Region
765         if( commonRegionAlign > lmap.bssRegionAlign ) {
766             lmap.bssRegionAlign = commonRegionAlign;
767         }
768
769         // The following approach to laying out the COMMON symbols is greedy and
770         // suboptimal (in terms of space in the target), but it's quick...
771         Offset commonOffset = currentOffset;
772
773         // Make sure the COMMON Region's alignment is satisfied
774         commonOffset += computePadding(globalOffset + commonOffset, lmap.bssRegionAlign);
775         Offset commonStartOffset = commonOffset;
776
777         multimap<Offset, Symbol *>::iterator align_it;
778         for(align_it = commonAlignments.begin(); 
779             align_it != commonAlignments.end(); ++align_it)
780         {
781             commonOffset += computePadding(commonOffset, align_it->first);
782             lmap.origSymbols.push_back(make_pair(align_it->second, align_it->first));
783
784             // Update symbol with place in new linked data
785             align_it->second->setOffset(globalOffset + commonOffset);
786             commonOffset += align_it->second->getSize();
787         }
788
789         // Update the size of COMMON storage
790         if( commonAlignments.size() > 0 ) {
791             // A COMMON region is not really complete
792             lmap.commonStorage = Region::createRegion(0, Region::RP_RW,
793                     Region::RT_BSS, commonOffset - commonStartOffset, 0, 
794                     commonOffset - commonStartOffset,
795                     DEFAULT_COM_NAME, NULL, true, false, commonRegionAlign);
796             lmap.bssRegions.push_front(lmap.commonStorage);
797         }
798     }
799
800     // Allocate bss regions
801     lmap.bssRegionOffset = currentOffset;
802     lmap.bssRegionOffset += computePadding(globalOffset + lmap.bssRegionOffset,
803             lmap.bssRegionAlign);
804     currentOffset = layoutRegions(lmap.bssRegions, lmap.regionAllocs,
805             lmap.bssRegionOffset, globalOffset);
806     if( currentOffset == ~0UL ) {
807         err = Storage_Allocation_Failure;
808         errMsg = "assumption failed while creating link map";
809         return false;
810     }
811     lmap.bssSize = currentOffset - lmap.bssRegionOffset;
812
813     // Update all relevant symbols with their offsets in the new target
814     for(obj_it = relocatableObjects.begin(); obj_it != relocatableObjects.end(); ++obj_it) {
815         vector<Symbol *> definedSyms;
816         if( (*obj_it)->getAllDefinedSymbols(definedSyms) ) {
817             vector<Symbol *>::iterator sym_it;
818             for(sym_it = definedSyms.begin(); sym_it != definedSyms.end(); ++sym_it) {
819                 if(    !(*sym_it)->isCommonStorage() 
820                     && (*sym_it)->getType() != Symbol::ST_TLS) 
821                 {
822                     map<Region *, LinkMap::AllocPair>::iterator result;
823                     result = lmap.regionAllocs.find((*sym_it)->getRegion());
824                     if( result != lmap.regionAllocs.end() ) {
825                         Offset regionOffset = result->second.second;
826                         Offset symbolOffset = (*sym_it)->getOffset();
827                         lmap.origSymbols.push_back(make_pair(*sym_it, symbolOffset));
828
829                         symbolOffset += globalOffset + regionOffset;
830
831                         (*sym_it)->setOffset(symbolOffset);
832                     }
833                 }
834             }
835         }
836     }
837
838     /* ASSUMPTION
839      * At this point, the layout of the new regions is fixed, and
840      * addresses of all symbols are known (excluding Constructor/Destructor Regions)
841      */
842
843     // Allocate storage space
844     lmap.allocatedData = new char[currentOffset];
845     lmap.allocatedSize = currentOffset;
846
847     // Copy the Regions from the relocatable objects into the new storage space
848     copyRegions(lmap);
849
850     return true;
851 }
852
853 /**
854  * Lays out the specified regions, storing the layout info in the 
855  * passed map.
856  *
857  * regions              A collection of Regions to layout
858  * regionAllocs         A map of Regions to their layout information
859  * currentOffset        The starting offset for the passed Regions in
860  *                      the new storage space
861  * globalOffset         The location of the new storage space in the
862  *                      target (used for padding calculation)
863  */
864 Offset emitElfStatic::layoutRegions(deque<Region *> &regions, 
865         map<Region *, LinkMap::AllocPair> &regionAllocs,
866         Offset currentOffset, Offset globalOffset) 
867 {
868     Offset retOffset = currentOffset;
869
870     deque<Region *>::iterator copyReg_it;
871     for(copyReg_it = regions.begin(); copyReg_it != regions.end(); ++copyReg_it) {
872         // Skip empty Regions
873         if( (*copyReg_it)->getRegionSize() == 0 ) continue;
874
875         // Make sure the Region is aligned correctly in the new aggregate Region
876         Offset padding = computePadding(globalOffset + retOffset, (*copyReg_it)->getMemAlignment());
877         retOffset += padding;
878
879         // Set up mapping for a new Region in the specified storage space
880         pair<map<Region *, LinkMap::AllocPair>::iterator, bool> result;
881         result = regionAllocs.insert(make_pair(*copyReg_it, make_pair(padding, retOffset)));
882
883         // If the map already contains this Region, this is a logic error
884         if( !result.second ) {
885             retOffset = ~0UL;
886             break;
887         }
888                        
889         retOffset += (*copyReg_it)->getRegionSize();
890     }
891
892     return retOffset;
893 }
894
895 /*
896  * Adds new combined Regions to the target at the specified globalOffset
897  *
898  * target       The Symtab object to which the new Regions will be added
899  * globalOffset The offset of the first new Region in the target
900  * lmap         Contains all the information about the LinkMap
901  */
902 bool emitElfStatic::addNewRegions(Symtab *target, Offset globalOffset, LinkMap &lmap) {
903     char *newTargetData = lmap.allocatedData;
904     
905     if( lmap.codeSize > 0 ) {
906         target->addRegion(globalOffset + lmap.codeRegionOffset,
907                 reinterpret_cast<void *>(&newTargetData[lmap.codeRegionOffset]),
908                 static_cast<unsigned int>(lmap.codeSize),
909                 CODE_NAME, Region::RT_TEXT, true, lmap.codeRegionAlign);
910     }
911
912     if( lmap.dataSize > 0 ) {
913         target->addRegion(globalOffset + lmap.dataRegionOffset, 
914                 reinterpret_cast<void *>(&newTargetData[lmap.dataRegionOffset]),
915                 static_cast<unsigned int>(lmap.dataSize),
916                 DATA_NAME, Region::RT_DATA, true, lmap.dataRegionAlign);
917     }
918
919     if( lmap.gotSize > 0 ) {
920         buildGOT(lmap);
921
922         target->addRegion(globalOffset + lmap.gotRegionOffset,
923                 reinterpret_cast<void *>(&newTargetData[lmap.gotRegionOffset]),
924                 static_cast<unsigned int>(lmap.gotSize),
925                 GOT_NAME, Region::RT_DATA, true, lmap.gotRegionAlign);
926     }
927
928     if( lmap.tlsSize > 0 ) {
929         target->addRegion(globalOffset + lmap.tlsRegionOffset,
930                 reinterpret_cast<void *>(&newTargetData[lmap.tlsRegionOffset]),
931                 static_cast<unsigned int>(lmap.tlsSize),
932                 TLS_DATA_NAME, Region::RT_DATA, true, lmap.tlsRegionAlign, true);
933     }
934
935     if( lmap.newCtorRegions.size() > 0 ) {
936         if( !createNewCtorRegion(lmap) ) {
937             return false;
938         }
939
940         target->addRegion(globalOffset + lmap.ctorRegionOffset,
941                 reinterpret_cast<void *>(&newTargetData[lmap.ctorRegionOffset]),
942                 static_cast<unsigned int>(lmap.ctorSize),
943                 CTOR_NAME, Region::RT_DATA, true, 
944                 lmap.ctorRegionAlign);
945     }
946
947     if( lmap.newDtorRegions.size() > 0 ) {
948         if( !createNewDtorRegion(lmap) ) {
949             return false;
950         }
951
952         target->addRegion(globalOffset + lmap.dtorRegionOffset,
953                 reinterpret_cast<void *>(&newTargetData[lmap.dtorRegionOffset]),
954                 static_cast<unsigned int>(lmap.dtorSize),
955                 DTOR_NAME, Region::RT_DATA, true,
956                 lmap.dtorRegionAlign);
957     }
958
959     if( lmap.bssSize > 0 ) {
960         target->addRegion(globalOffset + lmap.bssRegionOffset, 
961                 reinterpret_cast<void *>(&newTargetData[lmap.bssRegionOffset]),
962                 static_cast<unsigned int>(lmap.bssSize),
963                 BSS_NAME, Region::RT_BSS, true, lmap.bssRegionAlign);
964     }
965
966     return true;
967 }
968
969 /**
970  * Copys the new Regions, as indicated by the LinkMap, into the
971  * allocated storage space
972  *
973  * lmap         Contains all the information necessary to perform the copy
974  */
975 void emitElfStatic::copyRegions(LinkMap &lmap) {
976     char *targetData = lmap.allocatedData;
977
978     map<Region *, LinkMap::AllocPair>::iterator regOff_it;
979     for(regOff_it = lmap.regionAllocs.begin(); regOff_it != lmap.regionAllocs.end(); ++regOff_it) {
980         Region *depRegion = regOff_it->first;
981         Offset regionOffset = regOff_it->second.second;
982         Offset padding = regOff_it->second.first;
983
984         // Copy in the Region data
985         char *rawRegionData = reinterpret_cast<char *>(depRegion->getPtrToRawData());
986
987         if( !depRegion->isBSS() ) {
988             memcpy(&targetData[regionOffset], rawRegionData, depRegion->getRegionSize());
989         }
990
991         // Set the padded space to a meaningful value
992         memset(&targetData[regionOffset - padding], getPaddingValue(depRegion->getRegionType()), padding);
993     }
994 }
995
996 /**
997  * Computes the padding necessary to satisfy the specified alignment
998  *
999  * candidateOffset      A possible offset for an item
1000  * alignment            The alignment for an item
1001  */
1002 inline
1003 Offset emitElfStatic::computePadding(Offset candidateOffset, Offset alignment) {
1004     Offset padding = 0;
1005     if( alignment != 0 && (candidateOffset % alignment) != 0 ) {
1006         padding = alignment - (candidateOffset % alignment);
1007     }
1008     return padding;
1009 }
1010
1011 /**
1012  * Given a collection of newly allocated regions in the specified storage space, 
1013  * computes relocations and places the values at the location specified by the
1014  * relocation entry (stored with the Regions)
1015  *
1016  * target               The Symtab object being rewritten
1017  * relocatableObjects   A list of relocatable files being linked into target
1018  * globalOffset         The location of the new storage space in target
1019  * lmap                 Contains all the information necessary to apply relocations
1020  */
1021 bool emitElfStatic::applyRelocations(Symtab *target, vector<Symtab *> &relocatableObjects,
1022         Offset globalOffset, LinkMap &lmap,
1023         StaticLinkError &err, string &errMsg) 
1024 {
1025     // Iterate over all relocations in all relocatable files
1026     vector<Symtab *>::iterator depObj_it;
1027     for(depObj_it = relocatableObjects.begin(); depObj_it != relocatableObjects.end(); ++depObj_it) {
1028         vector<Region *> allRegions;
1029         (*depObj_it)->getAllRegions(allRegions);
1030
1031         rewrite_printf("\n*** Computing relocations for: %s\n\n",
1032                 (*depObj_it)->memberName().c_str());
1033
1034         // Relocations are stored with the Region to which they will be applied
1035         // As an ELF example, .rel.text relocations are stored with the Region .text
1036         vector<Region *>::iterator region_it;
1037         for(region_it = allRegions.begin(); region_it != allRegions.end(); ++region_it) {
1038             // Only compute relocations for the new Regions
1039             map<Region *, LinkMap::AllocPair>::iterator result;
1040             result = lmap.regionAllocs.find(*region_it);
1041             if( result != lmap.regionAllocs.end() ) {
1042                 rewrite_printf("\nComputing relocations to apply to region: %s\n\n",
1043                         (*region_it)->getRegionName().c_str());
1044                 Offset regionOffset = result->second.second;
1045
1046                 vector<relocationEntry> region_rels = (*region_it)->getRelocations();
1047
1048                 vector<relocationEntry>::iterator rel_it;
1049                 for(rel_it = region_rels.begin(); rel_it != region_rels.end(); ++rel_it) {
1050                     // Compute destination of relocation
1051                     Offset dest = regionOffset + rel_it->rel_addr();
1052                     Offset relOffset = globalOffset + dest;
1053
1054                     char *targetData = lmap.allocatedData;
1055                     if( !archSpecificRelocation(targetData, *rel_it, dest, 
1056                                 relOffset, globalOffset, lmap, errMsg) ) 
1057                     {
1058                         err = Relocation_Computation_Failure;
1059                         errMsg = "Failed to compute relocation: " + errMsg;
1060                         return false;
1061                     }
1062                 }
1063             }
1064         }
1065     }
1066
1067     rewrite_printf("\n*** Computing relocations added to target.\n\n");
1068
1069     // Compute relocations added to target 
1070     vector<Region *> allRegions;
1071     target->getAllRegions(allRegions);
1072
1073     vector<Region *>::iterator reg_it;
1074     for(reg_it = allRegions.begin(); reg_it != allRegions.end(); ++reg_it) {
1075         char *regionData = reinterpret_cast<char *>((*reg_it)->getPtrToRawData());
1076         
1077         vector<relocationEntry>::iterator rel_it;
1078         for(rel_it = (*reg_it)->getRelocations().begin();
1079             rel_it != (*reg_it)->getRelocations().end();
1080             ++rel_it)
1081         {
1082             if( !archSpecificRelocation(regionData, *rel_it,
1083                         rel_it->rel_addr() - (*reg_it)->getRegionAddr(),
1084                         rel_it->rel_addr(), globalOffset, lmap, errMsg) )
1085             {
1086                 err = Relocation_Computation_Failure;
1087                 errMsg = "Failed to compute relocation: " + errMsg;
1088                 return false;
1089             }
1090         }
1091     }
1092
1093     return true;
1094 }
1095
1096 /**
1097  * A string representation of the StaticLinkError returned by
1098  * other functions
1099  */
1100 string emitElfStatic::printStaticLinkError(StaticLinkError err) {
1101     switch(err) {
1102         CASE_RETURN_STR(No_Static_Link_Error);
1103         CASE_RETURN_STR(Symbol_Resolution_Failure);
1104         CASE_RETURN_STR(Relocation_Computation_Failure);
1105         CASE_RETURN_STR(Storage_Allocation_Failure);
1106         default:
1107             return "unknown error";
1108     }
1109 }
1110
1111 /**
1112  * Indicates if a new TLS initialization image has been created
1113  */
1114 bool emitElfStatic::hasRewrittenTLS() const {
1115     return hasRewrittenTLS_;
1116 }
1117
1118 /** The following functions are all somewhat architecture-specific */
1119
1120 /* TLS Info
1121  *
1122  * TLS handling is pseudo-architecture dependent. The implementation of the TLS
1123  * functions depend on the implementation of TLS on a specific architecture.
1124  *
1125  * The following material is documented in more detail in the 
1126  * "ELF Handling For TLS" white paper. According to this paper, their are 
1127  * two variants w.r.t. creating a TLS initialization image.
1128  *
1129  * ======================
1130  *
1131  * The first is:
1132  *
1133  *            beginning of image
1134  *            |
1135  *            V                              high address
1136  * +----+-----+----------+---------+---------+
1137  * |    | TCB | image 1  | image 2 | image 3 |
1138  * +----+---- +----------+---------+---------+
1139  *
1140  * where TCB = thread control block, and each image is the
1141  * TLS initialization image for a module (in this context an executable or 
1142  * shared library).
1143  *
1144  * ========================
1145  *
1146  * The second is:
1147  * 
1148  * beginning of image
1149  * | 
1150  * V                                        high address
1151  * +---------+----------+---------+---------+
1152  * | image 3 | image 2  | image 1 |  TCB    |
1153  * +---------+----------+---------+---------+
1154  *
1155  * An image is:
1156  *
1157  * +--------+--------+
1158  * | DATA   |  BSS   |
1159  * +--------+--------+
1160  *
1161  * New TLS data and bss is added to the original initialization image as follows:
1162  *
1163  * +----------+------------------+-------------+------------+-----+
1164  * | NEW DATA | EXPANDED NEW BSS | TARGET DATA | TARGET BSS | TCB |
1165  * +----------+------------------+-------------+------------+-----+
1166  *
1167  * It is important to note that the TARGET DATA and TARGET BSS blocks are not moved.
1168  * This ensures that the modifications to the TLS image are safe.
1169  *
1170  * ==========================
1171  * 
1172  * These are the two variants one would see when working with ELF files. So, an
1173  * architecture either uses variant 1 or 2.
1174  *
1175  */
1176
1177 /* See architecture specific functions that call these for descriptions of function interface */
1178
1179 Offset emitElfStatic::tlsLayoutVariant1(Offset, Region *, Region *, LinkMap &)
1180 {
1181     assert(!"Layout of TLS initialization image, Variant 1, currently not implemented.");
1182     return 0;
1183 }
1184
1185 Offset emitElfStatic::tlsLayoutVariant2(Offset globalOffset, Region *dataTLS, Region *bssTLS,
1186         LinkMap &lmap)
1187 {
1188     // The original init. image needs to remain in the image 1 slot because
1189     // the TLS data references are relative to that position
1190     unsigned long tlsBssSize = 0;
1191     if( dataTLS != NULL ) lmap.tlsRegions.push_back(dataTLS);
1192     if( bssTLS != NULL ) tlsBssSize = bssTLS->getRegionSize();
1193
1194     // Create the image, note new BSS regions are expanded
1195     Offset endOffset = layoutRegions(lmap.tlsRegions,
1196             lmap.regionAllocs, lmap.tlsRegionOffset, globalOffset);
1197     if( endOffset == ~0UL ) return lmap.tlsRegionOffset;
1198     Offset adjustedEnd = endOffset - lmap.tlsRegionOffset;
1199
1200     // This is necessary so the offsets of existing TLS symbols can be updated
1201     // in a uniform, architecture independent way
1202     if( bssTLS != NULL ) {
1203         if( dataTLS != NULL ) {
1204             lmap.regionAllocs.insert(make_pair(bssTLS, lmap.regionAllocs[dataTLS]));
1205         }else{
1206             lmap.regionAllocs.insert(make_pair(bssTLS, make_pair(0, endOffset)));
1207         }
1208     }
1209
1210     // Update the symbols with their offsets relative to the TCB address
1211     vector<Symbol *>::iterator sym_it;
1212     for(sym_it = lmap.tlsSymbols.begin(); sym_it != lmap.tlsSymbols.end(); ++sym_it) {
1213         map<Region *, LinkMap::AllocPair>::iterator result;
1214         result = lmap.regionAllocs.find((*sym_it)->getRegion());
1215
1216         // It is a programming error if the region for the symbol
1217         // was not passed to this function
1218         if( result == lmap.regionAllocs.end() ) {
1219             endOffset = lmap.tlsRegionOffset;
1220             break;
1221         }
1222
1223         Offset regionOffset = result->second.second;
1224         Offset symbolOffset = (*sym_it)->getOffset();
1225         lmap.origSymbols.push_back(make_pair((*sym_it), symbolOffset));
1226
1227         symbolOffset += (regionOffset - lmap.tlsRegionOffset) - (adjustedEnd + tlsBssSize);
1228         (*sym_it)->setOffset(symbolOffset);
1229     }
1230
1231     return endOffset;
1232 }
1233
1234 // Note: Variant 1 does not require any modifications, so a separate
1235 // function is not necessary
1236 Offset emitElfStatic::tlsAdjustVariant2(Offset curOffset, Offset tlsSize) {
1237     // For Variant 2, offsets relative to the TCB need to be negative
1238     Offset retOffset = curOffset;
1239     retOffset -= tlsSize;
1240     return retOffset;
1241 }
1242
1243 void emitElfStatic::tlsCleanupVariant1(map<Region *, LinkMap::AllocPair> &,
1244         Region *, Region *) 
1245 {
1246     assert(!"Cleanup of TLS Regions from allocation map currently unimplemented");
1247 }
1248
1249 void emitElfStatic::tlsCleanupVariant2(map<Region *, LinkMap::AllocPair> &regionAllocs,
1250         Region *, Region *bssTLS) 
1251 {
1252     // Existing BSS TLS region is not copied to the new target data
1253     if( bssTLS != NULL ) regionAllocs.erase(bssTLS);
1254 }
1255
1256 bool 
1257 emitElfUtils::sort_reg(const Region* a, const Region* b)
1258 {   
1259     if (a->getMemOffset() == b->getMemOffset())
1260         return a->getMemSize() < b->getMemSize();
1261     return a->getMemOffset() < b->getMemOffset();
1262 }
1263
1264 /*
1265  * Sort the sections array so that sections with a non-zero
1266  * memory offset come first (and are sorted in increasing
1267  * order of offset). Preserves the ordering of zero-offset
1268  * sections.
1269  *
1270  * If no section has a non-zero offset, the return value will
1271  * be an address in the virtual memory space big enough to
1272  * hold all the loadable sections. Otherwise it will be the
1273  * address of the first non-zero offset section.
1274  *
1275  * NB if we need to create a new segment to hold these sections,
1276  * it needs to be clear up to the next page boundary to avoid
1277  * potentially clobbering other loadable segments.
1278  */
1279 Address 
1280 emitElfUtils::orderLoadableSections(Symtab *obj, vector<Region*> & sections)
1281 {
1282     Address ret = 0;
1283     Address sz = 0;
1284     vector<Region*> nonzero;
1285     vector<Region*> copy(sections);
1286     unsigned insert = sections.size()-1;
1287
1288     for(int i=copy.size()-1;i>=0;--i) {
1289         if(!copy[i]->getMemOffset())
1290             sections[insert--] = copy[i];
1291         else
1292             nonzero.push_back(copy[i]);
1293         sz += copy[i]->getMemSize();
1294     }
1295
1296     assert(nonzero.size() == (insert+1));
1297
1298     std::sort(nonzero.begin(),nonzero.end(),sort_reg);
1299     for(unsigned i=0;i<nonzero.size();++i)
1300         sections[i] = nonzero[i];
1301
1302     if(nonzero.size() > 0)
1303         ret = nonzero[0]->getMemOffset();
1304     else {
1305         // find a `hole' of appropriate size
1306         sz = (sz + 4096 - 1) & ~(4096-1);
1307         ret = obj->getFreeOffset(sz);
1308         if(!ret) {
1309             fprintf(stderr,"Failed to finde hole of size %lx, bailing\n",sz);
1310         }
1311     }
1312     return ret;
1313 }
1314