Skip to content

[llvm-objdump][macho] Fix relative method list dumping for little endian hosts #85778

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

Merged
merged 1 commit into from
Mar 19, 2024

Conversation

alx32
Copy link
Contributor

@alx32 alx32 commented Mar 19, 2024

macho-relative-method-lists.test is failing on little endian platforms, when matching 'name'.

CHK32-NEXT: name 0x144 (0x{{[0-9a-f]*}}) instance_method_00

next:10'0             X error: no match found
          18:  name 0x144 (0x7ac)      

This seems like the obvious fix.

alx32 referenced this pull request Mar 19, 2024
)

For Mach-O, ld64 supports the -fobjc-relative-method-lists flag which
changes the format in which method lists are generated. The format uses
delta encoding vs the original direct-pointer encoding.
This change adds support to llvm-objdump and llvm-otool for
decoding/dumping of method lists in the delta format. Previously, if a
binary with this information format was passed to the tooling, it would
output invalid information, trying to parse the delta lists as pointer
lists.
After this change, the tooling will output correct information if a
binary in this format is encountered.
The output format is closest feasible match to XCode 15.1's otool
output. Tests are included for both 32bit and 64bit binaries.

The code style was matched as close as possible to existing
implementation of parsing non-delta method lists.

Diff between llvm-objdump and XCode 15.1 otool:

![image](https://github.com/llvm/llvm-project/assets/103613512/2277e3ff-d59c-4fff-b93a-e0587ee740a6)

Note: This is a retry of this PR:
#84250
On the original PR, the armv7+armv8 builds were failing due to absolute
offsets being different.

Co-authored-by: Alex B <[email protected]>
@alx32 alx32 marked this pull request as ready for review March 19, 2024 11:56
@llvmbot
Copy link
Member

llvmbot commented Mar 19, 2024

@llvm/pr-subscribers-llvm-binary-utilities

Author: None (alx32)

Changes

macho-relative-method-lists.test is failing on little endian platforms, when matching 'name'.

CHK32-NEXT: name 0x144 (0x{{[0-9a-f]*}}) instance_method_00

next:10'0             X error: no match found
          18:  name 0x144 (0x7ac)      

This seems like the obvious fix.


Full diff: https://github.com/llvm/llvm-project/pull/85778.diff

2 Files Affected:

  • (modified) llvm/test/tools/llvm-objdump/MachO/AArch64/macho-relative-method-lists.test (-1)
  • (modified) llvm/tools/llvm-objdump/MachODump.cpp (+8-4)
diff --git a/llvm/test/tools/llvm-objdump/MachO/AArch64/macho-relative-method-lists.test b/llvm/test/tools/llvm-objdump/MachO/AArch64/macho-relative-method-lists.test
index 8e1a9b67970416..b1b96a41a32939 100644
--- a/llvm/test/tools/llvm-objdump/MachO/AArch64/macho-relative-method-lists.test
+++ b/llvm/test/tools/llvm-objdump/MachO/AArch64/macho-relative-method-lists.test
@@ -1,4 +1,3 @@
-XFAIL: system-aix
 RUN: llvm-objdump --macho --objc-meta-data    %p/Inputs/rel-method-lists-arm64_32.dylib | FileCheck %s --check-prefix=CHK32
 RUN: llvm-otool -ov                           %p/Inputs/rel-method-lists-arm64_32.dylib | FileCheck %s --check-prefix=CHK32
 
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index 1b0e5ba279d06b..5e0d69a68d69b4 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -4499,11 +4499,15 @@ static void print_relative_method_list(uint32_t structSizeAndFlags,
         outs() << indent << " (nameRefPtr extends past the end of the section)";
       else {
         if (pointerSize == 64) {
-          name = get_pointer_64(*reinterpret_cast<const uint64_t *>(nameRefPtr),
-                                xoffset, left, xS, info);
+          uint64_t nameOff_64 = *reinterpret_cast<const uint64_t *>(nameRefPtr);
+          if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
+            sys::swapByteOrder(nameOff_64);
+          name = get_pointer_64(nameOff_64, xoffset, left, xS, info);
         } else {
-          name = get_pointer_32(*reinterpret_cast<const uint32_t *>(nameRefPtr),
-                                xoffset, left, xS, info);
+          uint32_t nameOff_32 = *reinterpret_cast<const uint32_t *>(nameRefPtr);
+          if (info->O->isLittleEndian() != sys::IsLittleEndianHost)
+            sys::swapByteOrder(nameOff_32);
+          name = get_pointer_32(nameOff_32, xoffset, left, xS, info);
         }
         if (name != nullptr)
           outs() << format(" %.*s", left, name);

@uweigand
Copy link
Member

I'm seeing the same bug on s390x-linux, which is another big-endian platform like AIX.

This PR does fix the problem for me, so it looks like a good fix to me.

@kyulee-com kyulee-com self-requested a review March 19, 2024 14:42
Copy link
Contributor

@kyulee-com kyulee-com left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@kyulee-com kyulee-com merged commit b59c2a0 into llvm:main Mar 19, 2024
Copy link
Contributor

@amy-kwan amy-kwan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM as well.

chencha3 pushed a commit to chencha3/llvm-project that referenced this pull request Mar 23, 2024
…ian hosts (llvm#85778)

`macho-relative-method-lists.test` is failing on little endian
platforms, when matching 'name'.

```
CHK32-NEXT: name 0x144 (0x{{[0-9a-f]*}}) instance_method_00

next:10'0             X error: no match found
          18:  name 0x144 (0x7ac)      
```
This seems like the obvious fix.

Co-authored-by: Alex B <[email protected]>
@alx32 alx32 deleted the 06_objdump_rel_sel branch April 9, 2024 20:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants