1 /* Return unsigned constant represented by attribute.
2 Copyright (C) 2003-2012, 2014 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2003.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
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
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
19 or both in parallel, as here.
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.
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/>. */
37 internal_function unsigned char *
38 __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
39 int err_nodata, unsigned char **endpp,
45 const Elf_Data *d = attr->cu->dbg->sectiondata[sec_index];
46 if (unlikely (d == NULL))
48 __libdw_seterrno (err_nodata);
53 if (attr->form == DW_FORM_sec_offset)
55 if (__libdw_read_offset (attr->cu->dbg, attr->cu->dbg,
56 cu_sec_idx (attr->cu), attr->valp,
57 attr->cu->offset_size, &offset, sec_index, 0))
60 else if (attr->cu->version > 3)
67 if (__libdw_read_offset (attr->cu->dbg, attr->cu->dbg,
68 cu_sec_idx (attr->cu),
70 attr->form == DW_FORM_data4 ? 4 : 8,
71 &offset, sec_index, 0))
76 if (INTUSE(dwarf_formudata) (attr, &offset))
80 unsigned char *readp = d->d_buf + offset;
81 unsigned char *endp = d->d_buf + d->d_size;
82 if (unlikely (readp >= endp))
85 __libdw_seterrno (DWARF_E_INVALID_DWARF);
97 dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval)
102 const unsigned char *datap = attr->valp;
103 const unsigned char *endp = attr->cu->endp;
108 if (datap + 1 > endp)
111 __libdw_seterrno (DWARF_E_INVALID_DWARF);
114 *return_uval = *attr->valp;
118 if (datap + 2 > endp)
120 *return_uval = read_2ubyte_unaligned (attr->cu->dbg, attr->valp);
125 case DW_FORM_sec_offset:
126 /* Before DWARF4 data4 and data8 are pure constants unless the
127 attribute also allows offsets (*ptr classes), since DWARF4
128 they are always just constants (start_scope is special though,
129 since it only could express a rangelist since DWARF4). */
130 if (attr->form == DW_FORM_sec_offset
131 || (attr->cu->version < 4 && attr->code != DW_AT_start_scope))
135 case DW_AT_data_member_location:
136 case DW_AT_frame_base:
138 case DW_AT_return_addr:
140 case DW_AT_static_link:
141 case DW_AT_string_length:
142 case DW_AT_use_location:
143 case DW_AT_vtable_elem_location:
145 if (__libdw_formptr (attr, IDX_debug_loc,
146 DWARF_E_NO_LOCLIST, NULL,
147 return_uval) == NULL)
151 case DW_AT_macro_info:
152 /* macptr into .debug_macinfo */
153 if (__libdw_formptr (attr, IDX_debug_macinfo,
154 DWARF_E_NO_ENTRY, NULL,
155 return_uval) == NULL)
159 case DW_AT_GNU_macros:
160 /* macptr into .debug_macro */
161 if (__libdw_formptr (attr, IDX_debug_macro,
162 DWARF_E_NO_ENTRY, NULL,
163 return_uval) == NULL)
168 case DW_AT_start_scope:
170 if (__libdw_formptr (attr, IDX_debug_ranges,
171 DWARF_E_NO_DEBUG_RANGES, NULL,
172 return_uval) == NULL)
176 case DW_AT_stmt_list:
178 if (__libdw_formptr (attr, IDX_debug_line,
179 DWARF_E_NO_DEBUG_LINE, NULL,
180 return_uval) == NULL)
185 /* sec_offset can only be used by one of the above attrs. */
186 if (attr->form == DW_FORM_sec_offset)
188 __libdw_seterrno (DWARF_E_INVALID_DWARF);
192 /* Not one of the special attributes, just a constant. */
193 if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
195 attr->form == DW_FORM_data4 ? 4 : 8,
203 /* We are dealing with a constant data4 or data8. */
204 if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
206 attr->form == DW_FORM_data4 ? 4 : 8,
213 if (datap + 1 > endp)
215 get_sleb128 (*return_uval, datap, endp);
219 if (datap + 1 > endp)
221 get_uleb128 (*return_uval, datap, endp);
225 __libdw_seterrno (DWARF_E_NO_CONSTANT);
231 INTDEF(dwarf_formudata)