Branch data Line data Source code
1 : : /* Return child of current DIE.
2 : : Copyright (C) 2003-2011 Red Hat, Inc.
3 : : This file is part of elfutils.
4 : : Written by Ulrich Drepper <drepper@redhat.com>, 2003.
5 : :
6 : : This file is free software; you can redistribute it and/or modify
7 : : it under the terms of either
8 : :
9 : : * the GNU Lesser General Public License as published by the Free
10 : : Software Foundation; either version 3 of the License, or (at
11 : : your option) any later version
12 : :
13 : : or
14 : :
15 : : * the GNU General Public License as published by the Free
16 : : Software Foundation; either version 2 of the License, or (at
17 : : your option) any later version
18 : :
19 : : or both in parallel, as here.
20 : :
21 : : elfutils is distributed in the hope that it will be useful, but
22 : : WITHOUT ANY WARRANTY; without even the implied warranty of
23 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : : General Public License for more details.
25 : :
26 : : You should have received copies of the GNU General Public License and
27 : : the GNU Lesser General Public License along with this program. If
28 : : not, see <http://www.gnu.org/licenses/>. */
29 : :
30 : : #ifdef HAVE_CONFIG_H
31 : : # include <config.h>
32 : : #endif
33 : :
34 : : #include "libdwP.h"
35 : : #include <string.h>
36 : :
37 : : /* Some arbitrary value not conflicting with any existing code. */
38 : : #define INVALID 0xffffe444
39 : :
40 : :
41 : : unsigned char *
42 : : internal_function
43 : 15739859 : __libdw_find_attr (Dwarf_Die *die, unsigned int search_name,
44 : : unsigned int *codep, unsigned int *formp)
45 : : {
46 : 15739859 : Dwarf *dbg = die->cu->dbg;
47 : 15739859 : const unsigned char *readp = (unsigned char *) die->addr;
48 : :
49 : : /* First we have to get the abbreviation code so that we can decode
50 : : the data in the DIE. */
51 : : unsigned int abbrev_code;
52 [ + + ]: 15739859 : get_uleb128 (abbrev_code, readp);
53 : :
54 : : /* Find the abbreviation entry. */
55 : 15739859 : Dwarf_Abbrev *abbrevp = die->abbrev;
56 [ + + ]: 15739859 : if (abbrevp == NULL)
57 : : {
58 : 335701 : abbrevp = __libdw_findabbrev (die->cu, abbrev_code);
59 [ + - ]: 335701 : die->abbrev = abbrevp ?: DWARF_END_ABBREV;
60 : : }
61 [ - + ]: 15739859 : if (unlikely (die->abbrev == DWARF_END_ABBREV))
62 : : {
63 : : invalid_dwarf:
64 : 0 : __libdw_seterrno (DWARF_E_INVALID_DWARF);
65 : : return NULL;
66 : : }
67 : :
68 : : /* Search the name attribute. */
69 : 15739859 : unsigned char *const endp
70 : 15739859 : = ((unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf
71 : 15739859 : + dbg->sectiondata[IDX_debug_abbrev]->d_size);
72 : :
73 : 74942730 : const unsigned char *attrp = die->abbrev->attrp;
74 : : while (1)
75 : : {
76 : : /* Are we still in bounds? This test needs to be refined. */
77 [ - + ]: 74942730 : if (unlikely (attrp + 1 >= endp))
78 : : goto invalid_dwarf;
79 : :
80 : : /* Get attribute name and form.
81 : :
82 : : XXX We don't check whether this reads beyond the end of the
83 : : section. */
84 : : unsigned int attr_name;
85 [ + + ]: 74942730 : get_uleb128 (attr_name, attrp);
86 : : unsigned int attr_form;
87 [ + + ]: 74942730 : get_uleb128 (attr_form, attrp);
88 : :
89 : : /* We can stop if we found the attribute with value zero. */
90 [ + + ]: 74942730 : if (attr_name == 0 && attr_form == 0)
91 : : break;
92 : :
93 : : /* Is this the name attribute? */
94 [ + + ]: 60794793 : if (attr_name == search_name && search_name != INVALID)
95 : : {
96 [ + - ]: 1591922 : if (codep != NULL)
97 : 1591922 : *codep = attr_name;
98 [ + + ]: 1591922 : if (formp != NULL)
99 : 1588907 : *formp = attr_form;
100 : :
101 : 1591922 : return (unsigned char *) readp;
102 : : }
103 : :
104 : : /* Skip over the rest of this attribute (if there is any). */
105 [ - + ]: 59202871 : if (attr_form != 0)
106 : : {
107 : 59202871 : size_t len = __libdw_form_val_len (dbg, die->cu, attr_form, readp);
108 : :
109 [ - + ]: 59202871 : if (unlikely (len == (size_t) -1l))
110 : : {
111 : 0 : readp = NULL;
112 : 0 : break;
113 : : }
114 : :
115 : : // XXX We need better boundary checks.
116 : 59202871 : readp += len;
117 : : }
118 : : }
119 : :
120 : : // XXX Do we need other values?
121 [ + + ]: 14147937 : if (codep != NULL)
122 : 14026786 : *codep = INVALID;
123 [ + + ]: 14147937 : if (formp != NULL)
124 : 2485913 : *formp = INVALID;
125 : :
126 : 15739859 : return (unsigned char *) readp;
127 : : }
128 : :
129 : :
130 : : int
131 : 741984 : dwarf_child (die, result)
132 : : Dwarf_Die *die;
133 : : Dwarf_Die *result;
134 : : {
135 : : /* Ignore previous errors. */
136 [ + - ]: 741984 : if (die == NULL)
137 : : return -1;
138 : :
139 : : /* Skip past the last attribute. */
140 : 741984 : void *addr = NULL;
141 : :
142 : : /* If we already know there are no children do not search. */
143 [ + - ]: 741984 : if (die->abbrev != DWARF_END_ABBREV
144 [ + + ][ + + ]: 741984 : && (die->abbrev == NULL || die->abbrev->has_children))
145 : 121151 : addr = __libdw_find_attr (die, INVALID, NULL, NULL);
146 [ + - ]: 741984 : if (unlikely (die->abbrev == (Dwarf_Abbrev *) -1l))
147 : : return -1;
148 : :
149 : : /* Make sure the DIE really has children. */
150 [ + + ]: 741984 : if (! die->abbrev->has_children)
151 : : /* There cannot be any children. */
152 : : return 1;
153 : :
154 [ + - ]: 121151 : if (addr == NULL)
155 : : return -1;
156 : :
157 : : /* RESULT can be the same as DIE. So preserve what we need. */
158 : 121151 : struct Dwarf_CU *cu = die->cu;
159 : 121151 : Elf_Data *cu_sec = cu_data (cu);
160 : :
161 : : /* It's kosher (just suboptimal) to have a null entry first thing (7.5.3).
162 : : So if this starts with ULEB128 of 0 (even with silly encoding of 0),
163 : : it is a kosher null entry and we do not really have any children. */
164 : 121151 : const unsigned char *code = addr;
165 : 121151 : const unsigned char *endp = (cu_sec->d_buf + cu_sec->d_size);
166 : : while (1)
167 : : {
168 [ + - ]: 121151 : if (unlikely (code >= endp)) /* Truncated section. */
169 : : return 1;
170 [ - + ]: 121151 : if (unlikely (*code == 0x80))
171 : 0 : ++code;
172 : : else
173 : : break;
174 : 0 : }
175 [ + - ]: 121151 : if (unlikely (*code == '\0'))
176 : : return 1;
177 : :
178 : : /* Clear the entire DIE structure. This signals we have not yet
179 : : determined any of the information. */
180 : 121151 : memset (result, '\0', sizeof (Dwarf_Die));
181 : :
182 : : /* We have the address. */
183 : 121151 : result->addr = addr;
184 : :
185 : : /* Same CU as the parent. */
186 : 121151 : result->cu = cu;
187 : :
188 : 741984 : return 0;
189 : : }
190 : 121151 : INTDEF(dwarf_child)
|