File indexing completed on 2026-05-10 08:44:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef LLVM_OBJECT_WASM_H
0017 #define LLVM_OBJECT_WASM_H
0018
0019 #include "llvm/ADT/ArrayRef.h"
0020 #include "llvm/ADT/StringRef.h"
0021 #include "llvm/BinaryFormat/Wasm.h"
0022 #include "llvm/Config/llvm-config.h"
0023 #include "llvm/MC/MCSymbolWasm.h"
0024 #include "llvm/Object/Binary.h"
0025 #include "llvm/Object/ObjectFile.h"
0026 #include "llvm/Support/Error.h"
0027 #include "llvm/Support/MemoryBuffer.h"
0028 #include <cstddef>
0029 #include <cstdint>
0030 #include <vector>
0031
0032 namespace llvm {
0033 namespace object {
0034
0035 class WasmSymbol {
0036 public:
0037 WasmSymbol(const wasm::WasmSymbolInfo &Info,
0038 const wasm::WasmGlobalType *GlobalType,
0039 const wasm::WasmTableType *TableType,
0040 const wasm::WasmSignature *Signature)
0041 : Info(Info), GlobalType(GlobalType), TableType(TableType),
0042 Signature(Signature) {
0043 assert(!Signature || Signature->Kind != wasm::WasmSignature::Placeholder);
0044 }
0045
0046
0047
0048 wasm::WasmSymbolInfo Info;
0049 const wasm::WasmGlobalType *GlobalType;
0050 const wasm::WasmTableType *TableType;
0051 const wasm::WasmSignature *Signature;
0052
0053 bool isTypeFunction() const {
0054 return Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION;
0055 }
0056
0057 bool isTypeTable() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE; }
0058
0059 bool isTypeData() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA; }
0060
0061 bool isTypeGlobal() const {
0062 return Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL;
0063 }
0064
0065 bool isTypeSection() const {
0066 return Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION;
0067 }
0068
0069 bool isTypeTag() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_TAG; }
0070
0071 bool isDefined() const { return !isUndefined(); }
0072
0073 bool isUndefined() const {
0074 return (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) != 0;
0075 }
0076
0077 bool isBindingWeak() const {
0078 return getBinding() == wasm::WASM_SYMBOL_BINDING_WEAK;
0079 }
0080
0081 bool isBindingGlobal() const {
0082 return getBinding() == wasm::WASM_SYMBOL_BINDING_GLOBAL;
0083 }
0084
0085 bool isBindingLocal() const {
0086 return getBinding() == wasm::WASM_SYMBOL_BINDING_LOCAL;
0087 }
0088
0089 unsigned getBinding() const {
0090 return Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK;
0091 }
0092
0093 bool isHidden() const {
0094 return getVisibility() == wasm::WASM_SYMBOL_VISIBILITY_HIDDEN;
0095 }
0096
0097 unsigned getVisibility() const {
0098 return Info.Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK;
0099 }
0100
0101 void print(raw_ostream &Out) const;
0102
0103 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0104 LLVM_DUMP_METHOD void dump() const;
0105 #endif
0106 };
0107
0108 struct WasmSection {
0109 WasmSection() = default;
0110
0111 uint32_t Type = 0;
0112 uint32_t Offset = 0;
0113 StringRef Name;
0114 uint32_t Comdat = UINT32_MAX;
0115 ArrayRef<uint8_t> Content;
0116 std::vector<wasm::WasmRelocation> Relocations;
0117
0118 std::optional<uint8_t> HeaderSecSizeEncodingLen;
0119 };
0120
0121 struct WasmSegment {
0122 uint32_t SectionOffset;
0123 wasm::WasmDataSegment Data;
0124 };
0125
0126 class WasmObjectFile : public ObjectFile {
0127
0128 public:
0129 WasmObjectFile(MemoryBufferRef Object, Error &Err);
0130
0131 const wasm::WasmObjectHeader &getHeader() const;
0132 const WasmSymbol &getWasmSymbol(const DataRefImpl &Symb) const;
0133 const WasmSymbol &getWasmSymbol(const SymbolRef &Symbol) const;
0134 const WasmSection &getWasmSection(const SectionRef &Section) const;
0135 const wasm::WasmRelocation &getWasmRelocation(const RelocationRef &Ref) const;
0136
0137 static bool classof(const Binary *v) { return v->isWasm(); }
0138
0139 const wasm::WasmDylinkInfo &dylinkInfo() const { return DylinkInfo; }
0140 const wasm::WasmProducerInfo &getProducerInfo() const { return ProducerInfo; }
0141 ArrayRef<wasm::WasmFeatureEntry> getTargetFeatures() const {
0142 return TargetFeatures;
0143 }
0144 ArrayRef<wasm::WasmSignature> types() const { return Signatures; }
0145 ArrayRef<wasm::WasmImport> imports() const { return Imports; }
0146 ArrayRef<wasm::WasmTable> tables() const { return Tables; }
0147 ArrayRef<wasm::WasmLimits> memories() const { return Memories; }
0148 ArrayRef<wasm::WasmGlobal> globals() const { return Globals; }
0149 ArrayRef<wasm::WasmTag> tags() const { return Tags; }
0150 ArrayRef<wasm::WasmExport> exports() const { return Exports; }
0151 const wasm::WasmLinkingData &linkingData() const { return LinkingData; }
0152 uint32_t getNumberOfSymbols() const { return Symbols.size(); }
0153 ArrayRef<wasm::WasmElemSegment> elements() const { return ElemSegments; }
0154 ArrayRef<WasmSegment> dataSegments() const { return DataSegments; }
0155 ArrayRef<wasm::WasmFunction> functions() const { return Functions; }
0156 ArrayRef<wasm::WasmDebugName> debugNames() const { return DebugNames; }
0157 uint32_t startFunction() const { return StartFunction; }
0158 uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
0159 uint32_t getNumImportedTables() const { return NumImportedTables; }
0160 uint32_t getNumImportedFunctions() const { return NumImportedFunctions; }
0161 uint32_t getNumImportedTags() const { return NumImportedTags; }
0162 uint32_t getNumSections() const { return Sections.size(); }
0163 void moveSymbolNext(DataRefImpl &Symb) const override;
0164
0165 Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
0166
0167 basic_symbol_iterator symbol_begin() const override;
0168
0169 basic_symbol_iterator symbol_end() const override;
0170 Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
0171
0172 bool is64Bit() const override { return false; }
0173
0174 Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
0175 uint64_t getWasmSymbolValue(const WasmSymbol &Sym) const;
0176 uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
0177 uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
0178 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
0179 Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
0180 Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
0181 uint32_t getSymbolSectionId(SymbolRef Sym) const;
0182 uint32_t getSymbolSize(SymbolRef Sym) const;
0183
0184
0185 void moveSectionNext(DataRefImpl &Sec) const override;
0186 Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
0187 uint64_t getSectionAddress(DataRefImpl Sec) const override;
0188 uint64_t getSectionIndex(DataRefImpl Sec) const override;
0189 uint64_t getSectionSize(DataRefImpl Sec) const override;
0190 Expected<ArrayRef<uint8_t>>
0191 getSectionContents(DataRefImpl Sec) const override;
0192 uint64_t getSectionAlignment(DataRefImpl Sec) const override;
0193 bool isSectionCompressed(DataRefImpl Sec) const override;
0194 bool isSectionText(DataRefImpl Sec) const override;
0195 bool isSectionData(DataRefImpl Sec) const override;
0196 bool isSectionBSS(DataRefImpl Sec) const override;
0197 bool isSectionVirtual(DataRefImpl Sec) const override;
0198 relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
0199 relocation_iterator section_rel_end(DataRefImpl Sec) const override;
0200
0201
0202 void moveRelocationNext(DataRefImpl &Rel) const override;
0203 uint64_t getRelocationOffset(DataRefImpl Rel) const override;
0204 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
0205 uint64_t getRelocationType(DataRefImpl Rel) const override;
0206 void getRelocationTypeName(DataRefImpl Rel,
0207 SmallVectorImpl<char> &Result) const override;
0208
0209 section_iterator section_begin() const override;
0210 section_iterator section_end() const override;
0211 uint8_t getBytesInAddress() const override;
0212 StringRef getFileFormatName() const override;
0213 Triple::ArchType getArch() const override;
0214 Expected<SubtargetFeatures> getFeatures() const override;
0215 bool isRelocatableObject() const override;
0216 bool isSharedObject() const;
0217 bool hasUnmodeledTypes() const { return HasUnmodeledTypes; }
0218
0219 struct ReadContext {
0220 const uint8_t *Start;
0221 const uint8_t *Ptr;
0222 const uint8_t *End;
0223 };
0224
0225 private:
0226 bool isValidFunctionIndex(uint32_t Index) const;
0227 bool isDefinedFunctionIndex(uint32_t Index) const;
0228 bool isValidGlobalIndex(uint32_t Index) const;
0229 bool isValidTableNumber(uint32_t Index) const;
0230 bool isDefinedGlobalIndex(uint32_t Index) const;
0231 bool isDefinedTableNumber(uint32_t Index) const;
0232 bool isValidTagIndex(uint32_t Index) const;
0233 bool isDefinedTagIndex(uint32_t Index) const;
0234 bool isValidFunctionSymbol(uint32_t Index) const;
0235 bool isValidTableSymbol(uint32_t Index) const;
0236 bool isValidGlobalSymbol(uint32_t Index) const;
0237 bool isValidTagSymbol(uint32_t Index) const;
0238 bool isValidDataSymbol(uint32_t Index) const;
0239 bool isValidSectionSymbol(uint32_t Index) const;
0240 wasm::WasmFunction &getDefinedFunction(uint32_t Index);
0241 const wasm::WasmFunction &getDefinedFunction(uint32_t Index) const;
0242 const wasm::WasmGlobal &getDefinedGlobal(uint32_t Index) const;
0243 wasm::WasmTag &getDefinedTag(uint32_t Index);
0244
0245 const WasmSection &getWasmSection(DataRefImpl Ref) const;
0246 const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
0247 uint32_t getSymbolSectionIdImpl(const WasmSymbol &Symb) const;
0248
0249 Error parseSection(WasmSection &Sec);
0250 Error parseCustomSection(WasmSection &Sec, ReadContext &Ctx);
0251
0252
0253 Error parseTypeSection(ReadContext &Ctx);
0254 Error parseImportSection(ReadContext &Ctx);
0255 Error parseFunctionSection(ReadContext &Ctx);
0256 Error parseTableSection(ReadContext &Ctx);
0257 Error parseMemorySection(ReadContext &Ctx);
0258 Error parseTagSection(ReadContext &Ctx);
0259 Error parseGlobalSection(ReadContext &Ctx);
0260 Error parseExportSection(ReadContext &Ctx);
0261 Error parseStartSection(ReadContext &Ctx);
0262 Error parseElemSection(ReadContext &Ctx);
0263 Error parseCodeSection(ReadContext &Ctx);
0264 Error parseDataSection(ReadContext &Ctx);
0265 Error parseDataCountSection(ReadContext &Ctx);
0266
0267
0268 Error parseDylinkSection(ReadContext &Ctx);
0269 Error parseDylink0Section(ReadContext &Ctx);
0270 Error parseNameSection(ReadContext &Ctx);
0271 Error parseLinkingSection(ReadContext &Ctx);
0272 Error parseLinkingSectionSymtab(ReadContext &Ctx);
0273 Error parseLinkingSectionComdat(ReadContext &Ctx);
0274 Error parseProducersSection(ReadContext &Ctx);
0275 Error parseTargetFeaturesSection(ReadContext &Ctx);
0276 Error parseRelocSection(StringRef Name, ReadContext &Ctx);
0277
0278 wasm::WasmObjectHeader Header;
0279 std::vector<WasmSection> Sections;
0280 wasm::WasmDylinkInfo DylinkInfo;
0281 wasm::WasmProducerInfo ProducerInfo;
0282 std::vector<wasm::WasmFeatureEntry> TargetFeatures;
0283 std::vector<wasm::WasmSignature> Signatures;
0284 std::vector<wasm::WasmTable> Tables;
0285 std::vector<wasm::WasmLimits> Memories;
0286 std::vector<wasm::WasmGlobal> Globals;
0287 std::vector<wasm::WasmTag> Tags;
0288 std::vector<wasm::WasmImport> Imports;
0289 std::vector<wasm::WasmExport> Exports;
0290 std::vector<wasm::WasmElemSegment> ElemSegments;
0291 std::vector<WasmSegment> DataSegments;
0292 std::optional<size_t> DataCount;
0293 std::vector<wasm::WasmFunction> Functions;
0294 std::vector<WasmSymbol> Symbols;
0295 std::vector<wasm::WasmDebugName> DebugNames;
0296 uint32_t StartFunction = -1;
0297 bool HasLinkingSection = false;
0298 bool HasDylinkSection = false;
0299 bool HasMemory64 = false;
0300 bool HasUnmodeledTypes = false;
0301 wasm::WasmLinkingData LinkingData;
0302 uint32_t NumImportedGlobals = 0;
0303 uint32_t NumImportedTables = 0;
0304 uint32_t NumImportedFunctions = 0;
0305 uint32_t NumImportedTags = 0;
0306 uint32_t CodeSection = 0;
0307 uint32_t DataSection = 0;
0308 uint32_t TagSection = 0;
0309 uint32_t GlobalSection = 0;
0310 uint32_t TableSection = 0;
0311 };
0312
0313 class WasmSectionOrderChecker {
0314 public:
0315
0316 enum : int {
0317
0318 WASM_SEC_ORDER_NONE = 0,
0319
0320
0321 WASM_SEC_ORDER_TYPE,
0322 WASM_SEC_ORDER_IMPORT,
0323 WASM_SEC_ORDER_FUNCTION,
0324 WASM_SEC_ORDER_TABLE,
0325 WASM_SEC_ORDER_MEMORY,
0326 WASM_SEC_ORDER_TAG,
0327 WASM_SEC_ORDER_GLOBAL,
0328 WASM_SEC_ORDER_EXPORT,
0329 WASM_SEC_ORDER_START,
0330 WASM_SEC_ORDER_ELEM,
0331 WASM_SEC_ORDER_DATACOUNT,
0332 WASM_SEC_ORDER_CODE,
0333 WASM_SEC_ORDER_DATA,
0334
0335
0336
0337 WASM_SEC_ORDER_DYLINK,
0338
0339 WASM_SEC_ORDER_LINKING,
0340
0341 WASM_SEC_ORDER_RELOC,
0342
0343
0344 WASM_SEC_ORDER_NAME,
0345
0346 WASM_SEC_ORDER_PRODUCERS,
0347
0348 WASM_SEC_ORDER_TARGET_FEATURES,
0349
0350
0351 WASM_NUM_SEC_ORDERS
0352
0353 };
0354
0355
0356 static int DisallowedPredecessors[WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS];
0357
0358 bool isValidSectionOrder(unsigned ID, StringRef CustomSectionName = "");
0359
0360 private:
0361 bool Seen[WASM_NUM_SEC_ORDERS] = {};
0362
0363
0364 int getSectionOrder(unsigned ID, StringRef CustomSectionName = "");
0365 };
0366
0367 }
0368
0369 inline raw_ostream &operator<<(raw_ostream &OS, const object::WasmSymbol &Sym) {
0370 Sym.print(OS);
0371 return OS;
0372 }
0373
0374 }
0375
0376 #endif