annotate lld/MachO/Symbols.h @ 207:2e18cbf3894f

LLVM12
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 08 Jun 2021 06:07:14 +0900
parents 0572611fdcc8
children 5f17cb93ff66
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 //===- Symbols.h ------------------------------------------------*- C++ -*-===//
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 //
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 //
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 #ifndef LLD_MACHO_SYMBOLS_H
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 #define LLD_MACHO_SYMBOLS_H
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
12 #include "InputFiles.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 #include "InputSection.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 #include "Target.h"
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
15 #include "lld/Common/ErrorHandler.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 #include "lld/Common/Strings.h"
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 #include "llvm/Object/Archive.h"
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
18 #include "llvm/Support/MathExtras.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
19
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 namespace lld {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 namespace macho {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 class InputSection;
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
24 class MachHeaderSection;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
25
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 struct StringRefZ {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 StringRefZ(const char *s) : data(s), size(-1) {}
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 StringRefZ(StringRef s) : data(s.data()), size(s.size()) {}
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 const char *data;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 const uint32_t size;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 };
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
33
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 class Symbol {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 public:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 enum Kind {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 DefinedKind,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 UndefinedKind,
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
39 CommonKind,
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 DylibKind,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 LazyKind,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 };
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
43
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
44 virtual ~Symbol() {}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
45
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
46 Kind kind() const { return symbolKind; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
47
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
48 StringRef getName() const {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
49 if (nameSize == (uint32_t)-1)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
50 nameSize = strlen(nameData);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
51 return {nameData, nameSize};
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
52 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
53
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
54 bool isLive() const;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
55
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
56 virtual uint64_t getVA() const { return 0; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
57
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
58 virtual uint64_t getFileOffset() const {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
59 llvm_unreachable("attempt to get an offset from a non-defined symbol");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
60 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
61
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
62 virtual bool isWeakDef() const { llvm_unreachable("cannot be weak def"); }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
63
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
64 // Only undefined or dylib symbols can be weak references. A weak reference
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
65 // need not be satisfied at runtime, e.g. due to the symbol not being
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
66 // available on a given target platform.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
67 virtual bool isWeakRef() const { llvm_unreachable("cannot be a weak ref"); }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
68
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
69 virtual bool isTlv() const { llvm_unreachable("cannot be TLV"); }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
70
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
71 // Whether this symbol is in the GOT or TLVPointer sections.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
72 bool isInGot() const { return gotIndex != UINT32_MAX; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
73
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
74 // Whether this symbol is in the StubsSection.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
75 bool isInStubs() const { return stubsIndex != UINT32_MAX; }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
76
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
77 uint64_t getStubVA() const;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
78 uint64_t getGotVA() const;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
79 uint64_t getTlvVA() const;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
80 uint64_t resolveBranchVA() const {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
81 assert(isa<Defined>(this) || isa<DylibSymbol>(this));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
82 return isInStubs() ? getStubVA() : getVA();
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
83 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
84 uint64_t resolveGotVA() const { return isInGot() ? getGotVA() : getVA(); }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
85 uint64_t resolveTlvVA() const { return isInGot() ? getTlvVA() : getVA(); }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
86
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
87 // The index of this symbol in the GOT or the TLVPointer section, depending
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
88 // on whether it is a thread-local. A given symbol cannot be referenced by
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
89 // both these sections at once.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
90 uint32_t gotIndex = UINT32_MAX;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
91
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
92 uint32_t stubsIndex = UINT32_MAX;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
93
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
94 uint32_t symtabIndex = UINT32_MAX;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
95
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
96 InputFile *getFile() const { return file; }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
97
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 protected:
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
99 Symbol(Kind k, StringRefZ name, InputFile *file)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
100 : symbolKind(k), nameData(name.data), nameSize(name.size), file(file),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
101 isUsedInRegularObj(!file || isa<ObjFile>(file)),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
102 used(!config->deadStrip) {}
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
103
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 Kind symbolKind;
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
105 const char *nameData;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
106 mutable uint32_t nameSize;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
107 InputFile *file;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
108
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
109 public:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
110 // True if this symbol was referenced by a regular (non-bitcode) object.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
111 bool isUsedInRegularObj : 1;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
112
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
113 // True if an undefined or dylib symbol is used from a live section.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
114 bool used : 1;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 };
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
116
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 class Defined : public Symbol {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 public:
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
119 Defined(StringRefZ name, InputFile *file, InputSection *isec, uint64_t value,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
120 uint64_t size, bool isWeakDef, bool isExternal, bool isPrivateExtern,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
121 bool isThumb, bool isReferencedDynamically, bool noDeadStrip)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
122 : Symbol(DefinedKind, name, file), isec(isec), value(value), size(size),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
123 overridesWeakDef(false), privateExtern(isPrivateExtern),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
124 includeInSymtab(true), thumb(isThumb),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
125 referencedDynamically(isReferencedDynamically),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
126 noDeadStrip(noDeadStrip), weakDef(isWeakDef), external(isExternal) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
127 if (isec)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
128 isec->numRefs++;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
129 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
130
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
131 bool isWeakDef() const override { return weakDef; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
132 bool isExternalWeakDef() const {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
133 return isWeakDef() && isExternal() && !privateExtern;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
134 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
135 bool isTlv() const override {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
136 return !isAbsolute() && isThreadLocalVariables(isec->flags);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
137 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
138
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
139 bool isExternal() const { return external; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
140 bool isAbsolute() const { return isec == nullptr; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
141
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
142 uint64_t getVA() const override;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
143 uint64_t getFileOffset() const override;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
144
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
145 static bool classof(const Symbol *s) { return s->kind() == DefinedKind; }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
146
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 InputSection *isec;
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
148 // Contains the offset from the containing subsection. Note that this is
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
149 // different from nlist::n_value, which is the absolute address of the symbol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
150 uint64_t value;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
151 // size is only calculated for regular (non-bitcode) symbols.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
152 uint64_t size;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
153
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
154 bool overridesWeakDef : 1;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
155 // Whether this symbol should appear in the output binary's export trie.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
156 bool privateExtern : 1;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
157 // Whether this symbol should appear in the output symbol table.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
158 bool includeInSymtab : 1;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
159 // Only relevant when compiling for Thumb-supporting arm32 archs.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
160 bool thumb : 1;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
161 // Symbols marked referencedDynamically won't be removed from the output's
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
162 // symbol table by tools like strip. In theory, this could be set on arbitrary
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
163 // symbols in input object files. In practice, it's used solely for the
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
164 // synthetic __mh_execute_header symbol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
165 // This is information for the static linker, and it's also written to the
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
166 // output file's symbol table for tools running later (such as `strip`).
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
167 bool referencedDynamically : 1;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
168 // Set on symbols that should not be removed by dead code stripping.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
169 // Set for example on `__attribute__((used))` globals, or on some Objective-C
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
170 // metadata. This is information only for the static linker and not written
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
171 // to the output.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
172 bool noDeadStrip : 1;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
173
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
174 private:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
175 const bool weakDef : 1;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
176 const bool external : 1;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 };
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
178
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
179 // This enum does double-duty: as a symbol property, it indicates whether & how
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
180 // a dylib symbol is referenced. As a DylibFile property, it indicates the kind
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
181 // of referenced symbols contained within the file. If there are both weak
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
182 // and strong references to the same file, we will count the file as
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
183 // strongly-referenced.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
184 enum class RefState : uint8_t { Unreferenced = 0, Weak = 1, Strong = 2 };
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
185
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 class Undefined : public Symbol {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 public:
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
188 Undefined(StringRefZ name, InputFile *file, RefState refState)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
189 : Symbol(UndefinedKind, name, file), refState(refState) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
190 assert(refState != RefState::Unreferenced);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
191 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
192
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
193 bool isWeakRef() const override { return refState == RefState::Weak; }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
194
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 static bool classof(const Symbol *s) { return s->kind() == UndefinedKind; }
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
196
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
197 RefState refState : 2;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
198 };
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
199
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
200 // On Unix, it is traditionally allowed to write variable definitions without
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
201 // initialization expressions (such as "int foo;") to header files. These are
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
202 // called tentative definitions.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
203 //
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
204 // Using tentative definitions is usually considered a bad practice; you should
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
205 // write only declarations (such as "extern int foo;") to header files.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
206 // Nevertheless, the linker and the compiler have to do something to support
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
207 // bad code by allowing duplicate definitions for this particular case.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
208 //
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
209 // The compiler creates common symbols when it sees tentative definitions.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
210 // (You can suppress this behavior and let the compiler create a regular
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
211 // defined symbol by passing -fno-common. -fno-common is the default in clang
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
212 // as of LLVM 11.0.) When linking the final binary, if there are remaining
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
213 // common symbols after name resolution is complete, the linker converts them
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
214 // to regular defined symbols in a __common section.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
215 class CommonSymbol : public Symbol {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
216 public:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
217 CommonSymbol(StringRefZ name, InputFile *file, uint64_t size, uint32_t align,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
218 bool isPrivateExtern)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
219 : Symbol(CommonKind, name, file), size(size),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
220 align(align != 1 ? align : llvm::PowerOf2Ceil(size)),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
221 privateExtern(isPrivateExtern) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
222 // TODO: cap maximum alignment
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
223 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
224
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
225 static bool classof(const Symbol *s) { return s->kind() == CommonKind; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
226
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
227 const uint64_t size;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
228 const uint32_t align;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
229 const bool privateExtern;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 };
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
231
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
232 class DylibSymbol : public Symbol {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 public:
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
234 DylibSymbol(DylibFile *file, StringRefZ name, bool isWeakDef,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
235 RefState refState, bool isTlv)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
236 : Symbol(DylibKind, name, file), refState(refState), weakDef(isWeakDef),
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
237 tlv(isTlv) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
238 if (file && refState > RefState::Unreferenced)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
239 file->numReferencedSymbols++;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
240 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
241
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
242 uint64_t getVA() const override;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
243 bool isWeakDef() const override { return weakDef; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
244 bool isWeakRef() const override { return refState == RefState::Weak; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
245 bool isReferenced() const { return refState != RefState::Unreferenced; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
246 bool isTlv() const override { return tlv; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
247 bool isDynamicLookup() const { return file == nullptr; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
248 bool hasStubsHelper() const { return stubsHelperIndex != UINT32_MAX; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
249
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
250 DylibFile *getFile() const {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
251 assert(!isDynamicLookup());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
252 return cast<DylibFile>(file);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
253 }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
254
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
255 static bool classof(const Symbol *s) { return s->kind() == DylibKind; }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
256
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
257 uint32_t stubsHelperIndex = UINT32_MAX;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 uint32_t lazyBindOffset = UINT32_MAX;
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
259
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
260 RefState getRefState() const { return refState; }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
261
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
262 void reference(RefState newState) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
263 assert(newState > RefState::Unreferenced);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
264 if (refState == RefState::Unreferenced && file)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
265 getFile()->numReferencedSymbols++;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
266 refState = std::max(refState, newState);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
267 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
268
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
269 void unreference() {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
270 // dynamic_lookup symbols have no file.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
271 if (refState > RefState::Unreferenced && file) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
272 assert(getFile()->numReferencedSymbols > 0);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
273 getFile()->numReferencedSymbols--;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
274 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
275 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
276
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
277 private:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
278 RefState refState : 2;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
279 const bool weakDef : 1;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
280 const bool tlv : 1;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
281 };
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
282
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
283 class LazySymbol : public Symbol {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
284 public:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
285 LazySymbol(ArchiveFile *file, const llvm::object::Archive::Symbol &sym)
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
286 : Symbol(LazyKind, sym.getName(), file), sym(sym) {}
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
287
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
288 ArchiveFile *getFile() const { return cast<ArchiveFile>(file); }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
289 void fetchArchiveMember();
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
290
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
292
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
293 private:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
294 const llvm::object::Archive::Symbol sym;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 };
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
296
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 union SymbolUnion {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 alignas(Defined) char a[sizeof(Defined)];
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 alignas(Undefined) char b[sizeof(Undefined)];
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
300 alignas(CommonSymbol) char c[sizeof(CommonSymbol)];
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
301 alignas(DylibSymbol) char d[sizeof(DylibSymbol)];
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
302 alignas(LazySymbol) char e[sizeof(LazySymbol)];
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
303 };
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
304
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
305 template <typename T, typename... ArgT>
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
306 T *replaceSymbol(Symbol *s, ArgT &&...arg) {
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
307 static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
308 static_assert(alignof(T) <= alignof(SymbolUnion),
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
309 "SymbolUnion not aligned enough");
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
310 assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
311 "Not a Symbol");
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
312
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
313 bool isUsedInRegularObj = s->isUsedInRegularObj;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
314 T *sym = new (s) T(std::forward<ArgT>(arg)...);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
315 sym->isUsedInRegularObj |= isUsedInRegularObj;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
316 return sym;
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
317 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
318
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
319 } // namespace macho
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
320
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
321 std::string toString(const macho::Symbol &);
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
322 std::string toMachOString(const llvm::object::Archive::Symbol &);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
323
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 } // namespace lld
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
325
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
diff changeset
326 #endif