Branch data Line data Source code
1 : : /* Return unsigned constant represented by attribute.
2 : : Copyright (C) 2003-2012 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 <dwarf.h>
35 : : #include "libdwP.h"
36 : :
37 : : internal_function unsigned char *
38 : 132011 : __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
39 : : int err_nodata, unsigned char **endpp,
40 : : Dwarf_Off *offsetp)
41 : : {
42 [ + - ]: 132011 : if (attr == NULL)
43 : : return NULL;
44 : :
45 : 132011 : const Elf_Data *d = attr->cu->dbg->sectiondata[sec_index];
46 [ - + ]: 132011 : if (unlikely (d == NULL))
47 : : {
48 : 0 : __libdw_seterrno (err_nodata);
49 : : return NULL;
50 : : }
51 : :
52 : : Dwarf_Word offset;
53 [ + + ]: 132011 : if (attr->form == DW_FORM_sec_offset)
54 : : {
55 [ + - ]: 131869 : if (__libdw_read_offset (attr->cu->dbg, attr->cu->dbg,
56 : 263738 : cu_sec_idx (attr->cu), attr->valp,
57 : 131869 : attr->cu->offset_size, &offset, sec_index, 0))
58 : : return NULL;
59 : : }
60 [ + - ]: 142 : else if (attr->cu->version > 3)
61 : : goto invalid;
62 : : else
63 [ + - ]: 142 : switch (attr->form)
64 : : {
65 : : case DW_FORM_data4:
66 : : case DW_FORM_data8:
67 [ - + ][ + - ]: 142 : if (__libdw_read_offset (attr->cu->dbg, attr->cu->dbg,
68 : 142 : cu_sec_idx (attr->cu),
69 : 142 : attr->valp,
70 : : attr->form == DW_FORM_data4 ? 4 : 8,
71 : : &offset, sec_index, 0))
72 : : return NULL;
73 : : break;
74 : :
75 : : default:
76 [ # # ]: 0 : if (INTUSE(dwarf_formudata) (attr, &offset))
77 : : return NULL;
78 : : };
79 : :
80 : 132011 : unsigned char *readp = d->d_buf + offset;
81 : 132011 : unsigned char *endp = d->d_buf + d->d_size;
82 [ - + ]: 132011 : if (unlikely (readp >= endp))
83 : : {
84 : : invalid:
85 : 0 : __libdw_seterrno (DWARF_E_INVALID_DWARF);
86 : : return NULL;
87 : : }
88 : :
89 [ + + ]: 132011 : if (endpp != NULL)
90 : 14092 : *endpp = endp;
91 [ + + ]: 132011 : if (offsetp != NULL)
92 : 132011 : *offsetp = offset;
93 : : return readp;
94 : : }
95 : :
96 : : int
97 : 1656179 : dwarf_formudata (attr, return_uval)
98 : : Dwarf_Attribute *attr;
99 : : Dwarf_Word *return_uval;
100 : : {
101 [ + + ]: 1656179 : if (attr == NULL)
102 : : return -1;
103 : :
104 : : const unsigned char *datap;
105 : :
106 [ + + + + : 1645488 : switch (attr->form)
+ - ]
107 : : {
108 : : case DW_FORM_data1:
109 : 1187217 : *return_uval = *attr->valp;
110 : 1187217 : break;
111 : :
112 : : case DW_FORM_data2:
113 [ + + ][ - + ]: 217529 : *return_uval = read_2ubyte_unaligned (attr->cu->dbg, attr->valp);
114 : 217529 : break;
115 : :
116 : : case DW_FORM_data4:
117 : : case DW_FORM_data8:
118 : : case DW_FORM_sec_offset:
119 : : /* Before DWARF4 data4 and data8 are pure constants unless the
120 : : attribute also allows offsets (*ptr classes), since DWARF4
121 : : they are always just constants (start_scope is special though,
122 : : since it only could express a rangelist since DWARF4). */
123 [ + + ]: 117966 : if (attr->form == DW_FORM_sec_offset
124 [ + + ][ + - ]: 127 : || (attr->cu->version < 4 && attr->code != DW_AT_start_scope))
125 : : {
126 [ + + + + : 117925 : switch (attr->code)
+ + ]
127 : : {
128 : : case DW_AT_data_member_location:
129 : : case DW_AT_frame_base:
130 : : case DW_AT_location:
131 : : case DW_AT_return_addr:
132 : : case DW_AT_segment:
133 : : case DW_AT_static_link:
134 : : case DW_AT_string_length:
135 : : case DW_AT_use_location:
136 : : case DW_AT_vtable_elem_location:
137 : : /* loclistptr */
138 [ + - ]: 36156 : if (__libdw_formptr (attr, IDX_debug_loc,
139 : : DWARF_E_NO_LOCLIST, NULL,
140 : : return_uval) == NULL)
141 : : return -1;
142 : : break;
143 : :
144 : : case DW_AT_macro_info:
145 : : /* macptr into .debug_macinfo */
146 [ + - ]: 3 : if (__libdw_formptr (attr, IDX_debug_macinfo,
147 : : DWARF_E_NO_ENTRY, NULL,
148 : : return_uval) == NULL)
149 : : return -1;
150 : : break;
151 : :
152 : : case DW_AT_GNU_macros:
153 : : /* macptr into .debug_macro */
154 [ + - ]: 1 : if (__libdw_formptr (attr, IDX_debug_macro,
155 : : DWARF_E_NO_ENTRY, NULL,
156 : : return_uval) == NULL)
157 : : return -1;
158 : : break;
159 : :
160 : : case DW_AT_ranges:
161 : : case DW_AT_start_scope:
162 : : /* rangelistptr */
163 [ + - ]: 9137 : if (__libdw_formptr (attr, IDX_debug_ranges,
164 : : DWARF_E_NO_DEBUG_RANGES, NULL,
165 : : return_uval) == NULL)
166 : : return -1;
167 : : break;
168 : :
169 : : case DW_AT_stmt_list:
170 : : /* lineptr */
171 [ + - ]: 72622 : if (__libdw_formptr (attr, IDX_debug_line,
172 : : DWARF_E_NO_DEBUG_LINE, NULL,
173 : : return_uval) == NULL)
174 : : return -1;
175 : : break;
176 : :
177 : : default:
178 : : /* sec_offset can only be used by one of the above attrs. */
179 [ - + ]: 6 : if (attr->form == DW_FORM_sec_offset)
180 : : {
181 : 0 : __libdw_seterrno (DWARF_E_INVALID_DWARF);
182 : : return -1;
183 : : }
184 : :
185 : : /* Not one of the special attributes, just a constant. */
186 [ - + ][ + - ]: 6 : if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
187 : 6 : attr->valp,
188 : : attr->form == DW_FORM_data4 ? 4 : 8,
189 : : return_uval))
190 : : return -1;
191 : : break;
192 : : }
193 : : }
194 : : else
195 : : {
196 : : /* We are dealing with a constant data4 or data8. */
197 [ + + ][ + - ]: 41 : if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
198 : 41 : attr->valp,
199 : : attr->form == DW_FORM_data4 ? 4 : 8,
200 : : return_uval))
201 : : return -1;
202 : : }
203 : : break;
204 : :
205 : : case DW_FORM_sdata:
206 : 122772 : datap = attr->valp;
207 [ + + ]: 122772 : get_sleb128 (*return_uval, datap);
208 : : break;
209 : :
210 : : case DW_FORM_udata:
211 : 4 : datap = attr->valp;
212 [ - + ]: 4 : get_uleb128 (*return_uval, datap);
213 : : break;
214 : :
215 : : default:
216 : 1656179 : __libdw_seterrno (DWARF_E_NO_CONSTANT);
217 : : return -1;
218 : : }
219 : :
220 : : return 0;
221 : : }
222 : 132058 : INTDEF(dwarf_formudata)
|