aboutsummaryrefslogtreecommitdiff
path: root/libdwarf/libdwarf_loclist.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdwarf/libdwarf_loclist.c')
-rw-r--r--libdwarf/libdwarf_loclist.c131
1 files changed, 36 insertions, 95 deletions
diff --git a/libdwarf/libdwarf_loclist.c b/libdwarf/libdwarf_loclist.c
index 8b599868d00d..bb3e39f6c899 100644
--- a/libdwarf/libdwarf_loclist.c
+++ b/libdwarf/libdwarf_loclist.c
@@ -26,11 +26,11 @@
#include "_libdwarf.h"
-ELFTC_VCSID("$Id: libdwarf_loclist.c 2972 2013-12-23 06:46:04Z kaiwang27 $");
+ELFTC_VCSID("$Id: libdwarf_loclist.c 3061 2014-06-02 00:42:41Z kaiwang27 $");
static int
_dwarf_loclist_add_locdesc(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds,
- uint64_t *off, Dwarf_Locdesc **ld, uint64_t *ldlen,
+ Dwarf_Unsigned *off, Dwarf_Locdesc **ld, Dwarf_Signed *ldlen,
Dwarf_Unsigned *total_len, Dwarf_Error *error)
{
uint64_t start, end;
@@ -75,6 +75,7 @@ _dwarf_loclist_add_locdesc(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds,
if (ld != NULL) {
ret = _dwarf_loc_fill_locdesc(dbg, ld[i],
ds->ds_data + *off, len, cu->cu_pointer_size,
+ cu->cu_length_size == 4 ? 4 : 8, cu->cu_version,
error);
if (ret != DW_DLE_NONE)
return (ret);
@@ -91,134 +92,74 @@ _dwarf_loclist_add_locdesc(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Section *ds,
int
_dwarf_loclist_find(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t lloff,
- Dwarf_Loclist *ret_ll, Dwarf_Error *error)
-{
- Dwarf_Loclist ll;
- int ret;
-
- assert(ret_ll != NULL);
- ret = DW_DLE_NONE;
-
- TAILQ_FOREACH(ll, &dbg->dbg_loclist, ll_next)
- if (ll->ll_offset == lloff)
- break;
-
- if (ll == NULL)
- ret = _dwarf_loclist_add(dbg, cu, lloff, ret_ll, error);
- else
- *ret_ll = ll;
-
- return (ret);
-}
-
-int
-_dwarf_loclist_add(Dwarf_Debug dbg, Dwarf_CU cu, uint64_t lloff,
- Dwarf_Loclist *ret_ll, Dwarf_Error *error)
+ Dwarf_Locdesc ***ret_llbuf, Dwarf_Signed *listlen,
+ Dwarf_Unsigned *entry_len, Dwarf_Error *error)
{
+ Dwarf_Locdesc **llbuf;
Dwarf_Section *ds;
- Dwarf_Loclist ll, tll;
- uint64_t ldlen;
+ Dwarf_Signed ldlen;
+ Dwarf_Unsigned off;
int i, ret;
- ret = DW_DLE_NONE;
-
if ((ds = _dwarf_find_section(dbg, ".debug_loc")) == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
return (DW_DLE_NO_ENTRY);
}
- if ((ll = malloc(sizeof(struct _Dwarf_Loclist))) == NULL) {
- DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
- return (DW_DLE_MEMORY);
+ if (lloff >= ds->ds_size) {
+ DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
+ return (DW_DLE_NO_ENTRY);
}
- ll->ll_offset = lloff;
-
/* Get the number of locdesc the first round. */
- ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &lloff, NULL, &ldlen,
+ off = lloff;
+ ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &off, NULL, &ldlen,
NULL, error);
if (ret != DW_DLE_NONE)
- goto fail_cleanup;
+ return (ret);
+
+ if (ldlen == 0)
+ return (DW_DLE_NO_ENTRY);
/*
* Dwarf_Locdesc list memory is allocated in this way (one more level
* of indirect) to make the loclist API be compatible with SGI libdwarf.
*/
- ll->ll_ldlen = ldlen;
- if (ldlen != 0) {
- if ((ll->ll_ldlist = calloc(ldlen, sizeof(Dwarf_Locdesc *))) ==
- NULL) {
+ if ((llbuf = calloc(ldlen, sizeof(Dwarf_Locdesc *))) == NULL) {
+ DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
+ return (DW_DLE_MEMORY);
+ }
+ for (i = 0; i < ldlen; i++) {
+ if ((llbuf[i] = calloc(1, sizeof(Dwarf_Locdesc))) == NULL) {
DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
ret = DW_DLE_MEMORY;
goto fail_cleanup;
}
- for (i = 0; (uint64_t) i < ldlen; i++) {
- if ((ll->ll_ldlist[i] =
- calloc(1, sizeof(Dwarf_Locdesc))) == NULL) {
- DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
- ret = DW_DLE_MEMORY;
- goto fail_cleanup;
- }
- }
- } else
- ll->ll_ldlist = NULL;
+ }
- lloff = ll->ll_offset;
+ off = lloff;
/* Fill in locdesc. */
- ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &lloff, ll->ll_ldlist,
- NULL, &ll->ll_length, error);
+ ret = _dwarf_loclist_add_locdesc(dbg, cu, ds, &off, llbuf, NULL,
+ entry_len, error);
if (ret != DW_DLE_NONE)
goto fail_cleanup;
- /* Insert to the queue. Sort by offset. */
- TAILQ_FOREACH(tll, &dbg->dbg_loclist, ll_next)
- if (tll->ll_offset > ll->ll_offset) {
- TAILQ_INSERT_BEFORE(tll, ll, ll_next);
- break;
- }
-
- if (tll == NULL)
- TAILQ_INSERT_TAIL(&dbg->dbg_loclist, ll, ll_next);
+ *ret_llbuf = llbuf;
+ *listlen = ldlen;
- *ret_ll = ll;
return (DW_DLE_NONE);
fail_cleanup:
- _dwarf_loclist_free(ll);
-
- return (ret);
-}
-
-void
-_dwarf_loclist_free(Dwarf_Loclist ll)
-{
- int i;
-
- if (ll == NULL)
- return;
-
- if (ll->ll_ldlist != NULL) {
- for (i = 0; i < ll->ll_ldlen; i++) {
- if (ll->ll_ldlist[i]->ld_s)
- free(ll->ll_ldlist[i]->ld_s);
- free(ll->ll_ldlist[i]);
+ if (llbuf != NULL) {
+ for (i = 0; i < ldlen; i++) {
+ if (llbuf[i]->ld_s)
+ free(llbuf[i]->ld_s);
+ free(llbuf[i]);
}
- free(ll->ll_ldlist);
+ free(llbuf);
}
- free(ll);
-}
-void
-_dwarf_loclist_cleanup(Dwarf_Debug dbg)
-{
- Dwarf_Loclist ll, tll;
-
- assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ);
-
- TAILQ_FOREACH_SAFE(ll, &dbg->dbg_loclist, ll_next, tll) {
- TAILQ_REMOVE(&dbg->dbg_loclist, ll, ll_next);
- _dwarf_loclist_free(ll);
- }
+ return (ret);
}