1/*	$NetBSD: dwarf_cu.c,v 1.5 2024/03/03 17:37:30 christos Exp $	*/
2
3/*-
4 * Copyright (c) 2007 John Birrell (jb@freebsd.org)
5 * Copyright (c) 2014,2023 Kai Wang
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include "_libdwarf.h"
31
32__RCSID("$NetBSD: dwarf_cu.c,v 1.5 2024/03/03 17:37:30 christos Exp $");
33ELFTC_VCSID("Id: dwarf_cu.c 4013 2023-10-14 22:40:50Z kaiwang27");
34
35int
36dwarf_next_cu_header_d(Dwarf_Debug dbg, Dwarf_Bool is_info,
37    Dwarf_Unsigned *cu_length, Dwarf_Half *cu_version,
38    Dwarf_Off *cu_abbrev_offset, Dwarf_Half *cu_pointer_size,
39    Dwarf_Half *cu_offset_size, Dwarf_Half *cu_extension_size,
40    Dwarf_Sig8 *type_signature, Dwarf_Unsigned *type_offset,
41    Dwarf_Unsigned *cu_next_offset, Dwarf_Half *cu_type,
42    Dwarf_Error *error)
43{
44	Dwarf_CU cu;
45	int ret;
46
47	if (dbg == NULL) {
48		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
49		return (DW_DLV_ERROR);
50	}
51
52	if (is_info) {
53		if (dbg->dbg_cu_current == NULL)
54			ret = _dwarf_info_first_cu(dbg, error);
55		else
56			ret = _dwarf_info_next_cu(dbg, error);
57	} else {
58		if (dbg->dbg_tu_current == NULL)
59			ret = _dwarf_info_first_tu(dbg, error);
60		else
61			ret = _dwarf_info_next_tu(dbg, error);
62	}
63
64	if (ret == DW_DLE_NO_ENTRY) {
65		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
66		return (DW_DLV_NO_ENTRY);
67	} else if (ret != DW_DLE_NONE)
68		return (DW_DLV_ERROR);
69
70	if (is_info) {
71		if (dbg->dbg_cu_current == NULL) {
72			DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
73			return (DW_DLV_NO_ENTRY);
74		}
75		cu = dbg->dbg_cu_current;
76	} else {
77		if (dbg->dbg_tu_current == NULL) {
78			DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
79			return (DW_DLV_NO_ENTRY);
80		}
81		cu = dbg->dbg_tu_current;
82	}
83
84	if (cu_length)
85		*cu_length = cu->cu_length;
86	if (cu_version)
87		*cu_version = cu->cu_version;
88	if (cu_abbrev_offset)
89		*cu_abbrev_offset = (Dwarf_Off) cu->cu_abbrev_offset;
90	if (cu_pointer_size)
91		*cu_pointer_size = cu->cu_pointer_size;
92	if (cu_offset_size) {
93		if (cu->cu_length_size == 4)
94			*cu_offset_size = 4;
95		else
96			*cu_offset_size = 8;
97	}
98	if (cu_extension_size) {
99		if (cu->cu_length_size == 4)
100			*cu_extension_size = 0;
101		else
102			*cu_extension_size = 4;
103	}
104	if (cu_next_offset)
105		*cu_next_offset	= cu->cu_next_offset;
106
107	if (!is_info) {
108		if (type_signature)
109			*type_signature = cu->cu_type_sig;
110		if (type_offset)
111			*type_offset = cu->cu_type_offset;
112	}
113
114	if (cu_type)
115		*cu_type = cu->cu_unit_type;
116
117	return (DW_DLV_OK);
118}
119
120int
121dwarf_next_cu_header_c(Dwarf_Debug dbg, Dwarf_Bool is_info,
122    Dwarf_Unsigned *cu_length, Dwarf_Half *cu_version,
123    Dwarf_Off *cu_abbrev_offset, Dwarf_Half *cu_pointer_size,
124    Dwarf_Half *cu_offset_size, Dwarf_Half *cu_extension_size,
125    Dwarf_Sig8 *type_signature, Dwarf_Unsigned *type_offset,
126    Dwarf_Unsigned *cu_next_offset, Dwarf_Error *error)
127{
128
129	return (dwarf_next_cu_header_d(dbg, 1, cu_length, cu_version,
130	    cu_abbrev_offset, cu_pointer_size, cu_offset_size,
131	    cu_extension_size, NULL, NULL, cu_next_offset, NULL, error));
132}
133
134
135int
136dwarf_next_cu_header_b(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length,
137    Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset,
138    Dwarf_Half *cu_pointer_size, Dwarf_Half *cu_offset_size,
139    Dwarf_Half *cu_extension_size, Dwarf_Unsigned *cu_next_offset,
140    Dwarf_Error *error)
141{
142
143	return (dwarf_next_cu_header_c(dbg, 1, cu_length, cu_version,
144	    cu_abbrev_offset, cu_pointer_size, cu_offset_size,
145	    cu_extension_size, NULL, NULL, cu_next_offset, error));
146}
147
148int
149dwarf_next_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned *cu_length,
150    Dwarf_Half *cu_version, Dwarf_Off *cu_abbrev_offset,
151    Dwarf_Half *cu_pointer_size, Dwarf_Unsigned *cu_next_offset,
152    Dwarf_Error *error)
153{
154
155	return (dwarf_next_cu_header_b(dbg, cu_length, cu_version,
156	    cu_abbrev_offset, cu_pointer_size, NULL, NULL, cu_next_offset,
157	    error));
158}
159
160int
161dwarf_next_types_section(Dwarf_Debug dbg, Dwarf_Error *error)
162{
163
164	/* Free resource allocated for current .debug_types section. */
165	_dwarf_type_unit_cleanup(dbg);
166	dbg->dbg_types_loaded = 0;
167	dbg->dbg_types_off = 0;
168
169	/* Reset type unit pointer. */
170	dbg->dbg_tu_current = NULL;
171
172	/* Search for the next .debug_types section. */
173	dbg->dbg_types_sec = _dwarf_find_next_types_section(dbg,
174	    dbg->dbg_types_sec);
175
176	if (dbg->dbg_types_sec == NULL) {
177		DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
178		return (DW_DLV_NO_ENTRY);
179	}
180
181	return (DW_DLV_OK);
182}
183