/src/binutils-gdb/fuzz/fuzz_disassemble.c
Line | Count | Source |
1 | | /* Copyright 2020 Google Inc. |
2 | | |
3 | | Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | you may not use this file except in compliance with the License. |
5 | | You may obtain a copy of the License at |
6 | | |
7 | | http://www.apache.org/licenses/LICENSE-2.0 |
8 | | |
9 | | Unless required by applicable law or agreed to in writing, software |
10 | | distributed under the License is distributed on an "AS IS" BASIS, |
11 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | See the License for the specific language governing permissions and |
13 | | limitations under the License. |
14 | | */ |
15 | | |
16 | | #include "sysdep.h" |
17 | | #include "bfd.h" |
18 | | #include "dis-asm.h" |
19 | | #include "disassemble.h" |
20 | | |
21 | | #include <stdint.h> |
22 | | |
23 | 237M | #define MAX_TEXT_SIZE 256 |
24 | | |
25 | | typedef struct |
26 | | { |
27 | | char *buffer; |
28 | | size_t pos; |
29 | | } SFILE; |
30 | | |
31 | | static int |
32 | | fuzz_disasm_null_styled_printf (void *stream, |
33 | | enum disassembler_style style, |
34 | | const char *format, ...) |
35 | 65.3M | { |
36 | 65.3M | return 0; |
37 | 65.3M | } |
38 | | |
39 | | static int objdump_sprintf (void *vf, const char *format, ...) |
40 | 118M | { |
41 | 118M | SFILE *f = (SFILE *) vf; |
42 | 118M | size_t n; |
43 | 118M | va_list args; |
44 | | |
45 | 118M | va_start (args, format); |
46 | 118M | if (f->pos >= MAX_TEXT_SIZE){ |
47 | 940 | printf("buffer needs more space\n"); |
48 | | //reset |
49 | 940 | f->pos=0; |
50 | 940 | return 0; |
51 | 940 | } |
52 | 118M | n = vsnprintf (f->buffer + f->pos, MAX_TEXT_SIZE - f->pos, format, args); |
53 | | //vfprintf(stdout, format, args); |
54 | 118M | va_end (args); |
55 | 118M | f->pos += n; |
56 | 118M | return n; |
57 | 118M | } |
58 | | |
59 | | |
60 | 26.8k | int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { |
61 | 26.8k | char AssemblyText[MAX_TEXT_SIZE]; |
62 | 26.8k | struct disassemble_info disasm_info; |
63 | 26.8k | SFILE s; |
64 | | |
65 | 26.8k | if (Size < 10 || Size > 16394) { |
66 | | // 10 bytes for options |
67 | | // 16394 limit code to prevent timeouts |
68 | 11 | return 0; |
69 | 11 | } |
70 | | |
71 | 26.7k | init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf, fuzz_disasm_null_styled_printf); |
72 | 26.7k | disasm_info.fprintf_func = objdump_sprintf; |
73 | 26.7k | disasm_info.print_address_func = generic_print_address; |
74 | 26.7k | disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE; |
75 | 26.7k | disasm_info.buffer = (bfd_byte *) Data; |
76 | 26.7k | disasm_info.buffer_vma = 0x1000; |
77 | 26.7k | disasm_info.buffer_length = Size-10; |
78 | 26.7k | disasm_info.insn_info_valid = 0; |
79 | 26.7k | disasm_info.created_styled_output = false; |
80 | 26.7k | s.buffer = AssemblyText; |
81 | 26.7k | s.pos = 0; |
82 | 26.7k | disasm_info.stream = &s; |
83 | 26.7k | disasm_info.bytes_per_line = 0; |
84 | | |
85 | 26.7k | disasm_info.arch = Data[Size-1]; |
86 | 26.7k | disasm_info.mach = bfd_getl64(&Data[Size-9]); |
87 | 26.7k | disasm_info.flavour = Data[Size-10]; |
88 | | |
89 | 26.7k | if (bfd_lookup_arch (disasm_info.arch, disasm_info.mach) != NULL) { |
90 | 26.7k | disassembler_ftype disasfunc = disassembler(disasm_info.arch, 0, disasm_info.mach, NULL); |
91 | 26.7k | if (disasfunc != NULL) { |
92 | 26.7k | disassemble_init_for_target(&disasm_info); |
93 | 33.9M | while (1) { |
94 | 33.9M | s.pos = 0; |
95 | 33.9M | int octets = disasfunc(disasm_info.buffer_vma, &disasm_info); |
96 | 33.9M | if (octets < (int) disasm_info.octets_per_byte) |
97 | 14.6k | break; |
98 | 33.9M | if (disasm_info.buffer_length <= (size_t) octets) |
99 | 12.0k | break; |
100 | 33.9M | disasm_info.buffer += octets; |
101 | 33.9M | disasm_info.buffer_vma += octets / disasm_info.octets_per_byte; |
102 | 33.9M | disasm_info.buffer_length -= octets; |
103 | 33.9M | } |
104 | 26.7k | disassemble_free_target(&disasm_info); |
105 | 26.7k | } |
106 | 26.7k | } |
107 | | |
108 | 26.7k | return 0; |
109 | 26.8k | } |