Skip to content

Commit 70d197d

Browse files
author
George Rimar
committedJan 10, 2019
[llvm-objdump] - Implement -z/--disassemble-zeroes.
This is https://bugs.llvm.org/show_bug.cgi?id=37151, GNU objdump spec says that "Normally the disassembly output will skip blocks of zeroes.", but currently, llvm-objdump prints them. The patch implements the -z/--disassemble-zeroes option and switches the default to always skip blocks of zeroes. Differential revision: https://reviews.llvm.org/D56083 llvm-svn: 350823
1 parent 8c221b3 commit 70d197d

File tree

5 files changed

+127
-7
lines changed

5 files changed

+127
-7
lines changed
 

‎llvm/test/CodeGen/Mips/micromips-b-range.ll

+1-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@
4444
; CHECK-NEXT: 9a: ff fd 00 00 lw $ra, 0($sp)
4545
; CHECK-NEXT: 9e: 00 01 0f 3c jr $1
4646
; CHECK-NEXT: a2: 33 bd 00 08 addiu $sp, $sp, 8
47-
48-
; CHECK: 10466: 00 00 00 00 nop
47+
; CHECK: ...
4948
; CHECK-NEXT: 1046a: 94 00 00 02 b 8 <foo+0x10472>
5049
; CHECK-NEXT: 1046e: 00 00 00 00 nop
5150
; CHECK-NEXT: 10472: 33 bd ff f8 addiu $sp, $sp, -8

‎llvm/test/MC/Mips/cpsetup.s

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
# RUN: llvm-mc -triple mips-unknown-linux -target-abi o32 -filetype=obj -o - %s | \
2-
# RUN: llvm-objdump -d -r - | FileCheck -check-prefixes=ALL,O32 %s
2+
# RUN: llvm-objdump -d -r -z - | FileCheck -check-prefixes=ALL,O32 %s
33

44
# RUN: llvm-mc -triple mips-unknown-linux -target-abi o32 %s | \
55
# RUN: FileCheck -check-prefixes=ALL,ASM,ASM-O32 %s
66

77
# FIXME: Now we check .cpsetup expansion for `-mno-shared` case only.
88
# We also need to implement/check the `-mshared` case.
99
# RUN: llvm-mc -triple mips64-unknown-linux -target-abi n32 -filetype=obj -o - %s | \
10-
# RUN: llvm-objdump -d -r - | \
10+
# RUN: llvm-objdump -d -r -z - | \
1111
# RUN: FileCheck -check-prefixes=ALL,NXX,N32 %s
1212

1313
# RUN: llvm-mc -triple mips64-unknown-linux -target-abi n32 %s | \
1414
# RUN: FileCheck -check-prefixes=ALL,ASM,ASM-N32 %s
1515

1616
# RUN: llvm-mc -triple mips64-unknown-linux %s -filetype=obj -o - | \
17-
# RUN: llvm-objdump -d -r - | \
17+
# RUN: llvm-objdump -d -r -z - | \
1818
# RUN: FileCheck -check-prefixes=ALL,NXX,N64 %s
1919

2020
# RUN: llvm-mc -triple mips64-unknown-linux %s | \

‎llvm/test/MC/Mips/nacl-mask.s

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-nacl %s \
2-
# RUN: | llvm-objdump -disassemble -no-show-raw-insn - | FileCheck %s
2+
# RUN: | llvm-objdump -disassemble -z -no-show-raw-insn - | FileCheck %s
33

44
# This test tests that address-masking sandboxing is added when given assembly
55
# input.

