xref: /minix3/external/bsd/elftoolchain/dist/libdwarf/libdwarf_rw.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: libdwarf_rw.c,v 1.2 2014/03/09 16:58:04 christos Exp $	*/
2*0a6a1f1dSLionel Sambuc 
3*0a6a1f1dSLionel Sambuc /*-
4*0a6a1f1dSLionel Sambuc  * Copyright (c) 2007 John Birrell (jb@freebsd.org)
5*0a6a1f1dSLionel Sambuc  * Copyright (c) 2010 Kai Wang
6*0a6a1f1dSLionel Sambuc  * All rights reserved.
7*0a6a1f1dSLionel Sambuc  *
8*0a6a1f1dSLionel Sambuc  * Redistribution and use in source and binary forms, with or without
9*0a6a1f1dSLionel Sambuc  * modification, are permitted provided that the following conditions
10*0a6a1f1dSLionel Sambuc  * are met:
11*0a6a1f1dSLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
12*0a6a1f1dSLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
13*0a6a1f1dSLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
14*0a6a1f1dSLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
15*0a6a1f1dSLionel Sambuc  *    documentation and/or other materials provided with the distribution.
16*0a6a1f1dSLionel Sambuc  *
17*0a6a1f1dSLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18*0a6a1f1dSLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*0a6a1f1dSLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*0a6a1f1dSLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21*0a6a1f1dSLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22*0a6a1f1dSLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23*0a6a1f1dSLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24*0a6a1f1dSLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25*0a6a1f1dSLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26*0a6a1f1dSLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27*0a6a1f1dSLionel Sambuc  * SUCH DAMAGE.
28*0a6a1f1dSLionel Sambuc  */
29*0a6a1f1dSLionel Sambuc 
30*0a6a1f1dSLionel Sambuc #include "_libdwarf.h"
31*0a6a1f1dSLionel Sambuc 
32*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: libdwarf_rw.c,v 1.2 2014/03/09 16:58:04 christos Exp $");
33*0a6a1f1dSLionel Sambuc ELFTC_VCSID("Id: libdwarf_rw.c 2952 2013-06-26 19:09:40Z kaiwang27 ");
34*0a6a1f1dSLionel Sambuc 
35*0a6a1f1dSLionel Sambuc uint64_t
_dwarf_read_lsb(uint8_t * data,uint64_t * offsetp,int bytes_to_read)36*0a6a1f1dSLionel Sambuc _dwarf_read_lsb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
37*0a6a1f1dSLionel Sambuc {
38*0a6a1f1dSLionel Sambuc 	uint64_t ret;
39*0a6a1f1dSLionel Sambuc 	uint8_t *src;
40*0a6a1f1dSLionel Sambuc 
41*0a6a1f1dSLionel Sambuc 	src = data + *offsetp;
42*0a6a1f1dSLionel Sambuc 
43*0a6a1f1dSLionel Sambuc 	ret = 0;
44*0a6a1f1dSLionel Sambuc 	switch (bytes_to_read) {
45*0a6a1f1dSLionel Sambuc 	case 8:
46*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
47*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
48*0a6a1f1dSLionel Sambuc 	case 4:
49*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
50*0a6a1f1dSLionel Sambuc 	case 2:
51*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[1]) << 8;
52*0a6a1f1dSLionel Sambuc 	case 1:
53*0a6a1f1dSLionel Sambuc 		ret |= src[0];
54*0a6a1f1dSLionel Sambuc 		break;
55*0a6a1f1dSLionel Sambuc 	default:
56*0a6a1f1dSLionel Sambuc 		return (0);
57*0a6a1f1dSLionel Sambuc 	}
58*0a6a1f1dSLionel Sambuc 
59*0a6a1f1dSLionel Sambuc 	*offsetp += bytes_to_read;
60*0a6a1f1dSLionel Sambuc 
61*0a6a1f1dSLionel Sambuc 	return (ret);
62*0a6a1f1dSLionel Sambuc }
63*0a6a1f1dSLionel Sambuc 
64*0a6a1f1dSLionel Sambuc uint64_t
_dwarf_decode_lsb(uint8_t ** data,int bytes_to_read)65*0a6a1f1dSLionel Sambuc _dwarf_decode_lsb(uint8_t **data, int bytes_to_read)
66*0a6a1f1dSLionel Sambuc {
67*0a6a1f1dSLionel Sambuc 	uint64_t ret;
68*0a6a1f1dSLionel Sambuc 	uint8_t *src;
69*0a6a1f1dSLionel Sambuc 
70*0a6a1f1dSLionel Sambuc 	src = *data;
71*0a6a1f1dSLionel Sambuc 
72*0a6a1f1dSLionel Sambuc 	ret = 0;
73*0a6a1f1dSLionel Sambuc 	switch (bytes_to_read) {
74*0a6a1f1dSLionel Sambuc 	case 8:
75*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
76*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
77*0a6a1f1dSLionel Sambuc 	case 4:
78*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
79*0a6a1f1dSLionel Sambuc 	case 2:
80*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[1]) << 8;
81*0a6a1f1dSLionel Sambuc 	case 1:
82*0a6a1f1dSLionel Sambuc 		ret |= src[0];
83*0a6a1f1dSLionel Sambuc 		break;
84*0a6a1f1dSLionel Sambuc 	default:
85*0a6a1f1dSLionel Sambuc 		return (0);
86*0a6a1f1dSLionel Sambuc 	}
87*0a6a1f1dSLionel Sambuc 
88*0a6a1f1dSLionel Sambuc 	*data += bytes_to_read;
89*0a6a1f1dSLionel Sambuc 
90*0a6a1f1dSLionel Sambuc 	return (ret);
91*0a6a1f1dSLionel Sambuc }
92*0a6a1f1dSLionel Sambuc 
93*0a6a1f1dSLionel Sambuc uint64_t
_dwarf_read_msb(uint8_t * data,uint64_t * offsetp,int bytes_to_read)94*0a6a1f1dSLionel Sambuc _dwarf_read_msb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
95*0a6a1f1dSLionel Sambuc {
96*0a6a1f1dSLionel Sambuc 	uint64_t ret;
97*0a6a1f1dSLionel Sambuc 	uint8_t *src;
98*0a6a1f1dSLionel Sambuc 
99*0a6a1f1dSLionel Sambuc 	src = data + *offsetp;
100*0a6a1f1dSLionel Sambuc 
101*0a6a1f1dSLionel Sambuc 	switch (bytes_to_read) {
102*0a6a1f1dSLionel Sambuc 	case 1:
103*0a6a1f1dSLionel Sambuc 		ret = src[0];
104*0a6a1f1dSLionel Sambuc 		break;
105*0a6a1f1dSLionel Sambuc 	case 2:
106*0a6a1f1dSLionel Sambuc 		ret = src[1] | ((uint64_t) src[0]) << 8;
107*0a6a1f1dSLionel Sambuc 		break;
108*0a6a1f1dSLionel Sambuc 	case 4:
109*0a6a1f1dSLionel Sambuc 		ret = src[3] | ((uint64_t) src[2]) << 8;
110*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
111*0a6a1f1dSLionel Sambuc 		break;
112*0a6a1f1dSLionel Sambuc 	case 8:
113*0a6a1f1dSLionel Sambuc 		ret = src[7] | ((uint64_t) src[6]) << 8;
114*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
115*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
116*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
117*0a6a1f1dSLionel Sambuc 		break;
118*0a6a1f1dSLionel Sambuc 	default:
119*0a6a1f1dSLionel Sambuc 		return (0);
120*0a6a1f1dSLionel Sambuc 	}
121*0a6a1f1dSLionel Sambuc 
122*0a6a1f1dSLionel Sambuc 	*offsetp += bytes_to_read;
123*0a6a1f1dSLionel Sambuc 
124*0a6a1f1dSLionel Sambuc 	return (ret);
125*0a6a1f1dSLionel Sambuc }
126*0a6a1f1dSLionel Sambuc 
127*0a6a1f1dSLionel Sambuc uint64_t
_dwarf_decode_msb(uint8_t ** data,int bytes_to_read)128*0a6a1f1dSLionel Sambuc _dwarf_decode_msb(uint8_t **data, int bytes_to_read)
129*0a6a1f1dSLionel Sambuc {
130*0a6a1f1dSLionel Sambuc 	uint64_t ret;
131*0a6a1f1dSLionel Sambuc 	uint8_t *src;
132*0a6a1f1dSLionel Sambuc 
133*0a6a1f1dSLionel Sambuc 	src = *data;
134*0a6a1f1dSLionel Sambuc 
135*0a6a1f1dSLionel Sambuc 	ret = 0;
136*0a6a1f1dSLionel Sambuc 	switch (bytes_to_read) {
137*0a6a1f1dSLionel Sambuc 	case 1:
138*0a6a1f1dSLionel Sambuc 		ret = src[0];
139*0a6a1f1dSLionel Sambuc 		break;
140*0a6a1f1dSLionel Sambuc 	case 2:
141*0a6a1f1dSLionel Sambuc 		ret = src[1] | ((uint64_t) src[0]) << 8;
142*0a6a1f1dSLionel Sambuc 		break;
143*0a6a1f1dSLionel Sambuc 	case 4:
144*0a6a1f1dSLionel Sambuc 		ret = src[3] | ((uint64_t) src[2]) << 8;
145*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
146*0a6a1f1dSLionel Sambuc 		break;
147*0a6a1f1dSLionel Sambuc 	case 8:
148*0a6a1f1dSLionel Sambuc 		ret = src[7] | ((uint64_t) src[6]) << 8;
149*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
150*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
151*0a6a1f1dSLionel Sambuc 		ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
152*0a6a1f1dSLionel Sambuc 		break;
153*0a6a1f1dSLionel Sambuc 	default:
154*0a6a1f1dSLionel Sambuc 		return (0);
155*0a6a1f1dSLionel Sambuc 		break;
156*0a6a1f1dSLionel Sambuc 	}
157*0a6a1f1dSLionel Sambuc 
158*0a6a1f1dSLionel Sambuc 	*data += bytes_to_read;
159*0a6a1f1dSLionel Sambuc 
160*0a6a1f1dSLionel Sambuc 	return (ret);
161*0a6a1f1dSLionel Sambuc }
162*0a6a1f1dSLionel Sambuc 
163*0a6a1f1dSLionel Sambuc void
_dwarf_write_lsb(uint8_t * data,uint64_t * offsetp,uint64_t value,int bytes_to_write)164*0a6a1f1dSLionel Sambuc _dwarf_write_lsb(uint8_t *data, uint64_t *offsetp, uint64_t value,
165*0a6a1f1dSLionel Sambuc     int bytes_to_write)
166*0a6a1f1dSLionel Sambuc {
167*0a6a1f1dSLionel Sambuc 	uint8_t *dst;
168*0a6a1f1dSLionel Sambuc 
169*0a6a1f1dSLionel Sambuc 	dst = data + *offsetp;
170*0a6a1f1dSLionel Sambuc 
171*0a6a1f1dSLionel Sambuc 	switch (bytes_to_write) {
172*0a6a1f1dSLionel Sambuc 	case 8:
173*0a6a1f1dSLionel Sambuc 		dst[7] = (value >> 56) & 0xff;
174*0a6a1f1dSLionel Sambuc 		dst[6] = (value >> 48) & 0xff;
175*0a6a1f1dSLionel Sambuc 		dst[5] = (value >> 40) & 0xff;
176*0a6a1f1dSLionel Sambuc 		dst[4] = (value >> 32) & 0xff;
177*0a6a1f1dSLionel Sambuc 	case 4:
178*0a6a1f1dSLionel Sambuc 		dst[3] = (value >> 24) & 0xff;
179*0a6a1f1dSLionel Sambuc 		dst[2] = (value >> 16) & 0xff;
180*0a6a1f1dSLionel Sambuc 	case 2:
181*0a6a1f1dSLionel Sambuc 		dst[1] = (value >> 8) & 0xff;
182*0a6a1f1dSLionel Sambuc 	case 1:
183*0a6a1f1dSLionel Sambuc 		dst[0] = value & 0xff;
184*0a6a1f1dSLionel Sambuc 		break;
185*0a6a1f1dSLionel Sambuc 	default:
186*0a6a1f1dSLionel Sambuc 		return;
187*0a6a1f1dSLionel Sambuc 	}
188*0a6a1f1dSLionel Sambuc 
189*0a6a1f1dSLionel Sambuc 	*offsetp += bytes_to_write;
190*0a6a1f1dSLionel Sambuc }
191*0a6a1f1dSLionel Sambuc 
192*0a6a1f1dSLionel Sambuc int
_dwarf_write_lsb_alloc(uint8_t ** block,uint64_t * size,uint64_t * offsetp,uint64_t value,int bytes_to_write,Dwarf_Error * error)193*0a6a1f1dSLionel Sambuc _dwarf_write_lsb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
194*0a6a1f1dSLionel Sambuc     uint64_t value, int bytes_to_write, Dwarf_Error *error)
195*0a6a1f1dSLionel Sambuc {
196*0a6a1f1dSLionel Sambuc 
197*0a6a1f1dSLionel Sambuc 	assert(*size > 0);
198*0a6a1f1dSLionel Sambuc 
199*0a6a1f1dSLionel Sambuc 	while (*offsetp + bytes_to_write > *size) {
200*0a6a1f1dSLionel Sambuc 		*size *= 2;
201*0a6a1f1dSLionel Sambuc 		*block = realloc(*block, (size_t) *size);
202*0a6a1f1dSLionel Sambuc 		if (*block == NULL) {
203*0a6a1f1dSLionel Sambuc 			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
204*0a6a1f1dSLionel Sambuc 			return (DW_DLE_MEMORY);
205*0a6a1f1dSLionel Sambuc 		}
206*0a6a1f1dSLionel Sambuc 	}
207*0a6a1f1dSLionel Sambuc 
208*0a6a1f1dSLionel Sambuc 	_dwarf_write_lsb(*block, offsetp, value, bytes_to_write);
209*0a6a1f1dSLionel Sambuc 
210*0a6a1f1dSLionel Sambuc 	return (DW_DLE_NONE);
211*0a6a1f1dSLionel Sambuc }
212*0a6a1f1dSLionel Sambuc 
213*0a6a1f1dSLionel Sambuc void
_dwarf_write_msb(uint8_t * data,uint64_t * offsetp,uint64_t value,int bytes_to_write)214*0a6a1f1dSLionel Sambuc _dwarf_write_msb(uint8_t *data, uint64_t *offsetp, uint64_t value,
215*0a6a1f1dSLionel Sambuc     int bytes_to_write)
216*0a6a1f1dSLionel Sambuc {
217*0a6a1f1dSLionel Sambuc 	uint8_t *dst;
218*0a6a1f1dSLionel Sambuc 
219*0a6a1f1dSLionel Sambuc 	dst = data + *offsetp;
220*0a6a1f1dSLionel Sambuc 
221*0a6a1f1dSLionel Sambuc 	switch (bytes_to_write) {
222*0a6a1f1dSLionel Sambuc 	case 8:
223*0a6a1f1dSLionel Sambuc 		dst[7] = value & 0xff;
224*0a6a1f1dSLionel Sambuc 		dst[6] = (value >> 8) & 0xff;
225*0a6a1f1dSLionel Sambuc 		dst[5] = (value >> 16) & 0xff;
226*0a6a1f1dSLionel Sambuc 		dst[4] = (value >> 24) & 0xff;
227*0a6a1f1dSLionel Sambuc 		value >>= 32;
228*0a6a1f1dSLionel Sambuc 	case 4:
229*0a6a1f1dSLionel Sambuc 		dst[3] = value & 0xff;
230*0a6a1f1dSLionel Sambuc 		dst[2] = (value >> 8) & 0xff;
231*0a6a1f1dSLionel Sambuc 		value >>= 16;
232*0a6a1f1dSLionel Sambuc 	case 2:
233*0a6a1f1dSLionel Sambuc 		dst[1] = value & 0xff;
234*0a6a1f1dSLionel Sambuc 		value >>= 8;
235*0a6a1f1dSLionel Sambuc 	case 1:
236*0a6a1f1dSLionel Sambuc 		dst[0] = value & 0xff;
237*0a6a1f1dSLionel Sambuc 		break;
238*0a6a1f1dSLionel Sambuc 	default:
239*0a6a1f1dSLionel Sambuc 		return;
240*0a6a1f1dSLionel Sambuc 	}
241*0a6a1f1dSLionel Sambuc 
242*0a6a1f1dSLionel Sambuc 	*offsetp += bytes_to_write;
243*0a6a1f1dSLionel Sambuc }
244*0a6a1f1dSLionel Sambuc 
245*0a6a1f1dSLionel Sambuc int
_dwarf_write_msb_alloc(uint8_t ** block,uint64_t * size,uint64_t * offsetp,uint64_t value,int bytes_to_write,Dwarf_Error * error)246*0a6a1f1dSLionel Sambuc _dwarf_write_msb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
247*0a6a1f1dSLionel Sambuc     uint64_t value, int bytes_to_write, Dwarf_Error *error)
248*0a6a1f1dSLionel Sambuc {
249*0a6a1f1dSLionel Sambuc 
250*0a6a1f1dSLionel Sambuc 	assert(*size > 0);
251*0a6a1f1dSLionel Sambuc 
252*0a6a1f1dSLionel Sambuc 	while (*offsetp + bytes_to_write > *size) {
253*0a6a1f1dSLionel Sambuc 		*size *= 2;
254*0a6a1f1dSLionel Sambuc 		*block = realloc(*block, (size_t) *size);
255*0a6a1f1dSLionel Sambuc 		if (*block == NULL) {
256*0a6a1f1dSLionel Sambuc 			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
257*0a6a1f1dSLionel Sambuc 			return (DW_DLE_MEMORY);
258*0a6a1f1dSLionel Sambuc 		}
259*0a6a1f1dSLionel Sambuc 	}
260*0a6a1f1dSLionel Sambuc 
261*0a6a1f1dSLionel Sambuc 	_dwarf_write_msb(*block, offsetp, value, bytes_to_write);
262*0a6a1f1dSLionel Sambuc 
263*0a6a1f1dSLionel Sambuc 	return (DW_DLE_NONE);
264*0a6a1f1dSLionel Sambuc }
265*0a6a1f1dSLionel Sambuc 
266*0a6a1f1dSLionel Sambuc int64_t
_dwarf_read_sleb128(uint8_t * data,uint64_t * offsetp)267*0a6a1f1dSLionel Sambuc _dwarf_read_sleb128(uint8_t *data, uint64_t *offsetp)
268*0a6a1f1dSLionel Sambuc {
269*0a6a1f1dSLionel Sambuc 	int64_t ret = 0;
270*0a6a1f1dSLionel Sambuc 	uint8_t b;
271*0a6a1f1dSLionel Sambuc 	int shift = 0;
272*0a6a1f1dSLionel Sambuc 	uint8_t *src;
273*0a6a1f1dSLionel Sambuc 
274*0a6a1f1dSLionel Sambuc 	src = data + *offsetp;
275*0a6a1f1dSLionel Sambuc 
276*0a6a1f1dSLionel Sambuc 	do {
277*0a6a1f1dSLionel Sambuc 		b = *src++;
278*0a6a1f1dSLionel Sambuc 		ret |= ((b & 0x7f) << shift);
279*0a6a1f1dSLionel Sambuc 		(*offsetp)++;
280*0a6a1f1dSLionel Sambuc 		shift += 7;
281*0a6a1f1dSLionel Sambuc 	} while ((b & 0x80) != 0);
282*0a6a1f1dSLionel Sambuc 
283*0a6a1f1dSLionel Sambuc 	if (shift < 64 && (b & 0x40) != 0)
284*0a6a1f1dSLionel Sambuc 		ret |= (-1 << shift);
285*0a6a1f1dSLionel Sambuc 
286*0a6a1f1dSLionel Sambuc 	return (ret);
287*0a6a1f1dSLionel Sambuc }
288*0a6a1f1dSLionel Sambuc 
289*0a6a1f1dSLionel Sambuc int
_dwarf_write_sleb128(uint8_t * data,uint8_t * end,int64_t val)290*0a6a1f1dSLionel Sambuc _dwarf_write_sleb128(uint8_t *data, uint8_t *end, int64_t val)
291*0a6a1f1dSLionel Sambuc {
292*0a6a1f1dSLionel Sambuc 	uint8_t *p;
293*0a6a1f1dSLionel Sambuc 
294*0a6a1f1dSLionel Sambuc 	p = data;
295*0a6a1f1dSLionel Sambuc 
296*0a6a1f1dSLionel Sambuc 	for (;;) {
297*0a6a1f1dSLionel Sambuc 		if (p >= end)
298*0a6a1f1dSLionel Sambuc 			return (-1);
299*0a6a1f1dSLionel Sambuc 		*p = val & 0x7f;
300*0a6a1f1dSLionel Sambuc 		val >>= 7;
301*0a6a1f1dSLionel Sambuc 		if ((val == 0 && (*p & 0x40) == 0) ||
302*0a6a1f1dSLionel Sambuc 		    (val == -1 && (*p & 0x40) != 0)) {
303*0a6a1f1dSLionel Sambuc 			p++;
304*0a6a1f1dSLionel Sambuc 			break;
305*0a6a1f1dSLionel Sambuc 		}
306*0a6a1f1dSLionel Sambuc 		*p++ |= 0x80;
307*0a6a1f1dSLionel Sambuc 	}
308*0a6a1f1dSLionel Sambuc 
309*0a6a1f1dSLionel Sambuc 	return (p - data);
310*0a6a1f1dSLionel Sambuc }
311*0a6a1f1dSLionel Sambuc 
312*0a6a1f1dSLionel Sambuc int
_dwarf_write_sleb128_alloc(uint8_t ** block,uint64_t * size,uint64_t * offsetp,int64_t val,Dwarf_Error * error)313*0a6a1f1dSLionel Sambuc _dwarf_write_sleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
314*0a6a1f1dSLionel Sambuc     int64_t val, Dwarf_Error *error)
315*0a6a1f1dSLionel Sambuc {
316*0a6a1f1dSLionel Sambuc 	int len;
317*0a6a1f1dSLionel Sambuc 
318*0a6a1f1dSLionel Sambuc 	assert(*size > 0);
319*0a6a1f1dSLionel Sambuc 
320*0a6a1f1dSLionel Sambuc 	while ((len = _dwarf_write_sleb128(*block + *offsetp, *block + *size,
321*0a6a1f1dSLionel Sambuc 	    val)) < 0) {
322*0a6a1f1dSLionel Sambuc 		*size *= 2;
323*0a6a1f1dSLionel Sambuc 		*block = realloc(*block, (size_t) *size);
324*0a6a1f1dSLionel Sambuc 		if (*block == NULL) {
325*0a6a1f1dSLionel Sambuc 			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
326*0a6a1f1dSLionel Sambuc 			return (DW_DLE_MEMORY);
327*0a6a1f1dSLionel Sambuc 		}
328*0a6a1f1dSLionel Sambuc 	}
329*0a6a1f1dSLionel Sambuc 
330*0a6a1f1dSLionel Sambuc 	*offsetp += len;
331*0a6a1f1dSLionel Sambuc 
332*0a6a1f1dSLionel Sambuc 	return (DW_DLE_NONE);
333*0a6a1f1dSLionel Sambuc }
334*0a6a1f1dSLionel Sambuc 
335*0a6a1f1dSLionel Sambuc uint64_t
_dwarf_read_uleb128(uint8_t * data,uint64_t * offsetp)336*0a6a1f1dSLionel Sambuc _dwarf_read_uleb128(uint8_t *data, uint64_t *offsetp)
337*0a6a1f1dSLionel Sambuc {
338*0a6a1f1dSLionel Sambuc 	uint64_t ret = 0;
339*0a6a1f1dSLionel Sambuc 	uint8_t b;
340*0a6a1f1dSLionel Sambuc 	int shift = 0;
341*0a6a1f1dSLionel Sambuc 	uint8_t *src;
342*0a6a1f1dSLionel Sambuc 
343*0a6a1f1dSLionel Sambuc 	src = data + *offsetp;
344*0a6a1f1dSLionel Sambuc 
345*0a6a1f1dSLionel Sambuc 	do {
346*0a6a1f1dSLionel Sambuc 		b = *src++;
347*0a6a1f1dSLionel Sambuc 		ret |= ((b & 0x7f) << shift);
348*0a6a1f1dSLionel Sambuc 		(*offsetp)++;
349*0a6a1f1dSLionel Sambuc 		shift += 7;
350*0a6a1f1dSLionel Sambuc 	} while ((b & 0x80) != 0);
351*0a6a1f1dSLionel Sambuc 
352*0a6a1f1dSLionel Sambuc 	return (ret);
353*0a6a1f1dSLionel Sambuc }
354*0a6a1f1dSLionel Sambuc 
355*0a6a1f1dSLionel Sambuc int
_dwarf_write_uleb128(uint8_t * data,uint8_t * end,uint64_t val)356*0a6a1f1dSLionel Sambuc _dwarf_write_uleb128(uint8_t *data, uint8_t *end, uint64_t val)
357*0a6a1f1dSLionel Sambuc {
358*0a6a1f1dSLionel Sambuc 	uint8_t *p;
359*0a6a1f1dSLionel Sambuc 
360*0a6a1f1dSLionel Sambuc 	p = data;
361*0a6a1f1dSLionel Sambuc 
362*0a6a1f1dSLionel Sambuc 	do {
363*0a6a1f1dSLionel Sambuc 		if (p >= end)
364*0a6a1f1dSLionel Sambuc 			return (-1);
365*0a6a1f1dSLionel Sambuc 		*p = val & 0x7f;
366*0a6a1f1dSLionel Sambuc 		val >>= 7;
367*0a6a1f1dSLionel Sambuc 		if (val > 0)
368*0a6a1f1dSLionel Sambuc 			*p |= 0x80;
369*0a6a1f1dSLionel Sambuc 		p++;
370*0a6a1f1dSLionel Sambuc 	} while (val > 0);
371*0a6a1f1dSLionel Sambuc 
372*0a6a1f1dSLionel Sambuc 	return (p - data);
373*0a6a1f1dSLionel Sambuc }
374*0a6a1f1dSLionel Sambuc 
375*0a6a1f1dSLionel Sambuc int
_dwarf_write_uleb128_alloc(uint8_t ** block,uint64_t * size,uint64_t * offsetp,uint64_t val,Dwarf_Error * error)376*0a6a1f1dSLionel Sambuc _dwarf_write_uleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
377*0a6a1f1dSLionel Sambuc     uint64_t val, Dwarf_Error *error)
378*0a6a1f1dSLionel Sambuc {
379*0a6a1f1dSLionel Sambuc 	int len;
380*0a6a1f1dSLionel Sambuc 
381*0a6a1f1dSLionel Sambuc 	assert(*size > 0);
382*0a6a1f1dSLionel Sambuc 
383*0a6a1f1dSLionel Sambuc 	while ((len = _dwarf_write_uleb128(*block + *offsetp, *block + *size,
384*0a6a1f1dSLionel Sambuc 	    val)) < 0) {
385*0a6a1f1dSLionel Sambuc 		*size *= 2;
386*0a6a1f1dSLionel Sambuc 		*block = realloc(*block, (size_t) *size);
387*0a6a1f1dSLionel Sambuc 		if (*block == NULL) {
388*0a6a1f1dSLionel Sambuc 			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
389*0a6a1f1dSLionel Sambuc 			return (DW_DLE_MEMORY);
390*0a6a1f1dSLionel Sambuc 		}
391*0a6a1f1dSLionel Sambuc 	}
392*0a6a1f1dSLionel Sambuc 
393*0a6a1f1dSLionel Sambuc 	*offsetp += len;
394*0a6a1f1dSLionel Sambuc 
395*0a6a1f1dSLionel Sambuc 	return (DW_DLE_NONE);
396*0a6a1f1dSLionel Sambuc }
397*0a6a1f1dSLionel Sambuc 
398*0a6a1f1dSLionel Sambuc int64_t
_dwarf_decode_sleb128(uint8_t ** dp)399*0a6a1f1dSLionel Sambuc _dwarf_decode_sleb128(uint8_t **dp)
400*0a6a1f1dSLionel Sambuc {
401*0a6a1f1dSLionel Sambuc 	int64_t ret = 0;
402*0a6a1f1dSLionel Sambuc 	uint8_t b;
403*0a6a1f1dSLionel Sambuc 	int shift = 0;
404*0a6a1f1dSLionel Sambuc 
405*0a6a1f1dSLionel Sambuc 	uint8_t *src = *dp;
406*0a6a1f1dSLionel Sambuc 
407*0a6a1f1dSLionel Sambuc 	do {
408*0a6a1f1dSLionel Sambuc 		b = *src++;
409*0a6a1f1dSLionel Sambuc 		ret |= ((b & 0x7f) << shift);
410*0a6a1f1dSLionel Sambuc 		shift += 7;
411*0a6a1f1dSLionel Sambuc 	} while ((b & 0x80) != 0);
412*0a6a1f1dSLionel Sambuc 
413*0a6a1f1dSLionel Sambuc 	if (shift < 64 && (b & 0x40) != 0)
414*0a6a1f1dSLionel Sambuc 		ret |= (-1 << shift);
415*0a6a1f1dSLionel Sambuc 
416*0a6a1f1dSLionel Sambuc 	*dp = src;
417*0a6a1f1dSLionel Sambuc 
418*0a6a1f1dSLionel Sambuc 	return (ret);
419*0a6a1f1dSLionel Sambuc }
420*0a6a1f1dSLionel Sambuc 
421*0a6a1f1dSLionel Sambuc uint64_t
_dwarf_decode_uleb128(uint8_t ** dp)422*0a6a1f1dSLionel Sambuc _dwarf_decode_uleb128(uint8_t **dp)
423*0a6a1f1dSLionel Sambuc {
424*0a6a1f1dSLionel Sambuc 	uint64_t ret = 0;
425*0a6a1f1dSLionel Sambuc 	uint8_t b;
426*0a6a1f1dSLionel Sambuc 	int shift = 0;
427*0a6a1f1dSLionel Sambuc 
428*0a6a1f1dSLionel Sambuc 	uint8_t *src = *dp;
429*0a6a1f1dSLionel Sambuc 
430*0a6a1f1dSLionel Sambuc 	do {
431*0a6a1f1dSLionel Sambuc 		b = *src++;
432*0a6a1f1dSLionel Sambuc 		ret |= ((b & 0x7f) << shift);
433*0a6a1f1dSLionel Sambuc 		shift += 7;
434*0a6a1f1dSLionel Sambuc 	} while ((b & 0x80) != 0);
435*0a6a1f1dSLionel Sambuc 
436*0a6a1f1dSLionel Sambuc 	*dp = src;
437*0a6a1f1dSLionel Sambuc 
438*0a6a1f1dSLionel Sambuc 	return (ret);
439*0a6a1f1dSLionel Sambuc }
440*0a6a1f1dSLionel Sambuc 
441*0a6a1f1dSLionel Sambuc char *
_dwarf_read_string(void * data,Dwarf_Unsigned size,uint64_t * offsetp)442*0a6a1f1dSLionel Sambuc _dwarf_read_string(void *data, Dwarf_Unsigned size, uint64_t *offsetp)
443*0a6a1f1dSLionel Sambuc {
444*0a6a1f1dSLionel Sambuc 	char *ret, *src;
445*0a6a1f1dSLionel Sambuc 
446*0a6a1f1dSLionel Sambuc 	ret = src = (char *) data + *offsetp;
447*0a6a1f1dSLionel Sambuc 
448*0a6a1f1dSLionel Sambuc 	while (*src != '\0' && *offsetp < size) {
449*0a6a1f1dSLionel Sambuc 		src++;
450*0a6a1f1dSLionel Sambuc 		(*offsetp)++;
451*0a6a1f1dSLionel Sambuc 	}
452*0a6a1f1dSLionel Sambuc 
453*0a6a1f1dSLionel Sambuc 	if (*src == '\0' && *offsetp < size)
454*0a6a1f1dSLionel Sambuc 		(*offsetp)++;
455*0a6a1f1dSLionel Sambuc 
456*0a6a1f1dSLionel Sambuc 	return (ret);
457*0a6a1f1dSLionel Sambuc }
458*0a6a1f1dSLionel Sambuc 
459*0a6a1f1dSLionel Sambuc void
_dwarf_write_string(void * data,uint64_t * offsetp,char * string)460*0a6a1f1dSLionel Sambuc _dwarf_write_string(void *data, uint64_t *offsetp, char *string)
461*0a6a1f1dSLionel Sambuc {
462*0a6a1f1dSLionel Sambuc 	char *dst;
463*0a6a1f1dSLionel Sambuc 
464*0a6a1f1dSLionel Sambuc 	dst = (char *) data + *offsetp;
465*0a6a1f1dSLionel Sambuc 	strcpy(dst, string);
466*0a6a1f1dSLionel Sambuc 	(*offsetp) += strlen(string) + 1;
467*0a6a1f1dSLionel Sambuc }
468*0a6a1f1dSLionel Sambuc 
469*0a6a1f1dSLionel Sambuc int
_dwarf_write_string_alloc(uint8_t ** block,uint64_t * size,uint64_t * offsetp,char * string,Dwarf_Error * error)470*0a6a1f1dSLionel Sambuc _dwarf_write_string_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
471*0a6a1f1dSLionel Sambuc     char *string, Dwarf_Error *error)
472*0a6a1f1dSLionel Sambuc {
473*0a6a1f1dSLionel Sambuc 	size_t len;
474*0a6a1f1dSLionel Sambuc 
475*0a6a1f1dSLionel Sambuc 	assert(*size > 0);
476*0a6a1f1dSLionel Sambuc 
477*0a6a1f1dSLionel Sambuc 	len = strlen(string) + 1;
478*0a6a1f1dSLionel Sambuc 	while (*offsetp + len > *size) {
479*0a6a1f1dSLionel Sambuc 		*size *= 2;
480*0a6a1f1dSLionel Sambuc 		*block = realloc(*block, (size_t) *size);
481*0a6a1f1dSLionel Sambuc 		if (*block == NULL) {
482*0a6a1f1dSLionel Sambuc 			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
483*0a6a1f1dSLionel Sambuc 			return (DW_DLE_MEMORY);
484*0a6a1f1dSLionel Sambuc 		}
485*0a6a1f1dSLionel Sambuc 	}
486*0a6a1f1dSLionel Sambuc 
487*0a6a1f1dSLionel Sambuc 	_dwarf_write_string(*block, offsetp, string);
488*0a6a1f1dSLionel Sambuc 
489*0a6a1f1dSLionel Sambuc 	return (DW_DLE_NONE);
490*0a6a1f1dSLionel Sambuc }
491*0a6a1f1dSLionel Sambuc 
492*0a6a1f1dSLionel Sambuc uint8_t *
_dwarf_read_block(void * data,uint64_t * offsetp,uint64_t length)493*0a6a1f1dSLionel Sambuc _dwarf_read_block(void *data, uint64_t *offsetp, uint64_t length)
494*0a6a1f1dSLionel Sambuc {
495*0a6a1f1dSLionel Sambuc 	uint8_t *ret, *src;
496*0a6a1f1dSLionel Sambuc 
497*0a6a1f1dSLionel Sambuc 	ret = src = (uint8_t *) data + *offsetp;
498*0a6a1f1dSLionel Sambuc 
499*0a6a1f1dSLionel Sambuc 	(*offsetp) += length;
500*0a6a1f1dSLionel Sambuc 
501*0a6a1f1dSLionel Sambuc 	return (ret);
502*0a6a1f1dSLionel Sambuc }
503*0a6a1f1dSLionel Sambuc 
504*0a6a1f1dSLionel Sambuc void
_dwarf_write_block(void * data,uint64_t * offsetp,uint8_t * blk,uint64_t length)505*0a6a1f1dSLionel Sambuc _dwarf_write_block(void *data, uint64_t *offsetp, uint8_t *blk,
506*0a6a1f1dSLionel Sambuc     uint64_t length)
507*0a6a1f1dSLionel Sambuc {
508*0a6a1f1dSLionel Sambuc 	uint8_t *dst;
509*0a6a1f1dSLionel Sambuc 
510*0a6a1f1dSLionel Sambuc 	dst = (uint8_t *) data + *offsetp;
511*0a6a1f1dSLionel Sambuc 	memcpy(dst, blk, length);
512*0a6a1f1dSLionel Sambuc 	(*offsetp) += length;
513*0a6a1f1dSLionel Sambuc }
514*0a6a1f1dSLionel Sambuc 
515*0a6a1f1dSLionel Sambuc int
_dwarf_write_block_alloc(uint8_t ** block,uint64_t * size,uint64_t * offsetp,uint8_t * blk,uint64_t length,Dwarf_Error * error)516*0a6a1f1dSLionel Sambuc _dwarf_write_block_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
517*0a6a1f1dSLionel Sambuc     uint8_t *blk, uint64_t length, Dwarf_Error *error)
518*0a6a1f1dSLionel Sambuc {
519*0a6a1f1dSLionel Sambuc 
520*0a6a1f1dSLionel Sambuc 	assert(*size > 0);
521*0a6a1f1dSLionel Sambuc 
522*0a6a1f1dSLionel Sambuc 	while (*offsetp + length > *size) {
523*0a6a1f1dSLionel Sambuc 		*size *= 2;
524*0a6a1f1dSLionel Sambuc 		*block = realloc(*block, (size_t) *size);
525*0a6a1f1dSLionel Sambuc 		if (*block == NULL) {
526*0a6a1f1dSLionel Sambuc 			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
527*0a6a1f1dSLionel Sambuc 			return (DW_DLE_MEMORY);
528*0a6a1f1dSLionel Sambuc 		}
529*0a6a1f1dSLionel Sambuc 	}
530*0a6a1f1dSLionel Sambuc 
531*0a6a1f1dSLionel Sambuc 	_dwarf_write_block(*block, offsetp, blk, length);
532*0a6a1f1dSLionel Sambuc 
533*0a6a1f1dSLionel Sambuc 	return (DW_DLE_NONE);
534*0a6a1f1dSLionel Sambuc }
535*0a6a1f1dSLionel Sambuc 
536*0a6a1f1dSLionel Sambuc void
_dwarf_write_padding(void * data,uint64_t * offsetp,uint8_t byte,uint64_t length)537*0a6a1f1dSLionel Sambuc _dwarf_write_padding(void *data, uint64_t *offsetp, uint8_t byte,
538*0a6a1f1dSLionel Sambuc     uint64_t length)
539*0a6a1f1dSLionel Sambuc {
540*0a6a1f1dSLionel Sambuc 	uint8_t *dst;
541*0a6a1f1dSLionel Sambuc 
542*0a6a1f1dSLionel Sambuc 	dst = (uint8_t *) data + *offsetp;
543*0a6a1f1dSLionel Sambuc 	memset(dst, byte, length);
544*0a6a1f1dSLionel Sambuc 	(*offsetp) += length;
545*0a6a1f1dSLionel Sambuc }
546*0a6a1f1dSLionel Sambuc 
547*0a6a1f1dSLionel Sambuc int
_dwarf_write_padding_alloc(uint8_t ** block,uint64_t * size,uint64_t * offsetp,uint8_t byte,uint64_t cnt,Dwarf_Error * error)548*0a6a1f1dSLionel Sambuc _dwarf_write_padding_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
549*0a6a1f1dSLionel Sambuc     uint8_t byte, uint64_t cnt, Dwarf_Error *error)
550*0a6a1f1dSLionel Sambuc {
551*0a6a1f1dSLionel Sambuc 	assert(*size > 0);
552*0a6a1f1dSLionel Sambuc 
553*0a6a1f1dSLionel Sambuc 	while (*offsetp + cnt > *size) {
554*0a6a1f1dSLionel Sambuc 		*size *= 2;
555*0a6a1f1dSLionel Sambuc 		*block = realloc(*block, (size_t) *size);
556*0a6a1f1dSLionel Sambuc 		if (*block == NULL) {
557*0a6a1f1dSLionel Sambuc 			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
558*0a6a1f1dSLionel Sambuc 			return (DW_DLE_MEMORY);
559*0a6a1f1dSLionel Sambuc 		}
560*0a6a1f1dSLionel Sambuc 	}
561*0a6a1f1dSLionel Sambuc 
562*0a6a1f1dSLionel Sambuc 	_dwarf_write_padding(*block, offsetp, byte, cnt);
563*0a6a1f1dSLionel Sambuc 
564*0a6a1f1dSLionel Sambuc 	return (DW_DLE_NONE);
565*0a6a1f1dSLionel Sambuc }
566