Skip to content
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

[llvm-objdump][ARM] Find ELF file PLT entries for arm, thumb #130764

Merged
merged 8 commits into from
Mar 26, 2025

Conversation

dzhidzhoev
Copy link
Member

@dzhidzhoev dzhidzhoev commented Mar 11, 2025

This implements arm, armeb, thumb, thumbeb PLT entries parsing support in ELF for llvm-objdump.

Implementation is similar to AArch64MCInstrAnalysis::findPltEntries. PLT entry signatures are based on LLD code for PLT generation (ARM::writePlt).

llvm-objdump tests are produced from lld/test/ELF/arm-plt-reloc.s, lld/test/ELF/armv8-thumb-plt-reloc.s.

@llvmbot
Copy link
Member

llvmbot commented Mar 11, 2025

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

@llvm/pr-subscribers-backend-arm

Author: Vladislav Dzhidzhoev (dzhidzhoev)

Changes

This implements arm, armeb, thumb, thumbeb PLT entries parsing support in ELF for llvm-objdump.

Implementation is similar to AArch64MCInstrAnalysis::findPltEntries. PLT entry signatures are based on LLD code for PLT generation (ARM::writePlt).

llvm-objdump tests are generated based on lld/test/ELF/arm-plt-reloc.s, lld/test/ELF/armv8-thumb-plt-reloc.s.


Patch is 65.93 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/130764.diff

