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