1da0c48c4Sopenharmony_ci/* Return unsigned constant represented by attribute.
2da0c48c4Sopenharmony_ci   Copyright (C) 2003-2012, 2014, 2017 Red Hat, Inc.
3da0c48c4Sopenharmony_ci   This file is part of elfutils.
4da0c48c4Sopenharmony_ci   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
5da0c48c4Sopenharmony_ci
6da0c48c4Sopenharmony_ci   This file is free software; you can redistribute it and/or modify
7da0c48c4Sopenharmony_ci   it under the terms of either
8da0c48c4Sopenharmony_ci
9da0c48c4Sopenharmony_ci     * the GNU Lesser General Public License as published by the Free
10da0c48c4Sopenharmony_ci       Software Foundation; either version 3 of the License, or (at
11da0c48c4Sopenharmony_ci       your option) any later version
12da0c48c4Sopenharmony_ci
13da0c48c4Sopenharmony_ci   or
14da0c48c4Sopenharmony_ci
15da0c48c4Sopenharmony_ci     * the GNU General Public License as published by the Free
16da0c48c4Sopenharmony_ci       Software Foundation; either version 2 of the License, or (at
17da0c48c4Sopenharmony_ci       your option) any later version
18da0c48c4Sopenharmony_ci
19da0c48c4Sopenharmony_ci   or both in parallel, as here.
20da0c48c4Sopenharmony_ci
21da0c48c4Sopenharmony_ci   elfutils is distributed in the hope that it will be useful, but
22da0c48c4Sopenharmony_ci   WITHOUT ANY WARRANTY; without even the implied warranty of
23da0c48c4Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24da0c48c4Sopenharmony_ci   General Public License for more details.
25da0c48c4Sopenharmony_ci
26da0c48c4Sopenharmony_ci   You should have received copies of the GNU General Public License and
27da0c48c4Sopenharmony_ci   the GNU Lesser General Public License along with this program.  If
28da0c48c4Sopenharmony_ci   not, see <http://www.gnu.org/licenses/>.  */
29da0c48c4Sopenharmony_ci
30da0c48c4Sopenharmony_ci#ifdef HAVE_CONFIG_H
31da0c48c4Sopenharmony_ci# include <config.h>
32da0c48c4Sopenharmony_ci#endif
33da0c48c4Sopenharmony_ci
34da0c48c4Sopenharmony_ci#include <dwarf.h>
35da0c48c4Sopenharmony_ci#include "libdwP.h"
36da0c48c4Sopenharmony_ci
37da0c48c4Sopenharmony_ciinternal_function const unsigned char *
38da0c48c4Sopenharmony_ci__libdw_formptr (Dwarf_Attribute *attr, int sec_index,
39da0c48c4Sopenharmony_ci		 int err_nodata, const unsigned char **endpp,
40da0c48c4Sopenharmony_ci		 Dwarf_Off *offsetp)
41da0c48c4Sopenharmony_ci{
42da0c48c4Sopenharmony_ci  if (attr == NULL)
43da0c48c4Sopenharmony_ci    return NULL;
44da0c48c4Sopenharmony_ci
45da0c48c4Sopenharmony_ci  const Elf_Data *d = attr->cu->dbg->sectiondata[sec_index];
46da0c48c4Sopenharmony_ci  Dwarf_CU *skel = NULL; /* See below, needed for GNU DebugFission.  */
47da0c48c4Sopenharmony_ci  if (unlikely (d == NULL
48da0c48c4Sopenharmony_ci		&& sec_index == IDX_debug_ranges
49da0c48c4Sopenharmony_ci		&& attr->cu->version < 5
50da0c48c4Sopenharmony_ci		&& attr->cu->unit_type == DW_UT_split_compile))
51da0c48c4Sopenharmony_ci    {
52da0c48c4Sopenharmony_ci      skel = __libdw_find_split_unit (attr->cu);
53da0c48c4Sopenharmony_ci      if (skel != NULL)
54da0c48c4Sopenharmony_ci	d = skel->dbg->sectiondata[IDX_debug_ranges];
55da0c48c4Sopenharmony_ci    }
56da0c48c4Sopenharmony_ci
57da0c48c4Sopenharmony_ci  if (unlikely (d == NULL))
58da0c48c4Sopenharmony_ci    {
59da0c48c4Sopenharmony_ci      __libdw_seterrno (err_nodata);
60da0c48c4Sopenharmony_ci      return NULL;
61da0c48c4Sopenharmony_ci    }
62da0c48c4Sopenharmony_ci
63da0c48c4Sopenharmony_ci  Dwarf_Word offset;
64da0c48c4Sopenharmony_ci  if (attr->form == DW_FORM_sec_offset)
65da0c48c4Sopenharmony_ci    {
66da0c48c4Sopenharmony_ci      /* GNU DebugFission is slightly odd.  It uses DW_FORM_sec_offset
67da0c48c4Sopenharmony_ci	 in split units, but they are really (unrelocated) offsets
68da0c48c4Sopenharmony_ci	 from the skeleton DW_AT_GNU_ranges_base (which is only used
69da0c48c4Sopenharmony_ci	 for the split unit, not the skeleton ranges itself, see also
70da0c48c4Sopenharmony_ci	 DW_AT_rnglists_base, which is used in DWARF5 for both, but
71da0c48c4Sopenharmony_ci	 points to the offsets index).  So it isn't really a formptr,
72da0c48c4Sopenharmony_ci	 but an offset + base calculation.  */
73da0c48c4Sopenharmony_ci      if (unlikely (skel != NULL))
74da0c48c4Sopenharmony_ci	{
75da0c48c4Sopenharmony_ci	  Elf_Data *data = attr->cu->dbg->sectiondata[cu_sec_idx (attr->cu)];
76da0c48c4Sopenharmony_ci	  const unsigned char *datap = attr->valp;
77da0c48c4Sopenharmony_ci	  size_t size = attr->cu->offset_size;
78da0c48c4Sopenharmony_ci	  if (unlikely (data == NULL
79da0c48c4Sopenharmony_ci			|| datap < (const unsigned char *) data->d_buf
80da0c48c4Sopenharmony_ci			|| data->d_size < size
81da0c48c4Sopenharmony_ci			|| ((size_t) (datap
82da0c48c4Sopenharmony_ci				      - (const unsigned char *) data->d_buf)
83da0c48c4Sopenharmony_ci			    > data->d_size - size)))
84da0c48c4Sopenharmony_ci	    goto invalid;
85da0c48c4Sopenharmony_ci
86da0c48c4Sopenharmony_ci	  if (size == 4)
87da0c48c4Sopenharmony_ci	    offset = read_4ubyte_unaligned (attr->cu->dbg, datap);
88da0c48c4Sopenharmony_ci	  else
89da0c48c4Sopenharmony_ci	    offset = read_8ubyte_unaligned (attr->cu->dbg, datap);
90da0c48c4Sopenharmony_ci
91da0c48c4Sopenharmony_ci	  offset += __libdw_cu_ranges_base (skel);
92da0c48c4Sopenharmony_ci	}
93da0c48c4Sopenharmony_ci      else
94da0c48c4Sopenharmony_ci	{
95da0c48c4Sopenharmony_ci	  if (__libdw_read_offset (attr->cu->dbg, attr->cu->dbg,
96da0c48c4Sopenharmony_ci				   cu_sec_idx (attr->cu), attr->valp,
97da0c48c4Sopenharmony_ci				   attr->cu->offset_size, &offset,
98da0c48c4Sopenharmony_ci				   sec_index, 0))
99da0c48c4Sopenharmony_ci	    return NULL;
100da0c48c4Sopenharmony_ci	}
101da0c48c4Sopenharmony_ci    }
102da0c48c4Sopenharmony_ci  else if (attr->cu->version > 3)
103da0c48c4Sopenharmony_ci    goto invalid;
104da0c48c4Sopenharmony_ci  else
105da0c48c4Sopenharmony_ci    switch (attr->form)
106da0c48c4Sopenharmony_ci      {
107da0c48c4Sopenharmony_ci      case DW_FORM_data4:
108da0c48c4Sopenharmony_ci      case DW_FORM_data8:
109da0c48c4Sopenharmony_ci	if (__libdw_read_offset (attr->cu->dbg, attr->cu->dbg,
110da0c48c4Sopenharmony_ci				 cu_sec_idx (attr->cu),
111da0c48c4Sopenharmony_ci				 attr->valp,
112da0c48c4Sopenharmony_ci				 attr->form == DW_FORM_data4 ? 4 : 8,
113da0c48c4Sopenharmony_ci				 &offset, sec_index, 0))
114da0c48c4Sopenharmony_ci	  return NULL;
115da0c48c4Sopenharmony_ci	break;
116da0c48c4Sopenharmony_ci
117da0c48c4Sopenharmony_ci      default:
118da0c48c4Sopenharmony_ci	if (INTUSE(dwarf_formudata) (attr, &offset))
119da0c48c4Sopenharmony_ci	  return NULL;
120da0c48c4Sopenharmony_ci      };
121da0c48c4Sopenharmony_ci
122da0c48c4Sopenharmony_ci  unsigned char *readp = d->d_buf + offset;
123da0c48c4Sopenharmony_ci  unsigned char *endp = d->d_buf + d->d_size;
124da0c48c4Sopenharmony_ci  if (unlikely (readp >= endp))
125da0c48c4Sopenharmony_ci    {
126da0c48c4Sopenharmony_ci    invalid:
127da0c48c4Sopenharmony_ci      __libdw_seterrno (DWARF_E_INVALID_DWARF);
128da0c48c4Sopenharmony_ci      return NULL;
129da0c48c4Sopenharmony_ci    }
130da0c48c4Sopenharmony_ci
131da0c48c4Sopenharmony_ci  if (endpp != NULL)
132da0c48c4Sopenharmony_ci    *endpp = endp;
133da0c48c4Sopenharmony_ci  if (offsetp != NULL)
134da0c48c4Sopenharmony_ci    *offsetp = offset;
135da0c48c4Sopenharmony_ci  return readp;
136da0c48c4Sopenharmony_ci}
137da0c48c4Sopenharmony_ci
138da0c48c4Sopenharmony_ciint
139da0c48c4Sopenharmony_cidwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval)
140da0c48c4Sopenharmony_ci{
141da0c48c4Sopenharmony_ci  if (attr == NULL)
142da0c48c4Sopenharmony_ci    return -1;
143da0c48c4Sopenharmony_ci
144da0c48c4Sopenharmony_ci  const unsigned char *datap = attr->valp;
145da0c48c4Sopenharmony_ci  const unsigned char *endp = attr->cu->endp;
146da0c48c4Sopenharmony_ci
147da0c48c4Sopenharmony_ci  switch (attr->form)
148da0c48c4Sopenharmony_ci    {
149da0c48c4Sopenharmony_ci    case DW_FORM_data1:
150da0c48c4Sopenharmony_ci      if (datap + 1 > endp)
151da0c48c4Sopenharmony_ci	{
152da0c48c4Sopenharmony_ci	invalid:
153da0c48c4Sopenharmony_ci	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
154da0c48c4Sopenharmony_ci	  return -1;
155da0c48c4Sopenharmony_ci	}
156da0c48c4Sopenharmony_ci      *return_uval = *attr->valp;
157da0c48c4Sopenharmony_ci      break;
158da0c48c4Sopenharmony_ci
159da0c48c4Sopenharmony_ci    case DW_FORM_data2:
160da0c48c4Sopenharmony_ci      if (datap + 2 > endp)
161da0c48c4Sopenharmony_ci	goto invalid;
162da0c48c4Sopenharmony_ci      *return_uval = read_2ubyte_unaligned (attr->cu->dbg, attr->valp);
163da0c48c4Sopenharmony_ci      break;
164da0c48c4Sopenharmony_ci
165da0c48c4Sopenharmony_ci    case DW_FORM_data4:
166da0c48c4Sopenharmony_ci    case DW_FORM_data8:
167da0c48c4Sopenharmony_ci    case DW_FORM_sec_offset:
168da0c48c4Sopenharmony_ci      /* Before DWARF4 data4 and data8 are pure constants unless the
169da0c48c4Sopenharmony_ci	 attribute also allows offsets (*ptr classes), since DWARF4
170da0c48c4Sopenharmony_ci	 they are always just constants (start_scope is special though,
171da0c48c4Sopenharmony_ci	 since it only could express a rangelist since DWARF4).  */
172da0c48c4Sopenharmony_ci      if (attr->form == DW_FORM_sec_offset
173da0c48c4Sopenharmony_ci	  || (attr->cu->version < 4 && attr->code != DW_AT_start_scope))
174da0c48c4Sopenharmony_ci	{
175da0c48c4Sopenharmony_ci	  switch (attr->code)
176da0c48c4Sopenharmony_ci	    {
177da0c48c4Sopenharmony_ci	    case DW_AT_data_member_location:
178da0c48c4Sopenharmony_ci	    case DW_AT_frame_base:
179da0c48c4Sopenharmony_ci	    case DW_AT_location:
180da0c48c4Sopenharmony_ci	    case DW_AT_return_addr:
181da0c48c4Sopenharmony_ci	    case DW_AT_segment:
182da0c48c4Sopenharmony_ci	    case DW_AT_static_link:
183da0c48c4Sopenharmony_ci	    case DW_AT_string_length:
184da0c48c4Sopenharmony_ci	    case DW_AT_use_location:
185da0c48c4Sopenharmony_ci	    case DW_AT_vtable_elem_location:
186da0c48c4Sopenharmony_ci	    case DW_AT_GNU_locviews:
187da0c48c4Sopenharmony_ci	    case DW_AT_loclists_base:
188da0c48c4Sopenharmony_ci	      if (attr->cu->version < 5)
189da0c48c4Sopenharmony_ci		{
190da0c48c4Sopenharmony_ci		  /* loclistptr */
191da0c48c4Sopenharmony_ci		  if (__libdw_formptr (attr, IDX_debug_loc,
192da0c48c4Sopenharmony_ci				       DWARF_E_NO_DEBUG_LOC, NULL,
193da0c48c4Sopenharmony_ci				       return_uval) == NULL)
194da0c48c4Sopenharmony_ci		    return -1;
195da0c48c4Sopenharmony_ci		}
196da0c48c4Sopenharmony_ci	      else
197da0c48c4Sopenharmony_ci		{
198da0c48c4Sopenharmony_ci		  /* loclist, loclistsptr */
199da0c48c4Sopenharmony_ci		  if (__libdw_formptr (attr, IDX_debug_loclists,
200da0c48c4Sopenharmony_ci				       DWARF_E_NO_DEBUG_LOCLISTS, NULL,
201da0c48c4Sopenharmony_ci				       return_uval) == NULL)
202da0c48c4Sopenharmony_ci		    return -1;
203da0c48c4Sopenharmony_ci		}
204da0c48c4Sopenharmony_ci	      break;
205da0c48c4Sopenharmony_ci
206da0c48c4Sopenharmony_ci	    case DW_AT_macro_info:
207da0c48c4Sopenharmony_ci	      /* macptr into .debug_macinfo */
208da0c48c4Sopenharmony_ci	      if (__libdw_formptr (attr, IDX_debug_macinfo,
209da0c48c4Sopenharmony_ci				   DWARF_E_NO_ENTRY, NULL,
210da0c48c4Sopenharmony_ci				   return_uval) == NULL)
211da0c48c4Sopenharmony_ci		return -1;
212da0c48c4Sopenharmony_ci	      break;
213da0c48c4Sopenharmony_ci
214da0c48c4Sopenharmony_ci	    case DW_AT_GNU_macros:
215da0c48c4Sopenharmony_ci	    case DW_AT_macros:
216da0c48c4Sopenharmony_ci	      /* macptr into .debug_macro */
217da0c48c4Sopenharmony_ci	      if (__libdw_formptr (attr, IDX_debug_macro,
218da0c48c4Sopenharmony_ci				   DWARF_E_NO_ENTRY, NULL,
219da0c48c4Sopenharmony_ci				   return_uval) == NULL)
220da0c48c4Sopenharmony_ci		return -1;
221da0c48c4Sopenharmony_ci	      break;
222da0c48c4Sopenharmony_ci
223da0c48c4Sopenharmony_ci	    case DW_AT_ranges:
224da0c48c4Sopenharmony_ci	    case DW_AT_start_scope:
225da0c48c4Sopenharmony_ci	    case DW_AT_GNU_ranges_base:
226da0c48c4Sopenharmony_ci	    case DW_AT_rnglists_base:
227da0c48c4Sopenharmony_ci	      if (attr->cu->version < 5)
228da0c48c4Sopenharmony_ci		{
229da0c48c4Sopenharmony_ci		  /* rangelistptr */
230da0c48c4Sopenharmony_ci		  if (__libdw_formptr (attr, IDX_debug_ranges,
231da0c48c4Sopenharmony_ci				       DWARF_E_NO_DEBUG_RANGES, NULL,
232da0c48c4Sopenharmony_ci				       return_uval) == NULL)
233da0c48c4Sopenharmony_ci		    return -1;
234da0c48c4Sopenharmony_ci		}
235da0c48c4Sopenharmony_ci	      else
236da0c48c4Sopenharmony_ci		{
237da0c48c4Sopenharmony_ci		  /* rnglistsptr */
238da0c48c4Sopenharmony_ci		  if (__libdw_formptr (attr, IDX_debug_rnglists,
239da0c48c4Sopenharmony_ci				       DWARF_E_NO_DEBUG_RNGLISTS, NULL,
240da0c48c4Sopenharmony_ci				       return_uval) == NULL)
241da0c48c4Sopenharmony_ci		    return -1;
242da0c48c4Sopenharmony_ci		}
243da0c48c4Sopenharmony_ci	      break;
244da0c48c4Sopenharmony_ci
245da0c48c4Sopenharmony_ci	    case DW_AT_stmt_list:
246da0c48c4Sopenharmony_ci	      /* lineptr */
247da0c48c4Sopenharmony_ci	      if (__libdw_formptr (attr, IDX_debug_line,
248da0c48c4Sopenharmony_ci				   DWARF_E_NO_DEBUG_LINE, NULL,
249da0c48c4Sopenharmony_ci				   return_uval) == NULL)
250da0c48c4Sopenharmony_ci		return -1;
251da0c48c4Sopenharmony_ci	      break;
252da0c48c4Sopenharmony_ci
253da0c48c4Sopenharmony_ci	    case DW_AT_addr_base:
254da0c48c4Sopenharmony_ci	    case DW_AT_GNU_addr_base:
255da0c48c4Sopenharmony_ci	      /* addrptr */
256da0c48c4Sopenharmony_ci	      if (__libdw_formptr (attr, IDX_debug_addr,
257da0c48c4Sopenharmony_ci				   DWARF_E_NO_DEBUG_ADDR, NULL,
258da0c48c4Sopenharmony_ci				   return_uval) == NULL)
259da0c48c4Sopenharmony_ci		return -1;
260da0c48c4Sopenharmony_ci	      break;
261da0c48c4Sopenharmony_ci
262da0c48c4Sopenharmony_ci	    case DW_AT_str_offsets_base:
263da0c48c4Sopenharmony_ci	      /* stroffsetsptr */
264da0c48c4Sopenharmony_ci	      if (__libdw_formptr (attr, IDX_debug_str_offsets,
265da0c48c4Sopenharmony_ci				   DWARF_E_NO_STR_OFFSETS, NULL,
266da0c48c4Sopenharmony_ci				   return_uval) == NULL)
267da0c48c4Sopenharmony_ci		return -1;
268da0c48c4Sopenharmony_ci	      break;
269da0c48c4Sopenharmony_ci
270da0c48c4Sopenharmony_ci	    default:
271da0c48c4Sopenharmony_ci	      /* sec_offset can only be used by one of the above attrs.  */
272da0c48c4Sopenharmony_ci	      if (attr->form == DW_FORM_sec_offset)
273da0c48c4Sopenharmony_ci		{
274da0c48c4Sopenharmony_ci		  __libdw_seterrno (DWARF_E_INVALID_DWARF);
275da0c48c4Sopenharmony_ci		  return -1;
276da0c48c4Sopenharmony_ci		}
277da0c48c4Sopenharmony_ci
278da0c48c4Sopenharmony_ci	      /* Not one of the special attributes, just a constant.  */
279da0c48c4Sopenharmony_ci	      if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
280da0c48c4Sopenharmony_ci					attr->valp,
281da0c48c4Sopenharmony_ci					attr->form == DW_FORM_data4 ? 4 : 8,
282da0c48c4Sopenharmony_ci					return_uval))
283da0c48c4Sopenharmony_ci		return -1;
284da0c48c4Sopenharmony_ci	      break;
285da0c48c4Sopenharmony_ci	    }
286da0c48c4Sopenharmony_ci	}
287da0c48c4Sopenharmony_ci      else
288da0c48c4Sopenharmony_ci	{
289da0c48c4Sopenharmony_ci	  /* We are dealing with a constant data4 or data8.  */
290da0c48c4Sopenharmony_ci	  if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
291da0c48c4Sopenharmony_ci				    attr->valp,
292da0c48c4Sopenharmony_ci				    attr->form == DW_FORM_data4 ? 4 : 8,
293da0c48c4Sopenharmony_ci				    return_uval))
294da0c48c4Sopenharmony_ci	    return -1;
295da0c48c4Sopenharmony_ci	}
296da0c48c4Sopenharmony_ci      break;
297da0c48c4Sopenharmony_ci
298da0c48c4Sopenharmony_ci    case DW_FORM_sdata:
299da0c48c4Sopenharmony_ci      if (datap + 1 > endp)
300da0c48c4Sopenharmony_ci	goto invalid;
301da0c48c4Sopenharmony_ci      get_sleb128 (*return_uval, datap, endp);
302da0c48c4Sopenharmony_ci      break;
303da0c48c4Sopenharmony_ci
304da0c48c4Sopenharmony_ci    case DW_FORM_udata:
305da0c48c4Sopenharmony_ci    case DW_FORM_rnglistx:
306da0c48c4Sopenharmony_ci    case DW_FORM_loclistx:
307da0c48c4Sopenharmony_ci      if (datap + 1 > endp)
308da0c48c4Sopenharmony_ci	goto invalid;
309da0c48c4Sopenharmony_ci      get_uleb128 (*return_uval, datap, endp);
310da0c48c4Sopenharmony_ci      break;
311da0c48c4Sopenharmony_ci
312da0c48c4Sopenharmony_ci    case DW_FORM_implicit_const:
313da0c48c4Sopenharmony_ci      // The data comes from the abbrev, which has been bounds checked.
314da0c48c4Sopenharmony_ci      get_sleb128_unchecked (*return_uval, datap);
315da0c48c4Sopenharmony_ci      break;
316da0c48c4Sopenharmony_ci
317da0c48c4Sopenharmony_ci    /* These are indexes into the .debug_addr section, normally resolved
318da0c48c4Sopenharmony_ci       with dwarf_formaddr.  Here treat as constants.  */
319da0c48c4Sopenharmony_ci    case DW_FORM_GNU_addr_index:
320da0c48c4Sopenharmony_ci    case DW_FORM_addrx:
321da0c48c4Sopenharmony_ci      if (datap >= endp)
322da0c48c4Sopenharmony_ci	goto invalid;
323da0c48c4Sopenharmony_ci      get_uleb128 (*return_uval, datap, endp);
324da0c48c4Sopenharmony_ci      break;
325da0c48c4Sopenharmony_ci
326da0c48c4Sopenharmony_ci    case DW_FORM_addrx1:
327da0c48c4Sopenharmony_ci      if (datap >= endp - 1)
328da0c48c4Sopenharmony_ci	goto invalid;
329da0c48c4Sopenharmony_ci      *return_uval = *datap;
330da0c48c4Sopenharmony_ci      break;
331da0c48c4Sopenharmony_ci
332da0c48c4Sopenharmony_ci    case DW_FORM_addrx2:
333da0c48c4Sopenharmony_ci      if (datap >= endp - 2)
334da0c48c4Sopenharmony_ci	goto invalid;
335da0c48c4Sopenharmony_ci      *return_uval = read_2ubyte_unaligned (attr->cu->dbg, datap);
336da0c48c4Sopenharmony_ci      break;
337da0c48c4Sopenharmony_ci
338da0c48c4Sopenharmony_ci    case DW_FORM_addrx3:
339da0c48c4Sopenharmony_ci      if (datap >= endp - 3)
340da0c48c4Sopenharmony_ci	goto invalid;
341da0c48c4Sopenharmony_ci      *return_uval = read_3ubyte_unaligned (attr->cu->dbg, datap);
342da0c48c4Sopenharmony_ci      break;
343da0c48c4Sopenharmony_ci
344da0c48c4Sopenharmony_ci    case DW_FORM_addrx4:
345da0c48c4Sopenharmony_ci      if (datap >= endp - 4)
346da0c48c4Sopenharmony_ci	goto invalid;
347da0c48c4Sopenharmony_ci      *return_uval = read_4ubyte_unaligned (attr->cu->dbg, datap);
348da0c48c4Sopenharmony_ci      break;
349da0c48c4Sopenharmony_ci
350da0c48c4Sopenharmony_ci    default:
351da0c48c4Sopenharmony_ci      __libdw_seterrno (DWARF_E_NO_CONSTANT);
352da0c48c4Sopenharmony_ci      return -1;
353da0c48c4Sopenharmony_ci    }
354da0c48c4Sopenharmony_ci
355da0c48c4Sopenharmony_ci  return 0;
356da0c48c4Sopenharmony_ci}
357da0c48c4Sopenharmony_ciINTDEF(dwarf_formudata)
358