181ad6265SDimitry Andric //===-- SymbolVendorPECOFF.cpp --------------------------------------------===//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric
981ad6265SDimitry Andric #include "SymbolVendorPECOFF.h"
1081ad6265SDimitry Andric
1181ad6265SDimitry Andric #include <cstring>
1281ad6265SDimitry Andric
1381ad6265SDimitry Andric #include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
1481ad6265SDimitry Andric #include "lldb/Core/Module.h"
1581ad6265SDimitry Andric #include "lldb/Core/ModuleSpec.h"
1681ad6265SDimitry Andric #include "lldb/Core/PluginManager.h"
1781ad6265SDimitry Andric #include "lldb/Core/Section.h"
1881ad6265SDimitry Andric #include "lldb/Host/Host.h"
1981ad6265SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
2081ad6265SDimitry Andric #include "lldb/Target/Target.h"
2181ad6265SDimitry Andric #include "lldb/Utility/StreamString.h"
2281ad6265SDimitry Andric #include "lldb/Utility/Timer.h"
2381ad6265SDimitry Andric
2481ad6265SDimitry Andric using namespace lldb;
2581ad6265SDimitry Andric using namespace lldb_private;
2681ad6265SDimitry Andric
LLDB_PLUGIN_DEFINE(SymbolVendorPECOFF)2781ad6265SDimitry Andric LLDB_PLUGIN_DEFINE(SymbolVendorPECOFF)
2881ad6265SDimitry Andric
2981ad6265SDimitry Andric // SymbolVendorPECOFF constructor
3081ad6265SDimitry Andric SymbolVendorPECOFF::SymbolVendorPECOFF(const lldb::ModuleSP &module_sp)
3181ad6265SDimitry Andric : SymbolVendor(module_sp) {}
3281ad6265SDimitry Andric
Initialize()3381ad6265SDimitry Andric void SymbolVendorPECOFF::Initialize() {
3481ad6265SDimitry Andric PluginManager::RegisterPlugin(GetPluginNameStatic(),
3581ad6265SDimitry Andric GetPluginDescriptionStatic(), CreateInstance);
3681ad6265SDimitry Andric }
3781ad6265SDimitry Andric
Terminate()3881ad6265SDimitry Andric void SymbolVendorPECOFF::Terminate() {
3981ad6265SDimitry Andric PluginManager::UnregisterPlugin(CreateInstance);
4081ad6265SDimitry Andric }
4181ad6265SDimitry Andric
GetPluginDescriptionStatic()4281ad6265SDimitry Andric llvm::StringRef SymbolVendorPECOFF::GetPluginDescriptionStatic() {
4381ad6265SDimitry Andric return "Symbol vendor for PE/COFF that looks for dSYM files that match "
4481ad6265SDimitry Andric "executables.";
4581ad6265SDimitry Andric }
4681ad6265SDimitry Andric
4781ad6265SDimitry Andric // CreateInstance
4881ad6265SDimitry Andric //
4981ad6265SDimitry Andric // Platforms can register a callback to use when creating symbol vendors to
5081ad6265SDimitry Andric // allow for complex debug information file setups, and to also allow for
5181ad6265SDimitry Andric // finding separate debug information files.
5281ad6265SDimitry Andric SymbolVendor *
CreateInstance(const lldb::ModuleSP & module_sp,lldb_private::Stream * feedback_strm)5381ad6265SDimitry Andric SymbolVendorPECOFF::CreateInstance(const lldb::ModuleSP &module_sp,
5481ad6265SDimitry Andric lldb_private::Stream *feedback_strm) {
5581ad6265SDimitry Andric if (!module_sp)
5681ad6265SDimitry Andric return nullptr;
5781ad6265SDimitry Andric
5881ad6265SDimitry Andric ObjectFilePECOFF *obj_file =
5981ad6265SDimitry Andric llvm::dyn_cast_or_null<ObjectFilePECOFF>(module_sp->GetObjectFile());
6081ad6265SDimitry Andric if (!obj_file)
6181ad6265SDimitry Andric return nullptr;
6281ad6265SDimitry Andric
6381ad6265SDimitry Andric lldb_private::UUID uuid = obj_file->GetUUID();
6481ad6265SDimitry Andric if (!uuid)
6581ad6265SDimitry Andric return nullptr;
6681ad6265SDimitry Andric
6781ad6265SDimitry Andric // If the main object file already contains debug info, then we are done.
6881ad6265SDimitry Andric if (obj_file->GetSectionList()->FindSectionByType(
6981ad6265SDimitry Andric lldb::eSectionTypeDWARFDebugInfo, true))
7081ad6265SDimitry Andric return nullptr;
7181ad6265SDimitry Andric
7281ad6265SDimitry Andric // If the module specified a filespec, use that.
7381ad6265SDimitry Andric FileSpec fspec = module_sp->GetSymbolFileFileSpec();
7481ad6265SDimitry Andric // Otherwise, try gnu_debuglink, if one exists.
7581ad6265SDimitry Andric if (!fspec)
7681ad6265SDimitry Andric fspec = obj_file->GetDebugLink().value_or(FileSpec());
7781ad6265SDimitry Andric
7881ad6265SDimitry Andric LLDB_SCOPED_TIMERF("SymbolVendorPECOFF::CreateInstance (module = %s)",
7981ad6265SDimitry Andric module_sp->GetFileSpec().GetPath().c_str());
8081ad6265SDimitry Andric
8181ad6265SDimitry Andric ModuleSpec module_spec;
8281ad6265SDimitry Andric
8381ad6265SDimitry Andric module_spec.GetFileSpec() = obj_file->GetFileSpec();
8481ad6265SDimitry Andric FileSystem::Instance().Resolve(module_spec.GetFileSpec());
8581ad6265SDimitry Andric module_spec.GetSymbolFileSpec() = fspec;
8681ad6265SDimitry Andric module_spec.GetUUID() = uuid;
8781ad6265SDimitry Andric FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
8881ad6265SDimitry Andric FileSpec dsym_fspec =
89*5f757f3fSDimitry Andric PluginManager::LocateExecutableSymbolFile(module_spec, search_paths);
9081ad6265SDimitry Andric if (!dsym_fspec)
9181ad6265SDimitry Andric return nullptr;
9281ad6265SDimitry Andric
9381ad6265SDimitry Andric DataBufferSP dsym_file_data_sp;
9481ad6265SDimitry Andric lldb::offset_t dsym_file_data_offset = 0;
9581ad6265SDimitry Andric ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(
9681ad6265SDimitry Andric module_sp, &dsym_fspec, 0, FileSystem::Instance().GetByteSize(dsym_fspec),
9781ad6265SDimitry Andric dsym_file_data_sp, dsym_file_data_offset);
9881ad6265SDimitry Andric if (!dsym_objfile_sp)
9981ad6265SDimitry Andric return nullptr;
10081ad6265SDimitry Andric
10181ad6265SDimitry Andric // This objfile is for debugging purposes.
10281ad6265SDimitry Andric dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
10381ad6265SDimitry Andric
10481ad6265SDimitry Andric // Get the module unified section list and add our debug sections to
10581ad6265SDimitry Andric // that.
10681ad6265SDimitry Andric SectionList *module_section_list = module_sp->GetSectionList();
10781ad6265SDimitry Andric SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
10881ad6265SDimitry Andric if (!objfile_section_list || !module_section_list)
10981ad6265SDimitry Andric return nullptr;
11081ad6265SDimitry Andric
11181ad6265SDimitry Andric static const SectionType g_sections[] = {
11281ad6265SDimitry Andric eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAranges,
11381ad6265SDimitry Andric eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo,
11481ad6265SDimitry Andric eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLoc,
11581ad6265SDimitry Andric eSectionTypeDWARFDebugLocLists, eSectionTypeDWARFDebugMacInfo,
11681ad6265SDimitry Andric eSectionTypeDWARFDebugNames, eSectionTypeDWARFDebugPubNames,
11781ad6265SDimitry Andric eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges,
11881ad6265SDimitry Andric eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugTypes,
11981ad6265SDimitry Andric };
12081ad6265SDimitry Andric for (SectionType section_type : g_sections) {
12181ad6265SDimitry Andric if (SectionSP section_sp =
12281ad6265SDimitry Andric objfile_section_list->FindSectionByType(section_type, true)) {
12381ad6265SDimitry Andric if (SectionSP module_section_sp =
12481ad6265SDimitry Andric module_section_list->FindSectionByType(section_type, true))
12581ad6265SDimitry Andric module_section_list->ReplaceSection(module_section_sp->GetID(),
12681ad6265SDimitry Andric section_sp);
12781ad6265SDimitry Andric else
12881ad6265SDimitry Andric module_section_list->AddSection(section_sp);
12981ad6265SDimitry Andric }
13081ad6265SDimitry Andric }
13181ad6265SDimitry Andric
132bdd1243dSDimitry Andric SymbolVendorPECOFF *symbol_vendor = new SymbolVendorPECOFF(module_sp);
13381ad6265SDimitry Andric symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
13481ad6265SDimitry Andric return symbol_vendor;
13581ad6265SDimitry Andric }
136