Coverage Report

Created: 2026-07-24 06:15

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