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