2 * See the dyninst/COPYRIGHT file for copyright information.
4 * We provide the Paradyn Tools (below described as "Paradyn")
5 * on an AS IS basis, and do not warrant its validity or performance.
6 * We reserve the right to update, modify, or discontinue this
7 * software at any time. We shall have no obligation to supply such
8 * updates or modifications or any other form of support to you.
10 * By your use of Paradyn, you understand and agree that we (or any
11 * other person or entity with proprietary rights in Paradyn) are
12 * under no obligation to provide either maintenance services,
13 * update services, notices of latent defects, or correction of
14 * defects for Paradyn.
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
40 #include "common/h/Timer.h"
41 #include "common/h/debugOstream.h"
42 #include "common/h/serialize.h"
43 #include "common/h/pathName.h"
45 #include "Serialization.h"
48 #include "Collections.h"
52 #include "annotations.h"
56 #include "symtabAPI/src/Object.h"
58 #if !defined(os_windows)
67 using namespace Dyninst;
68 using namespace Dyninst::SymtabAPI;
71 static std::string errMsg;
72 extern bool parseCompilerType(Object *);
74 static const int Symtab_major_version = 7;
75 static const int Symtab_minor_version = 0;
76 static const int Symtab_maintenance_version = 0;
78 Dwarf::DwarfFrameParserPtr Symtab::debugDwarf() {
79 return getObject()->dwarf.frameParser();
82 void Symtab::version(int& major, int& minor, int& maintenance)
84 major = Symtab_major_version;
85 minor = Symtab_minor_version;
86 maintenance = Symtab_maintenance_version;
90 void symtab_log_perror(const char *msg)
92 errMsg = std::string(msg);
98 std::vector<Symtab *> Symtab::allSymtabs;
101 SymtabError Symtab::getLastSymtabError()
106 void setSymtabError(SymtabError new_err)
111 std::string Symtab::printError(SymtabError serr)
116 return "Failed to parse the Object"+errMsg;
117 case Syms_To_Functions:
118 return "Failed to convert Symbols to Functions";
119 case No_Such_Function:
120 return "Function does not exist";
121 case No_Such_Variable:
122 return "Variable does not exist";
124 return "Module does not exist";
126 return "Region does not exist";
128 return "Symbol does not exist";
130 return "Not a File. Call openArchive()";
132 return "Not an Archive. Call openFile()";
134 return "Error Constructing XML"+errMsg;
136 return "Error rewriting binary: " + errMsg;
138 return "Flags passed are invalid.";
140 return "No previous Error.";
142 return "Unknown Error";
146 boost::shared_ptr<Type> Symtab::type_Error()
148 static boost::shared_ptr<Type> store =
149 boost::shared_ptr<Type>(new Type(std::string("<error>"), 0, dataUnknownType));
152 boost::shared_ptr<Type> Symtab::type_Untyped()
154 static boost::shared_ptr<Type> store =
155 boost::shared_ptr<Type>(new Type(std::string("<no type>"), 0, dataUnknownType));
159 boost::shared_ptr<builtInTypeCollection> Symtab::builtInTypes()
161 static boost::shared_ptr<builtInTypeCollection> store =
165 boost::shared_ptr<typeCollection> Symtab::stdTypes()
167 static boost::shared_ptr<typeCollection> store =
172 boost::shared_ptr<builtInTypeCollection> Symtab::setupBuiltinTypes()
174 boost::shared_ptr<builtInTypeCollection> builtInTypes =
175 boost::shared_ptr<builtInTypeCollection>(new builtInTypeCollection);
179 // NOTE: integral type mean twos-complement
180 // -1 int, 32 bit signed integral type
181 // in stab document, size specified in bits, system size is in bytes
182 builtInTypes->addBuiltInType(newType = new typeScalar(-1, 4, "int", true));
183 newType->decrRefCount();
184 // -2 char, 8 bit type holding a character. GDB & dbx(AIX) treat as signed
185 builtInTypes->addBuiltInType(newType = new typeScalar(-2, 1, "char", true));
186 newType->decrRefCount();
187 // -3 short, 16 bit signed integral type
188 builtInTypes->addBuiltInType(newType = new typeScalar(-3, 2, "short", true));
189 newType->decrRefCount();
190 // -4 long, 32/64 bit signed integral type
191 builtInTypes->addBuiltInType(newType = new typeScalar(-4, sizeof(long), "long", true));
192 newType->decrRefCount();
193 // -5 unsigned char, 8 bit unsigned integral type
194 builtInTypes->addBuiltInType(newType = new typeScalar(-5, 1, "unsigned char"));
195 newType->decrRefCount();
196 // -6 signed char, 8 bit signed integral type
197 builtInTypes->addBuiltInType(newType = new typeScalar(-6, 1, "signed char", true));
198 newType->decrRefCount();
199 // -7 unsigned short, 16 bit unsigned integral type
200 builtInTypes->addBuiltInType(newType = new typeScalar(-7, 2, "unsigned short"));
201 newType->decrRefCount();
202 // -8 unsigned int, 32 bit unsigned integral type
203 builtInTypes->addBuiltInType(newType = new typeScalar(-8, 4, "unsigned int"));
204 newType->decrRefCount();
205 // -9 unsigned, 32 bit unsigned integral type
206 builtInTypes->addBuiltInType(newType = new typeScalar(-9, 4, "unsigned"));
207 newType->decrRefCount();
208 // -10 unsigned long, 32 bit unsigned integral type
209 builtInTypes->addBuiltInType(newType = new typeScalar(-10, sizeof(unsigned long), "unsigned long"));
210 newType->decrRefCount();
211 // -11 void, type indicating the lack of a value
212 // XXX-size may not be correct jdd 4/22/99
213 builtInTypes->addBuiltInType(newType = new typeScalar(-11, 0, "void", false));
214 newType->decrRefCount();
215 // -12 float, IEEE single precision
216 builtInTypes->addBuiltInType(newType = new typeScalar(-12, sizeof(float), "float", true));
217 newType->decrRefCount();
218 // -13 double, IEEE double precision
219 builtInTypes->addBuiltInType(newType = new typeScalar(-13, sizeof(double), "double", true));
220 newType->decrRefCount();
221 // -14 long double, IEEE double precision, size may increase in future
222 builtInTypes->addBuiltInType(newType = new typeScalar(-14, sizeof(long double), "long double", true));
223 newType->decrRefCount();
224 // -15 integer, 32 bit signed integral type
225 builtInTypes->addBuiltInType(newType = new typeScalar(-15, 4, "integer", true));
226 newType->decrRefCount();
227 // -16 boolean, 32 bit type. GDB/GCC 0=False, 1=True, all other values
228 // have unspecified meaning
229 builtInTypes->addBuiltInType(newType = new typeScalar(-16, sizeof(bool), "boolean"));
230 newType->decrRefCount();
231 // -17 short real, IEEE single precision
232 // XXX-size may not be correct jdd 4/22/99
233 builtInTypes->addBuiltInType(newType = new typeScalar(-17, sizeof(float), "short real", true));
234 newType->decrRefCount();
235 // -18 real, IEEE double precision XXX-size may not be correct jdd 4/22/99
236 builtInTypes->addBuiltInType(newType = new typeScalar(-18, sizeof(double), "real", true));
237 newType->decrRefCount();
238 // -19 stringptr XXX- size of void * -- jdd 4/22/99
239 builtInTypes->addBuiltInType(newType = new typeScalar(-19, sizeof(void *), "stringptr"));
240 newType->decrRefCount();
241 // -20 character, 8 bit unsigned character type
242 builtInTypes->addBuiltInType(newType = new typeScalar(-20, 1, "character"));
243 newType->decrRefCount();
244 // -21 logical*1, 8 bit type (Fortran, used for boolean or unsigned int)
245 builtInTypes->addBuiltInType(newType = new typeScalar(-21, 1, "logical*1"));
246 newType->decrRefCount();
247 // -22 logical*2, 16 bit type (Fortran, some for boolean or unsigned int)
248 builtInTypes->addBuiltInType(newType = new typeScalar(-22, 2, "logical*2"));
249 newType->decrRefCount();
250 // -23 logical*4, 32 bit type (Fortran, some for boolean or unsigned int)
251 builtInTypes->addBuiltInType(newType = new typeScalar(-23, 4, "logical*4"));
252 newType->decrRefCount();
253 // -24 logical, 32 bit type (Fortran, some for boolean or unsigned int)
254 builtInTypes->addBuiltInType(newType = new typeScalar(-24, 4, "logical"));
255 newType->decrRefCount();
256 // -25 complex, consists of 2 IEEE single-precision floating point values
257 builtInTypes->addBuiltInType(newType = new typeScalar(-25, sizeof(float)*2, "complex", true));
258 newType->decrRefCount();
259 // -26 complex, consists of 2 IEEE double-precision floating point values
260 builtInTypes->addBuiltInType(newType = new typeScalar(-26, sizeof(double)*2, "complex*16", true));
261 newType->decrRefCount();
262 // -27 integer*1, 8 bit signed integral type
263 builtInTypes->addBuiltInType(newType = new typeScalar(-27, 1, "integer*1", true));
264 newType->decrRefCount();
265 // -28 integer*2, 16 bit signed integral type
266 builtInTypes->addBuiltInType(newType = new typeScalar(-28, 2, "integer*2", true));
267 newType->decrRefCount();
269 /* Quick hack to make integer*4 compatible with int for Fortran
271 // This seems questionable - let's try removing that hack - jmo 05/21/04
273 builtInTypes->addBuiltInType(newType = new type("int",-29,
275 newType->decrRefCount();
277 // -29 integer*4, 32 bit signed integral type
278 builtInTypes->addBuiltInType(newType = new typeScalar(-29, 4, "integer*4", true));
279 newType->decrRefCount();
280 // -30 wchar, Wide character, 16 bits wide, unsigned (unknown format)
281 builtInTypes->addBuiltInType(newType = new typeScalar(-30, 2, "wchar"));
282 newType->decrRefCount();
283 #if defined(os_windows)
284 // -31 long long, 64 bit signed integral type
285 builtInTypes->addBuiltInType(newType = new typeScalar(-31, sizeof(LONGLONG), "long long", true));
286 newType->decrRefCount();
287 // -32 unsigned long long, 64 bit unsigned integral type
288 builtInTypes->addBuiltInType(newType = new typeScalar(-32, sizeof(ULONGLONG), "unsigned long long"));
289 newType->decrRefCount();
291 // -31 long long, 64 bit signed integral type
292 builtInTypes->addBuiltInType(newType = new typeScalar(-31, sizeof(long long), "long long", true));
293 newType->decrRefCount();
294 // -32 unsigned long long, 64 bit unsigned integral type
295 builtInTypes->addBuiltInType(newType = new typeScalar(-32, sizeof(unsigned long long), "unsigned long long"));
296 newType->decrRefCount();
298 // -33 logical*8, 64 bit unsigned integral type
299 builtInTypes->addBuiltInType(newType = new typeScalar(-33, 8, "logical*8"));
300 newType->decrRefCount();
301 // -34 integer*8, 64 bit signed integral type
302 builtInTypes->addBuiltInType(newType = new typeScalar(-34, 8, "integer*8", true));
303 newType->decrRefCount();
309 boost::shared_ptr<typeCollection> Symtab::setupStdTypes()
311 boost::shared_ptr<typeCollection> stdTypes =
312 boost::shared_ptr<typeCollection>(new typeCollection);
316 stdTypes->addType(newType = new typeScalar(-1, sizeof(int), "int"));
317 newType->decrRefCount();
319 Type *charType = new typeScalar(-2, sizeof(char), "char");
320 stdTypes->addType(charType);
322 std::string tName = "char *";
323 typePointer *newPtrType;
324 stdTypes->addType(newPtrType = new typePointer(-3, charType, tName));
325 charType->decrRefCount();
326 newPtrType->decrRefCount();
328 Type *voidType = new typeScalar(-11, 0, "void", false);
329 stdTypes->addType(voidType);
332 stdTypes->addType(newPtrType = new typePointer(-4, voidType, tName));
333 voidType->decrRefCount();
334 newPtrType->decrRefCount();
336 stdTypes->addType(newType = new typeScalar(-12, sizeof(float), "float"));
337 newType->decrRefCount();
339 #if defined(i386_unknown_nt4_0)
340 stdTypes->addType(newType = new typeScalar(-31, sizeof(LONGLONG), "long long"));
342 stdTypes->addType(newType = new typeScalar(-31, sizeof(long long), "long long"));
345 newType->decrRefCount();
350 SYMTAB_EXPORT unsigned Symtab::getAddressWidth() const
352 return address_width_;
355 SYMTAB_EXPORT bool Symtab::isNativeCompiler() const
357 return nativeCompiler;
360 SYMTAB_EXPORT Symtab::Symtab(MappedFile *mf_) :
365 address_width_(sizeof(int)),
366 object_type_(obj_Unknown),
367 defaultNamespacePrefix(""),
369 newSectionInsertPoint(0),
374 init_debug_symtabAPI();
376 #if defined(os_vxworks)
377 // This is how we initialize objects from WTX information alone.
378 // Basically replaces extractInfo().
379 object_type_ = obj_RelocatableFile;
380 mfForDebugInfo = NULL;
385 isStaticBinary_ = false;
402 createDefaultModule();
405 SYMTAB_EXPORT Symtab::Symtab() :
407 address_width_(sizeof(int)),
408 object_type_(obj_Unknown),
409 defaultNamespacePrefix(""),
411 newSectionInsertPoint(0),
416 init_debug_symtabAPI();
417 create_printf("%s[%d]: Created symtab via default constructor\n", FILE__, __LINE__);
418 createDefaultModule();
421 SYMTAB_EXPORT bool Symtab::isExec() const
426 SYMTAB_EXPORT bool Symtab::isStripped()
428 #if defined(os_linux) || defined(os_freebsd)
430 return !findRegion(sec,".symtab");
432 return (no_of_symbols==0);
436 SYMTAB_EXPORT Offset Symtab::imageOffset() const
441 SYMTAB_EXPORT Offset Symtab::dataOffset() const
446 SYMTAB_EXPORT Offset Symtab::dataLength() const
451 SYMTAB_EXPORT Offset Symtab::imageLength() const
456 SYMTAB_EXPORT void Symtab::fixup_code_and_data(Offset newImageOffset,
457 Offset newImageLength,
458 Offset newDataOffset,
459 Offset newDataLength)
461 imageOffset_ = newImageOffset;
462 imageLen_ = newImageLength;
463 dataOffset_ = newDataOffset;
464 dataLen_ = newDataLength;
466 // Should we update the underlying Object?
470 SYMTAB_EXPORT char* Symtab::image_ptr () const
475 SYMTAB_EXPORT char* Symtab::data_ptr () const
480 SYMTAB_EXPORT const char* Symtab::getInterpreterName() const
482 if (interpreter_name_.length())
483 return interpreter_name_.c_str();
487 SYMTAB_EXPORT Offset Symtab::getEntryOffset() const
489 return entry_address_;
492 SYMTAB_EXPORT Offset Symtab::getBaseOffset() const
494 return base_address_;
497 SYMTAB_EXPORT Offset Symtab::getLoadOffset() const
499 return load_address_;
502 SYMTAB_EXPORT Offset Symtab::getTOCoffset() const
507 SYMTAB_EXPORT string Symtab::getDefaultNamespacePrefix() const
509 return defaultNamespacePrefix;
513 // TODO -- is this g++ specific
514 bool Symtab::buildDemangledName( const std::string &mangled,
518 supportedLanguages lang )
520 /* The C++ demangling function demangles MPI__Allgather (and other MPI__
521 * functions with start with A) into the MPI constructor. In order to
522 * prevent this a hack needed to be made, and this seemed the cleanest
526 if ((mangled.length()>5) && (mangled.substr(0,5)==std::string("MPI__")))
531 /* If it's Fortran, eliminate the trailing underscores, if any. */
532 if (lang == lang_Fortran
533 || lang == lang_CMFortran
534 || lang == lang_Fortran_with_pretty_debug )
536 if ( mangled[ mangled.length() - 1 ] == '_' )
538 char * demangled = P_strdup( mangled.c_str() );
539 demangled[ mangled.length() - 1 ] = '\0';
540 pretty = std::string( demangled );
547 /* No trailing underscores, do nothing */
550 } /* end if it's Fortran. */
552 // Check to see if we have a gnu versioned symbol on our hands.
553 // These are of the form <symbol>@<version> or <symbol>@@<version>
555 // If we do, we want to create a "demangled" name for the one that
556 // is of the form <symbol>@@<version> since this is, by definition,
557 // the default. The "demangled" name will just be <symbol>
559 // NOTE: this is just a 0th order approach to dealing with versioned
560 // symbols. We may need to do something more sophisticated
561 // in the future. JAW 10/03
563 #if !defined(os_windows)
567 if (NULL != (atat = strstr(mangled.c_str(), "@@")))
569 pretty = mangled.substr(0 /*start pos*/,
570 (int)(atat - mangled.c_str())/*len*/);
572 //sprintf(msg, "%s[%d]: 'demangling' versioned symbol: %s, to %s",
573 // __FILE__, __LINE__, mangled.c_str(), pretty.c_str());
575 //cerr << msg << endl;
585 /* Try demangling it. */
586 char * demangled = P_cplus_demangle( mangled.c_str(), nativeCompiler, false);
589 pretty = std::string( demangled );
593 char *t_demangled = P_cplus_demangle(mangled.c_str(), nativeCompiler, true);
594 if (t_demangled && (strcmp(t_demangled, demangled) != 0))
596 typed = std::string(t_demangled);
606 } /* end buildDemangledName() */
610 * extractSymbolsFromFile
612 * Create a Symtab-level list of symbols by pulling out data
613 * from the low-level parse (linkedFile).
614 * Technically this causes a duplication of symbols; however,
615 * we will be rewriting these symbols and so we need our own
618 * TODO: delete the linkedFile once we're done?
621 bool Symtab::extractSymbolsFromFile(Object *linkedFile, std::vector<Symbol *> &raw_syms)
623 for (SymbolIter symIter(*linkedFile); symIter; symIter++) {
624 Symbol *sym = symIter.currval();
626 fprintf(stderr, "%s[%d]: range error, stopping now\n", FILE__, __LINE__);
630 // If a symbol starts with "." we want to skip it. These indicate labels in the
633 // removed 1/09: this should be done in Dyninst, not Symtab
635 // Have to do this before the undef check, below.
638 // check for undefined dynamic symbols. Used when rewriting relocation section.
639 // relocation entries have references to these undefined dynamic symbols.
640 // We also have undefined symbols for the static binary case.
642 #if !defined(os_vxworks)
643 if (sym->getRegion() == NULL && !sym->isAbsolute() && !sym->isCommonStorage()) {
644 undefDynSyms.push_back(sym);
649 // Check whether this symbol has a valid offset. If they do not we have a
650 // consistency issue. This should be a null check.
652 // Symbols can have an offset of 0 if they don't refer to things within a file.
654 raw_syms.push_back(sym);
660 bool Symtab::fixSymRegion(Symbol *sym) {
661 if (!sym->getRegion()) return true;
663 if (sym->getType() != Symbol::ST_FUNCTION &&
664 sym->getType() != Symbol::ST_OBJECT) return true;
666 if (sym->getRegion()->getMemOffset() <= sym->getOffset() &&
667 (sym->getRegion()->getMemOffset() + sym->getRegion()->getMemSize()) > sym->getOffset())
670 sym->setRegion(findEnclosingRegion(sym->getOffset()));
678 * Add Module information to all symbols.
681 bool Symtab::fixSymModules(std::vector<Symbol *> &raw_syms)
683 for (unsigned i = 0; i < raw_syms.size(); i++) {
684 fixSymModule(raw_syms[i]);
686 Object *obj = getObject();
688 #if !defined(os_vxworks)
689 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
693 const std::vector<std::pair<std::string, Offset> > &mods = obj->modules_;
694 for (unsigned i=0; i< mods.size(); i++) {
695 getOrCreateModule(mods[i].first, mods[i].second);
704 * Perform name demangling on all symbols.
707 bool Symtab::demangleSymbols(std::vector<Symbol *> &raw_syms)
709 for (unsigned i = 0; i < raw_syms.size(); i++) {
710 demangleSymbol(raw_syms[i]);
718 * We index symbols by various attributes for quick lookup. Build those
722 bool Symtab::createIndices(std::vector<Symbol *> &raw_syms, bool undefined) {
723 for (unsigned i = 0; i < raw_syms.size(); i++) {
724 addSymbolToIndices(raw_syms[i], undefined);
732 * Frequently there will be multiple Symbols that refer to a single
733 * code object (e.g., function or variable). We use separate objects
734 * to refer to these aggregates, and build those objects here.
737 bool Symtab::createAggregates()
739 #if !defined(os_vxworks)
740 // In VxWorks, symbol offsets are not complete until object is loaded.
742 for (unsigned i = 0; i < everyDefinedSymbol.size(); i++)
744 if (!doNotAggregate(everyDefinedSymbol[i])) {
745 addSymbolToAggregates(everyDefinedSymbol[i]);
753 bool Symtab::fixSymModule(Symbol *&sym)
759 // It has been decided that all libraries shall have only one
760 // module named after the library. The a.out has one module
761 // per (reported) source file, plus DEFAULT_MODULE for everything
762 // else. This is enforced here, although the Object-* files might
765 if (getObjectType() == obj_SharedLib) {
766 mod = getDefaultModule();
769 Object *obj = getObject();
772 #if !defined(os_vxworks)
773 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
777 std::string modName = obj->findModuleForSym(sym);
778 if (modName.length() == 0) {
779 mod = getDefaultModule();
782 mod = getOrCreateModule(modName, sym->getOffset());
794 bool Symtab::demangleSymbol(Symbol *&sym) {
795 bool typed_demangle = false;
796 if (sym->getType() == Symbol::ST_FUNCTION) typed_demangle = true;
798 // This is a bit of a hack; we're trying to demangle undefined symbols which don't necessarily
799 // have a ST_FUNCTION type.
800 if (sym->getRegion() == NULL && !sym->isAbsolute() && !sym->isCommonStorage())
801 typed_demangle = true;
803 if (typed_demangle) {
804 Module *rawmod = sym->getModule();
806 // At this point we need to generate the following information:
808 // A pretty (demangled) name.
809 // The symtab name goes in the global list as well as the module list.
810 // Same for the pretty name.
811 // Finally, check addresses to find aliases.
813 std::string mangled_name = sym->getMangledName();
814 std::string working_name = mangled_name;
816 #if !defined(os_windows)
817 //Remove extra stabs information
818 const char *p = strchr(working_name.c_str(), ':');
820 unsigned nchars = p - mangled_name.c_str();
821 working_name = std::string(mangled_name.c_str(), nchars);
825 std::string pretty_name = working_name;
826 std::string typed_name = working_name;
828 if (!buildDemangledName(working_name, pretty_name, typed_name,
829 nativeCompiler, (rawmod ? rawmod->language() : lang_Unknown))) {
830 pretty_name = working_name;
833 sym->prettyName_ = pretty_name;
834 sym->typedName_ = typed_name;
837 // All cases where there really shouldn't be a mangled
838 // name, since mangling is for functions.
840 char *prettyName = P_cplus_demangle(sym->getMangledName().c_str(), nativeCompiler, false);
842 sym->prettyName_ = std::string(prettyName);
851 bool Symtab::addSymbolToIndices(Symbol *&sym, bool undefined)
855 everyDefinedSymbol.push_back(sym);
856 symsByMangledName[sym->getMangledName()].push_back(sym);
857 symsByPrettyName[sym->getPrettyName()].push_back(sym);
858 symsByTypedName[sym->getTypedName()].push_back(sym);
859 #if !defined(os_vxworks)
860 // VxWorks doesn't know symbol addresses until object is loaded.
861 symsByOffset[sym->getOffset()].push_back(sym);
865 // We keep a different index for undefined symbols
866 undefDynSymsByMangledName[sym->getMangledName()].push_back(sym);
867 undefDynSymsByPrettyName[sym->getPrettyName()].push_back(sym);
868 undefDynSymsByTypedName[sym->getTypedName()].push_back(sym);
869 // And undefDynSyms is already filled in
874 bool Symtab::addSymbolToAggregates(Symbol *&sym)
877 switch(sym->getType()) {
878 case Symbol::ST_FUNCTION: {
879 // We want to do the following:
880 // If no function exists, create and add.
881 // Combine this information
882 // Add this symbol's names to the function.
883 // Keep module information
885 Function *func = NULL;
886 findFuncByEntryOffset(func, sym->getOffset());
888 // Create a new function
889 // Also, update the symbol to point to this function.
891 func = new Function(sym);
893 everyFunction.push_back(func);
894 sorted_everyFunction = false;
895 funcsByOffset[sym->getOffset()] = func;
899 * For relocatable files, the offset of a symbol is relative to the
900 * beginning of a Region. Therefore, a symbol in a relocatable file
901 * is not uniquely identifiable by its offset, but it is uniquely
902 * identifiable by its Region and its offset.
904 * For now, do not add these functions to funcsByOffset collection.
907 if( func->getRegion() != sym->getRegion() ) {
908 func = new Function(sym);
909 everyFunction.push_back(func);
910 sorted_everyFunction = false;
912 func->addSymbol(sym);
914 sym->setFunction(func);
919 case Symbol::ST_OBJECT: {
920 // The same as the above, but with variables.
921 Variable *var = NULL;
922 findVariableByOffset(var, sym->getOffset());
924 // Create a new function
925 // Also, update the symbol to point to this function.
926 var = new Variable(sym);
928 everyVariable.push_back(var);
929 varsByOffset[sym->getOffset()] = var;
933 * For relocatable files, the offset is not a unique identifier for
934 * a Symbol. With functions, the Region and offset could be used to
935 * identify the symbol. With variables, the Region and offset may
936 * not uniquely identify the symbol. The only case were this occurs
937 * is with COMMON symbols -- their offset is their memory alignment
938 * and their Region is undefined. In this case, always create a
941 if( obj_RelocatableFile == getObjectType() &&
942 ( var->getRegion() != sym->getRegion() ||
943 NULL == sym->getRegion() ) )
945 var = new Variable(sym);
946 everyVariable.push_back(var);
951 sym->setVariable(var);
961 // A hacky override for specially treating symbols that appear
962 // to be functions or variables but aren't.
964 // Example: IA-32/AMD-64 libc (and others compiled with libc headers)
965 // uses outlined locking primitives. These are named _L_lock_<num>
966 // and _L_unlock_<num> and labelled as functions. We explicitly do
967 // not include them in function scope.
968 bool Symtab::doNotAggregate(Symbol *&sym) {
969 if (sym->getMangledName().compare(0, strlen("_L_lock_"), "_L_lock_") == 0) {
972 if (sym->getMangledName().compare(0, strlen("_L_unlock_"), "_L_unlock_") == 0) {
976 // PPC64 Linux symbols in the .opd section appear to be functions,
978 if (sym->getRegion() && sym->getRegion()->getRegionName() == ".opd") {
985 /* Add the new name to the appropriate symbol index */
987 bool Symtab::updateIndices(Symbol *sym, std::string newName, NameType nameType) {
988 if (nameType & mangledName) {
989 // Add this symbol under the given name (as mangled)
990 symsByMangledName[newName].push_back(sym);
992 if (nameType & prettyName) {
993 // Add this symbol under the given name (as pretty)
994 symsByPrettyName[newName].push_back(sym);
996 if (nameType & typedName) {
997 // Add this symbol under the given name (as typed)
998 symsByTypedName[newName].push_back(sym);
1004 /* checkPPC64DescriptorSymbols() is no longer needed. 3-word descriptor
1005 * symbols are properly taken care of during symbol parsing. See
1006 * parse_symbols() in Object-elf.C for details.
1009 #if defined(ppc64_linux)
1010 /* Special case for ppc64 ELF binaries. Sometimes a function has a 3-byte descriptor symbol
1011 * along with it in the symbol table and "." preceding its original pretty name for the correct
1012 * function symbol. This checks to see if we have a corresponding 3-byte descriptor symbol existing
1013 * and if it does we remove the preceding "." from the name of the symbol
1016 void Symtab::checkPPC64DescriptorSymbols(Object *linkedFile)
1018 // find the real functions -- those with the correct type in the symbol table
1019 for(SymbolIter symIter(*linkedFile); symIter;symIter++)
1021 Symbol *lookUp = symIter.currval();
1022 const char *np = lookUp->getMangledName().c_str();
1026 if(np[0] == '.' && (lookUp->getType() == Symbol::ST_FUNCTION))
1028 std::vector<Symbol *>syms;
1029 std::string newName = np+1;
1030 if(linkedFile->get_symbols(newName, syms) && (syms[0]->getSize() == 24 || syms[0]->getSize() == 0))
1032 //Remove the "." from the name
1033 lookUp->mangledNames[0] = newName;
1035 //Change the type of the descriptor symbol
1036 syms[0]->type_ = Symbol::ST_NOTYPE;
1046 // setModuleLanguages is only called after modules have been defined.
1047 // it attempts to set each module's language, information which is needed
1048 // before names can be demangled.
1049 void Symtab::setModuleLanguages(dyn_hash_map<std::string, supportedLanguages> *mod_langs)
1051 if (!mod_langs->size())
1052 return; // cannot do anything here
1053 // this case will arise on non-stabs platforms until language parsing can be introduced at this level
1054 std::vector<Module *> *modlist;
1055 Module *currmod = NULL;
1059 for (unsigned int i = 0; i < modlist->size(); ++i)
1061 currmod = (*modlist)[i];
1062 supportedLanguages currLang;
1063 if (currmod->isShared()) {
1064 continue; // need to find some way to get shared object languages?
1067 const std::string fn = currmod->fileName();
1068 if (mod_langs->find(currmod->fileName()) != mod_langs->end())
1070 currLang = (*mod_langs)[fn];
1072 else if (fn.rfind(".s") != std::string::npos ||
1073 fn.rfind(".asm") != std::string::npos)
1075 currLang = lang_Assembly;
1077 else if (fn.rfind(".c") != std::string::npos)
1081 else if (fn.rfind(".cpp") != std::string::npos ||
1082 fn.rfind(".cc") != std::string::npos ||
1083 fn.rfind(".C") != std::string::npos)
1085 currLang = lang_CPlusPlus;
1091 currmod->setLanguage(currLang);
1095 void Symtab::createDefaultModule() {
1097 if (getObjectType() == obj_SharedLib) {
1098 mod = new Module(lang_Unknown,
1104 mod = new Module(lang_Unknown,
1106 #if defined(os_vxworks)
1107 // VxWorks' kernel objects should
1108 // have their own module.
1115 modsByFileName[mod->fileName()] = mod;
1116 modsByFullName[mod->fullName()] = mod;
1117 _mods.push_back(mod);
1122 Module *Symtab::getOrCreateModule(const std::string &modName,
1123 const Offset modAddr)
1125 std::string nameToUse;
1126 if (modName.length() > 0)
1127 nameToUse = modName;
1129 nameToUse = "DEFAULT_MODULE";
1132 if (findModuleByName(fm, nameToUse))
1137 const char *str = nameToUse.c_str();
1138 int len = nameToUse.length();
1141 // TODO ignore directory definitions for now
1142 if (str[len-1] == '/')
1145 return (newModule(nameToUse, modAddr, lang_Unknown));
1148 Module *Symtab::newModule(const std::string &name, const Offset addr, supportedLanguages lang)
1151 // modules can be defined several times in C++ due to templates and
1152 // in-line member functions.
1154 if (findModuleByName(ret, name))
1159 //parsing_printf("=== image, creating new pdmodule %s, addr 0x%x\n",
1160 // name.c_str(), addr);
1162 std::string fileNm, fullNm;
1164 fileNm = extract_pathname_tail(name);
1166 // /* DEBUG */ fprintf( stderr, "%s[%d]: In %p: Creating new pdmodule '%s'/'%s'\n", FILE__, __LINE__, this, fileNm.c_str(), fullNm.c_str() );
1167 create_printf("%s[%d]: In %p: Creating new module '%s'/'%s'\n", FILE__, __LINE__, this, fileNm.c_str(), fullNm.c_str());
1169 ret = new Module(lang, addr, fullNm, this);
1175 * There are cases where the fileName can be the same, but the full name is
1176 * different and the modules are actually different. This is an inherent
1177 * problem with how modules are processed.
1179 if (modsByFileName.end() != modsByFileName.find(ret->fileName()))
1181 create_printf("%s[%d]: WARN: LEAK? already have module with name %s\n",
1182 FILE__, __LINE__, ret->fileName().c_str());
1185 if (modsByFullName.end() != modsByFullName.find(ret->fullName()))
1187 create_printf("%s[%d]: WARN: LEAK? already have module with name %s\n",
1188 FILE__, __LINE__, ret->fullName().c_str());
1191 modsByFileName[ret->fileName()] = ret;
1192 modsByFullName[ret->fullName()] = ret;
1193 _mods.push_back(ret);
1198 Symtab::Symtab(std::string filename, bool defensive_bin, bool &err) :
1202 nativeCompiler(false),
1203 isLineInfoValid_(false),
1204 isTypeInfoValid_(false),
1205 isDefensiveBinary_(defensive_bin),
1209 init_debug_symtabAPI();
1210 // Initialize error parameter
1213 create_printf("%s[%d]: created symtab for %s\n", FILE__, __LINE__, filename.c_str());
1215 #if defined (os_windows)
1216 extern void fixup_filename(std::string &);
1217 fixup_filename(filename);
1220 // createMappedFile handles reference counting
1221 mf = MappedFile::createMappedFile(filename);
1223 create_printf("%s[%d]: WARNING: creating symtab for %s, "
1224 "createMappedFile() failed\n", FILE__, __LINE__,
1230 obj_private = new Object(mf, mfForDebugInfo, defensive_bin,
1231 symtab_log_perror, true);
1232 if (obj_private->hasError()) {
1237 if (!extractInfo(obj_private))
1239 create_printf("%s[%d]: WARNING: creating symtab for %s, extractInfo() "
1240 "failed\n", FILE__, __LINE__, filename.c_str());
1244 member_name_ = mf->filename();
1246 defaultNamespacePrefix = "";
1249 Symtab::Symtab(unsigned char *mem_image, size_t image_size,
1250 const std::string &name, bool defensive_bin, bool &err) :
1254 nativeCompiler(false),
1255 isLineInfoValid_(false),
1256 isTypeInfoValid_(false),
1257 isDefensiveBinary_(defensive_bin),
1261 // Initialize error parameter
1264 create_printf("%s[%d]: created symtab for memory image at addr %u\n",
1265 FILE__, __LINE__, mem_image);
1267 // createMappedFile handles reference counting
1268 mf = MappedFile::createMappedFile(mem_image, image_size, name);
1270 create_printf("%s[%d]: WARNING: creating symtab for memory image at "
1271 "addr %u, createMappedFile() failed\n", FILE__, __LINE__,
1277 obj_private = new Object(mf, mfForDebugInfo, defensive_bin,
1278 symtab_log_perror, true);
1279 if (obj_private->hasError()) {
1284 if (!extractInfo(obj_private))
1286 create_printf("%s[%d]: WARNING: creating symtab for memory image at addr"
1287 "%u, extractInfo() failed\n", FILE__, __LINE__, mem_image);
1291 member_name_ = mf->filename();
1293 defaultNamespacePrefix = "";
1296 // Symtab constructor for archive members
1298 Symtab::Symtab(std::string filename, std::string member_name, Offset offset,
1299 bool &err, void *base) :
1300 member_name_(member_name),
1301 member_offset_(offset),
1304 nativeCompiler(false),
1305 isLineInfoValid_(false),
1306 isTypeInfoValid_(false),
1310 mf = MappedFile::createMappedFile(filename);
1312 obj_private = new Object(mf, mfForDebugInfo, member_name, offset, symtab_log_perror, base);
1313 if (obj_private->hasError()) {
1317 err = !extractInfo(obj_private);
1318 defaultNamespacePrefix = "";
1320 create_printf("%s[%d]: created symtab for %s(%s)\n", FILE__, __LINE__, filename.c_str(),
1321 member_name.c_str());
1324 Symtab::Symtab(std::string, std::string, Offset, bool &, void *)
1330 #if defined(os_aix) // is this ever used on AIX?
1331 Symtab::Symtab(char *mem_image, size_t image_size, std::string member_name,
1332 Offset offset, bool &err, void *base) :
1333 member_name_(member_name),
1334 member_offset_(offset),
1337 nativeCompiler(false),
1338 isLineInfoValid_(false),
1339 isTypeInfoValid_(false),
1342 mf = MappedFile::createMappedFile(mem_image, image_size);
1344 obj_private = new Object(mf, mf, member_name, offset, symtab_log_perror, base);
1345 if (obj_private->hasError()) {
1349 err = !extractInfo(obj_private);
1350 defaultNamespacePrefix = "";
1353 Symtab::Symtab(char *, size_t, std::string , Offset, bool &, void *)
1359 bool sort_reg_by_addr(const Region* a, const Region* b)
1361 if (a->getMemOffset() == b->getMemOffset())
1362 return a->getMemSize() < b->getMemSize();
1363 return a->getMemOffset() < b->getMemOffset();
1366 extern void print_symbols( std::vector< Symbol *>& allsymbols );
1367 extern void print_symbol_map( dyn_hash_map< std::string, std::vector< Symbol *> > *symbols);
1369 bool Symtab::extractInfo(Object *linkedFile)
1371 #if defined(TIMED_PARSE)
1372 struct timeval starttime;
1373 gettimeofday(&starttime, NULL);
1375 mfForDebugInfo = linkedFile->getMappedFileForDebugInfo();
1379 * Some ELF .o's don't have contiguous code and data Regions so these data
1380 * members are imprecise. These members should probably be deprecated in
1381 * favor of the getCodeRegions and getDataRegions functions.
1384 imageOffset_ = linkedFile->code_off();
1385 dataOffset_ = linkedFile->data_off();
1387 imageLen_ = linkedFile->code_len();
1388 dataLen_ = linkedFile->data_len();
1390 if (0 == imageLen_ || 0 == linkedFile->code_ptr())
1392 // for AIX, code_ptr()==NULL is normal behavior
1393 #if !defined(os_aix)
1394 if (0 == linkedFile->code_ptr()) {
1395 //fprintf(stderr, "[%s][%d]WARNING: null code pointer in Symtab for"
1396 //" file %s, possibly due to a missing .text section.\n",
1397 //__FILE__,__LINE__, file().c_str());
1398 linkedFile->code_ptr_ = (char *) linkedFile->code_off();
1403 if( object_type_ != obj_RelocatableFile ||
1404 linkedFile->code_ptr() == 0)
1412 // if (!imageLen_ || !linkedFile->code_ptr()) {
1413 // serr = Obj_Parsing;
1417 no_of_sections = linkedFile->no_of_sections();
1418 newSectionInsertPoint = no_of_sections;
1419 no_of_symbols = linkedFile->no_of_symbols();
1421 isStaticBinary_ = linkedFile->isStaticBinary();
1426 hasReladyn_ = false;
1428 hasRelaplt_ = false;
1429 regions_ = linkedFile->getAllRegions();
1431 for (unsigned index=0;index<regions_.size();index++)
1433 if ( regions_[index]->isLoadable() )
1435 if ( (regions_[index]->getRegionPermissions() == Region::RP_RX)
1436 || (isDefensiveBinary_ &&
1437 regions_[index]->getRegionPermissions() == Region::RP_RW)
1438 || (regions_[index]->getRegionPermissions() == Region::RP_RWX))
1440 codeRegions_.push_back(regions_[index]);
1444 dataRegions_.push_back(regions_[index]);
1448 regionsByEntryAddr[regions_[index]->getMemOffset()] = regions_[index];
1450 if (regions_[index]->getRegionType() == Region::RT_REL)
1455 if (regions_[index]->getRegionType() == Region::RT_RELA)
1460 #if defined(os_linux) || defined(os_freebsd)
1461 hasReldyn_ = linkedFile->hasReldyn();
1462 hasReladyn_ = linkedFile->hasReladyn();
1463 hasRelplt_ = linkedFile->hasRelplt();
1464 hasRelaplt_ = linkedFile->hasRelaplt();
1468 // sort regions_ & codeRegions_ vectors
1470 std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
1471 std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
1472 std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
1474 /* insert error check here. check if parsed */
1475 address_width_ = linkedFile->getAddressWidth();
1476 is_a_out = linkedFile->is_aout();
1477 code_ptr_ = linkedFile->code_ptr();
1478 data_ptr_ = linkedFile->data_ptr();
1480 if (linkedFile->interpreter_name())
1481 interpreter_name_ = std::string(linkedFile->interpreter_name());
1483 entry_address_ = linkedFile->getEntryAddress();
1484 base_address_ = linkedFile->getBaseAddress();
1485 load_address_ = linkedFile->getLoadAddress();
1486 toc_offset_ = linkedFile->getTOCoffset();
1487 object_type_ = linkedFile->objType();
1488 is_eel_ = linkedFile->isEEL();
1489 linkedFile->getSegments(segments_);
1491 #if !defined(os_aix) && !defined(os_windows)
1492 linkedFile->getDependencies(deps_);
1495 #if defined (os_aix)
1496 // These should go away
1497 linkedFile->get_stab_info(stabstr_, nstabs_, stabs_, stringpool_);
1498 linkedFile->get_line_info(nlines_, lines_, fdptr_);
1501 #if defined(os_aix) || defined(os_linux) || defined(os_freebsd)
1502 // make sure we're using the right demangler
1504 nativeCompiler = parseCompilerType(linkedFile);
1505 //parsing_printf("isNativeCompiler: %d\n", nativeCompiler);
1508 // define all of the functions
1509 //statusLine("winnowing functions");
1511 // a vector to hold all created symbols until they are properly classified
1512 std::vector<Symbol *> raw_syms;
1514 #ifdef BINEDIT_DEBUG
1515 printf("== from linkedFile...\n");
1516 print_symbol_map(linkedFile->getAllSymbols());
1519 if (!extractSymbolsFromFile(linkedFile, raw_syms))
1521 serr = Syms_To_Functions;
1525 // don't sort the symbols--preserve the original ordering
1526 //sort(raw_syms.begin(),raw_syms.end(),symbol_compare);
1528 createDefaultModule();
1530 if (!fixSymModules(raw_syms))
1532 serr = Syms_To_Functions;
1535 Object *obj = getObject();
1538 #if !defined(os_vxworks)
1539 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
1543 obj->clearSymsToMods();
1545 // wait until all modules are defined before applying languages to
1546 // them we want to do it this way so that module information comes
1547 // from the function symbols, first and foremost, to avoid any
1548 // internal module-function mismatching.
1550 // get Information on the language each modules is written in
1551 // (prior to making modules)
1553 dyn_hash_map<std::string, supportedLanguages> mod_langs;
1554 linkedFile->getModuleLanguageInfo(&mod_langs);
1555 setModuleLanguages(&mod_langs);
1557 // Be sure that module languages are set before demangling, or
1558 // we won't get very far.
1560 if (!demangleSymbols(raw_syms))
1562 serr = Syms_To_Functions;
1566 if (!demangleSymbols(undefDynSyms)) {
1567 serr = Syms_To_Functions;
1571 if (!createIndices(raw_syms, false))
1573 serr = Syms_To_Functions;
1577 if (!createIndices(undefDynSyms, true))
1579 serr = Syms_To_Functions;
1583 if (!createAggregates())
1585 serr = Syms_To_Functions;
1589 // Once languages are assigned, we can build demangled names (in
1590 // the wider sense of demangling which includes stripping _'s from
1591 // fortran names -- this is why language information must be
1592 // determined before this step).
1594 // Also identifies aliases (multiple names with equal addresses)
1596 //addSymtabVariables();
1597 linkedFile->getAllExceptions(excpBlocks);
1599 vector<relocationEntry >fbt;
1600 linkedFile->get_func_binding_table(fbt);
1601 for(unsigned i=0; i<fbt.size();i++)
1602 relocation_table_.push_back(fbt[i]);
1606 Symtab::Symtab(const Symtab& obj) :
1609 AnnotatableSparse(),
1612 create_printf("%s[%d]: Creating symtab 0x%p from symtab 0x%p\n", FILE__, __LINE__, this, &obj);
1614 member_name_ = obj.member_name_;
1615 member_offset_ = obj.member_offset_;
1616 imageOffset_ = obj.imageOffset_;
1617 imageLen_ = obj.imageLen_;
1618 dataOffset_ = obj.dataOffset_;
1619 dataLen_ = obj.dataLen_;
1620 isDefensiveBinary_ = obj.isDefensiveBinary_;
1622 isLineInfoValid_ = obj.isLineInfoValid_;
1623 isTypeInfoValid_ = obj.isTypeInfoValid_;
1625 is_a_out = obj.is_a_out;
1626 main_call_addr_ = obj.main_call_addr_; // address of call to main()
1628 nativeCompiler = obj.nativeCompiler;
1629 defaultNamespacePrefix = obj.defaultNamespacePrefix;
1632 no_of_sections = obj.no_of_sections;
1635 for (i=0;i<obj.regions_.size();i++)
1636 regions_.push_back(new Region(*(obj.regions_[i])));
1638 for (i=0;i<regions_.size();i++)
1639 regionsByEntryAddr[regions_[i]->getMemOffset()] = regions_[i];
1641 // TODO FIXME: copying symbols/Functions/Variables
1643 for (i=0;i<obj._mods.size();i++)
1645 Module *m = new Module(*(obj._mods[i]));
1647 modsByFileName[m->fileName()] = m;
1648 modsByFullName[m->fullName()] = m;
1649 fprintf(stderr, "%s[%d]: copy ctor creating new module %s\n",
1650 FILE__, __LINE__, m->fileName().c_str());
1653 for (i=0; i<relocation_table_.size();i++)
1655 relocation_table_.push_back(relocationEntry(obj.relocation_table_[i]));
1658 for (i=0;i<excpBlocks.size();i++)
1660 excpBlocks.push_back(new ExceptionBlock(*(obj.excpBlocks[i])));
1666 // Address must be in code or data range since some code may end up
1667 // in the data segment
1668 bool Symtab::isValidOffset(const Offset where) const
1670 return isCode(where) || isData(where);
1673 /* Performs a binary search on the codeRegions_ vector, which must
1674 * be kept in sorted order
1676 bool Symtab::isCode(const Offset where) const
1678 #if defined(os_vxworks)
1679 // All memory is valid in the kernel. Kinda.
1683 if (!codeRegions_.size())
1685 fprintf(stderr, "%s[%d] No code regions in %s \n",
1686 __FILE__, __LINE__, mf->filename().c_str());
1690 // search for "where" in codeRegions_ (code regions must not overlap)
1692 int last = codeRegions_.size() - 1;
1694 while (last >= first)
1696 Region *curreg = codeRegions_[(first + last) / 2];
1697 if (where >= curreg->getMemOffset()
1698 && where < (curreg->getMemOffset()
1699 + curreg->getMemSize()))
1701 if (curreg->getRegionType() == Region::RT_BSS)
1705 else if (where < curreg->getMemOffset())
1707 last = ((first + last) / 2) - 1;
1709 else if (where >= (curreg->getMemOffset() + curreg->getMemSize()))
1711 first = ((first + last) / 2) + 1;
1714 { // "where" is in the range:
1715 // [memOffset + diskSize , memOffset + memSize)
1716 // meaning that it's in an uninitialized data region
1724 /* Performs a binary search on the dataRegions_ vector, which must
1725 * be kept in sorted order */
1726 bool Symtab::isData(const Offset where) const
1728 if (!dataRegions_.size())
1730 fprintf(stderr, "%s[%d] No data regions in %s \n",
1731 __FILE__,__LINE__,mf->filename().c_str());
1736 int last = dataRegions_.size() - 1;
1738 while (last >= first)
1740 Region *curreg = dataRegions_[(first + last) / 2];
1742 if ( (where >= curreg->getMemOffset())
1743 && (where < (curreg->getMemOffset() + curreg->getMemSize())))
1747 else if (where < curreg->getMemOffset())
1749 last = ((first + last) / 2) - 1;
1753 first = ((first + last) / 2) + 1;
1760 SYMTAB_EXPORT bool Symtab::getFuncBindingTable(std::vector<relocationEntry> &fbt) const
1762 fbt = relocation_table_;
1766 SYMTAB_EXPORT bool Symtab::updateFuncBindingTable(Offset stub_addr, Offset plt_addr)
1768 int stub_idx = -1, plt_idx = -1;
1770 for (unsigned i = 0; i < relocation_table_.size(); ++i) {
1771 if (stub_addr == relocation_table_[i].target_addr())
1773 if (plt_addr == relocation_table_[i].target_addr())
1775 if (stub_idx >= 0 && plt_idx >= 0)
1778 if (stub_idx >= 0 && plt_idx >= 0) {
1779 relocation_table_[stub_idx] = relocation_table_[plt_idx];
1780 relocation_table_[stub_idx].setTargetAddr(stub_addr);
1786 SYMTAB_EXPORT std::vector<std::string> &Symtab::getDependencies(){
1790 SYMTAB_EXPORT Archive *Symtab::getParentArchive() const {
1791 return parentArchive_;
1796 // Doesn't do anything yet, moved here so we don't mess with symtab.h
1797 // Only called if we fail to create a process.
1798 // Or delete the a.out...
1802 for (unsigned i = 0; i < regions_.size(); i++)
1808 codeRegions_.clear();
1809 dataRegions_.clear();
1810 regionsByEntryAddr.clear();
1812 std::vector<Region *> *user_regions = NULL;
1813 getAnnotation(user_regions, UserRegionsAnno);
1817 for (unsigned i = 0; i < user_regions->size(); ++i)
1818 delete (*user_regions)[i];
1819 user_regions->clear();
1822 // Symbols are copied from linkedFile, and NOT deleted
1823 everyDefinedSymbol.clear();
1824 undefDynSyms.clear();
1825 undefDynSymsByMangledName.clear();
1826 undefDynSymsByPrettyName.clear();
1827 undefDynSymsByTypedName.clear();
1829 // TODO make annotation
1830 symsByOffset.clear();
1831 symsByMangledName.clear();
1832 symsByPrettyName.clear();
1833 symsByTypedName.clear();
1835 for (unsigned i = 0; i < everyFunction.size(); i++)
1837 delete everyFunction[i];
1840 everyFunction.clear();
1841 funcsByOffset.clear();
1843 for (unsigned i = 0; i < everyVariable.size(); i++)
1845 delete everyVariable[i];
1848 everyVariable.clear();
1849 varsByOffset.clear();
1851 for (unsigned i = 0; i < _mods.size(); i++)
1856 modsByFileName.clear();
1857 modsByFullName.clear();
1859 for (unsigned i=0;i<excpBlocks.size();i++)
1860 delete excpBlocks[i];
1862 create_printf("%s[%d]: Symtab::~Symtab removing %p from allSymtabs\n",
1863 FILE__, __LINE__, this);
1867 for (unsigned i = 0; i < allSymtabs.size(); i++)
1869 if (allSymtabs[i] == this)
1870 allSymtabs.erase(allSymtabs.begin()+i);
1873 // Make sure to free the underlying Object as it doesn't have a factory
1875 if( obj_private ) delete obj_private;
1877 //fprintf(stderr, "%s[%d]: symtab DTOR, mf = %p: %s\n", FILE__, __LINE__, mf, mf->filename().c_str());
1878 if (mf) MappedFile::closeMappedFile(mf);
1879 //if (mfForDebugInfo) MappedFile::closeMappedFile(mfForDebugInfo);
1883 #if !defined(SERIALIZATION_DISABLED)
1884 bool Symtab::exportXML(string file)
1886 #if defined (cap_serialization)
1889 SerContext<Symtab> *scs = new SerContext<Symtab>(this, file);
1890 serialize(file, scs, ser_xml);
1892 SerContext<Symtab> *scs = new SerContext<Symtab>(this);
1893 SerializerXML *ser = new SerializerXML(scs, "XMLTranslator", file, sd_serialize, true);
1894 serialize(ser, "Symtab");
1897 SerializerXML sb("XMLTranslator", file, sd_serialize, true);
1898 serialize(&sb, "Symtab");
1901 catch (const SerializerError &err)
1903 fprintf(stderr, "%s[%d]: error serializing xml: %s\n", FILE__, __LINE__, err.what());
1909 fprintf(stderr, "%s[%d]: WARNING: cannot produce %s, serialization not available\n", FILE__, __LINE__, file.c_str());
1914 bool Symtab::exportBin(string file)
1918 SerContext<Symtab> *scs = new SerContext<Symtab>(this, file);
1919 serialize(file, scs, ser_bin);
1920 //fprintf(stderr, "%s[%d]: did serialize\n", FILE__, __LINE__);
1924 catch (const SerializerError &err)
1926 if (err.code() == SerializerError::ser_err_disabled)
1928 fprintf(stderr, "%s[%d]: WARN: serialization is disabled for file %s\n",
1929 FILE__, __LINE__, file.c_str());
1933 fprintf(stderr, "%s[%d]: %s\n\tfrom: %s[%d]\n", FILE__, __LINE__,
1934 err.what(), err.file().c_str(), err.line());
1937 fprintf(stderr, "%s[%d]: error doing binary serialization\n", __FILE__, __LINE__);
1941 Symtab *Symtab::importBin(std::string file)
1943 #if defined (cap_serialization)
1944 MappedFile *mf= MappedFile::createMappedFile(file);
1947 fprintf(stderr, "%s[%d]: failed to map file %s\n", FILE__, __LINE__, file.c_str());
1951 Symtab *st = new Symtab(mf);
1955 SerContext<Symtab> *scs = new SerContext<Symtab>(st, file);
1956 if (!st->deserialize(file, scs))
1965 catch (const SerializerError &err)
1967 if (err.code() == SerializerError::ser_err_disabled)
1969 serialize_printf("%s[%d]: WARN: serialization is disabled for file %s\n",
1970 FILE__, __LINE__, file.c_str());
1971 fprintf(stderr, "%s[%d]: WARN: serialization is disabled for file %s\n",
1972 FILE__, __LINE__, file.c_str());
1976 serialize_printf("%s[%d]: %s\n\tfrom: %s[%d]\n", FILE__, __LINE__,
1977 err.what(), err.file().c_str(), err.line());
1978 fprintf(stderr, "%s[%d]: %s\n\tfrom: %s[%d]\n", FILE__, __LINE__,
1979 err.what(), err.file().c_str(), err.line());
1983 serialize_printf("%s[%d]: error doing binary deserialization\n", __FILE__, __LINE__);
1987 serialize_printf("%s[%d]: WARNING: cannot produce %s, serialization not available\n", FILE__, __LINE__, file.c_str());
1993 bool Symtab::exportXML(string)
1998 bool Symtab::exportBin(string)
2003 Symtab *Symtab::importBin(std::string)
2009 bool Symtab::openFile(Symtab *&obj, void *mem_image, size_t size,
2010 std::string name, def_t def_bin)
2013 #if defined(TIMED_PARSE)
2014 struct timeval starttime;
2015 gettimeofday(&starttime, NULL);
2018 obj = new Symtab((unsigned char *) mem_image, size, name, (def_bin == Defensive), err);
2020 #if defined(TIMED_PARSE)
2021 struct timeval endtime;
2022 gettimeofday(&endtime, NULL);
2023 unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
2024 unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
2025 unsigned long difftime = lendtime - lstarttime;
2026 double dursecs = difftime/(1000 );
2027 cout << __FILE__ << ":" << __LINE__ <<": openFile "<< filename<< " took "<<dursecs <<" msecs" << endl;
2031 allSymtabs.push_back(obj);
2038 // returns true on success (not an error)
2042 bool Symtab::closeSymtab(Symtab *st)
2045 if (!st) return false;
2049 std::vector<Symtab *>::reverse_iterator iter;
2050 for (iter = allSymtabs.rbegin(); iter != allSymtabs.rend() ; iter++)
2055 if(0 == st->_ref_cnt) {
2056 allSymtabs.erase(iter.base() -1);
2061 if(0 == st->_ref_cnt)
2066 Symtab *Symtab::findOpenSymtab(std::string filename)
2068 unsigned numSymtabs = allSymtabs.size();
2069 for (unsigned u=0; u<numSymtabs; u++)
2071 assert(allSymtabs[u]);
2072 if (filename == allSymtabs[u]->file() &&
2073 allSymtabs[u]->mf->canBeShared())
2075 allSymtabs[u]->_ref_cnt++;
2077 return allSymtabs[u];
2083 bool Symtab::openFile(Symtab *&obj, std::string filename, def_t def_binary)
2086 #if defined(TIMED_PARSE)
2087 struct timeval starttime;
2088 gettimeofday(&starttime, NULL);
2091 // AIX: it's possible that we're reparsing a file with better information
2092 // about it. If so, yank the old one out of the allSymtabs std::vector -- replace
2094 if ( filename.find("/proc") == std::string::npos)
2096 obj = findOpenSymtab(filename);
2099 //fprintf(stderr, "%s[%d]: have existing symtab obj for %s\n", FILE__, __LINE__, filename.c_str());
2105 #if defined (cap_serialization)
2107 obj = importBin(filename);
2111 if (deserializeEnforced<Symtab>(filename))
2113 serialize_printf("%s[%d]: aborting new symtab, expected deserialize failed\n",
2115 fprintf(stderr, "%s[%d]: aborting new symtab, expected deserialize failed\n",
2119 //fprintf(stderr, "%s[%d]: deserialize failed, but not enforced for %s\n", FILE__, __LINE__, filename.c_str());
2123 //fprintf(stderr, "%s[%d]: deserialize success\n", FILE__, __LINE__);
2129 obj = new Symtab(filename, (def_binary == Defensive), err);
2131 #if defined(TIMED_PARSE)
2132 struct timeval endtime;
2133 gettimeofday(&endtime, NULL);
2134 unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
2135 unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
2136 unsigned long difftime = lendtime - lstarttime;
2137 double dursecs = difftime/(1000 );
2138 cout << __FILE__ << ":" << __LINE__ <<": openFile "<< filename<< " took "<<dursecs <<" msecs" << endl;
2143 if (filename.find("/proc") == std::string::npos)
2144 allSymtabs.push_back(obj);
2147 #if defined (cap_serialization)
2149 serialize_printf("%s[%d]: doing bin-serialize for %s\n",
2150 FILE__, __LINE__, filename.c_str());
2152 if (!obj->exportBin(filename))
2154 serialize_printf("%s[%d]: failed to export symtab\n", FILE__, __LINE__);
2157 serialize_printf("%s[%d]: did bin-serialize for %s\n",
2158 FILE__, __LINE__, filename.c_str());
2165 create_printf("%s[%d]: WARNING: failed to open symtab for %s\n",
2166 FILE__, __LINE__, filename.c_str());
2171 // returns true on success (not an error)
2175 bool Symtab::addRegion(Offset vaddr, void *data, unsigned int dataSize, std::string name,
2176 Region::RegionType rType_, bool loadable, unsigned long memAlign, bool tls)
2182 sec = new Region(newSectionInsertPoint, name, vaddr, dataSize, vaddr,
2183 dataSize, (char *)data, Region::RP_R, rType_, true, tls, memAlign);
2185 regions_.insert(regions_.begin()+newSectionInsertPoint, sec);
2187 for (i = newSectionInsertPoint+1; i < regions_.size(); i++)
2189 regions_[i]->setRegionNumber(regions_[i]->getRegionNumber() + 1);
2192 if ( (sec->getRegionType() == Region::RT_TEXT)
2193 || (sec->getRegionType() == Region::RT_TEXTDATA))
2195 codeRegions_.push_back(sec);
2196 std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
2199 if ( (sec->getRegionType() == Region::RT_DATA)
2200 || (sec->getRegionType() == Region::RT_TEXTDATA))
2202 dataRegions_.push_back(sec);
2203 std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
2208 sec = new Region(regions_.size()+1, name, vaddr, dataSize, 0, 0,
2209 (char *)data, Region::RP_R, rType_, loadable, tls, memAlign);
2210 regions_.push_back(sec);
2214 std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
2218 bool Symtab::addUserRegion(Region *reg)
2220 std::vector<Region *> *user_regions = NULL;
2222 if (!getAnnotation(user_regions, UserRegionsAnno))
2224 user_regions = new std::vector<Region *>();
2225 if (!addAnnotation(user_regions, UserRegionsAnno))
2227 fprintf(stderr, "%s[%d]: failed to addAnnotation here\n", FILE__, __LINE__);
2234 fprintf(stderr, "%s[%d]: failed to addAnnotation here\n", FILE__, __LINE__);
2238 user_regions->push_back(reg);
2243 bool Symtab::addUserType(Type *t)
2245 std::vector<Type *> *user_types = NULL;
2247 // need to change this to something based on AnnotationContainer
2248 // for it to work with serialization
2249 if (!getAnnotation(user_types, UserTypesAnno))
2251 user_types = new std::vector<Type *>();
2252 if (!addAnnotation(user_types, UserTypesAnno))
2254 fprintf(stderr, "%s[%d]: failed to addAnnotation here\n", FILE__, __LINE__);
2260 fprintf(stderr, "%s[%d]: failed to addAnnotation here\n", FILE__, __LINE__);
2264 user_types->push_back(t);
2269 bool Symtab::addRegion(Region *sec)
2271 regions_.push_back(sec);
2272 std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
2277 void Symtab::parseLineInformation()
2279 dyn_hash_map<std::string, LineInformation> *lineInfo = new dyn_hash_map <std::string, LineInformation>;
2282 Object *linkedFile = getObject();
2285 #if !defined(os_vxworks)
2286 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
2290 linkedFile->parseFileLineInfo(this, *lineInfo);
2292 isLineInfoValid_ = true;
2293 dyn_hash_map <std::string, LineInformation>::iterator iter;
2295 for (iter = lineInfo->begin(); iter!=lineInfo->end(); iter++)
2298 bool result = findModuleByName(mod, iter->first);
2300 mod = getDefaultModule();
2303 LineInformation *lineInformation = mod->getLineInformation();
2304 if (!lineInformation)
2306 mod->setLineInfo(&(iter->second));
2310 lineInformation->addLineInfo(&(iter->second));
2311 mod->setLineInfo(lineInformation);
2316 SYMTAB_EXPORT bool Symtab::getAddressRanges(std::vector<pair<Offset, Offset> >&ranges,
2317 std::string lineSource, unsigned int lineNo)
2319 unsigned int originalSize = ranges.size();
2321 /* Iteratate over the modules, looking for ranges in each. */
2323 for ( unsigned int i = 0; i < _mods.size(); i++ )
2325 LineInformation *lineInformation = _mods[i]->getLineInformation();
2327 if (lineInformation)
2328 lineInformation->getAddressRanges( lineSource.c_str(), lineNo, ranges );
2330 } /* end iteration over modules */
2332 if ( ranges.size() != originalSize )
2335 fprintf(stderr, "%s[%d]: failing to getAdressRanges for %s[%d]\n", FILE__, __LINE__, lineSource.c_str(), lineNo);
2339 SYMTAB_EXPORT bool Symtab::getSourceLines(std::vector<Statement *> &lines, Offset addressInRange)
2341 unsigned int originalSize = lines.size();
2343 /* Iteratate over the modules, looking for ranges in each. */
2344 for ( unsigned int i = 0; i < _mods.size(); i++ )
2346 LineInformation *lineInformation = _mods[i]->getLineInformation();
2348 if (lineInformation)
2349 lineInformation->getSourceLines( addressInRange, lines );
2351 } /* end iteration over modules */
2353 if ( lines.size() != originalSize )
2360 SYMTAB_EXPORT bool Symtab::getSourceLines(std::vector<LineNoTuple> &lines, Offset addressInRange)
2362 unsigned int originalSize = lines.size();
2364 /* Iteratate over the modules, looking for ranges in each. */
2365 for ( unsigned int i = 0; i < _mods.size(); i++ )
2367 LineInformation *lineInformation = _mods[i]->getLineInformation();
2369 if (lineInformation)
2370 lineInformation->getSourceLines( addressInRange, lines );
2372 } /* end iteration over modules */
2374 if ( lines.size() != originalSize )
2380 SYMTAB_EXPORT bool Symtab::addLine(std::string lineSource, unsigned int lineNo,
2381 unsigned int lineOffset, Offset lowInclAddr,
2382 Offset highExclAddr)
2386 if (!findModuleByName(mod, lineSource))
2388 std::string fileNm = extract_pathname_tail(lineSource);
2390 if (!findModuleByName(mod, fileNm))
2392 if (!findModuleByName(mod, mf->pathname()))
2397 LineInformation *lineInfo = mod->getLineInformation();
2402 return (lineInfo->addLine(lineSource.c_str(), lineNo, lineOffset,
2403 lowInclAddr, highExclAddr));
2406 SYMTAB_EXPORT bool Symtab::addAddressRange( Offset lowInclusiveAddr, Offset highExclusiveAddr,
2407 std::string lineSource, unsigned int lineNo,
2408 unsigned int lineOffset)
2412 if (!findModuleByName(mod, lineSource))
2414 std::string fileNm = extract_pathname_tail(lineSource);
2416 if (!findModuleByName(mod, fileNm))
2420 LineInformation *lineInfo = mod->getLineInformation();
2425 return (lineInfo->addAddressRange(lowInclusiveAddr, highExclusiveAddr,
2426 lineSource.c_str(), lineNo, lineOffset));
2429 void Symtab::setTruncateLinePaths(bool value)
2431 getObject()->setTruncateLinePaths(value);
2434 bool Symtab::getTruncateLinePaths()
2436 return getObject()->getTruncateLinePaths();
2439 void Symtab::parseTypes()
2441 Object *linkedFile = getObject();
2444 #if !defined(os_vxworks)
2445 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
2449 linkedFile->parseTypeInfo(this);
2450 isTypeInfoValid_ = true;
2452 for (unsigned int i = 0; i < _mods.size(); ++i)
2454 typeCollection *tc = typeCollection::getModTypeCollection(_mods[i]);
2456 if (!_mods[i]->addAnnotation(tc, ModuleTypeInfoAnno))
2458 fprintf(stderr, "%s[%d]: failed to addAnnotation here\n", FILE__, __LINE__);
2462 // optionally we might want to clear the static data struct in typeCollection
2463 // here.... the parsing is over, and we have added all typeCollections as
2464 // annotations proper.
2466 typeCollection::fileToTypesMap.clear();
2470 bool Symtab::addType(Type *type)
2472 bool result = addUserType(type);
2479 SYMTAB_EXPORT vector<Type *> *Symtab::getAllstdTypes()
2481 return stdTypes()->getAllTypes();
2484 SYMTAB_EXPORT vector<Type *> *Symtab::getAllbuiltInTypes()
2486 return builtInTypes()->getAllBuiltInTypes();
2489 SYMTAB_EXPORT bool Symtab::findType(Type *&type, std::string name)
2496 for (unsigned int i = 0; i < _mods.size(); ++i)
2498 typeCollection *tc = _mods[i]->getModuleTypes();
2500 type = tc->findType(name);
2501 if (type) return true;
2510 SYMTAB_EXPORT Type *Symtab::findType(unsigned type_id)
2517 //fprintf(stderr, "%s[%d]: findType failing due to lack of modules\n", FILE__, __LINE__);
2521 for (unsigned int i = 0; i < _mods.size(); ++i)
2523 typeCollection *tc = _mods[i]->getModuleTypes();
2525 t = tc->findType(type_id);
2533 t = builtInTypes()->findBuiltInType(type_id);
2538 //fprintf(stderr, "%s[%d]: no built in types!\n", FILE__, __LINE__);
2543 t = stdTypes()->findType(type_id);
2548 //fprintf(stderr, "%s[%d]: no std types!\n", FILE__, __LINE__);
2557 SYMTAB_EXPORT bool Symtab::findVariableType(Type *&type, std::string name)
2565 for (unsigned int i = 0; i < _mods.size(); ++i)
2567 typeCollection *tc = _mods[i]->getModuleTypes();
2569 type = tc->findVariableType(name);
2579 SYMTAB_EXPORT bool Symtab::findLocalVariable(std::vector<localVar *>&vars, std::string name)
2582 unsigned origSize = vars.size();
2584 for (unsigned i = 0; i < everyFunction.size(); i++)
2586 everyFunction[i]->findLocalVariable(vars, name);
2589 if (vars.size()>origSize)
2595 SYMTAB_EXPORT bool Symtab::hasRel() const
2600 SYMTAB_EXPORT bool Symtab::hasRela() const
2605 SYMTAB_EXPORT bool Symtab::hasReldyn() const
2610 SYMTAB_EXPORT bool Symtab::hasReladyn() const
2615 SYMTAB_EXPORT bool Symtab::hasRelplt() const
2620 SYMTAB_EXPORT bool Symtab::hasRelaplt() const
2625 SYMTAB_EXPORT bool Symtab::isStaticBinary() const
2627 return isStaticBinary_;
2630 bool Symtab::setDefaultNamespacePrefix(string &str)
2632 defaultNamespacePrefix = str;
2636 SYMTAB_EXPORT bool Symtab::emitSymbols(Object *linkedFile,std::string filename, unsigned flag)
2638 // Start with all the defined symbols
2639 std::vector<Symbol *> allSyms;
2640 allSyms.insert(allSyms.end(), everyDefinedSymbol.begin(), everyDefinedSymbol.end());
2642 // Add the undefined dynamic symbols
2643 map<string, std::vector<Symbol *> >::iterator iter;
2644 std::vector<Symbol *>::iterator siter;
2646 allSyms.insert(allSyms.end(), undefDynSyms.begin(), undefDynSyms.end());
2648 // Write the new file
2649 return linkedFile->emitDriver(this, filename, allSyms, flag);
2652 SYMTAB_EXPORT bool Symtab::emit(std::string filename, unsigned flag)
2654 Object *obj = getObject();
2657 #if !defined(os_vxworks)
2658 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
2662 obj->mf->setSharing(false);
2663 return emitSymbols(obj, filename, flag);
2666 SYMTAB_EXPORT void Symtab::addDynLibSubstitution(std::string oldName, std::string newName)
2668 dynLibSubs[oldName] = newName;
2671 SYMTAB_EXPORT std::string Symtab::getDynLibSubstitution(std::string name)
2673 #ifdef BINEDIT_DEBUG
2674 map<std::string, std::string>::iterator iter = dynLibSubs.begin();
2676 printf ("substitutions for %s:\n", mf->filename().c_str());
2678 while (iter != dynLibSubs.end())
2680 printf(" \"%s\" => \"%s\"\n", iter->first.c_str(), iter->second.c_str());
2685 map<std::string, std::string>::iterator loc = dynLibSubs.find(name);
2687 if (loc == dynLibSubs.end())
2693 SYMTAB_EXPORT bool Symtab::getSegments(vector<Segment> &segs) const
2697 if (!segments_.size())
2703 SYMTAB_EXPORT bool Symtab::getMappedRegions(std::vector<Region *> &mappedRegs) const
2705 unsigned origSize = mappedRegs.size();
2707 for (unsigned i = 0; i < regions_.size(); i++)
2709 if (regions_[i]->isLoadable())
2710 mappedRegs.push_back(regions_[i]);
2713 if (mappedRegs.size() > origSize)
2719 SYMTAB_EXPORT bool Symtab::fixup_RegionAddr(const char* name, Offset memOffset, long memSize)
2723 if (!findRegion(sec, name)) {
2727 vector<relocationEntry> relocs;
2728 Object *obj = getObject();
2730 // Fix relocation table with correct memory address
2732 obj->get_func_binding_table(relocs);
2734 fprintf(stderr, "There are %d relocs in this symtab.\n",
2735 relocs.size()); // */
2737 for (unsigned i=0; i < relocs.size(); i++) {
2738 Offset value = relocs[i].rel_addr();
2739 relocs[i].setRelAddr(memOffset + value);
2741 fprintf(stderr, "Fixing reloc from 0x%x to 0x%x\n",
2742 value, memOffset + value); // */
2745 relocation_table_ = relocs;
2747 vector<relocationEntry> &relref = sec->getRelocations();
2748 for (unsigned i=0; i < relref.size(); i++) {
2749 Offset value = relref[i].rel_addr();
2750 relref[i].setRelAddr(memOffset + value);
2752 fprintf(stderr, "Fixing region reloc from 0x%x to 0x%x\n",
2753 value, memOffset + value); // */
2756 #if defined(_MSC_VER)
2757 regionsByEntryAddr.erase(sec->getMemOffset());
2761 fprintf(stderr, "Fixing region %s from 0x%x [0x%x] to 0x%x [0x%x]\n",
2762 name, sec->getMemOffset(), sec->getMemSize(), memOffset,
2764 sec->setMemOffset(memOffset);
2765 sec->setMemSize(memSize);
2767 #if defined(_MSC_VER)
2768 regionsByEntryAddr[sec->getMemOffset()] = sec;
2771 std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
2772 std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
2773 std::sort(regions_.begin(), regions_.end(), sort_reg_by_addr);
2777 SYMTAB_EXPORT bool Symtab::fixup_SymbolAddr(const char* name, Offset newOffset)
2780 if (symsByMangledName.count(name) == 0) return false;
2782 if (symsByMangledName[name].size() != 1)
2783 fprintf(stderr, "*** Found %zu symbols with name %s. Expecting 1.\n",
2784 symsByMangledName[name].size(), name); // */
2785 Symbol *sym = symsByMangledName[name][0];
2788 Offset oldOffset = sym->getOffset();
2789 sym->setOffset(newOffset);
2792 fprintf(stderr, "Fixing symbol %s from 0x%x to 0x%x\n",
2793 name, oldOffset, newOffset); // */
2796 if (symsByOffset.count(oldOffset)) {
2797 std::vector<Symbol *>::iterator iter = symsByOffset[oldOffset].begin();
2798 while (iter != symsByOffset[oldOffset].end()) {
2800 symsByOffset[oldOffset].erase(iter);
2801 iter = symsByOffset[oldOffset].begin();
2806 if (!findSymbolByOffset(newOffset))
2807 symsByOffset[newOffset].push_back(sym);
2809 // Update aggregates.
2810 if (!doNotAggregate(sym)) {
2811 addSymbolToAggregates(sym);
2817 SYMTAB_EXPORT bool Symtab::updateRegion(const char* name, void *buffer, unsigned size)
2821 if (!findRegion(sec, name))
2824 sec->setPtrToRawData(buffer, size);
2829 SYMTAB_EXPORT bool Symtab::updateCode(void *buffer, unsigned size)
2831 return updateRegion(".text", buffer, size);
2834 SYMTAB_EXPORT bool Symtab::updateData(void *buffer, unsigned size)
2836 return updateRegion(".data", buffer, size);
2839 SYMTAB_EXPORT Offset Symtab::getFreeOffset(unsigned size)
2841 // Look through sections until we find a gap with
2842 // sufficient space.
2843 Offset highWaterMark = 0;
2844 Offset secoffset = 0;
2845 Offset prevSecoffset = 0;
2846 Object *linkedFile = getObject();
2849 #if !defined(os_vxworks)
2850 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
2855 for (unsigned i = 0; i < regions_.size(); i++)
2857 Offset end = regions_[i]->getMemOffset() + regions_[i]->getMemSize();
2858 if (regions_[i]->getMemOffset() == 0)
2861 prevSecoffset = secoffset;
2863 unsigned region_offset = (unsigned)((char *)(regions_[i]->getPtrToRawData())
2864 - linkedFile->mem_image());
2866 if (region_offset < (unsigned)prevSecoffset)
2868 secoffset += regions_[i]->getMemSize();
2872 secoffset = (char *)(regions_[i]->getPtrToRawData()) - linkedFile->mem_image();
2873 secoffset += regions_[i]->getMemSize();
2876 /*fprintf(stderr, "%d: secAddr 0x%lx, size %d, end 0x%lx, looking for %d\n",
2877 i, regions_[i]->getRegionAddr(), regions_[i]->getRegionSize(),
2880 if (end > highWaterMark)
2882 //fprintf(stderr, "Increasing highWaterMark...\n");
2883 newSectionInsertPoint = i+1;
2884 highWaterMark = end;
2887 if ( (i < (regions_.size()-2))
2888 && ((end + size) < regions_[i+1]->getMemOffset()))
2890 /* fprintf(stderr, "Found a hole between sections %d and %d\n",
2892 fprintf(stderr, "End at 0x%lx, next one at 0x%lx\n",
2893 end, regions_[i+1]->getRegionAddr());
2895 newSectionInsertPoint = i+1;
2896 highWaterMark = end;
2901 // return highWaterMark;
2902 #if defined (os_windows)
2903 Object *obj = getObject();
2906 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
2909 unsigned pgSize = obj->getSecAlign();
2910 //printf("pgSize:0x%x\n", pgSize);
2911 Offset newaddr = highWaterMark - (highWaterMark & (pgSize-1));
2912 while(newaddr < highWaterMark)
2914 //printf("getfreeoffset:%lu\n", newaddr);
2918 unsigned pgSize = P_getpagesize();
2920 #if defined(os_linux)
2921 // Bluegene compute nodes have a 1MB alignment restructions on PT_LOAD section
2922 Object *obj = getObject();
2925 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
2928 bool isBlueGeneQ = obj->isBlueGeneQ();
2929 bool isBlueGeneP = obj->isBlueGeneP();
2930 bool hasNoteSection = obj->hasNoteSection();
2931 bool isStaticBinary = obj->isStaticBinary();
2932 /* In BlueGeneQ static binary, we extend the existing LOAD section to add Dyninst code and data
2933 In BlueGeneQ dynamic binary, we add a new LOAD section
2934 In BlueGeneP, we replace NOTE section with new LOAD section, else we extend existing LOAD section
2935 If we add a new LOAD section in BlueGene, it needs to be aligned to 1MB
2937 if ((isBlueGeneQ && !isStaticBinary) || (isBlueGeneP && hasNoteSection)) {
2939 } else if( isBlueGeneQ && isStaticBinary ) {
2940 /* UGLY:: The maximum offset from TOC pointer is 0x7fff (15 bits + 1 sign bit).
2941 For static binaries, the TOC pointer must be able to reach the new load segment.
2942 If we align by page size (1MB), the TOC pointer will not be able to reach the new segment.
2943 Since we do not create a new PT_LOAD segment, but rather extend the existing PT_LOAD segment,
2944 we do not need to align by page size.
2945 Note1: 64 bytes is just random number I choose.
2946 Note2: We need to do this only for memory offset and not disk offset as TOC pointer
2947 uses only memory offset */
2953 Offset newaddr = highWaterMark - (highWaterMark & (pgSize-1));
2954 if(newaddr < highWaterMark)
2960 SYMTAB_EXPORT ObjectType Symtab::getObjectType() const
2962 return object_type_;
2965 SYMTAB_EXPORT Dyninst::Architecture Symtab::getArchitecture()
2967 return getObject()->getArch();
2970 SYMTAB_EXPORT char *Symtab::mem_image() const
2972 return (char *)mf->base_addr();
2975 SYMTAB_EXPORT std::string Symtab::file() const
2978 return mf->pathname();
2981 SYMTAB_EXPORT std::string Symtab::name() const
2983 return mf->filename();
2986 SYMTAB_EXPORT std::string Symtab::memberName() const
2988 return member_name_;
2991 SYMTAB_EXPORT unsigned Symtab::getNumberofRegions() const
2993 return no_of_sections;
2996 SYMTAB_EXPORT unsigned Symtab::getNumberofSymbols() const
2998 return no_of_symbols;
3001 bool Symtab::setup_module_up_ptrs(SerializerBase *, Symtab *st)
3003 std::vector<Module *> &mods = st->_mods;
3005 for (unsigned int i = 0; i < mods.size(); ++i)
3007 Module *m = mods[i];
3014 bool Symtab::fixup_relocation_symbols(SerializerBase *, Symtab *st)
3016 std::vector<Module *> &mods = st->_mods;
3018 for (unsigned int i = 0; i < mods.size(); ++i)
3020 Module *m = mods[i];
3027 void Symtab::rebuild_symbol_hashes(SerializerBase *sb)
3032 for (unsigned long i = 0; i < everyDefinedSymbol.size(); ++i)
3034 Symbol *s = everyDefinedSymbol[i];
3036 const std::string &pn = s->getPrettyName();
3037 const std::string &mn = s->getMangledName();
3038 const std::string tn = s->getTypedName();
3040 symsByPrettyName[pn].push_back(s);
3041 symsByMangledName[mn].push_back(s);
3042 symsByTypedName[tn].push_back(s);
3043 symsByOffset[s->getOffset()].push_back(s);
3047 void Symtab::rebuild_funcvar_hashes(SerializerBase *sb)
3051 for (unsigned int i = 0; i < everyFunction.size(); ++i)
3053 Function *f = everyFunction[i];
3054 funcsByOffset[f->getOffset()] = f;
3056 for (unsigned int i = 0; i < everyVariable.size(); ++i)
3058 Variable *v = everyVariable[i];
3059 varsByOffset[v->getOffset()] = v;
3062 void Symtab::rebuild_module_hashes(SerializerBase *sb)
3066 for (unsigned int i = 0; i < _mods.size(); ++i)
3068 Module *m = _mods[i];
3069 modsByFileName[m->fileName()] = m;
3070 modsByFullName[m->fullName()] = m;
3073 void Symtab::rebuild_region_indexes(SerializerBase *sb) THROW_SPEC (SerializerError)
3078 for (unsigned int i = 0; i < regions_.size(); ++i)
3080 Region *r = regions_[i];
3082 if ( r->isLoadable() )
3084 if ((r->getRegionPermissions() == Region::RP_RX)
3085 || (r->getRegionPermissions() == Region::RP_RWX))
3086 codeRegions_.push_back(r);
3088 dataRegions_.push_back(r);
3091 // entry addr might require some special attn on windows, since it
3092 // is not the disk offset but the actual mem addr, which is going to be
3093 // different after deserialize. Probably have to look it up again.
3094 regionsByEntryAddr[r->getMemOffset()] = r;
3097 std::sort(codeRegions_.begin(), codeRegions_.end(), sort_reg_by_addr);
3098 std::sort(dataRegions_.begin(), dataRegions_.end(), sort_reg_by_addr);
3101 #if !defined(SERIALIZATION_DISABLED)
3102 Serializable *Symtab::serialize_impl(SerializerBase *sb,
3103 const char *tag) THROW_SPEC (SerializerError)
3105 serialize_printf("%s[%d]: welcome to Symtab::serialize_impl\n",
3109 // don't bother with serializing standard and builtin types.
3110 /* XXX Change to use safe static allocation and initialization
3111 of standard and builtin types changes serialization behavior:
3112 these types are initialized on first access to the types
3113 structures (no explicit initialization). I think this code
3114 is dead anyway, though, so it probably doesn't matter.
3119 ifxml_start_element(sb, tag);
3120 gtranslate(sb, imageOffset_, "imageOffset");
3121 gtranslate(sb, imageLen_, "imageLen");
3122 gtranslate(sb, dataOffset_, "dataOff");
3123 gtranslate(sb, dataLen_, "dataLen");
3124 gtranslate(sb, is_a_out, "isExec");
3125 gtranslate(sb, _mods, "Modules", "Module");
3126 rebuild_module_hashes(sb);
3129 // problem: if isTypeInfoValid_ is not true, we can trigger type parsing
3130 // for an object class that does not exist. Need to introduce logic to
3131 // recreate the object in this case
3132 isTypeInfoValid_ = true;
3133 isLineInfoValid_ = true; // NOTE: set this to true after deserializing at least one lineInformaton object
3135 gtranslate(sb, regions_, "Regions", "Region");
3136 rebuild_region_indexes(sb);
3137 gtranslate(sb, everyDefinedSymbol, "EveryDefinedSymbol", "Symbol");
3138 rebuild_symbol_hashes(sb);
3139 gtranslate(sb, relocation_table_, "RelocationTable", "RelocationTableEntry");
3140 gtranslate(sb, everyFunction, "EveryFunction", "Function");
3141 gtranslate(sb, everyVariable, "EveryVariable", "Variable");
3142 rebuild_funcvar_hashes(sb);
3144 //gtranslate(sb, everyUniqueVariable, "EveryUniqueVariable", "UniqueVariable");
3145 //gtranslate(sb, modSyms, "ModuleSymbols", "ModuleSymbol");
3147 gtranslate(sb, excpBlocks, "ExceptionBlocks", "ExceptionBlock");
3148 ifxml_end_element(sb, tag);
3150 sb->magic_check(FILE__, __LINE__);
3152 ifinput(Symtab::setup_module_up_ptrs, sb, this);
3153 ifinput(fixup_relocation_symbols, sb, this);
3158 dyn_hash_map<Address, Symbol *> *map_p = NULL;
3159 if (getAnnotation(map_p, IdToSymAnno) && (NULL != map_p))
3161 if (!removeAnnotation(IdToSymAnno))
3163 fprintf(stderr, "%s[%d]: failed to remove id-to-sym map\n",
3169 serialize_printf("%s[%d]: leaving Symtab::serialize_impl\n", FILE__, __LINE__);
3173 Serializable *Symtab::serialize_impl(SerializerBase *, const char *) THROW_SPEC (SerializerError)
3179 SYMTAB_EXPORT LookupInterface::LookupInterface()
3183 SYMTAB_EXPORT LookupInterface::~LookupInterface()
3188 SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(Offset tStart,
3191 : tryStart_(tStart), trySize_(tSize), catchStart_(cStart), hasTry_(true)
3195 SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(Offset cStart)
3196 : tryStart_(0), trySize_(0), catchStart_(cStart), hasTry_(false)
3200 SYMTAB_EXPORT ExceptionBlock::ExceptionBlock(const ExceptionBlock &eb) :
3202 tryStart_(eb.tryStart_), trySize_(eb.trySize_),
3203 catchStart_(eb.catchStart_), hasTry_(eb.hasTry_)
3206 SYMTAB_EXPORT bool ExceptionBlock::hasTry() const
3211 SYMTAB_EXPORT Offset ExceptionBlock::tryStart() const
3216 SYMTAB_EXPORT Offset ExceptionBlock::tryEnd() const
3218 return tryStart_ + trySize_;
3221 SYMTAB_EXPORT Offset ExceptionBlock::trySize() const
3226 SYMTAB_EXPORT bool ExceptionBlock::contains(Offset a) const
3228 return (a >= tryStart_ && a < tryStart_ + trySize_);
3231 #if !defined(SERIALIZATION_DISABLED)
3232 Serializable * ExceptionBlock::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
3234 ifxml_start_element(sb, tag);
3235 gtranslate(sb, tryStart_, "tryStart");
3236 gtranslate(sb, trySize_, "trySize");
3237 gtranslate(sb, catchStart_, "catchStart");
3238 gtranslate(sb, hasTry_, "hasTry");
3239 ifxml_end_element(sb, tag);
3243 Serializable * ExceptionBlock::serialize_impl(SerializerBase *, const char *) THROW_SPEC (SerializerError)
3249 SYMTAB_EXPORT relocationEntry::relocationEntry() :
3253 rtype_(Region::RT_REL),
3260 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ta, Offset ra, std::string n,
3261 Symbol *dynref, unsigned long relType) :
3265 rtype_(Region::RT_REL),
3272 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ta, Offset ra, Offset add,
3273 std::string n, Symbol *dynref, unsigned long relType) :
3277 rtype_(Region::RT_REL),
3284 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ra, std::string n,
3285 Symbol *dynref, unsigned long relType, Region::RegionType rtype) :
3296 SYMTAB_EXPORT relocationEntry::relocationEntry(Offset ta, Offset ra, Offset add,
3297 std::string n, Symbol *dynref, unsigned long relType,
3298 Region::RegionType rtype) :
3308 SYMTAB_EXPORT Offset relocationEntry::target_addr() const
3310 return target_addr_;
3313 SYMTAB_EXPORT void relocationEntry::setTargetAddr(const Offset off)
3318 SYMTAB_EXPORT Offset relocationEntry::rel_addr() const
3323 SYMTAB_EXPORT void relocationEntry::setRelAddr(const Offset value)
3328 SYMTAB_EXPORT const string &relocationEntry::name() const
3333 SYMTAB_EXPORT Symbol *relocationEntry::getDynSym() const
3338 SYMTAB_EXPORT bool relocationEntry::addDynSym(Symbol *dynref)
3344 SYMTAB_EXPORT Region::RegionType relocationEntry::regionType() const
3349 SYMTAB_EXPORT unsigned long relocationEntry::getRelType() const
3354 SYMTAB_EXPORT Offset relocationEntry::addend() const
3359 SYMTAB_EXPORT void relocationEntry::setAddend(const Offset value)
3364 SYMTAB_EXPORT void relocationEntry::setRegionType(const Region::RegionType value)
3369 SYMTAB_EXPORT void relocationEntry::setName(const std::string &newName) {
3373 bool relocationEntry::operator==(const relocationEntry &r) const
3375 if (target_addr_ != r.target_addr_) return false;
3376 if (rel_addr_ != r.rel_addr_) return false;
3377 if (addend_ != r.addend_) return false;
3378 if (rtype_ != r.rtype_) return false;
3379 if (name_ != r.name_) return false;
3380 if (relType_ != r.relType_) return false;
3381 if (dynref_ && !r.dynref_) return false;
3382 if (!dynref_ && r.dynref_) return false;
3385 if (dynref_->getMangledName() != r.dynref_->getMangledName()) return false;
3386 if (dynref_->getOffset() != r.dynref_->getOffset()) return false;
3392 #if !defined(SERIALIZATION_DISABLED)
3393 Serializable *relocationEntry::serialize_impl(SerializerBase *sb, const char *tag) THROW_SPEC (SerializerError)
3395 // on deserialize need to rebuild symtab::undefDynSyms before deserializing relocations
3397 std::string symname = dynref_ ? dynref_->getName() : std::string("");
3398 Offset symoff = dynref_ ? dynref_->getOffset() : (Offset) -1;
3400 ifxml_start_element(sb, tag);
3401 gtranslate(sb, target_addr_, "targetAddress");
3402 gtranslate(sb, rel_addr_, "relocationAddress");
3403 gtranslate(sb, addend_, "Addend");
3404 gtranslate(sb, name_, "relocationName");
3405 gtranslate(sb, rtype_, Region::regionType2Str, "regionType");
3406 gtranslate(sb, relType_, "relocationType");
3407 gtranslate(sb, symname, "SymbolName");
3408 gtranslate(sb, symoff, "SymbolOffset");
3409 ifxml_end_element(sb, tag);
3414 if (symname != std::string(""))
3416 // if we have a name for this symbol, the offset should not be -1;
3417 if (symoff == (Offset) -1)
3419 fprintf(stderr, "%s[%d]: inconsistent symname and offset combo!\n",
3423 SerContextBase *scb = sb->getContext();
3426 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
3430 SerContext<Symtab> *scs = dynamic_cast<SerContext<Symtab> *>(scb);
3434 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
3438 Symtab *st = scs->getScope();
3442 fprintf(stderr, "%s[%d]: SERIOUS: FIXME\n", FILE__, __LINE__);
3446 std::vector<Symbol *> *syms = st->findSymbolByOffset(symoff);
3447 if (!syms || !syms->size())
3449 serialize_printf("%s[%d]: cannot find symbol by offset %p\n",
3450 FILE__, __LINE__, (void *)symoff);
3454 // Might want to try to select the "best" symbol here if there is
3455 // more than one. Or Maybe just returning the first is sufficient.
3457 dynref_ = (*syms)[0];
3463 Serializable *relocationEntry::serialize_impl(SerializerBase *, const char *) THROW_SPEC (SerializerError)
3469 ostream & Dyninst::SymtabAPI::operator<< (ostream &os, const relocationEntry &r)
3471 if( r.getDynSym() != NULL ) {
3472 os << "Name: " << setw(20) << ( "'" + r.getDynSym()->getMangledName() + "'" );
3474 os << "Name: " << setw(20) << r.name();
3476 os << " Offset: " << std::hex << std::setfill('0') << setw(8) << r.rel_addr()
3477 << std::dec << std::setfill(' ')
3478 << " Offset: " << std::hex << std::setfill('0') << setw(8) << r.target_addr()
3479 << std::dec << std::setfill(' ')
3480 << " Addend: " << r.addend()
3481 << " Region: " << Region::regionType2Str(r.regionType())
3482 << " Type: " << setw(15) << relocationEntry::relType2Str(r.getRelType())
3483 << "(" << r.getRelType() << ")";
3484 if( r.getDynSym() != NULL ) {
3485 os << " Symbol Offset: " << std::hex << std::setfill('0') << setw(8) << r.getDynSym()->getOffset();
3486 os << std::setfill(' ');
3487 if( r.getDynSym()->isCommonStorage() ) {
3489 }else if( r.getDynSym()->getRegion() == NULL ) {
3496 const char *Symbol::symbolType2Str(SymbolType t)
3500 CASE_RETURN_STR(ST_UNKNOWN);
3501 CASE_RETURN_STR(ST_FUNCTION);
3502 CASE_RETURN_STR(ST_OBJECT);
3503 CASE_RETURN_STR(ST_MODULE);
3504 CASE_RETURN_STR(ST_SECTION);
3505 CASE_RETURN_STR(ST_TLS);
3506 CASE_RETURN_STR(ST_DELETED);
3507 CASE_RETURN_STR(ST_NOTYPE);
3510 return "invalid symbol type";
3513 const char *Symbol::symbolLinkage2Str(SymbolLinkage t)
3517 CASE_RETURN_STR(SL_UNKNOWN);
3518 CASE_RETURN_STR(SL_GLOBAL);
3519 CASE_RETURN_STR(SL_LOCAL);
3520 CASE_RETURN_STR(SL_WEAK);
3523 return "invalid symbol linkage";
3526 const char *Symbol::symbolTag2Str(SymbolTag t)
3530 CASE_RETURN_STR(TAG_UNKNOWN);
3531 CASE_RETURN_STR(TAG_USER);
3532 CASE_RETURN_STR(TAG_LIBRARY);
3533 CASE_RETURN_STR(TAG_INTERNAL);
3536 return "invalid symbol tag";
3539 const char *Symbol::symbolVisibility2Str(SymbolVisibility t)
3542 CASE_RETURN_STR(SV_UNKNOWN);
3543 CASE_RETURN_STR(SV_DEFAULT);
3544 CASE_RETURN_STR(SV_INTERNAL);
3545 CASE_RETURN_STR(SV_HIDDEN);
3546 CASE_RETURN_STR(SV_PROTECTED);
3548 return "invalid symbol visibility";
3551 bool Symtab::hasStackwalkDebugInfo()
3554 Object *obj = getObject();
3557 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
3560 return obj->hasFrameDebugInfo();
3563 bool Symtab::getRegValueAtFrame(Address pc,
3564 Dyninst::MachRegister reg,
3565 Dyninst::MachRegisterVal ®_result,
3566 MemRegReader *reader)
3568 Object *obj = getObject();
3571 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
3574 return obj->getRegValueAtFrame(pc, reg, reg_result, reader);
3577 Object *Symtab::getObject()
3582 //TODO: This likely triggered because we serialized in an object
3583 // from cache, but now the user is requesting more information from
3584 // the on disk object. We should create a new 'Object' from data
3585 // (likely a file path) serialized in.
3587 fprintf(stderr, "%s[%d]: FIXME: request for object that does not exist!\n", FILE__, __LINE__);
3589 //obj_private = new Object();
3590 //return obj_private;
3593 void Symtab::parseTypesNow()
3595 if (isTypeInfoValid_)
3601 #if defined (cap_serialization)
3602 // Not sure this is strictly necessary, problems only seem to exist with Module
3603 // annotations when the file was split off, so there's probably something else that
3604 // can be done to instantiate the relevant functions.
3606 bool dummy_for_ser_instance(std::string file, SerializerBase *sb)
3608 if (file == std::string("no_such_file"))
3612 fprintf(stderr, "%s[%d]: really should not happen\n", FILE__, __LINE__);
3615 fprintf(stderr, "%s[%d]: WARN: disabled serializer init here\n", FILE__, __LINE__);
3623 namespace SymtabAPI {
3626 #if !defined(SERIALIZATION_DISABLED)
3627 SYMTAB_EXPORT SerializerBase *nonpublic_make_bin_symtab_serializer(Symtab *t, std::string file)
3630 SerContext<Symtab> *scs = new SerContext<Symtab>(t, file);
3631 ser = new SerializerBin(scs, "SerializerBin", file, sd_serialize, false);
3635 SYMTAB_EXPORT SerializerBase *nonpublic_make_bin_symtab_deserializer(Symtab *t, std::string file)
3638 SerContext<Symtab> *scs = new SerContext<Symtab>(t, file);
3639 ser = new SerializerBin(scs, "DeserializerBin", file, sd_deserialize, false);
3643 SYMTAB_EXPORT void nonpublic_free_bin_symtab_serializer(SerializerBase *sb)
3645 SerializerBin *sbin = dynamic_cast<SerializerBin *>(sb);
3651 fprintf(stderr, "%s[%d]: FIXME\n", FILE__, __LINE__);
3656 SYMTAB_EXPORT Offset Symtab::getElfDynamicOffset()
3658 #if defined(os_linux) || defined(os_freebsd)
3659 Object *obj = getObject();
3662 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
3665 return obj->getDynamicAddr();
3671 SYMTAB_EXPORT bool Symtab::removeLibraryDependency(std::string lib)
3673 #if defined(os_aix) || defined(os_windows)
3676 Object *obj = getObject();
3678 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
3681 return obj->removePrereqLibrary(lib);
3685 SYMTAB_EXPORT bool Symtab::addLibraryPrereq(std::string name)
3691 Object *obj = getObject();
3694 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
3697 // remove forward slashes and back slashes
3698 size_t size = name.find_last_of("/");
3699 size_t lastBS = name.find_last_of("\\");
3700 if (lastBS > size) {
3704 string filename = name.substr(size+1);
3706 #if ! defined(os_windows)
3707 obj->insertPrereqLibrary(filename);
3709 // must add a symbol for an exported function belonging to the library
3710 // to get the Windows loader to load the library
3712 Symtab *symtab = Symtab::findOpenSymtab(name);
3714 if (!Symtab::openFile(symtab, name)) {
3719 // find an exported function
3720 vector<Symbol*> funcs;
3721 symtab->getAllSymbolsByType(funcs, Symbol::ST_FUNCTION);
3722 vector<Symbol*>::iterator fit = funcs.begin();
3723 for (; fit != funcs.end() && !(*fit)->isInDynSymtab(); fit++);
3724 if (fit == funcs.end()) {
3728 string funcName = string((*fit)->getPrettyName());
3729 if (funcName.empty()) {
3730 funcName = string((*fit)->getMangledName());
3731 if (funcName.empty()) {
3736 symtab->getObject()->addReference((*fit)->getOffset(),
3739 obj->addReference((*fit)->getOffset(), filename, funcName);
3744 SYMTAB_EXPORT bool Symtab::addSysVDynamic(long name, long value)
3746 #if defined(os_linux) || defined(os_freebsd)
3747 Object *obj = getObject();
3750 fprintf(stderr, "%s[%d]: getObject failed here\n", FILE__, __LINE__);
3753 obj->insertDynamicEntry(name, value);
3760 SYMTAB_EXPORT bool Symtab::addExternalSymbolReference(Symbol *externalSym, Region *localRegion,
3761 relocationEntry localRel)
3763 // Adjust this to the correct value
3764 localRel.setRegionType(getObject()->getRelType());
3766 // Create placeholder Symbol for external Symbol reference
3767 // Bernat, 7SEP2010 - according to Matt, these symbols should have
3768 // type "undefined", which means a region of NULL. Changing
3769 // from "localRegion" to NULL.
3770 Symbol *symRef = new Symbol(externalSym->getMangledName(),
3771 externalSym->getType(),
3776 NULL, // localRegion,
3777 externalSym->getSize(),
3781 if( !addSymbol(symRef, externalSym) ) return false;
3783 localRegion->addRelocationEntry(localRel);
3785 // Make sure the Symtab holding the external symbol gets linked
3787 explicitSymtabRefs_.insert(externalSym->getSymtab());
3792 // on windows we can't specify the trap table's location by adding a dynamic
3793 // symbol as we don on windows
3794 SYMTAB_EXPORT bool Symtab::addTrapHeader_win(Address ptr)
3796 #if defined(os_windows)
3797 getObject()->setTrapHeader(ptr);
3800 ptr = ptr; //keep compiler happy
3806 bool Symtab::getExplicitSymtabRefs(std::set<Symtab *> &refs) {
3807 refs = explicitSymtabRefs_;
3808 return (refs.size() != 0);
3811 SYMTAB_EXPORT bool Symtab::addLinkingResource(Archive *library) {
3812 linkingResources_.push_back(library);
3817 SYMTAB_EXPORT bool Symtab::getLinkingResources(std::vector<Archive *> &libs) {
3818 libs = linkingResources_;
3819 return (linkingResources_.size() != 0);
3822 SYMTAB_EXPORT Address Symtab::getLoadAddress()
3824 #if defined(os_linux) || defined(os_freebsd) || defined(os_aix)
3825 return getObject()->getLoadAddress();
3831 SYMTAB_EXPORT bool Symtab::isDefensiveBinary() const
3833 return isDefensiveBinary_;
3836 SYMTAB_EXPORT bool Symtab::canBeShared()