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