Skip to contentSkip to conversation

scripts/decodecode: Fix decoding for AArch64 (arm64) instructions

PATCH Applied Will Deacon 2 participants 6 messages Sep 28, 2017 – Sep 29, 2017

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 scripts/decodecode: Fix decoding for AArch64 (arm64) instructions

There are a couple of problems with the decodecode script and arm64:

1. AArch64 objdump refuses to disassemble .4byte directives as instructions, insisting that they are data values and displaying them as:

	a94153f3	.word	0xa94153f3		<-- trapping instruction

This is resolved by using the .inst directive instead.

2. Disassembly of branch instructions attempts to provide the target as an offset from a symbol, e.g.:

0: 34000082 cbz w2, 10 <.text+0x10>

however this falls foul of the grep -v, which matches lines containing ".text" and ends up removing all branch instructions from the dump.

This patch resolves both issues by using the .inst directive for 4-byte quantities on arm64 and stripping the resulting binaries (as is done on arm already) to remove the mapping symbols.

---
 scripts/decodecode | 8 ++++++++
 1 file changed, 8 insertions(+)
scripts/decodecode +8 -0
index d8824f37acce..67214ec5b2cb 100755
@@ -58,6 +58,14 @@ disas() {
 		${CROSS_COMPILE}strip $1.o
 	fi
 
+	if [ "$ARCH" = "arm64" ]; then
+		if [ $width -eq 4 ]; then
+			type=inst
+		fi
+
+		${CROSS_COMPILE}strip $1.o
+	fi
+
 	${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
 		grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1
 }
Signature · 1 line
2.1.4
Reviewed-by on v1 1/1
#1 lore raw
Quoted 9 lines · Will Deacon

There are a couple of problems with the decodecode script and arm64:

1. AArch64 objdump refuses to disassemble .4byte directives as instructions, insisting that they are data values and displaying them as:

	a94153f3	.word	0xa94153f3		<-- trapping instruction

This is resolved by using the .inst directive instead.

Quoted 7 lines

2. Disassembly of branch instructions attempts to provide the target as an offset from a symbol, e.g.:

   0:	34000082	cbz	w2, 10 <.text+0x10>

however this falls foul of the grep -v, which matches lines containing ".text" and ends up removing all branch instructions from the dump.

Any idea why this doesn't affect other arches too ... or does it?

Quoted 15 lines

This patch resolves both issues by using the .inst directive for 4-byte quantities on arm64 and stripping the resulting binaries (as is done on arm already) to remove the mapping symbols.

---
 scripts/decodecode | 8 ++++++++
 1 file changed, 8 insertions(+)
scripts/decodecode +0 -0
index d8824f37acce..67214ec5b2cb 100755

scripts/decodecode disas() { · line 63

Quoted 6 lines
scripts/decodecode +3 -0
@@ -58,6 +58,14 @@ disas() {
 		${CROSS_COMPILE}strip $1.o
 	fi
 
+	if [ "$ARCH" = "arm64" ]; then
+		if [ $width -eq 4 ]; then
+			type=inst

Can we merge with arm here, or does arm still support toolchains that don't have .inst? Anyway, no big deal.

scripts/decodecode disas() { · line 70

Quoted 7 lines
scripts/decodecode +5 -0
+		fi
+
+		${CROSS_COMPILE}strip $1.o
+	fi
+
 	${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
 		grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1

FWIW,

Here's hoping someone runs this as a CGI script somewhere ;)

Cheers
---Dave

#2 lore raw
Quoted 13 lines · Dave Martin
Quoted 12 lines · Will Deacon

There are a couple of problems with the decodecode script and arm64:

1. AArch64 objdump refuses to disassemble .4byte directives as instructions, insisting that they are data values and displaying them as:

	a94153f3	.word	0xa94153f3		<-- trapping instruction

This is resolved by using the .inst directive instead.

2. Disassembly of branch instructions attempts to provide the target as an offset from a symbol, e.g.:

Quoted 6 lines
Quoted 4 lines
   0:	34000082	cbz	w2, 10 <.text+0x10>

however this falls foul of the grep -v, which matches lines containing ".text" and ends up removing all branch instructions from the dump.

Any idea why this doesn't affect other arches too ... or does it?

I'm not sure, although I don't know how .inst works for architectures with variable-length instructions and I *guess* the disassembly is less fussy about data vs text for those targets.

Quoted 18 lines
Quoted 18 lines

This patch resolves both issues by using the .inst directive for 4-byte quantities on arm64 and stripping the resulting binaries (as is done on arm already) to remove the mapping symbols.

---
 scripts/decodecode | 8 ++++++++
 1 file changed, 8 insertions(+)
scripts/decodecode +0 -0
index d8824f37acce..67214ec5b2cb 100755
@@ -58,6 +58,14 @@ disas() {
 		${CROSS_COMPILE}strip $1.o
 	fi
 
Quoted 6 lines

scripts/decodecode disas() { · line 63

Quoted 3 lines
scripts/decodecode +3 -0
+	if [ "$ARCH" = "arm64" ]; then
+		if [ $width -eq 4 ]; then
+			type=inst

Can we merge with arm here, or does arm still support toolchains that don't have .inst? Anyway, no big deal.

I thought we still supported those, so I'd be reluctant to merge the clauses unless it's broken (the script works as-is for me with arm). I'm also not sure what we should do for 16-bit Thumb-2 encodings, where we have inst.n and inst.w to contend with.

Quoted 11 lines

scripts/decodecode disas() { · line 70

Quoted 7 lines
scripts/decodecode +5 -0
+		fi
+
+		${CROSS_COMPILE}strip $1.o
+	fi
+
 	${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
 		grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1

FWIW,

Thanks!

Will

#3 lore raw
Quoted 16 lines · Will Deacon
Quoted 15 lines · Dave Martin
Quoted 14 lines · Will Deacon

There are a couple of problems with the decodecode script and arm64:

1. AArch64 objdump refuses to disassemble .4byte directives as instructions, insisting that they are data values and displaying them as:

	a94153f3	.word	0xa94153f3		<-- trapping instruction

This is resolved by using the .inst directive instead.

2. Disassembly of branch instructions attempts to provide the target as an offset from a symbol, e.g.:

   0:	34000082	cbz	w2, 10 <.text+0x10>
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

however this falls foul of the grep -v, which matches lines containing ".text" and ends up removing all branch instructions from the dump.

Any idea why this doesn't affect other arches too ... or does it?

I'm not sure, although I don't know how .inst works for architectures with variable-length instructions and I *guess* the disassembly is less fussy about data vs text for those targets.

I rather meant the target disassembly for relative branches in the absence of labels.

Anyway, I think this is at least harmless to other arches, and possibly helpful to them (if they disassemble those branch targets in the same sort of way).

Quoted 25 lines
Quoted 18 lines
Quoted 18 lines

This patch resolves both issues by using the .inst directive for 4-byte quantities on arm64 and stripping the resulting binaries (as is done on arm already) to remove the mapping symbols.

---
 scripts/decodecode | 8 ++++++++
 1 file changed, 8 insertions(+)
scripts/decodecode +0 -0
index d8824f37acce..67214ec5b2cb 100755
@@ -58,6 +58,14 @@ disas() {
 		${CROSS_COMPILE}strip $1.o
 	fi
 
Quoted 6 lines

scripts/decodecode disas() { · line 63

Quoted 3 lines
scripts/decodecode +3 -0
+	if [ "$ARCH" = "arm64" ]; then
+		if [ $width -eq 4 ]; then
+			type=inst

Can we merge with arm here, or does arm still support toolchains that don't have .inst? Anyway, no big deal.

Quoted 4 lines

I thought we still supported those, so I'd be reluctant to merge the clauses unless it's broken (the script works as-is for me with arm). I'm also not sure what we should do for 16-bit Thumb-2 encodings, where we have inst.n and inst.w to contend with.

Fair enough. I suspected as much, too.

Cheers
---Dave

Quoted 20 lines
Quoted 11 lines

scripts/decodecode disas() { · line 70

Quoted 7 lines
scripts/decodecode +5 -0
+		fi
+
+		${CROSS_COMPILE}strip $1.o
+	fi
+
 	${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
 		grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1

FWIW,

Thanks!

Will

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

#4 lore raw
Quoted 26 lines · Dave Martin
Quoted 16 lines · Will Deacon
Quoted 15 lines · Dave Martin
Quoted 14 lines · Will Deacon

There are a couple of problems with the decodecode script and arm64:

1. AArch64 objdump refuses to disassemble .4byte directives as instructions, insisting that they are data values and displaying them as:

	a94153f3	.word	0xa94153f3		<-- trapping instruction

This is resolved by using the .inst directive instead.

2. Disassembly of branch instructions attempts to provide the target as an offset from a symbol, e.g.:

   0:	34000082	cbz	w2, 10 <.text+0x10>
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

however this falls foul of the grep -v, which matches lines containing ".text" and ends up removing all branch instructions from the dump.

Any idea why this doesn't affect other arches too ... or does it?

I'm not sure, although I don't know how .inst works for architectures with variable-length instructions and I *guess* the disassembly is less fussy about data vs text for those targets.

Quoted 6 lines

I rather meant the target disassembly for relative branches in the absence of labels.

Anyway, I think this is at least harmless to other arches, and possibly helpful to them (if they disassemble those branch targets in the same sort of way).

Ah, I see what you mean. Something like the fixup below on top.

Will

--->8

scripts/decodecode +5 -12
index 67214ec5b2cb..f1ec57c3cbf7 100755
@@ -49,21 +49,14 @@ esac
 
 disas() {
 	${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s > /dev/null 2>&1
+	${CROSS_COMPILE}strip $1.o
 
-	if [ "$ARCH" = "arm" ]; then
-		if [ $width -eq 2 ]; then
-			OBJDUMPFLAGS="-M force-thumb"
-		fi
-
-		${CROSS_COMPILE}strip $1.o
+	if [ "$ARCH" = "arm" -a $width -eq 2 ]; then
+		OBJDUMPFLAGS="-M force-thumb"
 	fi
 
-	if [ "$ARCH" = "arm64" ]; then
-		if [ $width -eq 4 ]; then
-			type=inst
-		fi
-
-		${CROSS_COMPILE}strip $1.o
+	if [ "$ARCH" = "arm64" -a $width -eq 4 ]; then
+		type=inst
 	fi
 
 	${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
#5 lore raw
Quoted 59 lines · Will Deacon
Quoted 26 lines · Dave Martin
Quoted 16 lines · Will Deacon
Quoted 15 lines · Dave Martin
Quoted 14 lines · Will Deacon

There are a couple of problems with the decodecode script and arm64:

1. AArch64 objdump refuses to disassemble .4byte directives as instructions, insisting that they are data values and displaying them as:

	a94153f3	.word	0xa94153f3		<-- trapping instruction

This is resolved by using the .inst directive instead.

2. Disassembly of branch instructions attempts to provide the target as an offset from a symbol, e.g.:

   0:	34000082	cbz	w2, 10 <.text+0x10>
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

however this falls foul of the grep -v, which matches lines containing ".text" and ends up removing all branch instructions from the dump.

Any idea why this doesn't affect other arches too ... or does it?

I'm not sure, although I don't know how .inst works for architectures with variable-length instructions and I *guess* the disassembly is less fussy about data vs text for those targets.

Quoted 6 lines

I rather meant the target disassembly for relative branches in the absence of labels.

Anyway, I think this is at least harmless to other arches, and possibly helpful to them (if they disassemble those branch targets in the same sort of way).

Ah, I see what you mean. Something like the fixup below on top.

Will

--->8

scripts/decodecode +3 -6
index 67214ec5b2cb..f1ec57c3cbf7 100755
@@ -49,21 +49,14 @@ esac
 
 disas() {
 	${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s > /dev/null 2>&1
+	${CROSS_COMPILE}strip $1.o
 
-	if [ "$ARCH" = "arm" ]; then
-		if [ $width -eq 2 ]; then
-			OBJDUMPFLAGS="-M force-thumb"
-		fi
-
-		${CROSS_COMPILE}strip $1.o
+	if [ "$ARCH" = "arm" -a $width -eq 2 ]; then
+		OBJDUMPFLAGS="-M force-thumb"
 	fi

scripts/decodecode esac · line 60

Quoted 10 lines
scripts/decodecode +2 -6
 
-	if [ "$ARCH" = "arm64" ]; then
-		if [ $width -eq 4 ]; then
-			type=inst
-		fi
-
-		${CROSS_COMPILE}strip $1.o
+	if [ "$ARCH" = "arm64" -a $width -eq 4 ]; then
+		type=inst
 	fi

Reasonable, though I guess it doesn't matter unless another arch really cares -- in which case someone will eventually spot the issue and probably write the same patch.

Cheers
---Dave