28 Files Affected:

  • (modified) lld/test/ELF/arm-gnu-ifunc-plt.s (+4)
  • (modified) lld/test/ELF/arm-mixed-plts.s (+2)
  • (modified) lld/test/ELF/arm-plt-reloc.s (+36)
  • (modified) lld/test/ELF/arm-thumb-interwork-shared.s (+4)
  • (modified) lld/test/ELF/arm-thumb-interwork-thunk.s (+16)
  • (modified) lld/test/ELF/arm-thumb-plt-range-thunk-os.s (+6)
  • (modified) lld/test/ELF/arm-thumb-plt-reloc.s (+6)
  • (modified) lld/test/ELF/arm-thunk-multipass-plt.s (+4)
  • (modified) lld/test/ELF/arm-thunk-re-add.s (+4)
  • (modified) lld/test/ELF/armv8-thumb-plt-reloc.s (+6)
  • (modified) llvm/include/llvm/MC/MCInstrAnalysis.h (+2-1)
  • (modified) llvm/lib/Object/ELFObjectFile.cpp (+17-3)
  • (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp (+4-3)
  • (modified) llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp (+106)
  • (modified) llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp (+4-3)
  • (modified) llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp (+8-7)
  • (added) llvm/test/tools/llvm-objdump/ELF/ARM/plt-be.test (+81)
  • (added) llvm/test/tools/llvm-objdump/ELF/ARM/plt-be8.test (+81)
  • (added) llvm/test/tools/llvm-objdump/ELF/ARM/plt-long-be.test (+84)
  • (added) llvm/test/tools/llvm-objdump/ELF/ARM/plt-long-be8.test (+84)
  • (added) llvm/test/tools/llvm-objdump/ELF/ARM/plt-long.test (+84)
  • (added) llvm/test/tools/llvm-objdump/ELF/ARM/plt-mix-be.test (+93)
  • (added) llvm/test/tools/llvm-objdump/ELF/ARM/plt-mix-be8.test (+93)
  • (added) llvm/test/tools/llvm-objdump/ELF/ARM/plt-mix.test (+93)
  • (added) llvm/test/tools/llvm-objdump/ELF/ARM/plt-thumb-be.test (+91)
  • (added) llvm/test/tools/llvm-objdump/ELF/ARM/plt-thumb-be8.test (+97)
  • (added) llvm/test/tools/llvm-objdump/ELF/ARM/plt-thumb.test (+91)
  • (added) llvm/test/tools/llvm-objdump/ELF/ARM/plt.test (+81)
diff --git a/lld/test/ELF/arm-gnu-ifunc-plt.s b/lld/test/ELF/arm-gnu-ifunc-plt.s
index 55592c0843d6a..f3960b3f42f7f 100644
--- a/lld/test/ELF/arm-gnu-ifunc-plt.s
+++ b/lld/test/ELF/arm-gnu-ifunc-plt.s
@@ -53,10 +53,14 @@
 // DISASM-NEXT:    20214:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // DISASM-NEXT:    20218:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // DISASM-NEXT:    2021c:       d4 d4 d4 d4     .word   0xd4d4d4d4
+// DISASM-EMPTY:
+// DISASM-NEXT:  <bar2@plt>:
 // DISASM-NEXT:    20220:       add     r12, pc, #0, #12
 // DISASM-NEXT:    20224:       add     r12, r12, #32
 // DISASM-NEXT:    20228:       ldr     pc, [r12, #212]!
 // DISASM-NEXT:    2022c:       d4 d4 d4 d4     .word   0xd4d4d4d4
+// DISASM-EMPTY:
+// DISASM-NEXT:  <zed2@plt>:
 // DISASM-NEXT:    20230:       add     r12, pc, #0, #12
 // DISASM-NEXT:    20234:       add     r12, r12, #32
 // DISASM-NEXT:    20238:       ldr     pc, [r12, #200]!
diff --git a/lld/test/ELF/arm-mixed-plts.s b/lld/test/ELF/arm-mixed-plts.s
index 801de70f4f101..529983dfd9266 100644
--- a/lld/test/ELF/arm-mixed-plts.s
+++ b/lld/test/ELF/arm-mixed-plts.s
@@ -18,6 +18,8 @@
 # CHECK-NEXT: d4 d4 d4 d4   .word   0xd4d4d4d4
 # CHECK-NEXT: d4 d4 d4 d4   .word   0xd4d4d4d4
 # CHECK-NEXT: d4 d4 d4 d4   .word   0xd4d4d4d4
+# CHECK-EMPTY:
+# CHECK-NEXT: <bar@plt>:
 # CHECK-NEXT: e28fc600      add     r12, pc, #0, #12
 # CHECK-NEXT: e28cca20      add     r12, r12, #32, #20
 # CHECK-NEXT: e5bcf06c      ldr     pc, [r12, #0x6c]!
diff --git a/lld/test/ELF/arm-plt-reloc.s b/lld/test/ELF/arm-plt-reloc.s
index bfd51467e7425..a12aea45dfb15 100644
--- a/lld/test/ELF/arm-plt-reloc.s
+++ b/lld/test/ELF/arm-plt-reloc.s
@@ -74,16 +74,22 @@ _start:
 // DSO-NEXT:     10248:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // DSO-NEXT:     1024c:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // (0x10250 + 8) + (0 RoR 12) + (32 RoR 20 = 0x20000) + 140 = 0x302e4
+// DSO-EMPTY:
+// DSO-NEXT:     <func1@plt>:
 // DSO-NEXT:     10250:       add     r12, pc, #0, #12
 // DSO-NEXT:     10254:       add     r12, r12, #32, #20
 // DSO-NEXT:     10258:       ldr     pc, [r12, #140]!
 // DSO-NEXT:     1025c:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // (0x10260 + 8) + (0 RoR 12) + (32 RoR 20 = 0x20000) + 128 = 0x302e8
+// DSO-EMPTY:
+// DSO-NEXT:     <func2@plt>:
 // DSO-NEXT:     10260:       add     r12, pc, #0, #12
 // DSO-NEXT:     10264:       add     r12, r12, #32, #20
 // DSO-NEXT:     10268:       ldr     pc, [r12, #128]!
 // DSO-NEXT:     1026c:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // (0x10270 + 8) + (0 RoR 12) + (32 RoR 20 = 0x20000) + 116 = 0x302ec
+// DSO-EMPTY:
+// DSO-NEXT:     <func3@plt>:
 // DSO-NEXT:     10270:       add     r12, pc, #0, #12
 // DSO-NEXT:     10274:       add     r12, r12, #32, #20
 // DSO-NEXT:     10278:       ldr     pc, [r12, #116]!
@@ -152,14 +158,20 @@ _start:
 // CHECKHIGH-NEXT:     2014:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECKHIGH-NEXT:     2018:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECKHIGH-NEXT:     201c:       d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKHIGH-EMPTY:
+// CHECKHIGH-NEXT:     <func1@plt>:
 // CHECKHIGH-NEXT:     2020:       add     r12, pc, #16, #12
 // CHECKHIGH-NEXT:     2024:       add     r12, r12, #1036288
 // CHECKHIGH-NEXT:     2028:       ldr     pc, [r12, #4068]!
 // CHECKHIGH-NEXT:     202c:       d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKHIGH-EMPTY:
+// CHECKHIGH-NEXT:     <func2@plt>:
 // CHECKHIGH-NEXT:     2030:       add     r12, pc, #16, #12
 // CHECKHIGH-NEXT:     2034:       add     r12, r12, #1036288
 // CHECKHIGH-NEXT:     2038:       ldr     pc, [r12, #4056]!
 // CHECKHIGH-NEXT:     203c:       d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKHIGH-EMPTY:
+// CHECKHIGH-NEXT:     <func3@plt>:
 // CHECKHIGH-NEXT:     2040:       add     r12, pc, #16, #12
 // CHECKHIGH-NEXT:     2044:       add     r12, r12, #1036288
 // CHECKHIGH-NEXT:     2048:       ldr     pc, [r12, #4044]!
@@ -220,14 +232,20 @@ _start:
 // CHECKLONG-NEXT:     2014:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECKLONG-NEXT:     2018:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECKLONG-NEXT:     201c:       d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKLONG-EMPTY:
+// CHECKLONG-NEXT: <func1@plt>:
 // CHECKLONG-NEXT:     2020:       ldr     r12, [pc, #4]
 // CHECKLONG-NEXT:     2024:       add     r12, r12, pc
 // CHECKLONG-NEXT:     2028:       ldr     pc, [r12]
 // CHECKLONG-NEXT:     202c:       e0 f0 10 11     .word   0x1110f0e0
+// CHECKLONG-EMPTY:
+// CHECKLONG-NEXT: <func2@plt>:
 // CHECKLONG-NEXT:     2030:       ldr     r12, [pc, #4]
 // CHECKLONG-NEXT:     2034:       add     r12, r12, pc
 // CHECKLONG-NEXT:     2038:       ldr     pc, [r12]
 // CHECKLONG-NEXT:     203c:       d4 f0 10 11     .word   0x1110f0d4
+// CHECKLONG-EMPTY:
+// CHECKLONG-NEXT: <func3@plt>:
 // CHECKLONG-NEXT:     2040:       ldr     r12, [pc, #4]
 // CHECKLONG-NEXT:     2044:       add     r12, r12, pc
 // CHECKLONG-NEXT:     2048:       ldr     pc, [r12]
@@ -257,14 +275,20 @@ _start:
 // CHECKLONG-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECKLONG-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECKLONG-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKLONG-EB-EMPTY:
+// CHECKLONG-EB-NEXT: <func1@plt>:
 // CHECKLONG-EB-NEXT:     2020:       ldr     r12, [pc, #4]
 // CHECKLONG-EB-NEXT:                 add     r12, r12, pc
 // CHECKLONG-EB-NEXT:                 ldr     pc, [r12]
 // CHECKLONG-EB-NEXT:                 11 10 f0 e0     .word   0x1110f0e0
+// CHECKLONG-EB-EMPTY:
+// CHECKLONG-EB-NEXT: <func2@plt>:
 // CHECKLONG-EB-NEXT:     2030:       ldr     r12, [pc, #4]
 // CHECKLONG-EB-NEXT:                 add     r12, r12, pc
 // CHECKLONG-EB-NEXT:                 ldr     pc, [r12]
 // CHECKLONG-EB-NEXT:                 11 10 f0 d4     .word   0x1110f0d4
+// CHECKLONG-EB-EMPTY:
+// CHECKLONG-EB-NEXT: <func3@plt>:
 // CHECKLONG-EB-NEXT:     2040:       ldr     r12, [pc, #4]
 // CHECKLONG-EB-NEXT:                 add     r12, r12, pc
 // CHECKLONG-EB-NEXT:                 ldr     pc, [r12]
@@ -326,14 +350,20 @@ _start:
 // CHECKMIX-NEXT:     2014:     d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECKMIX-NEXT:     2018:     d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECKMIX-NEXT:     201c:     d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKMIX-EMPTY:
+// CHECKMIX-NEXT:     <func1@plt>:
 // CHECKMIX-NEXT:     2020:       ldr     r12, [pc, #4]
 // CHECKMIX-NEXT:     2024:       add     r12, r12, pc
 // CHECKMIX-NEXT:     2028:       ldr     pc, [r12]
 // CHECKMIX-NEXT:     202c:     00 00 00 08     .word   0x08000000
+// CHECKMIX-EMPTY:
+// CHECKMIX-NEXT:     <func2@plt>:
 // CHECKMIX-NEXT:     2030:       add     r12, pc, #133169152
 // CHECKMIX-NEXT:     2034:       add     r12, r12, #1044480
 // CHECKMIX-NEXT:     2038:       ldr     pc, [r12, #4088]!
 // CHECKMIX-NEXT:     203c:     d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKMIX-EMPTY:
+// CHECKMIX-NEXT:     <func3@plt>:
 // CHECKMIX-NEXT:     2040:       add     r12, pc, #133169152
 // CHECKMIX-NEXT:     2044:       add     r12, r12, #1044480
 // CHECKMIX-NEXT:     2048:       ldr     pc, [r12, #4076]!
@@ -363,14 +393,20 @@ _start:
 // CHECKMIX-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECKMIX-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECKMIX-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKMIX-EB-EMPTY:
+// CHECKMIX-EB-NEXT:     <func1@plt>:
 // CHECKMIX-EB-NEXT:     2020:       ldr     r12, [pc, #4]
 // CHECKMIX-EB-NEXT:                 add     r12, r12, pc
 // CHECKMIX-EB-NEXT:                 ldr     pc, [r12]
 // CHECKMIX-EB-NEXT:                 08 00 00 00     .word   0x08000000
+// CHECKMIX-EB-EMPTY:
+// CHECKMIX-EB-NEXT:     <func2@plt>:
 // CHECKMIX-EB-NEXT:     2030:       add     r12, pc, #133169152
 // CHECKMIX-EB-NEXT:                 add     r12, r12, #1044480
 // CHECKMIX-EB-NEXT:                 ldr     pc, [r12, #4088]!
 // CHECKMIX-EB-NEXT:                 d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECKMIX-EB-EMPTY:
+// CHECKMIX-EB-NEXT:     <func3@plt>:
 // CHECKMIX-EB-NEXT:     2040:       add     r12, pc, #133169152
 // CHECKMIX-EB-NEXT:                 add     r12, r12, #1044480
 // CHECKMIX-EB-NEXT:                 ldr     pc, [r12, #4076]!
diff --git a/lld/test/ELF/arm-thumb-interwork-shared.s b/lld/test/ELF/arm-thumb-interwork-shared.s
index 03bed000a02e6..8a616f9d75797 100644
--- a/lld/test/ELF/arm-thumb-interwork-shared.s
+++ b/lld/test/ELF/arm-thumb-interwork-shared.s
@@ -45,10 +45,14 @@ sym1:
 // CHECK-NEXT:           .word   0xd4d4d4d4
 // CHECK-NEXT:           .word   0xd4d4d4d4
 // CHECK-NEXT:           .word   0xd4d4d4d4
+// CHECK-EMPTY:
+// CHECK-NEXT: <elsewhere@plt>:
 // CHECK-NEXT:     10230: add     r12, pc, #0, #12
 // CHECK-NEXT:           add     r12, r12, #32
 // CHECK-NEXT:           ldr     pc, [r12, #124]!
 // CHECK-NEXT:     1023c: d4 d4 d4 d4 .word   0xd4d4d4d4
+// CHECK-EMPTY:
+// CHECK-NEXT: <weakref@plt>:
 // CHECK-NEXT:     10240: add     r12, pc, #0, #12
 // CHECK-NEXT:           add     r12, r12, #32
 // CHECK-NEXT:           ldr     pc, [r12, #112]!
diff --git a/lld/test/ELF/arm-thumb-interwork-thunk.s b/lld/test/ELF/arm-thumb-interwork-thunk.s
index 39a2e737cc9d2..a01be31bfd9ae 100644
--- a/lld/test/ELF/arm-thumb-interwork-thunk.s
+++ b/lld/test/ELF/arm-thumb-interwork-thunk.s
@@ -298,34 +298,50 @@ _start:
 // CHECK-ARM-PLT-NEXT:     1624:     d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECK-ARM-PLT-NEXT:     1628:     d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECK-ARM-PLT-NEXT:     162c:     d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-ARM-PLT-EMPTY:
+// CHECK-ARM-PLT-NEXT:     <thumb_callee1@plt>
 // CHECK-ARM-PLT-NEXT:     1630:             add     r12, pc, #0, #12
 // CHECK-ARM-PLT-NEXT:     1634:             add     r12, r12, #0, #20
 // CHECK-ARM-PLT-NEXT:     1638:             ldr     pc, [r12, #648]!
 // CHECK-ARM-PLT-NEXT:     163c:     d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-ARM-PLT-EMPTY:
+// CHECK-ARM-PLT-NEXT:     <arm_callee1@plt>
 // CHECK-ARM-PLT-NEXT:     1640:             add     r12, pc, #0, #12
 // CHECK-ARM-PLT-NEXT:     1644:             add     r12, r12, #0, #20
 // CHECK-ARM-PLT-NEXT:     1648:             ldr     pc, [r12, #636]!
 // CHECK-ARM-PLT-NEXT:     164c:     d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-ARM-PLT-EMPTY:
+// CHECK-ARM-PLT-NEXT:     <arm_caller@plt>
 // CHECK-ARM-PLT-NEXT:     1650:             add     r12, pc, #0, #12
 // CHECK-ARM-PLT-NEXT:     1654:             add     r12, r12, #0, #20
 // CHECK-ARM-PLT-NEXT:     1658:             ldr     pc, [r12, #624]!
 // CHECK-ARM-PLT-NEXT:     165c:     d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-ARM-PLT-EMPTY:
+// CHECK-ARM-PLT-NEXT:     <thumb_callee2@plt>
 // CHECK-ARM-PLT-NEXT:     1660:             add     r12, pc, #0, #12
 // CHECK-ARM-PLT-NEXT:     1664:             add     r12, r12, #0, #20
 // CHECK-ARM-PLT-NEXT:     1668:             ldr     pc, [r12, #612]!
 // CHECK-ARM-PLT-NEXT:     166c:     d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-ARM-PLT-EMPTY:
+// CHECK-ARM-PLT-NEXT:     <thumb_callee3@plt>
 // CHECK-ARM-PLT-NEXT:     1670:             add     r12, pc, #0, #12
 // CHECK-ARM-PLT-NEXT:     1674:             add     r12, r12, #0, #20
 // CHECK-ARM-PLT-NEXT:     1678:             ldr     pc, [r12, #600]!
 // CHECK-ARM-PLT-NEXT:     167c:     d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-ARM-PLT-EMPTY:
+// CHECK-ARM-PLT-NEXT:     <arm_callee2@plt>
 // CHECK-ARM-PLT-NEXT:     1680:             add     r12, pc, #0, #12
 // CHECK-ARM-PLT-NEXT:     1684:             add     r12, r12, #0, #20
 // CHECK-ARM-PLT-NEXT:     1688:             ldr     pc, [r12, #588]!
 // CHECK-ARM-PLT-NEXT:     168c:     d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-ARM-PLT-EMPTY:
+// CHECK-ARM-PLT-NEXT:     <arm_callee3@plt>
 // CHECK-ARM-PLT-NEXT:     1690:             add     r12, pc, #0, #12
 // CHECK-ARM-PLT-NEXT:     1694:             add     r12, r12, #0, #20
 // CHECK-ARM-PLT-NEXT:     1698:             ldr     pc, [r12, #576]!
 // CHECK-ARM-PLT-NEXT:     169c:     d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-ARM-PLT-EMPTY:
+// CHECK-ARM-PLT-NEXT:     <thumb_caller@plt>
 // CHECK-ARM-PLT-NEXT:     16a0:             add     r12, pc, #0, #12
 // CHECK-ARM-PLT-NEXT:     16a4:             add     r12, r12, #0, #20
 // CHECK-ARM-PLT-NEXT:     16a8:             ldr     pc, [r12, #564]!
diff --git a/lld/test/ELF/arm-thumb-plt-range-thunk-os.s b/lld/test/ELF/arm-thumb-plt-range-thunk-os.s
index 65e7e4b525926..945cef6d4b4d5 100644
--- a/lld/test/ELF/arm-thumb-plt-range-thunk-os.s
+++ b/lld/test/ELF/arm-thumb-plt-range-thunk-os.s
@@ -96,14 +96,20 @@ far_nonpreemptible_alias:
 // CHECK4-NEXT:  4000024:	d4 d4 d4 d4 	.word	0xd4d4d4d4
 // CHECK4-NEXT:  4000028:	d4 d4 d4 d4 	.word	0xd4d4d4d4
 // CHECK4-NEXT:  400002c:	d4 d4 d4 d4 	.word	0xd4d4d4d4
+// CHECK4-EMPTY:
+// CHECK4-NEXT: <elsewhere@plt>:
 // CHECK4-NEXT:  4000030:	e28fc600    	add	r12, pc, #0, #12
 // CHECK4-NEXT:  4000034:	e28cca20    	add	r12, r12, #32
 // CHECK4-NEXT:  4000038:	e5bcf08c    	ldr	pc, [r12, #140]!
 // CHECK4-NEXT:  400003c:	d4 d4 d4 d4 	.word	0xd4d4d4d4
+// CHECK4-EMPTY:
+// CHECK4-NEXT: <preemptible@plt>:
 // CHECK4-NEXT:  4000040:	e28fc600    	add	r12, pc, #0, #12
 // CHECK4-NEXT:  4000044:	e28cca20    	add	r12, r12, #32
 // CHECK4-NEXT:  4000048:	e5bcf080    	ldr	pc, [r12, #128]!
 // CHECK4-NEXT:  400004c:	d4 d4 d4 d4 	.word	0xd4d4d4d4
+// CHECK4-EMPTY:
+// CHECK4-NEXT: <far_preemptible@plt>:
 // CHECK4-NEXT:  4000050:	e28fc600    	add	r12, pc, #0, #12
 // CHECK4-NEXT:  4000054:	e28cca20    	add	r12, r12, #32
 // CHECK4-NEXT:  4000058:	e5bcf074    	ldr	pc, [r12, #116]!
diff --git a/lld/test/ELF/arm-thumb-plt-reloc.s b/lld/test/ELF/arm-thumb-plt-reloc.s
index 4a1fd020452c9..9c4674779e3b9 100644
--- a/lld/test/ELF/arm-thumb-plt-reloc.s
+++ b/lld/test/ELF/arm-thumb-plt-reloc.s
@@ -83,16 +83,22 @@ _start:
 // DSO-NEXT:     10248:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // DSO-NEXT:     1024c:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // (0x10250 + 8) + (0 RoR 12) + (32 RoR 20 = 0x20000) + 140 = 0x302e4
+// DSO-EMPTY:
+// DSO-NEXT: <func1@plt>:
 // DSO-NEXT:     10250:       e28fc600        add     r12, pc, #0, #12
 // DSO-NEXT:     10254:       e28cca20        add     r12, r12, #32, #20
 // DSO-NEXT:     10258:       e5bcf08c        ldr     pc, [r12, #140]!
 // DSO-NEXT:     1025c:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // (0x10260 + 8) + (0 RoR 12) + (32 RoR 20 = 0x20000) + 128 = 0x302e8
+// DSO-EMPTY:
+// DSO-NEXT: <func2@plt>:
 // DSO-NEXT:     10260:       e28fc600        add     r12, pc, #0, #12
 // DSO-NEXT:     10264:       e28cca20        add     r12, r12, #32, #20
 // DSO-NEXT:     10268:       e5bcf080        ldr     pc, [r12, #128]!
 // DSO-NEXT:     1026c:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // (0x10270 + 8) + (0 RoR 12) + (32 RoR 20 = 0x20000) + 116 = 0x302ec
+// DSO-EMPTY:
+// DSO-NEXT: <func3@plt>:
 // DSO-NEXT:     10270:       e28fc600        add     r12, pc, #0, #12
 // DSO-NEXT:     10274:       e28cca20        add     r12, r12, #32, #20
 // DSO-NEXT:     10278:       e5bcf074        ldr     pc, [r12, #116]!
diff --git a/lld/test/ELF/arm-thunk-multipass-plt.s b/lld/test/ELF/arm-thunk-multipass-plt.s
index 2e8f054ce3f73..ecf69d58b510e 100644
--- a/lld/test/ELF/arm-thunk-multipass-plt.s
+++ b/lld/test/ELF/arm-thunk-multipass-plt.s
@@ -86,10 +86,14 @@ preemptible2:
 // CHECK-PLT-NEXT:   d00034: d4 d4 d4 d4      .word   0xd4d4d4d4
 // CHECK-PLT-NEXT:   d00038: d4 d4 d4 d4      .word   0xd4d4d4d4
 // CHECK-PLT-NEXT:   d0003c: d4 d4 d4 d4      .word   0xd4d4d4d4
+// CHECK-PLT-EMPTY:
+// CHECK-PLT-NEXT: <preemptible@plt>:
 // CHECK-PLT-NEXT:   d00040: add     r12, pc, #0, #12
 // CHECK-PLT-NEXT:   d00044: add     r12, r12, #32, #20
 // CHECK-PLT-NEXT:   d00048: ldr     pc, [r12, #124]!
 // CHECK-PLT-NEXT:   d0004c: d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK-PLT-EMPTY:
+// CHECK-PLT-NEXT: <preemptible2@plt>:
 // CHECK-PLT-NEXT:   d00050: add     r12, pc, #0, #12
 // CHECK-PLT-NEXT:   d00054: add     r12, r12, #32, #20
 // CHECK-PLT-NEXT:   d00058: ldr     pc, [r12, #112]!
diff --git a/lld/test/ELF/arm-thunk-re-add.s b/lld/test/ELF/arm-thunk-re-add.s
index 7505ec045fff0..1745237d38829 100644
--- a/lld/test/ELF/arm-thunk-re-add.s
+++ b/lld/test/ELF/arm-thunk-re-add.s
@@ -109,10 +109,14 @@ callers:
 // CHECK3-NEXT:  1100034:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECK3-NEXT:  1100038:       d4 d4 d4 d4     .word   0xd4d4d4d4
 // CHECK3-NEXT:  110003c:       d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK3-EMPTY:
+// CHECK3-NEXT: <imported@plt>:
 // CHECK3-NEXT:  1100040:       e28fc600        add     r12, pc, #0, #12
 // CHECK3-NEXT:  1100044:       e28cca20        add     r12, r12, #32
 // CHECK3-NEXT:  1100048:       e5bcf07c        ldr     pc, [r12, #124]!
 // CHECK3-NEXT:  110004c:       d4 d4 d4 d4     .word   0xd4d4d4d4
+// CHECK3-EMPTY:
+// CHECK3-NEXT: <imported2@plt>:
 // CHECK3-NEXT:  1100050:       e28fc600        add     r12, pc, #0, #12
 // CHECK3-NEXT:  1100054:       e28cca20        add     r12, r12, #32
 // CHECK3-NEXT:  1100058:       e5bcf070        ldr     pc, [r12, #112]!
diff --git a/lld/test/ELF/armv8-thumb-plt-reloc.s b/lld/test/ELF/armv8-thumb-plt-reloc.s
index 5b6e4b5fdd139..df2b960684b93 100644
--- a/lld/test/ELF/armv8-thumb-plt-reloc.s
+++ b/lld/test/ELF/armv8-thumb-plt-reloc.s
@@ -101,18 +101,24 @@ _start:
 // DSO-NEXT:     .word   0xd4d4d4d4
 
 /// 136 + 2 << 16 + 0x1026c = 0x302f4 = got entry 1
+// DSO-EMPTY:
+// DSO-NEXT:     <func1@plt>:
 // DSO-NEXT:     10260:       f240 0c88     movw    r12, #136
 // DSO-NEXT:                  f2c0 0c02     movt    r12, #2
 // DSO-NEXT:                  44fc          add     r12, pc
 // DSO-NEXT:                  f8dc f000     ldr.w   pc, [r12]
 // DSO-NEXT:                  e7fc          b       0x1026a
 /// 124 + 2 << 16 + 0x1027c = 0x302f8 = got entry 2
+// DSO-EMPTY:
+// DSO-NEXT:     <func2@plt>:
 // DSO-NEXT:     10270:       f240 0c7c     movw    r12, #124
 // DSO-NEXT:                  f2c0 0c02     movt    r12, #2
 // DSO-NEXT:                  44fc          add     r12, pc
 // DSO-NEXT:                  f8dc f000     ldr.w   pc, [r12]
 // DSO-NEXT:                  e7fc          b       0x1027a
 /// 112 + 2 << 16 + 0x1028c = 0x302fc = got entry 3
+// DSO-EMPTY:
+// DSO-NEXT:     <func3@plt>:
 // DSO-NEXT:     10280:       f240 0c70     movw    r12, #112
 // DSO-NEXT:                  f2c0 0c02     movt    r12, #2
 // DSO-NEXT:                  44fc          add     r12, pc
diff --git a/llvm/include/llvm/MC/MCInstrAnalysis.h b/llvm/include/llvm/MC/MCInstrAnalysis.h
index b571791c518da..eacadce6b91d9 100644
--- a/llvm/include/llvm/MC/MCInstrAnalysis.h
+++ b/llvm/include/llvm/MC/MCInstrAnalysis.h
@@ -195,7 +195,8 @@ class MCInstrAnalysis {
   /// Returns (PLT virtual address, GOT virtual address) pairs for PLT entries.
   virtual std::vector<std::pair<uint64_t, uint64_t>>
   findPltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents,
-                 const Triple &TargetTriple) const {
+                 const Triple &TargetTriple,
+                 std::optional<llvm::endianness> InstrEndiannessHint) const {
     return {};
   }
 };
diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp
index d0897c62b3e8e..c9ff42175dccd 100644
--- a/llvm/lib/Object/ELFObjectFile.cpp
+++ b/llvm/lib/Object/ELFObjectFile.cpp
@@ -798,6 +798,12 @@ std::vector<ELFPltEntry> ELFObjectFileBase::getPltEntries() const {
     case Triple::aarch64_be:
       JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT;
       break;
+    case Triple::arm:
+    case Triple::armeb:
+    case Triple::thumb:
+    case Triple::thumbeb:
+      JumpSlotReloc = ELF::R_ARM_JUMP_SLOT;
+      break;
     case Triple::hexagon:
       JumpSlotReloc = ELF::R_HEX_JMP_SLOT;
       GlobDatReloc = ELF::R_HEX_GLOB_DAT;
@@ -833,10 +839,18 @@ std::vector<ELFPltEntry> ELFObjectFileBase::getPltEntries() const {
         consumeError(PltContents.takeError());
         return {};
       }
+      std::optional<llvm::endianness> InstrEndianness;
+      if (const auto *Elf32BE = dyn_cast<ELF32BEObjectFile>(this)) {
+        if (!Elf32BE->isRelocatableObject() &&
+            (Elf32BE->getPlatformFlags() & ELF::EF_ARM_BE8)) {
+          InstrEndianness = endianness::little;
+        }
+      }
+
       llvm::a...
[truncated]

Copy link
Collaborator

@smithp35 smithp35 left a comment

Choose a reason for hiding this comment

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

Thanks for the patch.

This looks correct for the Arm/Thumb details. I've left some stylistic suggestions that I think might help someone reading this for the first time.

For LLD generated PLTs at least, we should only see Thumb2 PLTs for a Cortex-M which I think only supports be8, however it is possible to generate be32 images so I don't think it is worth trying to take advantage of that.

uint32_t InsnPart1 =
support::endian::read16(PltContents.data() + Byte, InstrEndianness);

// Is Thumb? Check for movw.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this kind test can be hoisted out of the loop, and cached, although the first entry of the Thumb2 PLT won't be a mov as it will be the PLT header.

All PLT entries will be Arm state or Thumb2. If you've access to the symbol table, the canonical way of determining whether Arm or Thumb is from the mapping symbol at address 0, $a for Arm or $t for Thumb.

It may even be a bit easier to read if we have something like (pseudo code)

test if Arm or Thumb
// Arm is the most common case.
if Arm {
  for(...) {

  }
}
else {
  for (...) {

  }
}

Copy link
Member Author

Choose a reason for hiding this comment

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

We do have access to the symbol table from findPltEntries, though it's a raw symbol table, with no Section->Symbols mapping. Probably we don't want to traverse the whole symbol table in findPltEntries.

Meanwhile, the described logic was implemented in llvm-objdump.cpp here https://reviews.llvm.org/D60927. However, "thumb-ness" for sections is checked during disassembly after addPltEntries call.

I've added the code to detect Thumb usage of .plt section before addPltEntries, and to pass MCSubtargetInfo instead of TargetTriple to findPltEntries, so that findPltEntries can get that information from feature flags. I hope it doesn't violate abstraction layers too much.

((Insn2Part2 & 0xff) << 16) + ((Insn2Part2 & 0x7000) << 12) +
((Insn2Part1 & 0x400) << 17) + ((Insn2Part1 & 0xf) << 28);

// Check for add
Copy link
Collaborator

Choose a reason for hiding this comment

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

The remaining instructions of the PLT entry are matched exactly. Could these be put in an array, and looped through. For example

uint16_t Insns = 
  { 0x44fc,  // add ip, pc
    0xf8dc, 0xf000, // ldr.w pc, [ip]
    0xe7fc              // b . -4 };
// loop from Byte + 8 to Byte + 14
// check insn against array[offset in array]

If any of these fail its likely a corrupt PLT, you may be able to skip to the next PLT start boundary on failure (Byte += 12)

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed. I did the same to check long entries.

support::endian::read16(PltContents.data() + Byte, InstrEndianness);

// Is Thumb? Check for movw.
if ((InsnPart1 & 0xffb0) == 0xf200) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it would be helpful if there's an overall expected PLT sequence before we start. For example:

   movw ip, #lower16
   movt ip, #upper16
   add ip, pc
   ldr.w pc, [ip]
   b . -4

Copy link
Member Author

Choose a reason for hiding this comment

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

Added comments for every case

Byte += 12;
} else {
// Check for first add
if ((Insn & 0xe28fc600) != 0xe28fc600)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Rather than Insn, Insn2 and Insn3 could you use Add1, Add2, Ldr?

if ((Insn3 & 0xe5bcf000) != 0xe5bcf000)
continue;

uint64_t Offset = (PltSectionVA + Byte + 8) + ((Insn & 0xff) << 20) +
Copy link
Collaborator

Choose a reason for hiding this comment

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

Similar to the thumb case. Can we explain that the 8 is the Arm PC-Bias.

@@ -0,0 +1,81 @@
# RUN: yaml2obj %s -o %t
Copy link
Member

Choose a reason for hiding this comment

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

We need ET_DYN / ET_EXE to test .plt, but due to project layering we cannot use lld here.
Therefore, we resort to yaml2obj, but I can see that these plt* files could be challenging to update.

Is it possible to use yaml2obj -D... to remove some duplication?

Copy link
Member Author

Choose a reason for hiding this comment

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

Should in look like that 7d7c9ba?

Copy link
Collaborator

@jh7370 jh7370 left a comment

Choose a reason for hiding this comment

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

I'm not a great fan of the big binary blobs in the llvm-objdump tests. I wonder if it would be more appropriate for these tests to appear in cross-project-tests, where they could use both lld and llvm-objdump, since they are testing llvm-objdump's behaviour in conjunction with LLD's PLT generation behaviour. Thoughts @MaskRay?

Another slightly wacky idea could be to write the instructions in assembly, use llvm-mc to generate an object file containing the corresponding sections (with pre-computed values for addresses, where needed), then use llvm-objcopy to extract those sections into files that are somehow read and passed as the -D parameter values to yaml2obj. That's probably too much setup to be worthwhile, but just throwing it out there as an option.

std::optional<llvm::endianness> InstrEndianness;
if (const auto *Elf32BE = dyn_cast<ELF32BEObjectFile>(this)) {
if (!Elf32BE->isRelocatableObject() &&
(Elf32BE->getPlatformFlags() & ELF::EF_ARM_BE8)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Doesn't this need some sort of guard that the machine is actually ARM? Otherwise, in theory, you could have a Big Endian object file for a different machine, which just so happens to have a flag with the same value as EF_ARM_BE8.

(It's possible I missed something, so apologies if I have)

Copy link
Member Author

@dzhidzhoev dzhidzhoev Mar 13, 2025

Choose a reason for hiding this comment

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

Thank you for the catch!
Now it uses STI.checkFeatures("+big-endian-instructions") instead of manually checking for flags.

@@ -0,0 +1,104 @@
# Test PLT section with long entries parsing on arm
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: newer tests among the LLVM tools tend to use ## for comments, to help distinguish them from RUN and CHECK lines.

Also missing "." at the end of the sentence.

Suggested change
# Test PLT section with long entries parsing on arm
## Test PLT section with long entries parsing on arm.

Applies throughout.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

@MaskRay
Copy link
Member

MaskRay commented Mar 13, 2025

I'm not a great fan of the big binary blobs in the llvm-objdump tests. I wonder if it would be more appropriate for these tests to appear in cross-project-tests, where they could use both lld and llvm-objdump, since they are testing llvm-objdump's behaviour in conjunction with LLD's PLT generation behaviour. Thoughts @MaskRay?

Another slightly wacky idea could be to write the instructions in assembly, use llvm-mc to generate an object file containing the corresponding sections (with pre-computed values for addresses, where needed), then use llvm-objcopy to extract those sections into files that are somehow read and passed as the -D parameter values to yaml2obj. That's probably too much setup to be worthwhile, but just throwing it out there as an option.

Adding clang --target=armSUFFIX -fuse-ld=lld tests to cross-project-tests seems like a good approach.
We can perhaps create cross-project-tests/tools/llvm-objdump/ARM.

While cross-project-tests might not be the primary focus for all developers, we still have lld/test/ELF tests for the behavior.

Copy link
Collaborator

@smithp35 smithp35 left a comment

Choose a reason for hiding this comment

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

Thanks for the updates. Some really small comments for me, but otherwise looks good to me. I'd better leave the maintainers to approve when they're happy.

@@ -833,10 +840,11 @@ std::vector<ELFPltEntry> ELFObjectFileBase::getPltEntries() const {
consumeError(PltContents.takeError());
return {};
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

Was this extra newline intentional? If not I recommend removing to keep the diff as small as possible

@@ -392,6 +392,18 @@ static MCRelocationInfo *createARMMCRelocationInfo(const Triple &TT,
return llvm::createMCRelocationInfo(TT, Ctx);
}

template <typename T, size_t N>
bool instructionsAreMatching(const T (&Insns)[N], const uint8_t *Buf,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this be made static?

I suggest instructionsMatch as a shorter name. Not got a strong opinion.

// ldr.w pc, [ip]
// b . -4

// Check for movw.
Copy link
Collaborator

Choose a reason for hiding this comment

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

With the additional comments above and variable names I think the // Check for comments aren't needed anymore.


if (instructionsAreMatching(Insns, PltContents.data() + Byte + 8,
InstrEndianness)) {
uint64_t Offset =
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we add a comment

// add ip, pc at Byte + 8 +thumb-pc-bias = 12

if ((Ldr & 0xe5bcf000) != 0xe5bcf000)
continue;

uint64_t Offset = (PltSectionVA + Byte + 8) + ((Add1 & 0xff) << 20) +
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we add a comment
// add ip, pc, #offset at Byte + 0 + arm-pc-bias = 8

Copy link

github-actions bot commented Mar 13, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@dzhidzhoev
Copy link
Member Author

I'm not a great fan of the big binary blobs in the llvm-objdump tests. I wonder if it would be more appropriate for these tests to appear in cross-project-tests, where they could use both lld and llvm-objdump, since they are testing llvm-objdump's behaviour in conjunction with LLD's PLT generation behaviour. Thoughts @MaskRay?
Another slightly wacky idea could be to write the instructions in assembly, use llvm-mc to generate an object file containing the corresponding sections (with pre-computed values for addresses, where needed), then use llvm-objcopy to extract those sections into files that are somehow read and passed as the -D parameter values to yaml2obj. That's probably too much setup to be worthwhile, but just throwing it out there as an option.

Adding clang --target=armSUFFIX -fuse-ld=lld tests to cross-project-tests seems like a good approach. We can perhaps create cross-project-tests/tools/llvm-objdump/ARM.

While cross-project-tests might not be the primary focus for all developers, we still have lld/test/ELF tests for the behavior.

Done

@@ -0,0 +1,243 @@
// Test PLT section parsing on arm.

// RUN: %clang -target armv6a-none-linux-gnueabi -fuse-ld=ld.lld \
Copy link
Member

Choose a reason for hiding this comment

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

-target has been deprecated since about clang 3.4. Use --target=

Use -fuse-ld=lld instead of -fuse-ld=ld.lld, the latter is an abuse of a non-guaranteed behavior of clang driver's -fuse-ld support.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed

// CHECK-NEXT: <_start>:
// CHECK-NEXT: push {r11, lr}
// CHECK-NEXT: mov r11, sp
// CHECK-NEXT: bl 0x10240 <func1@plt>
Copy link
Member

@MaskRay MaskRay Mar 15, 2025

Choose a reason for hiding this comment

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

bl {{.*}} <func1@plt>. The addresses are not reliable. (linker layout might change; compiler codegen might be different; %clang might expand to slightly different options, etc)

(Addresses in lld are sometimes fine as we precisely control how the relocatable files and image files are generated.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed


// THUMB: Disassembly of section .plt:
// THUMB-EMPTY:
// THUMB: 00010270 <func1@plt>:
Copy link
Member

Choose a reason for hiding this comment

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

Delete the leading address. Not reliable

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed

Copy link
Member

@MaskRay MaskRay left a comment

Choose a reason for hiding this comment

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

Changing Triple to const MCSubtargetInfo &STI looks good to me, but perhaps the refactoring could be a separate patch

if (PltSectionRef != SectionNames.end()) {
bool PltIsThumb = false;
for (auto [Addr, SymbolName] : AllMappingSymbols[PltSectionRef->second]) {
if (Addr == 0) {
Copy link
Member

Choose a reason for hiding this comment

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

early return

if (Addr != 0)
  break;
...

PltIsThumb = true;
break;
}
if (SymbolName == 'a') {
Copy link
Member

Choose a reason for hiding this comment

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

remove braces when the body is a single-line simple stmt

auto *ElfObj = dyn_cast<ELFObjectFileBase>(&Obj);
if (!ElfObj)
return;
DenseMap<StringRef, SectionRef> getSectionNames(const ObjectFile &Obj) {
Copy link
Member

Choose a reason for hiding this comment

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

@@ -431,6 +443,126 @@ class ARMMCInstrAnalysis : public MCInstrAnalysis {
std::optional<uint64_t>
evaluateMemoryOperandAddress(const MCInst &Inst, const MCSubtargetInfo *STI,
uint64_t Addr, uint64_t Size) const override;

std::vector<std::pair<uint64_t, uint64_t>>
findPltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents,
Copy link
Member

Choose a reason for hiding this comment

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

Declare it here and define it outside of the class

dzhidzhoev added a commit to dzhidzhoev/llvm-project that referenced this pull request Mar 18, 2025
It allows to check for subtarget features, collected in llvm-objdump.cpp,
in findPltEntries, which will be used in llvm#130764.
@dzhidzhoev
Copy link
Member Author

Changing Triple to const MCSubtargetInfo &STI looks good to me, but perhaps the refactoring could be a separate patch

Created a separate PR for the refactoring change. #131773

dzhidzhoev added a commit that referenced this pull request Mar 18, 2025
It allows access to subtarget features, collected in llvm-objdump.cpp,
from findPltEntries, which will be used in
#130764.
This implements arm, armeb, thumb, thumbeb PLT entries parsing support
in ELF for llvm-objdump.

Implementation is similar to AArch64MCInstrAnalysis::findPltEntries.
PLT entry signatures are based on LLD code for PLT generation (ARM::writePlt).

llvm-objdump tests are generated based on lld/test/ELF/arm-plt-reloc.s,
lld/test/ELF/armv8-thumb-plt-reloc.s.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Mar 18, 2025
…) (#131773)

It allows access to subtarget features, collected in llvm-objdump.cpp,
from findPltEntries, which will be used in
llvm/llvm-project#130764.
@dzhidzhoev dzhidzhoev force-pushed the objdump-arm-plt-parsing branch from f2d41b6 to def15be Compare March 18, 2025 13:28
@dzhidzhoev
Copy link
Member Author

Changing Triple to const MCSubtargetInfo &STI looks good to me, but perhaps the refactoring could be a separate patch

Created a separate PR for the refactoring change. #131773

Rebased this PR on top of it.

@dzhidzhoev
Copy link
Member Author

Gentle ping

// Test PLT section parsing on thumbeb with be8.

// RUN: %clang --target=thumbebv8.1m.main-none-linux-eabi \
// RUN: -nostdlib -nostdinc -c %s -o %t6.o
Copy link
Member

Choose a reason for hiding this comment

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

-c suppresses the link phase. -nostdlib should be removed, as it only affects linking.


// RUN: %clang --target=armv6a-none-linux-gnueabi -fuse-ld=lld \
// RUN: -nostdlib -nostdinc -shared %s -o %t1
// RUN: llvm-objdump --no-show-raw-insn --no-print-imm-hex \
Copy link
Member

@MaskRay MaskRay Mar 25, 2025

Choose a reason for hiding this comment

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

The tet tests v6a/v8m & LE/BE. Perhaps use a more meaningful executable name, say, %tv6 %tv6.be than %t1.

@dzhidzhoev dzhidzhoev merged commit bcad050 into llvm:main Mar 26, 2025
11 checks passed
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