rdwarf 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +28 -0
- data/README.md +39 -0
- data/Rakefile +8 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/ext/rdwarf/depend +5 -0
- data/ext/rdwarf/extconf.rb +29 -0
- data/ext/rdwarf/libdwarf/CHANGES +102 -0
- data/ext/rdwarf/libdwarf/CODINGSTYLE +71 -0
- data/ext/rdwarf/libdwarf/COPYING +28 -0
- data/ext/rdwarf/libdwarf/ChangeLog +619 -0
- data/ext/rdwarf/libdwarf/ChangeLog2006 +835 -0
- data/ext/rdwarf/libdwarf/ChangeLog2007 +217 -0
- data/ext/rdwarf/libdwarf/ChangeLog2008 +263 -0
- data/ext/rdwarf/libdwarf/ChangeLog2009 +348 -0
- data/ext/rdwarf/libdwarf/ChangeLog2010 +175 -0
- data/ext/rdwarf/libdwarf/ChangeLog2011 +297 -0
- data/ext/rdwarf/libdwarf/ChangeLog2012 +131 -0
- data/ext/rdwarf/libdwarf/ChangeLog2013 +238 -0
- data/ext/rdwarf/libdwarf/ChangeLog2014 +399 -0
- data/ext/rdwarf/libdwarf/LGPL.txt +504 -0
- data/ext/rdwarf/libdwarf/LIBDWARFCOPYRIGHT +40 -0
- data/ext/rdwarf/libdwarf/Makefile.in +220 -0
- data/ext/rdwarf/libdwarf/NEWS +535 -0
- data/ext/rdwarf/libdwarf/README +235 -0
- data/ext/rdwarf/libdwarf/checkexamples.c +1179 -0
- data/ext/rdwarf/libdwarf/cmplrs/dwarf_addr_finder.h +55 -0
- data/ext/rdwarf/libdwarf/common.c +62 -0
- data/ext/rdwarf/libdwarf/common.h +38 -0
- data/ext/rdwarf/libdwarf/config.h.in +146 -0
- data/ext/rdwarf/libdwarf/configure +5581 -0
- data/ext/rdwarf/libdwarf/configure.in +167 -0
- data/ext/rdwarf/libdwarf/dw-linetableheader.txt +39 -0
- data/ext/rdwarf/libdwarf/dwarf.h +1342 -0
- data/ext/rdwarf/libdwarf/dwarf_abbrev.c +291 -0
- data/ext/rdwarf/libdwarf/dwarf_abbrev.h +45 -0
- data/ext/rdwarf/libdwarf/dwarf_addr_finder.c +676 -0
- data/ext/rdwarf/libdwarf/dwarf_alloc.c +685 -0
- data/ext/rdwarf/libdwarf/dwarf_alloc.h +38 -0
- data/ext/rdwarf/libdwarf/dwarf_arange.c +595 -0
- data/ext/rdwarf/libdwarf/dwarf_arange.h +62 -0
- data/ext/rdwarf/libdwarf/dwarf_base_types.h +157 -0
- data/ext/rdwarf/libdwarf/dwarf_die_deliv.c +1802 -0
- data/ext/rdwarf/libdwarf/dwarf_die_deliv.h +46 -0
- data/ext/rdwarf/libdwarf/dwarf_elf_access.c +1348 -0
- data/ext/rdwarf/libdwarf/dwarf_elf_access.h +46 -0
- data/ext/rdwarf/libdwarf/dwarf_error.c +492 -0
- data/ext/rdwarf/libdwarf/dwarf_error.h +53 -0
- data/ext/rdwarf/libdwarf/dwarf_form.c +1302 -0
- data/ext/rdwarf/libdwarf/dwarf_frame.c +2454 -0
- data/ext/rdwarf/libdwarf/dwarf_frame.h +418 -0
- data/ext/rdwarf/libdwarf/dwarf_frame2.c +1533 -0
- data/ext/rdwarf/libdwarf/dwarf_frame3.c +282 -0
- data/ext/rdwarf/libdwarf/dwarf_funcs.c +123 -0
- data/ext/rdwarf/libdwarf/dwarf_funcs.h +33 -0
- data/ext/rdwarf/libdwarf/dwarf_gdbindex.c +520 -0
- data/ext/rdwarf/libdwarf/dwarf_gdbindex.h +97 -0
- data/ext/rdwarf/libdwarf/dwarf_global.c +612 -0
- data/ext/rdwarf/libdwarf/dwarf_global.h +117 -0
- data/ext/rdwarf/libdwarf/dwarf_harmless.c +228 -0
- data/ext/rdwarf/libdwarf/dwarf_harmless.h +31 -0
- data/ext/rdwarf/libdwarf/dwarf_incl.h +61 -0
- data/ext/rdwarf/libdwarf/dwarf_init_finish.c +1263 -0
- data/ext/rdwarf/libdwarf/dwarf_leb.c +159 -0
- data/ext/rdwarf/libdwarf/dwarf_line.c +1822 -0
- data/ext/rdwarf/libdwarf/dwarf_line.h +446 -0
- data/ext/rdwarf/libdwarf/dwarf_line2.c +98 -0
- data/ext/rdwarf/libdwarf/dwarf_line_table_reader_common.c +1583 -0
- data/ext/rdwarf/libdwarf/dwarf_loc.c +1525 -0
- data/ext/rdwarf/libdwarf/dwarf_loc.h +149 -0
- data/ext/rdwarf/libdwarf/dwarf_loc2.c +833 -0
- data/ext/rdwarf/libdwarf/dwarf_macro.c +479 -0
- data/ext/rdwarf/libdwarf/dwarf_macro.h +35 -0
- data/ext/rdwarf/libdwarf/dwarf_opaque.h +778 -0
- data/ext/rdwarf/libdwarf/dwarf_original_elf_init.c +219 -0
- data/ext/rdwarf/libdwarf/dwarf_print_lines.c +631 -0
- data/ext/rdwarf/libdwarf/dwarf_pubtypes.c +132 -0
- data/ext/rdwarf/libdwarf/dwarf_query.c +1594 -0
- data/ext/rdwarf/libdwarf/dwarf_ranges.c +194 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_arm.h +308 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_mips.h +117 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_ppc.h +242 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_ppc64.h +272 -0
- data/ext/rdwarf/libdwarf/dwarf_reloc_x86_64.h +127 -0
- data/ext/rdwarf/libdwarf/dwarf_sort_line.c +665 -0
- data/ext/rdwarf/libdwarf/dwarf_string.c +82 -0
- data/ext/rdwarf/libdwarf/dwarf_stubs.c +38 -0
- data/ext/rdwarf/libdwarf/dwarf_tied.c +423 -0
- data/ext/rdwarf/libdwarf/dwarf_tsearch.h +125 -0
- data/ext/rdwarf/libdwarf/dwarf_tsearchhash.c +675 -0
- data/ext/rdwarf/libdwarf/dwarf_types.c +121 -0
- data/ext/rdwarf/libdwarf/dwarf_types.h +32 -0
- data/ext/rdwarf/libdwarf/dwarf_util.c +913 -0
- data/ext/rdwarf/libdwarf/dwarf_util.h +324 -0
- data/ext/rdwarf/libdwarf/dwarf_vars.c +125 -0
- data/ext/rdwarf/libdwarf/dwarf_vars.h +29 -0
- data/ext/rdwarf/libdwarf/dwarf_weaks.c +123 -0
- data/ext/rdwarf/libdwarf/dwarf_weaks.h +29 -0
- data/ext/rdwarf/libdwarf/dwarf_xu_index.c +579 -0
- data/ext/rdwarf/libdwarf/dwarf_xu_index.h +68 -0
- data/ext/rdwarf/libdwarf/dwgetopt.c +181 -0
- data/ext/rdwarf/libdwarf/dwgetopt.h +51 -0
- data/ext/rdwarf/libdwarf/gennames.c +531 -0
- data/ext/rdwarf/libdwarf/install.sh +119 -0
- data/ext/rdwarf/libdwarf/libdwarf.h.in +3746 -0
- data/ext/rdwarf/libdwarf/libdwarf2.1.mm +9805 -0
- data/ext/rdwarf/libdwarf/libdwarf2.1.pdf +0 -0
- data/ext/rdwarf/libdwarf/libdwarf2p.1.mm +2807 -0
- data/ext/rdwarf/libdwarf/libdwarf2p.1.pdf +0 -0
- data/ext/rdwarf/libdwarf/libdwarfdefs.h +81 -0
- data/ext/rdwarf/libdwarf/malloc_check.c +327 -0
- data/ext/rdwarf/libdwarf/malloc_check.h +52 -0
- data/ext/rdwarf/libdwarf/mips_extensions.mm +1266 -0
- data/ext/rdwarf/libdwarf/mips_extensions.pdf +0 -0
- data/ext/rdwarf/libdwarf/pro_alloc.c +179 -0
- data/ext/rdwarf/libdwarf/pro_alloc.h +33 -0
- data/ext/rdwarf/libdwarf/pro_arange.c +310 -0
- data/ext/rdwarf/libdwarf/pro_arange.h +51 -0
- data/ext/rdwarf/libdwarf/pro_die.c +431 -0
- data/ext/rdwarf/libdwarf/pro_die.h +59 -0
- data/ext/rdwarf/libdwarf/pro_encode_nm.c +108 -0
- data/ext/rdwarf/libdwarf/pro_encode_nm.h +39 -0
- data/ext/rdwarf/libdwarf/pro_error.c +96 -0
- data/ext/rdwarf/libdwarf/pro_error.h +43 -0
- data/ext/rdwarf/libdwarf/pro_expr.c +575 -0
- data/ext/rdwarf/libdwarf/pro_expr.h +36 -0
- data/ext/rdwarf/libdwarf/pro_finish.c +45 -0
- data/ext/rdwarf/libdwarf/pro_forms.c +1271 -0
- data/ext/rdwarf/libdwarf/pro_frame.c +572 -0
- data/ext/rdwarf/libdwarf/pro_frame.h +120 -0
- data/ext/rdwarf/libdwarf/pro_funcs.c +50 -0
- data/ext/rdwarf/libdwarf/pro_incl.h +91 -0
- data/ext/rdwarf/libdwarf/pro_init.c +327 -0
- data/ext/rdwarf/libdwarf/pro_line.c +373 -0
- data/ext/rdwarf/libdwarf/pro_line.h +112 -0
- data/ext/rdwarf/libdwarf/pro_macinfo.c +457 -0
- data/ext/rdwarf/libdwarf/pro_macinfo.h +31 -0
- data/ext/rdwarf/libdwarf/pro_opaque.h +513 -0
- data/ext/rdwarf/libdwarf/pro_pubnames.c +60 -0
- data/ext/rdwarf/libdwarf/pro_reloc.c +253 -0
- data/ext/rdwarf/libdwarf/pro_reloc.h +38 -0
- data/ext/rdwarf/libdwarf/pro_reloc_stream.c +256 -0
- data/ext/rdwarf/libdwarf/pro_reloc_stream.h +52 -0
- data/ext/rdwarf/libdwarf/pro_reloc_symbolic.c +245 -0
- data/ext/rdwarf/libdwarf/pro_reloc_symbolic.h +45 -0
- data/ext/rdwarf/libdwarf/pro_section.c +2233 -0
- data/ext/rdwarf/libdwarf/pro_section.h +100 -0
- data/ext/rdwarf/libdwarf/pro_types.c +274 -0
- data/ext/rdwarf/libdwarf/pro_types.h +34 -0
- data/ext/rdwarf/libdwarf/pro_util.h +38 -0
- data/ext/rdwarf/libdwarf/pro_vars.c +52 -0
- data/ext/rdwarf/libdwarf/pro_weaks.c +51 -0
- data/ext/rdwarf/rdwarf.c +765 -0
- data/ext/rdwarf/rdwarf.h +52 -0
- data/ext/rdwarf/rdwarf_names_gen.rb +109 -0
- data/lib/rdwarf.rb +181 -0
- data/lib/rdwarf/version.rb +3 -0
- data/rdwarf.gemspec +30 -0
- metadata +251 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
|
|
4
|
+
Portions Copyright 2011 David Anderson. All Rights Reserved.
|
|
5
|
+
|
|
6
|
+
This program is free software; you can redistribute it and/or modify it
|
|
7
|
+
under the terms of version 2.1 of the GNU Lesser General Public License
|
|
8
|
+
as published by the Free Software Foundation.
|
|
9
|
+
|
|
10
|
+
This program is distributed in the hope that it would be useful, but
|
|
11
|
+
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
13
|
+
|
|
14
|
+
Further, this software is distributed without any warranty that it is
|
|
15
|
+
free of the rightful claim of any third person regarding infringement
|
|
16
|
+
or the like. Any license provided herein, whether implied or
|
|
17
|
+
otherwise, applies only to this software file. Patent licenses, if
|
|
18
|
+
any, provided herein do not apply to combinations of this program with
|
|
19
|
+
other software, or any other product whatsoever.
|
|
20
|
+
|
|
21
|
+
You should have received a copy of the GNU Lesser General Public
|
|
22
|
+
License along with this program; if not, write the Free Software
|
|
23
|
+
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
|
|
24
|
+
USA.
|
|
25
|
+
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
#include "config.h"
|
|
29
|
+
#include "libdwarfdefs.h"
|
|
30
|
+
#include <stdio.h>
|
|
31
|
+
#include <string.h>
|
|
32
|
+
#ifdef HAVE_ELFACCESS_H
|
|
33
|
+
#include <elfaccess.h>
|
|
34
|
+
#endif
|
|
35
|
+
#include "pro_incl.h"
|
|
36
|
+
#include "pro_section.h"
|
|
37
|
+
|
|
38
|
+
/*
|
|
39
|
+
This function adds another weak name to the
|
|
40
|
+
list of weak names for the given Dwarf_P_Debug.
|
|
41
|
+
It returns 0 on error, and 1 otherwise.
|
|
42
|
+
*/
|
|
43
|
+
Dwarf_Unsigned
|
|
44
|
+
dwarf_add_weakname(Dwarf_P_Debug dbg,
|
|
45
|
+
Dwarf_P_Die die,
|
|
46
|
+
char *weak_name, Dwarf_Error * error)
|
|
47
|
+
{
|
|
48
|
+
return
|
|
49
|
+
_dwarf_add_simple_name_entry(dbg, die, weak_name,
|
|
50
|
+
dwarf_snk_weakname, error);
|
|
51
|
+
}
|
data/ext/rdwarf/rdwarf.c
ADDED
|
@@ -0,0 +1,765 @@
|
|
|
1
|
+
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*-
|
|
2
|
+
*
|
|
3
|
+
* rdwarf - a ruby module to read DWARF debugging information
|
|
4
|
+
* https://github.com/kubo/rdwarf
|
|
5
|
+
*
|
|
6
|
+
* Copyright (C) 2015 Kubo Takehiro <kubo@jiubao.org>
|
|
7
|
+
*
|
|
8
|
+
* Redistribution and use in source and binary forms, with or without
|
|
9
|
+
* modification, are permitted provided that the following conditions are met:
|
|
10
|
+
*
|
|
11
|
+
* 1. Redistributions of source code must retain the above copyright
|
|
12
|
+
* notice, this list of conditions and the following disclaimer.
|
|
13
|
+
*
|
|
14
|
+
* 2. Redistributions in binary form must reproduce the above
|
|
15
|
+
* copyright notice, this list of conditions and the following
|
|
16
|
+
* disclaimer in the documentation and/or other materials provided
|
|
17
|
+
* with the distribution.
|
|
18
|
+
*
|
|
19
|
+
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS OR
|
|
20
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
21
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR CONTRIBUTORS BE
|
|
23
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
24
|
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
25
|
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
26
|
+
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
27
|
+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
28
|
+
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
29
|
+
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
30
|
+
*
|
|
31
|
+
* The views and conclusions contained in the software and documentation
|
|
32
|
+
* are those of the authors and should not be interpreted as representing
|
|
33
|
+
* official policies, either expressed or implied, of the authors.
|
|
34
|
+
*/
|
|
35
|
+
#include "rdwarf.h"
|
|
36
|
+
#include <ruby/encoding.h>
|
|
37
|
+
#include <libelf.h>
|
|
38
|
+
#include <fcntl.h>
|
|
39
|
+
|
|
40
|
+
static VALUE cRDwarf; /* RDwarf */
|
|
41
|
+
static VALUE rd_eError; /* RDwarf:Error */
|
|
42
|
+
static VALUE rd_mDie; /* RDwarf::Die */
|
|
43
|
+
static VALUE rd_cDieBase; /* RDwarf::Die:Base */
|
|
44
|
+
static VALUE rd_mAttr; /* RDwarf::Attribute */
|
|
45
|
+
static VALUE rd_cAttrBase; /* RDwarf::Attribute::Base */
|
|
46
|
+
static VALUE rd_cLocList; /* RDwarf::LocationList */
|
|
47
|
+
static VALUE rd_cLocDesc; /* RDwarf::LocationDescriptor */
|
|
48
|
+
|
|
49
|
+
static VALUE sym_unsupported_type;
|
|
50
|
+
static ID id_at_top;
|
|
51
|
+
static ID id_at_cu;
|
|
52
|
+
|
|
53
|
+
typedef struct {
|
|
54
|
+
Elf *elf;
|
|
55
|
+
Dwarf_Debug dbg;
|
|
56
|
+
size_t refcnt;
|
|
57
|
+
VALUE off2die;
|
|
58
|
+
} rd_shared_data_t;
|
|
59
|
+
|
|
60
|
+
typedef struct {
|
|
61
|
+
rd_shared_data_t *shared_data;
|
|
62
|
+
VALUE compile_units;
|
|
63
|
+
} rdwarf_t;
|
|
64
|
+
|
|
65
|
+
typedef struct {
|
|
66
|
+
rd_shared_data_t *shared_data;
|
|
67
|
+
Dwarf_Die die;
|
|
68
|
+
VALUE children;
|
|
69
|
+
VALUE attributes;
|
|
70
|
+
VALUE srcfiles;
|
|
71
|
+
} rd_die_t;
|
|
72
|
+
|
|
73
|
+
typedef struct {
|
|
74
|
+
rd_shared_data_t *shared_data;
|
|
75
|
+
Dwarf_Attribute attr;
|
|
76
|
+
Dwarf_Half attr_type;
|
|
77
|
+
} rd_attr_t;
|
|
78
|
+
|
|
79
|
+
#define rd_shared_data_ref(sd) (++(sd)->refcnt, (sd))
|
|
80
|
+
#define rd_shared_data_unref(sd) ((--(sd)->refcnt) == 0 ? rd_shared_data_free(sd) : 0)
|
|
81
|
+
|
|
82
|
+
#define GetRDwarf(obj) (rdwarf_t*)rb_check_typeddata((obj), &rdwarf_data_type)
|
|
83
|
+
#define GetDie(obj) (rd_die_t*)rb_check_typeddata((obj), &rd_die_data_type)
|
|
84
|
+
#define GetAttr(obj) (rd_attr_t*)rb_check_typeddata((obj), &rd_attr_data_type)
|
|
85
|
+
|
|
86
|
+
static VALUE rd_die_new(rd_shared_data_t *sd, VALUE top, VALUE cu, Dwarf_Die die);
|
|
87
|
+
static VALUE rd_attr_new(rd_shared_data_t *sd, VALUE top, VALUE cu, Dwarf_Attribute attr);
|
|
88
|
+
static VALUE rd_attr_loc_list(VALUE self);
|
|
89
|
+
|
|
90
|
+
static rd_shared_data_t *rd_shared_data_alloc(Elf *elf, Dwarf_Debug dbg, VALUE obj)
|
|
91
|
+
{
|
|
92
|
+
rd_shared_data_t *sd = xmalloc(sizeof(rd_shared_data_t));
|
|
93
|
+
sd->elf = elf;
|
|
94
|
+
sd->dbg = dbg;
|
|
95
|
+
sd->refcnt = 1;
|
|
96
|
+
sd->off2die = rb_hash_new();
|
|
97
|
+
return sd;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static void rd_shared_data_mark(rd_shared_data_t *sd)
|
|
101
|
+
{
|
|
102
|
+
if (sd != NULL) {
|
|
103
|
+
rb_gc_mark(sd->off2die);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
static void rd_shared_data_free(rd_shared_data_t *sd)
|
|
108
|
+
{
|
|
109
|
+
Dwarf_Error err;
|
|
110
|
+
|
|
111
|
+
dwarf_finish(sd->dbg, &err);
|
|
112
|
+
elf_end(sd->elf);
|
|
113
|
+
xfree(sd);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
static void chkerr1(int ret, Dwarf_Error *err, VALUE obj)
|
|
117
|
+
{
|
|
118
|
+
VALUE exc = Qnil;
|
|
119
|
+
switch (ret) {
|
|
120
|
+
case DW_DLV_NO_ENTRY:
|
|
121
|
+
exc = rb_exc_new_cstr(rd_eError, "No Entry");
|
|
122
|
+
case DW_DLV_ERROR:
|
|
123
|
+
if (err != NULL) {
|
|
124
|
+
exc = rb_exc_new_cstr(rd_eError, dwarf_errmsg(*err));
|
|
125
|
+
} else {
|
|
126
|
+
exc = rb_exc_new_cstr(rd_eError, "Unknown Error");
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (!NIL_P(exc)) {
|
|
130
|
+
rb_iv_set(exc, "@obj", obj);
|
|
131
|
+
rb_exc_raise(exc);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
static int chkerr2(int ret, Dwarf_Error *err)
|
|
136
|
+
{
|
|
137
|
+
if (ret == DW_DLV_ERROR) {
|
|
138
|
+
if (err != NULL) {
|
|
139
|
+
rb_raise(rd_eError, "%s", dwarf_errmsg(*err));
|
|
140
|
+
} else {
|
|
141
|
+
rb_raise(rd_eError, "Unknown Error");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return ret == DW_DLV_OK;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/*******************************************
|
|
148
|
+
* class definitins
|
|
149
|
+
*******************************************/
|
|
150
|
+
|
|
151
|
+
/* RDwarf */
|
|
152
|
+
|
|
153
|
+
static void rdwarf_dmark(void *ptr)
|
|
154
|
+
{
|
|
155
|
+
rdwarf_t *rd = (rdwarf_t *)ptr;
|
|
156
|
+
rd_shared_data_mark(rd->shared_data);
|
|
157
|
+
rb_gc_mark(rd->compile_units);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
static void rdwarf_dfree(void *ptr)
|
|
161
|
+
{
|
|
162
|
+
rdwarf_t *rd = (rdwarf_t *)ptr;
|
|
163
|
+
|
|
164
|
+
if (rd->shared_data != NULL) {
|
|
165
|
+
rd_shared_data_unref(rd->shared_data);
|
|
166
|
+
}
|
|
167
|
+
xfree(rd);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
static size_t rdwarf_dsize(const void *ptr)
|
|
171
|
+
{
|
|
172
|
+
return sizeof(rdwarf_t);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
static const rb_data_type_t rdwarf_data_type = {
|
|
176
|
+
"RDwarf",
|
|
177
|
+
{rdwarf_dmark, rdwarf_dfree, rdwarf_dsize,},
|
|
178
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
|
179
|
+
NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
|
|
180
|
+
#endif
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
/* RDwarf::DIE:Base */
|
|
184
|
+
|
|
185
|
+
static void rd_die_dmark(void *ptr)
|
|
186
|
+
{
|
|
187
|
+
rd_die_t *die = (rd_die_t *)ptr;
|
|
188
|
+
rd_shared_data_mark(die->shared_data);
|
|
189
|
+
rb_gc_mark(die->children);
|
|
190
|
+
rb_gc_mark(die->attributes);
|
|
191
|
+
rb_gc_mark(die->srcfiles);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
static void rd_die_dfree(void *ptr)
|
|
195
|
+
{
|
|
196
|
+
rd_die_t *die = (rd_die_t *)ptr;
|
|
197
|
+
if (die->shared_data != NULL) {
|
|
198
|
+
if (die->die != NULL) {
|
|
199
|
+
dwarf_dealloc(die->shared_data->dbg, die->die, DW_DLA_DIE);
|
|
200
|
+
}
|
|
201
|
+
rd_shared_data_unref(die->shared_data);
|
|
202
|
+
}
|
|
203
|
+
xfree(die);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
static size_t rd_die_dsize(const void *ptr)
|
|
207
|
+
{
|
|
208
|
+
return sizeof(rd_die_t);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
static const rb_data_type_t rd_die_data_type = {
|
|
212
|
+
"RDwarf::Die:Base",
|
|
213
|
+
{rd_die_dmark, rd_die_dfree, rd_die_dsize,},
|
|
214
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
|
215
|
+
NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
|
|
216
|
+
#endif
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
/* RDwarf::Attribute:Base */
|
|
220
|
+
|
|
221
|
+
static void rd_attr_dmark(void *ptr)
|
|
222
|
+
{
|
|
223
|
+
rd_attr_t *attr = (rd_attr_t *)ptr;
|
|
224
|
+
rd_shared_data_mark(attr->shared_data);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
static void rd_attr_dfree(void *ptr)
|
|
228
|
+
{
|
|
229
|
+
rd_attr_t *attr = (rd_attr_t *)ptr;
|
|
230
|
+
if (attr->shared_data != NULL) {
|
|
231
|
+
if (attr->attr != NULL) {
|
|
232
|
+
dwarf_dealloc(attr->shared_data->dbg, attr->attr, DW_DLA_ATTR);
|
|
233
|
+
}
|
|
234
|
+
rd_shared_data_unref(attr->shared_data);
|
|
235
|
+
}
|
|
236
|
+
xfree(attr);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
static size_t rd_attr_dsize(const void *ptr)
|
|
240
|
+
{
|
|
241
|
+
return sizeof(rd_attr_t);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
static const rb_data_type_t rd_attr_data_type = {
|
|
245
|
+
"RDwarf::Attribute:Base",
|
|
246
|
+
{rd_attr_dmark, rd_attr_dfree, rd_attr_dsize,},
|
|
247
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
|
248
|
+
NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
|
|
249
|
+
#endif
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
/*******************************************
|
|
253
|
+
* method definitins
|
|
254
|
+
*******************************************/
|
|
255
|
+
|
|
256
|
+
/* RDwarf */
|
|
257
|
+
|
|
258
|
+
static VALUE rdwarf_s_alloc(VALUE klass)
|
|
259
|
+
{
|
|
260
|
+
VALUE obj;
|
|
261
|
+
rdwarf_t *rd;
|
|
262
|
+
|
|
263
|
+
obj = TypedData_Make_Struct(klass, rdwarf_t, &rdwarf_data_type, rd);
|
|
264
|
+
rd->compile_units = Qfalse;
|
|
265
|
+
return obj;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
static VALUE rdwarf_initialize(VALUE self, VALUE filename)
|
|
269
|
+
{
|
|
270
|
+
rdwarf_t *rd = GetRDwarf(self);
|
|
271
|
+
Elf *elf;
|
|
272
|
+
Dwarf_Debug dbg;
|
|
273
|
+
Dwarf_Error err;
|
|
274
|
+
int fd;
|
|
275
|
+
int ret;
|
|
276
|
+
|
|
277
|
+
SafeStringValue(filename);
|
|
278
|
+
filename = rb_str_export_to_enc(filename, rb_filesystem_encoding());
|
|
279
|
+
|
|
280
|
+
fd = rb_cloexec_open(StringValueCStr(filename), O_RDONLY, 0);
|
|
281
|
+
if (fd < 0) {
|
|
282
|
+
rb_sys_fail("open");
|
|
283
|
+
}
|
|
284
|
+
elf = elf_begin(fd, ELF_C_READ, (Elf*)0);
|
|
285
|
+
ret = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dbg, &err);
|
|
286
|
+
if (ret == DW_DLV_NO_ENTRY) {
|
|
287
|
+
elf_end(elf);
|
|
288
|
+
rb_raise(rd_eError, "%s", dwarf_errmsg(err));
|
|
289
|
+
}
|
|
290
|
+
rd->shared_data = rd_shared_data_alloc(elf, dbg, self);
|
|
291
|
+
return self;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
static VALUE rdwarf_compile_units(VALUE self)
|
|
295
|
+
{
|
|
296
|
+
rdwarf_t *rd = GetRDwarf(self);
|
|
297
|
+
Dwarf_Unsigned cu_header_length = 0;
|
|
298
|
+
Dwarf_Unsigned abbrev_offset = 0;
|
|
299
|
+
Dwarf_Half version_stamp = 0;
|
|
300
|
+
Dwarf_Half address_size = 0;
|
|
301
|
+
Dwarf_Unsigned next_cu_offset = 0;
|
|
302
|
+
Dwarf_Error err;
|
|
303
|
+
Dwarf_Die die;
|
|
304
|
+
VALUE ary;
|
|
305
|
+
|
|
306
|
+
if (rd->compile_units != Qfalse) {
|
|
307
|
+
return rd->compile_units;
|
|
308
|
+
}
|
|
309
|
+
ary = rb_ary_new();
|
|
310
|
+
|
|
311
|
+
while (dwarf_next_cu_header(rd->shared_data->dbg, &cu_header_length, &version_stamp, &abbrev_offset,
|
|
312
|
+
&address_size, &next_cu_offset, &err) == DW_DLV_OK) {
|
|
313
|
+
if (!chkerr2(dwarf_siblingof(rd->shared_data->dbg, NULL, &die, &err), &err)) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
rb_ary_push(ary, rd_die_new(rd->shared_data, self, Qnil, die));
|
|
317
|
+
}
|
|
318
|
+
rd->compile_units = ary;
|
|
319
|
+
return ary;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
static VALUE rdwarf_die_at(VALUE self, VALUE offset)
|
|
323
|
+
{
|
|
324
|
+
rdwarf_t *rd = GetRDwarf(self);
|
|
325
|
+
Dwarf_Die die;
|
|
326
|
+
Dwarf_Off cu_off;
|
|
327
|
+
Dwarf_Error err;
|
|
328
|
+
VALUE cu;
|
|
329
|
+
|
|
330
|
+
chkerr1(dwarf_offdie(rd->shared_data->dbg, NUM2LL(offset), &die, &err), &err, self);
|
|
331
|
+
chkerr1(dwarf_CU_dieoffset_given_die(die, &cu_off, &err), &err, self);
|
|
332
|
+
|
|
333
|
+
rdwarf_compile_units(self);
|
|
334
|
+
cu = rb_hash_aref(rd->shared_data->off2die, LL2NUM(cu_off));
|
|
335
|
+
if (NIL_P(cu)) {
|
|
336
|
+
rb_raise(rd_eError, "Cannot find CU");
|
|
337
|
+
}
|
|
338
|
+
return rd_die_new(rd->shared_data, self, cu, die);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/* RDwarf::DIE */
|
|
342
|
+
|
|
343
|
+
static VALUE rd_die_s_alloc(VALUE klass)
|
|
344
|
+
{
|
|
345
|
+
VALUE obj;
|
|
346
|
+
rd_die_t *die;
|
|
347
|
+
|
|
348
|
+
obj = TypedData_Make_Struct(klass, rd_die_t, &rd_die_data_type, die);
|
|
349
|
+
die->children = Qfalse;
|
|
350
|
+
die->attributes = Qfalse;
|
|
351
|
+
die->srcfiles = Qfalse;
|
|
352
|
+
return obj;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
static VALUE rd_die_new(rd_shared_data_t *sd, VALUE top, VALUE cu, Dwarf_Die die)
|
|
356
|
+
{
|
|
357
|
+
rd_die_t *rd_die;
|
|
358
|
+
Dwarf_Off off;
|
|
359
|
+
Dwarf_Half tag;
|
|
360
|
+
Dwarf_Error err;
|
|
361
|
+
VALUE obj;
|
|
362
|
+
VALUE klass;
|
|
363
|
+
|
|
364
|
+
chkerr1(dwarf_dieoffset(die, &off, &err), &err, Qnil);
|
|
365
|
+
obj = rb_hash_aref(sd->off2die, LL2NUM(off));
|
|
366
|
+
if (!NIL_P(obj)) {
|
|
367
|
+
return obj;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
chkerr1(dwarf_tag(die, &tag, &err), &err, Qnil);
|
|
371
|
+
klass = rb_hash_aref(rdwarf_tag2class, INT2FIX(tag));
|
|
372
|
+
if (NIL_P(klass)) {
|
|
373
|
+
rb_raise(rb_eRuntimeError, "unknown tag %d\n", tag);
|
|
374
|
+
}
|
|
375
|
+
obj = rd_die_s_alloc(klass);
|
|
376
|
+
rd_die = GetDie(obj);
|
|
377
|
+
rd_die->shared_data = rd_shared_data_ref(sd);
|
|
378
|
+
rd_die->die = die;
|
|
379
|
+
rb_ivar_set(obj, id_at_top, top);
|
|
380
|
+
rb_ivar_set(obj, id_at_cu, NIL_P(cu) ? obj : cu);
|
|
381
|
+
rb_hash_aset(sd->off2die, LL2NUM(off), obj);
|
|
382
|
+
return obj;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
static VALUE rd_die_name(VALUE self)
|
|
386
|
+
{
|
|
387
|
+
rd_die_t *die = GetDie(self);
|
|
388
|
+
char *name;
|
|
389
|
+
Dwarf_Error err;
|
|
390
|
+
|
|
391
|
+
if (chkerr2(dwarf_diename(die->die, &name, &err), &err)) {
|
|
392
|
+
return rb_enc_str_new_cstr(name, rb_usascii_encoding());
|
|
393
|
+
} else {
|
|
394
|
+
return Qnil;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
static VALUE rd_die_tag_name(VALUE self)
|
|
399
|
+
{
|
|
400
|
+
rd_die_t *die = GetDie(self);
|
|
401
|
+
Dwarf_Half tag = 0;
|
|
402
|
+
Dwarf_Error err;
|
|
403
|
+
|
|
404
|
+
chkerr1(dwarf_tag(die->die, &tag, &err), &err, self);
|
|
405
|
+
return rb_hash_aref(rdwarf_tag2name, INT2FIX(tag));
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
static VALUE rd_die_die_offset(VALUE self)
|
|
409
|
+
{
|
|
410
|
+
rd_die_t *die = GetDie(self);
|
|
411
|
+
Dwarf_Off off;
|
|
412
|
+
Dwarf_Error err;
|
|
413
|
+
|
|
414
|
+
chkerr1(dwarf_dieoffset(die->die, &off, &err), &err, self);
|
|
415
|
+
return LL2NUM(off);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
static VALUE rd_die_die_cu_offset(VALUE self)
|
|
419
|
+
{
|
|
420
|
+
rd_die_t *die = GetDie(self);
|
|
421
|
+
Dwarf_Off off;
|
|
422
|
+
Dwarf_Error err;
|
|
423
|
+
|
|
424
|
+
chkerr1(dwarf_die_CU_offset(die->die, &off, &err), &err, self);
|
|
425
|
+
return LL2NUM(off);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
static VALUE rd_die_children(VALUE self)
|
|
429
|
+
{
|
|
430
|
+
rd_die_t *die = GetDie(self);
|
|
431
|
+
VALUE top;
|
|
432
|
+
VALUE cu;
|
|
433
|
+
VALUE ary;
|
|
434
|
+
Dwarf_Die child;
|
|
435
|
+
Dwarf_Error err;
|
|
436
|
+
|
|
437
|
+
if (die->children != Qfalse) {
|
|
438
|
+
return die->children;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
top = rb_ivar_get(self, id_at_top);
|
|
442
|
+
cu = rb_ivar_get(self, id_at_cu);
|
|
443
|
+
ary = rb_ary_new();
|
|
444
|
+
if (chkerr2(dwarf_child(die->die, &child, &err), &err)) {
|
|
445
|
+
do {
|
|
446
|
+
rb_ary_push(ary, rd_die_new(die->shared_data, top, cu, child));
|
|
447
|
+
} while (chkerr2(dwarf_siblingof(die->shared_data->dbg, child, &child, &err), &err));
|
|
448
|
+
}
|
|
449
|
+
die->children = ary;
|
|
450
|
+
return ary;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
static VALUE rd_die_attributes(VALUE self)
|
|
454
|
+
{
|
|
455
|
+
rd_die_t *die = GetDie(self);
|
|
456
|
+
Dwarf_Attribute *list;
|
|
457
|
+
Dwarf_Signed count;
|
|
458
|
+
Dwarf_Error err;
|
|
459
|
+
Dwarf_Signed idx;
|
|
460
|
+
VALUE top;
|
|
461
|
+
VALUE cu;
|
|
462
|
+
VALUE ary;
|
|
463
|
+
|
|
464
|
+
if (die->attributes != Qfalse) {
|
|
465
|
+
return die->attributes;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
top = rb_ivar_get(self, id_at_top);
|
|
469
|
+
cu = rb_ivar_get(self, id_at_cu);
|
|
470
|
+
if (chkerr2(dwarf_attrlist(die->die, &list, &count, &err), &err)) {
|
|
471
|
+
ary = rb_ary_new_capa(count);
|
|
472
|
+
for (idx = 0; idx < count; idx++) {
|
|
473
|
+
rb_ary_store(ary, idx, rd_attr_new(die->shared_data, top, cu, list[idx]));
|
|
474
|
+
}
|
|
475
|
+
} else {
|
|
476
|
+
ary = rb_ary_new();
|
|
477
|
+
}
|
|
478
|
+
die->attributes = ary;
|
|
479
|
+
return ary;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
static VALUE rd_die_source_files(VALUE self)
|
|
483
|
+
{
|
|
484
|
+
rd_die_t *die = GetDie(self);
|
|
485
|
+
Dwarf_Signed cnt = 0;
|
|
486
|
+
char **srcfiles = 0;
|
|
487
|
+
Dwarf_Error err;
|
|
488
|
+
VALUE files = Qnil;
|
|
489
|
+
|
|
490
|
+
if (die->srcfiles != Qfalse) {
|
|
491
|
+
return die->srcfiles;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
if (chkerr2(dwarf_srcfiles(die->die, &srcfiles, &cnt, &err), &err)) {
|
|
495
|
+
int i;
|
|
496
|
+
|
|
497
|
+
files = rb_ary_new_capa(cnt);
|
|
498
|
+
for (i = 0; i < cnt; i++) {
|
|
499
|
+
VALUE file = rb_str_new_cstr(srcfiles[i]);
|
|
500
|
+
OBJ_FREEZE(file);
|
|
501
|
+
rb_ary_store(files, i, file);
|
|
502
|
+
dwarf_dealloc(die->shared_data->dbg, srcfiles[i], DW_DLA_STRING);
|
|
503
|
+
}
|
|
504
|
+
dwarf_dealloc(die->shared_data->dbg, srcfiles, DW_DLA_LIST);
|
|
505
|
+
}
|
|
506
|
+
die->srcfiles = files;
|
|
507
|
+
return files;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
static VALUE rd_die_inspect(VALUE self)
|
|
511
|
+
{
|
|
512
|
+
rd_die_t *die = GetDie(self);
|
|
513
|
+
char *name;
|
|
514
|
+
Dwarf_Off dieoff = 0;
|
|
515
|
+
Dwarf_Error err;
|
|
516
|
+
|
|
517
|
+
dwarf_dieoffset(die->die, &dieoff, &err);
|
|
518
|
+
|
|
519
|
+
switch (dwarf_diename(die->die, &name, &err)) {
|
|
520
|
+
case DW_DLV_OK:
|
|
521
|
+
return rb_sprintf("#<%s:(%llu) '%s'>", rb_obj_classname(self), dieoff, name);
|
|
522
|
+
default:
|
|
523
|
+
return rb_sprintf("#<%s:(%llu)>", rb_obj_classname(self), dieoff);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/* RDwarf::Attribute */
|
|
528
|
+
|
|
529
|
+
static VALUE rd_attr_s_alloc(VALUE klass)
|
|
530
|
+
{
|
|
531
|
+
VALUE obj;
|
|
532
|
+
rd_attr_t *attr;
|
|
533
|
+
|
|
534
|
+
obj = TypedData_Make_Struct(klass, rd_attr_t, &rd_attr_data_type, attr);
|
|
535
|
+
return obj;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
static VALUE rd_attr_new(rd_shared_data_t *sd, VALUE top, VALUE cu, Dwarf_Attribute attr)
|
|
539
|
+
{
|
|
540
|
+
rd_attr_t *rd_attr;
|
|
541
|
+
Dwarf_Error err;
|
|
542
|
+
VALUE obj;
|
|
543
|
+
VALUE klass;
|
|
544
|
+
Dwarf_Half attr_type = 0;
|
|
545
|
+
|
|
546
|
+
chkerr1(dwarf_whatattr(attr, &attr_type, &err), &err, Qnil);
|
|
547
|
+
klass = rb_hash_aref(rdwarf_at2class, INT2FIX(attr_type));
|
|
548
|
+
if (NIL_P(klass)) {
|
|
549
|
+
rb_raise(rb_eRuntimeError, "unknown attribute %d\n", attr_type);
|
|
550
|
+
}
|
|
551
|
+
obj = rd_attr_s_alloc(klass);
|
|
552
|
+
rd_attr = GetAttr(obj);
|
|
553
|
+
rd_attr->shared_data = rd_shared_data_ref(sd);
|
|
554
|
+
rd_attr->attr = attr;
|
|
555
|
+
rd_attr->attr_type = attr_type;
|
|
556
|
+
rb_ivar_set(obj, id_at_top, top);
|
|
557
|
+
rb_ivar_set(obj, id_at_cu, cu);
|
|
558
|
+
return obj;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
static VALUE rd_attr_type(VALUE self)
|
|
562
|
+
{
|
|
563
|
+
rd_attr_t *attr = GetAttr(self);
|
|
564
|
+
return rb_hash_aref(rdwarf_at2name, INT2FIX(attr->attr_type));
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
static VALUE rd_attr_form(VALUE self)
|
|
568
|
+
{
|
|
569
|
+
rd_attr_t *attr = GetAttr(self);
|
|
570
|
+
Dwarf_Half form_type;
|
|
571
|
+
Dwarf_Error err;
|
|
572
|
+
|
|
573
|
+
chkerr1(dwarf_whatform(attr->attr, &form_type, &err), &err, self);
|
|
574
|
+
return rb_hash_aref(rdwarf_form2name, INT2FIX(form_type));
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
static VALUE rd_attr_raw_value(VALUE self)
|
|
578
|
+
{
|
|
579
|
+
rd_attr_t *attr = GetAttr(self);
|
|
580
|
+
Dwarf_Half form;
|
|
581
|
+
Dwarf_Error err;
|
|
582
|
+
union {
|
|
583
|
+
Dwarf_Addr addr;
|
|
584
|
+
Dwarf_Off off;
|
|
585
|
+
Dwarf_Unsigned udata;
|
|
586
|
+
Dwarf_Signed sdata;
|
|
587
|
+
Dwarf_Bool bool;
|
|
588
|
+
char *str;
|
|
589
|
+
} val;
|
|
590
|
+
VALUE top;
|
|
591
|
+
|
|
592
|
+
chkerr1(dwarf_whatform(attr->attr, &form, &err), &err, self);
|
|
593
|
+
switch (form) {
|
|
594
|
+
case DW_FORM_addr:
|
|
595
|
+
chkerr1(dwarf_formaddr(attr->attr, &val.addr, &err), &err, self);
|
|
596
|
+
return ULL2NUM(val.addr);
|
|
597
|
+
case DW_FORM_ref1:
|
|
598
|
+
case DW_FORM_ref2:
|
|
599
|
+
case DW_FORM_ref4:
|
|
600
|
+
case DW_FORM_ref8:
|
|
601
|
+
case DW_FORM_ref_udata:
|
|
602
|
+
chkerr1(dwarf_global_formref(attr->attr, &val.off, &err), &err, self);
|
|
603
|
+
top = rb_ivar_get(self, id_at_top);
|
|
604
|
+
return rdwarf_die_at(top, LL2NUM(val.off));
|
|
605
|
+
case DW_FORM_data1:
|
|
606
|
+
case DW_FORM_data2:
|
|
607
|
+
case DW_FORM_data4:
|
|
608
|
+
case DW_FORM_data8:
|
|
609
|
+
case DW_FORM_udata:
|
|
610
|
+
chkerr1(dwarf_formudata(attr->attr, &val.udata, &err), &err, self);
|
|
611
|
+
return ULL2NUM(val.udata);
|
|
612
|
+
case DW_FORM_sdata:
|
|
613
|
+
chkerr1(dwarf_formsdata(attr->attr, &val.sdata, &err), &err, self);
|
|
614
|
+
return LL2NUM(val.sdata);
|
|
615
|
+
case DW_FORM_flag:
|
|
616
|
+
chkerr1(dwarf_formflag(attr->attr, &val.bool, &err), &err, self);
|
|
617
|
+
return val.bool ? Qtrue : Qfalse;
|
|
618
|
+
case DW_FORM_strp:
|
|
619
|
+
case DW_FORM_string:
|
|
620
|
+
chkerr1(dwarf_formstring(attr->attr, &val.str, &err), &err, self);
|
|
621
|
+
return rb_str_new_cstr(val.str);
|
|
622
|
+
}
|
|
623
|
+
return sym_unsupported_type;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
static VALUE rd_attr_inspect(VALUE self)
|
|
627
|
+
{
|
|
628
|
+
rd_attr_t *attr = GetAttr(self);
|
|
629
|
+
Dwarf_Half form;
|
|
630
|
+
Dwarf_Error err;
|
|
631
|
+
const char *form_name = "?";
|
|
632
|
+
|
|
633
|
+
if (dwarf_whatform(attr->attr, &form, &err) == DW_DLV_OK) {
|
|
634
|
+
dwarf_get_FORM_name(form, &form_name);
|
|
635
|
+
}
|
|
636
|
+
return rb_sprintf("#<%s: %s>", rb_obj_classname(self), form_name);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
static VALUE rd_attr_loc_list(VALUE self)
|
|
640
|
+
{
|
|
641
|
+
rd_attr_t *attr = GetAttr(self);
|
|
642
|
+
Dwarf_Error err;
|
|
643
|
+
Dwarf_Loc_Head_c loc_head;
|
|
644
|
+
Dwarf_Unsigned count;
|
|
645
|
+
VALUE lhead;
|
|
646
|
+
Dwarf_Unsigned idx;
|
|
647
|
+
|
|
648
|
+
chkerr1(dwarf_get_loclist_c(attr->attr, &loc_head, &count, &err), &err, self);
|
|
649
|
+
lhead = rb_ary_new_capa(count);
|
|
650
|
+
for (idx = 0; idx < count; idx++) {
|
|
651
|
+
Dwarf_Small lle;
|
|
652
|
+
Dwarf_Addr lowpc;
|
|
653
|
+
Dwarf_Addr hipc;
|
|
654
|
+
Dwarf_Unsigned loclist_count;
|
|
655
|
+
Dwarf_Locdesc_c locentry;
|
|
656
|
+
Dwarf_Small source;
|
|
657
|
+
Dwarf_Unsigned expression_offset;
|
|
658
|
+
Dwarf_Unsigned locdesc_offset;
|
|
659
|
+
ID id_lle;
|
|
660
|
+
ID id_lowpc;
|
|
661
|
+
ID id_hipc;
|
|
662
|
+
ID id_source;
|
|
663
|
+
ID id_expression_offset;
|
|
664
|
+
ID id_locdesc_offset;
|
|
665
|
+
VALUE llist;
|
|
666
|
+
int idx2;
|
|
667
|
+
|
|
668
|
+
CONST_ID(id_lle, "@lle");
|
|
669
|
+
CONST_ID(id_lowpc, "@lowpc");
|
|
670
|
+
CONST_ID(id_hipc, "@hipc");
|
|
671
|
+
CONST_ID(id_source, "@source");
|
|
672
|
+
CONST_ID(id_expression_offset, "@expression_offset");
|
|
673
|
+
CONST_ID(id_locdesc_offset, "@locdesc_offset");
|
|
674
|
+
|
|
675
|
+
chkerr1(dwarf_get_locdesc_entry_c(loc_head, idx, &lle, &lowpc, &hipc,
|
|
676
|
+
&loclist_count, &locentry, &source,
|
|
677
|
+
&expression_offset, &locdesc_offset, &err),
|
|
678
|
+
&err, self);
|
|
679
|
+
llist = rb_class_new_instance(0, NULL, rd_cLocList);
|
|
680
|
+
rb_ivar_set(llist, id_lle, rb_hash_aref(rdwarf_lle2name, INT2FIX(lle)));
|
|
681
|
+
rb_ivar_set(llist, id_lowpc, ULL2NUM(lowpc));
|
|
682
|
+
rb_ivar_set(llist, id_hipc, ULL2NUM(hipc));
|
|
683
|
+
rb_ivar_set(llist, id_source, INT2FIX(source));
|
|
684
|
+
rb_ivar_set(llist, id_expression_offset, ULL2NUM(expression_offset));
|
|
685
|
+
rb_ivar_set(llist, id_locdesc_offset, ULL2NUM(locdesc_offset));
|
|
686
|
+
for (idx2 = 0; idx2 < loclist_count; idx2++) {
|
|
687
|
+
Dwarf_Small atom;
|
|
688
|
+
Dwarf_Unsigned operand1;
|
|
689
|
+
Dwarf_Unsigned operand2;
|
|
690
|
+
Dwarf_Unsigned operand3;
|
|
691
|
+
Dwarf_Unsigned offset_for_branch;
|
|
692
|
+
ID id_atom;
|
|
693
|
+
ID id_operand1;
|
|
694
|
+
ID id_operand2;
|
|
695
|
+
ID id_operand3;
|
|
696
|
+
ID id_offset_for_branch;
|
|
697
|
+
VALUE ldesc;
|
|
698
|
+
|
|
699
|
+
CONST_ID(id_atom, "@atom");
|
|
700
|
+
CONST_ID(id_operand1, "@operand1");
|
|
701
|
+
CONST_ID(id_operand2, "@operand2");
|
|
702
|
+
CONST_ID(id_operand3, "@operand3");
|
|
703
|
+
CONST_ID(id_offset_for_branch, "@offset_for_branch");
|
|
704
|
+
|
|
705
|
+
chkerr1(dwarf_get_location_op_value_c(locentry, idx2, &atom, &operand1, &operand2, &operand3, &offset_for_branch, &err),
|
|
706
|
+
&err, self);
|
|
707
|
+
ldesc = rb_class_new_instance(0, NULL, rd_cLocDesc);
|
|
708
|
+
rb_ivar_set(ldesc, id_atom, rb_hash_aref(rdwarf_op2name, INT2FIX(atom)));
|
|
709
|
+
rb_ivar_set(ldesc, id_operand1, ULL2NUM(operand1));
|
|
710
|
+
rb_ivar_set(ldesc, id_operand2, ULL2NUM(operand2));
|
|
711
|
+
rb_ivar_set(ldesc, id_operand3, ULL2NUM(operand3));
|
|
712
|
+
rb_ivar_set(ldesc, id_offset_for_branch, ULL2NUM(offset_for_branch));
|
|
713
|
+
rb_ary_store(llist, idx2, ldesc);
|
|
714
|
+
}
|
|
715
|
+
rb_ary_store(lhead, idx, llist);
|
|
716
|
+
}
|
|
717
|
+
dwarf_loc_head_c_dealloc(loc_head);
|
|
718
|
+
return lhead;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
void Init_rdwarf(void)
|
|
722
|
+
{
|
|
723
|
+
elf_version(EV_CURRENT);
|
|
724
|
+
|
|
725
|
+
sym_unsupported_type = ID2SYM(rb_intern("unsupported_type"));
|
|
726
|
+
id_at_top = rb_intern("@top");
|
|
727
|
+
id_at_cu = rb_intern("@cu");
|
|
728
|
+
|
|
729
|
+
cRDwarf = rb_define_class("RDwarf", rb_cObject);
|
|
730
|
+
rb_define_alloc_func(cRDwarf, rdwarf_s_alloc);
|
|
731
|
+
rb_define_method(cRDwarf, "initialize", rdwarf_initialize, 1);
|
|
732
|
+
rb_define_method(cRDwarf, "compile_units", rdwarf_compile_units, 0);
|
|
733
|
+
rb_define_method(cRDwarf, "die_at", rdwarf_die_at, 1);
|
|
734
|
+
|
|
735
|
+
rd_mDie = rb_define_module_under(cRDwarf, "DIE");
|
|
736
|
+
rd_cDieBase = rb_define_class_under(rd_mDie, "Base", rb_cObject);
|
|
737
|
+
rb_define_alloc_func(rd_cDieBase, rd_die_s_alloc);
|
|
738
|
+
rb_define_method(rd_cDieBase, "name", rd_die_name, 0);
|
|
739
|
+
rb_define_method(rd_cDieBase, "tag_name", rd_die_tag_name, 0);
|
|
740
|
+
rb_define_method(rd_cDieBase, "die_offset", rd_die_die_offset, 0);
|
|
741
|
+
rb_define_method(rd_cDieBase, "die_cu_offset", rd_die_die_cu_offset, 0);
|
|
742
|
+
rb_define_method(rd_cDieBase, "children", rd_die_children, 0);
|
|
743
|
+
rb_define_method(rd_cDieBase, "attributes", rd_die_attributes, 0);
|
|
744
|
+
rb_define_method(rd_cDieBase, "source_files", rd_die_source_files, 0);
|
|
745
|
+
rb_define_method(rd_cDieBase, "to_s", rd_die_inspect, 0);
|
|
746
|
+
rb_define_method(rd_cDieBase, "inspect", rd_die_inspect, 0);
|
|
747
|
+
|
|
748
|
+
rd_mAttr = rb_define_module_under(cRDwarf, "Attribute");
|
|
749
|
+
rd_cAttrBase = rb_define_class_under(rd_mAttr, "Base", rb_cObject);
|
|
750
|
+
rb_define_method(rd_cAttrBase, "type", rd_attr_type, 0);
|
|
751
|
+
rb_define_method(rd_cAttrBase, "form", rd_attr_form, 0);
|
|
752
|
+
rb_define_method(rd_cAttrBase, "raw_value", rd_attr_raw_value, 0);
|
|
753
|
+
rb_define_method(rd_cAttrBase, "value", rd_attr_raw_value, 0);
|
|
754
|
+
rb_define_method(rd_cAttrBase, "to_s", rd_attr_inspect, 0);
|
|
755
|
+
rb_define_method(rd_cAttrBase, "inspect", rd_attr_inspect, 0);
|
|
756
|
+
rb_define_private_method(rd_cAttrBase, "loc_list", rd_attr_loc_list, 0);
|
|
757
|
+
|
|
758
|
+
rd_cLocList = rb_define_class_under(cRDwarf, "LocationList", rb_cArray);
|
|
759
|
+
|
|
760
|
+
rd_cLocDesc = rb_define_class_under(cRDwarf, "LocationDescriptor", rb_cObject);
|
|
761
|
+
|
|
762
|
+
rd_eError = rb_define_class_under(cRDwarf, "Error", rb_eStandardError);
|
|
763
|
+
|
|
764
|
+
Init_rdwarf_names(cRDwarf, rd_mDie, rd_cDieBase, rd_mAttr, rd_cAttrBase);
|
|
765
|
+
}
|