Home | History | Annotate | Line # | Download | only in libdwarf
libdwarf_rw.c revision 1.2.8.2
      1 /*	$NetBSD: libdwarf_rw.c,v 1.2.8.2 2014/08/19 23:46:45 tls Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2007 John Birrell (jb (at) freebsd.org)
      5  * Copyright (c) 2010 Kai Wang
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     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.
     16  *
     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
     27  * SUCH DAMAGE.
     28  */
     29 
     30 #include "_libdwarf.h"
     31 
     32 __RCSID("$NetBSD: libdwarf_rw.c,v 1.2.8.2 2014/08/19 23:46:45 tls Exp $");
     33 ELFTC_VCSID("Id: libdwarf_rw.c 2952 2013-06-26 19:09:40Z kaiwang27 ");
     34 
     35 uint64_t
     36 _dwarf_read_lsb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
     37 {
     38 	uint64_t ret;
     39 	uint8_t *src;
     40 
     41 	src = data + *offsetp;
     42 
     43 	ret = 0;
     44 	switch (bytes_to_read) {
     45 	case 8:
     46 		ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
     47 		ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
     48 	case 4:
     49 		ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
     50 	case 2:
     51 		ret |= ((uint64_t) src[1]) << 8;
     52 	case 1:
     53 		ret |= src[0];
     54 		break;
     55 	default:
     56 		return (0);
     57 	}
     58 
     59 	*offsetp += bytes_to_read;
     60 
     61 	return (ret);
     62 }
     63 
     64 uint64_t
     65 _dwarf_decode_lsb(uint8_t **data, int bytes_to_read)
     66 {
     67 	uint64_t ret;
     68 	uint8_t *src;
     69 
     70 	src = *data;
     71 
     72 	ret = 0;
     73 	switch (bytes_to_read) {
     74 	case 8:
     75 		ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
     76 		ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
     77 	case 4:
     78 		ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
     79 	case 2:
     80 		ret |= ((uint64_t) src[1]) << 8;
     81 	case 1:
     82 		ret |= src[0];
     83 		break;
     84 	default:
     85 		return (0);
     86 	}
     87 
     88 	*data += bytes_to_read;
     89 
     90 	return (ret);
     91 }
     92 
     93 uint64_t
     94 _dwarf_read_msb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
     95 {
     96 	uint64_t ret;
     97 	uint8_t *src;
     98 
     99 	src = data + *offsetp;
    100 
    101 	switch (bytes_to_read) {
    102 	case 1:
    103 		ret = src[0];
    104 		break;
    105 	case 2:
    106 		ret = src[1] | ((uint64_t) src[0]) << 8;
    107 		break;
    108 	case 4:
    109 		ret = src[3] | ((uint64_t) src[2]) << 8;
    110 		ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
    111 		break;
    112 	case 8:
    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;
    117 		break;
    118 	default:
    119 		return (0);
    120 	}
    121 
    122 	*offsetp += bytes_to_read;
    123 
    124 	return (ret);
    125 }
    126 
    127 uint64_t
    128 _dwarf_decode_msb(uint8_t **data, int bytes_to_read)
    129 {
    130 	uint64_t ret;
    131 	uint8_t *src;
    132 
    133 	src = *data;
    134 
    135 	ret = 0;
    136 	switch (bytes_to_read) {
    137 	case 1:
    138 		ret = src[0];
    139 		break;
    140 	case 2:
    141 		ret = src[1] | ((uint64_t) src[0]) << 8;
    142 		break;
    143 	case 4:
    144 		ret = src[3] | ((uint64_t) src[2]) << 8;
    145 		ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
    146 		break;
    147 	case 8:
    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;
    152 		break;
    153 	default:
    154 		return (0);
    155 		break;
    156 	}
    157 
    158 	*data += bytes_to_read;
    159 
    160 	return (ret);
    161 }
    162 
    163 void
    164 _dwarf_write_lsb(uint8_t *data, uint64_t *offsetp, uint64_t value,
    165     int bytes_to_write)
    166 {
    167 	uint8_t *dst;
    168 
    169 	dst = data + *offsetp;
    170 
    171 	switch (bytes_to_write) {
    172 	case 8:
    173 		dst[7] = (value >> 56) & 0xff;
    174 		dst[6] = (value >> 48) & 0xff;
    175 		dst[5] = (value >> 40) & 0xff;
    176 		dst[4] = (value >> 32) & 0xff;
    177 	case 4:
    178 		dst[3] = (value >> 24) & 0xff;
    179 		dst[2] = (value >> 16) & 0xff;
    180 	case 2:
    181 		dst[1] = (value >> 8) & 0xff;
    182 	case 1:
    183 		dst[0] = value & 0xff;
    184 		break;
    185 	default:
    186 		return;
    187 	}
    188 
    189 	*offsetp += bytes_to_write;
    190 }
    191 
    192 int
    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)
    195 {
    196 
    197 	assert(*size > 0);
    198 
    199 	while (*offsetp + bytes_to_write > *size) {
    200 		*size *= 2;
    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);
    205 		}
    206 	}
    207 
    208 	_dwarf_write_lsb(*block, offsetp, value, bytes_to_write);
    209 
    210 	return (DW_DLE_NONE);
    211 }
    212 
    213 void
    214 _dwarf_write_msb(uint8_t *data, uint64_t *offsetp, uint64_t value,
    215     int bytes_to_write)
    216 {
    217 	uint8_t *dst;
    218 
    219 	dst = data + *offsetp;
    220 
    221 	switch (bytes_to_write) {
    222 	case 8:
    223 		dst[7] = value & 0xff;
    224 		dst[6] = (value >> 8) & 0xff;
    225 		dst[5] = (value >> 16) & 0xff;
    226 		dst[4] = (value >> 24) & 0xff;
    227 		value >>= 32;
    228 	case 4:
    229 		dst[3] = value & 0xff;
    230 		dst[2] = (value >> 8) & 0xff;
    231 		value >>= 16;
    232 	case 2:
    233 		dst[1] = value & 0xff;
    234 		value >>= 8;
    235 	case 1:
    236 		dst[0] = value & 0xff;
    237 		break;
    238 	default:
    239 		return;
    240 	}
    241 
    242 	*offsetp += bytes_to_write;
    243 }
    244 
    245 int
    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)
    248 {
    249 
    250 	assert(*size > 0);
    251 
    252 	while (*offsetp + bytes_to_write > *size) {
    253 		*size *= 2;
    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);
    258 		}
    259 	}
    260 
    261 	_dwarf_write_msb(*block, offsetp, value, bytes_to_write);
    262 
    263 	return (DW_DLE_NONE);
    264 }
    265 
    266 int64_t
    267 _dwarf_read_sleb128(uint8_t *data, uint64_t *offsetp)
    268 {
    269 	int64_t ret = 0;
    270 	uint8_t b;
    271 	int shift = 0;
    272 	uint8_t *src;
    273 
    274 	src = data + *offsetp;
    275 
    276 	do {
    277 		b = *src++;
    278 		ret |= ((b & 0x7f) << shift);
    279 		(*offsetp)++;
    280 		shift += 7;
    281 	} while ((b & 0x80) != 0);
    282 
    283 	if (shift < 64 && (b & 0x40) != 0)
    284 		ret |= (-1 << shift);
    285 
    286 	return (ret);
    287 }
    288 
    289 int
    290 _dwarf_write_sleb128(uint8_t *data, uint8_t *end, int64_t val)
    291 {
    292 	uint8_t *p;
    293 
    294 	p = data;
    295 
    296 	for (;;) {
    297 		if (p >= end)
    298 			return (-1);
    299 		*p = val & 0x7f;
    300 		val >>= 7;
    301 		if ((val == 0 && (*p & 0x40) == 0) ||
    302 		    (val == -1 && (*p & 0x40) != 0)) {
    303 			p++;
    304 			break;
    305 		}
    306 		*p++ |= 0x80;
    307 	}
    308 
    309 	return (p - data);
    310 }
    311 
    312 int
    313 _dwarf_write_sleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
    314     int64_t val, Dwarf_Error *error)
    315 {
    316 	int len;
    317 
    318 	assert(*size > 0);
    319 
    320 	while ((len = _dwarf_write_sleb128(*block + *offsetp, *block + *size,
    321 	    val)) < 0) {
    322 		*size *= 2;
    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);
    327 		}
    328 	}
    329 
    330 	*offsetp += len;
    331 
    332 	return (DW_DLE_NONE);
    333 }
    334 
    335 uint64_t
    336 _dwarf_read_uleb128(uint8_t *data, uint64_t *offsetp)
    337 {
    338 	uint64_t ret = 0;
    339 	uint8_t b;
    340 	int shift = 0;
    341 	uint8_t *src;
    342 
    343 	src = data + *offsetp;
    344 
    345 	do {
    346 		b = *src++;
    347 		ret |= ((b & 0x7f) << shift);
    348 		(*offsetp)++;
    349 		shift += 7;
    350 	} while ((b & 0x80) != 0);
    351 
    352 	return (ret);
    353 }
    354 
    355 int
    356 _dwarf_write_uleb128(uint8_t *data, uint8_t *end, uint64_t val)
    357 {
    358 	uint8_t *p;
    359 
    360 	p = data;
    361 
    362 	do {
    363 		if (p >= end)
    364 			return (-1);
    365 		*p = val & 0x7f;
    366 		val >>= 7;
    367 		if (val > 0)
    368 			*p |= 0x80;
    369 		p++;
    370 	} while (val > 0);
    371 
    372 	return (p - data);
    373 }
    374 
    375 int
    376 _dwarf_write_uleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
    377     uint64_t val, Dwarf_Error *error)
    378 {
    379 	int len;
    380 
    381 	assert(*size > 0);
    382 
    383 	while ((len = _dwarf_write_uleb128(*block + *offsetp, *block + *size,
    384 	    val)) < 0) {
    385 		*size *= 2;
    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);
    390 		}
    391 	}
    392 
    393 	*offsetp += len;
    394 
    395 	return (DW_DLE_NONE);
    396 }
    397 
    398 int64_t
    399 _dwarf_decode_sleb128(uint8_t **dp)
    400 {
    401 	int64_t ret = 0;
    402 	uint8_t b;
    403 	int shift = 0;
    404 
    405 	uint8_t *src = *dp;
    406 
    407 	do {
    408 		b = *src++;
    409 		ret |= ((b & 0x7f) << shift);
    410 		shift += 7;
    411 	} while ((b & 0x80) != 0);
    412 
    413 	if (shift < 64 && (b & 0x40) != 0)
    414 		ret |= (-1 << shift);
    415 
    416 	*dp = src;
    417 
    418 	return (ret);
    419 }
    420 
    421 uint64_t
    422 _dwarf_decode_uleb128(uint8_t **dp)
    423 {
    424 	uint64_t ret = 0;
    425 	uint8_t b;
    426 	int shift = 0;
    427 
    428 	uint8_t *src = *dp;
    429 
    430 	do {
    431 		b = *src++;
    432 		ret |= ((b & 0x7f) << shift);
    433 		shift += 7;
    434 	} while ((b & 0x80) != 0);
    435 
    436 	*dp = src;
    437 
    438 	return (ret);
    439 }
    440 
    441 char *
    442 _dwarf_read_string(void *data, Dwarf_Unsigned size, uint64_t *offsetp)
    443 {
    444 	char *ret, *src;
    445 
    446 	ret = src = (char *) data + *offsetp;
    447 
    448 	while (*src != '\0' && *offsetp < size) {
    449 		src++;
    450 		(*offsetp)++;
    451 	}
    452 
    453 	if (*src == '\0' && *offsetp < size)
    454 		(*offsetp)++;
    455 
    456 	return (ret);
    457 }
    458 
    459 void
    460 _dwarf_write_string(void *data, uint64_t *offsetp, char *string)
    461 {
    462 	char *dst;
    463 
    464 	dst = (char *) data + *offsetp;
    465 	strcpy(dst, string);
    466 	(*offsetp) += strlen(string) + 1;
    467 }
    468 
    469 int
    470 _dwarf_write_string_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
    471     char *string, Dwarf_Error *error)
    472 {
    473 	size_t len;
    474 
    475 	assert(*size > 0);
    476 
    477 	len = strlen(string) + 1;
    478 	while (*offsetp + len > *size) {
    479 		*size *= 2;
    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);
    484 		}
    485 	}
    486 
    487 	_dwarf_write_string(*block, offsetp, string);
    488 
    489 	return (DW_DLE_NONE);
    490 }
    491 
    492 uint8_t *
    493 _dwarf_read_block(void *data, uint64_t *offsetp, uint64_t length)
    494 {
    495 	uint8_t *ret, *src;
    496 
    497 	ret = src = (uint8_t *) data + *offsetp;
    498 
    499 	(*offsetp) += length;
    500 
    501 	return (ret);
    502 }
    503 
    504 void
    505 _dwarf_write_block(void *data, uint64_t *offsetp, uint8_t *blk,
    506     uint64_t length)
    507 {
    508 	uint8_t *dst;
    509 
    510 	dst = (uint8_t *) data + *offsetp;
    511 	memcpy(dst, blk, length);
    512 	(*offsetp) += length;
    513 }
    514 
    515 int
    516 _dwarf_write_block_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
    517     uint8_t *blk, uint64_t length, Dwarf_Error *error)
    518 {
    519 
    520 	assert(*size > 0);
    521 
    522 	while (*offsetp + length > *size) {
    523 		*size *= 2;
    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);
    528 		}
    529 	}
    530 
    531 	_dwarf_write_block(*block, offsetp, blk, length);
    532 
    533 	return (DW_DLE_NONE);
    534 }
    535 
    536 void
    537 _dwarf_write_padding(void *data, uint64_t *offsetp, uint8_t byte,
    538     uint64_t length)
    539 {
    540 	uint8_t *dst;
    541 
    542 	dst = (uint8_t *) data + *offsetp;
    543 	memset(dst, byte, length);
    544 	(*offsetp) += length;
    545 }
    546 
    547 int
    548 _dwarf_write_padding_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
    549     uint8_t byte, uint64_t cnt, Dwarf_Error *error)
    550 {
    551 	assert(*size > 0);
    552 
    553 	while (*offsetp + cnt > *size) {
    554 		*size *= 2;
    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);
    559 		}
    560 	}
    561 
    562 	_dwarf_write_padding(*block, offsetp, byte, cnt);
    563 
    564 	return (DW_DLE_NONE);
    565 }
    566