Skip to content

Commit f3d784f

Browse files
committed
Factor out Object File handling from swift-reflection-dump to separate CMake target: StaticMirror
This target will then be used to have a broader set of tools for reading metadata from object files.
1 parent d6d4216 commit f3d784f

File tree

8 files changed

+720
-568
lines changed

8 files changed

+720
-568
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
//===---------------- ObjectFileCOntext.h - Swift Compiler ---------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2021 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+
#ifndef SWIFT_OBJECT_FILE_CONTEXT_H
14+
#define SWIFT_OBJECT_FILE_CONTEXT_H
15+
16+
#include "swift/Reflection/ReflectionContext.h"
17+
18+
namespace llvm {
19+
namespace object {
20+
template <typename Type>
21+
class ELFObjectFile;
22+
class ELFObjectFileBase;
23+
class MachOObjectFile;
24+
} // namespace object
25+
} // namespace llvm
26+
27+
namespace swift {
28+
namespace static_mirror {
29+
30+
using ReadBytesResult = swift::remote::MemoryReader::ReadBytesResult;
31+
32+
class Image {
33+
private:
34+
struct Segment {
35+
uint64_t Addr;
36+
StringRef Contents;
37+
};
38+
const llvm::object::ObjectFile *O;
39+
uint64_t HeaderAddress;
40+
std::vector<Segment> Segments;
41+
struct DynamicRelocation {
42+
StringRef Symbol;
43+
uint64_t Offset;
44+
};
45+
llvm::DenseMap<uint64_t, DynamicRelocation> DynamicRelocations;
46+
47+
void scanMachO(const llvm::object::MachOObjectFile *O);
48+
49+
template <typename ELFT>
50+
void scanELFType(const llvm::object::ELFObjectFile<ELFT> *O);
51+
52+
void scanELF(const llvm::object::ELFObjectFileBase *O);
53+
54+
void scanCOFF(const llvm::object::COFFObjectFile *O);
55+
56+
bool isMachOWithPtrAuth() const;
57+
58+
public:
59+
explicit Image(const llvm::object::ObjectFile *O);
60+
61+
const llvm::object::ObjectFile *getObjectFile() const { return O; }
62+
63+
unsigned getBytesInAddress() const { return O->getBytesInAddress(); }
64+
65+
uint64_t getStartAddress() const { return HeaderAddress; }
66+
67+
uint64_t getEndAddress() const;
68+
69+
StringRef getContentsAtAddress(uint64_t Addr, uint64_t Size) const;
70+
71+
remote::RemoteAbsolutePointer resolvePointer(uint64_t Addr,
72+
uint64_t pointerValue) const;
73+
};
74+
75+
/// MemoryReader that reads from the on-disk representation of an executable
76+
/// or dynamic library image.
77+
///
78+
/// This reader uses a remote addressing scheme where the most significant
79+
/// 16 bits of the address value serve as an index into the array of loaded
80+
/// images, and the low 48 bits correspond to the preferred virtual address
81+
/// mapping of the image.
82+
class ObjectMemoryReader : public reflection::MemoryReader {
83+
struct ImageEntry {
84+
Image TheImage;
85+
uint64_t Slide;
86+
};
87+
std::vector<ImageEntry> Images;
88+
89+
std::pair<const Image *, uint64_t>
90+
decodeImageIndexAndAddress(uint64_t Addr) const;
91+
92+
uint64_t encodeImageIndexAndAddress(const Image *image,
93+
uint64_t imageAddr) const;
94+
95+
StringRef getContentsAtAddress(uint64_t Addr, uint64_t Size);
96+
97+
public:
98+
explicit ObjectMemoryReader(
99+
const std::vector<const llvm::object::ObjectFile *> &ObjectFiles);
100+
101+
ArrayRef<ImageEntry> getImages() const { return Images; }
102+
103+
bool queryDataLayout(DataLayoutQueryType type, void *inBuffer,
104+
void *outBuffer) override;
105+
106+
reflection::RemoteAddress getImageStartAddress(unsigned i) const;
107+
108+
// TODO: We could consult the dynamic symbol tables of the images to
109+
// implement this.
110+
reflection::RemoteAddress getSymbolAddress(const std::string &name) override {
111+
return reflection::RemoteAddress(nullptr);
112+
}
113+
114+
ReadBytesResult readBytes(reflection::RemoteAddress Addr,
115+
uint64_t Size) override;
116+
117+
bool readString(reflection::RemoteAddress Addr, std::string &Dest) override;
118+
119+
remote::RemoteAbsolutePointer resolvePointer(reflection::RemoteAddress Addr,
120+
uint64_t pointerValue) override;
121+
};
122+
123+
using ReflectionContextOwner = std::unique_ptr<void, void (*)(void *)>;
124+
125+
struct ReflectionContextHolder {
126+
ReflectionContextOwner Owner;
127+
reflection::TypeRefBuilder &Builder;
128+
ObjectMemoryReader &Reader;
129+
};
130+
131+
template <typename T>
132+
T unwrap(llvm::Expected<T> value) {
133+
if (value)
134+
return std::move(value.get());
135+
llvm::errs() << "swift-reflection-test error: " << toString(value.takeError())
136+
<< "\n";
137+
exit(EXIT_FAILURE);
138+
}
139+
140+
ReflectionContextHolder makeReflectionContextForObjectFiles(
141+
const std::vector<const llvm::object::ObjectFile *> &objectFiles);
142+
143+
ReflectionContextHolder makeReflectionContextForMetadataReader(
144+
std::shared_ptr<ObjectMemoryReader> reader);
145+
146+
} // end namespace static_mirror
147+
} // end namespace swift
148+
149+
#endif // SWIFT_OBJECT_FILE_CONTEXT_H

lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ add_subdirectory(SwiftRemoteMirror)
4545
add_subdirectory(SIL)
4646
add_subdirectory(SILGen)
4747
add_subdirectory(SILOptimizer)
48+
add_subdirectory(StaticMirror)
4849
add_subdirectory(SymbolGraphGen)
4950
add_subdirectory(Syntax)
5051
add_subdirectory(SyntaxParse)

lib/StaticMirror/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
3+
add_swift_host_library(swiftStaticMirror STATIC
4+
ObjectFileContext.cpp)
5+
6+
target_link_libraries(swiftStaticMirror PRIVATE
7+
swiftFrontend
8+
swiftReflection)

0 commit comments

Comments
 (0)