ruby-changes:52120
From: naruse <ko1@a...>
Date: Mon, 13 Aug 2018 11:56:16 +0900 (JST)
Subject: [ruby-changes:52120] naruse:r64328 (trunk): support compressed debug_line
naruse 2018-08-13 11:56:06 +0900 (Mon, 13 Aug 2018) New Revision: 64328 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64328 Log: support compressed debug_line https://blogs.oracle.com/solaris/elf_section_compression-v2 https://gnu.wildebeest.org/blog/mjw/2016/01/13/elf-libelf-compressed-sections-and-elfutils/ Modified files: trunk/addr2line.c trunk/configure.ac Index: configure.ac =================================================================== --- configure.ac (revision 64327) +++ configure.ac (revision 64328) @@ -2451,6 +2451,9 @@ AS_IF([test "$rb_cv_binary_elf" = yes], https://github.com/ruby/ruby/blob/trunk/configure.ac#L2451 AC_CHECK_HEADERS([elf.h elf_abi.h]) AS_IF([test $ac_cv_header_elf_h = yes -o $ac_cv_header_elf_abi_h = yes], [ AC_LIBOBJ([addr2line]) + AS_IF([test "x$compress_debug_sections" = xzlib], [ + AC_CHECK_LIB([z], [uncompress]) + ]) ]) ]) Index: addr2line.c =================================================================== --- addr2line.c (revision 64327) +++ addr2line.c (revision 64328) @@ -101,7 +101,9 @@ void *alloca(); https://github.com/ruby/ruby/blob/trunk/addr2line.c#L101 #define PATH_MAX 4096 #endif -#ifndef SHF_COMPRESSED /* compatibility with glibc < 2.22 */ +#ifdef SHF_COMPRESSED +#include <zlib.h> +#else /* compatibility with glibc < 2.22 */ #define SHF_COMPRESSED 0 #endif @@ -478,6 +480,41 @@ follow_debuglink(const char *debuglink, https://github.com/ruby/ruby/blob/trunk/addr2line.c#L480 fill_lines(num_traces, traces, 0, objp, lines, offset); } +static int +parse_compressed_debug_line(int num_traces, void **traces, + char *debug_line, unsigned long size, + obj_info_t *obj, line_info_t *lines, int offset) +{ + void *uncompressed_debug_line; + ElfW(Chdr) *chdr = (ElfW(Chdr) *)debug_line; + unsigned long destsize = chdr->ch_size; + int ret = 0; + + if (chdr->ch_type != ELFCOMPRESS_ZLIB) { + /* unsupported compression type */ + return -1; + } + + uncompressed_debug_line = malloc(destsize); + if (!uncompressed_debug_line) return -1; + ret = uncompress(uncompressed_debug_line, &destsize, + (const Bytef *)debug_line + sizeof(ElfW(Chdr)), size-sizeof(ElfW(Chdr))); + if (ret != Z_OK) { /* Z_OK = 0 */ + goto finish; + } + ret = parse_debug_line(num_traces, traces, + uncompressed_debug_line, + destsize, + obj, lines, offset); + if (ret) { + goto finish; + } + +finish: + free(uncompressed_debug_line); + return ret ? -1 : 0; +} + /* read file and fill lines */ static uintptr_t fill_lines(int num_traces, void **traces, int check_debuglink, @@ -644,12 +681,20 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L681 goto finish; } - if (!compressed_p && - parse_debug_line(num_traces, traces, - file + debug_line_shdr->sh_offset, - debug_line_shdr->sh_size, - obj, lines, offset)) - goto fail; + if (compressed_p) { + int r = parse_compressed_debug_line(num_traces, traces, + file + debug_line_shdr->sh_offset, + debug_line_shdr->sh_size, + obj, lines, offset); + if (r) goto fail; + } + else { + int r = parse_debug_line(num_traces, traces, + file + debug_line_shdr->sh_offset, + debug_line_shdr->sh_size, + obj, lines, offset); + if (r) goto fail; + } finish: return dladdr_fbase; fail: -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/