Index: test/ELF/mips-26.s =================================================================== --- test/ELF/mips-26.s +++ test/ELF/mips-26.s @@ -6,7 +6,7 @@ # RUN: %S/Inputs/mips-dynamic.s -o %t2.o # RUN: ld.lld %t2.o -shared -o %t.so # RUN: ld.lld %t1.o %t.so -o %t.exe -# RUN: llvm-objdump -d %t.exe | FileCheck %s +# RUN: llvm-objdump -d -z %t.exe | FileCheck %s # RUN: llvm-readobj -dynamic-table -s -r -mips-plt-got %t.exe \ # RUN: | FileCheck -check-prefix=REL %s Index: test/ELF/mips-micro-jal.s =================================================================== --- test/ELF/mips-micro-jal.s +++ test/ELF/mips-micro-jal.s @@ -7,7 +7,7 @@ # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ # RUN: -mattr=micromips %s -o %t2eb.o # RUN: ld.lld -o %teb.exe %t2eb.o %teb.so -# RUN: llvm-objdump -d -mattr=micromips %teb.exe | FileCheck --check-prefix=EB %s +# RUN: llvm-objdump -d -z -mattr=micromips %teb.exe | FileCheck --check-prefix=EB %s # RUN: llvm-readobj -mips-plt-got %teb.exe | FileCheck --check-prefix=PLT %s # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ @@ -16,7 +16,7 @@ # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ # RUN: -mattr=micromips %s -o %t2el.o # RUN: ld.lld -o %tel.exe %t2el.o %tel.so -# RUN: llvm-objdump -d -mattr=micromips %tel.exe | FileCheck --check-prefix=EL %s +# RUN: llvm-objdump -d -z -mattr=micromips %tel.exe | FileCheck --check-prefix=EL %s # RUN: llvm-readobj -mips-plt-got %tel.exe | FileCheck --check-prefix=PLT %s # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ @@ -25,7 +25,7 @@ # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ # RUN: -mattr=micromips -mcpu=mips32r6 %s -o %t2eb.o # RUN: ld.lld -o %teb.exe %t2eb.o %teb.so -# RUN: llvm-objdump -d -mattr=micromips %teb.exe | FileCheck --check-prefix=EBR6 %s +# RUN: llvm-objdump -d -z -mattr=micromips %teb.exe | FileCheck --check-prefix=EBR6 %s # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ # RUN: -mattr=micromips -mcpu=mips32r6 %S/Inputs/mips-micro.s -o %t1el.o @@ -33,7 +33,7 @@ # RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux \ # RUN: -mattr=micromips -mcpu=mips32r6 %s -o %t2el.o # RUN: ld.lld -o %tel.exe %t2el.o %tel.so -# RUN: llvm-objdump -d -mattr=micromips %tel.exe | FileCheck --check-prefix=ELR6 %s +# RUN: llvm-objdump -d -z -mattr=micromips %tel.exe | FileCheck --check-prefix=ELR6 %s # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ # RUN: -mattr=micromips %S/Inputs/mips-micro.s -o %t1eb.o @@ -43,7 +43,7 @@ # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ # RUN: -mattr=micromips %s -o %t2eb.o # RUN: ld.lld --no-threads -o %teb.exe %t-reg.o %t2eb.o %teb.so -# RUN: llvm-objdump -d -mattr=micromips %teb.exe \ +# RUN: llvm-objdump -d -z -mattr=micromips %teb.exe \ # RUN: | FileCheck --check-prefix=MIXED %s # EB: Disassembly of section .plt: Index: test/ELF/mips-npic-call-pic-os.s =================================================================== --- test/ELF/mips-npic-call-pic-os.s +++ test/ELF/mips-npic-call-pic-os.s @@ -11,7 +11,7 @@ # RUN: %p/Inputs/mips-pic.s -o %t-pic.o # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-npic.o # RUN: ld.lld %t-npic.o %t-pic.o %t-sto-pic.o -o %t.exe -# RUN: llvm-objdump -d %t.exe | FileCheck %s +# RUN: llvm-objdump -d -z %t.exe | FileCheck %s # CHECK: Disassembly of section .text: # CHECK-NEXT: __LA25Thunk_foo1a: @@ -71,7 +71,7 @@ # objects are laid out. # # RUN: ld.lld %t-pic.o %t-npic.o %t-sto-pic.o -o %t.exe -# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=REVERSE %s +# RUN: llvm-objdump -d -z %t.exe | FileCheck -check-prefix=REVERSE %s # REVERSE: Disassembly of section .text: # REVERSE-NEXT: __LA25Thunk_foo1a: Index: test/ELF/mips-npic-call-pic-script.s =================================================================== --- test/ELF/mips-npic-call-pic-script.s +++ test/ELF/mips-npic-call-pic-script.s @@ -11,7 +11,7 @@ # RUN: %p/Inputs/mips-pic.s -o %t-pic.o # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-npic.o # RUN: ld.lld --script %t1.script %t-npic.o %t-pic.o %t-sto-pic.o -o %t.exe -# RUN: llvm-objdump -d %t.exe | FileCheck %s +# RUN: llvm-objdump -d -z %t.exe | FileCheck %s # CHECK: Disassembly of section .out: # CHECK-NEXT: __LA25Thunk_foo1a: @@ -81,7 +81,7 @@ # .text.2 sections will be added to .text # RUN: echo "SECTIONS { .text 0x20000 : { *(.text) } }" > %t2.script # RUN: ld.lld --script %t2.script %t-npic.o %t-pic.o %t-sto-pic.o -o %t2.exe -# RUN: llvm-objdump -d %t2.exe | FileCheck -check-prefix=ORPH1 %s +# RUN: llvm-objdump -d -z %t2.exe | FileCheck -check-prefix=ORPH1 %s # ORPH1: Disassembly of section .text: # ORPH1-NEXT: __start: @@ -141,7 +141,7 @@ # .text.2 sections will form a new OutputSection .text # RUN: echo "SECTIONS { .out 0x20000 : { *(.text) } }" > %t3.script # RUN: ld.lld --script %t3.script %t-npic.o %t-pic.o %t-sto-pic.o -o %t3.exe -# RUN: llvm-objdump -d %t3.exe | FileCheck -check-prefix=ORPH2 %s +# RUN: llvm-objdump -d -z %t3.exe | FileCheck -check-prefix=ORPH2 %s # ORPH2: Disassembly of section .out: # ORPH2-NEXT: __start: Index: test/ELF/mips-npic-call-pic.s =================================================================== --- test/ELF/mips-npic-call-pic.s +++ test/ELF/mips-npic-call-pic.s @@ -11,7 +11,7 @@ # RUN: %p/Inputs/mips-pic.s -o %t-pic.o # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-npic.o # RUN: ld.lld %t-npic.o %t-pic.o %t-sto-pic.o -o %t.exe -# RUN: llvm-objdump -d %t.exe | FileCheck %s +# RUN: llvm-objdump -d -z %t.exe | FileCheck %s # CHECK: Disassembly of section .text: # CHECK-NEXT: __start: @@ -71,7 +71,7 @@ # objects are laid out. # # RUN: ld.lld %t-pic.o %t-npic.o %t-sto-pic.o -o %t.exe -# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=REVERSE %s +# RUN: llvm-objdump -d -z %t.exe | FileCheck -check-prefix=REVERSE %s # REVERSE: Disassembly of section .text: # REVERSE-NEXT: __LA25Thunk_foo1a: Index: test/ELF/ppc64-dtprel.s =================================================================== --- test/ELF/ppc64-dtprel.s +++ test/ELF/ppc64-dtprel.s @@ -4,15 +4,15 @@ // RUN: ld.lld -shared %t.o -o %t.so // RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s // RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s -// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s -// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=GotDisLE %s +// RUN: llvm-objdump -D -z %t.so | FileCheck --check-prefix=Dis %s +// RUN: llvm-objdump -D -z %t.so | FileCheck --check-prefix=GotDisLE %s // RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o // RUN: ld.lld -shared %t.o -o %t.so // RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s // RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s -// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s -// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=GotDisBE %s +// RUN: llvm-objdump -D -z %t.so | FileCheck --check-prefix=Dis %s +// RUN: llvm-objdump -D -z %t.so | FileCheck --check-prefix=GotDisBE %s .text .abiversion 2 Index: test/ELF/relocation-size-shared.s =================================================================== --- test/ELF/relocation-size-shared.s +++ test/ELF/relocation-size-shared.s @@ -4,7 +4,7 @@ // RUN: ld.lld -shared %tso.o -o %tso // RUN: ld.lld %t.o %tso -o %t1 // RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOCSHARED %s -// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s +// RUN: llvm-objdump -d -z %t1 | FileCheck --check-prefix=DISASM %s // RELOCSHARED: Relocations [ // RELOCSHARED-NEXT: Section ({{.*}}) .rela.dyn { Index: test/ELF/relocation-size.s =================================================================== --- test/ELF/relocation-size.s +++ test/ELF/relocation-size.s @@ -2,10 +2,10 @@ // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o // RUN: ld.lld %t.o -o %t1 // RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s -// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s +// RUN: llvm-objdump -d -z %t1 | FileCheck --check-prefix=DISASM %s // RUN: ld.lld -shared %t.o -o %t1 // RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOCSHARED %s -// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASMSHARED %s +// RUN: llvm-objdump -d -z %t1 | FileCheck --check-prefix=DISASMSHARED %s // NORELOC: Relocations [ // NORELOC-NEXT: ] Index: test/MC/Mips/cpsetup.s =================================================================== --- test/MC/Mips/cpsetup.s +++ test/MC/Mips/cpsetup.s @@ -1,5 +1,5 @@ # 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 @@ -7,14 +7,14 @@ # 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 | \ Index: test/MC/Mips/nacl-mask.s =================================================================== --- test/MC/Mips/nacl-mask.s +++ test/MC/Mips/nacl-mask.s @@ -1,5 +1,5 @@ # 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. Index: test/MC/X86/disassemble-zeroes.s =================================================================== --- /dev/null +++ test/MC/X86/disassemble-zeroes.s @@ -0,0 +1,63 @@ +// 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 that can force +// dissasembly of zero blocks with the -z and --disassemble-zeroes options. + +// NODISASM: Disassembly of section .text: +// NODISASM-NEXT: 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: 14: 00 00 addb %al, (%rax) +// NODISASM-NEXT: 16: 00 00 addb %al, (%rax) +// NODISASM-NEXT: 18: 90 nop +// NODISASM-NEXT: ... +// NODISASM-NEXT: 25: 00 00 addb %al, (%rax) +// NODISASM-NEXT: 27: 00 00 addb %al, (%rax) + +// Check that with -z we disassemble zeroes blocks. +// RUN: llvm-objdump -d -z %t | FileCheck %s --check-prefix=DISASM + +// DISASM: Disassembly of section .text: +// DISASM-NEXT: 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: 90 nop +// DISASM-NEXT: 19: 00 00 addb %al, (%rax) +// DISASM-NEXT: 1b: 00 00 addb %al, (%rax) +// DISASM-NEXT: 1d: 00 00 addb %al, (%rax) +// DISASM-NEXT: 1f: 00 00 addb %al, (%rax) +// 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) + +// 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 + nop + .quad 0 + .quad 0 Index: tools/llvm-objdump/llvm-objdump.cpp =================================================================== --- tools/llvm-objdump/llvm-objdump.cpp +++ tools/llvm-objdump/llvm-objdump.cpp @@ -267,6 +267,14 @@ cl::opt StopAddress("stop-address", cl::desc("Stop disassembly at address"), cl::value_desc("address"), cl::init(UINT64_MAX)); + +cl::opt 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> SectionSymbolsTy; @@ -1298,6 +1306,29 @@ } } +// Normally the disassembly output will skip blocks of zeroes. This function for +// the given buffer Buf with the instructions returns the number of zero bytes +// that can be skipped during dumping the disassembly output. +static size_t skipZeroesBlock(ArrayRef Buf) { + // When -z or --disassemble-zeroes are given we always dissasemble them. + if (DisassembleZeroes) + return 0; + + // Find the amount of leading zeroes. + size_t Amount = 0; + while (Amount < Buf.size() && !Buf[Amount]) + ++Amount; + + // We may want to skip blocks of zero bytes, but not earlier + // than we see at least 8 of them in a row. + if (Amount < 8) + return 0; + + // We keep at least 4 zero bytes because may have an instruction + // that starts from a zero byte and we do not want to trunctate it. + return Amount - 4; +} + static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { if (StartAddress > StopAddress) error("Start address should be less than stop address"); @@ -1729,6 +1760,11 @@ if (Index >= End) break; + if (size_t N = skipZeroesBlock(Bytes.slice(Index))) { + outs() << "\t\t..." << '\n'; + Index += N; + } + // Disassemble a real instruction or a data when disassemble all is // provided bool Disassembled = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),