Coverage Report

Created: 2025-10-28 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libdwarf/fuzz/fuzz_macro_dwarf5.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 <fcntl.h> /* open() O_RDONLY O_BINARY */
13
#include <stdint.h>
14
#include <stdio.h>
15
#include <stdlib.h>
16
#include <string.h>
17
#include <sys/stat.h>
18
#include <sys/types.h>
19
#include <unistd.h>
20
#include "dwarf.h"
21
#include "libdwarf.h"
22
23
2.93k
#define TRUE 1
24
2.93k
#define FALSE 0
25
#ifndef O_BINARY
26
13.1k
#define O_BINARY 0
27
#endif
28
29
int examplep5(Dwarf_Die cu_die, Dwarf_Error *error);
30
31
13.1k
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
32
13.1k
  char filename[256];
33
34
#ifdef DWREGRESSIONTEMP
35
  /*  Under msys2, the /tmp/ results in an open fail,
36
      so we discard the /tmp/ here */
37
  sprintf(filename, "junklibfuzzer.%d", getpid());
38
#else
39
13.1k
  sprintf(filename, "/tmp/libfuzzer.%d", getpid());
40
13.1k
#endif
41
13.1k
  FILE *fp = fopen(filename, "wb");
42
13.1k
  if (!fp) {
43
0
    printf("FAIL libfuzzer cannot open temp as writeable %s\n",
44
0
        filename);
45
0
    return 0;
46
0
  }
47
13.1k
  fwrite(data, size, 1, fp);
48
13.1k
  fclose(fp);
49
50
13.1k
  Dwarf_Debug dbg = 0;
51
13.1k
  int fuzz_fd = 0;
52
13.1k
  int res = DW_DLV_ERROR;
53
13.1k
  Dwarf_Error error = 0;
54
13.1k
  Dwarf_Handler errhand = 0;
55
13.1k
  Dwarf_Ptr errarg = 0;
56
13.1k
  Dwarf_Sig8 hash8;
57
13.1k
  Dwarf_Error *errp = 0;
58
13.1k
  int simpleerrhand = 0;
59
13.1k
  int i = 0;
60
13.1k
  Dwarf_Die die;
61
62
13.1k
  fuzz_fd = open(filename, O_RDONLY|O_BINARY);
63
13.1k
  if (fuzz_fd != -1) {
64
13.1k
    res =
65
13.1k
        dwarf_init_b(fuzz_fd, DW_GROUPNUMBER_ANY, errhand, errarg, &dbg, errp);
66
13.1k
    if (res == DW_DLV_OK) {
67
5.94k
      Dwarf_Bool is_info = 0;
68
5.94k
      Dwarf_Unsigned cu_header_length = 0;
69
5.94k
      Dwarf_Half version_stamp = 0;
70
5.94k
      Dwarf_Off abbrev_offset = 0;
71
5.94k
      Dwarf_Half address_size = 0;
72
5.94k
      Dwarf_Half length_size = 0;
73
5.94k
      Dwarf_Half extension_size = 0;
74
5.94k
      Dwarf_Sig8 type_signature;
75
5.94k
      Dwarf_Unsigned typeoffset = 0;
76
5.94k
      Dwarf_Unsigned next_cu_header_offset = 0;
77
5.94k
      Dwarf_Half header_cu_type = 0;
78
5.94k
      int res = 0;
79
5.94k
      Dwarf_Die cu_die = 0;
80
5.94k
      int level = 0;
81
5.94k
      static const Dwarf_Sig8 zerosignature;
82
83
5.94k
      type_signature = zerosignature;
84
5.94k
      res = dwarf_next_cu_header_d(
85
5.94k
          dbg, is_info, &cu_header_length, &version_stamp, &abbrev_offset,
86
5.94k
          &address_size, &length_size, &extension_size, &type_signature,
87
5.94k
          &typeoffset, &next_cu_header_offset, &header_cu_type, errp);
88
5.94k
      if (res == DW_DLV_OK) {
89
3.14k
        printf(">>CU header length..........0x%lx\n",
90
3.14k
               (unsigned long)cu_header_length);
91
3.14k
        printf(">>Version stamp.............%d\n", version_stamp);
92
3.14k
        printf(">>Address size .............%d\n", address_size);
93
3.14k
        printf(">>Offset size...............%d\n", length_size);
94
3.14k
        printf(">>Next cu header offset.....0x%lx\n",
95
3.14k
               (unsigned long)next_cu_header_offset);
96
3.14k
        res = dwarf_siblingof_b(dbg, NULL, is_info, &cu_die, errp);
97
3.14k
        if (res == DW_DLV_OK) {
98
2.93k
          examplep5(cu_die, &error);
99
2.93k
        };
100
3.14k
        dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
101
3.14k
      }
102
5.94k
    }
103
13.1k
  }
104
13.1k
  dwarf_finish(dbg);
105
13.1k
  close(fuzz_fd);
106
13.1k
  unlink(filename);
107
13.1k
  return 0;
