1179187Sjb/*- 2179187Sjb * Copyright (c) 2007 John Birrell (jb@freebsd.org) 3179187Sjb * All rights reserved. 4179187Sjb * 5179187Sjb * Redistribution and use in source and binary forms, with or without 6179187Sjb * modification, are permitted provided that the following conditions 7179187Sjb * are met: 8179187Sjb * 1. Redistributions of source code must retain the above copyright 9179187Sjb * notice, this list of conditions and the following disclaimer. 10179187Sjb * 2. Redistributions in binary form must reproduce the above copyright 11179187Sjb * notice, this list of conditions and the following disclaimer in the 12179187Sjb * documentation and/or other materials provided with the distribution. 13179187Sjb * 14179187Sjb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15179187Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16179187Sjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17179187Sjb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18179187Sjb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19179187Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20179187Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21179187Sjb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22179187Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23179187Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24179187Sjb * SUCH DAMAGE. 25179187Sjb * 26179187Sjb * $FreeBSD$ 27179187Sjb */ 28179187Sjb 29179187Sjb#include <stdlib.h> 30179187Sjb#include "_libdwarf.h" 31179187Sjb 32179187Sjbint 33179187Sjbdwarf_die_add(Dwarf_CU cu, int level, uint64_t offset, uint64_t abnum, Dwarf_Abbrev a, Dwarf_Die *diep, Dwarf_Error *err) 34179187Sjb{ 35179187Sjb Dwarf_Die die; 36179187Sjb uint64_t key; 37179187Sjb int ret = DWARF_E_NONE; 38179187Sjb 39179187Sjb if (err == NULL) 40179187Sjb return DWARF_E_ERROR; 41179187Sjb 42179187Sjb if (cu == NULL || a == NULL) { 43179187Sjb DWARF_SET_ERROR(err, DWARF_E_ARGUMENT); 44179187Sjb return DWARF_E_ARGUMENT; 45179187Sjb } 46179187Sjb 47179187Sjb if ((die = malloc(sizeof(struct _Dwarf_Die))) == NULL) { 48179187Sjb DWARF_SET_ERROR(err, DWARF_E_MEMORY); 49179187Sjb return DWARF_E_MEMORY; 50179187Sjb } 51179187Sjb 52179187Sjb /* Initialise the abbrev structure. */ 53179187Sjb die->die_level = level; 54179187Sjb die->die_offset = offset; 55179187Sjb die->die_abnum = abnum; 56179187Sjb die->die_a = a; 57179187Sjb die->die_cu = cu; 58248641Savg die->die_name = ""; 59179187Sjb 60179187Sjb /* Initialise the list of attribute values. */ 61179187Sjb STAILQ_INIT(&die->die_attrval); 62179187Sjb 63179187Sjb /* Add the die to the list in the compilation unit. */ 64179187Sjb STAILQ_INSERT_TAIL(&cu->cu_die, die, die_next); 65179187Sjb 66179187Sjb /* Add the die to the hash table in the compilation unit. */ 67179187Sjb key = offset % DWARF_DIE_HASH_SIZE; 68179187Sjb STAILQ_INSERT_TAIL(&cu->cu_die_hash[key], die, die_hash); 69179187Sjb 70179187Sjb if (diep != NULL) 71179187Sjb *diep = die; 72179187Sjb 73179187Sjb return ret; 74179187Sjb} 75179187Sjb 76179187Sjbint 77179187Sjbdwarf_dieoffset(Dwarf_Die die, Dwarf_Off *ret_offset, Dwarf_Error *err __unused) 78179187Sjb{ 79179187Sjb *ret_offset = die->die_offset; 80179187Sjb 81179187Sjb return DWARF_E_NONE; 82179187Sjb} 83179187Sjb 84179187Sjbint 85179187Sjbdwarf_child(Dwarf_Die die, Dwarf_Die *ret_die, Dwarf_Error *err) 86179187Sjb{ 87179187Sjb Dwarf_Die next; 88179187Sjb int ret = DWARF_E_NONE; 89179187Sjb 90179187Sjb if (err == NULL) 91179187Sjb return DWARF_E_ERROR; 92179187Sjb 93179187Sjb if (die == NULL || ret_die == NULL) { 94179187Sjb DWARF_SET_ERROR(err, DWARF_E_ARGUMENT); 95179187Sjb return DWARF_E_ARGUMENT; 96179187Sjb } 97179187Sjb 98179187Sjb if ((next = STAILQ_NEXT(die, die_next)) == NULL || 99179187Sjb next->die_level != die->die_level + 1) { 100179187Sjb *ret_die = NULL; 101179187Sjb DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY); 102179187Sjb ret = DWARF_E_NO_ENTRY; 103179187Sjb } else 104179187Sjb *ret_die = next; 105179187Sjb 106179187Sjb return ret; 107179187Sjb} 108179187Sjb 109179187Sjbint 110179187Sjbdwarf_tag(Dwarf_Die die, Dwarf_Half *tag, Dwarf_Error *err) 111179187Sjb{ 112179187Sjb Dwarf_Abbrev a; 113179187Sjb 114179187Sjb if (err == NULL) 115179187Sjb return DWARF_E_ERROR; 116179187Sjb 117179187Sjb if (die == NULL || tag == NULL || (a = die->die_a) == NULL) { 118179187Sjb DWARF_SET_ERROR(err, DWARF_E_ARGUMENT); 119179187Sjb return DWARF_E_ARGUMENT; 120179187Sjb } 121179187Sjb 122179187Sjb *tag = a->a_tag; 123179187Sjb 124179187Sjb return DWARF_E_NONE; 125179187Sjb} 126179187Sjb 127179187Sjbint 128179187Sjbdwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *caller_ret_die, Dwarf_Error *err) 129179187Sjb{ 130179187Sjb Dwarf_Die next; 131179187Sjb Dwarf_CU cu; 132179187Sjb int ret = DWARF_E_NONE; 133179187Sjb 134179187Sjb if (err == NULL) 135179187Sjb return DWARF_E_ERROR; 136179187Sjb 137179187Sjb if (dbg == NULL || caller_ret_die == NULL) { 138179187Sjb DWARF_SET_ERROR(err, DWARF_E_ARGUMENT); 139179187Sjb return DWARF_E_ARGUMENT; 140179187Sjb } 141179187Sjb 142179187Sjb if ((cu = dbg->dbg_cu_current) == NULL) { 143179187Sjb DWARF_SET_ERROR(err, DWARF_E_CU_CURRENT); 144179187Sjb return DWARF_E_CU_CURRENT; 145179187Sjb } 146179187Sjb 147179187Sjb if (die == NULL) { 148179187Sjb *caller_ret_die = STAILQ_FIRST(&cu->cu_die); 149179187Sjb 150179187Sjb if (*caller_ret_die == NULL) { 151179187Sjb DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY); 152179187Sjb ret = DWARF_E_NO_ENTRY; 153179187Sjb } 154179187Sjb } else { 155179187Sjb next = die; 156179187Sjb while ((next = STAILQ_NEXT(next, die_next)) != NULL) { 157179187Sjb if (next->die_level < die->die_level) { 158179187Sjb next = NULL; 159179187Sjb break; 160179187Sjb } 161179187Sjb if (next->die_level == die->die_level) { 162179187Sjb *caller_ret_die = next; 163179187Sjb break; 164179187Sjb } 165179187Sjb } 166179187Sjb 167179187Sjb if (next == NULL) { 168179187Sjb *caller_ret_die = NULL; 169179187Sjb DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY); 170179187Sjb ret = DWARF_E_NO_ENTRY; 171179187Sjb } 172179187Sjb } 173179187Sjb 174179187Sjb return ret; 175179187Sjb} 176179187Sjb 177179187SjbDwarf_Die 178179187Sjbdwarf_die_find(Dwarf_Die die, Dwarf_Unsigned off) 179179187Sjb{ 180179187Sjb Dwarf_CU cu = die->die_cu; 181179187Sjb Dwarf_Die die1; 182179187Sjb 183179187Sjb STAILQ_FOREACH(die1, &cu->cu_die, die_next) { 184179187Sjb if (die1->die_offset == off) 185179187Sjb return (die1); 186179187Sjb } 187179187Sjb 188179187Sjb return (NULL); 189179187Sjb} 190