-
Notifications
You must be signed in to change notification settings - Fork 14k
[lldb] Fix object format of some mach-o files by using vendor info in getDefaultFormat()
#143633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-lldb Author: None (royitaqi) ChangesContext: See previous attempt #142704 TL;DR: Some mach-o files (including some of those in lldb tests) are mistakenly reported as So we are dealing with the following constraints:
Full diff: https://github.com/llvm/llvm-project/pull/143633.diff 2 Files Affected:
diff --git a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp
index 0ef2d0b85fd36..71ff866abb352 100644
--- a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp
+++ b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp
@@ -94,4 +94,59 @@ TEST_F(ObjectFileMachOTest, IndirectSymbolsInTheSharedCache) {
for (size_t i = 0; i < 10; i++)
OF->ParseSymtab(symtab);
}
+
+TEST_F(ObjectFileMachOTest, ObjectFormatWithoutVersionLoadCommand) {
+ // A Mach-O file without the load command LC_BUILD_VERSION.
+ const char *yamldata = R"(
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x0100000C
+ cpusubtype: 0x00000000
+ filetype: 0x00000001
+ ncmds: 1
+ sizeofcmds: 152
+ flags: 0x00002000
+ reserved: 0x00000000
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 4
+ fileoff: 184
+ filesize: 4
+ maxprot: 7
+ initprot: 7
+ nsects: 1
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x0000000000000000
+ content: 'AABBCCDD'
+ size: 4
+ offset: 184
+ align: 0
+ reloff: 0x00000000
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x00000000
+ reserved2: 0x00000000
+ reserved3: 0x00000000
+...
+)";
+
+ // Perform setup.
+ llvm::Expected<TestFile> file = TestFile::fromYaml(yamldata);
+ EXPECT_THAT_EXPECTED(file, llvm::Succeeded());
+ auto module_sp = std::make_shared<Module>(file->moduleSpec());
+ ASSERT_NE(module_sp, nullptr);
+ auto object_file = module_sp->GetObjectFile();
+ ASSERT_NE(object_file, nullptr);
+
+ // Verify that the object file is recognized as Mach-O.
+ ASSERT_EQ(object_file->GetArchitecture().GetTriple().getObjectFormat(),
+ llvm::Triple::MachO);
+}
#endif
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index 6a559ff023caa..19ccd44322314 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -933,6 +933,9 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::Win32:
case Triple::UEFI:
return Triple::COFF;
+ case Triple::UnknownOS:
+ return T.getVendor() == Triple::Apple ? Triple::MachO : Triple::ELF;
+ // Intentional leak into the default case for additional logic.
default:
return T.isOSDarwin() ? Triple::MachO : Triple::ELF;
}
|
@@ -933,6 +933,9 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) { | |||
case Triple::Win32: | |||
case Triple::UEFI: | |||
return Triple::COFF; | |||
case Triple::UnknownOS: | |||
return T.getVendor() == Triple::Apple ? Triple::MachO : Triple::ELF; | |||
// Intentional leak into the default case for additional logic. | |||
default: | |||
return T.isOSDarwin() ? Triple::MachO : Triple::ELF; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we fold the above check into this line?
return T.isOSDarwin() ? Triple::MachO : Triple::ELF; | |
return T.isOSDarwin() || (T.getVendor() == Triple::Apple) ? Triple::MachO : Triple::ELF; |
Or do we really only want it when the OS is unknown?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Off the top of my head: For the sake of future proof, e.g. say Apple ships their own Linux, I assume their Linux will use ELF format, and so for case where "vendor == Apple && os == Linux", we probably want to return ELF.
WDYT?
(BTW the command of "Intentional leak" is outdated. Will remove in next update.)
I don't have an opinion on the patch, but I want to point out that, despite it being motivated by lldb, this is really an change to one of the foundational llvm classes, so you should get someone from the llvm side to review this and also add an (llvm) test to demonstrate/test the behavior you expect. |
Tagging a few people involved in the last PR (#75469) that modified this code path: @arsenm, @MaskRay, @lhames, @dsandersllvm, @rudkx
Great call out. Looks like this would be a good place to add a test: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems ok, but we should get some ok from the owners or contributors to the llvm/lib/TargetParser/Triple.cpp
file.
What kind of files don't have this |
Context: See previous attempt #142704
TL;DR: If a Mach-O file (including those yaml data in lldb unit tests) doesn't have load commands like
LC_BUILD_VERSION
orLC_VERSION_MIN_*
, they are mistakenly reported asELF
(as in theirTriple
) when they are parsed byObjectFileMachO
. If the load commands existed, they would have causedObjectFileMachO
to set the correct OS name into theTriple
here and here, which would have led to a correct defaultMachO
object format. Previously, #142704 tries to fix this by setting the correct object format inObjectFileMachO::GetAllArchSpecs
. However, it seems such explicit assignment cause theTriple
to report "-macho" in its string form, causing change in UI and a test failure which depends on the UI.So we are dealing with the following constraints:
Triple
'sgetDefaultFormat()
, changing the returned default format based on theTriple
's other fields.getDefaultFormat()
, at least in the case that I tested (see added unit test), theOS
is not set.Vendor
is set toApple
. This is becauseObjectFileMachO::GetAllArchSpecs()
callsArchSpec::SetArchitecture()
(code), which sets the vendor (code).eArchTypeMachO
, which will always lead to the vendor to be set asApple
, it seems to be a consistent way to detect mach-o object format.This patch doesn't change the main logic flow of
getDefaultFormat()
- it still first look at CPU arch, then OS. The change is that, when we look at OS and it'sUnknownOS
, then we further look at vendor and returnMachO
if the vendor isApple
.An alternative approach is to: