Skip to content

Commit 25c8a06

Browse files
alvinhochunmstorsjo
authored andcommitted
[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 llvm#50775 * Fixes mstorsjo/llvm-mingw#226 * Fixes mstorsjo/llvm-mingw#282 Reviewed By: omjavaid Differential Revision: https://reviews.llvm.org/D127048
1 parent 56d68e8 commit 25c8a06

13 files changed

+285
-12
lines changed

lldb/include/lldb/Core/PluginManager.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ class PluginManager {
174174
ObjectFileCreateInstance create_callback,
175175
ObjectFileCreateMemoryInstance create_memory_callback,
176176
ObjectFileGetModuleSpecifications get_module_specifications,
177-
ObjectFileSaveCore save_core = nullptr);
177+
ObjectFileSaveCore save_core = nullptr,
178+
DebuggerInitializeCallback debugger_init_callback = nullptr);
178179

179180
static bool UnregisterPlugin(ObjectFileCreateInstance create_callback);
180181

@@ -482,6 +483,13 @@ class PluginManager {
482483
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
483484
ConstString description, bool is_global_property);
484485

486+
static lldb::OptionValuePropertiesSP
487+
GetSettingForObjectFilePlugin(Debugger &debugger, ConstString setting_name);
488+
489+
static bool CreateSettingForObjectFilePlugin(
490+
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
491+
ConstString description, bool is_global_property);
492+
485493
static lldb::OptionValuePropertiesSP
486494
GetSettingForSymbolFilePlugin(Debugger &debugger, ConstString setting_name);
487495

lldb/source/Core/PluginManager.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -621,9 +621,10 @@ struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> {
621621
CallbackType create_callback,
622622
ObjectFileCreateMemoryInstance create_memory_callback,
623623
ObjectFileGetModuleSpecifications get_module_specifications,
624-
ObjectFileSaveCore save_core)
625-
: PluginInstance<ObjectFileCreateInstance>(name, description,
626-
create_callback),
624+
ObjectFileSaveCore save_core,
625+
DebuggerInitializeCallback debugger_init_callback)
626+
: PluginInstance<ObjectFileCreateInstance>(
627+
name, description, create_callback, debugger_init_callback),
627628
create_memory_callback(create_memory_callback),
628629
get_module_specifications(get_module_specifications),
629630
save_core(save_core) {}
@@ -644,10 +645,11 @@ bool PluginManager::RegisterPlugin(
644645
ObjectFileCreateInstance create_callback,
645646
ObjectFileCreateMemoryInstance create_memory_callback,
646647
ObjectFileGetModuleSpecifications get_module_specifications,
647-
ObjectFileSaveCore save_core) {
648+
ObjectFileSaveCore save_core,
649+
DebuggerInitializeCallback debugger_init_callback) {
648650
return GetObjectFileInstances().RegisterPlugin(
649651
name, description, create_callback, create_memory_callback,
650-
get_module_specifications, save_core);
652+
get_module_specifications, save_core, debugger_init_callback);
651653
}
652654

