summaryrefslogtreecommitdiffstats
path: root/rtemstoolkit/elftoolchain/libdwarf/libdwarf_ranges.c
diff options
context:
space:
mode:
Diffstat (limited to 'rtemstoolkit/elftoolchain/libdwarf/libdwarf_ranges.c')
-rw-r--r--rtemstoolkit/elftoolchain/libdwarf/libdwarf_ranges.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/rtemstoolkit/elftoolchain/libdwarf/libdwarf_ranges.c b/rtemstoolkit/elftoolchain/libdwarf/libdwarf_ranges.c
new file mode 100644
index 0000000..3396bb9
--- /dev/null
+++ b/rtemstoolkit/elftoolchain/libdwarf/libdwarf_ranges.c
@@ -0,0 +1,152 @@
+/*-
+ * Copyright (c) 2009 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_ranges.c 2972 2013-12-23 06:46:04Z kaiwang27 $");
+
+static int
+_dwarf_ranges_parse(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds,
+ uint64_t off, Dwarf_Ranges *rg, Dwarf_Unsigned *cnt)
+{
+ Dwarf_Unsigned start, end;
+ int i;
+
+ i = 0;
+ while (off < ds->ds_size) {
+
+ start = dbg->read(ds->ds_data, &off, cu->cu_pointer_size);
+ end = dbg->read(ds->ds_data, &off, cu->cu_pointer_size);
+
+ if (rg != NULL) {
+ rg[i].dwr_addr1 = start;
+ rg[i].dwr_addr2 = end;
+ if (start == 0 && end == 0)
+ rg[i].dwr_type = DW_RANGES_END;
+ else if ((start == ~0U && cu->cu_pointer_size == 4) ||
+ (start == ~0ULL && cu->cu_pointer_size == 8))
+ rg[i].dwr_type = DW_RANGES_ADDRESS_SELECTION;
+ else
+ rg[i].dwr_type = DW_RANGES_ENTRY;
+ }
+
+ i++;
+
+ if (start == 0 && end == 0)
+ break;
+ }
+
+ if (cnt != NULL)
+ *cnt = i;
+
+ return (DW_DLE_NONE);
+}
+
+int
+_dwarf_ranges_find(Dwarf_Debug dbg, uint64_t off, Dwarf_Rangelist *ret_rl)
+{
+ Dwarf_Rangelist rl;
+
+ STAILQ_FOREACH(rl, &dbg->dbg_rllist, rl_next)
+ if (rl->rl_offset == off)
+ break;
+
+ if (rl == NULL)
+ return (DW_DLE_NO_ENTRY);
+
+ if (ret_rl != NULL)
+ *ret_rl = rl;
+
+ return (DW_DLE_NONE);
+}
+
+void
+_dwarf_ranges_cleanup(Dwarf_Debug dbg)
+{
+ Dwarf_Rangelist rl, trl;
+
+ if (STAILQ_EMPTY(&dbg->dbg_rllist))
+ return;
+
+ STAILQ_FOREACH_SAFE(rl, &dbg->dbg_rllist, rl_next, trl) {
+ STAILQ_REMOVE(&dbg->dbg_rllist, rl, _Dwarf_Rangelist, rl_next);
+ if (rl->rl_rgarray)
+ free(rl->rl_rgarray);
+ free(rl);
+ }
+}
+
+int
+_dwarf_ranges_add(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t off,
+ Dwarf_Rangelist *ret_rl, Dwarf_Error *error)
+{
+ Dwarf_Section *ds;
+ Dwarf_Rangelist rl;
+ Dwarf_Unsigned cnt;
+ int ret;
+
+ if ((ds = _dwarf_find_section(dbg, ".debug_ranges")) == NULL) {
+ DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
+ return (DW_DLE_NO_ENTRY);
+ }
+
+ if ((rl = malloc(sizeof(struct _Dwarf_Rangelist))) == NULL) {
+ DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
+ return (DW_DLE_MEMORY);
+ }
+
+ rl->rl_offset = off;
+
+ ret = _dwarf_ranges_parse(dbg, cu, ds, off, NULL, &cnt);
+ if (ret != DW_DLE_NONE) {
+ free(rl);
+ return (ret);
+ }
+
+ rl->rl_rglen = cnt;
+ if (cnt != 0) {
+ if ((rl->rl_rgarray = calloc(cnt, sizeof(Dwarf_Ranges))) ==
+ NULL) {
+ free(rl);
+ DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
+ return (DW_DLE_MEMORY);
+ }
+
+ ret = _dwarf_ranges_parse(dbg, cu, ds, off, rl->rl_rgarray,
+ NULL);
+ if (ret != DW_DLE_NONE) {
+ free(rl->rl_rgarray);
+ free(rl);
+ return (ret);
+ }
+ } else
+ rl->rl_rgarray = NULL;
+
+ STAILQ_INSERT_TAIL(&dbg->dbg_rllist, rl, rl_next);
+ *ret_rl = rl;
+
+ return (DW_DLE_NONE);
+}