108
13.1k
}
109
110
2.93k
int examplep5(Dwarf_Die cu_die, Dwarf_Error *error) {
111
2.93k
  int lres = 0;
112
2.93k
  Dwarf_Unsigned version = 0;
113
2.93k
  Dwarf_Macro_Context macro_context = 0;
114
2.93k
  Dwarf_Unsigned macro_unit_offset = 0;
115
2.93k
  Dwarf_Unsigned number_of_ops = 0;
116
2.93k
  Dwarf_Unsigned ops_total_byte_len = 0;
117
2.93k
  Dwarf_Bool is_primary = TRUE;
118
2.93k
  unsigned k = 0;
119
120
  /*  Just call once each way to test both.
121
      Really the second is just for imported units,
122
      but this is a  way to get testing of both calls.
123
  */
124
3.36k
  for (; k < 2 ;++k) {
125
2.93k
    if (is_primary) {
126
2.93k
      lres = dwarf_get_macro_context(cu_die, &version, &macro_context,
127
2.93k
                                     &macro_unit_offset, &number_of_ops,
128
2.93k
                                     &ops_total_byte_len, error);
129
2.93k
      is_primary = FALSE;
130
2.93k
    } else {
131
0
      lres = dwarf_get_macro_context_by_offset(
132
0
          cu_die, macro_unit_offset, &version, &macro_context, &number_of_ops,
133
0
          &ops_total_byte_len, error);
134
0
    }
135
136
2.93k
    if (lres == DW_DLV_ERROR) {
137
1.78k
      return lres;
138
1.78k
    }
139
1.14k
    if (lres == DW_DLV_NO_ENTRY) {
140
704
      break;
141
704
    }
142
16.0k
    for (k = 0; k < number_of_ops; ++k) {
143
15.5k
      Dwarf_Unsigned section_offset = 0;
144
15.5k
      Dwarf_Half macro_operator = 0;
145
15.5k
      Dwarf_Half forms_count = 0;
146
15.5k
      const Dwarf_Small *formcode_array = 0;
147
15.5k
      Dwarf_Unsigned line_number = 0;
148
15.5k
      Dwarf_Unsigned index = 0;
149
15.5k
      Dwarf_Unsigned offset = 0;
150
15.5k
      const char *macro_string = 0;
151
15.5k
      int lres2 = 0;
152
153
15.5k
      lres2 =
154
15.5k
          dwarf_get_macro_op(macro_context, k, &section_offset, &macro_operator,
155
15.5k
                             &forms_count, &formcode_array, error);
156
15.5k
      if (lres2 != DW_DLV_OK) {
157
0
        dwarf_dealloc_macro_context(macro_context);
158
0
        return lres2;
159
0
      }
160
15.5k
      switch (macro_operator) {
161
432
      case 0:
162
432
        break;
163
2.51k
      case DW_MACRO_end_file:
164
2.51k
        break;
165
482
      case DW_MACRO_define:
166
933
      case DW_MACRO_undef:
167
3.69k
      case DW_MACRO_define_strp:
168
4.24k
      case DW_MACRO_undef_strp:
169
4.96k
      case DW_MACRO_define_strx:
170
5.92k
      case DW_MACRO_undef_strx:
171
5.92k
      case DW_MACRO_define_sup:
172
5.92k
      case DW_MACRO_undef_sup: {
173
5.92k
        lres2 = dwarf_get_macro_defundef(macro_context, k, &line_number, &index,
174
5.92k
                                         &offset, &forms_count, &macro_string,
175
5.92k
                                         error);
176
5.92k
        if (lres2 != DW_DLV_OK) {
177
13
          dwarf_dealloc_macro_context(macro_context);
178
13
          return lres2;
179
13
        }
180
5.92k
      } break;
181
5.91k
      case DW_MACRO_start_file: {
182
5.53k
        lres2 = dwarf_get_macro_startend_file(macro_context, k, &line_number,
183
5.53k
                                              &index, &macro_string, error);
184
5.53k
        if (lres2 != DW_DLV_OK) {
185
0
          dwarf_dealloc_macro_context(macro_context);
186
0
          return lres2;
187
0
        }
188
5.53k
      } break;
189
5.53k
      case DW_MACRO_import: {
190
543
        lres2 = dwarf_get_macro_import(macro_context, k, &offset, error);
191
543
        if (lres2 != DW_DLV_OK) {
192
0
          dwarf_dealloc_macro_context(macro_context);
193
0
          return lres2;
194
0
        }
195
543
      } break;
196
650
      case DW_MACRO_import_sup: {
197
650
        lres2 = dwarf_get_macro_import(macro_context, k, &offset, error);
198
650
        if (lres2 != DW_DLV_OK) {
199
0
          dwarf_dealloc_macro_context(macro_context);
200
0
          return lres2;
201
0
        }
202
650
      } break;
203
650
      default:
204
0
        break;
205
15.5k
      }
206
15.5k
    }
207
432
    dwarf_dealloc_macro_context(macro_context);
208
432
    macro_context = 0;
209
432
  }
210
1.13k
  return DW_DLV_OK;
211
2.93k
}