[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]