1260684Skaiw/*-
2260684Skaiw * Copyright (c) 2007 John Birrell (jb@freebsd.org)
3260684Skaiw * Copyright (c) 2010 Kai Wang
4260684Skaiw * All rights reserved.
5260684Skaiw *
6260684Skaiw * Redistribution and use in source and binary forms, with or without
7260684Skaiw * modification, are permitted provided that the following conditions
8260684Skaiw * are met:
9260684Skaiw * 1. Redistributions of source code must retain the above copyright
10260684Skaiw *    notice, this list of conditions and the following disclaimer.
11260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright
12260684Skaiw *    notice, this list of conditions and the following disclaimer in the
13260684Skaiw *    documentation and/or other materials provided with the distribution.
14260684Skaiw *
15260684Skaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16260684Skaiw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17260684Skaiw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18260684Skaiw * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19260684Skaiw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20260684Skaiw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21260684Skaiw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22260684Skaiw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23260684Skaiw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24260684Skaiw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25260684Skaiw * SUCH DAMAGE.
26260684Skaiw */
27260684Skaiw
28260684Skaiw#include "_libdwarf.h"
29260684Skaiw
30295577SemasteELFTC_VCSID("$Id: libdwarf_rw.c 3286 2015-12-31 16:45:46Z emaste $");
31260684Skaiw
32260684Skaiwuint64_t
33260684Skaiw_dwarf_read_lsb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
34260684Skaiw{
35260684Skaiw	uint64_t ret;
36260684Skaiw	uint8_t *src;
37260684Skaiw
38260684Skaiw	src = data + *offsetp;
39260684Skaiw
40260684Skaiw	ret = 0;
41260684Skaiw	switch (bytes_to_read) {
42260684Skaiw	case 8:
43260684Skaiw		ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
44260684Skaiw		ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
45295577Semaste		/* FALLTHROUGH */
46260684Skaiw	case 4:
47260684Skaiw		ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
48295577Semaste		/* FALLTHROUGH */
49260684Skaiw	case 2:
50260684Skaiw		ret |= ((uint64_t) src[1]) << 8;
51295577Semaste		/* FALLTHROUGH */
52260684Skaiw	case 1:
53260684Skaiw		ret |= src[0];
54260684Skaiw		break;
55260684Skaiw	default:
56260684Skaiw		return (0);
57260684Skaiw	}
58260684Skaiw
59260684Skaiw	*offsetp += bytes_to_read;
60260684Skaiw
61260684Skaiw	return (ret);
62260684Skaiw}
63260684Skaiw
64260684Skaiwuint64_t
65260684Skaiw_dwarf_decode_lsb(uint8_t **data, int bytes_to_read)
66260684Skaiw{
67260684Skaiw	uint64_t ret;
68260684Skaiw	uint8_t *src;
69260684Skaiw
70260684Skaiw	src = *data;
71260684Skaiw
72260684Skaiw	ret = 0;
73260684Skaiw	switch (bytes_to_read) {
74260684Skaiw	case 8:
75260684Skaiw		ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
76260684Skaiw		ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
77295577Semaste		/* FALLTHROUGH */
78260684Skaiw	case 4:
79260684Skaiw		ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
80295577Semaste		/* FALLTHROUGH */
81260684Skaiw	case 2:
82260684Skaiw		ret |= ((uint64_t) src[1]) << 8;
83295577Semaste		/* FALLTHROUGH */
84260684Skaiw	case 1:
85260684Skaiw		ret |= src[0];
86260684Skaiw		break;
87260684Skaiw	default:
88260684Skaiw		return (0);
89260684Skaiw	}
90260684Skaiw
91260684Skaiw	*data += bytes_to_read;
92260684Skaiw
93260684Skaiw	return (ret);
94260684Skaiw}
95260684Skaiw
96260684Skaiwuint64_t
97260684Skaiw_dwarf_read_msb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
98260684Skaiw{
99260684Skaiw	uint64_t ret;
100260684Skaiw	uint8_t *src;
101260684Skaiw
102260684Skaiw	src = data + *offsetp;
103260684Skaiw
104260684Skaiw	switch (bytes_to_read) {
105260684Skaiw	case 1:
106260684Skaiw		ret = src[0];
107260684Skaiw		break;
108260684Skaiw	case 2:
109260684Skaiw		ret = src[1] | ((uint64_t) src[0]) << 8;
110260684Skaiw		break;
111260684Skaiw	case 4:
112260684Skaiw		ret = src[3] | ((uint64_t) src[2]) << 8;
113260684Skaiw		ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
114260684Skaiw		break;
115260684Skaiw	case 8:
116260684Skaiw		ret = src[7] | ((uint64_t) src[6]) << 8;
117260684Skaiw		ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
118260684Skaiw		ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
119260684Skaiw		ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
120260684Skaiw		break;
121260684Skaiw	default:
122260684Skaiw		return (0);
123260684Skaiw	}
124260684Skaiw
125260684Skaiw	*offsetp += bytes_to_read;
126260684Skaiw
127260684Skaiw	return (ret);
128260684Skaiw}
129260684Skaiw
130260684Skaiwuint64_t
131260684Skaiw_dwarf_decode_msb(uint8_t **data, int bytes_to_read)
132260684Skaiw{
133260684Skaiw	uint64_t ret;
134260684Skaiw	uint8_t *src;
135260684Skaiw
136260684Skaiw	src = *data;
137260684Skaiw
138260684Skaiw	ret = 0;
139260684Skaiw	switch (bytes_to_read) {
140260684Skaiw	case 1:
141260684Skaiw		ret = src[0];
142260684Skaiw		break;
143260684Skaiw	case 2:
144260684Skaiw		ret = src[1] | ((uint64_t) src[0]) << 8;
145260684Skaiw		break;
146260684Skaiw	case 4:
147260684Skaiw		ret = src[3] | ((uint64_t) src[2]) << 8;
148260684Skaiw		ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
149260684Skaiw		break;
150260684Skaiw	case 8:
151260684Skaiw		ret = src[7] | ((uint64_t) src[6]) << 8;
152260684Skaiw		ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
153260684Skaiw		ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
154260684Skaiw		ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
155260684Skaiw		break;
156260684Skaiw	default:
157260684Skaiw		return (0);
158260684Skaiw		break;
159260684Skaiw	}
160260684Skaiw
161260684Skaiw	*data += bytes_to_read;
162260684Skaiw
163260684Skaiw	return (ret);
164260684Skaiw}
165260684Skaiw
166260684Skaiwvoid
167260684Skaiw_dwarf_write_lsb(uint8_t *data, uint64_t *offsetp, uint64_t value,
168260684Skaiw    int bytes_to_write)
169260684Skaiw{
170260684Skaiw	uint8_t *dst;
171260684Skaiw
172260684Skaiw	dst = data + *offsetp;
173260684Skaiw
174260684Skaiw	switch (bytes_to_write) {
175260684Skaiw	case 8:
176260684Skaiw		dst[7] = (value >> 56) & 0xff;
177260684Skaiw		dst[6] = (value >> 48) & 0xff;
178260684Skaiw		dst[5] = (value >> 40) & 0xff;
179260684Skaiw		dst[4] = (value >> 32) & 0xff;
180295577Semaste		/* FALLTHROUGH */
181260684Skaiw	case 4:
182260684Skaiw		dst[3] = (value >> 24) & 0xff;
183260684Skaiw		dst[2] = (value >> 16) & 0xff;
184295577Semaste		/* FALLTHROUGH */
185260684Skaiw	case 2:
186260684Skaiw		dst[1] = (value >> 8) & 0xff;
187295577Semaste		/* FALLTHROUGH */
188260684Skaiw	case 1:
189260684Skaiw		dst[0] = value & 0xff;
190260684Skaiw		break;
191260684Skaiw	default:
192260684Skaiw		return;
193260684Skaiw	}
194260684Skaiw
195260684Skaiw	*offsetp += bytes_to_write;
196260684Skaiw}
197260684Skaiw
198260684Skaiwint
199260684Skaiw_dwarf_write_lsb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
200260684Skaiw    uint64_t value, int bytes_to_write, Dwarf_Error *error)
201260684Skaiw{
202260684Skaiw
203260684Skaiw	assert(*size > 0);
204260684Skaiw
205260684Skaiw	while (*offsetp + bytes_to_write > *size) {
206260684Skaiw		*size *= 2;
207260684Skaiw		*block = realloc(*block, (size_t) *size);
208260684Skaiw		if (*block == NULL) {
209260684Skaiw			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
210260684Skaiw			return (DW_DLE_MEMORY);
211260684Skaiw		}
212260684Skaiw	}
213260684Skaiw
214260684Skaiw	_dwarf_write_lsb(*block, offsetp, value, bytes_to_write);
215260684Skaiw
216260684Skaiw	return (DW_DLE_NONE);
217260684Skaiw}
218260684Skaiw
219260684Skaiwvoid
220260684Skaiw_dwarf_write_msb(uint8_t *data, uint64_t *offsetp, uint64_t value,
221260684Skaiw    int bytes_to_write)
222260684Skaiw{
223260684Skaiw	uint8_t *dst;
224260684Skaiw
225260684Skaiw	dst = data + *offsetp;
226260684Skaiw
227260684Skaiw	switch (bytes_to_write) {
228260684Skaiw	case 8:
229260684Skaiw		dst[7] = value & 0xff;
230260684Skaiw		dst[6] = (value >> 8) & 0xff;
231260684Skaiw		dst[5] = (value >> 16) & 0xff;
232260684Skaiw		dst[4] = (value >> 24) & 0xff;
233260684Skaiw		value >>= 32;
234295577Semaste		/* FALLTHROUGH */
235260684Skaiw	case 4:
236260684Skaiw		dst[3] = value & 0xff;
237260684Skaiw		dst[2] = (value >> 8) & 0xff;
238260684Skaiw		value >>= 16;
239295577Semaste		/* FALLTHROUGH */
240260684Skaiw	case 2:
241260684Skaiw		dst[1] = value & 0xff;
242260684Skaiw		value >>= 8;
243295577Semaste		/* FALLTHROUGH */
244260684Skaiw	case 1:
245260684Skaiw		dst[0] = value & 0xff;
246260684Skaiw		break;
247260684Skaiw	default:
248260684Skaiw		return;
249260684Skaiw	}
250260684Skaiw
251260684Skaiw	*offsetp += bytes_to_write;
252260684Skaiw}
253260684Skaiw
254260684Skaiwint
255260684Skaiw_dwarf_write_msb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
256260684Skaiw    uint64_t value, int bytes_to_write, Dwarf_Error *error)
257260684Skaiw{
258260684Skaiw
259260684Skaiw	assert(*size > 0);
260260684Skaiw
261260684Skaiw	while (*offsetp + bytes_to_write > *size) {
262260684Skaiw		*size *= 2;
263260684Skaiw		*block = realloc(*block, (size_t) *size);
264260684Skaiw		if (*block == NULL) {
265260684Skaiw			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
266260684Skaiw			return (DW_DLE_MEMORY);
267260684Skaiw		}
268260684Skaiw	}
269260684Skaiw
270260684Skaiw	_dwarf_write_msb(*block, offsetp, value, bytes_to_write);
271260684Skaiw
272260684Skaiw	return (DW_DLE_NONE);
273260684Skaiw}
274260684Skaiw
275260684Skaiwint64_t
276260684Skaiw_dwarf_read_sleb128(uint8_t *data, uint64_t *offsetp)
277260684Skaiw{
278260684Skaiw	int64_t ret = 0;
279260684Skaiw	uint8_t b;
280260684Skaiw	int shift = 0;
281260684Skaiw	uint8_t *src;
282260684Skaiw
283260684Skaiw	src = data + *offsetp;
284260684Skaiw
285260684Skaiw	do {
286260684Skaiw		b = *src++;
287260684Skaiw		ret |= ((b & 0x7f) << shift);
288260684Skaiw		(*offsetp)++;
289260684Skaiw		shift += 7;
290260684Skaiw	} while ((b & 0x80) != 0);
291260684Skaiw
292260684Skaiw	if (shift < 64 && (b & 0x40) != 0)
293260684Skaiw		ret |= (-1 << shift);
294260684Skaiw
295260684Skaiw	return (ret);
296260684Skaiw}
297260684Skaiw
298260684Skaiwint
299260684Skaiw_dwarf_write_sleb128(uint8_t *data, uint8_t *end, int64_t val)
300260684Skaiw{
301260684Skaiw	uint8_t *p;
302260684Skaiw
303260684Skaiw	p = data;
304260684Skaiw
305260684Skaiw	for (;;) {
306260684Skaiw		if (p >= end)
307260684Skaiw			return (-1);
308260684Skaiw		*p = val & 0x7f;
309260684Skaiw		val >>= 7;
310260684Skaiw		if ((val == 0 && (*p & 0x40) == 0) ||
311260684Skaiw		    (val == -1 && (*p & 0x40) != 0)) {
312260684Skaiw			p++;
313260684Skaiw			break;
314260684Skaiw		}
315260684Skaiw		*p++ |= 0x80;
316260684Skaiw	}
317260684Skaiw
318260684Skaiw	return (p - data);
319260684Skaiw}
320260684Skaiw
321260684Skaiwint
322260684Skaiw_dwarf_write_sleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
323260684Skaiw    int64_t val, Dwarf_Error *error)
324260684Skaiw{
325260684Skaiw	int len;
326260684Skaiw
327260684Skaiw	assert(*size > 0);
328260684Skaiw
329260684Skaiw	while ((len = _dwarf_write_sleb128(*block + *offsetp, *block + *size,
330260684Skaiw	    val)) < 0) {
331260684Skaiw		*size *= 2;
332260684Skaiw		*block = realloc(*block, (size_t) *size);
333260684Skaiw		if (*block == NULL) {
334260684Skaiw			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
335260684Skaiw			return (DW_DLE_MEMORY);
336260684Skaiw		}
337260684Skaiw	}
338260684Skaiw
339260684Skaiw	*offsetp += len;
340260684Skaiw
341260684Skaiw	return (DW_DLE_NONE);
342260684Skaiw}
343260684Skaiw
344260684Skaiwuint64_t
345260684Skaiw_dwarf_read_uleb128(uint8_t *data, uint64_t *offsetp)
346260684Skaiw{
347260684Skaiw	uint64_t ret = 0;
348260684Skaiw	uint8_t b;
349260684Skaiw	int shift = 0;
350260684Skaiw	uint8_t *src;
351260684Skaiw
352260684Skaiw	src = data + *offsetp;
353260684Skaiw
354260684Skaiw	do {
355260684Skaiw		b = *src++;
356260684Skaiw		ret |= ((b & 0x7f) << shift);
357260684Skaiw		(*offsetp)++;
358260684Skaiw		shift += 7;
359260684Skaiw	} while ((b & 0x80) != 0);
360260684Skaiw
361260684Skaiw	return (ret);
362260684Skaiw}
363260684Skaiw
364260684Skaiwint
365260684Skaiw_dwarf_write_uleb128(uint8_t *data, uint8_t *end, uint64_t val)
366260684Skaiw{
367260684Skaiw	uint8_t *p;
368260684Skaiw
369260684Skaiw	p = data;
370260684Skaiw
371260684Skaiw	do {
372260684Skaiw		if (p >= end)
373260684Skaiw			return (-1);
374260684Skaiw		*p = val & 0x7f;
375260684Skaiw		val >>= 7;
376260684Skaiw		if (val > 0)
377260684Skaiw			*p |= 0x80;
378260684Skaiw		p++;
379260684Skaiw	} while (val > 0);
380260684Skaiw
381260684Skaiw	return (p - data);
382260684Skaiw}
383260684Skaiw
384260684Skaiwint
385260684Skaiw_dwarf_write_uleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
386260684Skaiw    uint64_t val, Dwarf_Error *error)
387260684Skaiw{
388260684Skaiw	int len;
389260684Skaiw
390260684Skaiw	assert(*size > 0);
391260684Skaiw
392260684Skaiw	while ((len = _dwarf_write_uleb128(*block + *offsetp, *block + *size,
393260684Skaiw	    val)) < 0) {
394260684Skaiw		*size *= 2;
395260684Skaiw		*block = realloc(*block, (size_t) *size);
396260684Skaiw		if (*block == NULL) {
397260684Skaiw			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
398260684Skaiw			return (DW_DLE_MEMORY);
399260684Skaiw		}
400260684Skaiw	}
401260684Skaiw
402260684Skaiw	*offsetp += len;
403260684Skaiw
404260684Skaiw	return (DW_DLE_NONE);
405260684Skaiw}
406260684Skaiw
407260684Skaiwint64_t
408260684Skaiw_dwarf_decode_sleb128(uint8_t **dp)
409260684Skaiw{
410260684Skaiw	int64_t ret = 0;
411260684Skaiw	uint8_t b;
412260684Skaiw	int shift = 0;
413260684Skaiw
414260684Skaiw	uint8_t *src = *dp;
415260684Skaiw
416260684Skaiw	do {
417260684Skaiw		b = *src++;
418260684Skaiw		ret |= ((b & 0x7f) << shift);
419260684Skaiw		shift += 7;
420260684Skaiw	} while ((b & 0x80) != 0);
421260684Skaiw
422260684Skaiw	if (shift < 64 && (b & 0x40) != 0)
423260684Skaiw		ret |= (-1 << shift);
424260684Skaiw
425260684Skaiw	*dp = src;
426260684Skaiw
427260684Skaiw	return (ret);
428260684Skaiw}
429260684Skaiw
430260684Skaiwuint64_t
431260684Skaiw_dwarf_decode_uleb128(uint8_t **dp)
432260684Skaiw{
433260684Skaiw	uint64_t ret = 0;
434260684Skaiw	uint8_t b;
435260684Skaiw	int shift = 0;
436260684Skaiw
437260684Skaiw	uint8_t *src = *dp;
438260684Skaiw
439260684Skaiw	do {
440260684Skaiw		b = *src++;
441260684Skaiw		ret |= ((b & 0x7f) << shift);
442260684Skaiw		shift += 7;
443260684Skaiw	} while ((b & 0x80) != 0);
444260684Skaiw
445260684Skaiw	*dp = src;
446260684Skaiw
447260684Skaiw	return (ret);
448260684Skaiw}
449260684Skaiw
450260684Skaiwchar *
451260684Skaiw_dwarf_read_string(void *data, Dwarf_Unsigned size, uint64_t *offsetp)
452260684Skaiw{
453260684Skaiw	char *ret, *src;
454260684Skaiw
455260684Skaiw	ret = src = (char *) data + *offsetp;
456260684Skaiw
457260684Skaiw	while (*src != '\0' && *offsetp < size) {
458260684Skaiw		src++;
459260684Skaiw		(*offsetp)++;
460260684Skaiw	}
461260684Skaiw
462260684Skaiw	if (*src == '\0' && *offsetp < size)
463260684Skaiw		(*offsetp)++;
464260684Skaiw
465260684Skaiw	return (ret);
466260684Skaiw}
467260684Skaiw
468260684Skaiwvoid
469260684Skaiw_dwarf_write_string(void *data, uint64_t *offsetp, char *string)
470260684Skaiw{
471260684Skaiw	char *dst;
472260684Skaiw
473260684Skaiw	dst = (char *) data + *offsetp;
474260684Skaiw	strcpy(dst, string);
475260684Skaiw	(*offsetp) += strlen(string) + 1;
476260684Skaiw}
477260684Skaiw
478260684Skaiwint
479260684Skaiw_dwarf_write_string_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
480260684Skaiw    char *string, Dwarf_Error *error)
481260684Skaiw{
482260684Skaiw	size_t len;
483260684Skaiw
484260684Skaiw	assert(*size > 0);
485260684Skaiw
486260684Skaiw	len = strlen(string) + 1;
487260684Skaiw	while (*offsetp + len > *size) {
488260684Skaiw		*size *= 2;
489260684Skaiw		*block = realloc(*block, (size_t) *size);
490260684Skaiw		if (*block == NULL) {
491260684Skaiw			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
492260684Skaiw			return (DW_DLE_MEMORY);
493260684Skaiw		}
494260684Skaiw	}
495260684Skaiw
496260684Skaiw	_dwarf_write_string(*block, offsetp, string);
497260684Skaiw
498260684Skaiw	return (DW_DLE_NONE);
499260684Skaiw}
500260684Skaiw
501260684Skaiwuint8_t *
502260684Skaiw_dwarf_read_block(void *data, uint64_t *offsetp, uint64_t length)
503260684Skaiw{
504260684Skaiw	uint8_t *ret, *src;
505260684Skaiw
506260684Skaiw	ret = src = (uint8_t *) data + *offsetp;
507260684Skaiw
508260684Skaiw	(*offsetp) += length;
509260684Skaiw
510260684Skaiw	return (ret);
511260684Skaiw}
512260684Skaiw
513260684Skaiwvoid
514260684Skaiw_dwarf_write_block(void *data, uint64_t *offsetp, uint8_t *blk,
515260684Skaiw    uint64_t length)
516260684Skaiw{
517260684Skaiw	uint8_t *dst;
518260684Skaiw
519260684Skaiw	dst = (uint8_t *) data + *offsetp;
520260684Skaiw	memcpy(dst, blk, length);
521260684Skaiw	(*offsetp) += length;
522260684Skaiw}
523260684Skaiw
524260684Skaiwint
525260684Skaiw_dwarf_write_block_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
526260684Skaiw    uint8_t *blk, uint64_t length, Dwarf_Error *error)
527260684Skaiw{
528260684Skaiw
529260684Skaiw	assert(*size > 0);
530260684Skaiw
531260684Skaiw	while (*offsetp + length > *size) {
532260684Skaiw		*size *= 2;
533260684Skaiw		*block = realloc(*block, (size_t) *size);
534260684Skaiw		if (*block == NULL) {
535260684Skaiw			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
536260684Skaiw			return (DW_DLE_MEMORY);
537260684Skaiw		}
538260684Skaiw	}
539260684Skaiw
540260684Skaiw	_dwarf_write_block(*block, offsetp, blk, length);
541260684Skaiw
542260684Skaiw	return (DW_DLE_NONE);
543260684Skaiw}
544260684Skaiw
545260684Skaiwvoid
546260684Skaiw_dwarf_write_padding(void *data, uint64_t *offsetp, uint8_t byte,
547260684Skaiw    uint64_t length)
548260684Skaiw{
549260684Skaiw	uint8_t *dst;
550260684Skaiw
551260684Skaiw	dst = (uint8_t *) data + *offsetp;
552260684Skaiw	memset(dst, byte, length);
553260684Skaiw	(*offsetp) += length;
554260684Skaiw}
555260684Skaiw
556260684Skaiwint
557260684Skaiw_dwarf_write_padding_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
558260684Skaiw    uint8_t byte, uint64_t cnt, Dwarf_Error *error)
559260684Skaiw{
560260684Skaiw	assert(*size > 0);
561260684Skaiw
562260684Skaiw	while (*offsetp + cnt > *size) {
563260684Skaiw		*size *= 2;
564260684Skaiw		*block = realloc(*block, (size_t) *size);
565260684Skaiw		if (*block == NULL) {
566260684Skaiw			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
567260684Skaiw			return (DW_DLE_MEMORY);
568260684Skaiw		}
569260684Skaiw	}
570260684Skaiw
571260684Skaiw	_dwarf_write_padding(*block, offsetp, byte, cnt);
572260684Skaiw
573260684Skaiw	return (DW_DLE_NONE);
574260684Skaiw}
575