; CHECK-NEXT: 9a: ff fd 00 00 lw $ra, 0($sp)
; CHECK-NEXT: 9e: 00 01 0f 3c jr $1
; CHECK-NEXT: a2: 33 bd 00 08 addiu $sp, $sp, 8
-
-; CHECK: 10466: 00 00 00 00 nop
+; CHECK: ...
; CHECK-NEXT: 1046a: 94 00 00 02 b 8 <foo+0x10472>
; CHECK-NEXT: 1046e: 00 00 00 00 nop
; CHECK-NEXT: 10472: 33 bd ff f8 addiu $sp, $sp, -8
# RUN: llvm-mc -triple mips-unknown-linux -target-abi o32 -filetype=obj -o - %s | \
-# RUN: llvm-objdump -d -r - | FileCheck -check-prefixes=ALL,O32 %s
+# RUN: llvm-objdump -d -r -z - | FileCheck -check-prefixes=ALL,O32 %s
# RUN: llvm-mc -triple mips-unknown-linux -target-abi o32 %s | \
# RUN: FileCheck -check-prefixes=ALL,ASM,ASM-O32 %s
# FIXME: Now we check .cpsetup expansion for `-mno-shared` case only.
# We also need to implement/check the `-mshared` case.
# RUN: llvm-mc -triple mips64-unknown-linux -target-abi n32 -filetype=obj -o - %s | \
-# RUN: llvm-objdump -d -r - | \
+# RUN: llvm-objdump -d -r -z - | \
# RUN: FileCheck -check-prefixes=ALL,NXX,N32 %s
# RUN: llvm-mc -triple mips64-unknown-linux -target-abi n32 %s | \
# RUN: FileCheck -check-prefixes=ALL,ASM,ASM-N32 %s
# RUN: llvm-mc -triple mips64-unknown-linux %s -filetype=obj -o - | \
-# RUN: llvm-objdump -d -r - | \
+# RUN: llvm-objdump -d -r -z - | \
# RUN: FileCheck -check-prefixes=ALL,NXX,N64 %s
# RUN: llvm-mc -triple mips64-unknown-linux %s | \
# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-nacl %s \
-# RUN: | llvm-objdump -disassemble -no-show-raw-insn - | FileCheck %s
+# RUN: | llvm-objdump -disassemble -z -no-show-raw-insn - | FileCheck %s
# This test tests that address-masking sandboxing is added when given assembly
# input.
--- /dev/null
+// RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t
+// RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=NODISASM
+
+// The exact rules of skipping the bytes you can find in the code.
+// This test checks that we follow these rules and can force
+// dissasembly of zero blocks with the -z and --disassemble-zeroes options.
+
+// NODISASM: Disassembly of section .text:
+// NODISASM-NEXT: 0000000000000000 main:
+// NODISASM-NEXT: 0: 00 00 addb %al, (%rax)
+// NODISASM-NEXT: 2: 00 00 addb %al, (%rax)
+// NODISASM-NEXT: 4: 00 00 addb %al, (%rax)
+// NODISASM-NEXT: 6: 00 90 00 00 00 00 addb %dl, (%rax)
+// NODISASM-NEXT: ...
+// NODISASM-NEXT: 20: 90 nop
+// NODISASM-NEXT: ...
+// NODISASM: 0000000000000031 foo:
+// NODISASM-NEXT: 31: 00 00 addb %al, (%rax)
+// NODISASM-NEXT: 33: 00 00 addb %al, (%rax)
+// NODISASM: 0000000000000035 bar:
+// NODISASM-NEXT: ...
+
+// Check that with -z we disassemble blocks of zeroes.
+// RUN: llvm-objdump -d -z %t | FileCheck %s --check-prefix=DISASM
+
+// DISASM: Disassembly of section .text:
+// DISASM-NEXT: 0000000000000000 main:
+// DISASM-NEXT: 0: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 2: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 4: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 6: 00 90 00 00 00 00 addb %dl, (%rax)
+// DISASM-NEXT: c: 00 00 addb %al, (%rax)
+// DISASM-NEXT: e: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 10: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 12: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 14: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 16: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 18: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 1a: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 1c: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 1e: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 20: 90 nop
+// DISASM-NEXT: 21: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 23: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 25: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 27: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 29: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 2b: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 2d: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 2f: 00 00 addb %al, (%rax)
+// DISASM: 0000000000000031 foo:
+// DISASM-NEXT: 31: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 33: 00 00 addb %al, (%rax)
+// DISASM: 0000000000000035 bar:
+// DISASM-NEXT: 35: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 37: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 39: 00 00 addb %al, (%rax)
+// DISASM-NEXT: 3b: 00 00 addb %al, (%rax)
+
+// Check that --disassemble-zeroes work as alias for -z.
+// RUN: llvm-objdump -d --disassemble-zeroes %t | FileCheck %s --check-prefix=DISASM
+
+.text
+.globl main
+.type main, @function
+main:
+ .long 0
+ .byte 0
+ .byte 0
+ .byte 0
+ nop
+ .quad 0
+ .quad 0
+ .quad 0
+ nop
+ .quad 0
+ .quad 0
+foo:
+ .long 0
+bar:
+ .quad 0
StartAddress("start-address", cl::desc("Disassemble beginning at address"),
cl::value_desc("address"), cl::init(0));
cl::opt<unsigned long long>
- StopAddress("stop-address", cl::desc("Stop disassembly at address"),
+ StopAddress("stop-address",
+ cl::desc("Do not skip blocks of zeroes when disassembling"),
cl::value_desc("address"), cl::init(UINT64_MAX));
+
+cl::opt<bool> DisassembleZeroes("disassemble-zeroes",
+ cl::desc("Do not skip blocks of zeroes when "
+ "disassembling the blocks of zeroes"));
+cl::alias DisassembleZeroesShort("z",
+ cl::desc("Alias for --disassemble-zeroes"),
+ cl::aliasopt(DisassembleZeroes));
+
static StringRef ToolName;
typedef std::vector<std::tuple<uint64_t, StringRef, uint8_t>> SectionSymbolsTy;
}
}
+// Normally the disassembly output will skip blocks of zeroes. This function
+// returns the number of zero bytes that can be skipped when dumping the
+// disassembly of the instructions in Buf.
+static size_t countSkippableZeroBytes(ArrayRef<uint8_t> Buf) {
+ // When -z or --disassemble-zeroes are given we always dissasemble them.
+ if (DisassembleZeroes)
+ return 0;
+
+ // Find the number of leading zeroes.
+ size_t N = 0;
+ while (N < Buf.size() && !Buf[N])
+ ++N;
+
+ // We may want to skip blocks of zero bytes, but unless we see
+ // at least 8 of them in a row.
+ if (N < 8)
+ return 0;
+
+ // We skip zeroes in multiples of 4 because do not want to truncate an
+ // instruction if it starts with a zero byte.
+ return N & ~0x3;
+}
+
static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
if (StartAddress > StopAddress)
error("Start address should be less than stop address");
if (Index >= End)
break;
+ if (size_t N =
+ countSkippableZeroBytes(Bytes.slice(Index, End - Index))) {
+ outs() << "\t\t..." << '\n';
+ Index += N;
+ if (Index >= End)
+ break;
+ }
+
// Disassemble a real instruction or a data when disassemble all is
// provided
bool Disassembled = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),