Skip to content

Commit

Permalink
tools: support decoding ARM EHABI opcodes in readobj
Browse files Browse the repository at this point in the history
Add support to llvm-readobj to decode the actual opcodes.  The ARM EHABI opcodes
are a variable length instruction set that describe the operations required for
properly unwinding stack frames.

The primary motivation for this change is to ease the creation of tests for the
ARM EHABI object emission as well as the unwinding directive handling in the ARM
IAS.

Thanks to Logan Chien for an extra test case!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199708 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
compnerd committed Jan 21, 2014
1 parent e502a6a commit d28c094
Show file tree
Hide file tree
Showing 3 changed files with 449 additions and 43 deletions.
33 changes: 15 additions & 18 deletions test/MC/ARM/eh-directive-unwind_raw.s
Original file line number Diff line number Diff line change
Expand Up @@ -62,49 +62,46 @@ stack_adjust:
@ CHECK: Model: Compact (Inline)
@ CHECK: PersonalityIndex: 0
@ CHECK: Opcodes [
@ CHECK: Opcode: 0xB1
@ CHECK: Opcode: 0x1
@ CHECK: Opcode: 0xB0
@ CHECK: 0xB1 0x01 ; pop {r0}
@ CHECK: 0xB0 ; finish
@ CHECK: ]
@ CHECK: }
@ CHECK: Entry {
@ CHECK: Model: Compact (Inline)
@ CHECK: PersonalityIndex: 0
@ CHECK: Opcodes [
@ CHECK: Opcode: 0xB0
@ CHECK: Opcode: 0xB0
@ CHECK: Opcode: 0xB0
@ CHECK: 0xB0 ; finish
@ CHECK: 0xB0 ; finish
@ CHECK: 0xB0 ; finish
@ CHECK: ]
@ CHECK: }
@ CHECK: Entry {
@ CHECK: ExceptionHandlingTable: .ARM.extab
@ CHECK: Model: Compact
@ CHECK: PersonalityIndex: 1
@ CHECK: Opcodes [
@ CHECK: Opcode: 0x9B
@ CHECK: Opcode: 0x40
@ CHECK: Opcode: 0x84
@ CHECK: Opcode: 0x80
@ CHECK: Opcode: 0xB0
@ CHECK: Opcode: 0xB0
@ CHECK: 0x9B ; vsp = r11
@ CHECK: 0x40 ; vsp = vsp - 4
@ CHECK: 0x84 0x80 ; pop {fp, lr}
@ CHECK: 0xB0 ; finish
@ CHECK: 0xB0 ; finish
@ CHECK: ]
@ CHECK: }
@ CHECK: Entry {
@ CHECK: Model: Compact (Inline)
@ CHECK: PersonalityIndex: 0
@ CHECK: Opcodes [
@ CHECK: Opcode: 0x80
@ CHECK: Opcode: 0x0
@ CHECK: Opcode: 0xB0
@ CHECK: 0x80 0x00 ; refuse to unwind
@ CHECK: 0xB0 ; finish
@ CHECK: ]
@ CHECK: }
@ CHECK: Entry {
@ CHECK: Model: Compact (Inline)
@ CHECK: PersonalityIndex: 0
@ CHECK: Opcodes [
@ CHECK: Opcode: 0x9B
@ CHECK: Opcode: 0x4D
@ CHECK: Opcode: 0xC2
@ CHECK: 0x9B ; vsp = r11
@ CHECK: 0x4D ; vsp = vsp - 56
@ CHECK: 0xC2 ; pop {wR10, wR11, wR12}
@ CHECK: ]
@ CHECK: }
@ CHECK: ]
Expand Down
169 changes: 146 additions & 23 deletions test/tools/llvm-readobj/ARM/unwind.s
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@ RUN: llvm-mc -triple armv7-eabi -filetype obj -o - %s | llvm-readobj -u - \
@ RUN: | FileCheck %s
@ RUN: llvm-mc -triple armv7-linux-eabi -filetype obj -o - %s \
@ RUN: | llvm-readobj -u | FileCheck %s

.syntax unified

Expand Down Expand Up @@ -82,6 +82,69 @@ function2:
bx lr
.fnend

.section .raw