653655
bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
@@ -1364,6 +1366,7 @@ LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
13641366
void PluginManager::DebuggerInitialize(Debugger &debugger) {
13651367
GetDynamicLoaderInstances().PerformDebuggerCallback(debugger);
13661368
GetJITLoaderInstances().PerformDebuggerCallback(debugger);
1369+
GetObjectFileInstances().PerformDebuggerCallback(debugger);
13671370
GetPlatformInstances().PerformDebuggerCallback(debugger);
13681371
GetProcessInstances().PerformDebuggerCallback(debugger);
13691372
GetSymbolFileInstances().PerformDebuggerCallback(debugger);
@@ -1490,6 +1493,7 @@ CreateSettingForPlugin(Debugger &debugger, ConstString plugin_type_name,
14901493
static const char *kDynamicLoaderPluginName("dynamic-loader");
14911494
static const char *kPlatformPluginName("platform");
14921495
static const char *kProcessPluginName("process");
1496+
static const char *kObjectFilePluginName("object-file");
14931497
static const char *kSymbolFilePluginName("symbol-file");
14941498
static const char *kJITLoaderPluginName("jit-loader");
14951499
static const char *kStructuredDataPluginName("structured-data");
@@ -1542,6 +1546,22 @@ bool PluginManager::CreateSettingForProcessPlugin(
15421546
properties_sp, description, is_global_property);
15431547
}
15441548

1549+
lldb::OptionValuePropertiesSP
1550+
PluginManager::GetSettingForObjectFilePlugin(Debugger &debugger,
1551+
ConstString setting_name) {
1552+
return GetSettingForPlugin(debugger, setting_name,
1553+
ConstString(kObjectFilePluginName));
1554+
}
1555+
1556+
bool PluginManager::CreateSettingForObjectFilePlugin(
1557+
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1558+
ConstString description, bool is_global_property) {
1559+
return CreateSettingForPlugin(
1560+
debugger, ConstString(kObjectFilePluginName),
1561+
ConstString("Settings for object file plug-ins"), properties_sp,
1562+
description, is_global_property);
1563+
}
1564+
15451565
lldb::OptionValuePropertiesSP
15461566
PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
15471567
ConstString setting_name) {

lldb/source/Plugins/ObjectFile/PECOFF/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ else()
55
set(DBGHELP_LINK_FILES "")
66
endif()
77

8+
lldb_tablegen(ObjectFilePECOFFProperties.inc -gen-lldb-property-defs
9+
SOURCE ObjectFilePECOFFProperties.td
10+
TARGET LLDBPluginObjectFilePECOFFPropertiesGen)
11+
12+
lldb_tablegen(ObjectFilePECOFFPropertiesEnum.inc -gen-lldb-property-enum-defs
13+
SOURCE ObjectFilePECOFFProperties.td
14+
TARGET LLDBPluginObjectFilePECOFFPropertiesEnumGen)
15+
816
add_lldb_library(lldbPluginObjectFilePECOFF PLUGIN
917
ObjectFilePECOFF.cpp
1018
PECallFrameInfo.cpp
@@ -20,3 +28,7 @@ add_lldb_library(lldbPluginObjectFilePECOFF PLUGIN
2028
BinaryFormat
2129
Support
2230
)
31+
32+
add_dependencies(lldbPluginObjectFilePECOFF
33+
LLDBPluginObjectFilePECOFFPropertiesGen
34+
LLDBPluginObjectFilePECOFFPropertiesEnumGen)

lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "lldb/Core/PluginManager.h"
1717
#include "lldb/Core/Section.h"
1818
#include "lldb/Core/StreamFile.h"
19+
#include "lldb/Interpreter/OptionValueProperties.h"
1920
#include "lldb/Symbol/ObjectFile.h"
2021
#include "lldb/Target/Process.h"
2122
#include "lldb/Target/SectionLoadList.h"
@@ -33,6 +34,7 @@
3334
#include "llvm/Object/COFFImportFile.h"
3435
#include "llvm/Support/CRC.h"
3536
#include "llvm/Support/Error.h"
37+
#include "llvm/Support/Host.h"
3638
#include "llvm/Support/MemoryBuffer.h"
3739

3840
#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
@@ -45,6 +47,59 @@ using namespace lldb_private;
4547

4648
LLDB_PLUGIN_DEFINE(ObjectFilePECOFF)
4749

50+
namespace {
51+
52+
static constexpr OptionEnumValueElement g_abi_enums[] = {
53+
{
54+
llvm::Triple::UnknownEnvironment,
55+
"default",
56+
"Use default target (if it is Windows) or MSVC",
57+
},
58+
{
59+
llvm::Triple::MSVC,
60+
"msvc",
61+
"MSVC ABI",
62+
},
63+
{
64+
llvm::Triple::GNU,
65+
"gnu",
66+
"MinGW / Itanium ABI",
67+
},
68+
};
69+
70+
#define LLDB_PROPERTIES_objectfilepecoff
71+
#include "ObjectFilePECOFFProperties.inc"
72+
73+
enum {
74+
#define LLDB_PROPERTIES_objectfilepecoff
75+
#include "ObjectFilePECOFFPropertiesEnum.inc"
76+
};
77+
78+
class PluginProperties : public Properties {
79+
public:
80+
static ConstString GetSettingName() {
81+
return ConstString(ObjectFilePECOFF::GetPluginNameStatic());
82+
}
83+
84+
PluginProperties() {
85+
m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
86+
m_collection_sp->Initialize(g_objectfilepecoff_properties);
87+
}
88+
89+
llvm::Triple::EnvironmentType ABI() const {
90+
return (llvm::Triple::EnvironmentType)
91+
m_collection_sp->GetPropertyAtIndexAsEnumeration(
92+
nullptr, ePropertyABI, llvm::Triple::UnknownEnvironment);
93+
}
94+
};
95+
96+
static PluginProperties &GetGlobalPluginProperties() {
97+
static PluginProperties g_settings;
98+
return g_settings;
99+
}
100+
101+
} // namespace
102+
48103
static bool GetDebugLinkContents(const llvm::object::COFFObjectFile &coff_obj,
49104
std::string &gnu_debuglink_file,
50105
uint32_t &gnu_debuglink_crc) {
@@ -115,9 +170,21 @@ static UUID GetCoffUUID(llvm::object::COFFObjectFile &coff_obj) {
115170
char ObjectFilePECOFF::ID;
116171

117172
void ObjectFilePECOFF::Initialize() {
118-
PluginManager::RegisterPlugin(
119-
GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
120-
CreateMemoryInstance, GetModuleSpecifications, SaveCore);
173+
PluginManager::RegisterPlugin(GetPluginNameStatic(),
174+
GetPluginDescriptionStatic(), CreateInstance,
175+
CreateMemoryInstance, GetModuleSpecifications,
176+
SaveCore, DebuggerInitialize);
177+
}
178+
179+
void ObjectFilePECOFF::DebuggerInitialize(Debugger &debugger) {
180+
if (!PluginManager::GetSettingForObjectFilePlugin(
181+
debugger, PluginProperties::GetSettingName())) {
182+
const bool is_global_setting = true;
183+
PluginManager::CreateSettingForObjectFilePlugin(
184+
debugger, GetGlobalPluginProperties().GetValueProperties(),
185+
ConstString("Properties for the PE/COFF object-file plug-in."),
186+
is_global_setting);
187+
}
121188
}
122189

123190
void ObjectFilePECOFF::Terminate() {
@@ -207,23 +274,41 @@ size_t ObjectFilePECOFF::GetModuleSpecifications(
207274
if (!uuid.IsValid())
208275
uuid = GetCoffUUID(*COFFObj);
209276

277+
static llvm::Triple::EnvironmentType default_env = [] {
278+
auto def_target = llvm::Triple(
279+
llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()));
280+
if (def_target.getOS() == llvm::Triple::Win32 &&
281+
def_target.getEnvironment() != llvm::Triple::UnknownEnvironment)
282+
return def_target.getEnvironment();
283+
return llvm::Triple::MSVC;
284+
}();
285+
286+
llvm::Triple::EnvironmentType env = GetGlobalPluginProperties().ABI();
287+
if (env == llvm::Triple::UnknownEnvironment)
288+
env = default_env;
289+
210290
switch (COFFObj->getMachine()) {
211291
case MachineAmd64:
212292
spec.SetTriple("x86_64-pc-windows");
293+
spec.GetTriple().setEnvironment(env);
213294
specs.Append(module_spec);
214295
break;
215296
case MachineX86:
216297
spec.SetTriple("i386-pc-windows");
298+
spec.GetTriple().setEnvironment(env);
217299
specs.Append(module_spec);
218300
spec.SetTriple("i686-pc-windows");
301+
spec.GetTriple().setEnvironment(env);
219302
specs.Append(module_spec);
220303
break;
221304
case MachineArmNt:
222305
spec.SetTriple("armv7-pc-windows");
306+
spec.GetTriple().setEnvironment(env);
223307
specs.Append(module_spec);
224308
break;
225309
case MachineArm64:
226310
spec.SetTriple("aarch64-pc-windows");
311+
spec.GetTriple().setEnvironment(env);
227312
specs.Append(module_spec);
228313
break;
229314
default:

lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ class ObjectFilePECOFF : public lldb_private::ObjectFile {
5555
// Static Functions
5656
static void Initialize();
5757

58+
static void DebuggerInitialize(lldb_private::Debugger &debugger);
59+
5860
static void Terminate();
5961

6062
static llvm::StringRef GetPluginNameStatic() { return "pe-coff"; }
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
include "../../../../include/lldb/Core/PropertiesBase.td"
2+
3+
let Definition = "objectfilepecoff" in {
4+
def ABI: Property<"abi", "Enum">,
5+
Global,
6+
DefaultEnumValue<"llvm::Triple::UnknownEnvironment">,
7+
EnumValues<"OptionEnumValues(g_abi_enums)">,
8+
Desc<"ABI to use when loading a PE/COFF module. This configures the C++ ABI used, which affects things like the handling of class layout. Accepted values are: `msvc` for the MSVC ABI, `gnu` for the MinGW / Itanium ABI, and `default` to follow the default target if it is a Windows triple or use the MSVC ABI by default.">;
9+
}

lldb/test/Shell/ObjectFile/PECOFF/basic-info-arm.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# RUN: lldb-test object-file %t | FileCheck %s
33

44
# CHECK: Plugin name: pe-coff
5-
# CHECK: Architecture: armv7-pc-windows-msvc
5+
# CHECK: Architecture: armv7-pc-windows-{{(msvc|gnu)}}
66
# CHECK: UUID:
77
# CHECK: Executable: true
88
# CHECK: Stripped: false

lldb/test/Shell/ObjectFile/PECOFF/basic-info-arm64.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# RUN: lldb-test object-file %t | FileCheck %s
33

44
# CHECK: Plugin name: pe-coff
5-
# CHECK: Architecture: aarch64-pc-windows-msvc
5+
# CHECK: Architecture: aarch64-pc-windows-{{(msvc|gnu)}}
66
# CHECK: UUID:
77
# CHECK: Executable: true
88
# CHECK: Stripped: false

lldb/test/Shell/ObjectFile/PECOFF/basic-info.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# RUN: lldb-test object-file %t | FileCheck %s
33

44
# CHECK: Plugin name: pe-coff
5-
# CHECK: Architecture: x86_64-pc-windows-msvc
5+
# CHECK: Architecture: x86_64-pc-windows-{{(msvc|gnu)}}
66
# CHECK: UUID:
77
# CHECK: Executable: true
88
# CHECK: Stripped: false
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# XFAIL: !windows-gnu
2+
3+
# RUN: yaml2obj %s -o %t
4+
# RUN: lldb-test object-file %t | FileCheck %s
5+
6+
# CHECK: Architecture: x86_64-pc-windows-gnu
7+
8+
--- !COFF
9+
OptionalHeader:
10+
AddressOfEntryPoint: 5152
11+
ImageBase: 5368709120
12+
SectionAlignment: 4096
13+
FileAlignment: 512
14+
MajorOperatingSystemVersion: 6
15+
MinorOperatingSystemVersion: 0
16+
MajorImageVersion: 0
17+
MinorImageVersion: 0
18+
MajorSubsystemVersion: 6
19+
MinorSubsystemVersion: 0
20+
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
21+
DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ]
22+
SizeOfStackReserve: 1048576
23+
SizeOfStackCommit: 4096
24+
SizeOfHeapReserve: 1048576
25+
SizeOfHeapCommit: 4096
26+
header:
27+
Machine: IMAGE_FILE_MACHINE_AMD64
28+
Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ]
29+
sections:
30+
- Name: .text
31+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
32+
VirtualAddress: 4096
33+
VirtualSize: 64
34+
SectionData: DEADBEEFBAADF00D
35+
- Name: .data
36+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
37+
VirtualAddress: 8192
38+
VirtualSize: 64
39+
SectionData: DEADBEEFBAADF00D
40+
symbols: []
41+
...
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# XFAIL: windows-gnu
2+
3+
# RUN: yaml2obj %s -o %t
4+
# RUN: lldb-test object-file %t | FileCheck %s
5+
6+
# CHECK: Architecture: x86_64-pc-windows-msvc
7+
8+
--- !COFF
9+
OptionalHeader:
10+
AddressOfEntryPoint: 5152
11+
ImageBase: 5368709120
12+
SectionAlignment: 4096
13+
FileAlignment: 512
14+
MajorOperatingSystemVersion: 6
15+
MinorOperatingSystemVersion: 0
16+
MajorImageVersion: 0
17+
MinorImageVersion: 0
18+
MajorSubsystemVersion: 6
19+
MinorSubsystemVersion: 0
20+
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
21+
DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ]
22+
SizeOfStackReserve: 1048576
23+
SizeOfStackCommit: 4096
24+
SizeOfHeapReserve: 1048576
25+
SizeOfHeapCommit: 4096
26+
header:
27+
Machine: IMAGE_FILE_MACHINE_AMD64
28+
Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ]
29+
sections:
30+
- Name: .text
31+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
32+
VirtualAddress: 4096
33+
VirtualSize: 64
34+
SectionData: DEADBEEFBAADF00D
35+
- Name: .data
36+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
37+
VirtualAddress: 8192
38+
VirtualSize: 64
39+
SectionData: DEADBEEFBAADF00D
40+
symbols: []
41+
...

0 commit comments

Comments
 (0)