1260684Skaiw/*-
2260684Skaiw * Copyright (c) 2007 John Birrell (jb@freebsd.org)
3276371Semaste * Copyright (c) 2014 Kai Wang
4260684Skaiw * All rights reserved.
5260684Skaiw *
6260684Skaiw * Redistribution and use in source and binary forms, with or without
7260684Skaiw * modification, are permitted provided that the following conditions
8260684Skaiw * are met:
9260684Skaiw * 1. Redistributions of source code must retain the above copyright
10260684Skaiw *    notice, this list of conditions and the following disclaimer.
11260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright
12260684Skaiw *    notice, this list of conditions and the following disclaimer in the
13260684Skaiw *    documentation and/or other materials provided with the distribution.
14260684Skaiw *
15260684Skaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16260684Skaiw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17260684Skaiw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18260684Skaiw * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19260684Skaiw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20260684Skaiw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21260684Skaiw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22260684Skaiw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23260684Skaiw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24260684Skaiw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25260684Skaiw * SUCH DAMAGE.
26260684Skaiw */
27260684Skaiw
28260684Skaiw#include "_libdwarf.h"
29260684Skaiw
30276371SemasteELFTC_VCSID("$Id: dwarf_cu.c 3041 2014-05-18 15:11:03Z kaiwang27 $");
31260684Skaiw
32260684Skaiwint
33276371Semastedwarf_next_cu_header_c(Dwarf_Debug dbg, Dwarf_Bool is_info,
34276371Semaste    Dwarf_Unsigned *cu_length, Dwarf_Half *cu_version,
35276371Semaste    Dwarf_Off *cu_abbrev_offset, Dwarf_Half *cu_pointer_size,
36276371Semaste    Dwarf_Half *cu_offset_size, Dwarf_Half *cu_extension_size,
37276371Semaste    Dwarf_Sig8 *type_signature, Dwarf_Unsigned *type_offset,
38276371Semaste    Dwarf_Unsigned *cu_next_offset, Dwarf_Error *error)
39260684Skaiw{
40260684Skaiw	Dwarf_CU cu;
41260684Skaiw	int ret;
42260684Skaiw
43260684Skaiw	if (dbg == NULL) {
44260684Skaiw		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
45260684Skaiw		return (DW_DLV_ERROR);
46260684Skaiw	}
47260684Skaiw
48276371Semaste	if (is_info) {
49276371Semaste		if (dbg->dbg_cu_current == NULL)
50276371Semaste			ret = _dwarf_info_first_cu(dbg, error);
51276371Semaste		else
52276371Semaste			ret = _dwarf_info_next_cu(dbg, error);
53276371Semaste	} else {
54276371Semaste		if (dbg->dbg_tu_current == NULL)
55276371Semaste			ret = _dwarf_info_first_tu(dbg, error);
56276371Semaste		else
57276371Semaste			ret = _dwarf_info_next_tu(dbg, error);
58276371Semaste	}
59260684Skaiw
60260684Skaiw	if (ret == DW_DLE_NO_ENTRY) {
61260684Skaiw		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
62260684Skaiw		return (DW_DLV_NO_ENTRY);
63260684Skaiw	} else if (ret != DW_DLE_NONE)
64260684Skaiw		return (DW_DLV_ERROR);
65260684Skaiw
66276371Semaste	if (is_info) {
67276371Semaste		if (dbg->dbg_cu_current == NULL) {
68276371Semaste			DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
69276371Semaste			return (DW_DLV_NO_ENTRY);
70276371Semaste		}
71276371Semaste		cu = dbg->dbg_cu_current;
72276371Semaste	} else {
73276371Semaste		if (dbg->dbg_tu_current == NULL) {
74276371Semaste			DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
75276371Semaste			return (DW_DLV_NO_ENTRY);
76276371Semaste		}
77276371Semaste		cu = dbg->dbg_tu_current;
78260684Skaiw	}
79260684Skaiw
80260684Skaiw	if (cu_length)
81260684Skaiw		*cu_length = cu->cu_length;
82260684Skaiw	if (cu_version)
83260684Skaiw		*cu_version = cu->cu_version;
84260684Skaiw	if (cu_abbrev_offset)
85260684Skaiw		*cu_abbrev_offset = (Dwarf_Off) cu->cu_abbrev_offset;
86260684Skaiw	if (cu_pointer_size)
87260684Skaiw		*cu_pointer_size = cu->cu_pointer_size;
88260684Skaiw	if (cu_offset_size) {
89260684Skaiw		if (cu->cu_length_size == 4)
90260684Skaiw			*cu_offset_size = 4;
91260684Skaiw		else
92260684Skaiw			*cu_offset_size = 8;
93260684Skaiw	}
94260684Skaiw	if (cu_extension_size) {
95260684Skaiw		if (cu->cu_length_size == 4)
96260684Skaiw			*cu_extension_size = 0;
97260684Skaiw		else
98260684Skaiw			*cu_extension_size = 4;
99260684Skaiw	}
100260684Skaiw	if (cu_next_offset)
101276371Semaste		*cu_next_offset	= cu->cu_next_offset;
102260684Skaiw
103276371Semaste	if (!is_info) {
104276371Semaste		if (type_signature)
105276371Semaste			*type_signature = cu->cu_type_sig;
106276371Semaste		if (type_offset)
107276371Semaste			*type_offset = cu->cu_type_offset;
108276371Semaste	}
109276371Semaste
110260684Skaiw	return (DW_DLV_OK);
111260684Skaiw}
112260684Skaiw
113276371Semaste
114260684Skaiwint
115276371Semastedwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length,
116276371Semaste    Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset,
117276371Semaste    Dwarf_Half *cu_pointer_size, Dwarf_Half *cu_offset_size,
118276371Semaste    Dwarf_Half *cu_extension_size, Dwarf_Unsigned *cu_next_offset,
119276371Semaste    Dwarf_Error *error)
120276371Semaste{
121276371Semaste
122276371Semaste	return (dwarf_next_cu_header_c(dbg, 1, cu_length, cu_version,
123276371Semaste	    cu_abbrev_offset, cu_pointer_size, cu_offset_size,
124276371Semaste	    cu_extension_size, NULL, NULL, cu_next_offset, error));
125276371Semaste}
126276371Semaste
127276371Semasteint
128260684Skaiwdwarf_next_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length,
129260684Skaiw    Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset,
130260684Skaiw    Dwarf_Half *cu_pointer_size, Dwarf_Unsigned *cu_next_offset,
131260684Skaiw    Dwarf_Error *error)
132260684Skaiw{
133260684Skaiw
134260684Skaiw	return (dwarf_next_cu_header_b(dbg, cu_length, cu_version,
135260684Skaiw	    cu_abbrev_offset, cu_pointer_size, NULL, NULL, cu_next_offset,
136260684Skaiw	    error));
137260684Skaiw}
138276371Semaste
139276371Semasteint
140276371Semastedwarf_next_types_section(Dwarf_Debug dbg, Dwarf_Error *error)
141276371Semaste{
142276371Semaste
143276371Semaste	/* Free resource allocated for current .debug_types section. */
144276371Semaste	_dwarf_type_unit_cleanup(dbg);
145276371Semaste	dbg->dbg_types_loaded = 0;
146276371Semaste	dbg->dbg_types_off = 0;
147276371Semaste
148276371Semaste	/* Reset type unit pointer. */
149276371Semaste	dbg->dbg_tu_current = NULL;
150276371Semaste
151276371Semaste	/* Search for the next .debug_types section. */
152276371Semaste	dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg,
153276371Semaste	    dbg->dbg_types_sec);
154276371Semaste
155276371Semaste	if (dbg->dbg_types_sec == NULL) {
156276371Semaste		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
157276371Semaste		return (DW_DLV_NO_ENTRY);
158276371Semaste	}
159276371Semaste
160276371Semaste	return (DW_DLV_OK);
161276371Semaste}
162