Coverage Report

Created: 2026-05-30 06:30

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
3.10k
#define TRUE 1
24
3.10k
#define FALSE 0
25
#ifndef O_BINARY
26
14.0k
#define O_BINARY 0
27
#endif
28
29
int examplep5(Dwarf_Die cu_die, Dwarf_Error *error);
30
31
14.0k
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
32
14.0k
  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
14.0k
  sprintf(filename, "/tmp/libfuzzer.%d", getpid());
40
14.0k
#endif
41
14.0k
  FILE *fp = fopen(filename, "wb");
42
14.0k
  if (!fp) {
43
0
    printf("FAIL libfuzzer cannot open temp as writeable %s\n",
44
0
        filename);
45
0
    return 0;
46
0
  }
47
14.0k
  fwrite(data, size, 1, fp);
48
14.0k
  fclose(fp);
49
50
14.0k
  Dwarf_Debug dbg = 0;
51
14.0k
  int fuzz_fd = 0;
52
14.0k
  int res = DW_DLV_ERROR;
53
14.0k
  Dwarf_Error error = 0;
54
14.0k
  Dwarf_Handler errhand = 0;
55
14.0k
  Dwarf_Ptr errarg = 0;
56
14.0k
  Dwarf_Sig8 hash8;
57
14.0k
  Dwarf_Error *errp = 0;
58
14.0k
  int simpleerrhand = 0;
59
14.0k
  int i = 0;
60
14.0k
  Dwarf_Die die;
61
62
14.0k
  fuzz_fd = open(filename, O_RDONLY|O_BINARY);
63
14.0k
  if (fuzz_fd != -1) {
64
14.0k
    res =
65
14.0k
        dwarf_init_b(fuzz_fd, DW_GROUPNUMBER_ANY, errhand, errarg, &dbg, errp);
66
14.0k
    if (res == DW_DLV_OK) {
67
6.71k
      Dwarf_Bool is_info = 0;
68
6.71k
      Dwarf_Unsigned cu_header_length = 0;
69
6.71k
      Dwarf_Half version_stamp = 0;
70
6.71k
      Dwarf_Off abbrev_offset = 0;
71
6.71k
      Dwarf_Half address_size = 0;
72
6.71k
      Dwarf_Half length_size = 0;
73
6.71k
      Dwarf_Half extension_size = 0;
74
6.71k
      Dwarf_Sig8 type_signature;
75
6.71k
      Dwarf_Unsigned typeoffset = 0;
76
6.71k
      Dwarf_Unsigned next_cu_header_offset = 0;
77
6.71k
      Dwarf_Half header_cu_type = 0;
78
6.71k
      int res = 0;
79
6.71k
      Dwarf_Die cu_die = 0;
80
6.71k
      int level = 0;
81
6.71k
      static const Dwarf_Sig8 zerosignature;
82
83
6.71k
      type_signature = zerosignature;
84
6.71k
      res = dwarf_next_cu_header_d(
85
6.71k
          dbg, is_info, &cu_header_length, &version_stamp, &abbrev_offset,
86
6.71k
          &address_size, &length_size, &extension_size, &type_signature,
87
6.71k
          &typeoffset, &next_cu_header_offset, &header_cu_type, errp);
88
6.71k
      if (res == DW_DLV_OK) {
89
3.47k
        printf(">>CU header length..........0x%lx\n",
90
3.47k
               (unsigned long)cu_header_length);
91
3.47k
        printf(">>Version stamp.............%d\n", version_stamp);
92
3.47k
        printf(">>Address size .............%d\n", address_size);
93
3.47k
        printf(">>Offset size...............%d\n", length_size);
94
3.47k
        printf(">>Next cu header offset.....0x%lx\n",
95
3.47k
               (unsigned long)next_cu_header_offset);
96
3.47k
        res = dwarf_siblingof_b(dbg, NULL, is_info, &cu_die, errp);
97
3.47k
        if (res == DW_DLV_OK) {
98
3.10k
          examplep5(cu_die, &error);
99
3.10k
        };
100
3.47k
        dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
101
3.47k
      }
102
6.71k
    }
103
14.0k
  }
104
14.0k
  dwarf_finish(dbg);
105
14.0k
  close(fuzz_fd);
106
14.0k
  unlink(filename);
107
14.0k
  return 0;
