aboutsummaryrefslogtreecommitdiffstats
path: root/addr2line.c
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-10-21 00:08:02 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-10-21 00:08:02 +0000
commitec91ea5c16f2c3d0b94e27cf16a581e46693513f (patch)
tree59852e3bfbaccb7f7ee543d3f55e09647522eb28 /addr2line.c
parent69e328b532b52befa92fb2d3a52db9914d2c918f (diff)
downloadruby-ec91ea5c16f2c3d0b94e27cf16a581e46693513f.tar.gz
check version of .debug_info
and refactor related code. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65257 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'addr2line.c')
-rw-r--r--addr2line.c67
1 files changed, 30 insertions, 37 deletions
diff --git a/addr2line.c b/addr2line.c
index 244eb56fac..cafb7c8549 100644
--- a/addr2line.c
+++ b/addr2line.c
@@ -753,21 +753,6 @@ enum {
VAL_int = 4
};
-typedef struct {
- uint32_t unit_length;
- uint16_t version;
- uint32_t debug_abbrev_offset;
- uint8_t address_size;
-} __attribute__((packed)) DW_CompilationUnitHeader32;
-
-typedef struct {
- uint32_t initial_length; /* 0xffffffff */
- uint64_t unit_length;
- uint16_t version;
- uint64_t debug_abbrev_offset;
- uint8_t address_size;
-} __attribute__((packed)) DW_CompilationUnitHeader64;
-
# define ABBREV_TABLE_SIZE 256
typedef struct {
obj_info_t *obj;
@@ -782,7 +767,7 @@ typedef struct {
char *pend;
char *q0;
char *q;
- int format; /* 32 or 64 */;
+ int format; /* 4 or 8 */;
uint8_t address_size;
int level;
char *abbrev_table[ABBREV_TABLE_SIZE];
@@ -883,13 +868,11 @@ read_uintptr(char **ptr)
static uint64_t
read_uint(DebugInfoReader *reader)
{
- uint64_t v;
- if (reader->format == 32) {
- v = read_uint32(&reader->p);
+ if (reader->format == 4) {
+ return read_uint32(&reader->p);
} else { /* 64 bit */
- v = read_uint64(&reader->p);
+ return read_uint64(&reader->p);
}
- return v;
}
static uint64_t
@@ -1413,23 +1396,32 @@ ranges_inspect(DebugInfoReader *reader, ranges_t *ptr)
static int
di_read_cu(DebugInfoReader *reader)
{
- DW_CompilationUnitHeader32 *hdr32 = (DW_CompilationUnitHeader32 *)reader->p;
+ uint64_t unit_length;
+ uint16_t version;
+ uint64_t debug_abbrev_offset;
+ reader->format = 4;
reader->current_cu = reader->p;
- if (hdr32->unit_length == 0xffffffff) {
- DW_CompilationUnitHeader64 *hdr = (DW_CompilationUnitHeader64 *)hdr32;
- reader->cu_end = reader->p + 12 + hdr->unit_length;
- reader->p += 23;
- reader->q0 = reader->obj->debug_abbrev.ptr + hdr->debug_abbrev_offset;
- reader->address_size = hdr->address_size;
- reader->format = 64;
- } else {
- DW_CompilationUnitHeader32 *hdr = hdr32;
- reader->cu_end = reader->p + 4 + hdr->unit_length;
- reader->p += 11;
- reader->q0 = reader->obj->debug_abbrev.ptr + hdr->debug_abbrev_offset;
- reader->address_size = hdr->address_size;
- reader->format = 32;
+ unit_length = read_uint32(&reader->p);
+ if (unit_length == 0xffffffff) {
+ unit_length = read_uint64(&reader->p);
+ reader->format = 8;
+ }
+ reader->cu_end = reader->p + unit_length;
+ version = read_uint16(&reader->p);
+ if (version > 5) {
+ return -1;
}
+ else if (version == 5) {
+ /* unit_type = */ read_uint8(&reader->p);
+ reader->address_size = read_uint8(&reader->p);
+ debug_abbrev_offset = read_uint(reader);
+ }
+ else {
+ debug_abbrev_offset = read_uint(reader);
+ reader->address_size = read_uint8(&reader->p);
+ }
+ reader->q0 = reader->obj->debug_abbrev.ptr + debug_abbrev_offset;
+
reader->level = 0;
di_read_debug_abbrev_cu(reader);
if (di_read_debug_line_cu(reader)) return -1;
@@ -1748,12 +1740,13 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
i = 0;
while (reader.p < reader.pend) {
/* fprintf(stderr, "%d:%tx: CU[%d]\n", __LINE__, reader.p - reader.obj->debug_info.ptr, i++); */
- if (di_read_cu(&reader)) goto fail;
+ if (di_read_cu(&reader)) goto use_symtab;
debug_info_read(&reader, num_traces, traces, lines, offset);
}
}
else {
/* This file doesn't have dwarf, use symtab or dynsym */
+use_symtab:
if (!symtab_shdr) {
/* This file doesn't have symtab, use dynsym instead */
symtab_shdr = dynsym_shdr;