-
Notifications
You must be signed in to change notification settings - Fork 10.5k
/
Copy pathImageInspectionCommon.cpp
228 lines (193 loc) · 7.79 KB
/
ImageInspectionCommon.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
//===--- ImageInspectionCommon.cpp - Image inspection routines --*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
///
/// This file unifies common ELF and COFF image inspection routines
///
//===----------------------------------------------------------------------===//
#ifndef SWIFT_RUNTIME_IMAGEINSPECTIONCOMMON_H
#define SWIFT_RUNTIME_IMAGEINSPECTIONCOMMON_H
#if !defined(__MACH__)
#include "swift/shims/Visibility.h"
#include "swift/shims/MetadataSections.h"
#include "ImageInspection.h"
#include "swift/Basic/Lazy.h"
#include "swift/Runtime/Concurrent.h"
#include <algorithm>
#include <atomic>
#include <cstdlib>
namespace swift {
static Lazy<ConcurrentReadableArray<swift::MetadataSections *>> registered;
/// Adjust the \c baseAddress field of a metadata sections structure.
///
/// \param sections A pointer to a valid \c swift::MetadataSections structure.
///
/// This function should be called at least once before the structure or its
/// address is passed to code outside this file to ensure that the structure's
/// \c baseAddress field correctly points to the base address of the image it
/// is describing.
static void fixupMetadataSectionBaseAddress(swift::MetadataSections *sections) {
bool fixupNeeded = false;
#if defined(__ELF__)
// If the base address was set but the image is an ELF image, it is going to
// be __dso_handle which is not the value we expect (Dl_info::dli_fbase), so
// we need to fix it up.
fixupNeeded = true;
#elif !defined(__MACH__)
// For non-ELF, non-Apple platforms, if the base address is nullptr, it
// implies that this image was built against an older version of the runtime
// that did not capture any value for the base address.
auto oldBaseAddress = sections->baseAddress.load(std::memory_order_relaxed);
if (!oldBaseAddress) {
fixupNeeded = true;
}
#endif
if (fixupNeeded) {
// We need to fix up the base address. We'll need a known-good address in
// the same image: `sections` itself will work nicely.
auto symbolInfo = SymbolInfo::lookup(sections);
if (symbolInfo.has_value() && symbolInfo->getBaseAddress()) {
sections->baseAddress.store(symbolInfo->getBaseAddress(),
std::memory_order_relaxed);
}
}
}
}
SWIFT_RUNTIME_EXPORT
void swift_addNewDSOImage(swift::MetadataSections *sections) {
#if 0
// Ensure the base address of the sections structure is correct.
//
// Currently disabled because none of the registration functions below
// actually do anything with the baseAddress field. Instead,
// swift_enumerateAllMetadataSections() is called by other individual
// functions, lower in this file, that yield metadata section pointers.
//
// If one of these registration functions starts needing the baseAddress
// field, this call should be enabled and the calls elsewhere in the file can
// be removed.
swift::fixupMetadataSectionBaseAddress(sections);
#endif
auto baseAddress = sections->baseAddress.load(std::memory_order_relaxed);
const auto &protocols_section = sections->swift5_protocols;
const void *protocols = reinterpret_cast<void *>(protocols_section.start);
if (protocols_section.length)
swift::addImageProtocolsBlockCallback(baseAddress,
protocols, protocols_section.length);
const auto &protocol_conformances = sections->swift5_protocol_conformances;
const void *conformances =
reinterpret_cast<void *>(protocol_conformances.start);
if (protocol_conformances.length)
swift::addImageProtocolConformanceBlockCallback(baseAddress, conformances,
protocol_conformances.length);
const auto &type_metadata = sections->swift5_type_metadata;
const void *metadata = reinterpret_cast<void *>(type_metadata.start);
if (type_metadata.length)
swift::addImageTypeMetadataRecordBlockCallback(baseAddress,
metadata,
type_metadata.length);
const auto &dynamic_replacements = sections->swift5_replace;
const auto *replacements =
reinterpret_cast<void *>(dynamic_replacements.start);
if (dynamic_replacements.length) {
const auto &dynamic_replacements_some = sections->swift5_replac2;
const auto *replacements_some =
reinterpret_cast<void *>(dynamic_replacements_some.start);
swift::addImageDynamicReplacementBlockCallback(baseAddress,
replacements, dynamic_replacements.length, replacements_some,
dynamic_replacements_some.length);
}
const auto &accessible_funcs_section = sections->swift5_accessible_functions;
const void *functions =
reinterpret_cast<void *>(accessible_funcs_section.start);
if (accessible_funcs_section.length) {
swift::addImageAccessibleFunctionsBlockCallback(
baseAddress, functions, accessible_funcs_section.length);
}
// Register this section for future enumeration by clients. This should occur
// after this function has done all other relevant work to avoid a race
// condition when someone calls swift_enumerateAllMetadataSections() on
// another thread.
swift::registered->push_back(sections);
}
SWIFT_RUNTIME_EXPORT
void swift_enumerateAllMetadataSections(
bool (* body)(const swift::MetadataSections *sections, void *context),
void *context
) {
auto snapshot = swift::registered->snapshot();
for (swift::MetadataSections *sections : snapshot) {
// Ensure the base address is fixed up before yielding the pointer.
swift::fixupMetadataSectionBaseAddress(sections);
// Yield the pointer and (if the callback returns false) break the loop.
if (!(* body)(sections, context)) {
return;
}
}
}
void swift::initializeProtocolLookup() {
}
void swift::initializeProtocolConformanceLookup() {
}
void swift::initializeTypeMetadataRecordLookup() {
}
void swift::initializeDynamicReplacementLookup() {
}
void swift::initializeAccessibleFunctionsLookup() {
}
#ifndef NDEBUG
SWIFT_RUNTIME_EXPORT
const swift::MetadataSections *swift_getMetadataSection(size_t index) {
swift::MetadataSections *result = nullptr;
auto snapshot = swift::registered->snapshot();
if (index < snapshot.count()) {
result = snapshot[index];
}
if (result) {
// Ensure the base address is fixed up before returning it.
swift::fixupMetadataSectionBaseAddress(result);
}
return result;
}
SWIFT_RUNTIME_EXPORT
const char *
swift_getMetadataSectionName(const swift::MetadataSections *section) {
if (auto info = swift::SymbolInfo::lookup(section)) {
if (info->getFilename()) {
return info->getFilename();
}
}
return "";
}
SWIFT_RUNTIME_EXPORT
void swift_getMetadataSectionBaseAddress(const swift::MetadataSections *section,
void const **out_actual,
void const **out_expected) {
if (auto info = swift::SymbolInfo::lookup(section)) {
*out_actual = info->getBaseAddress();
} else {
*out_actual = nullptr;
}
// fixupMetadataSectionBaseAddress() was already called by
// swift_getMetadataSection(), presumably on the same thread, so we don't need
// to call it again here.
*out_expected = section->baseAddress.load(std::memory_order_relaxed);
}
SWIFT_RUNTIME_EXPORT
size_t swift_getMetadataSectionCount() {
auto snapshot = swift::registered->snapshot();
return snapshot.count();
}
#endif // NDEBUG
#endif // !defined(__MACH__)
#endif // SWIFT_RUNTIME_IMAGEINSPECTIONCOMMON_H