2 * Copyright (c) 2007 John Birrell (jb@freebsd.org)
3 * Copyright (c) 2010 Kai Wang
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include "_libdwarf.h"
30 ELFTC_VCSID("$Id: libdwarf_rw.c 2952 2013-06-26 19:09:40Z kaiwang27 $");
33 _dwarf_read_lsb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
38 src = data + *offsetp;
41 switch (bytes_to_read) {
43 ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
44 ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
46 ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
48 ret |= ((uint64_t) src[1]) << 8;
56 *offsetp += bytes_to_read;
62 _dwarf_decode_lsb(uint8_t **data, int bytes_to_read)
70 switch (bytes_to_read) {
72 ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
73 ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
75 ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
77 ret |= ((uint64_t) src[1]) << 8;
85 *data += bytes_to_read;
91 _dwarf_read_msb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
96 src = data + *offsetp;
98 switch (bytes_to_read) {
103 ret = src[1] | ((uint64_t) src[0]) << 8;
106 ret = src[3] | ((uint64_t) src[2]) << 8;
107 ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
110 ret = src[7] | ((uint64_t) src[6]) << 8;
111 ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
112 ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
113 ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
119 *offsetp += bytes_to_read;
125 _dwarf_decode_msb(uint8_t **data, int bytes_to_read)
133 switch (bytes_to_read) {
138 ret = src[1] | ((uint64_t) src[0]) << 8;
141 ret = src[3] | ((uint64_t) src[2]) << 8;
142 ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
145 ret = src[7] | ((uint64_t) src[6]) << 8;
146 ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
147 ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
148 ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
155 *data += bytes_to_read;
161 _dwarf_write_lsb(uint8_t *data, uint64_t *offsetp, uint64_t value,
166 dst = data + *offsetp;
168 switch (bytes_to_write) {
170 dst[7] = (value >> 56) & 0xff;
171 dst[6] = (value >> 48) & 0xff;
172 dst[5] = (value >> 40) & 0xff;
173 dst[4] = (value >> 32) & 0xff;
175 dst[3] = (value >> 24) & 0xff;
176 dst[2] = (value >> 16) & 0xff;
178 dst[1] = (value >> 8) & 0xff;
180 dst[0] = value & 0xff;
186 *offsetp += bytes_to_write;
190 _dwarf_write_lsb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
191 uint64_t value, int bytes_to_write, Dwarf_Error *error)
196 while (*offsetp + bytes_to_write > *size) {
198 *block = realloc(*block, (size_t) *size);
199 if (*block == NULL) {
200 DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
201 return (DW_DLE_MEMORY);
205 _dwarf_write_lsb(*block, offsetp, value, bytes_to_write);
207 return (DW_DLE_NONE);
211 _dwarf_write_msb(uint8_t *data, uint64_t *offsetp, uint64_t value,
216 dst = data + *offsetp;
218 switch (bytes_to_write) {
220 dst[7] = value & 0xff;
221 dst[6] = (value >> 8) & 0xff;
222 dst[5] = (value >> 16) & 0xff;
223 dst[4] = (value >> 24) & 0xff;
226 dst[3] = value & 0xff;
227 dst[2] = (value >> 8) & 0xff;
230 dst[1] = value & 0xff;
233 dst[0] = value & 0xff;
239 *offsetp += bytes_to_write;
243 _dwarf_write_msb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
244 uint64_t value, int bytes_to_write, Dwarf_Error *error)
249 while (*offsetp + bytes_to_write > *size) {
251 *block = realloc(*block, (size_t) *size);
252 if (*block == NULL) {
253 DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
254 return (DW_DLE_MEMORY);
258 _dwarf_write_msb(*block, offsetp, value, bytes_to_write);
260 return (DW_DLE_NONE);
264 _dwarf_read_sleb128(uint8_t *data, uint64_t *offsetp)
271 src = data + *offsetp;
275 ret |= ((b & 0x7f) << shift);
278 } while ((b & 0x80) != 0);
280 if (shift < 64 && (b & 0x40) != 0)
281 ret |= (-1 << shift);
287 _dwarf_write_sleb128(uint8_t *data, uint8_t *end, int64_t val)
298 if ((val == 0 && (*p & 0x40) == 0) ||
299 (val == -1 && (*p & 0x40) != 0)) {
310 _dwarf_write_sleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
311 int64_t val, Dwarf_Error *error)
317 while ((len = _dwarf_write_sleb128(*block + *offsetp, *block + *size,
320 *block = realloc(*block, (size_t) *size);
321 if (*block == NULL) {
322 DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
323 return (DW_DLE_MEMORY);
329 return (DW_DLE_NONE);
333 _dwarf_read_uleb128(uint8_t *data, uint64_t *offsetp)
340 src = data + *offsetp;
344 ret |= ((b & 0x7f) << shift);
347 } while ((b & 0x80) != 0);
353 _dwarf_write_uleb128(uint8_t *data, uint8_t *end, uint64_t val)
373 _dwarf_write_uleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
374 uint64_t val, Dwarf_Error *error)
380 while ((len = _dwarf_write_uleb128(*block + *offsetp, *block + *size,
383 *block = realloc(*block, (size_t) *size);
384 if (*block == NULL) {
385 DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
386 return (DW_DLE_MEMORY);
392 return (DW_DLE_NONE);
396 _dwarf_decode_sleb128(uint8_t **dp)
406 ret |= ((b & 0x7f) << shift);
408 } while ((b & 0x80) != 0);
410 if (shift < 64 && (b & 0x40) != 0)
411 ret |= (-1 << shift);
419 _dwarf_decode_uleb128(uint8_t **dp)
429 ret |= ((b & 0x7f) << shift);
431 } while ((b & 0x80) != 0);
439 _dwarf_read_string(void *data, Dwarf_Unsigned size, uint64_t *offsetp)
443 ret = src = (char *) data + *offsetp;
445 while (*src != '\0' && *offsetp < size) {
450 if (*src == '\0' && *offsetp < size)
457 _dwarf_write_string(void *data, uint64_t *offsetp, char *string)
461 dst = (char *) data + *offsetp;
463 (*offsetp) += strlen(string) + 1;
467 _dwarf_write_string_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
468 char *string, Dwarf_Error *error)
474 len = strlen(string) + 1;
475 while (*offsetp + len > *size) {
477 *block = realloc(*block, (size_t) *size);
478 if (*block == NULL) {
479 DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
480 return (DW_DLE_MEMORY);
484 _dwarf_write_string(*block, offsetp, string);
486 return (DW_DLE_NONE);
490 _dwarf_read_block(void *data, uint64_t *offsetp, uint64_t length)
494 ret = src = (uint8_t *) data + *offsetp;
496 (*offsetp) += length;
502 _dwarf_write_block(void *data, uint64_t *offsetp, uint8_t *blk,
507 dst = (uint8_t *) data + *offsetp;
508 memcpy(dst, blk, length);
509 (*offsetp) += length;
513 _dwarf_write_block_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
514 uint8_t *blk, uint64_t length, Dwarf_Error *error)
519 while (*offsetp + length > *size) {
521 *block = realloc(*block, (size_t) *size);
522 if (*block == NULL) {
523 DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
524 return (DW_DLE_MEMORY);
528 _dwarf_write_block(*block, offsetp, blk, length);
530 return (DW_DLE_NONE);
534 _dwarf_write_padding(void *data, uint64_t *offsetp, uint8_t byte,
539 dst = (uint8_t *) data + *offsetp;
540 memset(dst, byte, length);
541 (*offsetp) += length;
545 _dwarf_write_padding_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
546 uint8_t byte, uint64_t cnt, Dwarf_Error *error)
550 while (*offsetp + cnt > *size) {
552 *block = realloc(*block, (size_t) *size);
553 if (*block == NULL) {
554 DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
555 return (DW_DLE_MEMORY);
559 _dwarf_write_padding(*block, offsetp, byte, cnt);
561 return (DW_DLE_NONE);