Mercurial > hg > CbC > CbC_llvm
comparison lld/MachO/ExportTrie.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | c4bab56944e8 |
comparison
equal
deleted
inserted
replaced
173:0572611fdcc8 | 207:2e18cbf3894f |
---|---|
42 #include "llvm/ADT/Optional.h" | 42 #include "llvm/ADT/Optional.h" |
43 #include "llvm/BinaryFormat/MachO.h" | 43 #include "llvm/BinaryFormat/MachO.h" |
44 #include "llvm/Support/LEB128.h" | 44 #include "llvm/Support/LEB128.h" |
45 | 45 |
46 using namespace llvm; | 46 using namespace llvm; |
47 using namespace llvm::MachO; | |
48 using namespace lld; | 47 using namespace lld; |
49 using namespace lld::macho; | 48 using namespace lld::macho; |
50 | 49 |
51 namespace { | 50 namespace { |
52 | 51 |
57 struct TrieNode *child; | 56 struct TrieNode *child; |
58 }; | 57 }; |
59 | 58 |
60 struct ExportInfo { | 59 struct ExportInfo { |
61 uint64_t address; | 60 uint64_t address; |
62 // TODO: Add proper support for re-exports & stub-and-resolver flags. | 61 uint8_t flags = 0; |
62 ExportInfo(const Symbol &sym, uint64_t imageBase) | |
63 : address(sym.getVA() - imageBase) { | |
64 using namespace llvm::MachO; | |
65 // Set the symbol type. | |
66 if (sym.isWeakDef()) | |
67 flags |= EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION; | |
68 // TODO: Add proper support for re-exports & stub-and-resolver flags. | |
69 | |
70 // Set the symbol kind. | |
71 if (sym.isTlv()) { | |
72 flags |= EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL; | |
73 } else if (auto *defined = dyn_cast<Defined>(&sym)) { | |
74 if (defined->isAbsolute()) | |
75 flags |= EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE; | |
76 } | |
77 } | |
63 }; | 78 }; |
64 | 79 |
65 } // namespace | 80 } // namespace |
66 | 81 |
67 namespace lld { | 82 struct macho::TrieNode { |
68 namespace macho { | |
69 | |
70 struct TrieNode { | |
71 std::vector<Edge> edges; | 83 std::vector<Edge> edges; |
72 Optional<ExportInfo> info; | 84 Optional<ExportInfo> info; |
73 // Estimated offset from the start of the serialized trie to the current node. | 85 // Estimated offset from the start of the serialized trie to the current node. |
74 // This will converge to the true offset when updateOffset() is run to a | 86 // This will converge to the true offset when updateOffset() is run to a |
75 // fixpoint. | 87 // fixpoint. |
84 // Size of the whole node (including the terminalSize and the outgoing edges.) | 96 // Size of the whole node (including the terminalSize and the outgoing edges.) |
85 // In contrast, terminalSize only records the size of the other data in the | 97 // In contrast, terminalSize only records the size of the other data in the |
86 // node. | 98 // node. |
87 size_t nodeSize; | 99 size_t nodeSize; |
88 if (info) { | 100 if (info) { |
89 uint64_t flags = 0; | |
90 uint32_t terminalSize = | 101 uint32_t terminalSize = |
91 getULEB128Size(flags) + getULEB128Size(info->address); | 102 getULEB128Size(info->flags) + getULEB128Size(info->address); |
92 // Overall node size so far is the uleb128 size of the length of the symbol | 103 // Overall node size so far is the uleb128 size of the length of the symbol |
93 // info + the symbol info itself. | 104 // info + the symbol info itself. |
94 nodeSize = terminalSize + getULEB128Size(terminalSize); | 105 nodeSize = terminalSize + getULEB128Size(terminalSize); |
95 } else { | 106 } else { |
96 nodeSize = 1; // Size of terminalSize (which has a value of 0) | 107 nodeSize = 1; // Size of terminalSize (which has a value of 0) |
97 } | 108 } |
98 // Compute size of all child edges. | 109 // Compute size of all child edges. |
99 ++nodeSize; // Byte for number of children. | 110 ++nodeSize; // Byte for number of children. |
100 for (Edge &edge : edges) { | 111 for (const Edge &edge : edges) { |
101 nodeSize += edge.substring.size() + 1 // String length. | 112 nodeSize += edge.substring.size() + 1 // String length. |
102 + getULEB128Size(edge.child->offset); // Offset len. | 113 + getULEB128Size(edge.child->offset); // Offset len. |
103 } | 114 } |
104 // On input, 'nextOffset' is the new preferred location for this node. | 115 // On input, 'nextOffset' is the new preferred location for this node. |
105 bool result = (offset != nextOffset); | 116 bool result = (offset != nextOffset); |
111 | 122 |
112 void TrieNode::writeTo(uint8_t *buf) const { | 123 void TrieNode::writeTo(uint8_t *buf) const { |
113 buf += offset; | 124 buf += offset; |
114 if (info) { | 125 if (info) { |
115 // TrieNodes with Symbol info: size, flags address | 126 // TrieNodes with Symbol info: size, flags address |
116 uint64_t flags = 0; // TODO: emit proper flags | |
117 uint32_t terminalSize = | 127 uint32_t terminalSize = |
118 getULEB128Size(flags) + getULEB128Size(info->address); | 128 getULEB128Size(info->flags) + getULEB128Size(info->address); |
119 buf += encodeULEB128(terminalSize, buf); | 129 buf += encodeULEB128(terminalSize, buf); |
120 buf += encodeULEB128(flags, buf); | 130 buf += encodeULEB128(info->flags, buf); |
121 buf += encodeULEB128(info->address, buf); | 131 buf += encodeULEB128(info->address, buf); |
122 } else { | 132 } else { |
123 // TrieNode with no Symbol info. | 133 // TrieNode with no Symbol info. |
124 *buf++ = 0; // terminalSize | 134 *buf++ = 0; // terminalSize |
125 } | 135 } |
195 sortAndBuild(vec.slice(0, i), node, lastPos, pos); | 205 sortAndBuild(vec.slice(0, i), node, lastPos, pos); |
196 sortAndBuild(vec.slice(j), node, lastPos, pos); | 206 sortAndBuild(vec.slice(j), node, lastPos, pos); |
197 | 207 |
198 if (isTerminal) { | 208 if (isTerminal) { |
199 assert(j - i == 1); // no duplicate symbols | 209 assert(j - i == 1); // no duplicate symbols |
200 node->info = {pivotSymbol->getVA()}; | 210 node->info = ExportInfo(*pivotSymbol, imageBase); |
201 } else { | 211 } else { |
202 // This is the tail-call-optimized version of the following: | 212 // This is the tail-call-optimized version of the following: |
203 // sortAndBuild(vec.slice(i, j - i), node, lastPos, pos + 1); | 213 // sortAndBuild(vec.slice(i, j - i), node, lastPos, pos + 1); |
204 vec = vec.slice(i, j - i); | 214 vec = vec.slice(i, j - i); |
205 ++pos; | 215 ++pos; |
275 buf += ulebSize; | 285 buf += ulebSize; |
276 parse(start + offset, cumulativeString + substring); | 286 parse(start + offset, cumulativeString + substring); |
277 } | 287 } |
278 } | 288 } |
279 | 289 |
280 void parseTrie(const uint8_t *buf, size_t size, | 290 void macho::parseTrie(const uint8_t *buf, size_t size, |
281 const TrieEntryCallback &callback) { | 291 const TrieEntryCallback &callback) { |
282 if (size == 0) | 292 if (size == 0) |
283 return; | 293 return; |
284 | 294 |
285 TrieParser(buf, size, callback).parse(); | 295 TrieParser(buf, size, callback).parse(); |
286 } | 296 } |
287 | |
288 } // namespace macho | |
289 } // namespace lld |