llvm-project/llvm/test/MC/ELF/compression.s

117 lines
4.5 KiB
ArmAsm
Raw Normal View History

// Check zlib-gnu style
// RUN: llvm-mc -filetype=obj -compress-debug-sections=zlib-gnu -triple x86_64-pc-linux-gnu < %s -o %t
// RUN: llvm-objdump -s %t | FileCheck --check-prefix=CHECK-GNU-STYLE %s
// RUN: llvm-dwarfdump -debug-dump=str %t | FileCheck --check-prefix=STR %s
// RUN: llvm-mc -filetype=obj -compress-debug-sections=zlib-gnu -triple i386-pc-linux-gnu < %s \
// RUN: | llvm-readobj -symbols - | FileCheck --check-prefix=386-SYMBOLS-GNU %s
// Check zlib style
// RUN: llvm-mc -filetype=obj -compress-debug-sections=zlib -triple x86_64-pc-linux-gnu < %s -o %t
// RUN: llvm-objdump -s %t | FileCheck --check-prefix=CHECK-ZLIB-STYLE %s
// RUN: llvm-dwarfdump -debug-dump=str %t | FileCheck --check-prefix=STR %s
// RUN: llvm-mc -filetype=obj -compress-debug-sections=zlib -triple i386-pc-linux-gnu < %s \
// RUN: | llvm-readobj -symbols - | FileCheck --check-prefix=386-SYMBOLS-ZLIB %s
// RUN: llvm-readobj -sections %t | FileCheck --check-prefix=ZLIB-STYLE-FLAGS %s
// REQUIRES: zlib
// Don't compress small sections, such as this simple debug_abbrev example
// CHECK-GNU-STYLE: Contents of section .debug_abbrev:
// CHECK-GNU-STYLE-NOT: ZLIB
// CHECK-GNU-STYLE-NOT: Contents of
// CHECK-GNU-STYLE: Contents of section .debug_info:
// CHECK-GNU-STYLE: Contents of section .zdebug_str:
// Check for the 'ZLIB' file magic at the start of the section only
// CHECK-GNU-STYLE-NEXT: ZLIB
// CHECK-GNU-STYLE-NOT: ZLIB
Reimplement debug info compression by compressing the whole section, rather than a fragment. To support compressing the debug_line section that contains multiple fragments (due, I believe, to variation in choices of line table encoding depending on the size of instruction ranges in the actual program code) we needed to support compressing multiple MCFragments in a single pass. This patch implements that behavior by mutating the post-relaxed and relocated section to be the compressed form of its former self, including renaming the section. This is a more flexible (and less invasive, to a degree) implementation that will allow for other features such as "use compression only if it's smaller than the uncompressed data". Compressing debug_frame would be a possible further extension to this work, but I've left it for now. The hurdle there is alignment sections - which might require going as far as to refactor MCAssembler.cpp:writeFragment to handle writing to a byte buffer or an MCObjectWriter (there's already a virtual call there, so it shouldn't add substantial compile-time cost) which could in turn involve refactoring MCAsmBackend::writeNopData to use that same abstraction... which involves touching all the backends. This would remove the limited handling of fragment writing seen in ELFObjectWriter.cpp:getUncompressedData which would be nice - but it's more invasive. I did discover that I (perhaps obviously) don't need to handle relocations when I rewrite the fragments - since the relocations have already been applied and computed (and stored into ELFObjectWriter::Relocations) by this stage (necessarily, because we need to have written any immediate values or assembly-time relocations into the data already before we compress it, which we have). The test case doesn't necessarily cover that in detail - I can add more test coverage if that's preferred. llvm-svn: 205990
2014-04-11 05:53:53 +08:00
// FIXME: Handle compressing alignment fragments to support compressing debug_frame
// CHECK-GNU-STYLE: Contents of section .debug_frame:
// CHECK-GNU-STYLE-NOT: ZLIB
// CHECK-GNU-STYLE: Contents of
Reimplement debug info compression by compressing the whole section, rather than a fragment. To support compressing the debug_line section that contains multiple fragments (due, I believe, to variation in choices of line table encoding depending on the size of instruction ranges in the actual program code) we needed to support compressing multiple MCFragments in a single pass. This patch implements that behavior by mutating the post-relaxed and relocated section to be the compressed form of its former self, including renaming the section. This is a more flexible (and less invasive, to a degree) implementation that will allow for other features such as "use compression only if it's smaller than the uncompressed data". Compressing debug_frame would be a possible further extension to this work, but I've left it for now. The hurdle there is alignment sections - which might require going as far as to refactor MCAssembler.cpp:writeFragment to handle writing to a byte buffer or an MCObjectWriter (there's already a virtual call there, so it shouldn't add substantial compile-time cost) which could in turn involve refactoring MCAsmBackend::writeNopData to use that same abstraction... which involves touching all the backends. This would remove the limited handling of fragment writing seen in ELFObjectWriter.cpp:getUncompressedData which would be nice - but it's more invasive. I did discover that I (perhaps obviously) don't need to handle relocations when I rewrite the fragments - since the relocations have already been applied and computed (and stored into ELFObjectWriter::Relocations) by this stage (necessarily, because we need to have written any immediate values or assembly-time relocations into the data already before we compress it, which we have). The test case doesn't necessarily cover that in detail - I can add more test coverage if that's preferred. llvm-svn: 205990
2014-04-11 05:53:53 +08:00
// Decompress one valid dwarf section just to check that this roundtrips,
// we use .zdebug_str section for that
// STR: perfectly compressable data sample *****************************************
Update the fragments of symbols in compressed sections. While unnamed relocations are already cached in side tables in ELFObjectWriter::RecordRelocation, symbols still need their fragments updated to refer to the newly compressed fragment (even if that fragment isn't big enough to fit the offset). Even though we only create temporary symbols in debug info sections this comes up in 32 bit builds where even temporary symbols in mergeable sections (such as debug_str) have to be emitted as named symbols. I tried a few other ways to do this but they all didn't work for various reasons: 1) Canonicalize the MCSymbolData in RecordRelocation, nulling out the Fragment (so it didn't have to be updated by CompressDebugSection). This doesn't work because some code relies on symbols having fragments to indicate that they're defined, I think. 2) Canonicalize the MCSymbolData in RecordRelocation to be "first fragment + absolute offset" so it would be cheaper to just test and update the fragment in CompressDebugSections. This doesn't work because the offset computed in RecordRelocation isn't that of the symbol's fragment, it's the passed in fragment (I haven't figured out what that fragment is - perhaps it's the location where the relocation is to be written). And if the fragment offset has to be computed only for this use we might as well just do it when we need to, in CompressDebugSection. I also added an assert to help catch this a bit more clearly, even though it is UB. The test case improvements would either assert fail and/or valgrind vail without the fix, even if they wouldn't necessarily fail the FileCheck output. llvm-svn: 206653
2014-04-19 05:24:12 +08:00
// In x86 32 bit named symbols are used for temporary symbols in merge
// sections, so make sure we handle symbols inside compressed sections
// 386-SYMBOLS-GNU: Name: .Linfo_string0
// 386-SYMBOLS-GNU-NOT: }
// 386-SYMBOLS-GNU: Section: .zdebug_str
// Now check the zlib style output:
// Don't compress small sections, such as this simple debug_abbrev example
// CHECK-ZLIB-STYLE: Contents of section .debug_abbrev:
// CHECK-ZLIB-STYLE-NOT: ZLIB
// CHECK-ZLIB-STYLE-NOT: Contents of
// CHECK-ZLIB-STYLE: Contents of section .debug_info:
// FIXME: Handle compressing alignment fragments to support compressing debug_frame
// CHECK-ZLIB-STYLE: Contents of section .debug_frame:
// CHECK-ZLIB-STYLE-NOT: ZLIB
// CHECK-ZLIB-STYLE: Contents of
// Check that debug_line section was not renamed, so it is
// zlib-style, not zlib-gnu one. Check that SHF_COMPRESSED was set.
// ZLIB-STYLE-FLAGS: Section {
// ZLIB-STYLE-FLAGS: Index:
// ZLIB-STYLE-FLAGS: Name: .debug_str
// ZLIB-STYLE-FLAGS-NEXT: Type: SHT_PROGBITS
// ZLIB-STYLE-FLAGS-NEXT: Flags [
// ZLIB-STYLE-FLAGS-NEXT: SHF_COMPRESSED
// 386-SYMBOLS-ZLIB: Name: .Linfo_string0
// 386-SYMBOLS-ZLIB-NOT: }
// 386-SYMBOLS-ZLIB: Section: .debug_str
Update the fragments of symbols in compressed sections. While unnamed relocations are already cached in side tables in ELFObjectWriter::RecordRelocation, symbols still need their fragments updated to refer to the newly compressed fragment (even if that fragment isn't big enough to fit the offset). Even though we only create temporary symbols in debug info sections this comes up in 32 bit builds where even temporary symbols in mergeable sections (such as debug_str) have to be emitted as named symbols. I tried a few other ways to do this but they all didn't work for various reasons: 1) Canonicalize the MCSymbolData in RecordRelocation, nulling out the Fragment (so it didn't have to be updated by CompressDebugSection). This doesn't work because some code relies on symbols having fragments to indicate that they're defined, I think. 2) Canonicalize the MCSymbolData in RecordRelocation to be "first fragment + absolute offset" so it would be cheaper to just test and update the fragment in CompressDebugSections. This doesn't work because the offset computed in RecordRelocation isn't that of the symbol's fragment, it's the passed in fragment (I haven't figured out what that fragment is - perhaps it's the location where the relocation is to be written). And if the fragment offset has to be computed only for this use we might as well just do it when we need to, in CompressDebugSection. I also added an assert to help catch this a bit more clearly, even though it is UB. The test case improvements would either assert fail and/or valgrind vail without the fix, even if they wouldn't necessarily fail the FileCheck output. llvm-svn: 206653
2014-04-19 05:24:12 +08:00
.section .debug_line,"",@progbits
.section .debug_abbrev,"",@progbits
Update the fragments of symbols in compressed sections. While unnamed relocations are already cached in side tables in ELFObjectWriter::RecordRelocation, symbols still need their fragments updated to refer to the newly compressed fragment (even if that fragment isn't big enough to fit the offset). Even though we only create temporary symbols in debug info sections this comes up in 32 bit builds where even temporary symbols in mergeable sections (such as debug_str) have to be emitted as named symbols. I tried a few other ways to do this but they all didn't work for various reasons: 1) Canonicalize the MCSymbolData in RecordRelocation, nulling out the Fragment (so it didn't have to be updated by CompressDebugSection). This doesn't work because some code relies on symbols having fragments to indicate that they're defined, I think. 2) Canonicalize the MCSymbolData in RecordRelocation to be "first fragment + absolute offset" so it would be cheaper to just test and update the fragment in CompressDebugSections. This doesn't work because the offset computed in RecordRelocation isn't that of the symbol's fragment, it's the passed in fragment (I haven't figured out what that fragment is - perhaps it's the location where the relocation is to be written). And if the fragment offset has to be computed only for this use we might as well just do it when we need to, in CompressDebugSection. I also added an assert to help catch this a bit more clearly, even though it is UB. The test case improvements would either assert fail and/or valgrind vail without the fix, even if they wouldn't necessarily fail the FileCheck output. llvm-svn: 206653
2014-04-19 05:24:12 +08:00
.Lsection_abbrev:
.byte 1 # Abbreviation Code
Reimplement debug info compression by compressing the whole section, rather than a fragment. To support compressing the debug_line section that contains multiple fragments (due, I believe, to variation in choices of line table encoding depending on the size of instruction ranges in the actual program code) we needed to support compressing multiple MCFragments in a single pass. This patch implements that behavior by mutating the post-relaxed and relocated section to be the compressed form of its former self, including renaming the section. This is a more flexible (and less invasive, to a degree) implementation that will allow for other features such as "use compression only if it's smaller than the uncompressed data". Compressing debug_frame would be a possible further extension to this work, but I've left it for now. The hurdle there is alignment sections - which might require going as far as to refactor MCAssembler.cpp:writeFragment to handle writing to a byte buffer or an MCObjectWriter (there's already a virtual call there, so it shouldn't add substantial compile-time cost) which could in turn involve refactoring MCAsmBackend::writeNopData to use that same abstraction... which involves touching all the backends. This would remove the limited handling of fragment writing seen in ELFObjectWriter.cpp:getUncompressedData which would be nice - but it's more invasive. I did discover that I (perhaps obviously) don't need to handle relocations when I rewrite the fragments - since the relocations have already been applied and computed (and stored into ELFObjectWriter::Relocations) by this stage (necessarily, because we need to have written any immediate values or assembly-time relocations into the data already before we compress it, which we have). The test case doesn't necessarily cover that in detail - I can add more test coverage if that's preferred. llvm-svn: 205990
2014-04-11 05:53:53 +08:00
.byte 17 # DW_TAG_compile_unit
.byte 0 # DW_CHILDREN_no
Update the fragments of symbols in compressed sections. While unnamed relocations are already cached in side tables in ELFObjectWriter::RecordRelocation, symbols still need their fragments updated to refer to the newly compressed fragment (even if that fragment isn't big enough to fit the offset). Even though we only create temporary symbols in debug info sections this comes up in 32 bit builds where even temporary symbols in mergeable sections (such as debug_str) have to be emitted as named symbols. I tried a few other ways to do this but they all didn't work for various reasons: 1) Canonicalize the MCSymbolData in RecordRelocation, nulling out the Fragment (so it didn't have to be updated by CompressDebugSection). This doesn't work because some code relies on symbols having fragments to indicate that they're defined, I think. 2) Canonicalize the MCSymbolData in RecordRelocation to be "first fragment + absolute offset" so it would be cheaper to just test and update the fragment in CompressDebugSections. This doesn't work because the offset computed in RecordRelocation isn't that of the symbol's fragment, it's the passed in fragment (I haven't figured out what that fragment is - perhaps it's the location where the relocation is to be written). And if the fragment offset has to be computed only for this use we might as well just do it when we need to, in CompressDebugSection. I also added an assert to help catch this a bit more clearly, even though it is UB. The test case improvements would either assert fail and/or valgrind vail without the fix, even if they wouldn't necessarily fail the FileCheck output. llvm-svn: 206653
2014-04-19 05:24:12 +08:00
.byte 27 # DW_AT_comp_dir
.byte 14 # DW_FORM_strp
Reimplement debug info compression by compressing the whole section, rather than a fragment. To support compressing the debug_line section that contains multiple fragments (due, I believe, to variation in choices of line table encoding depending on the size of instruction ranges in the actual program code) we needed to support compressing multiple MCFragments in a single pass. This patch implements that behavior by mutating the post-relaxed and relocated section to be the compressed form of its former self, including renaming the section. This is a more flexible (and less invasive, to a degree) implementation that will allow for other features such as "use compression only if it's smaller than the uncompressed data". Compressing debug_frame would be a possible further extension to this work, but I've left it for now. The hurdle there is alignment sections - which might require going as far as to refactor MCAssembler.cpp:writeFragment to handle writing to a byte buffer or an MCObjectWriter (there's already a virtual call there, so it shouldn't add substantial compile-time cost) which could in turn involve refactoring MCAsmBackend::writeNopData to use that same abstraction... which involves touching all the backends. This would remove the limited handling of fragment writing seen in ELFObjectWriter.cpp:getUncompressedData which would be nice - but it's more invasive. I did discover that I (perhaps obviously) don't need to handle relocations when I rewrite the fragments - since the relocations have already been applied and computed (and stored into ELFObjectWriter::Relocations) by this stage (necessarily, because we need to have written any immediate values or assembly-time relocations into the data already before we compress it, which we have). The test case doesn't necessarily cover that in detail - I can add more test coverage if that's preferred. llvm-svn: 205990
2014-04-11 05:53:53 +08:00
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.section .debug_info,"",@progbits
.long 12 # Length of Unit
.short 4 # DWARF version number
.long .Lsection_abbrev # Offset Into Abbrev. Section
.byte 8 # Address Size (in bytes)
.byte 1 # Abbrev [1] DW_TAG_compile_unit
.long .Linfo_string0 # DW_AT_comp_dir
.text
foo:
.cfi_startproc
.file 1 "Driver.ii"
# pad out the line table to make sure it's big enough to warrant compression
.loc 1 2 0
nop
.loc 1 3 0
nop
.loc 1 4 0
nop
.loc 1 5 0
nop
.loc 1 6 0
nop
.loc 1 7 0
nop
.loc 1 8 0
nop
.cfi_endproc
.cfi_sections .debug_frame
Update the fragments of symbols in compressed sections. While unnamed relocations are already cached in side tables in ELFObjectWriter::RecordRelocation, symbols still need their fragments updated to refer to the newly compressed fragment (even if that fragment isn't big enough to fit the offset). Even though we only create temporary symbols in debug info sections this comes up in 32 bit builds where even temporary symbols in mergeable sections (such as debug_str) have to be emitted as named symbols. I tried a few other ways to do this but they all didn't work for various reasons: 1) Canonicalize the MCSymbolData in RecordRelocation, nulling out the Fragment (so it didn't have to be updated by CompressDebugSection). This doesn't work because some code relies on symbols having fragments to indicate that they're defined, I think. 2) Canonicalize the MCSymbolData in RecordRelocation to be "first fragment + absolute offset" so it would be cheaper to just test and update the fragment in CompressDebugSections. This doesn't work because the offset computed in RecordRelocation isn't that of the symbol's fragment, it's the passed in fragment (I haven't figured out what that fragment is - perhaps it's the location where the relocation is to be written). And if the fragment offset has to be computed only for this use we might as well just do it when we need to, in CompressDebugSection. I also added an assert to help catch this a bit more clearly, even though it is UB. The test case improvements would either assert fail and/or valgrind vail without the fix, even if they wouldn't necessarily fail the FileCheck output. llvm-svn: 206653
2014-04-19 05:24:12 +08:00
# Below is the section we will use to check that after compression with llvm-mc,
# llvm-dwarfdump tool will be able to decompress data back and dump it. Data sample
# should be compressable enough, so it is filled with some amount of equal symbols at the end
Update the fragments of symbols in compressed sections. While unnamed relocations are already cached in side tables in ELFObjectWriter::RecordRelocation, symbols still need their fragments updated to refer to the newly compressed fragment (even if that fragment isn't big enough to fit the offset). Even though we only create temporary symbols in debug info sections this comes up in 32 bit builds where even temporary symbols in mergeable sections (such as debug_str) have to be emitted as named symbols. I tried a few other ways to do this but they all didn't work for various reasons: 1) Canonicalize the MCSymbolData in RecordRelocation, nulling out the Fragment (so it didn't have to be updated by CompressDebugSection). This doesn't work because some code relies on symbols having fragments to indicate that they're defined, I think. 2) Canonicalize the MCSymbolData in RecordRelocation to be "first fragment + absolute offset" so it would be cheaper to just test and update the fragment in CompressDebugSections. This doesn't work because the offset computed in RecordRelocation isn't that of the symbol's fragment, it's the passed in fragment (I haven't figured out what that fragment is - perhaps it's the location where the relocation is to be written). And if the fragment offset has to be computed only for this use we might as well just do it when we need to, in CompressDebugSection. I also added an assert to help catch this a bit more clearly, even though it is UB. The test case improvements would either assert fail and/or valgrind vail without the fix, even if they wouldn't necessarily fail the FileCheck output. llvm-svn: 206653
2014-04-19 05:24:12 +08:00
.section .debug_str,"MS",@progbits,1
.Linfo_string0:
.asciz "perfectly compressable data sample *****************************************"