+void ModuleInfo::addSymbol(const SymbolRef &Symbol, uint64_t SymbolSize,
+ DataExtractor *OpdExtractor, uint64_t OpdAddress) {
+ SymbolRef::Type SymbolType = Symbol.getType();
+ if (SymbolType != SymbolRef::ST_Function && SymbolType != SymbolRef::ST_Data)
+ return;
+ ErrorOr<uint64_t> SymbolAddressOrErr = Symbol.getAddress();
+ if (error(SymbolAddressOrErr.getError()))
+ return;
+ uint64_t SymbolAddress = *SymbolAddressOrErr;
+ if (OpdExtractor) {
+ // For big-endian PowerPC64 ELF, symbols in the .opd section refer to
+ // function descriptors. The first word of the descriptor is a pointer to
+ // the function's code.
+ // For the purposes of symbolization, pretend the symbol's address is that
+ // of the function's code, not the descriptor.
+ uint64_t OpdOffset = SymbolAddress - OpdAddress;
+ uint32_t OpdOffset32 = OpdOffset;
+ if (OpdOffset == OpdOffset32 &&
+ OpdExtractor->isValidOffsetForAddress(OpdOffset32))
+ SymbolAddress = OpdExtractor->getAddress(&OpdOffset32);
+ }
+ ErrorOr<StringRef> SymbolNameOrErr = Symbol.getName();
+ if (error(SymbolNameOrErr.getError()))
+ return;
+ StringRef SymbolName = *SymbolNameOrErr;
+ // Mach-O symbol table names have leading underscore, skip it.
+ if (Module->isMachO() && SymbolName.size() > 0 && SymbolName[0] == '_')
+ SymbolName = SymbolName.drop_front();
+ // FIXME: If a function has alias, there are two entries in symbol table
+ // with same address size. Make sure we choose the correct one.
+ auto &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects;
+ SymbolDesc SD = { SymbolAddress, SymbolSize };
+ M.insert(std::make_pair(SD, SymbolName));
+}
+
+// Return true if this is a 32-bit x86 PE COFF module.
+bool ModuleInfo::isWin32Module() const {
+ auto *CoffObject = dyn_cast<COFFObjectFile>(Module);
+ return CoffObject && CoffObject->getMachine() == COFF::IMAGE_FILE_MACHINE_I386;
+}
+
+uint64_t ModuleInfo::getModulePreferredBase() const {
+ if (auto *CoffObject = dyn_cast<COFFObjectFile>(Module))
+ return CoffObject->getImageBase();
+ return 0;
+}
+