‎llvm/test/MC/X86/disassemble-zeroes.s

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t
2+
// RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=NODISASM
3+
4+
// The exact rules of skipping the bytes you can find in the code.
5+
// This test checks that we follow these rules and can force
6+
// dissasembly of zero blocks with the -z and --disassemble-zeroes options.
7+
8+
// NODISASM: Disassembly of section .text:
9+
// NODISASM-NEXT: 0000000000000000 main:
10+
// NODISASM-NEXT: 0: 00 00 addb %al, (%rax)
11+
// NODISASM-NEXT: 2: 00 00 addb %al, (%rax)
12+
// NODISASM-NEXT: 4: 00 00 addb %al, (%rax)
13+
// NODISASM-NEXT: 6: 00 90 00 00 00 00 addb %dl, (%rax)
14+
// NODISASM-NEXT: ...
15+
// NODISASM-NEXT: 20: 90 nop
16+
// NODISASM-NEXT: ...
17+
// NODISASM: 0000000000000031 foo:
18+
// NODISASM-NEXT: 31: 00 00 addb %al, (%rax)
19+
// NODISASM-NEXT: 33: 00 00 addb %al, (%rax)
20+
// NODISASM: 0000000000000035 bar:
21+
// NODISASM-NEXT: ...
22+
23+
// Check that with -z we disassemble blocks of zeroes.
24+
// RUN: llvm-objdump -d -z %t | FileCheck %s --check-prefix=DISASM
25+
26+
// DISASM: Disassembly of section .text:
27+
// DISASM-NEXT: 0000000000000000 main:
28+
// DISASM-NEXT: 0: 00 00 addb %al, (%rax)
29+
// DISASM-NEXT: 2: 00 00 addb %al, (%rax)
30+
// DISASM-NEXT: 4: 00 00 addb %al, (%rax)
31+
// DISASM-NEXT: 6: 00 90 00 00 00 00 addb %dl, (%rax)
32+
// DISASM-NEXT: c: 00 00 addb %al, (%rax)
33+
// DISASM-NEXT: e: 00 00 addb %al, (%rax)
34+
// DISASM-NEXT: 10: 00 00 addb %al, (%rax)
35+
// DISASM-NEXT: 12: 00 00 addb %al, (%rax)
36+
// DISASM-NEXT: 14: 00 00 addb %al, (%rax)
37+
// DISASM-NEXT: 16: 00 00 addb %al, (%rax)
38+
// DISASM-NEXT: 18: 00 00 addb %al, (%rax)
39+
// DISASM-NEXT: 1a: 00 00 addb %al, (%rax)
40+
// DISASM-NEXT: 1c: 00 00 addb %al, (%rax)
41+
// DISASM-NEXT: 1e: 00 00 addb %al, (%rax)
42+
// DISASM-NEXT: 20: 90 nop
43+
// DISASM-NEXT: 21: 00 00 addb %al, (%rax)
44+
// DISASM-NEXT: 23: 00 00 addb %al, (%rax)
45+
// DISASM-NEXT: 25: 00 00 addb %al, (%rax)
46+
// DISASM-NEXT: 27: 00 00 addb %al, (%rax)
47+
// DISASM-NEXT: 29: 00 00 addb %al, (%rax)
48+
// DISASM-NEXT: 2b: 00 00 addb %al, (%rax)
49+
// DISASM-NEXT: 2d: 00 00 addb %al, (%rax)
50+
// DISASM-NEXT: 2f: 00 00 addb %al, (%rax)
51+
// DISASM: 0000000000000031 foo:
52+
// DISASM-NEXT: 31: 00 00 addb %al, (%rax)
53+
// DISASM-NEXT: 33: 00 00 addb %al, (%rax)
54+
// DISASM: 0000000000000035 bar:
55+
// DISASM-NEXT: 35: 00 00 addb %al, (%rax)
56+
// DISASM-NEXT: 37: 00 00 addb %al, (%rax)
57+
// DISASM-NEXT: 39: 00 00 addb %al, (%rax)
58+
// DISASM-NEXT: 3b: 00 00 addb %al, (%rax)
59+
60+
// Check that --disassemble-zeroes work as alias for -z.
61+
// RUN: llvm-objdump -d --disassemble-zeroes %t | FileCheck %s --check-prefix=DISASM
62+
63+
.text
64+
.globl main
65+
.type main, @function
66+
main:
67+
.long 0
68+
.byte 0
69+
.byte 0
70+
.byte 0
71+
nop
72+
.quad 0
73+
.quad 0
74+
.quad 0
75+
nop
76+
.quad 0
77+
.quad 0
78+
foo:
79+
.long 0
80+
bar:
81+
.quad 0

‎llvm/tools/llvm-objdump/llvm-objdump.cpp

+41-1
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,17 @@ cl::opt<unsigned long long>
265265
StartAddress("start-address", cl::desc("Disassemble beginning at address"),
266266
cl::value_desc("address"), cl::init(0));
267267
cl::opt<unsigned long long>
268-
StopAddress("stop-address", cl::desc("Stop disassembly at address"),
268+
StopAddress("stop-address",
269+
cl::desc("Do not skip blocks of zeroes when disassembling"),
269270
cl::value_desc("address"), cl::init(UINT64_MAX));
271+
272+
cl::opt<bool> DisassembleZeroes("disassemble-zeroes",
273+
cl::desc("Do not skip blocks of zeroes when "
274+
"disassembling the blocks of zeroes"));
275+
cl::alias DisassembleZeroesShort("z",
276+
cl::desc("Alias for --disassemble-zeroes"),
277+
cl::aliasopt(DisassembleZeroes));
278+
270279
static StringRef ToolName;
271280

272281
typedef std::vector<std::tuple<uint64_t, StringRef, uint8_t>> SectionSymbolsTy;
@@ -1298,6 +1307,29 @@ static void addPltEntries(const ObjectFile *Obj,
12981307
}
12991308
}
13001309

1310+
// Normally the disassembly output will skip blocks of zeroes. This function
1311+
// returns the number of zero bytes that can be skipped when dumping the
1312+
// disassembly of the instructions in Buf.
1313+
static size_t countSkippableZeroBytes(ArrayRef<uint8_t> Buf) {
1314+
// When -z or --disassemble-zeroes are given we always dissasemble them.
1315+
if (DisassembleZeroes)
1316+
return 0;
1317+
1318+
// Find the number of leading zeroes.
1319+
size_t N = 0;
1320+
while (N < Buf.size() && !Buf[N])
1321+
++N;
1322+
1323+
// We may want to skip blocks of zero bytes, but unless we see
1324+
// at least 8 of them in a row.
1325+
if (N < 8)
1326+
return 0;
1327+
1328+
// We skip zeroes in multiples of 4 because do not want to truncate an
1329+
// instruction if it starts with a zero byte.
1330+
return N & ~0x3;
1331+
}
1332+
13011333
static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
13021334
if (StartAddress > StopAddress)
13031335
error("Start address should be less than stop address");
@@ -1732,6 +1764,14 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
17321764
if (Index >= End)
17331765
break;
17341766

1767+
if (size_t N =
1768+
countSkippableZeroBytes(Bytes.slice(Index, End - Index))) {
1769+
outs() << "\t\t..." << '\n';
1770+
Index += N;
1771+
if (Index >= End)
1772+
break;
1773+
}
1774+
17351775
// Disassemble a real instruction or a data when disassemble all is
17361776
// provided
17371777
bool Disassembled = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),

0 commit comments

Comments
 (0)
Please sign in to comment.