Home | History | Annotate | Line # | Download | only in libdwarf
      1 /*	$NetBSD: libdwarf_rw.c,v 1.5 2024/03/03 17:37:32 christos 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.5 2024/03/03 17:37:32 christos Exp $");
     33 ELFTC_VCSID("Id: libdwarf_rw.c 4007 2023-10-12 18:17:02Z 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 		/* FALLTHROUGH */
     49 	case 4:
     50 		ret |= ((uint64_t) src[3]) << 24;
     51 		/* FALLTHROUGH */
     52 	case 3:
     53 		ret |= ((uint64_t) src[2]) << 16;
     54 		/* FALLTHROUGH */
     55 	case 2:
     56 		ret |= ((uint64_t) src[1]) << 8;
     57 		/* FALLTHROUGH */
     58 	case 1:
     59 		ret |= src[0];
     60 		break;
     61 	default:
     62 		return (0);
     63 	}
     64 
     65 	*offsetp += bytes_to_read;
     66 
     67 	return (ret);
     68 }
     69 
     70 uint64_t
     71 _dwarf_decode_lsb(uint8_t **data, int bytes_to_read)
     72 {
     73 	uint64_t ret;
     74 	uint8_t *src;
     75 
     76 	src = *data;
     77 
     78 	ret = 0;
     79 	switch (bytes_to_read) {
     80 	case 8:
     81 		ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
     82 		ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
     83 		/* FALLTHROUGH */
     84 	case 4:
     85 		ret |= ((uint64_t) src[3]) << 24;
     86 		/* FALLTHROUGH */
     87 	case 3:
     88 		ret |= ((uint64_t) src[2]) << 16;
     89 		/* FALLTHROUGH */
     90 	case 2:
     91 		ret |= ((uint64_t) src[1]) << 8;
     92 		/* FALLTHROUGH */
     93 	case 1:
     94 		ret |= src[0];
     95 		break;
     96 	default:
     97 		return (0);
     98 	}
     99 
    100 	*data += bytes_to_read;
    101 
    102 	return (ret);
    103 }
    104 
    105 uint64_t
    106 _dwarf_read_msb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
    107 {
    108 	uint64_t ret;
    109 	uint8_t *src;
    110 
    111 	src = data + *offsetp;
    112 
    113 	switch (bytes_to_read) {
    114 	case 1:
    115 		ret = src[0];
    116 		break;
    117 	case 2:
    118 		ret = src[1] | ((uint64_t) src[0]) << 8;
    119 		break;
    120 	case 3:
    121 		ret = src[2] | ((uint64_t) src[1]) << 8;
    122 		ret |= ((uint64_t) src[0]) << 16;
    123 		break;
    124 	case 4:
    125 		ret = src[3] | ((uint64_t) src[2]) << 8;
    126 		ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
    127 		break;
    128 	case 8:
    129 		ret = src[7] | ((uint64_t) src[6]) << 8;
    130 		ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
    131 		ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
    132 		ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
    133 		break;
    134 	default:
    135 		return (0);
    136 	}
    137 
    138 	*offsetp += bytes_to_read;
    139 
    140 	return (ret);
    141 }
    142 
    143 uint64_t
    144 _dwarf_decode_msb(uint8_t **data, int bytes_to_read)
    145 {
    146 	uint64_t ret;
    147 	uint8_t *src;
    148 
    149 	src = *data;
    150 
    151 	ret = 0;
    152 	switch (bytes_to_read) {
    153 	case 1:
    154 		ret = src[0];
    155 		break;
    156 	case 2:
    157 		ret = src[1] | ((uint64_t) src[0]) << 8;
    158 		break;
    159 	case 3:
    160 		ret = src[2] | ((uint64_t) src[1]) << 8;
    161 		ret |= ((uint64_t) src[0]) << 16;
    162 		break;
    163 	case 4:
    164 		ret = src[3] | ((uint64_t) src[2]) << 8;
    165 		ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
    166 		break;
    167 	case 8:
    168 		ret = src[7] | ((uint64_t) src[6]) << 8;
    169 		ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
    170 		ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
    171 		ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
    172 		break;
    173 	default:
    174 		return (0);
    175 	}
    176 
    177 	*data += bytes_to_read;
    178 
    179 	return (ret);
    180 }
    181 
    182 void
    183 _dwarf_write_lsb(uint8_t *data, uint64_t *offsetp, uint64_t value,
    184     int bytes_to_write)
    185 {
    186 	uint8_t *dst;
    187 
    188 	dst = data + *offsetp;
    189 
    190 	switch (bytes_to_write) {
    191 	case 8:
    192 		dst[7] = (value >> 56) & 0xff;
    193 		dst[6] = (value >> 48) & 0xff;
    194 		dst[5] = (value >> 40) & 0xff;
    195 		dst[4] = (value >> 32) & 0xff;
    196 		/* FALLTHROUGH */
    197 	case 4:
    198 		dst[3] = (value >> 24) & 0xff;
    199 		dst[2] = (value >> 16) & 0xff;
    200 		/* FALLTHROUGH */
    201 	case 2:
    202 		dst[1] = (value >> 8) & 0xff;
    203 		/* FALLTHROUGH */
    204 	case 1:
    205 		dst[0] = value & 0xff;
    206 		break;
    207 	default:
    208 		return;
    209 	}
    210 
    211 	*offsetp += bytes_to_write;
    212 }
    213 
    214 int
    215 _dwarf_write_lsb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
    216     uint64_t value, int bytes_to_write, Dwarf_Error *error)
    217 {
    218 
    219 	assert(*size > 0);
    220 
    221 	while (*offsetp + bytes_to_write > *size) {
    222 		*size *= 2;
    223 		*block = realloc(*block, (size_t) *size);
    224 		if (*block == NULL) {
    225 			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
    226 			return (DW_DLE_MEMORY);
    227 		}
    228 	}
    229 
    230 	_dwarf_write_lsb(*block, offsetp, value, bytes_to_write);
    231 
    232 	return (DW_DLE_NONE);
    233 }
    234 
    235 void
    236 _dwarf_write_msb(uint8_t *data, uint64_t *offsetp, uint64_t value,
    237     int bytes_to_write)
    238 {
    239 	uint8_t *dst;
    240 
    241 	dst = data + *offsetp;
    242 
    243 	switch (bytes_to_write) {
    244 	case 8:
    245 		dst[7] = value & 0xff;
    246 		dst[6] = (value >> 8) & 0xff;
    247 		dst[5] = (value >> 16) & 0xff;
    248 		dst[4] = (value >> 24) & 0xff;
    249 		value >>= 32;
    250 		/* FALLTHROUGH */
    251 	case 4:
    252 		dst[3] = value & 0xff;
    253 		dst[2] = (value >> 8) & 0xff;
    254 		value >>= 16;
    255 		/* FALLTHROUGH */
    256 	case 2:
    257 		dst[1] = value & 0xff;
    258 		value >>= 8;
    259 		/* FALLTHROUGH */
    260 	case 1:
    261 		dst[0] = value & 0xff;
    262 		break;
    263 	default:
    264 		return;
    265 	}
    266 
    267 	*offsetp += bytes_to_write;
    268 }
    269 
    270 int
    271 _dwarf_write_msb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
    272     uint64_t value, int bytes_to_write, Dwarf_Error *error)
    273 {
    274 
    275 	assert(*size > 0);
    276 
    277 	while (*offsetp + bytes_to_write > *size) {
    278 		*size *= 2;
    279 		*block = realloc(*block, (size_t) *size);
    280 		if (*block == NULL) {
    281 			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
    282 			return (DW_DLE_MEMORY);
    283 		}
    284 	}
    285 
    286 	_dwarf_write_msb(*block, offsetp, value, bytes_to_write);
    287 
    288 	return (DW_DLE_NONE);
    289 }
    290 
    291 int64_t
    292 _dwarf_read_sleb128(uint8_t *data, uint64_t *offsetp)
    293 {
    294 	int64_t ret = 0;
    295 	uint8_t b;
    296 	int shift = 0;
    297 	uint8_t *src;
    298 
    299 	src = data + *offsetp;
    300 
    301 	do {
    302 		b = *src++;
    303 		ret |= ((b & 0x7f) << shift);
    304 		(*offsetp)++;
    305 		shift += 7;
    306 	} while ((b & 0x80) != 0);
    307 
    308 	if (shift < 64 && (b & 0x40) != 0)
    309 		ret |= (~0UL << shift);
    310 
    311 	return (ret);
    312 }
    313 
    314 int
    315 _dwarf_write_sleb128(uint8_t *data, uint8_t *end, int64_t val)
    316 {
    317 	uint8_t *p;
    318 
    319 	p = data;
    320 
    321 	for (;;) {
    322 		if (p >= end)
    323 			return (-1);
    324 		*p = val & 0x7f;
    325 		val >>= 7;
    326 		if ((val == 0 && (*p & 0x40) == 0) ||
    327 		    (val == -1 && (*p & 0x40) != 0)) {
    328 			p++;
    329 			break;
    330 		}
    331 		*p++ |= 0x80;
    332 	}
    333 
    334 	return (p - data);
    335 }
    336 
    337 int
    338 _dwarf_write_sleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
    339     int64_t val, Dwarf_Error *error)
    340 {
    341 	int len;
    342 
    343 	assert(*size > 0);
    344 
    345 	while ((len = _dwarf_write_sleb128(*block + *offsetp, *block + *size,
    346 	    val)) < 0) {
    347 		*size *= 2;
    348 		*block = realloc(*block, (size_t) *size);
    349 		if (*block == NULL) {
    350 			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
    351 			return (DW_DLE_MEMORY);
    352 		}
    353 	}
    354 
    355 	*offsetp += len;
    356 
    357 	return (DW_DLE_NONE);
    358 }
    359 
    360 uint64_t
    361 _dwarf_read_uleb128(uint8_t *data, uint64_t *offsetp)
    362 {
    363 	uint64_t ret = 0;
    364 	uint8_t b;
    365 	int shift = 0;
    366 	uint8_t *src;
    367 
    368 	src = data + *offsetp;
    369 
    370 	do {
    371 		b = *src++;
    372 		ret |= ((b & 0x7f) << shift);
    373 		(*offsetp)++;
    374 		shift += 7;
    375 	} while ((b & 0x80) != 0);
    376 
    377 	return (ret);
    378 }
    379 
    380 int
    381 _dwarf_write_uleb128(uint8_t *data, uint8_t *end, uint64_t val)
    382 {
    383 	uint8_t *p;
    384 
    385 	p = data;
    386 
    387 	do {
    388 		if (p >= end)
    389 			return (-1);
    390 		*p = val & 0x7f;
    391 		val >>= 7;
    392 		if (val > 0)
    393 			*p |= 0x80;
    394 		p++;
    395 	} while (val > 0);
    396 
    397 	return (p - data);
    398 }
    399 
    400 int
    401 _dwarf_write_uleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
    402     uint64_t val, Dwarf_Error *error)
    403 {
    404 	int len;
    405 
    406 	assert(*size > 0);
    407 
    408 	while ((len = _dwarf_write_uleb128(*block + *offsetp, *block + *size,
    409 	    val)) < 0) {
    410 		*size *= 2;
    411 		*block = realloc(*block, (size_t) *size);
    412 		if (*block == NULL) {
    413 			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
    414 			return (DW_DLE_MEMORY);
    415 		}
    416 	}
    417 
    418 	*offsetp += len;
    419 
    420 	return (DW_DLE_NONE);
    421 }
    422 
    423 int64_t
    424 _dwarf_decode_sleb128(uint8_t **dp)
    425 {
    426 	int64_t ret = 0;
    427 	uint8_t b;
    428 	int shift = 0;
    429 
    430 	uint8_t *src = *dp;
    431 
    432 	do {
    433 		b = *src++;
    434 		ret |= ((b & 0x7f) << shift);
    435 		shift += 7;
    436 	} while ((b & 0x80) != 0);
    437 
    438 	if (shift < 64 && (b & 0x40) != 0)
    439 		ret |= (~0UL << shift);
    440 
    441 	*dp = src;
    442 
    443 	return (ret);
    444 }
    445 
    446 uint64_t
    447 _dwarf_decode_uleb128(uint8_t **dp)
    448 {
    449 	uint64_t ret = 0;
    450 	uint8_t b;
    451 	int shift = 0;
    452 
    453 	uint8_t *src = *dp;
    454 
    455 	do {
    456 		b = *src++;
    457 		ret |= ((b & 0x7f) << shift);
    458 		shift += 7;
    459 	} while ((b & 0x80) != 0);
    460 
    461 	*dp = src;
    462 
    463 	return (ret);
    464 }
    465 
    466 char *
    467 _dwarf_read_string(void *data, Dwarf_Unsigned size, uint64_t *offsetp)
    468 {
    469 	char *ret, *src;
    470 
    471 	ret = src = (char *) data + *offsetp;
    472 
    473 	while (*src != '\0' && *offsetp < size) {
    474 		src++;
    475 		(*offsetp)++;
    476 	}
    477 
    478 	if (*src == '\0' && *offsetp < size)
    479 		(*offsetp)++;
    480 
    481 	return (ret);
    482 }
    483 
    484 void
    485 _dwarf_write_string(void *data, uint64_t *offsetp, char *string)
    486 {
    487 	char *dst;
    488 
    489 	dst = (char *) data + *offsetp;
    490 	strcpy(dst, string);
    491 	(*offsetp) += strlen(string) + 1;
    492 }
    493 
    494 int
    495 _dwarf_write_string_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
    496     char *string, Dwarf_Error *error)
    497 {
    498 	size_t len;
    499 
    500 	assert(*size > 0);
    501 
    502 	len = strlen(string) + 1;
    503 	while (*offsetp + len > *size) {
    504 		*size *= 2;
    505 		*block = realloc(*block, (size_t) *size);
    506 		if (*block == NULL) {
    507 			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
    508 			return (DW_DLE_MEMORY);
    509 		}
    510 	}
    511 
    512 	_dwarf_write_string(*block, offsetp, string);
    513 
    514 	return (DW_DLE_NONE);
    515 }
    516 
    517 uint8_t *
    518 _dwarf_read_block(void *data, uint64_t *offsetp, uint64_t length)
    519 {
    520 	uint8_t *ret, *src;
    521 
    522 	ret = src = (uint8_t *) data + *offsetp;
    523 
    524 	(*offsetp) += length;
    525 
    526 	return (ret);
    527 }
    528 
    529 void
    530 _dwarf_write_block(void *data, uint64_t *offsetp, uint8_t *blk,
    531     uint64_t length)
    532 {
    533 	uint8_t *dst;
    534 
    535 	dst = (uint8_t *) data + *offsetp;
    536 	memcpy(dst, blk, length);
    537 	(*offsetp) += length;
    538 }
    539 
    540 int
    541 _dwarf_write_block_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
    542     uint8_t *blk, uint64_t length, Dwarf_Error *error)
    543 {
    544 
    545 	assert(*size > 0);
    546 
    547 	while (*offsetp + length > *size) {
    548 		*size *= 2;
    549 		*block = realloc(*block, (size_t) *size);
    550 		if (*block == NULL) {
    551 			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
    552 			return (DW_DLE_MEMORY);
    553 		}
    554 	}
    555 
    556 	_dwarf_write_block(*block, offsetp, blk, length);
    557 
    558 	return (DW_DLE_NONE);
    559 }
    560 
    561 void
    562 _dwarf_write_padding(void *data, uint64_t *offsetp, uint8_t byte,
    563     uint64_t length)
    564 {
    565 	uint8_t *dst;
    566 
    567 	dst = (uint8_t *) data + *offsetp;
    568 	memset(dst, byte, length);
    569 	(*offsetp) += length;
    570 }
    571 
    572 int
    573 _dwarf_write_padding_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
    574     uint8_t byte, uint64_t cnt, Dwarf_Error *error)
    575 {
    576 	assert(*size > 0);
    577 
    578 	while (*offsetp + cnt > *size) {
    579 		*size *= 2;
    580 		*block = realloc(*block, (size_t) *size);
    581 		if (*block == NULL) {
    582 			DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
    583 			return (DW_DLE_MEMORY);
    584 		}
    585 	}
    586 
    587 	_dwarf_write_padding(*block, offsetp, byte, cnt);
    588 
    589 	return (DW_DLE_NONE);
    590 }
    591