static Dwfl_Error
intern_cu (Dwfl_Module *mod, Dwarf_Off cuoff, struct dwfl_cu **result)
{
- struct Dwarf_CU dwkey;
- struct dwfl_cu key;
- key.die.cu = &dwkey;
- dwkey.offset_size = 0;
- dwkey.start = cuoff - (3 * 0 - 4 + 3);
- struct dwfl_cu **found = tsearch (&key, &mod->lazy_cu_root, &compare_cukey);
- if (unlikely (found == NULL))
- return DWFL_E_NOMEM;
-
- if (*found == &key || *found == NULL)
+ if (unlikely (cuoff + 4 >= mod->dw->sectiondata[IDX_debug_info]->d_size))
{
- if (unlikely (cuoff + 4 >= mod->dw->sectiondata[IDX_debug_info]->d_size))
+ if (likely (mod->lazycu == 1))
{
/* This is the EOF marker. Now we have interned all the CUs.
One increment in MOD->lazycu counts not having hit EOF yet. */
- *found = *result = (void *) -1;
+ *result = (void *) -1;
less_lazy (mod);
return DWFL_E_NOERROR;
}
else
{
- /* This is a new entry, meaning we haven't looked at this CU. */
+ /* Unexpected EOF, most likely a bogus aranges. */
+ return (DWFL_E (LIBDW, DWARF_E_INVALID_DWARF));
+ }
+ }
- *found = NULL;
+ /* Make sure the cuoff points to a real DIE. */
+ Dwarf_Die cudie;
+ Dwarf_Die *die = INTUSE(dwarf_offdie) (mod->dw, cuoff, &cudie);
+ if (die == NULL)
+ return DWFL_E_LIBDW;
- struct dwfl_cu *cu = malloc (sizeof *cu);
- if (unlikely (cu == NULL))
- return DWFL_E_NOMEM;
+ struct Dwarf_CU dwkey;
+ struct dwfl_cu key;
+ key.die.cu = &dwkey;
+ dwkey.offset_size = 0;
+ dwkey.start = cuoff - (3 * 0 - 4 + 3);
+ struct dwfl_cu **found = tsearch (&key, &mod->lazy_cu_root, &compare_cukey);
+ if (unlikely (found == NULL))
+ return DWFL_E_NOMEM;
- cu->mod = mod;
- cu->next = NULL;
- cu->lines = NULL;
+ if (*found == &key || *found == NULL)
+ {
+ /* This is a new entry, meaning we haven't looked at this CU. */
- /* XXX use non-searching lookup */
- Dwarf_Die *die = INTUSE(dwarf_offdie) (mod->dw, cuoff, &cu->die);
- if (die == NULL)
- {
- free (cu);
- return DWFL_E_LIBDW;
- }
- assert (die == &cu->die);
+ *found = NULL;
- struct dwfl_cu **newvec = realloc (mod->cu, ((mod->ncu + 1)
- * sizeof (mod->cu[0])));
- if (newvec == NULL)
- {
- free (cu);
- return DWFL_E_NOMEM;
- }
- mod->cu = newvec;
+ struct dwfl_cu *cu = malloc (sizeof *cu);
+ if (unlikely (cu == NULL))
+ return DWFL_E_NOMEM;
- mod->cu[mod->ncu++] = cu;
- if (cu->die.cu->start == 0)
- mod->first_cu = cu;
+ cu->mod = mod;
+ cu->next = NULL;
+ cu->lines = NULL;
+ cu->die = cudie;
- *found = cu;
+ struct dwfl_cu **newvec = realloc (mod->cu, ((mod->ncu + 1)
+ * sizeof (mod->cu[0])));
+ if (newvec == NULL)
+ {
+ free (cu);
+ return DWFL_E_NOMEM;
}
+ mod->cu = newvec;
+
+ mod->cu[mod->ncu++] = cu;
+ if (cu->die.cu->start == 0)
+ mod->first_cu = cu;
+
+ *found = cu;
}
*result = *found;