Skip to content

Commit 8a64dd5

Browse files
committed
[lldb] Fix reading i686-windows executables with GNU environment
25c8a06 / D127048 added an option for setting the ABI to GNU. When an object file is loaded, there's only minimal verification done for the architecture spec set for it, if the object file only provides one. However, for i386 object files, the PECOFF object file plugin provides two architectures, i386-pc-windows and i686-pc-windows. This picks a totally different codepath in TargetList::CreateTargetInternal, where it's treated as a fat binary. This goes through more verifications to see if the architectures provided by the object file matches what the platform plugin supports. The PlatformWindows() constructor explicitly adds the "i386-pc-windows" and "i686-pc-windows" architectures (even when running on other architectures), which allows this "fat binary verification" to succeed for the i386 object files that provide two architectures. However, after that commit, if the object file is advertised with the different environment (either when lldb is built in a mingw environment, or if that setting is set), the fat binary validation won't accept the file any longer. Update ArchSpec::IsEqualTo with more logic for the Windows use cases; mismatching vendors is not an issue (they don't have any practical effect on Windows), and GNU and MSVC environments are compatible to the point that PlatformWindows can handle object files for both environments/ABIs. As a separate path forward, one could also consider to stop returning two architecture specs from ObjectFilePECOFF::GetModuleSpecifications for i386 files. Differential Revision: https://reviews.llvm.org/D128268
1 parent 17e2702 commit 8a64dd5

File tree

2 files changed

+74
-3
lines changed

2 files changed

+74
-3
lines changed

lldb/source/Utility/ArchSpec.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,16 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
979979

980980
const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor();
981981
const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor();
982-
if (lhs_triple_vendor != rhs_triple_vendor) {
982+
983+
const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS();
984+
const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS();
985+
986+
bool both_windows = lhs_triple.isOSWindows() && rhs_triple.isOSWindows();
987+
988+
// On Windows, the vendor field doesn't have any practical effect, but
989+
// it is often set to either "pc" or "w64".
990+
if ((lhs_triple_vendor != rhs_triple_vendor) &&
991+
(exact_match || !both_windows)) {
983992
const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified();
984993
const bool lhs_vendor_specified = TripleVendorWasSpecified();
985994
// Both architectures had the vendor specified, so if they aren't equal
@@ -993,8 +1002,6 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
9931002
return false;
9941003
}
9951004

996-
const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS();
997-
const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS();
9981005
const llvm::Triple::EnvironmentType lhs_triple_env =
9991006
lhs_triple.getEnvironment();
10001007
const llvm::Triple::EnvironmentType rhs_triple_env =
@@ -1032,6 +1039,9 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
10321039
return true;
10331040
}
10341041

1042+
if (!exact_match && both_windows)
1043+
return true; // The Windows environments (MSVC vs GNU) are compatible
1044+
10351045
return IsCompatibleEnvironment(lhs_triple_env, rhs_triple_env);
10361046
}
10371047

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
## Check that i386 executables can be opened in both ABI modes.
2+
## I386 executables are special in the sense that the PECOFF object
3+
## file plugin returns two architectures for them, i386 and i686, which
4+
## causes more elaborate comparisons to be run against the Platform plugin's
5+
## architecture list. Check that this is accepted despite potential mismatches
6+
## in the environment part of the triple.
7+
8+
# RUN: yaml2obj %s -o %t
9+
10+
## Default ABI is msvc:
11+
# RUN: %lldb -O "settings set plugin.object-file.pe-coff.abi msvc" \
12+
# RUN: -f %t -o "image list --triple --basename" -o exit | \
13+
# RUN: FileCheck -DABI=msvc -DFILENAME=%basename_t.tmp %s
14+
15+
## Default ABI is gnu:
16+
# RUN: %lldb -O "settings set plugin.object-file.pe-coff.abi gnu" \
17+
# RUN: -f %t -o "image list --triple --basename" -o exit | \
18+
# RUN: FileCheck -DABI=gnu -DFILENAME=%basename_t.tmp %s
19+
20+
# CHECK-LABEL: image list --triple --basename
21+
# CHECK-NEXT: i686-pc-windows-[[ABI]] [[FILENAME]]
22+
23+
--- !COFF
24+
OptionalHeader:
25+
AddressOfEntryPoint: 4480
26+
ImageBase: 268435456
27+
SectionAlignment: 4096
28+
FileAlignment: 512
29+
MajorOperatingSystemVersion: 6
30+
MinorOperatingSystemVersion: 0
31+
MajorImageVersion: 0
32+
MinorImageVersion: 0
33+
MajorSubsystemVersion: 6
34+
MinorSubsystemVersion: 0
35+
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
36+
DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ]
37+
SizeOfStackReserve: 1048576
38+
SizeOfStackCommit: 4096
39+
SizeOfHeapReserve: 1048576
40+
SizeOfHeapCommit: 4096
41+
header:
42+
Machine: IMAGE_FILE_MACHINE_I386
43+
Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_32BIT_MACHINE ]
44+
sections:
45+
- Name: .text
46+
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
47+
VirtualAddress: 4096
48+
VirtualSize: 64
49+
SectionData: DEADBEEFBAADF00D
50+
- Name: .data
51+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
52+
VirtualAddress: 8192
53+
VirtualSize: 64
54+
SectionData: DEADBEEFBAADF00D
55+
- Name: .debug_info
56+
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
57+
VirtualAddress: 16384
58+
VirtualSize: 64
59+
SectionData: DEADBEEFBAADF00D
60+
symbols: []
61+
...

0 commit comments

Comments
 (0)