1 /* $NetBSD: libdwarf_rw.c,v 1.2 2014/03/09 16:58:04 christos Exp $ */
4 * Copyright (c) 2007 John Birrell (jb@freebsd.org)
5 * Copyright (c) 2010 Kai Wang
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include "_libdwarf.h"
32 __RCSID("$NetBSD: libdwarf_rw.c,v 1.2 2014/03/09 16:58:04 christos Exp $");
33 ELFTC_VCSID("Id: libdwarf_rw.c 2952 2013-06-26 19:09:40Z kaiwang27 ");
36 _dwarf_read_lsb(uint8_t *data
, uint64_t *offsetp
, int bytes_to_read
)
41 src
= data
+ *offsetp
;
44 switch (bytes_to_read
) {
46 ret
|= ((uint64_t) src
[4]) << 32 | ((uint64_t) src
[5]) << 40;
47 ret
|= ((uint64_t) src
[6]) << 48 | ((uint64_t) src
[7]) << 56;
49 ret
|= ((uint64_t) src
[2]) << 16 | ((uint64_t) src
[3]) << 24;
51 ret
|= ((uint64_t) src
[1]) << 8;
59 *offsetp
+= bytes_to_read
;
65 _dwarf_decode_lsb(uint8_t **data
, int bytes_to_read
)
73 switch (bytes_to_read
) {
75 ret
|= ((uint64_t) src
[4]) << 32 | ((uint64_t) src
[5]) << 40;
76 ret
|= ((uint64_t) src
[6]) << 48 | ((uint64_t) src
[7]) << 56;
78 ret
|= ((uint64_t) src
[2]) << 16 | ((uint64_t) src
[3]) << 24;
80 ret
|= ((uint64_t) src
[1]) << 8;
88 *data
+= bytes_to_read
;
94 _dwarf_read_msb(uint8_t *data
, uint64_t *offsetp
, int bytes_to_read
)
99 src
= data
+ *offsetp
;
101 switch (bytes_to_read
) {
106 ret
= src
[1] | ((uint64_t) src
[0]) << 8;
109 ret
= src
[3] | ((uint64_t) src
[2]) << 8;
110 ret
|= ((uint64_t) src
[1]) << 16 | ((uint64_t) src
[0]) << 24;
113 ret
= src
[7] | ((uint64_t) src
[6]) << 8;
114 ret
|= ((uint64_t) src
[5]) << 16 | ((uint64_t) src
[4]) << 24;
115 ret
|= ((uint64_t) src
[3]) << 32 | ((uint64_t) src
[2]) << 40;
116 ret
|= ((uint64_t) src
[1]) << 48 | ((uint64_t) src
[0]) << 56;
122 *offsetp
+= bytes_to_read
;
128 _dwarf_decode_msb(uint8_t **data
, int bytes_to_read
)
136 switch (bytes_to_read
) {
141 ret
= src
[1] | ((uint64_t) src
[0]) << 8;
144 ret
= src
[3] | ((uint64_t) src
[2]) << 8;
145 ret
|= ((uint64_t) src
[1]) << 16 | ((uint64_t) src
[0]) << 24;
148 ret
= src
[7] | ((uint64_t) src
[6]) << 8;
149 ret
|= ((uint64_t) src
[5]) << 16 | ((uint64_t) src
[4]) << 24;
150 ret
|= ((uint64_t) src
[3]) << 32 | ((uint64_t) src
[2]) << 40;
151 ret
|= ((uint64_t) src
[1]) << 48 | ((uint64_t) src
[0]) << 56;
158 *data
+= bytes_to_read
;
164 _dwarf_write_lsb(uint8_t *data
, uint64_t *offsetp
, uint64_t value
,
169 dst
= data
+ *offsetp
;
171 switch (bytes_to_write
) {
173 dst
[7] = (value
>> 56) & 0xff;
174 dst
[6] = (value
>> 48) & 0xff;
175 dst
[5] = (value
>> 40) & 0xff;
176 dst
[4] = (value
>> 32) & 0xff;
178 dst
[3] = (value
>> 24) & 0xff;
179 dst
[2] = (value
>> 16) & 0xff;
181 dst
[1] = (value
>> 8) & 0xff;
183 dst
[0] = value
& 0xff;
189 *offsetp
+= bytes_to_write
;
193 _dwarf_write_lsb_alloc(uint8_t **block
, uint64_t *size
, uint64_t *offsetp
,
194 uint64_t value
, int bytes_to_write
, Dwarf_Error
*error
)
199 while (*offsetp
+ bytes_to_write
> *size
) {
201 *block
= realloc(*block
, (size_t) *size
);
202 if (*block
== NULL
) {
203 DWARF_SET_ERROR(NULL
, error
, DW_DLE_MEMORY
);
204 return (DW_DLE_MEMORY
);
208 _dwarf_write_lsb(*block
, offsetp
, value
, bytes_to_write
);
210 return (DW_DLE_NONE
);
214 _dwarf_write_msb(uint8_t *data
, uint64_t *offsetp
, uint64_t value
,
219 dst
= data
+ *offsetp
;
221 switch (bytes_to_write
) {
223 dst
[7] = value
& 0xff;
224 dst
[6] = (value
>> 8) & 0xff;
225 dst
[5] = (value
>> 16) & 0xff;
226 dst
[4] = (value
>> 24) & 0xff;
229 dst
[3] = value
& 0xff;
230 dst
[2] = (value
>> 8) & 0xff;
233 dst
[1] = value
& 0xff;
236 dst
[0] = value
& 0xff;
242 *offsetp
+= bytes_to_write
;
246 _dwarf_write_msb_alloc(uint8_t **block
, uint64_t *size
, uint64_t *offsetp
,
247 uint64_t value
, int bytes_to_write
, Dwarf_Error
*error
)
252 while (*offsetp
+ bytes_to_write
> *size
) {
254 *block
= realloc(*block
, (size_t) *size
);
255 if (*block
== NULL
) {
256 DWARF_SET_ERROR(NULL
, error
, DW_DLE_MEMORY
);
257 return (DW_DLE_MEMORY
);
261 _dwarf_write_msb(*block
, offsetp
, value
, bytes_to_write
);
263 return (DW_DLE_NONE
);
267 _dwarf_read_sleb128(uint8_t *data
, uint64_t *offsetp
)
274 src
= data
+ *offsetp
;
278 ret
|= ((b
& 0x7f) << shift
);
281 } while ((b
& 0x80) != 0);
283 if (shift
< 64 && (b
& 0x40) != 0)
284 ret
|= (-1 << shift
);
290 _dwarf_write_sleb128(uint8_t *data
, uint8_t *end
, int64_t val
)
301 if ((val
== 0 && (*p
& 0x40) == 0) ||
302 (val
== -1 && (*p
& 0x40) != 0)) {
313 _dwarf_write_sleb128_alloc(uint8_t **block
, uint64_t *size
, uint64_t *offsetp
,
314 int64_t val
, Dwarf_Error
*error
)
320 while ((len
= _dwarf_write_sleb128(*block
+ *offsetp
, *block
+ *size
,
323 *block
= realloc(*block
, (size_t) *size
);
324 if (*block
== NULL
) {
325 DWARF_SET_ERROR(NULL
, error
, DW_DLE_MEMORY
);
326 return (DW_DLE_MEMORY
);
332 return (DW_DLE_NONE
);
336 _dwarf_read_uleb128(uint8_t *data
, uint64_t *offsetp
)
343 src
= data
+ *offsetp
;
347 ret
|= ((b
& 0x7f) << shift
);
350 } while ((b
& 0x80) != 0);
356 _dwarf_write_uleb128(uint8_t *data
, uint8_t *end
, uint64_t val
)
376 _dwarf_write_uleb128_alloc(uint8_t **block
, uint64_t *size
, uint64_t *offsetp
,
377 uint64_t val
, Dwarf_Error
*error
)
383 while ((len
= _dwarf_write_uleb128(*block
+ *offsetp
, *block
+ *size
,
386 *block
= realloc(*block
, (size_t) *size
);
387 if (*block
== NULL
) {
388 DWARF_SET_ERROR(NULL
, error
, DW_DLE_MEMORY
);
389 return (DW_DLE_MEMORY
);
395 return (DW_DLE_NONE
);
399 _dwarf_decode_sleb128(uint8_t **dp
)
409 ret
|= ((b
& 0x7f) << shift
);
411 } while ((b
& 0x80) != 0);
413 if (shift
< 64 && (b
& 0x40) != 0)
414 ret
|= (-1 << shift
);
422 _dwarf_decode_uleb128(uint8_t **dp
)
432 ret
|= ((b
& 0x7f) << shift
);
434 } while ((b
& 0x80) != 0);
442 _dwarf_read_string(void *data
, Dwarf_Unsigned size
, uint64_t *offsetp
)
446 ret
= src
= (char *) data
+ *offsetp
;
448 while (*src
!= '\0' && *offsetp
< size
) {
453 if (*src
== '\0' && *offsetp
< size
)
460 _dwarf_write_string(void *data
, uint64_t *offsetp
, char *string
)
464 dst
= (char *) data
+ *offsetp
;
466 (*offsetp
) += strlen(string
) + 1;
470 _dwarf_write_string_alloc(uint8_t **block
, uint64_t *size
, uint64_t *offsetp
,
471 char *string
, Dwarf_Error
*error
)
477 len
= strlen(string
) + 1;
478 while (*offsetp
+ len
> *size
) {
480 *block
= realloc(*block
, (size_t) *size
);
481 if (*block
== NULL
) {
482 DWARF_SET_ERROR(NULL
, error
, DW_DLE_MEMORY
);
483 return (DW_DLE_MEMORY
);
487 _dwarf_write_string(*block
, offsetp
, string
);
489 return (DW_DLE_NONE
);
493 _dwarf_read_block(void *data
, uint64_t *offsetp
, uint64_t length
)
497 ret
= src
= (uint8_t *) data
+ *offsetp
;
499 (*offsetp
) += length
;
505 _dwarf_write_block(void *data
, uint64_t *offsetp
, uint8_t *blk
,
510 dst
= (uint8_t *) data
+ *offsetp
;
511 memcpy(dst
, blk
, length
);
512 (*offsetp
) += length
;
516 _dwarf_write_block_alloc(uint8_t **block
, uint64_t *size
, uint64_t *offsetp
,
517 uint8_t *blk
, uint64_t length
, Dwarf_Error
*error
)
522 while (*offsetp
+ length
> *size
) {
524 *block
= realloc(*block
, (size_t) *size
);
525 if (*block
== NULL
) {
526 DWARF_SET_ERROR(NULL
, error
, DW_DLE_MEMORY
);
527 return (DW_DLE_MEMORY
);
531 _dwarf_write_block(*block
, offsetp
, blk
, length
);
533 return (DW_DLE_NONE
);
537 _dwarf_write_padding(void *data
, uint64_t *offsetp
, uint8_t byte
,
542 dst
= (uint8_t *) data
+ *offsetp
;
543 memset(dst
, byte
, length
);
544 (*offsetp
) += length
;
548 _dwarf_write_padding_alloc(uint8_t **block
, uint64_t *size
, uint64_t *offsetp
,
549 uint8_t byte
, uint64_t cnt
, Dwarf_Error
*error
)
553 while (*offsetp
+ cnt
> *size
) {
555 *block
= realloc(*block
, (size_t) *size
);
556 if (*block
== NULL
) {
557 DWARF_SET_ERROR(NULL
, error
, DW_DLE_MEMORY
);
558 return (DW_DLE_MEMORY
);
562 _dwarf_write_padding(*block
, offsetp
, byte
, cnt
);
564 return (DW_DLE_NONE
);