xref: /netbsd-src/external/bsd/elftoolchain/dist/libdwarf/dwarf_cu.c (revision 5ac3bc719ce6e70593039505b491894133237d12)
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 $");
33 ELFTC_VCSID("Id: dwarf_cu.c 4013 2023-10-14 22:40:50Z kaiwang27");
34 
35 int
dwarf_next_cu_header_d(Dwarf_Debug dbg,Dwarf_Bool is_info,Dwarf_Unsigned * cu_length,Dwarf_Half * cu_version,Dwarf_Off * cu_abbrev_offset,Dwarf_Half * cu_pointer_size,Dwarf_Half * cu_offset_size,Dwarf_Half * cu_extension_size,Dwarf_Sig8 * type_signature,Dwarf_Unsigned * type_offset,Dwarf_Unsigned * cu_next_offset,Dwarf_Half * cu_type,Dwarf_Error * error)36 dwarf_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 
120 int
dwarf_next_cu_header_c(Dwarf_Debug dbg,Dwarf_Bool is_info,Dwarf_Unsigned * cu_length,Dwarf_Half * cu_version,Dwarf_Off * cu_abbrev_offset,Dwarf_Half * cu_pointer_size,Dwarf_Half * cu_offset_size,Dwarf_Half * cu_extension_size,Dwarf_Sig8 * type_signature,Dwarf_Unsigned * type_offset,Dwarf_Unsigned * cu_next_offset,Dwarf_Error * error)121 dwarf_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 
135 int
dwarf_next_cu_header_b(Dwarf_Debug dbg,Dwarf_Unsigned * cu_length,Dwarf_Half * cu_version,Dwarf_Off * cu_abbrev_offset,Dwarf_Half * cu_pointer_size,Dwarf_Half * cu_offset_size,Dwarf_Half * cu_extension_size,Dwarf_Unsigned * cu_next_offset,Dwarf_Error * error)136 dwarf_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 
148 int
dwarf_next_cu_header(Dwarf_Debug dbg,Dwarf_Unsigned * cu_length,Dwarf_Half * cu_version,Dwarf_Off * cu_abbrev_offset,Dwarf_Half * cu_pointer_size,Dwarf_Unsigned * cu_next_offset,Dwarf_Error * error)149 dwarf_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 
160 int
dwarf_next_types_section(Dwarf_Debug dbg,Dwarf_Error * error)161 dwarf_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