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.
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 (attr, return_uval)
98 Dwarf_Attribute *attr;
99 Dwarf_Word *return_uval;
104 const unsigned char *datap;
109 *return_uval = *attr->valp;
113 *return_uval = read_2ubyte_unaligned (attr->cu->dbg, attr->valp);
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 if (attr->form == DW_FORM_sec_offset
124 || (attr->cu->version < 4 && attr->code != DW_AT_start_scope))
128 case DW_AT_data_member_location:
129 case DW_AT_frame_base:
131 case DW_AT_return_addr:
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:
138 if (__libdw_formptr (attr, IDX_debug_loc,
139 DWARF_E_NO_LOCLIST, NULL,
140 return_uval) == NULL)
144 case DW_AT_macro_info:
145 /* macptr into .debug_macinfo */
146 if (__libdw_formptr (attr, IDX_debug_macinfo,
147 DWARF_E_NO_ENTRY, NULL,
148 return_uval) == NULL)
152 case DW_AT_GNU_macros:
153 /* macptr into .debug_macro */
154 if (__libdw_formptr (attr, IDX_debug_macro,
155 DWARF_E_NO_ENTRY, NULL,
156 return_uval) == NULL)
161 case DW_AT_start_scope:
163 if (__libdw_formptr (attr, IDX_debug_ranges,
164 DWARF_E_NO_DEBUG_RANGES, NULL,
165 return_uval) == NULL)
169 case DW_AT_stmt_list:
171 if (__libdw_formptr (attr, IDX_debug_line,
172 DWARF_E_NO_DEBUG_LINE, NULL,
173 return_uval) == NULL)
178 /* sec_offset can only be used by one of the above attrs. */
179 if (attr->form == DW_FORM_sec_offset)
181 __libdw_seterrno (DWARF_E_INVALID_DWARF);
185 /* Not one of the special attributes, just a constant. */
186 if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
188 attr->form == DW_FORM_data4 ? 4 : 8,
196 /* We are dealing with a constant data4 or data8. */
197 if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
199 attr->form == DW_FORM_data4 ? 4 : 8,
207 get_sleb128 (*return_uval, datap);
212 get_uleb128 (*return_uval, datap);
216 __libdw_seterrno (DWARF_E_NO_CONSTANT);
222 INTDEF(dwarf_formudata)