.type raw,%function
.thumb_func
raw:
.fnstart
.unwind_raw 12, 0x02
.unwind_raw -12, 0x42
.unwind_raw 0, 0x80, 0x00
.unwind_raw 4, 0x81, 0x00
.unwind_raw 4, 0x80, 0x01
.unwind_raw 8, 0x80, 0xc0
.unwind_raw 12, 0x84, 0xc0
.unwind_raw 0, 0x91
.unwind_raw 8, 0xa1
.unwind_raw 12, 0xa9
.unwind_raw 0, 0xb0
.unwind_raw 4, 0xb1, 0x01
.unwind_raw 0xa04, 0xb2, 0x80, 0x04
.unwind_raw 24, 0xb3, 0x12
.unwind_raw 24, 0xba
.unwind_raw 24, 0xc2
.unwind_raw 24, 0xc6, 0x02
.unwind_raw 8, 0xc7, 0x03
.unwind_raw 24, 0xc8, 0x02
.unwind_raw 24, 0xc9, 0x02
.unwind_raw 64, 0xd7
.fnend

.section .spare

.type spare,%function
spare:
.fnstart
.unwind_raw 4, 0x00
.unwind_raw -4, 0x40
.unwind_raw 0, 0x80, 0x00
.unwind_raw 4, 0x88, 0x00
.unwind_raw 0, 0x91
.unwind_raw 0, 0x9d
.unwind_raw 0, 0x9f
.unwind_raw 0, 0xa0
.unwind_raw 0, 0xa8
.unwind_raw 0, 0xb0
.unwind_raw 0, 0xb1, 0x00
.unwind_raw 4, 0xb1, 0x01
.unwind_raw 0, 0xb1, 0x10
.unwind_raw 0x204, 0xb2, 0x00
.unwind_raw 16, 0xb3, 0x00
.unwind_raw 0, 0xb4
.unwind_raw 16, 0xb8
.unwind_raw 4, 0xc0
.unwind_raw 4, 0xc6, 0x00
.unwind_raw 4, 0xc7, 0x00
.unwind_raw 4, 0xc7, 0x01
.unwind_raw 0, 0xc7, 0x10
.unwind_raw 16, 0xc8, 0x00
.unwind_raw 16, 0xc9, 0x00
.unwind_raw 0, 0xca
.unwind_raw 16, 0xd0
.unwind_raw 0, 0xd8
.fnend

