Compressed Debug Sections
As discussed in Ancillary Objects, objects contain both allocable and non-allocable sections. Allocable sections are the sections that contain executable code and the data needed by that code at runtime. Non-allocable sections contain supplemental information that is not required to execute an object at runtime. These sections support the operation of debuggers and other observability tools, and are informally referred to as debug sections.
Depending on the level of debug information requested, debug sections can become very large relative to the code they describe. Ancillary objects, which write these sections to a separate file, offer one mechanism for dealing with these large sections. Section compression offers a second, complimentary, option for reducing section sizes.
The link-editor recognizes compressed sections within input objects, and automatically decompresses these sections. This operation is transparent to the user of the link-editor, and requires no special action.
By default, the link-editor does not compress sections in output objects. Use the -z compress-sections option to enable the compression of non-allocable sections in the output file.
$ cc ... -z compress-sections[=cmp-type[,cmp-opt...]] ...The following values for cmp-type are recognized.
-
none -
No compression is done. This option is equivalent to not specifying the
-z compress-sectionsoption. -
zlib -
Compress candidate sections using ZLIB compression. Documentation for ZLIB is found at https://zlib.net/
-
zstd -
Compress candidate sections using ZStandard compression. Documentation for ZSTD is found at https://facebook.github.io/zstd/zstd_manual.html
-
zlib-gnu -
Compress sections with ZLIB compression, using the older deprecated GNU style. Candidate sections must have a name that begins with
.debug. Each resulting output section is renamed to start with .zdebug to identify the use of compression.
The following cmp-opt option can be specified.
-
force -
By default, the link-editor will only compress sections if their resulting size is equal to or smaller than the original data. Specify force to force compression even when the resulting size is larger than the original.
If cmp-type is omitted, the zlib style is used.
To be a candidate for compression, a section must be non-allocable. The link-editor -z compress-class option can be used to choose from a wide variety of section classes to compress. If -z compress-sections is specified without also using -z compress-class, then annotate and debug sections are compressed by default. See ld(1) for a full description of -z compress-class and the section classes supported.
The zlib and zstd compression types are implemented using standard ELF compression features, and can be applied to a wide variety of sections. The resulting sections will have the SHF_COMPRESSED section flag set to identify the use of compression. The zlib-gnu style predates the introduction of standard compression to ELF, and is more limited. Unless there is a specific requirement to use the zlib-gnu style, the more general default zlib or zstd styles are recommended.
The zlib-gnu compression type is limited to sections with a name that starts with .debug. When zlib-gnu is used, sections that would otherwise be candidates for compression are not compressed. The underlying ZLIB compression is identical for the zlib and zlib-gnu styles, and both formats deliver the same amount of compression for a given input section. The two styles differ in the selection of candidate sections, the format of the compression header, and in how compressed sections are identified. See Section Compression.
The following program demonstrates the use of compressed debug sections. For the purpose of comparison, the program is built twice, once without compression, and once with compression.
$ cat hello.c #include <stdio.h> int main(int argc, char **argv) { (void) printf("hello, world\n"); return (0); } % cc -g hello.c -o a.out.uncompressed % cc -g hello.c -o a.out.compressed -z compress-sections
The section headers of the uncompressed, and compressed debug can now be compared.
$ elfdump -c a.out.uncompressed .... Section Header[24]: sh_name: .debug_info sh_addr: 0 sh_flags: 0 sh_size: 0x17b sh_type: [ SHT_PROGBITS ] .... Section Header[25]: sh_name: .debug_line sh_addr: 0 sh_flags: 0 sh_size: 0x4f sh_type: [ SHT_PROGBITS ] .... Section Header[26]: sh_name: .debug_abbrev sh_addr: 0 sh_flags: 0 sh_size: 0x7c sh_type: [ SHT_PROGBITS ] .... Section Header[27]: sh_name: .debug_pubnames sh_addr: 0 sh_flags: 0 sh_size: 0x1b sh_type: [ SHT_PROGBITS ] .... $ elfdump -c a.out.compressed .... Section Header[24]: sh_name: .debug_info sh_addr: 0 sh_flags: [ SHF_COMPRESSED ] sh_size: 0x14f sh_type: [ SHT_PROGBITS ] .... ch_size: 0x196 ch_type: [ ELFCOMPRESS_ZLIB ] ch_addralign: 0x1 Section Header[25]: sh_name: .debug_line sh_addr: 0 sh_flags: 0 sh_size: 0x4f sh_type: [ SHT_PROGBITS ] .... Section Header[26]: sh_name: .debug_abbrev sh_addr: 0 sh_flags: [ SHF_COMPRESSED ] sh_size: 0x79 sh_type: [ SHT_PROGBITS ] .... ch_size: 0x7c ch_type: [ ELFCOMPRESS_ZLIB ] ch_addralign: 0x1 Section Header[27]: sh_name: .debug_pubnames sh_addr: 0 sh_flags: 0 sh_size: 0x1b sh_type: [ SHT_PROGBITS ] ....
Each compressed section, .debug_info, and .debug_abbrev, is identified with a SHF_COMPRESSED section flag. In addition, the section header information is accompanied with compression header structure information. The ch_size and ch_addralign fields provide size and alignment requirements for the uncompressed data. See Section Compression.
The .debug_line and .debug_pubnames sections would be larger compressed than in their original uncompressed form, and have therefore been left uncompressed.