108
14.0k
}
109
110
3.10k
int examplep5(Dwarf_Die cu_die, Dwarf_Error *error) {
111
3.10k
  int lres = 0;
112
3.10k
  Dwarf_Unsigned version = 0;
113
3.10k
  Dwarf_Macro_Context macro_context = 0;
114
3.10k
  Dwarf_Unsigned macro_unit_offset = 0;
115
3.10k
  Dwarf_Unsigned number_of_ops = 0;
116
3.10k
  Dwarf_Unsigned ops_total_byte_len = 0;
117
3.10k
  Dwarf_Bool is_primary = TRUE;
118
3.10k
  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.49k
  for (; k < 2 ;++k) {
125
3.10k
    if (is_primary) {
126
3.10k
      lres = dwarf_get_macro_context(cu_die, &version, &macro_context,
127
3.10k
                                     &macro_unit_offset, &number_of_ops,
128
3.10k
                                     &ops_total_byte_len, error);
129
3.10k
      is_primary = FALSE;
130
3.10k
    } 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
3.10k
    if (lres == DW_DLV_ERROR) {
137
1.97k
      return lres;
138
1.97k
    }
139
1.13k
    if (lres == DW_DLV_NO_ENTRY) {
140
728
      break;
141
728
    }
142
14.4k
    for (k = 0; k < number_of_ops; ++k) {
143
14.0k
      Dwarf_Unsigned section_offset = 0;
144
14.0k
      Dwarf_Half macro_operator = 0;
145
14.0k
      Dwarf_Half forms_count = 0;
146
14.0k
      const Dwarf_Small *formcode_array = 0;
147
14.0k
      Dwarf_Unsigned line_number = 0;
148
14.0k
      Dwarf_Unsigned index = 0;
149
14.0k
      Dwarf_Unsigned offset = 0;
150
14.0k
      const char *macro_string = 0;
151
14.0k
      int lres2 = 0;
152
153
14.0k
      lres2 =
154
14.0k
          dwarf_get_macro_op(macro_context, k, &section_offset, &macro_operator,
155
14.0k
                             &forms_count, &formcode_array, error);
156
14.0k
      if (lres2 != DW_DLV_OK) {
157
0
        dwarf_dealloc_macro_context(macro_context);
158
0
        return lres2;
159
0
      }
160
14.0k
      switch (macro_operator) {
161
381
      case 0:
162
381
        break;
163
644
      case DW_MACRO_end_file:
164
644
        break;
165
434
      case DW_MACRO_define:
166
808
      case DW_MACRO_undef:
167
3.67k
      case DW_MACRO_define_strp:
168
4.33k
      case DW_MACRO_undef_strp:
169
4.85k
      case DW_MACRO_define_strx:
170
5.51k
      case DW_MACRO_undef_strx:
171
5.51k
      case DW_MACRO_define_sup:
172
5.51k
      case DW_MACRO_undef_sup: {
173
5.51k
        lres2 = dwarf_get_macro_defundef(macro_context, k, &line_number, &index,
174
5.51k
                                         &offset, &forms_count, &macro_string,
175
5.51k
                                         error);
176
5.51k
        if (lres2 != DW_DLV_OK) {
177
21
          dwarf_dealloc_macro_context(macro_context);
178
21
          return lres2;
179
21
        }
180
5.51k
      } break;
181
6.30k
      case DW_MACRO_start_file: {
182
6.30k
        lres2 = dwarf_get_macro_startend_file(macro_context, k, &line_number,
183
6.30k
                                              &index, &macro_string, error);
184
6.30k
        if (lres2 != DW_DLV_OK) {
185
0
          dwarf_dealloc_macro_context(macro_context);
186
0
          return lres2;
187
0
        }
188
6.30k
      } break;
189
6.30k
      case DW_MACRO_import: {
190
533
        lres2 = dwarf_get_macro_import(macro_context, k, &offset, error);
191
533
        if (lres2 != DW_DLV_OK) {
192
0
          dwarf_dealloc_macro_context(macro_context);
193
0
          return lres2;
194
0
        }
195
533
      } break;
196
689
      case DW_MACRO_import_sup: {
197
689
        lres2 = dwarf_get_macro_import(macro_context, k, &offset, error);
198
689
        if (lres2 != DW_DLV_OK) {
199
0
          dwarf_dealloc_macro_context(macro_context);
200
0
          return lres2;
201
0
        }
202
689
      } break;
203
689
      default:
204
0
        break;
205
14.0k
      }
206
14.0k
    }
207
381
    dwarf_dealloc_macro_context(macro_context);
208
381
    macro_context = 0;
209
381
  }
210
1.10k
  return DW_DLV_OK;
211
3.10k
}