[lldb] Set COFF module ABI from default triple and make it an option
PE/COFF can use either MSVC or GNU (MinGW) ABI for C++ code, however LLDB had defaulted to MSVC implicitly with no way to override it. This causes issues when debugging modules built with the GNU ABI, sometimes even crashes. This changes the PE/COFF plugin to set the module triple according to the default target triple used to build LLDB. If the default target triple is Windows and a valid environment is specified, then this environment will be used for the module spec. This not only works for MSVC and GNU, but also other environments. A new setting, `plugin.object-file.pe-coff.abi`, has been added to allow overriding this default ABI. * Fixes https://github.com/llvm/llvm-project/issues/50775 * Fixes https://github.com/mstorsjo/llvm-mingw/issues/226 * Fixes https://github.com/mstorsjo/llvm-mingw/issues/282 Reviewed By: omjavaid Differential Revision: https://reviews.llvm.org/D127048
This commit is contained in:
committed by
Martin Storsjö
parent
56d68e8d7a
commit
25c8a061c5
@@ -16,6 +16,7 @@
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Core/Section.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Interpreter/OptionValueProperties.h"
|
||||
#include "lldb/Symbol/ObjectFile.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
@@ -33,6 +34,7 @@
|
||||
#include "llvm/Object/COFFImportFile.h"
|
||||
#include "llvm/Support/CRC.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
|
||||
#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
|
||||
@@ -45,6 +47,59 @@ using namespace lldb_private;
|
||||
|
||||
LLDB_PLUGIN_DEFINE(ObjectFilePECOFF)
|
||||
|
||||
namespace {
|
||||
|
||||
static constexpr OptionEnumValueElement g_abi_enums[] = {
|
||||
{
|
||||
llvm::Triple::UnknownEnvironment,
|
||||
"default",
|
||||
"Use default target (if it is Windows) or MSVC",
|
||||
},
|
||||
{
|
||||
llvm::Triple::MSVC,
|
||||
"msvc",
|
||||
"MSVC ABI",
|
||||
},
|
||||
{
|
||||
llvm::Triple::GNU,
|
||||
"gnu",
|
||||
"MinGW / Itanium ABI",
|
||||
},
|
||||
};
|
||||
|
||||
#define LLDB_PROPERTIES_objectfilepecoff
|
||||
#include "ObjectFilePECOFFProperties.inc"
|
||||
|
||||
enum {
|
||||
#define LLDB_PROPERTIES_objectfilepecoff
|
||||
#include "ObjectFilePECOFFPropertiesEnum.inc"
|
||||
};
|
||||
|
||||
class PluginProperties : public Properties {
|
||||
public:
|
||||
static ConstString GetSettingName() {
|
||||
return ConstString(ObjectFilePECOFF::GetPluginNameStatic());
|
||||
}
|
||||
|
||||
PluginProperties() {
|
||||
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
|
||||
m_collection_sp->Initialize(g_objectfilepecoff_properties);
|
||||
}
|
||||
|
||||
llvm::Triple::EnvironmentType ABI() const {
|
||||
return (llvm::Triple::EnvironmentType)
|
||||
m_collection_sp->GetPropertyAtIndexAsEnumeration(
|
||||
nullptr, ePropertyABI, llvm::Triple::UnknownEnvironment);
|
||||
}
|
||||
};
|
||||
|
||||
static PluginProperties &GetGlobalPluginProperties() {
|
||||
static PluginProperties g_settings;
|
||||
return g_settings;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
static bool GetDebugLinkContents(const llvm::object::COFFObjectFile &coff_obj,
|
||||
std::string &gnu_debuglink_file,
|
||||
uint32_t &gnu_debuglink_crc) {
|
||||
@@ -115,9 +170,21 @@ static UUID GetCoffUUID(llvm::object::COFFObjectFile &coff_obj) {
|
||||
char ObjectFilePECOFF::ID;
|
||||
|
||||
void ObjectFilePECOFF::Initialize() {
|
||||
PluginManager::RegisterPlugin(
|
||||
GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
|
||||
CreateMemoryInstance, GetModuleSpecifications, SaveCore);
|
||||
PluginManager::RegisterPlugin(GetPluginNameStatic(),
|
||||
GetPluginDescriptionStatic(), CreateInstance,
|
||||
CreateMemoryInstance, GetModuleSpecifications,
|
||||
SaveCore, DebuggerInitialize);
|
||||
}
|
||||
|
||||
void ObjectFilePECOFF::DebuggerInitialize(Debugger &debugger) {
|
||||
if (!PluginManager::GetSettingForObjectFilePlugin(
|
||||
debugger, PluginProperties::GetSettingName())) {
|
||||
const bool is_global_setting = true;
|
||||
PluginManager::CreateSettingForObjectFilePlugin(
|
||||
debugger, GetGlobalPluginProperties().GetValueProperties(),
|
||||
ConstString("Properties for the PE/COFF object-file plug-in."),
|
||||
is_global_setting);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectFilePECOFF::Terminate() {
|
||||
@@ -207,23 +274,41 @@ size_t ObjectFilePECOFF::GetModuleSpecifications(
|
||||
if (!uuid.IsValid())
|
||||
uuid = GetCoffUUID(*COFFObj);
|
||||
|
||||
static llvm::Triple::EnvironmentType default_env = [] {
|
||||
auto def_target = llvm::Triple(
|
||||
llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()));
|
||||
if (def_target.getOS() == llvm::Triple::Win32 &&
|
||||
def_target.getEnvironment() != llvm::Triple::UnknownEnvironment)
|
||||
return def_target.getEnvironment();
|
||||
return llvm::Triple::MSVC;
|
||||
}();
|
||||
|
||||
llvm::Triple::EnvironmentType env = GetGlobalPluginProperties().ABI();
|
||||
if (env == llvm::Triple::UnknownEnvironment)
|
||||
env = default_env;
|
||||
|
||||
switch (COFFObj->getMachine()) {
|
||||
case MachineAmd64:
|
||||
spec.SetTriple("x86_64-pc-windows");
|
||||
spec.GetTriple().setEnvironment(env);
|
||||
specs.Append(module_spec);
|
||||
break;
|
||||
case MachineX86:
|
||||
spec.SetTriple("i386-pc-windows");
|
||||
spec.GetTriple().setEnvironment(env);
|
||||
specs.Append(module_spec);
|
||||
spec.SetTriple("i686-pc-windows");
|
||||
spec.GetTriple().setEnvironment(env);
|
||||
specs.Append(module_spec);
|
||||
break;
|
||||
case MachineArmNt:
|
||||
spec.SetTriple("armv7-pc-windows");
|
||||
spec.GetTriple().setEnvironment(env);
|
||||
specs.Append(module_spec);
|
||||
break;
|
||||
case MachineArm64:
|
||||
spec.SetTriple("aarch64-pc-windows");
|
||||
spec.GetTriple().setEnvironment(env);
|
||||
specs.Append(module_spec);
|
||||
break;
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user