136 lines · cpp
1//===-- SymbolVendorPECOFF.cpp --------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "SymbolVendorPECOFF.h"10 11#include <cstring>12 13#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"14#include "lldb/Core/Module.h"15#include "lldb/Core/ModuleSpec.h"16#include "lldb/Core/PluginManager.h"17#include "lldb/Core/Section.h"18#include "lldb/Host/Host.h"19#include "lldb/Symbol/ObjectFile.h"20#include "lldb/Target/Target.h"21#include "lldb/Utility/StreamString.h"22#include "lldb/Utility/Timer.h"23 24using namespace lldb;25using namespace lldb_private;26 27LLDB_PLUGIN_DEFINE(SymbolVendorPECOFF)28 29// SymbolVendorPECOFF constructor30SymbolVendorPECOFF::SymbolVendorPECOFF(const lldb::ModuleSP &module_sp)31 : SymbolVendor(module_sp) {}32 33void SymbolVendorPECOFF::Initialize() {34 PluginManager::RegisterPlugin(GetPluginNameStatic(),35 GetPluginDescriptionStatic(), CreateInstance);36}37 38void SymbolVendorPECOFF::Terminate() {39 PluginManager::UnregisterPlugin(CreateInstance);40}41 42llvm::StringRef SymbolVendorPECOFF::GetPluginDescriptionStatic() {43 return "Symbol vendor for PE/COFF that looks for dSYM files that match "44 "executables.";45}46 47// CreateInstance48//49// Platforms can register a callback to use when creating symbol vendors to50// allow for complex debug information file setups, and to also allow for51// finding separate debug information files.52SymbolVendor *53SymbolVendorPECOFF::CreateInstance(const lldb::ModuleSP &module_sp,54 lldb_private::Stream *feedback_strm) {55 if (!module_sp)56 return nullptr;57 58 ObjectFilePECOFF *obj_file =59 llvm::dyn_cast_or_null<ObjectFilePECOFF>(module_sp->GetObjectFile());60 if (!obj_file)61 return nullptr;62 63 lldb_private::UUID uuid = obj_file->GetUUID();64 if (!uuid)65 return nullptr;66 67 // If the main object file already contains debug info, then we are done.68 if (obj_file->GetSectionList()->FindSectionByType(69 lldb::eSectionTypeDWARFDebugInfo, true))70 return nullptr;71 72 // If the module specified a filespec, use that.73 FileSpec fspec = module_sp->GetSymbolFileFileSpec();74 // Otherwise, try gnu_debuglink, if one exists.75 if (!fspec)76 fspec = obj_file->GetDebugLink().value_or(FileSpec());77 78 LLDB_SCOPED_TIMERF("SymbolVendorPECOFF::CreateInstance (module = %s)",79 module_sp->GetFileSpec().GetPath().c_str());80 81 ModuleSpec module_spec;82 83 module_spec.GetFileSpec() = obj_file->GetFileSpec();84 FileSystem::Instance().Resolve(module_spec.GetFileSpec());85 module_spec.GetSymbolFileSpec() = fspec;86 module_spec.GetUUID() = uuid;87 FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();88 FileSpec dsym_fspec = PluginManager::LocateExecutableSymbolFile(89 module_spec, search_paths, module_sp->GetSymbolLocatorStatistics());90 if (!dsym_fspec)91 return nullptr;92 93 DataBufferSP dsym_file_data_sp;94 lldb::offset_t dsym_file_data_offset = 0;95 ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(96 module_sp, &dsym_fspec, 0, FileSystem::Instance().GetByteSize(dsym_fspec),97 dsym_file_data_sp, dsym_file_data_offset);98 if (!dsym_objfile_sp)99 return nullptr;100 101 // This objfile is for debugging purposes.102 dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);103 104 // Get the module unified section list and add our debug sections to105 // that.106 SectionList *module_section_list = module_sp->GetSectionList();107 SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();108 if (!objfile_section_list || !module_section_list)109 return nullptr;110 111 static const SectionType g_sections[] = {112 eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAranges,113 eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo,114 eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLoc,115 eSectionTypeDWARFDebugLocLists, eSectionTypeDWARFDebugMacInfo,116 eSectionTypeDWARFDebugNames, eSectionTypeDWARFDebugPubNames,117 eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges,118 eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugTypes,119 };120 for (SectionType section_type : g_sections) {121 if (SectionSP section_sp =122 objfile_section_list->FindSectionByType(section_type, true)) {123 if (SectionSP module_section_sp =124 module_section_list->FindSectionByType(section_type, true))125 module_section_list->ReplaceSection(module_section_sp->GetID(),126 section_sp);127 else128 module_section_list->AddSection(section_sp);129 }130 }131 132 SymbolVendorPECOFF *symbol_vendor = new SymbolVendorPECOFF(module_sp);133 symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);134 return symbol_vendor;135}136