/src/libdwarf/fuzz/fuzz_srcfiles.c
Line | Count | Source |
1 | | /* Copyright 2021 Google LLC |
2 | | Licensed under the Apache License, Version 2.0 (the "License"); |
3 | | you may not use this file except in compliance with the License. |
4 | | You may obtain a copy of the License at |
5 | | http://www.apache.org/licenses/LICENSE-2.0 |
6 | | Unless required by applicable law or agreed to in writing, software |
7 | | distributed under the License is distributed on an "AS IS" BASIS, |
8 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
9 | | See the License for the specific language governing permissions and |
10 | | limitations under the License. |
11 | | */ |
12 | | #include "dwarf.h" |
13 | | #include "libdwarf.h" |
14 | | #include <fcntl.h> /* open() O_RDONLY O_BINARY */ |
15 | | #include <stdint.h> |
16 | | #include <stdio.h> |
17 | | #include <stdlib.h> |
18 | | #include <string.h> |
19 | | #include <sys/stat.h> |
20 | | #include <sys/types.h> |
21 | | #include <unistd.h> |
22 | | |
23 | | #ifndef O_BINARY |
24 | 32.5k | #define O_BINARY 0 |
25 | | #endif |
26 | | |
27 | | int examplee(Dwarf_Debug dbg, Dwarf_Die somedie, Dwarf_Error *error); |
28 | | int exampled(Dwarf_Die somedie, Dwarf_Error *error); |
29 | 32.5k | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
30 | 32.5k | char filename[256]; |
31 | | #ifdef DWREGRESSIONTEMP |
32 | | /* Under msys2, the /tmp/ results in an open fail */ |
33 | | sprintf(filename, "junklibfuzzer.%d", getpid()); |
34 | | #else |
35 | 32.5k | sprintf(filename, "/tmp/libfuzzer.%d", getpid()); |
36 | 32.5k | #endif |
37 | | |
38 | 32.5k | FILE *fp = fopen(filename, "wb"); |
39 | 32.5k | if (!fp) { |
40 | 0 | printf("FAIL libfuzzer cannot open temp as writeable %s\n", |
41 | 0 | filename); |
42 | 0 | return EXIT_FAILURE; |
43 | 0 | } |
44 | 32.5k | fwrite(data, size, 1, fp); |
45 | 32.5k | fclose(fp); |
46 | | |
47 | 32.5k | Dwarf_Debug dbg = 0; |
48 | 32.5k | int fuzz_fd = 0; |
49 | 32.5k | int res = DW_DLV_ERROR; |
50 | 32.5k | Dwarf_Error error = 0; |
51 | 32.5k | Dwarf_Handler errhand = 0; |
52 | 32.5k | Dwarf_Ptr errarg = 0; |
53 | 32.5k | Dwarf_Sig8 hash8; |
54 | 32.5k | Dwarf_Error *errp = 0; |
55 | 32.5k | int simpleerrhand = 0; |
56 | 32.5k | int i = 0; |
57 | 32.5k | Dwarf_Die die; |
58 | | |
59 | 32.5k | fuzz_fd = open(filename, O_RDONLY|O_BINARY); |
60 | 32.5k | if (fuzz_fd != -1) { |
61 | 32.5k | res = |
62 | 32.5k | dwarf_init_b(fuzz_fd, DW_GROUPNUMBER_ANY, errhand, errarg, &dbg, errp); |
63 | 32.5k | if (res == DW_DLV_OK) { |
64 | 15.4k | Dwarf_Bool is_info = 0; |
65 | 15.4k | Dwarf_Unsigned cu_header_length = 0; |
66 | 15.4k | Dwarf_Half version_stamp = 0; |
67 | 15.4k | Dwarf_Off abbrev_offset = 0; |
68 | 15.4k | Dwarf_Half address_size = 0; |
69 | 15.4k | Dwarf_Half length_size = 0; |
70 | 15.4k | Dwarf_Half extension_size = 0; |
71 | 15.4k | Dwarf_Sig8 type_signature; |
72 | 15.4k | Dwarf_Unsigned typeoffset = 0; |
73 | 15.4k | Dwarf_Unsigned next_cu_header_offset = 0; |
74 | 15.4k | Dwarf_Half header_cu_type = 0; |
75 | 15.4k | int res = 0; |
76 | 15.4k | Dwarf_Die cu_die = 0; |
77 | 15.4k | int level = 0; |
78 | 15.4k | static const Dwarf_Sig8 zerosignature; |
79 | | |
80 | 15.4k | type_signature = zerosignature; |
81 | 15.4k | res = dwarf_next_cu_header_d( |
82 | 15.4k | dbg, is_info, &cu_header_length, &version_stamp, &abbrev_offset, |
83 | 15.4k | &address_size, &length_size, &extension_size, &type_signature, |
84 | 15.4k | &typeoffset, &next_cu_header_offset, &header_cu_type, errp); |
85 | 15.4k | if (res == DW_DLV_OK) { |
86 | 6.66k | res = dwarf_siblingof_b(dbg, NULL, is_info, &cu_die, errp); |
87 | 6.66k | if (res == DW_DLV_OK) { |
88 | 5.61k | examplee(dbg, cu_die, errp); |
89 | 5.61k | exampled(cu_die, errp); |
90 | 5.61k | } else { |
91 | 1.04k | } |
92 | | |
93 | 6.66k | dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); |
94 | 6.66k | } |
95 | 15.4k | } |
96 | 32.5k | } |
97 | 32.5k | dwarf_finish(dbg); |
98 | 32.5k | close(fuzz_fd); |
99 | 32.5k | unlink(filename); |
100 | 32.5k | return 0; |
101 | 32.5k | } |
102 | | |
103 | 4.13k | int examplee(Dwarf_Debug dbg, Dwarf_Die somedie, Dwarf_Error *error) { |
104 | 4.13k | Dwarf_Signed count = 0; |
105 | 4.13k | char **srcfiles = 0; |
106 | 4.13k | Dwarf_Signed i = 0; |
107 | 4.13k | int res = 0; |
108 | | |
109 | 4.13k | res = dwarf_srcfiles(somedie, &srcfiles, &count, error); |
110 | 4.13k | if (res != DW_DLV_OK) { |
111 | 3.94k | return res; |
112 | 3.94k | } |
113 | 1.62k | for (i = 0; i < count; ++i) { |
114 | 1.43k | dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING); |
115 | 1.43k | } |
116 | 188 | dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST); |
117 | 188 | return DW_DLV_OK; |
118 | 4.13k | } |
119 | | |
120 | 4.13k | int exampled(Dwarf_Die somedie, Dwarf_Error *error) { |
121 | 4.13k | Dwarf_Signed count = 0; |
122 | 4.13k | Dwarf_Line_Context context = 0; |
123 | 4.13k | Dwarf_Line *linebuf = 0; |
124 | 4.13k | Dwarf_Signed i = 0; |
125 | 4.13k | Dwarf_Line line; |
126 | 4.13k | Dwarf_Small table_count = 0; |
127 | 4.13k | Dwarf_Unsigned version = 0; |
128 | 4.13k | int sres = 0; |
129 | | |
130 | 4.13k | int lineheader_errcount = 0; |
131 | 4.13k | dwarf_check_lineheader_b(somedie, &lineheader_errcount, error); |
132 | 4.13k | dwarf_print_lines(somedie, error, &lineheader_errcount); |
133 | | |
134 | 4.13k | sres = dwarf_srclines_b(somedie, &version, &table_count, &context, error); |
135 | 4.13k | if (sres != DW_DLV_OK) { |
136 | 3.56k | return sres; |
137 | 3.56k | } |
138 | 564 | sres = dwarf_srclines_from_linecontext(context, &linebuf, &count, error); |
139 | 564 | if (sres != DW_DLV_OK) { |
140 | 0 | dwarf_srclines_dealloc_b(context); |
141 | 0 | return sres; |
142 | 0 | } |
143 | | |
144 | 564 | Dwarf_Line *dw_linebuf_actuals = 0; /* init by davea*/ |
145 | 564 | Dwarf_Signed dw_linecount_actuals = 0; /* init by davea*/ |
146 | | |
147 | 564 | sres = dwarf_srclines_two_level_from_linecontext( |
148 | 564 | context, &linebuf, &count, &dw_linebuf_actuals, &dw_linecount_actuals, |
149 | 564 | error); |
150 | 564 | if (sres != DW_DLV_OK) { |
151 | 0 | dwarf_srclines_dealloc_b(context); |
152 | 0 | return sres; |
153 | 0 | } |
154 | | |
155 | 564 | Dwarf_Unsigned dw_context_section_offset = 0; /* init by davea*/ |
156 | 564 | sres = |
157 | 564 | dwarf_srclines_table_offset(context, &dw_context_section_offset, error); |
158 | 564 | if (sres != DW_DLV_OK) { |
159 | 0 | dwarf_srclines_dealloc_b(context); |
160 | 0 | return sres; |
161 | 0 | } |
162 | | |
163 | 564 | const char *dw_compilation_directory = 0; /* init by davea*/ |
164 | 564 | sres = dwarf_srclines_comp_dir(context, &dw_compilation_directory, error); |
165 | 564 | if (sres != DW_DLV_OK) { |
166 | 0 | dwarf_srclines_dealloc_b(context); |
167 | 0 | return sres; |
168 | 0 | } |
169 | | |
170 | 564 | Dwarf_Signed subprogram_count = 0; /* init by davea*/ |
171 | 564 | sres = dwarf_srclines_subprog_count(context, |
172 | 564 | &subprogram_count, error); |
173 | 564 | if (sres != DW_DLV_OK) { |
174 | 0 | dwarf_srclines_dealloc_b(context); |
175 | 0 | return sres; |
176 | 0 | } |
177 | | |
178 | 564 | Dwarf_Unsigned version_2 = 0; /* init by davea*/ |
179 | 564 | Dwarf_Small table_count_2 = 0; /* init by davea*/ |
180 | 564 | dwarf_srclines_version(context, &version_2, &table_count_2, error); |
181 | | |
182 | 564 | Dwarf_Signed dw_baseindex = 0; /* init by davea*/ |
183 | 564 | Dwarf_Signed dw_count = 0; /* init by davea*/ |
184 | 564 | Dwarf_Signed dw_endindex = 0; /* init by davea*/ |
185 | 564 | sres = dwarf_srclines_files_indexes(context, |
186 | 564 | &dw_baseindex, &dw_count, |
187 | 564 | &dw_endindex, error); |
188 | 564 | if (sres != DW_DLV_OK) { |
189 | 0 | dwarf_srclines_dealloc_b(context); |
190 | 0 | return sres; |
191 | 0 | } |
192 | | |
193 | 4.23k | for (i = 0; i < subprogram_count; i++) { |
194 | 3.66k | const char *dw_name = 0; /* init by davea*/ |
195 | 3.66k | Dwarf_Unsigned dw_decl_file = 0; /* init by davea*/ |
196 | 3.66k | Dwarf_Unsigned dw_decl_line = 0; /* init by davea*/ |
197 | 3.66k | sres = dwarf_srclines_subprog_data(context, i + 1, |
198 | 3.66k | &dw_name, &dw_decl_file, |
199 | 3.66k | &dw_decl_line, error); |
200 | 3.66k | if (sres != DW_DLV_OK) { |
201 | 0 | continue; |
202 | 0 | } |
203 | 3.66k | } |
204 | | |
205 | 125k | for (i = 0; i < count; ++i) { |
206 | 125k | line = linebuf[i]; |
207 | | |
208 | 125k | Dwarf_Bool ans = 0; /* init by davea */ |
209 | 125k | Dwarf_Unsigned linenum = 0; /* init by davea */ |
210 | 125k | dwarf_linebeginstatement(line, &ans, error); |
211 | 125k | dwarf_lineendsequence(line, &ans, error); |
212 | 125k | dwarf_line_is_addr_set(line, &ans, error); |
213 | | |
214 | 125k | dwarf_lineno(line, &linenum, error); |
215 | 125k | dwarf_line_srcfileno(line, &linenum, error); |
216 | 125k | dwarf_lineoff_b(line, &linenum, error); |
217 | | |
218 | 125k | char *linesrc = 0; /* INIT by davea */ |
219 | | |
220 | 125k | dwarf_linesrc(line, &linesrc, error); |
221 | | |
222 | 125k | Dwarf_Bool prologue_end = 0; /* init by davea*/ |
223 | 125k | Dwarf_Bool epilogue_begin = 0; /* init by davea*/ |
224 | 125k | Dwarf_Unsigned isa = 0; /* init by davea*/ |
225 | 125k | Dwarf_Unsigned discriminator = 0; /* init by davea*/ |
226 | 125k | dwarf_prologue_end_etc(line, &prologue_end, &epilogue_begin, &isa, |
227 | 125k | &discriminator, error); |
228 | | |
229 | 125k | #if 1 /* this is problematic and does not work */ |
230 | 125k | Dwarf_Unsigned l_logical = 0; /* init by davea*/ |
231 | 125k | dwarf_linelogical(line, &l_logical, error); |
232 | | |
233 | 125k | Dwarf_Unsigned subprog_no = 0; /* init by davea*/ |
234 | 125k | dwarf_line_subprogno(line, &subprog_no, error); |
235 | 125k | #endif |
236 | 125k | } |
237 | 564 | dwarf_srclines_dealloc_b(context); |
238 | 564 | return DW_DLV_OK; |
239 | 564 | } |