Skip to content

Commit 8702c23

Browse files
authored
Merge pull request #23464 from dcci/rdar49043621
[Reflection] Add an utility to stress test the metadata reader.
2 parents 8ed0ebe + 3a17628 commit 8702c23

File tree

3 files changed

+106
-0
lines changed

3 files changed

+106
-0
lines changed

tools/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ endif()
3737

3838
if(LLVM_USE_SANITIZE_COVERAGE)
3939
add_swift_tool_subdirectory(swift-demangle-fuzzer)
40+
add_swift_tool_subdirectory(swift-reflection-fuzzer)
4041
endif()
4142

4243
if(SWIFT_BUILD_STDLIB AND SWIFT_BUILD_SDK_OVERLAY)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
add_swift_fuzzer_host_tool(swift-reflection-fuzzer
2+
swift-reflection-fuzzer.cpp
3+
LLVM_COMPONENT_DEPENDS support
4+
SWIFT_COMPONENT tools
5+
)
6+
target_link_libraries(swift-reflection-fuzzer
7+
PRIVATE
8+
swiftReflection)
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//===--- swift-reflection-fuzzer.cpp - Swift reflection fuzzer ------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This program tries to fuzz the metadata reader shipped as part of the swift
14+
// runtime and used by the debugger.
15+
// For this to work you need to pass --enable-sanitizer-coverage to build-script
16+
// otherwise the fuzzer doesn't have coverage information to make progress
17+
// (making the whole fuzzing operation really ineffective).
18+
// It is recommended to use the tool together with another sanitizer to expose
19+
// more bugs (asan, lsan, etc...)
20+
//
21+
//===----------------------------------------------------------------------===//
22+
23+
#include "swift/Reflection/ReflectionContext.h"
24+
#include "swift/Reflection/TypeRef.h"
25+
#include "swift/Reflection/TypeRefBuilder.h"
26+
#include "llvm/Object/Archive.h"
27+
#include "llvm/Object/ELF.h"
28+
#include "llvm/Object/ELFObjectFile.h"
29+
#include "llvm/Object/MachOUniversal.h"
30+
#include "llvm/Support/CommandLine.h"
31+
#include <stddef.h>
32+
#include <stdint.h>
33+
34+
using namespace llvm::object;
35+
36+
using namespace swift;
37+
using namespace swift::reflection;
38+
using namespace swift::remote;
39+
40+
using NativeReflectionContext = swift::reflection::ReflectionContext<
41+
External<RuntimeTarget<sizeof(uintptr_t)>>>;
42+
43+
template <typename T> static T unwrap(llvm::Expected<T> value) {
44+
if (value)
45+
return std::move(value.get());
46+
return T();
47+
}
48+
49+
class ObjectMemoryReader : public MemoryReader {
50+
public:
51+
ObjectMemoryReader() {}
52+
53+
bool queryDataLayout(DataLayoutQueryType type, void *inBuffer,
54+
void *outBuffer) override {
55+
switch (type) {
56+
case DLQ_GetPointerSize: {
57+
auto result = static_cast<uint8_t *>(outBuffer);
58+
*result = sizeof(void *);
59+
return true;
60+
}
61+
case DLQ_GetSizeSize: {
62+
auto result = static_cast<uint8_t *>(outBuffer);
63+
*result = sizeof(size_t);
64+
return true;
65+
}
66+
}
67+
68+
return false;
69+
}
70+
71+
RemoteAddress getSymbolAddress(const std::string &name) override {
72+
return RemoteAddress(nullptr);
73+
}
74+
75+
bool isAddressValid(RemoteAddress addr, uint64_t size) const { return true; }
76+
77+
ReadBytesResult readBytes(RemoteAddress address, uint64_t size) override {
78+
return ReadBytesResult((const void *)address.getAddressData(),
79+
[](const void *) {});
80+
}
81+
82+
bool readString(RemoteAddress address, std::string &dest) override {
83+
if (!isAddressValid(address, 1))
84+
return false;
85+
auto cString = StringRef((const char *)address.getAddressData());
86+
dest.append(cString.begin(), cString.end());
87+
return true;
88+
}
89+
};
90+
91+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
92+
auto reader = std::make_shared<ObjectMemoryReader>();
93+
NativeReflectionContext context(std::move(reader));
94+
context.addImage(RemoteAddress(Data));
95+
context.getBuilder().dumpAllSections(std::cout);
96+
return 0; // Non-zero return values are reserved for future use.
97+
}

0 commit comments

Comments
 (0)