File indexing completed on 2026-05-10 08:44:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #ifndef LLVM_OBJECT_IRSYMTAB_H
0024 #define LLVM_OBJECT_IRSYMTAB_H
0025
0026 #include "llvm/ADT/ArrayRef.h"
0027 #include "llvm/ADT/StringRef.h"
0028 #include "llvm/ADT/iterator_range.h"
0029 #include "llvm/IR/Comdat.h"
0030 #include "llvm/IR/GlobalValue.h"
0031 #include "llvm/Object/SymbolicFile.h"
0032 #include "llvm/Support/Allocator.h"
0033 #include "llvm/Support/Endian.h"
0034 #include "llvm/Support/Error.h"
0035 #include <cassert>
0036 #include <cstdint>
0037 #include <vector>
0038
0039 namespace llvm {
0040
0041 struct BitcodeFileContents;
0042 class StringTableBuilder;
0043
0044 namespace irsymtab {
0045
0046 namespace storage {
0047
0048
0049
0050
0051
0052 using Word = support::ulittle32_t;
0053
0054
0055 struct Str {
0056 Word Offset, Size;
0057
0058 StringRef get(StringRef Strtab) const {
0059 return {Strtab.data() + Offset, Size};
0060 }
0061 };
0062
0063
0064 template <typename T> struct Range {
0065 Word Offset, Size;
0066
0067 ArrayRef<T> get(StringRef Symtab) const {
0068 return {reinterpret_cast<const T *>(Symtab.data() + Offset), Size};
0069 }
0070 };
0071
0072
0073
0074 struct Module {
0075 Word Begin, End;
0076
0077
0078 Word UncBegin;
0079 };
0080
0081
0082 struct Comdat {
0083 Str Name;
0084
0085
0086 Word SelectionKind;
0087 };
0088
0089
0090
0091 struct Symbol {
0092
0093 Str Name;
0094
0095
0096
0097 Str IRName;
0098
0099
0100 Word ComdatIndex;
0101
0102 Word Flags;
0103 enum FlagBits {
0104 FB_visibility,
0105 FB_has_uncommon = FB_visibility + 2,
0106 FB_undefined,
0107 FB_weak,
0108 FB_common,
0109 FB_indirect,
0110 FB_used,
0111 FB_tls,
0112 FB_may_omit,
0113 FB_global,
0114 FB_format_specific,
0115 FB_unnamed_addr,
0116 FB_executable,
0117 };
0118 };
0119
0120
0121
0122 struct Uncommon {
0123 Word CommonSize, CommonAlign;
0124
0125
0126
0127 Str COFFWeakExternFallbackName;
0128
0129
0130 Str SectionName;
0131 };
0132
0133
0134 struct Header {
0135
0136
0137
0138 Word Version;
0139 enum { kCurrentVersion = 3 };
0140
0141
0142
0143
0144
0145 Str Producer;
0146
0147 Range<Module> Modules;
0148 Range<Comdat> Comdats;
0149 Range<Symbol> Symbols;
0150 Range<Uncommon> Uncommons;
0151
0152 Str TargetTriple, SourceFileName;
0153
0154
0155 Str COFFLinkerOpts;
0156
0157
0158 Range<Str> DependentLibraries;
0159 };
0160
0161 }
0162
0163
0164
0165 Error build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab,
0166 StringTableBuilder &StrtabBuilder, BumpPtrAllocator &Alloc);
0167
0168
0169
0170 struct Symbol {
0171
0172 mutable StringRef Name;
0173 StringRef IRName;
0174 int ComdatIndex;
0175 uint32_t Flags;
0176
0177
0178 uint32_t CommonSize, CommonAlign;
0179 StringRef COFFWeakExternFallbackName;
0180 StringRef SectionName;
0181
0182
0183 StringRef getName() const { return Name; }
0184
0185
0186
0187 StringRef getIRName() const { return IRName; }
0188
0189
0190
0191 int getComdatIndex() const { return ComdatIndex; }
0192
0193 using S = storage::Symbol;
0194
0195 GlobalValue::VisibilityTypes getVisibility() const {
0196 return GlobalValue::VisibilityTypes((Flags >> S::FB_visibility) & 3);
0197 }
0198
0199 bool isUndefined() const { return (Flags >> S::FB_undefined) & 1; }
0200 bool isWeak() const { return (Flags >> S::FB_weak) & 1; }
0201 bool isCommon() const { return (Flags >> S::FB_common) & 1; }
0202 bool isIndirect() const { return (Flags >> S::FB_indirect) & 1; }
0203 bool isUsed() const { return (Flags >> S::FB_used) & 1; }
0204 bool isTLS() const { return (Flags >> S::FB_tls) & 1; }
0205
0206 bool canBeOmittedFromSymbolTable() const {
0207 return (Flags >> S::FB_may_omit) & 1;
0208 }
0209
0210 bool isGlobal() const { return (Flags >> S::FB_global) & 1; }
0211 bool isFormatSpecific() const { return (Flags >> S::FB_format_specific) & 1; }
0212 bool isUnnamedAddr() const { return (Flags >> S::FB_unnamed_addr) & 1; }
0213 bool isExecutable() const { return (Flags >> S::FB_executable) & 1; }
0214
0215 uint64_t getCommonSize() const {
0216 assert(isCommon());
0217 return CommonSize;
0218 }
0219
0220 uint32_t getCommonAlignment() const {
0221 assert(isCommon());
0222 return CommonAlign;
0223 }
0224
0225
0226
0227 StringRef getCOFFWeakExternalFallback() const {
0228 assert(isWeak() && isIndirect());
0229 return COFFWeakExternFallbackName;
0230 }
0231
0232 StringRef getSectionName() const { return SectionName; }
0233 };
0234
0235
0236
0237 class Reader {
0238 StringRef Symtab, Strtab;
0239
0240 ArrayRef<storage::Module> Modules;
0241 ArrayRef<storage::Comdat> Comdats;
0242 ArrayRef<storage::Symbol> Symbols;
0243 ArrayRef<storage::Uncommon> Uncommons;
0244 ArrayRef<storage::Str> DependentLibraries;
0245
0246 StringRef str(storage::Str S) const { return S.get(Strtab); }
0247
0248 template <typename T> ArrayRef<T> range(storage::Range<T> R) const {
0249 return R.get(Symtab);
0250 }
0251
0252 const storage::Header &header() const {
0253 return *reinterpret_cast<const storage::Header *>(Symtab.data());
0254 }
0255
0256 public:
0257 class SymbolRef;
0258
0259 Reader() = default;
0260 Reader(StringRef Symtab, StringRef Strtab) : Symtab(Symtab), Strtab(Strtab) {
0261 Modules = range(header().Modules);
0262 Comdats = range(header().Comdats);
0263 Symbols = range(header().Symbols);
0264 Uncommons = range(header().Uncommons);
0265 DependentLibraries = range(header().DependentLibraries);
0266 }
0267
0268 using symbol_range = iterator_range<object::content_iterator<SymbolRef>>;
0269
0270
0271
0272
0273 symbol_range symbols() const;
0274
0275 size_t getNumModules() const { return Modules.size(); }
0276
0277
0278
0279
0280 symbol_range module_symbols(unsigned I) const;
0281
0282 StringRef getTargetTriple() const { return str(header().TargetTriple); }
0283
0284
0285 StringRef getSourceFileName() const { return str(header().SourceFileName); }
0286
0287
0288 std::vector<std::pair<StringRef, llvm::Comdat::SelectionKind>>
0289 getComdatTable() const {
0290 std::vector<std::pair<StringRef, llvm::Comdat::SelectionKind>> ComdatTable;
0291 ComdatTable.reserve(Comdats.size());
0292 for (auto C : Comdats)
0293 ComdatTable.push_back({str(C.Name), llvm::Comdat::SelectionKind(
0294 uint32_t(C.SelectionKind))});
0295 return ComdatTable;
0296 }
0297
0298
0299 StringRef getCOFFLinkerOpts() const { return str(header().COFFLinkerOpts); }
0300
0301
0302 std::vector<StringRef> getDependentLibraries() const {
0303 std::vector<StringRef> Specifiers;
0304 Specifiers.reserve(DependentLibraries.size());
0305 for (auto S : DependentLibraries) {
0306 Specifiers.push_back(str(S));
0307 }
0308 return Specifiers;
0309 }
0310 };
0311
0312
0313
0314 class Reader::SymbolRef : public Symbol {
0315 const storage::Symbol *SymI, *SymE;
0316 const storage::Uncommon *UncI;
0317 const Reader *R;
0318
0319 void read() {
0320 if (SymI == SymE)
0321 return;
0322
0323 Name = R->str(SymI->Name);
0324 IRName = R->str(SymI->IRName);
0325 ComdatIndex = SymI->ComdatIndex;
0326 Flags = SymI->Flags;
0327
0328 if (Flags & (1 << storage::Symbol::FB_has_uncommon)) {
0329 CommonSize = UncI->CommonSize;
0330 CommonAlign = UncI->CommonAlign;
0331 COFFWeakExternFallbackName = R->str(UncI->COFFWeakExternFallbackName);
0332 SectionName = R->str(UncI->SectionName);
0333 } else
0334
0335 SectionName = "";
0336 }
0337
0338 public:
0339 SymbolRef(const storage::Symbol *SymI, const storage::Symbol *SymE,
0340 const storage::Uncommon *UncI, const Reader *R)
0341 : SymI(SymI), SymE(SymE), UncI(UncI), R(R) {
0342 read();
0343 }
0344
0345 void moveNext() {
0346 ++SymI;
0347 if (Flags & (1 << storage::Symbol::FB_has_uncommon))
0348 ++UncI;
0349 read();
0350 }
0351
0352 bool operator==(const SymbolRef &Other) const { return SymI == Other.SymI; }
0353 };
0354
0355 inline Reader::symbol_range Reader::symbols() const {
0356 return {SymbolRef(Symbols.begin(), Symbols.end(), Uncommons.begin(), this),
0357 SymbolRef(Symbols.end(), Symbols.end(), nullptr, this)};
0358 }
0359
0360 inline Reader::symbol_range Reader::module_symbols(unsigned I) const {
0361 const storage::Module &M = Modules[I];
0362 const storage::Symbol *MBegin = Symbols.begin() + M.Begin,
0363 *MEnd = Symbols.begin() + M.End;
0364 return {SymbolRef(MBegin, MEnd, Uncommons.begin() + M.UncBegin, this),
0365 SymbolRef(MEnd, MEnd, nullptr, this)};
0366 }
0367
0368
0369
0370 struct FileContents {
0371 SmallVector<char, 0> Symtab, Strtab;
0372 Reader TheReader;
0373 };
0374
0375
0376 Expected<FileContents> readBitcode(const BitcodeFileContents &BFC);
0377
0378 }
0379 }
0380
0381 #endif