1349cc55cSDimitry Andric //===-- ObjectFileMinidump.cpp --------------------------------------------===// 2349cc55cSDimitry Andric // 3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6349cc55cSDimitry Andric // 7349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 8349cc55cSDimitry Andric 9349cc55cSDimitry Andric #include "ObjectFileMinidump.h" 10349cc55cSDimitry Andric 11349cc55cSDimitry Andric #include "MinidumpFileBuilder.h" 12349cc55cSDimitry Andric 13349cc55cSDimitry Andric #include "lldb/Core/ModuleSpec.h" 14349cc55cSDimitry Andric #include "lldb/Core/PluginManager.h" 15349cc55cSDimitry Andric #include "lldb/Core/Section.h" 16349cc55cSDimitry Andric #include "lldb/Target/Process.h" 17*0fca6ea1SDimitry Andric #include "lldb/Utility/LLDBLog.h" 18*0fca6ea1SDimitry Andric #include "lldb/Utility/Log.h" 19349cc55cSDimitry Andric 20349cc55cSDimitry Andric #include "llvm/Support/FileSystem.h" 21349cc55cSDimitry Andric 22349cc55cSDimitry Andric using namespace lldb; 23349cc55cSDimitry Andric using namespace lldb_private; 24349cc55cSDimitry Andric 25349cc55cSDimitry Andric LLDB_PLUGIN_DEFINE(ObjectFileMinidump) 26349cc55cSDimitry Andric 27349cc55cSDimitry Andric void ObjectFileMinidump::Initialize() { 28349cc55cSDimitry Andric PluginManager::RegisterPlugin( 29349cc55cSDimitry Andric GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, 30349cc55cSDimitry Andric CreateMemoryInstance, GetModuleSpecifications, SaveCore); 31349cc55cSDimitry Andric } 32349cc55cSDimitry Andric 33349cc55cSDimitry Andric void ObjectFileMinidump::Terminate() { 34349cc55cSDimitry Andric PluginManager::UnregisterPlugin(CreateInstance); 35349cc55cSDimitry Andric } 36349cc55cSDimitry Andric 37349cc55cSDimitry Andric ObjectFile *ObjectFileMinidump::CreateInstance( 3881ad6265SDimitry Andric const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, 39349cc55cSDimitry Andric lldb::offset_t data_offset, const lldb_private::FileSpec *file, 40349cc55cSDimitry Andric lldb::offset_t offset, lldb::offset_t length) { 41349cc55cSDimitry Andric return nullptr; 42349cc55cSDimitry Andric } 43349cc55cSDimitry Andric 44349cc55cSDimitry Andric ObjectFile *ObjectFileMinidump::CreateMemoryInstance( 4581ad6265SDimitry Andric const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp, 46349cc55cSDimitry Andric const ProcessSP &process_sp, lldb::addr_t header_addr) { 47349cc55cSDimitry Andric return nullptr; 48349cc55cSDimitry Andric } 49349cc55cSDimitry Andric 50349cc55cSDimitry Andric size_t ObjectFileMinidump::GetModuleSpecifications( 51349cc55cSDimitry Andric const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, 52349cc55cSDimitry Andric lldb::offset_t data_offset, lldb::offset_t file_offset, 53349cc55cSDimitry Andric lldb::offset_t length, lldb_private::ModuleSpecList &specs) { 54349cc55cSDimitry Andric specs.Clear(); 55349cc55cSDimitry Andric return 0; 56349cc55cSDimitry Andric } 57349cc55cSDimitry Andric 58349cc55cSDimitry Andric bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp, 59*0fca6ea1SDimitry Andric const lldb_private::SaveCoreOptions &options, 60349cc55cSDimitry Andric lldb_private::Status &error) { 61*0fca6ea1SDimitry Andric // Output file and process_sp are both checked in PluginManager::SaveCore. 62*0fca6ea1SDimitry Andric assert(options.GetOutputFile().has_value()); 63*0fca6ea1SDimitry Andric assert(process_sp); 64*0fca6ea1SDimitry Andric 65*0fca6ea1SDimitry Andric // Minidump defaults to stacks only. 66*0fca6ea1SDimitry Andric SaveCoreStyle core_style = options.GetStyle(); 675f757f3fSDimitry Andric if (core_style == SaveCoreStyle::eSaveCoreUnspecified) 685f757f3fSDimitry Andric core_style = SaveCoreStyle::eSaveCoreStackOnly; 69349cc55cSDimitry Andric 70349cc55cSDimitry Andric llvm::Expected<lldb::FileUP> maybe_core_file = FileSystem::Instance().Open( 71*0fca6ea1SDimitry Andric options.GetOutputFile().value(), 72*0fca6ea1SDimitry Andric File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate); 73349cc55cSDimitry Andric if (!maybe_core_file) { 74349cc55cSDimitry Andric error = maybe_core_file.takeError(); 75349cc55cSDimitry Andric return false; 76349cc55cSDimitry Andric } 77*0fca6ea1SDimitry Andric MinidumpFileBuilder builder(std::move(maybe_core_file.get()), process_sp); 78349cc55cSDimitry Andric 79*0fca6ea1SDimitry Andric Log *log = GetLog(LLDBLog::Object); 80*0fca6ea1SDimitry Andric error = builder.AddHeaderAndCalculateDirectories(); 81*0fca6ea1SDimitry Andric if (error.Fail()) { 82*0fca6ea1SDimitry Andric LLDB_LOGF(log, "AddHeaderAndCalculateDirectories failed: %s", 83*0fca6ea1SDimitry Andric error.AsCString()); 84349cc55cSDimitry Andric return false; 85*0fca6ea1SDimitry Andric }; 86*0fca6ea1SDimitry Andric error = builder.AddSystemInfo(); 87*0fca6ea1SDimitry Andric if (error.Fail()) { 88*0fca6ea1SDimitry Andric LLDB_LOGF(log, "AddSystemInfo failed: %s", error.AsCString()); 89*0fca6ea1SDimitry Andric return false; 90*0fca6ea1SDimitry Andric } 91*0fca6ea1SDimitry Andric 92*0fca6ea1SDimitry Andric error = builder.AddModuleList(); 93*0fca6ea1SDimitry Andric if (error.Fail()) { 94*0fca6ea1SDimitry Andric LLDB_LOGF(log, "AddModuleList failed: %s", error.AsCString()); 95*0fca6ea1SDimitry Andric return false; 96*0fca6ea1SDimitry Andric } 97*0fca6ea1SDimitry Andric error = builder.AddMiscInfo(); 98*0fca6ea1SDimitry Andric if (error.Fail()) { 99*0fca6ea1SDimitry Andric LLDB_LOGF(log, "AddMiscInfo failed: %s", error.AsCString()); 100*0fca6ea1SDimitry Andric return false; 101*0fca6ea1SDimitry Andric } 102*0fca6ea1SDimitry Andric 103*0fca6ea1SDimitry Andric error = builder.AddThreadList(); 104*0fca6ea1SDimitry Andric if (error.Fail()) { 105*0fca6ea1SDimitry Andric LLDB_LOGF(log, "AddThreadList failed: %s", error.AsCString()); 106*0fca6ea1SDimitry Andric return false; 107*0fca6ea1SDimitry Andric } 108*0fca6ea1SDimitry Andric 109*0fca6ea1SDimitry Andric error = builder.AddLinuxFileStreams(); 110*0fca6ea1SDimitry Andric if (error.Fail()) { 111*0fca6ea1SDimitry Andric LLDB_LOGF(log, "AddLinuxFileStreams failed: %s", error.AsCString()); 112*0fca6ea1SDimitry Andric return false; 113*0fca6ea1SDimitry Andric } 114*0fca6ea1SDimitry Andric 115*0fca6ea1SDimitry Andric // Add any exceptions but only if there are any in any threads. 116*0fca6ea1SDimitry Andric error = builder.AddExceptions(); 117*0fca6ea1SDimitry Andric if (error.Fail()) { 118*0fca6ea1SDimitry Andric LLDB_LOGF(log, "AddExceptions failed: %s", error.AsCString()); 119*0fca6ea1SDimitry Andric return false; 120*0fca6ea1SDimitry Andric } 121*0fca6ea1SDimitry Andric 122*0fca6ea1SDimitry Andric // Note: add memory HAS to be the last thing we do. It can overflow into 64b 123*0fca6ea1SDimitry Andric // land and many RVA's only support 32b 124*0fca6ea1SDimitry Andric error = builder.AddMemoryList(core_style); 125*0fca6ea1SDimitry Andric if (error.Fail()) { 126*0fca6ea1SDimitry Andric LLDB_LOGF(log, "AddMemoryList failed: %s", error.AsCString()); 127*0fca6ea1SDimitry Andric return false; 128*0fca6ea1SDimitry Andric } 129*0fca6ea1SDimitry Andric 130*0fca6ea1SDimitry Andric error = builder.DumpFile(); 131*0fca6ea1SDimitry Andric if (error.Fail()) { 132*0fca6ea1SDimitry Andric LLDB_LOGF(log, "DumpFile failed: %s", error.AsCString()); 133*0fca6ea1SDimitry Andric return false; 134*0fca6ea1SDimitry Andric } 135349cc55cSDimitry Andric 136349cc55cSDimitry Andric return true; 137349cc55cSDimitry Andric } 138