ruby-changes:52123
From: naruse <ko1@a...>
Date: Mon, 13 Aug 2018 15:20:17 +0900 (JST)
Subject: [ruby-changes:52123] naruse:r64331 (trunk): support compressed debug_line
naruse 2018-08-13 15:20:12 +0900 (Mon, 13 Aug 2018) New Revision: 64331 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64331 Log: support compressed debug_line re-commit r64328 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 64330) +++ configure.ac (revision 64331) @@ -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]) + ]) ]) ]) @@ -3067,7 +3070,11 @@ AS_CASE("$enable_shared", [yes], [ https://github.com/ruby/ruby/blob/trunk/configure.ac#L3070 LIBRUBY_SO='lib$(RUBY_SO_NAME).$(SOEXT).$(MAJOR)' LIBRUBY_SONAME='lib$(RUBY_SO_NAME).$(SOEXT).$(RUBY_PROGRAM_VERSION)' LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_SO_NAME).$(SOEXT)' - RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ["${linker_flag}-h${linker_flag:+,}"'$(@F)']) + AS_IF([test "$GCC" = yes], [ + LIBRUBY_DLDFLAGS="$DLDFLAGS "'-Wl,-h,$(@F)' + ], [ + LIBRUBY_DLDFLAGS="$DLDFLAGS "'-h $(@F)' + ]) XLDFLAGS="$XLDFLAGS "'-R${libdir}' ], [hpux*], [ @@ -3314,7 +3321,7 @@ AS_CASE(["$target_os"], https://github.com/ruby/ruby/blob/trunk/configure.ac#L3321 ]) ], [cygwin*|mingw*], [ - LIBRUBY_DLDFLAGS="${LIBRUBY_DLDFLAGS}"' -Wl,--out-implib=$(LIBRUBY)' + LIBRUBY_DLDFLAGS="${DLDFLAGS}"' -Wl,--out-implib=$(LIBRUBY)' AS_CASE(["$target_os"], [cygwin*], [ AS_IF([test x"$enable_shared" = xyes], [ Index: addr2line.c =================================================================== --- addr2line.c (revision 64330) +++ addr2line.c (revision 64331) @@ -101,8 +101,12 @@ 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 */ -#define SHF_COMPRESSED 0 +#ifdef SHF_COMPRESSED +# ifdef HAVE_LIBZ +# include <zlib.h> +# endif +#else /* compatibility with glibc < 2.22 */ +# define SHF_COMPRESSED 0 #endif PRINTF_ARGS(static int kprintf(const char *fmt, ...), 1, 2); @@ -478,6 +482,41 @@ follow_debuglink(const char *debuglink, https://github.com/ruby/ruby/blob/trunk/addr2line.c#L482 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 +683,22 @@ fill_lines(int num_traces, void **traces https://github.com/ruby/ruby/blob/trunk/addr2line.c#L683 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) { +#ifdef HAVE_LIBZ + 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; +#endif + } + 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/