summaryrefslogtreecommitdiffstats
path: root/rtemstoolkit/elftoolchain/libdwarf/libdwarf_rw.c
diff options
context:
space:
mode:
Diffstat (limited to 'rtemstoolkit/elftoolchain/libdwarf/libdwarf_rw.c')
-rw-r--r--rtemstoolkit/elftoolchain/libdwarf/libdwarf_rw.c574
1 files changed, 574 insertions, 0 deletions
diff --git a/rtemstoolkit/elftoolchain/libdwarf/libdwarf_rw.c b/rtemstoolkit/elftoolchain/libdwarf/libdwarf_rw.c
new file mode 100644
index 0000000..f0286d5
--- /dev/null
+++ b/rtemstoolkit/elftoolchain/libdwarf/libdwarf_rw.c
@@ -0,0 +1,574 @@
+/*-
+ * Copyright (c) 2007 John Birrell (jb@freebsd.org)
+ * Copyright (c) 2010 Kai Wang
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "_libdwarf.h"
+
+ELFTC_VCSID("$Id: libdwarf_rw.c 3286 2015-12-31 16:45:46Z emaste $");
+
+uint64_t
+_dwarf_read_lsb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
+{
+ uint64_t ret;
+ uint8_t *src;
+
+ src = data + *offsetp;
+
+ ret = 0;
+ switch (bytes_to_read) {
+ case 8:
+ ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
+ ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
+ /* FALLTHROUGH */
+ case 4:
+ ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
+ /* FALLTHROUGH */
+ case 2:
+ ret |= ((uint64_t) src[1]) << 8;
+ /* FALLTHROUGH */
+ case 1:
+ ret |= src[0];
+ break;
+ default:
+ return (0);
+ }
+
+ *offsetp += bytes_to_read;
+
+ return (ret);
+}
+
+uint64_t
+_dwarf_decode_lsb(uint8_t **data, int bytes_to_read)
+{
+ uint64_t ret;
+ uint8_t *src;
+
+ src = *data;
+
+ ret = 0;
+ switch (bytes_to_read) {
+ case 8:
+ ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
+ ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
+ /* FALLTHROUGH */
+ case 4:
+ ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
+ /* FALLTHROUGH */
+ case 2:
+ ret |= ((uint64_t) src[1]) << 8;
+ /* FALLTHROUGH */
+ case 1:
+ ret |= src[0];
+ break;
+ default:
+ return (0);
+ }
+
+ *data += bytes_to_read;
+
+ return (ret);
+}
+
+uint64_t
+_dwarf_read_msb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
+{
+ uint64_t ret;
+ uint8_t *src;
+
+ src = data + *offsetp;
+
+ switch (bytes_to_read) {
+ case 1:
+ ret = src[0];
+ break;
+ case 2:
+ ret = src[1] | ((uint64_t) src[0]) << 8;
+ break;
+ case 4:
+ ret = src[3] | ((uint64_t) src[2]) << 8;
+ ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
+ break;
+ case 8:
+ ret = src[7] | ((uint64_t) src[6]) << 8;
+ ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
+ ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
+ ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
+ break;
+ default:
+ return (0);
+ }
+
+ *offsetp += bytes_to_read;
+
+ return (ret);
+}
+
+uint64_t
+_dwarf_decode_msb(uint8_t **data, int bytes_to_read)
+{
+ uint64_t ret;
+ uint8_t *src;
+
+ src = *data;
+
+ ret = 0;
+ switch (bytes_to_read) {
+ case 1:
+ ret = src[0];
+ break;
+ case 2:
+ ret = src[1] | ((uint64_t) src[0]) << 8;
+ break;
+ case 4:
+ ret = src[3] | ((uint64_t) src[2]) << 8;
+ ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
+ break;
+ case 8:
+ ret = src[7] | ((uint64_t) src[6]) << 8;
+ ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
+ ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
+ ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
+ break;
+ default:
+ return (0);
+ break;
+ }
+
+ *data += bytes_to_read;
+
+ return (ret);
+}
+
+void
+_dwarf_write_lsb(uint8_t *data, uint64_t *offsetp, uint64_t value,
+ int bytes_to_write)
+{
+ uint8_t *dst;
+
+ dst = data + *offsetp;
+
+ switch (bytes_to_write) {
+ case 8:
+ dst[7] = (value >> 56) & 0xff;
+ dst[6] = (value >> 48) & 0xff;
+ dst[5] = (value >> 40) & 0xff;
+ dst[4] = (value >> 32) & 0xff;
+ /* FALLTHROUGH */
+ case 4:
+ dst[3] = (value >> 24) & 0xff;
+ dst[2] = (value >> 16) & 0xff;
+ /* FALLTHROUGH */
+ case 2:
+ dst[1] = (value >> 8) & 0xff;
+ /* FALLTHROUGH */
+ case 1:
+ dst[0] = value & 0xff;
+ break;
+ default:
+ return;
+ }
+
+ *offsetp += bytes_to_write;
+}
+
+int
+_dwarf_write_lsb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
+ uint64_t value, int bytes_to_write, Dwarf_Error *error)
+{
+
+ assert(*size > 0);
+
+ while (*offsetp + bytes_to_write > *size) {
+ *size *= 2;
+ *block = realloc(*block, (size_t) *size);
+ if (*block == NULL) {
+ DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
+ return (DW_DLE_MEMORY);
+ }
+ }
+
+ _dwarf_write_lsb(*block, offsetp, value, bytes_to_write);
+
+ return (DW_DLE_NONE);
+}
+
+void
+_dwarf_write_msb(uint8_t *data, uint64_t *offsetp, uint64_t value,
+ int bytes_to_write)
+{
+ uint8_t *dst;
+
+ dst = data + *offsetp;
+
+ switch (bytes_to_write) {
+ case 8:
+ dst[7] = value & 0xff;
+ dst[6] = (value >> 8) & 0xff;
+ dst[5] = (value >> 16) & 0xff;
+ dst[4] = (value >> 24) & 0xff;
+ value >>= 32;
+ /* FALLTHROUGH */
+ case 4:
+ dst[3] = value & 0xff;
+ dst[2] = (value >> 8) & 0xff;
+ value >>= 16;
+ /* FALLTHROUGH */
+ case 2:
+ dst[1] = value & 0xff;
+ value >>= 8;
+ /* FALLTHROUGH */
+ case 1:
+ dst[0] = value & 0xff;
+ break;
+ default:
+ return;
+ }
+
+ *offsetp += bytes_to_write;
+}
+
+int
+_dwarf_write_msb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
+ uint64_t value, int bytes_to_write, Dwarf_Error *error)
+{
+
+ assert(*size > 0);
+
+ while (*offsetp + bytes_to_write > *size) {
+ *size *= 2;
+ *block = realloc(*block, (size_t) *size);
+ if (*block == NULL) {
+ DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
+ return (DW_DLE_MEMORY);
+ }
+ }
+
+ _dwarf_write_msb(*block, offsetp, value, bytes_to_write);
+
+ return (DW_DLE_NONE);
+}
+
+int64_t
+_dwarf_read_sleb128(uint8_t *data, uint64_t *offsetp)
+{
+ int64_t ret = 0;
+ uint8_t b;
+ int shift = 0;
+ uint8_t *src;
+
+ src = data + *offsetp;
+
+ do {
+ b = *src++;
+ ret |= ((b & 0x7f) << shift);
+ (*offsetp)++;
+ shift += 7;
+ } while ((b & 0x80) != 0);
+
+ if (shift < 64 && (b & 0x40) != 0)
+ ret |= (-1 << shift);
+
+ return (ret);
+}
+
+int
+_dwarf_write_sleb128(uint8_t *data, uint8_t *end, int64_t val)
+{
+ uint8_t *p;
+
+ p = data;
+
+ for (;;) {
+ if (p >= end)
+ return (-1);
+ *p = val & 0x7f;
+ val >>= 7;
+ if ((val == 0 && (*p & 0x40) == 0) ||
+ (val == -1 && (*p & 0x40) != 0)) {
+ p++;
+ break;
+ }
+ *p++ |= 0x80;
+ }
+
+ return (p - data);
+}
+
+int
+_dwarf_write_sleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
+ int64_t val, Dwarf_Error *error)
+{
+ int len;
+
+ assert(*size > 0);
+
+ while ((len = _dwarf_write_sleb128(*block + *offsetp, *block + *size,
+ val)) < 0) {
+ *size *= 2;
+ *block = realloc(*block, (size_t) *size);
+ if (*block == NULL) {
+ DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
+ return (DW_DLE_MEMORY);
+ }
+ }
+
+ *offsetp += len;
+
+ return (DW_DLE_NONE);
+}
+
+uint64_t
+_dwarf_read_uleb128(uint8_t *data, uint64_t *offsetp)
+{
+ uint64_t ret = 0;
+ uint8_t b;
+ int shift = 0;
+ uint8_t *src;
+
+ src = data + *offsetp;
+
+ do {
+ b = *src++;
+ ret |= ((b & 0x7f) << shift);
+ (*offsetp)++;
+ shift += 7;
+ } while ((b & 0x80) != 0);
+
+ return (ret);
+}
+
+int
+_dwarf_write_uleb128(uint8_t *data, uint8_t *end, uint64_t val)
+{
+ uint8_t *p;
+
+ p = data;
+
+ do {
+ if (p >= end)
+ return (-1);
+ *p = val & 0x7f;
+ val >>= 7;
+ if (val > 0)
+ *p |= 0x80;
+ p++;
+ } while (val > 0);
+
+ return (p - data);
+}
+
+int
+_dwarf_write_uleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
+ uint64_t val, Dwarf_Error *error)
+{
+ int len;
+
+ assert(*size > 0);
+
+ while ((len = _dwarf_write_uleb128(*block + *offsetp, *block + *size,
+ val)) < 0) {
+ *size *= 2;
+ *block = realloc(*block, (size_t) *size);
+ if (*block == NULL) {
+ DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
+ return (DW_DLE_MEMORY);
+ }
+ }
+
+ *offsetp += len;
+
+ return (DW_DLE_NONE);
+}
+
+int64_t
+_dwarf_decode_sleb128(uint8_t **dp)
+{
+ int64_t ret = 0;
+ uint8_t b;
+ int shift = 0;
+
+ uint8_t *src = *dp;
+
+ do {
+ b = *src++;
+ ret |= ((b & 0x7f) << shift);
+ shift += 7;
+ } while ((b & 0x80) != 0);
+
+ if (shift < 64 && (b & 0x40) != 0)
+ ret |= (-1 << shift);
+
+ *dp = src;
+
+ return (ret);
+}
+
+uint64_t
+_dwarf_decode_uleb128(uint8_t **dp)
+{
+ uint64_t ret = 0;
+ uint8_t b;
+ int shift = 0;
+
+ uint8_t *src = *dp;
+
+ do {
+ b = *src++;
+ ret |= ((b & 0x7f) << shift);
+ shift += 7;
+ } while ((b & 0x80) != 0);
+
+ *dp = src;
+
+ return (ret);
+}
+
+char *
+_dwarf_read_string(void *data, Dwarf_Unsigned size, uint64_t *offsetp)
+{
+ char *ret, *src;
+
+ ret = src = (char *) data + *offsetp;
+
+ while (*src != '\0' && *offsetp < size) {
+ src++;
+ (*offsetp)++;
+ }
+
+ if (*src == '\0' && *offsetp < size)
+ (*offsetp)++;
+
+ return (ret);
+}
+
+void
+_dwarf_write_string(void *data, uint64_t *offsetp, char *string)
+{
+ char *dst;
+
+ dst = (char *) data + *offsetp;
+ strcpy(dst, string);
+ (*offsetp) += strlen(string) + 1;
+}
+
+int
+_dwarf_write_string_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
+ char *string, Dwarf_Error *error)
+{
+ size_t len;
+
+ assert(*size > 0);
+
+ len = strlen(string) + 1;
+ while (*offsetp + len > *size) {
+ *size *= 2;
+ *block = realloc(*block, (size_t) *size);
+ if (*block == NULL) {
+ DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
+ return (DW_DLE_MEMORY);
+ }
+ }
+
+ _dwarf_write_string(*block, offsetp, string);
+
+ return (DW_DLE_NONE);
+}
+
+uint8_t *
+_dwarf_read_block(void *data, uint64_t *offsetp, uint64_t length)
+{
+ uint8_t *ret, *src;
+
+ ret = src = (uint8_t *) data + *offsetp;
+
+ (*offsetp) += length;
+
+ return (ret);
+}
+
+void
+_dwarf_write_block(void *data, uint64_t *offsetp, uint8_t *blk,
+ uint64_t length)
+{
+ uint8_t *dst;
+
+ dst = (uint8_t *) data + *offsetp;
+ memcpy(dst, blk, length);
+ (*offsetp) += length;
+}
+
+int
+_dwarf_write_block_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
+ uint8_t *blk, uint64_t length, Dwarf_Error *error)
+{
+
+ assert(*size > 0);
+
+ while (*offsetp + length > *size) {
+ *size *= 2;
+ *block = realloc(*block, (size_t) *size);
+ if (*block == NULL) {
+ DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
+ return (DW_DLE_MEMORY);
+ }
+ }
+
+ _dwarf_write_block(*block, offsetp, blk, length);
+
+ return (DW_DLE_NONE);
+}
+
+void
+_dwarf_write_padding(void *data, uint64_t *offsetp, uint8_t byte,
+ uint64_t length)
+{
+ uint8_t *dst;
+
+ dst = (uint8_t *) data + *offsetp;
+ memset(dst, byte, length);
+ (*offsetp) += length;
+}
+
+int
+_dwarf_write_padding_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
+ uint8_t byte, uint64_t cnt, Dwarf_Error *error)
+{
+ assert(*size > 0);
+
+ while (*offsetp + cnt > *size) {
+ *size *= 2;
+ *block = realloc(*block, (size_t) *size);
+ if (*block == NULL) {
+ DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
+ return (DW_DLE_MEMORY);
+ }
+ }
+
+ _dwarf_write_padding(*block, offsetp, byte, cnt);
+
+ return (DW_DLE_NONE);
+}