xref: /minix3/external/bsd/elftoolchain/dist/libdwarf/dwarf_loclist.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: dwarf_loclist.c,v 1.2 2014/03/09 16:58:04 christos Exp $	*/
2*0a6a1f1dSLionel Sambuc 
3*0a6a1f1dSLionel Sambuc /*-
4*0a6a1f1dSLionel Sambuc  * Copyright (c) 2009 Kai Wang
5*0a6a1f1dSLionel Sambuc  * All rights reserved.
6*0a6a1f1dSLionel Sambuc  *
7*0a6a1f1dSLionel Sambuc  * Redistribution and use in source and binary forms, with or without
8*0a6a1f1dSLionel Sambuc  * modification, are permitted provided that the following conditions
9*0a6a1f1dSLionel Sambuc  * are met:
10*0a6a1f1dSLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
11*0a6a1f1dSLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
12*0a6a1f1dSLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
13*0a6a1f1dSLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
14*0a6a1f1dSLionel Sambuc  *    documentation and/or other materials provided with the distribution.
15*0a6a1f1dSLionel Sambuc  *
16*0a6a1f1dSLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*0a6a1f1dSLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*0a6a1f1dSLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*0a6a1f1dSLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*0a6a1f1dSLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*0a6a1f1dSLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*0a6a1f1dSLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*0a6a1f1dSLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*0a6a1f1dSLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*0a6a1f1dSLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*0a6a1f1dSLionel Sambuc  * SUCH DAMAGE.
27*0a6a1f1dSLionel Sambuc  */
28*0a6a1f1dSLionel Sambuc 
29*0a6a1f1dSLionel Sambuc #include "_libdwarf.h"
30*0a6a1f1dSLionel Sambuc 
31*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: dwarf_loclist.c,v 1.2 2014/03/09 16:58:04 christos Exp $");
32*0a6a1f1dSLionel Sambuc ELFTC_VCSID("Id: dwarf_loclist.c 2074 2011-10-27 03:34:33Z jkoshy ");
33*0a6a1f1dSLionel Sambuc 
34*0a6a1f1dSLionel Sambuc int
dwarf_loclist_n(Dwarf_Attribute at,Dwarf_Locdesc *** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)35*0a6a1f1dSLionel Sambuc dwarf_loclist_n(Dwarf_Attribute at, Dwarf_Locdesc ***llbuf,
36*0a6a1f1dSLionel Sambuc     Dwarf_Signed *listlen, Dwarf_Error *error)
37*0a6a1f1dSLionel Sambuc {
38*0a6a1f1dSLionel Sambuc 	Dwarf_Loclist ll;
39*0a6a1f1dSLionel Sambuc 	Dwarf_Debug dbg;
40*0a6a1f1dSLionel Sambuc 	int ret;
41*0a6a1f1dSLionel Sambuc 
42*0a6a1f1dSLionel Sambuc 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
43*0a6a1f1dSLionel Sambuc 
44*0a6a1f1dSLionel Sambuc 	if (at == NULL || llbuf == NULL || listlen == NULL) {
45*0a6a1f1dSLionel Sambuc 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
46*0a6a1f1dSLionel Sambuc 		return (DW_DLV_ERROR);
47*0a6a1f1dSLionel Sambuc 	}
48*0a6a1f1dSLionel Sambuc 
49*0a6a1f1dSLionel Sambuc 	switch (at->at_attrib) {
50*0a6a1f1dSLionel Sambuc 	case DW_AT_location:
51*0a6a1f1dSLionel Sambuc 	case DW_AT_string_length:
52*0a6a1f1dSLionel Sambuc 	case DW_AT_return_addr:
53*0a6a1f1dSLionel Sambuc 	case DW_AT_data_member_location:
54*0a6a1f1dSLionel Sambuc 	case DW_AT_frame_base:
55*0a6a1f1dSLionel Sambuc 	case DW_AT_segment:
56*0a6a1f1dSLionel Sambuc 	case DW_AT_static_link:
57*0a6a1f1dSLionel Sambuc 	case DW_AT_use_location:
58*0a6a1f1dSLionel Sambuc 	case DW_AT_vtable_elem_location:
59*0a6a1f1dSLionel Sambuc 		switch (at->at_form) {
60*0a6a1f1dSLionel Sambuc 		case DW_FORM_data4:
61*0a6a1f1dSLionel Sambuc 		case DW_FORM_data8:
62*0a6a1f1dSLionel Sambuc 			/*
63*0a6a1f1dSLionel Sambuc 			 * DW_FORM_data[48] can not be used as section offset
64*0a6a1f1dSLionel Sambuc 			 * since DWARF4. For DWARF[23], the application needs
65*0a6a1f1dSLionel Sambuc 			 * to determine if DW_FORM_data[48] is representing
66*0a6a1f1dSLionel Sambuc 			 * a constant or a section offset.
67*0a6a1f1dSLionel Sambuc 			 */
68*0a6a1f1dSLionel Sambuc 			if (at->at_die->die_cu->cu_version >= 4) {
69*0a6a1f1dSLionel Sambuc 				DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
70*0a6a1f1dSLionel Sambuc 				return (DW_DLV_NO_ENTRY);
71*0a6a1f1dSLionel Sambuc 			}
72*0a6a1f1dSLionel Sambuc 			/* FALLTHROUGH */
73*0a6a1f1dSLionel Sambuc 		case DW_FORM_sec_offset:
74*0a6a1f1dSLionel Sambuc 			ret = _dwarf_loclist_find(dbg, at->at_die->die_cu,
75*0a6a1f1dSLionel Sambuc 			    at->u[0].u64, &ll, error);
76*0a6a1f1dSLionel Sambuc 			if (ret == DW_DLE_NO_ENTRY) {
77*0a6a1f1dSLionel Sambuc 				DWARF_SET_ERROR(dbg, error, ret);
78*0a6a1f1dSLionel Sambuc 				return (DW_DLV_NO_ENTRY);
79*0a6a1f1dSLionel Sambuc 			}
80*0a6a1f1dSLionel Sambuc 			if (ret != DW_DLE_NONE)
81*0a6a1f1dSLionel Sambuc 				return (DW_DLV_ERROR);
82*0a6a1f1dSLionel Sambuc 			*llbuf = ll->ll_ldlist;
83*0a6a1f1dSLionel Sambuc 			*listlen = ll->ll_ldlen;
84*0a6a1f1dSLionel Sambuc 			return (DW_DLV_OK);
85*0a6a1f1dSLionel Sambuc 		case DW_FORM_block:
86*0a6a1f1dSLionel Sambuc 		case DW_FORM_block1:
87*0a6a1f1dSLionel Sambuc 		case DW_FORM_block2:
88*0a6a1f1dSLionel Sambuc 		case DW_FORM_block4:
89*0a6a1f1dSLionel Sambuc 			if (at->at_ld == NULL) {
90*0a6a1f1dSLionel Sambuc 				ret = _dwarf_loc_add(at->at_die, at, error);
91*0a6a1f1dSLionel Sambuc 				if (ret != DW_DLE_NONE)
92*0a6a1f1dSLionel Sambuc 					return (DW_DLV_ERROR);
93*0a6a1f1dSLionel Sambuc 			}
94*0a6a1f1dSLionel Sambuc 			*llbuf = &at->at_ld;
95*0a6a1f1dSLionel Sambuc 			*listlen = 1;
96*0a6a1f1dSLionel Sambuc 			return (DW_DLV_OK);
97*0a6a1f1dSLionel Sambuc 		default:
98*0a6a1f1dSLionel Sambuc 			/* Malformed Attr? */
99*0a6a1f1dSLionel Sambuc 			DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
100*0a6a1f1dSLionel Sambuc 			return (DW_DLV_NO_ENTRY);
101*0a6a1f1dSLionel Sambuc 		}
102*0a6a1f1dSLionel Sambuc 	default:
103*0a6a1f1dSLionel Sambuc 		/* Wrong attr supplied. */
104*0a6a1f1dSLionel Sambuc 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
105*0a6a1f1dSLionel Sambuc 		return (DW_DLV_ERROR);
106*0a6a1f1dSLionel Sambuc 	}
107*0a6a1f1dSLionel Sambuc }
108*0a6a1f1dSLionel Sambuc 
109*0a6a1f1dSLionel Sambuc int
dwarf_loclist(Dwarf_Attribute at,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)110*0a6a1f1dSLionel Sambuc dwarf_loclist(Dwarf_Attribute at, Dwarf_Locdesc **llbuf,
111*0a6a1f1dSLionel Sambuc     Dwarf_Signed *listlen, Dwarf_Error *error)
112*0a6a1f1dSLionel Sambuc {
113*0a6a1f1dSLionel Sambuc 	Dwarf_Loclist ll;
114*0a6a1f1dSLionel Sambuc 	Dwarf_Debug dbg;
115*0a6a1f1dSLionel Sambuc 	int ret;
116*0a6a1f1dSLionel Sambuc 
117*0a6a1f1dSLionel Sambuc 	dbg = at != NULL ? at->at_die->die_dbg : NULL;
118*0a6a1f1dSLionel Sambuc 
119*0a6a1f1dSLionel Sambuc 	if (at == NULL || llbuf == NULL || listlen == NULL) {
120*0a6a1f1dSLionel Sambuc 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
121*0a6a1f1dSLionel Sambuc 		return (DW_DLV_ERROR);
122*0a6a1f1dSLionel Sambuc 	}
123*0a6a1f1dSLionel Sambuc 
124*0a6a1f1dSLionel Sambuc 	switch (at->at_attrib) {
125*0a6a1f1dSLionel Sambuc 	case DW_AT_location:
126*0a6a1f1dSLionel Sambuc 	case DW_AT_string_length:
127*0a6a1f1dSLionel Sambuc 	case DW_AT_return_addr:
128*0a6a1f1dSLionel Sambuc 	case DW_AT_data_member_location:
129*0a6a1f1dSLionel Sambuc 	case DW_AT_frame_base:
130*0a6a1f1dSLionel Sambuc 	case DW_AT_segment:
131*0a6a1f1dSLionel Sambuc 	case DW_AT_static_link:
132*0a6a1f1dSLionel Sambuc 	case DW_AT_use_location:
133*0a6a1f1dSLionel Sambuc 	case DW_AT_vtable_elem_location:
134*0a6a1f1dSLionel Sambuc 		switch (at->at_form) {
135*0a6a1f1dSLionel Sambuc 		case DW_FORM_data4:
136*0a6a1f1dSLionel Sambuc 		case DW_FORM_data8:
137*0a6a1f1dSLionel Sambuc 			/*
138*0a6a1f1dSLionel Sambuc 			 * DW_FORM_data[48] can not be used as section offset
139*0a6a1f1dSLionel Sambuc 			 * since DWARF4. For DWARF[23], the application needs
140*0a6a1f1dSLionel Sambuc 			 * to determine if DW_FORM_data[48] is representing
141*0a6a1f1dSLionel Sambuc 			 * a constant or a section offset.
142*0a6a1f1dSLionel Sambuc 			 */
143*0a6a1f1dSLionel Sambuc 			if (at->at_die->die_cu->cu_version >= 4) {
144*0a6a1f1dSLionel Sambuc 				printf("called cu_version >= 4\n");
145*0a6a1f1dSLionel Sambuc 				DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
146*0a6a1f1dSLionel Sambuc 				return (DW_DLV_NO_ENTRY);
147*0a6a1f1dSLionel Sambuc 			}
148*0a6a1f1dSLionel Sambuc 			/* FALLTHROUGH */
149*0a6a1f1dSLionel Sambuc 		case DW_FORM_sec_offset:
150*0a6a1f1dSLionel Sambuc 			ret = _dwarf_loclist_find(at->at_die->die_dbg,
151*0a6a1f1dSLionel Sambuc 			    at->at_die->die_cu, at->u[0].u64, &ll, error);
152*0a6a1f1dSLionel Sambuc 			if (ret == DW_DLE_NO_ENTRY) {
153*0a6a1f1dSLionel Sambuc 				DWARF_SET_ERROR(dbg, error, DW_DLV_NO_ENTRY);
154*0a6a1f1dSLionel Sambuc 				return (DW_DLV_NO_ENTRY);
155*0a6a1f1dSLionel Sambuc 			}
156*0a6a1f1dSLionel Sambuc 			if (ret != DW_DLE_NONE)
157*0a6a1f1dSLionel Sambuc 				return (DW_DLV_ERROR);
158*0a6a1f1dSLionel Sambuc 			*llbuf = ll->ll_ldlist[0];
159*0a6a1f1dSLionel Sambuc 			*listlen = 1;
160*0a6a1f1dSLionel Sambuc 			return (DW_DLV_OK);
161*0a6a1f1dSLionel Sambuc 		case DW_FORM_block:
162*0a6a1f1dSLionel Sambuc 		case DW_FORM_block1:
163*0a6a1f1dSLionel Sambuc 		case DW_FORM_block2:
164*0a6a1f1dSLionel Sambuc 		case DW_FORM_block4:
165*0a6a1f1dSLionel Sambuc 			if (at->at_ld == NULL) {
166*0a6a1f1dSLionel Sambuc 				ret = _dwarf_loc_add(at->at_die, at, error);
167*0a6a1f1dSLionel Sambuc 				if (ret != DW_DLE_NONE)
168*0a6a1f1dSLionel Sambuc 					return (DW_DLV_ERROR);
169*0a6a1f1dSLionel Sambuc 			}
170*0a6a1f1dSLionel Sambuc 			*llbuf = at->at_ld;
171*0a6a1f1dSLionel Sambuc 			*listlen = 1;
172*0a6a1f1dSLionel Sambuc 			return (DW_DLV_OK);
173*0a6a1f1dSLionel Sambuc 		default:
174*0a6a1f1dSLionel Sambuc 			DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD);
175*0a6a1f1dSLionel Sambuc 			return (DW_DLV_ERROR);
176*0a6a1f1dSLionel Sambuc 		}
177*0a6a1f1dSLionel Sambuc 	default:
178*0a6a1f1dSLionel Sambuc 		/* Wrong attr supplied. */
179*0a6a1f1dSLionel Sambuc 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
180*0a6a1f1dSLionel Sambuc 		return (DW_DLV_ERROR);
181*0a6a1f1dSLionel Sambuc 	}
182*0a6a1f1dSLionel Sambuc }
183*0a6a1f1dSLionel Sambuc 
184*0a6a1f1dSLionel Sambuc int
dwarf_get_loclist_entry(Dwarf_Debug dbg,Dwarf_Unsigned offset,Dwarf_Addr * hipc,Dwarf_Addr * lopc,Dwarf_Ptr * data,Dwarf_Unsigned * entry_len,Dwarf_Unsigned * next_entry,Dwarf_Error * error)185*0a6a1f1dSLionel Sambuc dwarf_get_loclist_entry(Dwarf_Debug dbg, Dwarf_Unsigned offset,
186*0a6a1f1dSLionel Sambuc     Dwarf_Addr *hipc, Dwarf_Addr *lopc, Dwarf_Ptr *data,
187*0a6a1f1dSLionel Sambuc     Dwarf_Unsigned *entry_len, Dwarf_Unsigned *next_entry,
188*0a6a1f1dSLionel Sambuc     Dwarf_Error *error)
189*0a6a1f1dSLionel Sambuc {
190*0a6a1f1dSLionel Sambuc 	Dwarf_Loclist ll, next_ll;
191*0a6a1f1dSLionel Sambuc 	Dwarf_Locdesc *ld;
192*0a6a1f1dSLionel Sambuc 	Dwarf_Section *ds;
193*0a6a1f1dSLionel Sambuc 	int i, ret;
194*0a6a1f1dSLionel Sambuc 
195*0a6a1f1dSLionel Sambuc 	if (dbg == NULL || hipc == NULL || lopc == NULL || data == NULL ||
196*0a6a1f1dSLionel Sambuc 	    entry_len == NULL || next_entry == NULL) {
197*0a6a1f1dSLionel Sambuc 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
198*0a6a1f1dSLionel Sambuc 		return (DW_DLV_ERROR);
199*0a6a1f1dSLionel Sambuc 	}
200*0a6a1f1dSLionel Sambuc 
201*0a6a1f1dSLionel Sambuc 	ret = _dwarf_loclist_find(dbg, STAILQ_FIRST(&dbg->dbg_cu), offset, &ll,
202*0a6a1f1dSLionel Sambuc 	    error);
203*0a6a1f1dSLionel Sambuc 	if (ret == DW_DLE_NO_ENTRY) {
204*0a6a1f1dSLionel Sambuc 		DWARF_SET_ERROR(dbg, error, DW_DLV_NO_ENTRY);
205*0a6a1f1dSLionel Sambuc 		return (DW_DLV_NO_ENTRY);
206*0a6a1f1dSLionel Sambuc 	} else if (ret != DW_DLE_NONE)
207*0a6a1f1dSLionel Sambuc 		return (DW_DLV_ERROR);
208*0a6a1f1dSLionel Sambuc 
209*0a6a1f1dSLionel Sambuc 	*hipc = *lopc = 0;
210*0a6a1f1dSLionel Sambuc 	for (i = 0; i < ll->ll_ldlen; i++) {
211*0a6a1f1dSLionel Sambuc 		ld = ll->ll_ldlist[i];
212*0a6a1f1dSLionel Sambuc 		if (i == 0) {
213*0a6a1f1dSLionel Sambuc 			*hipc = ld->ld_hipc;
214*0a6a1f1dSLionel Sambuc 			*lopc = ld->ld_lopc;
215*0a6a1f1dSLionel Sambuc 		} else {
216*0a6a1f1dSLionel Sambuc 			if (ld->ld_lopc < *lopc)
217*0a6a1f1dSLionel Sambuc 				*lopc = ld->ld_lopc;
218*0a6a1f1dSLionel Sambuc 			if (ld->ld_hipc > *hipc)
219*0a6a1f1dSLionel Sambuc 				*hipc = ld->ld_hipc;
220*0a6a1f1dSLionel Sambuc 		}
221*0a6a1f1dSLionel Sambuc 	}
222*0a6a1f1dSLionel Sambuc 
223*0a6a1f1dSLionel Sambuc 	ds = _dwarf_find_section(dbg, ".debug_loc");
224*0a6a1f1dSLionel Sambuc 	assert(ds != NULL);
225*0a6a1f1dSLionel Sambuc 	*data = (uint8_t *) ds->ds_data + ll->ll_offset;
226*0a6a1f1dSLionel Sambuc 	*entry_len = ll->ll_length;
227*0a6a1f1dSLionel Sambuc 
228*0a6a1f1dSLionel Sambuc 	next_ll = TAILQ_NEXT(ll, ll_next);
229*0a6a1f1dSLionel Sambuc 	if (next_ll != NULL)
230*0a6a1f1dSLionel Sambuc 		*next_entry = next_ll->ll_offset;
231*0a6a1f1dSLionel Sambuc 	else
232*0a6a1f1dSLionel Sambuc 		*next_entry = ds->ds_size;
233*0a6a1f1dSLionel Sambuc 
234*0a6a1f1dSLionel Sambuc 	return (DW_DLV_OK);
235*0a6a1f1dSLionel Sambuc }
236*0a6a1f1dSLionel Sambuc 
237*0a6a1f1dSLionel Sambuc int
dwarf_loclist_from_expr(Dwarf_Debug dbg,Dwarf_Ptr bytes_in,Dwarf_Unsigned bytes_len,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)238*0a6a1f1dSLionel Sambuc dwarf_loclist_from_expr(Dwarf_Debug dbg, Dwarf_Ptr bytes_in,
239*0a6a1f1dSLionel Sambuc     Dwarf_Unsigned bytes_len, Dwarf_Locdesc **llbuf, Dwarf_Signed *listlen,
240*0a6a1f1dSLionel Sambuc     Dwarf_Error *error)
241*0a6a1f1dSLionel Sambuc {
242*0a6a1f1dSLionel Sambuc 	Dwarf_Locdesc *ld;
243*0a6a1f1dSLionel Sambuc 	int ret;
244*0a6a1f1dSLionel Sambuc 
245*0a6a1f1dSLionel Sambuc 	if (dbg == NULL || bytes_in == NULL || bytes_len == 0 ||
246*0a6a1f1dSLionel Sambuc 	    llbuf == NULL || listlen == NULL) {
247*0a6a1f1dSLionel Sambuc 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
248*0a6a1f1dSLionel Sambuc 		return (DW_DLV_ERROR);
249*0a6a1f1dSLionel Sambuc 	}
250*0a6a1f1dSLionel Sambuc 
251*0a6a1f1dSLionel Sambuc 	ret = _dwarf_loc_fill_locexpr(dbg, &ld, bytes_in, bytes_len,
252*0a6a1f1dSLionel Sambuc 	    dbg->dbg_pointer_size, error);
253*0a6a1f1dSLionel Sambuc 	if (ret != DW_DLE_NONE)
254*0a6a1f1dSLionel Sambuc 		return (DW_DLV_ERROR);
255*0a6a1f1dSLionel Sambuc 
256*0a6a1f1dSLionel Sambuc 	*llbuf = ld;
257*0a6a1f1dSLionel Sambuc 	*listlen = 1;
258*0a6a1f1dSLionel Sambuc 
259*0a6a1f1dSLionel Sambuc 	return (DW_DLV_OK);
260*0a6a1f1dSLionel Sambuc }
261*0a6a1f1dSLionel Sambuc 
262*0a6a1f1dSLionel Sambuc int
dwarf_loclist_from_expr_a(Dwarf_Debug dbg,Dwarf_Ptr bytes_in,Dwarf_Unsigned bytes_len,Dwarf_Half addr_size,Dwarf_Locdesc ** llbuf,Dwarf_Signed * listlen,Dwarf_Error * error)263*0a6a1f1dSLionel Sambuc dwarf_loclist_from_expr_a(Dwarf_Debug dbg, Dwarf_Ptr bytes_in,
264*0a6a1f1dSLionel Sambuc     Dwarf_Unsigned bytes_len, Dwarf_Half addr_size, Dwarf_Locdesc **llbuf,
265*0a6a1f1dSLionel Sambuc     Dwarf_Signed *listlen, Dwarf_Error *error)
266*0a6a1f1dSLionel Sambuc {
267*0a6a1f1dSLionel Sambuc 	Dwarf_Locdesc *ld;
268*0a6a1f1dSLionel Sambuc 	int ret;
269*0a6a1f1dSLionel Sambuc 
270*0a6a1f1dSLionel Sambuc 	if (dbg == NULL || bytes_in == NULL || bytes_len == 0 ||
271*0a6a1f1dSLionel Sambuc 	    llbuf == NULL || listlen == NULL) {
272*0a6a1f1dSLionel Sambuc 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
273*0a6a1f1dSLionel Sambuc 		return (DW_DLV_ERROR);
274*0a6a1f1dSLionel Sambuc 	}
275*0a6a1f1dSLionel Sambuc 
276*0a6a1f1dSLionel Sambuc 	if (addr_size != 4 && addr_size != 8) {
277*0a6a1f1dSLionel Sambuc 		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
278*0a6a1f1dSLionel Sambuc 		return (DW_DLV_ERROR);
279*0a6a1f1dSLionel Sambuc 	}
280*0a6a1f1dSLionel Sambuc 
281*0a6a1f1dSLionel Sambuc 	ret = _dwarf_loc_fill_locexpr(dbg, &ld, bytes_in, bytes_len, addr_size,
282*0a6a1f1dSLionel Sambuc 	    error);
283*0a6a1f1dSLionel Sambuc 	if (ret != DW_DLE_NONE)
284*0a6a1f1dSLionel Sambuc 		return (DW_DLV_ERROR);
285*0a6a1f1dSLionel Sambuc 
286*0a6a1f1dSLionel Sambuc 	*llbuf = ld;
287*0a6a1f1dSLionel Sambuc 	*listlen = 1;
288*0a6a1f1dSLionel Sambuc 
289*0a6a1f1dSLionel Sambuc 	return (DW_DLV_OK);
290*0a6a1f1dSLionel Sambuc }
291