addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() { addr_t virt_entry; if (m_load_offset != LLDB_INVALID_ADDRESS) return m_load_offset; if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS) return LLDB_INVALID_ADDRESS; ModuleSP module = m_process->GetTarget().GetExecutableModule(); if (!module) return LLDB_INVALID_ADDRESS; ObjectFile *exe = module->GetObjectFile(); if (!exe) return LLDB_INVALID_ADDRESS; Address file_entry = exe->GetEntryPointAddress(); if (!file_entry.IsValid()) return LLDB_INVALID_ADDRESS; m_load_offset = virt_entry - file_entry.GetFileAddress(); return m_load_offset; }
bool SymbolContext::GetAddressRange (uint32_t scope, AddressRange &range) const { if ((scope & eSymbolContextLineEntry) && line_entry.IsValid()) { range = line_entry.range; return true; } else if ((scope & eSymbolContextFunction) && function != NULL) { range = function->GetAddressRange(); return true; } else if ((scope & eSymbolContextSymbol) && symbol != NULL && symbol->GetAddressRangePtr()) { range = *symbol->GetAddressRangePtr(); if (range.GetByteSize() == 0) { if (module_sp) { ObjectFile *objfile = module_sp->GetObjectFile(); if (objfile) { Symtab *symtab = objfile->GetSymtab(); if (symtab) range.SetByteSize(symtab->CalculateSymbolSize (symbol)); } } } return true; } range.Clear(); return false; }
// Find the load address of a symbol static lldb::addr_t findSymbolAddress( Process *proc, ConstString findName ) { assert( proc != nullptr ); ModuleSP module = proc->GetTarget().GetExecutableModule(); assert( module.get() != nullptr ); ObjectFile *exe = module->GetObjectFile(); assert( exe != nullptr ); lldb_private::Symtab *symtab = exe->GetSymtab( ); assert( symtab != nullptr ); for ( size_t i = 0; i < symtab->GetNumSymbols( ); i++ ) { const Symbol* sym = symtab->SymbolAtIndex( i ); assert( sym != nullptr ); const ConstString &symName = sym->GetName( ); if ( ConstString::Compare( findName, symName ) == 0 ) { Address addr = sym->GetAddress(); return addr.GetLoadAddress( & proc->GetTarget() ); } } return LLDB_INVALID_ADDRESS; }
ClangASTContext & Module::GetClangASTContext () { Mutex::Locker locker (m_mutex); if (m_did_init_ast == false) { ObjectFile * objfile = GetObjectFile(); ArchSpec object_arch; if (objfile && objfile->GetArchitecture(object_arch)) { m_did_init_ast = true; // LLVM wants this to be set to iOS or MacOSX; if we're working on // a bare-boards type image, change the triple for llvm's benefit. if (object_arch.GetTriple().getVendor() == llvm::Triple::Apple && object_arch.GetTriple().getOS() == llvm::Triple::UnknownOS) { if (object_arch.GetTriple().getArch() == llvm::Triple::arm || object_arch.GetTriple().getArch() == llvm::Triple::thumb) { object_arch.GetTriple().setOS(llvm::Triple::IOS); } else { object_arch.GetTriple().setOS(llvm::Triple::MacOSX); } } m_ast.SetArchitecture (object_arch); } } return m_ast; }
Builder::Builder( vector<string> &objFilePath,string lib,string output ) { libDirPath_ = lib; outputPath_ = output; entryFunc_ = "mini_crt_entry"; myEntryFuncObj_ = lib + "/entry.o"; objFilePath.push_back(myEntryFuncObj_); for( unsigned int i = 0;i < objFilePath.size();++i ) { //这些变量在后面都会以指针形式被保存下来,所以不能用局部变亮 ObjectFile *pObj = new ObjectFile( objFilePath[i] ); if( !pObj->IsValid() ) { cout << objFilePath[i] << " is invalid. * Ignore *" << endl; continue; } ElfHeader *pEh = new ElfHeader; pEh->GetHeader( *pObj ); Section *pSec = new Section(); if( !pSec->GetSection(*pEh) ) { cout << "error while getting section:" << objFilePath[i] << endl; exit(0); } if( !pSec->GetSymbol() ) { cout << "error while getting symbols:" << objFilePath[i] << endl; exit(0); } rawSection_.push_back(pSec); } }
//---------------------------------------------------------------------- // FindPlugin // // Platforms can register a callback to use when creating symbol // vendors to allow for complex debug information file setups, and to // also allow for finding separate debug information files. //---------------------------------------------------------------------- SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm) { std::unique_ptr<SymbolVendor> instance_ap; SymbolVendorCreateInstance create_callback; for (size_t idx = 0; (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex( idx)) != nullptr; ++idx) { instance_ap.reset(create_callback(module_sp, feedback_strm)); if (instance_ap.get()) { return instance_ap.release(); } } // The default implementation just tries to create debug information using the // file representation for the module. instance_ap.reset(new SymbolVendor(module_sp)); if (instance_ap.get()) { ObjectFile *objfile = module_sp->GetObjectFile(); if (objfile) instance_ap->AddSymbolFileRepresentation(objfile->shared_from_this()); } return instance_ap.release(); }
bool Module::SetLoadAddress (Target &target, lldb::addr_t offset, bool &changed) { size_t num_loaded_sections = 0; ObjectFile *objfile = GetObjectFile(); if (objfile) { SectionList *section_list = objfile->GetSectionList (); if (section_list) { const size_t num_sections = section_list->GetSize(); size_t sect_idx = 0; for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) { // Iterate through the object file sections to find the // first section that starts of file offset zero and that // has bytes in the file... SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx)); // Only load non-thread specific sections when given a slide if (section_sp && !section_sp->IsThreadSpecific()) { if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + offset)) ++num_loaded_sections; } } } } changed = num_loaded_sections > 0; return num_loaded_sections > 0; }
//---------------------------------------------------------------------- // FindPlugin // // Platforms can register a callback to use when creating symbol // vendors to allow for complex debug information file setups, and to // also allow for finding separate debug information files. //---------------------------------------------------------------------- SymbolVendor* SymbolVendor::FindPlugin (Module* module) { std::auto_ptr<SymbolVendor> instance_ap; //---------------------------------------------------------------------- // We currently only have one debug symbol parser... //---------------------------------------------------------------------- SymbolVendorCreateInstance create_callback; for (uint32_t idx = 0; (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex(idx)) != NULL; ++idx) { instance_ap.reset(create_callback(module)); if (instance_ap.get()) { // TODO: make sure this symbol vendor is what we want. We // currently are just returning the first one we find, but // we may want to call this function only when we have our // main executable module and then give all symbol vendor // plug-ins a chance to compete for who wins. return instance_ap.release(); } } // The default implementation just tries to create debug information using the // file representation for the module. instance_ap.reset(new SymbolVendor(module)); if (instance_ap.get()) { ObjectFile *objfile = module->GetObjectFile(); if (objfile) instance_ap->AddSymbolFileRepresentation(objfile->GetSP()); } return instance_ap.release(); }
SBSection SBModule::FindSection (const char *sect_name) { SBSection sb_section; ModuleSP module_sp (GetSP ()); if (sect_name && module_sp) { ObjectFile *objfile = module_sp->GetObjectFile(); if (objfile) { SectionList *section_list = objfile->GetSectionList(); if (section_list) { ConstString const_sect_name(sect_name); SectionSP section_sp (section_list->FindSectionByName(const_sect_name)); if (section_sp) { sb_section.SetSP (section_sp); } } } } return sb_section; }
void Module::Dump(Stream *s) { Mutex::Locker locker (m_mutex); //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); s->Indent(); s->Printf("Module %s/%s%s%s%s\n", m_file.GetDirectory().AsCString(), m_file.GetFilename().AsCString(), m_object_name ? "(" : "", m_object_name ? m_object_name.GetCString() : "", m_object_name ? ")" : ""); s->IndentMore(); ObjectFile *objfile = GetObjectFile (); if (objfile) objfile->Dump(s); SymbolVendor *symbols = GetSymbolVendor (); if (symbols) symbols->Dump(s); s->IndentLess(); }
size_t Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list) { // No need to protect this call using m_mutex all other method calls are // already thread safe. Timer scoped_timer(__PRETTY_FUNCTION__, "Module::FindSymbolsWithNameAndType (name = %s, type = %i)", name.AsCString(), symbol_type); const size_t initial_size = sc_list.GetSize(); ObjectFile *objfile = GetObjectFile (); if (objfile) { Symtab *symtab = objfile->GetSymtab(); if (symtab) { std::vector<uint32_t> symbol_indexes; symtab->FindAllSymbolsWithNameAndType (name, symbol_type, symbol_indexes); SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list); } } return sc_list.GetSize() - initial_size; }
//------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ enum ObjCRuntimeVersions AppleObjCRuntime::GetObjCVersion (Process *process, ModuleSP &objc_module_sp) { ModuleList &images = process->GetTarget().GetImages(); size_t num_images = images.GetSize(); for (size_t i = 0; i < num_images; i++) { ModuleSP module_sp = images.GetModuleAtIndex(i); if (AppleIsModuleObjCLibrary (module_sp)) { objc_module_sp = module_sp; ObjectFile *ofile = module_sp->GetObjectFile(); if (!ofile) return eObjC_VersionUnknown; SectionList *sections = ofile->GetSectionList(); if (!sections) return eObjC_VersionUnknown; SectionSP v1_telltale_section_sp = sections->FindSectionByName(ConstString ("__OBJC")); if (v1_telltale_section_sp) { return eAppleObjC_V1; } return eAppleObjC_V2; } } return eObjC_VersionUnknown; }
// compute stub buffer size for the given section unsigned RuntimeDyldImpl::computeSectionStubBufSize(const ObjectFile &Obj, const SectionRef &Section) { unsigned StubSize = getMaxStubSize(); if (StubSize == 0) { return 0; } // FIXME: this is an inefficient way to handle this. We should computed the // necessary section allocation size in loadObject by walking all the sections // once. unsigned StubBufSize = 0; for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end(); SI != SE; ++SI) { section_iterator RelSecI = SI->getRelocatedSection(); if (!(RelSecI == Section)) continue; for (const RelocationRef &Reloc : SI->relocations()) { (void)Reloc; StubBufSize += StubSize; } } // Get section data size and alignment uint64_t DataSize = Section.getSize(); uint64_t Alignment64 = Section.getAlignment(); // Add stubbuf size alignment unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; unsigned StubAlignment = getStubAlignment(); unsigned EndAlignment = (DataSize | Alignment) & -(DataSize | Alignment); if (StubAlignment > EndAlignment) StubBufSize += StubAlignment - EndAlignment; return StubBufSize; }
static error_code dumpObject(const ObjectFile &Obj) { if (Obj.isCOFF()) return coff2yaml(outs(), cast<COFFObjectFile>(Obj)); if (Obj.isELF()) return elf2yaml(outs(), Obj); return obj2yaml_error::unsupported_obj_file_format; }
// Delete an object bool OSToken::deleteObject(OSObject* object) { if (!valid) return false; if (objects.find(object) == objects.end()) { ERROR_MSG("Cannot delete non-existent object 0x%08X", object); return false; } MutexLocker lock(tokenMutex); ObjectFile* fileObject = dynamic_cast<ObjectFile*>(object); if (fileObject == NULL) { ERROR_MSG("Object type not compatible with this token class 0x%08X", object); return false; } // Invalidate the object instance fileObject->invalidate(); // Retrieve the filename of the object std::string objectFilename = fileObject->getFilename(); // Attempt to delete the file if (!tokenDir->remove(objectFilename)) { ERROR_MSG("Failed to delete object file %s", objectFilename.c_str()); return false; } // Retrieve the filename of the lock std::string lockFilename = fileObject->getLockname(); // Attempt to delete the lock if (!tokenDir->remove(lockFilename)) { ERROR_MSG("Failed to delete lock file %s", lockFilename.c_str()); return false; } objects.erase(object); DEBUG_MSG("Deleted object %s", objectFilename.c_str()); gen->update(); gen->commit(); return true; }
bool Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr) { Mutex::Locker locker (m_mutex); Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%llx)", vm_addr); ObjectFile* ofile = GetObjectFile(); if (ofile) return so_addr.ResolveAddressUsingFileSections(vm_addr, ofile->GetSectionList()); return false; }
void SymbolVendor::ClearSymtab() { ModuleSP module_sp(GetModule()); if (module_sp) { ObjectFile *objfile = module_sp->GetObjectFile(); if (objfile) { // Clear symbol table from unified section list. objfile->ClearSymtab(); } } }
std::vector<section> read(const ObjectFile& obj) { int size = utils::distance(obj.begin_sections(), obj.end_sections()); std::vector<section> sections; sections.reserve(size); std::transform(obj.begin_sections(), obj.end_sections(), std::back_inserter(sections), [](const SectionRef& s) { return section(s); }); return sections; }
std::vector<symbol> read(const ObjectFile& obj) { int size = utils::distance(obj.begin_symbols(), obj.end_symbols()); std::vector<symbol> symbols; symbols.reserve(size); read(obj.begin_symbols(), obj.end_symbols(), std::back_inserter(symbols)); return symbols; }
Symtab *SymbolVendor::GetSymtab() { ModuleSP module_sp(GetModule()); if (module_sp) { ObjectFile *objfile = module_sp->GetObjectFile(); if (objfile) { // Get symbol table from unified section list. return objfile->GetSymtab(); } } return nullptr; }
uint32_t Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) { Mutex::Locker locker (m_mutex); uint32_t resolved_flags = 0; // Clear the result symbol context in case we don't find anything sc.Clear(); // Get the section from the section/offset address. const Section *section = so_addr.GetSection(); // Make sure the section matches this module before we try and match anything if (section && section->GetModule() == this) { // If the section offset based address resolved itself, then this // is the right module. sc.module_sp = GetSP(); resolved_flags |= eSymbolContextModule; // Resolve the compile unit, function, block, line table or line // entry if requested. if (resolve_scope & eSymbolContextCompUnit || resolve_scope & eSymbolContextFunction || resolve_scope & eSymbolContextBlock || resolve_scope & eSymbolContextLineEntry ) { SymbolVendor *symbols = GetSymbolVendor (); if (symbols) resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc); } // Resolve the symbol if requested, but don't re-look it up if we've already found it. if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol)) { ObjectFile* ofile = GetObjectFile(); if (ofile) { Symtab *symtab = ofile->GetSymtab(); if (symtab) { if (so_addr.IsSectionOffset()) { sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress()); if (sc.symbol) resolved_flags |= eSymbolContextSymbol; } } } } } return resolved_flags; }
uint64_t SBSection::GetFileOffset() { SectionSP section_sp(GetSP()); if (section_sp) { ModuleSP module_sp(section_sp->GetModule()); if (module_sp) { ObjectFile *objfile = module_sp->GetObjectFile(); if (objfile) return objfile->GetFileOffset() + section_sp->GetFileOffset(); } } return UINT64_MAX; }
ErrorOr<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { for (const SectionRef &Sec : Obj.sections()) { if (Sec.isBitcode()) { StringRef SecContents; if (std::error_code EC = Sec.getContents(SecContents)) return EC; return MemoryBufferRef(SecContents, Obj.getFileName()); } } return object_error::bitcode_section_not_found; }
void test_desobj() { ErrorOr<ObjectFile *> objfile = ObjectFile::createObjectFile("/usr/lib/libQtCore.so"); ObjectFile *pobj = objfile.get(); qDebug()<<"heheho"<<pobj->getFileFormatName().data(); int i = 0; DynamicLibrary dlib = DynamicLibrary::getPermanentLibrary("/usr/lib/libQt5Core.so"); qDebug()<<dlib.isValid(); void *addr = dlib.SearchForAddressOfSymbol("_ZN7QString4chopEi"); qDebug()<<"addr:"<<addr; }
//---------------------------------------------------------------------- // SymbolVendor constructor //---------------------------------------------------------------------- SymbolVendor::SymbolVendor(Module *module) : ModuleChild(module), m_mutex (Mutex::eMutexTypeRecursive), m_type_list(), m_compile_units(), m_sym_file_ap() { ObjectFile * objfile = module->GetObjectFile(); ConstString target_triple; if (objfile && objfile->GetTargetTriple(target_triple)) { m_type_list.GetClangASTContext().SetTargetTriple (target_triple.AsCString()); } }
Expected<MemoryBufferRef> IRObjectFile::findBitcodeInObject(const ObjectFile &Obj) { for (const SectionRef &Sec : Obj.sections()) { if (Sec.isBitcode()) { StringRef SecContents; if (std::error_code EC = Sec.getContents(SecContents)) return errorCodeToError(EC); if (SecContents.size() <= 1) return errorCodeToError(object_error::bitcode_section_not_found); return MemoryBufferRef(SecContents, Obj.getFileName()); } } return errorCodeToError(object_error::bitcode_section_not_found); }
ClangASTContext & Module::GetClangASTContext () { Mutex::Locker locker (m_mutex); if (m_did_init_ast == false) { ObjectFile * objfile = GetObjectFile(); ArchSpec object_arch; if (objfile && objfile->GetArchitecture(object_arch)) { m_did_init_ast = true; m_ast.SetArchitecture (object_arch); } } return m_ast; }
const Symbol * Module::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type) { Timer scoped_timer(__PRETTY_FUNCTION__, "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)", name.AsCString(), symbol_type); ObjectFile *objfile = GetObjectFile(); if (objfile) { Symtab *symtab = objfile->GetSymtab(); if (symtab) return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny); } return NULL; }
void RuntimeDyldMachOCRTPBase<Impl>::finalizeLoad(const ObjectFile &Obj, ObjSectionToIDMap &SectionMap) { unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID; unsigned TextSID = RTDYLD_INVALID_SECTION_ID; unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID; for (const auto &Section : Obj.sections()) { StringRef Name; Section.getName(Name); // Force emission of the __text, __eh_frame, and __gcc_except_tab sections // if they're present. Otherwise call down to the impl to handle other // sections that have already been emitted. if (Name == "__text") TextSID = findOrEmitSection(Obj, Section, true, SectionMap); else if (Name == "__eh_frame") EHFrameSID = findOrEmitSection(Obj, Section, false, SectionMap); else if (Name == "__gcc_except_tab") ExceptTabSID = findOrEmitSection(Obj, Section, true, SectionMap); else { auto I = SectionMap.find(Section); if (I != SectionMap.end()) impl().finalizeSection(Obj, I->second, Section); } } UnregisteredEHFrameSections.push_back( EHFrameRelatedSections(EHFrameSID, TextSID, ExceptTabSID)); }
// This function is where all the optimizations of link-time // optimization happens. When LTO is in use, some input files are // not in native object file format but in the LLVM bitcode format. // This function compiles bitcode files into a few big native files // using LLVM functions and replaces bitcode symbols with the results. // Because all bitcode files that consist of a program are passed // to the compiler at once, it can do whole-program optimization. template <class ELFT> void SymbolTable<ELFT>::addCombinedLTOObject() { if (BitcodeFiles.empty()) return; // Compile bitcode files and replace bitcode symbols. LTO.reset(new BitcodeCompiler); for (BitcodeFile *F : BitcodeFiles) LTO->add<ELFT>(*F); for (InputFile *File : LTO->compile()) { ObjectFile<ELFT> *Obj = cast<ObjectFile<ELFT>>(File); DenseSet<CachedHashStringRef> DummyGroups; Obj->parse(DummyGroups); ObjectFiles.push_back(Obj); } }