1*eb293b8fSAndroid Build Coastguard Worker /*
2*eb293b8fSAndroid Build Coastguard Worker * Copyright 2020 The Android Open Source Project
3*eb293b8fSAndroid Build Coastguard Worker *
4*eb293b8fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*eb293b8fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*eb293b8fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*eb293b8fSAndroid Build Coastguard Worker *
8*eb293b8fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*eb293b8fSAndroid Build Coastguard Worker *
10*eb293b8fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*eb293b8fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*eb293b8fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*eb293b8fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*eb293b8fSAndroid Build Coastguard Worker * limitations under the License.
15*eb293b8fSAndroid Build Coastguard Worker */
16*eb293b8fSAndroid Build Coastguard Worker
17*eb293b8fSAndroid Build Coastguard Worker #include <functional>
18*eb293b8fSAndroid Build Coastguard Worker #include <iostream>
19*eb293b8fSAndroid Build Coastguard Worker #include <vector>
20*eb293b8fSAndroid Build Coastguard Worker
21*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/JitDebug.h>
22*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Maps.h>
23*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Memory.h>
24*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Unwinder.h>
25*eb293b8fSAndroid Build Coastguard Worker
26*eb293b8fSAndroid Build Coastguard Worker #include "UnwinderComponentCreator.h"
27*eb293b8fSAndroid Build Coastguard Worker #include "fuzzer/FuzzedDataProvider.h"
28*eb293b8fSAndroid Build Coastguard Worker #include "utils/MemoryFake.h"
29*eb293b8fSAndroid Build Coastguard Worker
30*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack {
31*eb293b8fSAndroid Build Coastguard Worker
32*eb293b8fSAndroid Build Coastguard Worker static constexpr int kMaxUnwindStringLen = 50;
33*eb293b8fSAndroid Build Coastguard Worker static constexpr int kMaxUnwindStrings = 50;
34*eb293b8fSAndroid Build Coastguard Worker
PerformUnwind(FuzzedDataProvider * data_provider,Unwinder * unwinder)35*eb293b8fSAndroid Build Coastguard Worker void PerformUnwind(FuzzedDataProvider* data_provider, Unwinder* unwinder) {
36*eb293b8fSAndroid Build Coastguard Worker // 0 = don't set any values
37*eb293b8fSAndroid Build Coastguard Worker // 1 = set initial_map_names_to_skip
38*eb293b8fSAndroid Build Coastguard Worker // 2 = set map_suffixes_to_ignore
39*eb293b8fSAndroid Build Coastguard Worker // 3 = set both
40*eb293b8fSAndroid Build Coastguard Worker uint8_t set_values = data_provider->ConsumeIntegral<uint8_t>() % 4;
41*eb293b8fSAndroid Build Coastguard Worker if (set_values == 0) {
42*eb293b8fSAndroid Build Coastguard Worker unwinder->Unwind();
43*eb293b8fSAndroid Build Coastguard Worker } else if (set_values == 1) {
44*eb293b8fSAndroid Build Coastguard Worker // Only setting initial_map_names_to_skip
45*eb293b8fSAndroid Build Coastguard Worker std::vector<std::string> skip_names =
46*eb293b8fSAndroid Build Coastguard Worker GetStringList(data_provider, kMaxUnwindStringLen, kMaxUnwindStrings);
47*eb293b8fSAndroid Build Coastguard Worker
48*eb293b8fSAndroid Build Coastguard Worker unwinder->Unwind(&skip_names, nullptr);
49*eb293b8fSAndroid Build Coastguard Worker } else if (set_values == 2) {
50*eb293b8fSAndroid Build Coastguard Worker // Only setting map_suffixes_to_ignore
51*eb293b8fSAndroid Build Coastguard Worker std::vector<std::string> ignore_suffixes =
52*eb293b8fSAndroid Build Coastguard Worker GetStringList(data_provider, kMaxUnwindStringLen, kMaxUnwindStrings);
53*eb293b8fSAndroid Build Coastguard Worker
54*eb293b8fSAndroid Build Coastguard Worker unwinder->Unwind(nullptr, &ignore_suffixes);
55*eb293b8fSAndroid Build Coastguard Worker } else if (set_values == 3) {
56*eb293b8fSAndroid Build Coastguard Worker // Setting both values
57*eb293b8fSAndroid Build Coastguard Worker std::vector<std::string> skip_names =
58*eb293b8fSAndroid Build Coastguard Worker GetStringList(data_provider, kMaxUnwindStringLen, kMaxUnwindStrings);
59*eb293b8fSAndroid Build Coastguard Worker std::vector<std::string> ignore_suffixes =
60*eb293b8fSAndroid Build Coastguard Worker GetStringList(data_provider, kMaxUnwindStringLen, kMaxUnwindStrings);
61*eb293b8fSAndroid Build Coastguard Worker
62*eb293b8fSAndroid Build Coastguard Worker unwinder->Unwind(&skip_names, &ignore_suffixes);
63*eb293b8fSAndroid Build Coastguard Worker }
64*eb293b8fSAndroid Build Coastguard Worker }
65*eb293b8fSAndroid Build Coastguard Worker
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)66*eb293b8fSAndroid Build Coastguard Worker extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
67*eb293b8fSAndroid Build Coastguard Worker FuzzedDataProvider data_provider(data, size);
68*eb293b8fSAndroid Build Coastguard Worker
69*eb293b8fSAndroid Build Coastguard Worker // We need to construct an unwinder.
70*eb293b8fSAndroid Build Coastguard Worker // Generate the Maps:
71*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<Maps> maps = GetMaps(&data_provider);
72*eb293b8fSAndroid Build Coastguard Worker
73*eb293b8fSAndroid Build Coastguard Worker // Generate the Regs:
74*eb293b8fSAndroid Build Coastguard Worker uint8_t arch_val = data_provider.ConsumeIntegralInRange<uint8_t>(1, kArchCount);
75*eb293b8fSAndroid Build Coastguard Worker ArchEnum arch = static_cast<ArchEnum>(arch_val);
76*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<Regs> regs = GetRegisters(arch);
77*eb293b8fSAndroid Build Coastguard Worker
78*eb293b8fSAndroid Build Coastguard Worker // Generate memory:
79*eb293b8fSAndroid Build Coastguard Worker std::shared_ptr<Memory> memory = std::make_shared<MemoryFake>();
80*eb293b8fSAndroid Build Coastguard Worker PutElfFilesInMemory(reinterpret_cast<MemoryFake*>(memory.get()), &data_provider);
81*eb293b8fSAndroid Build Coastguard Worker
82*eb293b8fSAndroid Build Coastguard Worker size_t max_frames = data_provider.ConsumeIntegralInRange<size_t>(0, 5000);
83*eb293b8fSAndroid Build Coastguard Worker
84*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<JitDebug> jit_debug_ptr = CreateJitDebug(arch, memory);
85*eb293b8fSAndroid Build Coastguard Worker
86*eb293b8fSAndroid Build Coastguard Worker // Create instance
87*eb293b8fSAndroid Build Coastguard Worker Unwinder unwinder(max_frames, maps.get(), regs.get(), memory);
88*eb293b8fSAndroid Build Coastguard Worker unwinder.SetJitDebug(jit_debug_ptr.get());
89*eb293b8fSAndroid Build Coastguard Worker unwinder.SetResolveNames(data_provider.ConsumeBool());
90*eb293b8fSAndroid Build Coastguard Worker // Call unwind
91*eb293b8fSAndroid Build Coastguard Worker PerformUnwind(&data_provider, &unwinder);
92*eb293b8fSAndroid Build Coastguard Worker
93*eb293b8fSAndroid Build Coastguard Worker // Run some additional logic that changes after unwind
94*eb293b8fSAndroid Build Coastguard Worker uint64_t pc = data_provider.ConsumeIntegral<uint64_t>();
95*eb293b8fSAndroid Build Coastguard Worker unwinder.BuildFrameFromPcOnly(pc);
96*eb293b8fSAndroid Build Coastguard Worker unwinder.ConsumeFrames();
97*eb293b8fSAndroid Build Coastguard Worker return 0;
98*eb293b8fSAndroid Build Coastguard Worker }
99*eb293b8fSAndroid Build Coastguard Worker } // namespace unwindstack
100