1 /* Return address represented by attribute.
2 Copyright (C) 2003-2010, 2018 Red Hat, Inc.
3 This file is part of elfutils.
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
8 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
18 or both in parallel, as here.
20 elfutils is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
38 __libdw_addrx (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr)
40 Dwarf_Off addr_off = __libdw_cu_addr_base (cu);
41 if (addr_off == (Dwarf_Off) -1)
45 if (dbg->sectiondata[IDX_debug_addr] == NULL)
47 __libdw_seterrno (DWARF_E_NO_DEBUG_ADDR);
51 /* The section should at least contain room for one address. */
52 int address_size = cu->address_size;
53 if (cu->address_size > dbg->sectiondata[IDX_debug_addr]->d_size)
56 __libdw_seterrno (DWARF_E_INVALID_OFFSET);
60 if (addr_off > (dbg->sectiondata[IDX_debug_addr]->d_size
65 if (idx > (dbg->sectiondata[IDX_debug_addr]->d_size
66 - address_size - addr_off))
69 const unsigned char *datap;
70 datap = dbg->sectiondata[IDX_debug_addr]->d_buf + addr_off + idx;
71 if (address_size == 4)
72 *addr = read_4ubyte_unaligned (dbg, datap);
74 *addr = read_8ubyte_unaligned (dbg, datap);
80 dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr)
86 Dwarf_CU *cu = attr->cu;
88 const unsigned char *datap = attr->valp;
89 const unsigned char *endp = attr->cu->endp;
92 /* There is one form that just encodes the whole address. */
94 if (__libdw_read_address (dbg, cu_sec_idx (cu), datap,
95 cu->address_size, return_addr))
99 /* All others encode an index into the .debug_addr section where
100 the address can be found. */
101 case DW_FORM_GNU_addr_index:
106 __libdw_seterrno (DWARF_E_INVALID_DWARF);
109 get_uleb128 (idx, datap, endp);
113 if (datap >= endp - 1)
119 if (datap >= endp - 2)
121 idx = read_2ubyte_unaligned (dbg, datap);
125 if (datap >= endp - 3)
127 idx = read_3ubyte_unaligned (dbg, datap);
131 if (datap >= endp - 4)
133 idx = read_4ubyte_unaligned (dbg, datap);
137 __libdw_seterrno (DWARF_E_NO_ADDR);
141 /* So we got an index. Lets see if it is valid and we can get the actual
143 if (__libdw_addrx (cu, idx, return_addr) != 0)
148 INTDEF(dwarf_formaddr)