/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 | 278M | #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 | 111M | { |
36 | 111M | return 0; |
37 | 111M | } |
38 | | |
39 | | static int objdump_sprintf (void *vf, const char *format, ...) |
40 | 139M | { |
41 | 139M | SFILE *f = (SFILE *) vf; |
42 | 139M | size_t n; |
43 | 139M | va_list args; |
44 | | |
45 | 139M | va_start (args, format); |
46 | 139M | if (f->pos >= MAX_TEXT_SIZE){ |
47 | 1.29k | printf("buffer needs more space\n"); |
48 | | //reset |
49 | 1.29k | f->pos=0; |
50 | 1.29k | return 0; |
51 | 1.29k | } |
52 | 139M | n = vsnprintf (f->buffer + f->pos, MAX_TEXT_SIZE - f->pos, format, args); |
53 | | //vfprintf(stdout, format, args); |
54 | 139M | va_end (args); |
55 | 139M | f->pos += n; |
56 | 139M | return n; |
57 | 139M | } |
58 | | |
59 | | |
60 | 79.4k | int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { |
61 | 79.4k | char AssemblyText[MAX_TEXT_SIZE]; |
62 | 79.4k | struct disassemble_info disasm_info; |
63 | 79.4k | SFILE s; |
64 | | |
65 | 79.4k | if (Size < 10 || Size > 16394) { |
66 | | // 10 bytes for options |
67 | | // 16394 limit code to prevent timeouts |
68 | 14 | return 0; |
69 | 14 | } |
70 | | |
71 | 79.4k | init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf, fuzz_disasm_null_styled_printf); |
72 | 79.4k | disasm_info.fprintf_func = objdump_sprintf; |
73 | 79.4k | disasm_info.print_address_func = generic_print_address; |
74 | 79.4k | disasm_info.display_endian = disasm_info.endian = BFD_ENDIAN_LITTLE; |
75 | 79.4k | disasm_info.buffer = (bfd_byte *) Data; |
76 | 79.4k | disasm_info.buffer_vma = 0x1000; |
77 | 79.4k | disasm_info.buffer_length = Size-10; |
78 | 79.4k | disasm_info.insn_info_valid = 0; |
79 | 79.4k | disasm_info.created_styled_output = false; |
80 | 79.4k | s.buffer = AssemblyText; |
81 | 79.4k | s.pos = 0; |
82 | 79.4k | disasm_info.stream = &s; |
83 | 79.4k | disasm_info.bytes_per_line = 0; |
84 | | |
85 | 79.4k | disasm_info.flags |= USER_SPECIFIED_MACHINE_TYPE; |
86 | 79.4k | disasm_info.arch = Data[Size-1]; |
87 | 79.4k | disasm_info.mach = bfd_getl64(&Data[Size-9]); |
88 | 79.4k | disasm_info.flavour = Data[Size-10]; |
89 | | |
90 | 79.4k | if (bfd_lookup_arch (disasm_info.arch, disasm_info.mach) != NULL) { |
91 | 79.3k | disassembler_ftype disasfunc = disassembler(disasm_info.arch, 0, disasm_info.mach, NULL); |
92 | 79.3k | if (disasfunc != NULL) { |
93 | 79.3k | disassemble_init_for_target(&disasm_info); |
94 | 41.4M | while (1) { |
95 | 41.4M | s.pos = 0; |
96 | 41.4M | int octets = disasfunc(disasm_info.buffer_vma, &disasm_info); |
97 | 41.4M | if (octets < (int) disasm_info.octets_per_byte) |
98 | 40.5k | break; |
99 | 41.4M | if (disasm_info.buffer_length <= (size_t) octets) |
100 | 38.8k | break; |
101 | 41.3M | disasm_info.buffer += octets; |
102 | 41.3M | disasm_info.buffer_vma += octets / disasm_info.octets_per_byte; |
103 | 41.3M | disasm_info.buffer_length -= octets; |
104 | 41.3M | } |
105 | 79.3k | disassemble_free_target(&disasm_info); |
106 | 79.3k | } |
107 | 79.3k | } |
108 | | |
109 | 79.4k | return 0; |
110 | 79.4k | } |