@ CHECK: UnwindInformation {
@ CHECK: UnwindIndexTable {
@ CHECK: SectionName: .ARM.exidx.personality
Expand All @@ -92,9 +155,9 @@ function2:
@ CHECK: Model: Compact (Inline)
@ CHECK: PersonalityIndex: 0
@ CHECK: Opcodes [
@ CHECK: Opcode: 0xB0
@ CHECK: Opcode: 0xB0
@ CHECK: Opcode: 0xB0
@ CHECK: 0xB0 ; finish
@ CHECK: 0xB0 ; finish
@ CHECK: 0xB0 ; finish
@ CHECK: ]
@ CHECK: }
@ CHECK: ]
Expand All @@ -108,9 +171,9 @@ function2:
@ CHECK: Model: Compact (Inline)
@ CHECK: PersonalityIndex: 0
@ CHECK: Opcodes [
@ CHECK: Opcode: 0xB0
@ CHECK: Opcode: 0xB0
@ CHECK: Opcode: 0xB0
@ CHECK: 0xB0 ; finish
@ CHECK: 0xB0 ; finish
@ CHECK: 0xB0 ; finish
@ CHECK: ]
@ CHECK: }
@ CHECK: ]
Expand All @@ -126,12 +189,11 @@ function2:
@ CHECK: Model: Compact
@ CHECK: PersonalityIndex: 1
@ CHECK: Opcodes [
@ CHECK: Opcode: 0xB1
@ CHECK: Opcode: 0xF
@ CHECK: Opcode: 0xA7
@ CHECK: Opcode: 0x3F
@ CHECK: Opcode: 0xB0
@ CHECK: Opcode: 0xB0
@ CHECK: 0xB1 0x0F ; pop {r0, r1, r2, r3}
@ CHECK: 0xA7 ; pop {r4, r5, r6, r7, r8, r9, r10, fp}
@ CHECK: 0x3F ; vsp = vsp + 256
@ CHECK: 0xB0 ; finish
@ CHECK: 0xB0 ; finish
@ CHECK: ]
@ CHECK: }
@ CHECK: ]
Expand All @@ -158,9 +220,8 @@ function2:
@ CHECK: Model: Compact (Inline)
@ CHECK: PersonalityIndex: 0
@ CHECK: Opcodes [
@ CHECK: Opcode: 0xC9
@ CHECK: Opcode: 0x84
@ CHECK: Opcode: 0xB0
@ CHECK: 0xC9 0x84 ; pop {d8, d9, d10, d11, d12}
@ CHECK: 0xB0 ; finish
@ CHECK: ]
@ CHECK: }
@ CHECK: ]
Expand All @@ -174,9 +235,9 @@ function2:
@ CHECK: Model: Compact (Inline)
@ CHECK: PersonalityIndex: 0
@ CHECK: Opcodes [
@ CHECK: Opcode: 0xB0
@ CHECK: Opcode: 0xB0
@ CHECK: Opcode: 0xB0
@ CHECK: 0xB0 ; finish
@ CHECK: 0xB0 ; finish
@ CHECK: 0xB0 ; finish
@ CHECK: ]
@ CHECK: }
@ CHECK: Entry {
Expand All @@ -192,12 +253,74 @@ function2:
@ CHECK: Model: Compact (Inline)
@ CHECK: PersonalityIndex: 0
@ CHECK: Opcodes [
@ CHECK: Opcode: 0xB0
@ CHECK: Opcode: 0xB0
@ CHECK: Opcode: 0xB0
@ CHECK: 0xB0 ; finish
@ CHECK: 0xB0 ; finish
@ CHECK: 0xB0 ; finish
@ CHECK: ]
@ CHECK: }
@ CHECK: ]
@ CHECK: }
@ CHECK: UnwindIndexTable {
@ CHECK: SectionName: .ARM.exidx.raw
@ CHECK: Entries [
@ CHECK: Opcodes [
@ CHECK: 0xD7 ; pop {d8, d9, d10, d11, d12, d13, d14, d15}
@ CHECK: 0xC9 0x02 ; pop {d0, d1, d2}
@ CHECK: 0xC8 0x02 ; pop {d16, d17, d18}
@ CHECK: 0xC7 0x03 ; pop {wCGR0, wCGR1}
@ CHECK: 0xC6 0x02 ; pop {wR0, wR1, wR2}
@ CHECK: 0xC2 ; pop {wR10, wR11, wR12}
@ CHECK: 0xBA ; pop {d8, d9, d10}
@ CHECK: 0xB3 0x12 ; pop {d1, d2, d3}
@ CHECK: 0xB2 0x80 0x04 ; vsp = vsp + 2564
@ CHECK: 0xB1 0x01 ; pop {r0}
@ CHECK: 0xB0 ; finish
@ CHECK: 0xA9 ; pop {r4, r5, lr}
@ CHECK: 0xA1 ; pop {r4, r5}
@ CHECK: 0x91 ; vsp = r1
@ CHECK: 0x84 0xC0 ; pop {r10, fp, lr}
@ CHECK: 0x80 0xC0 ; pop {r10, fp}
@ CHECK: 0x80 0x01 ; pop {r4}
@ CHECK: 0x81 0x00 ; pop {ip}
@ CHECK: 0x80 0x00 ; refuse to unwind
@ CHECK: 0x42 ; vsp = vsp - 12
@ CHECK: 0x02 ; vsp = vsp + 12
@ CHECK: ]
@ CHECK: ]
@ CHECK: }
@ CHECK: UnwindIndexTable {
@ CHECK: SectionName: .ARM.exidx.spare
@ CHECK: Entries [
@ CHECK: Opcodes [
@ CHECK: 0xD8 ; spare
@ CHECK: 0xD0 ; pop {d8}
@ CHECK: 0xCA ; spare
@ CHECK: 0xC9 0x00 ; pop {d0}
@ CHECK: 0xC8 0x00 ; pop {d16}
@ CHECK: 0xC7 0x10 ; spare
@ CHECK: 0xC7 0x01 ; pop {wCGR0}
@ CHECK: 0xC7 0x00 ; spare
@ CHECK: 0xC6 0x00 ; pop {wR0}
@ CHECK: 0xC0 ; pop {wR10}
@ CHECK: 0xB8 ; pop {d8}
@ CHECK: 0xB4 ; spare
@ CHECK: 0xB3 0x00 ; pop {d0}
@ CHECK: 0xB2 0x00 ; vsp = vsp + 516
@ CHECK: 0xB1 0x10 ; spare
@ CHECK: 0xB1 0x01 ; pop {r0}
@ CHECK: 0xB1 0x00 ; spare
@ CHECK: 0xB0 ; finish
@ CHECK: 0xA8 ; pop {r4, lr}
@ CHECK: 0xA0 ; pop {r4}
@ CHECK: 0x9F ; reserved (WiMMX MOVrr)
@ CHECK: 0x9D ; reserved (ARM MOVrr)
@ CHECK: 0x91 ; vsp = r1
@ CHECK: 0x88 0x00 ; pop {pc}
@ CHECK: 0x80 0x00 ; refuse to unwind
@ CHECK: 0x40 ; vsp = vsp - 4
@ CHECK: 0x00 ; vsp = vsp + 4
@ CHECK: ]
@ CHECK: ]
@ CHECK: }
@ CHECK: }

Loading

0 comments on commit d28c094

Please sign in to comment.