llvm.org GIT mirror llvm / d578479
[WebAssembly] Add first claass symbol table to wasm objects This is combination of two patches by Nicholas Wilson: 1. https://reviews.llvm.org/D41954 2. https://reviews.llvm.org/D42495 Along with a few local modifications: - One change I made was to add the UNDEFINED bit to the binary format to avoid the extra byte used when writing data symbols. Although this bit is redundant for other symbols types (i.e. undefined can be implied if a function or global is a wasm import) - I prefer to be explicit and consistent and not have derived flags. - Some field renaming. - Some reverting of unrelated minor changes. - No test output differences. Differential Revision: https://reviews.llvm.org/D43147 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325860 91177308-0d34-0410-b5e6-96231b3b80d8 Sam Clegg 1 year, 5 months ago
43 changed file(s) with 1053 addition(s) and 918 deletion(s). Raw diff Collapse all Expand all
118118 std::vector Functions;
119119 };
120120
121 // Represents the location of a Wasm data symbol within a WasmDataSegment, as
122 // the index of the segment, and the offset and size within the segment.
123 struct WasmDataReference {
124 uint32_t Segment;
125 uint32_t Offset;
126 uint32_t Size;
127 };
128
121129 struct WasmRelocation {
122130 uint32_t Type; // The type of the relocation.
123 uint32_t Index; // Index into function or global index space.
131 uint32_t Index; // Index into either symbol or type index space.
124132 uint64_t Offset; // Offset from the start of the section.
125133 int64_t Addend; // A value to add to the symbol.
126134 };
127135
128136 struct WasmInitFunc {
129137 uint32_t Priority;
130 uint32_t FunctionIndex;
138 uint32_t Symbol;
139 };
140
141 struct WasmSymbolInfo {
142 StringRef Name;
143 uint32_t Kind;
144 uint32_t Flags;
145 union {
146 // For function or global symbols, the index in function of global index
147 // space.
148 uint32_t ElementIndex;
149 // For a data symbols, the address of the data relative to segment.
150 WasmDataReference DataRef;
151 };
131152 };
132153
133154 struct WasmFunctionName {
138159 struct WasmLinkingData {
139160 uint32_t DataSize;
140161 std::vector InitFunctions;
162 std::vector SymbolTable;
141163 };
142164
143165 enum : unsigned {
204226
205227 // Kind codes used in the custom "linking" section
206228 enum : unsigned {
207 WASM_SYMBOL_INFO = 0x2,
208229 WASM_DATA_SIZE = 0x3,
209230 WASM_SEGMENT_INFO = 0x5,
210231 WASM_INIT_FUNCS = 0x6,
211232 WASM_COMDAT_INFO = 0x7,
233 WASM_SYMBOL_TABLE = 0x8,
212234 };
213235
214236 // Kind codes used in the custom "linking" section in the WASM_COMDAT_INFO
217239 WASM_COMDAT_FUNCTION = 0x1,
218240 };
219241
242 // Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE
243 enum WasmSymbolType : unsigned {
244 WASM_SYMBOL_TYPE_FUNCTION = 0x0,
245 WASM_SYMBOL_TYPE_DATA = 0x1,
246 WASM_SYMBOL_TYPE_GLOBAL = 0x2,
247 };
248
220249 const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
221 const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0x4;
250 const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0xc;
222251
223252 const unsigned WASM_SYMBOL_BINDING_GLOBAL = 0x0;
224253 const unsigned WASM_SYMBOL_BINDING_WEAK = 0x1;
225254 const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2;
226255 const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0;
227256 const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4;
257 const unsigned WASM_SYMBOL_UNDEFINED = 0x10;
228258
229259 #define WASM_RELOC(name, value) name = value,
230260
233263 };
234264
235265 #undef WASM_RELOC
236
237 struct Global {
238 ValType Type;
239 bool Mutable;
240
241 // The initial value for this global is either the value of an imported
242 // global, in which case InitialModule and InitialName specify the global
243 // import, or a value, in which case InitialModule is empty and InitialValue
244 // holds the value.
245 StringRef InitialModule;
246 StringRef InitialName;
247 uint64_t InitialValue;
248 };
249266
250267 } // end namespace wasm
251268 } // end namespace llvm
3636 // The offset of the MC function/data section in the wasm code/data section.
3737 // For data relocations the offset is relative to start of the data payload
3838 // itself and does not include the size of the section header.
39 uint64_t SectionOffset;
39 uint64_t SectionOffset = 0;
4040
41 // For data sections, this is the offset of the corresponding wasm data
41 // For data sections, this is the index of of the corresponding wasm data
4242 // segment
43 uint64_t MemoryOffset;
43 uint32_t SegmentIndex = 0;
4444
4545 friend class MCContext;
4646 MCSectionWasm(StringRef Section, SectionKind K, const MCSymbolWasm *group,
4747 unsigned UniqueID, MCSymbol *Begin)
4848 : MCSection(SV_Wasm, K, Begin), SectionName(Section), UniqueID(UniqueID),
49 Group(group), SectionOffset(0) {}
49 Group(group) {}
5050
5151 void setSectionName(StringRef Name) { SectionName = Name; }
5252
7676 uint64_t getSectionOffset() const { return SectionOffset; }
7777 void setSectionOffset(uint64_t Offset) { SectionOffset = Offset; }
7878
79 uint32_t getMemoryOffset() const { return MemoryOffset; }
80 void setMemoryOffset(uint32_t Offset) { MemoryOffset = Offset; }
79 uint32_t getSegmentIndex() const { return SegmentIndex; }
80 void setSegmentIndex(uint32_t Index) { SegmentIndex = Index; }
8181
8282 static bool classof(const MCSection *S) { return S->getVariant() == SV_Wasm; }
8383 };
1414 namespace llvm {
1515
1616 class MCSymbolWasm : public MCSymbol {
17 bool IsFunction = false;
17 wasm::WasmSymbolType Type = wasm::WASM_SYMBOL_TYPE_DATA;
1818 bool IsWeak = false;
1919 bool IsHidden = false;
2020 bool IsComdat = false;
2121 std::string ModuleName;
2222 SmallVector Returns;
2323 SmallVector Params;
24 wasm::WasmGlobalType GlobalType;
2425 bool ParamsSet = false;
2526 bool ReturnsSet = false;
27 bool GlobalTypeSet = false;
2628
2729 /// An expression describing how to calculate the size of a symbol. If a
2830 /// symbol has no size this field will be NULL.
3941 const MCExpr *getSize() const { return SymbolSize; }
4042 void setSize(const MCExpr *SS) { SymbolSize = SS; }
4143
42 bool isFunction() const { return IsFunction; }
43 void setIsFunction(bool isFunc) { IsFunction = isFunc; }
44 bool isFunction() const { return Type == wasm::WASM_SYMBOL_TYPE_FUNCTION; }
45 bool isData() const { return Type == wasm::WASM_SYMBOL_TYPE_DATA; }
46 bool isGlobal() const { return Type == wasm::WASM_SYMBOL_TYPE_GLOBAL; }
47 wasm::WasmSymbolType getType() const { return Type; }
48 void setType(wasm::WasmSymbolType type) { Type = type; }
4449
4550 bool isWeak() const { return IsWeak; }
4651 void setWeak(bool isWeak) { IsWeak = isWeak; }
7378 ParamsSet = true;
7479 Params = std::move(Pars);
7580 }
81
82 const wasm::WasmGlobalType &getGlobalType() const {
83 assert(GlobalTypeSet);
84 return GlobalType;
85 }
86
87 void setGlobalType(wasm::WasmGlobalType GT) {
88 GlobalTypeSet = true;
89 GlobalType = GT;
90 }
7691 };
7792
7893 } // end namespace llvm
3333
3434 class WasmSymbol {
3535 public:
36 enum class SymbolType {
37 FUNCTION_IMPORT,
38 FUNCTION_EXPORT,
39 GLOBAL_IMPORT,
40 GLOBAL_EXPORT,
41 };
42
43 WasmSymbol(StringRef Name, SymbolType Type, uint32_t ElementIndex,
44 uint32_t FunctionType = 0)
45 : Name(Name), Type(Type), ElementIndex(ElementIndex),
46 FunctionType(FunctionType) {}
47
48 StringRef Name;
49 SymbolType Type;
50 uint32_t Flags = 0;
51
52 // Index into either the function or global index space.
53 uint32_t ElementIndex;
54
55 // For function, the type index
56 uint32_t FunctionType;
57
58 // Symbols can be both exported and imported (in the case of the weakly
59 // defined symbol). In this the import index is stored as AltIndex.
60 uint32_t AltIndex = 0;
61 bool HasAltIndex = false;
62
63 void setAltIndex(uint32_t Index) {
64 HasAltIndex = true;
65 AltIndex = Index;
66 }
36 WasmSymbol(const wasm::WasmSymbolInfo &Info,
37 const wasm::WasmSignature *FunctionType,
38 const wasm::WasmGlobalType *GlobalType)
39 : Info(Info), FunctionType(FunctionType), GlobalType(GlobalType) {}
40
41 const wasm::WasmSymbolInfo &Info;
42 const wasm::WasmSignature *FunctionType;
43 const wasm::WasmGlobalType *GlobalType;
6744
6845 bool isTypeFunction() const {
69 return Type == SymbolType::FUNCTION_IMPORT ||
70 Type == SymbolType::FUNCTION_EXPORT;
71 }
46 return Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION;
47 }
48
49 bool isTypeData() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA; }
7250
7351 bool isTypeGlobal() const {
74 return Type == SymbolType::GLOBAL_IMPORT ||
75 Type == SymbolType::GLOBAL_EXPORT;
76 }
77
52 return Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL;
53 }
54
55 bool isDefined() const { return !isUndefined(); }
56
57 bool isUndefined() const {
58 return (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) != 0;
59 }
7860
7961 bool isBindingWeak() const {
8062 return getBinding() == wasm::WASM_SYMBOL_BINDING_WEAK;
8971 }
9072
9173 unsigned getBinding() const {
92 return Flags & wasm::WASM_SYMBOL_BINDING_MASK;
74 return Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK;
9375 }
9476
9577 bool isHidden() const {
9779 }
9880
9981 unsigned getVisibility() const {
100 return Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK;
82 return Info.Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK;
10183 }
10284
10385 void print(raw_ostream &Out) const {
104 Out << "Name=" << Name << ", Type=" << static_cast(Type)
105 << ", Flags=" << Flags << " ElemIndex=" << ElementIndex;
86 Out << "Name=" << Info.Name << ", Kind=" << Info.Kind
87 << ", Flags=" << Info.Flags;
88 if (!isTypeData()) {
89 Out << ", ElemIndex=" << Info.ElementIndex;
90 } else if (isDefined()) {
91 Out << ", Segment=" << Info.DataRef.Segment;
92 Out << ", Offset=" << Info.DataRef.Offset;
93 Out << ", Size=" << Info.DataRef.Size;
94 }
10695 }
10796
10897 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
153142 ArrayRef comdats() const { return Comdats; }
154143 ArrayRef debugNames() const { return DebugNames; }
155144 uint32_t startFunction() const { return StartFunction; }
145 uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
146 uint32_t getNumImportedFunctions() const { return NumImportedFunctions; }
156147
157148 void moveSymbolNext(DataRefImpl &Symb) const override;
158149
209200 private:
210201 bool isValidFunctionIndex(uint32_t Index) const;
211202 bool isDefinedFunctionIndex(uint32_t Index) const;
212 wasm::WasmFunction& getDefinedFunction(uint32_t Index);
203 bool isValidGlobalIndex(uint32_t Index) const;
204 bool isDefinedGlobalIndex(uint32_t Index) const;
205 bool isValidFunctionSymbolIndex(uint32_t Index) const;
206 wasm::WasmFunction &getDefinedFunction(uint32_t Index);
207 wasm::WasmGlobal &getDefinedGlobal(uint32_t Index);
213208
214209 const WasmSection &getWasmSection(DataRefImpl Ref) const;
215210 const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
238233 // Custom section types
239234 Error parseNameSection(const uint8_t *Ptr, const uint8_t *End);
240235 Error parseLinkingSection(const uint8_t *Ptr, const uint8_t *End);
236 Error parseLinkingSectionSymtab(const uint8_t *&Ptr, const uint8_t *End);
241237 Error parseLinkingSectionComdat(const uint8_t *&Ptr, const uint8_t *End);
242238 Error parseRelocSection(StringRef Name, const uint8_t *Ptr,
243239 const uint8_t *End);
244
245 void populateSymbolTable();
246240
247241 wasm::WasmObjectHeader Header;
248242 std::vector Sections;
266260 uint32_t NumImportedFunctions = 0;
267261 uint32_t CodeSection = 0;
268262 uint32_t DataSection = 0;
269
270 StringMap SymbolMap;
263 uint32_t GlobalSection = 0;
271264 };
272265
273266 } // end namespace object
3434 LLVM_YAML_STRONG_TYPEDEF(uint32_t, Opcode)
3535 LLVM_YAML_STRONG_TYPEDEF(uint32_t, RelocType)
3636 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SymbolFlags)
37 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SymbolKind)
3738 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SegmentFlags)
3839 LLVM_YAML_STRONG_TYPEDEF(uint32_t, LimitFlags)
3940 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ComdatKind)
129130 };
130131
131132 struct SymbolInfo {
132 StringRef Name;
133 uint32_t Index;
134 StringRef Name;
135 SymbolKind Kind;
133136 SymbolFlags Flags;
137 union {
138 uint32_t ElementIndex;
139 wasm::WasmDataReference DataRef;
140 };
134141 };
135142
136143 struct InitFunction {
137144 uint32_t Priority;
138 uint32_t FunctionIndex;
145 uint32_t Symbol;
139146 };
140147
141148 struct ComdatEntry {
188195 }
189196
190197 uint32_t DataSize;
191 std::vector SymbolInfos;
198 std::vector SymbolTable;
192199 std::vector SegmentInfos;
193200 std::vector InitFunctions;
194201 std::vector Comdats;
367374 static void bitset(IO &IO, WasmYAML::SymbolFlags &Value);
368375 };
369376
377 template <> struct ScalarEnumerationTraits {
378 static void enumeration(IO &IO, WasmYAML::SymbolKind &Kind);
379 };
380
370381 template <> struct ScalarBitSetTraits {
371382 static void bitset(IO &IO, WasmYAML::SegmentFlags &Value);
372383 };
112112 break;
113113
114114 case MCSA_ELF_TypeFunction:
115 Symbol->setIsFunction(true);
115 Symbol->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
116116 break;
117117
118118 case MCSA_ELF_TypeObject:
119 Symbol->setIsFunction(false);
119 Symbol->setType(wasm::WASM_SYMBOL_TYPE_DATA);
120120 break;
121121
122122 default:
189189 // Maps function symbols to the table element index space. Used
190190 // for TABLE_INDEX relocation types (i.e. address taken functions).
191191 DenseMap TableIndices;
192 // Maps function/global symbols to the function/global index space.
192 // Maps function/global symbols to the (shared) Symbol index space.
193193 DenseMap SymbolIndices;
194 // Maps function/global symbols to the function/global Wasm index space.
195 DenseMap WasmIndices;
196 // Maps data symbols to the Wasm segment and offset/size with the segment.
197 DenseMap DataLocations;
194198
195199 DenseMap
196200 FunctionTypeIndices;
197201 SmallVector FunctionTypes;
198202 SmallVector Globals;
203 SmallVector DataSegments;
199204 unsigned NumFunctionImports = 0;
200205 unsigned NumGlobalImports = 0;
201206
223228 DataRelocations.clear();
224229 TypeIndices.clear();
225230 SymbolIndices.clear();
231 WasmIndices.clear();
226232 TableIndices.clear();
233 DataLocations.clear();
227234 FunctionTypeIndices.clear();
228235 FunctionTypes.clear();
229236 Globals.clear();
237 DataSegments.clear();
230238 MCObjectWriter::reset();
231239 NumFunctionImports = 0;
232240 NumGlobalImports = 0;
261269 void writeElemSection(ArrayRef TableElems);
262270 void writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
263271 ArrayRef Functions);
264 void writeDataSection(ArrayRef Segments);
272 void writeDataSection();
265273 void writeCodeRelocSection();
266274 void writeDataRelocSection();
267275 void writeLinkingMetaDataSection(
268 ArrayRef Segments, uint32_t DataSize,
269 ArrayRef> SymbolFlags,
276 uint32_t DataSize, ArrayRef SymbolInfos,
270277 ArrayRef> InitFuncs,
271 const std::map>& Comdats);
278 const std::map> &Comdats);
272279
273280 uint32_t getProvisionalValue(const WasmRelocationEntry &RelEntry);
274281 void applyRelocations(ArrayRef Relocations,
493500 assert(Sym->isFunction());
494501 return TableIndices[Sym];
495502 }
503 case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
504 // Provisional value is same as the index
505 return getRelocationIndexValue(RelEntry);
496506 case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
497 case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
498507 case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
499 // Provisional value is function/type/global index itself
500 return getRelocationIndexValue(RelEntry);
508 // Provisional value is function/global Wasm index
509 if (!WasmIndices.count(RelEntry.Symbol))
510 report_fatal_error("symbol not found in wasm index space: " +
511 RelEntry.Symbol->getName());
512 return WasmIndices[RelEntry.Symbol];
501513 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
502514 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
503515 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: {
506518 // For undefined symbols, use zero
507519 if (!Sym->isDefined())
508520 return 0;
509
510 if (!SymbolIndices.count(Sym))
511 report_fatal_error("symbol not found in function/global index space: " +
512 Sym->getName());
513 uint32_t GlobalIndex = SymbolIndices[Sym];
514 const WasmGlobal& Global = Globals[GlobalIndex - NumGlobalImports];
515 uint64_t Address = Global.InitialValue + RelEntry.Addend;
516
521 const wasm::WasmDataReference &Ref = DataLocations[Sym];
522 const WasmDataSegment &Segment = DataSegments[Ref.Segment];
517523 // Ignore overflow. LLVM allows address arithmetic to silently wrap.
518 return Address;
524 return Segment.Offset + Ref.Offset + RelEntry.Addend;
519525 }
520526 default:
521527 llvm_unreachable("invalid relocation type");
528534
529535 DataBytes.resize(alignTo(DataBytes.size(), DataSection.getAlignment()));
530536
531 size_t LastFragmentSize = 0;
532537 for (const MCFragment &Frag : DataSection) {
533538 if (Frag.hasInstructions())
534539 report_fatal_error("only data supported in data sections");
553558 const SmallVectorImpl &Contents = DataFrag.getContents();
554559
555560 DataBytes.insert(DataBytes.end(), Contents.begin(), Contents.end());
556 LastFragmentSize = Contents.size();
557 }
558 }
559
560 // Don't allow empty segments, or segments that end with zero-sized
561 // fragment, otherwise the linker cannot map symbols to a unique
562 // data segment. This can be triggered by zero-sized structs
563 // See: test/MC/WebAssembly/bss.ll
564 if (LastFragmentSize == 0)
565 DataBytes.resize(DataBytes.size() + 1);
561 }
562 }
563
566564 DEBUG(dbgs() << "addData -> " << DataBytes.size() << "\n");
567565 }
568566
576574 }
577575
578576 if (!SymbolIndices.count(RelEntry.Symbol))
579 report_fatal_error("symbol not found in function/global index space: " +
577 report_fatal_error("symbol not found in symbol index space: " +
580578 RelEntry.Symbol->getName());
581579 return SymbolIndices[RelEntry.Symbol];
582580 }
801799 endSection(Section);
802800 }
803801
804 void WasmObjectWriter::writeDataSection(ArrayRef Segments) {
805 if (Segments.empty())
802 void WasmObjectWriter::writeDataSection() {
803 if (DataSegments.empty())
806804 return;
807805
808806 SectionBookkeeping Section;
809807 startSection(Section, wasm::WASM_SEC_DATA);
810808
811 encodeULEB128(Segments.size(), getStream()); // count
812
813 for (const WasmDataSegment & Segment : Segments) {
809 encodeULEB128(DataSegments.size(), getStream()); // count
810
811 for (const WasmDataSegment &Segment : DataSegments) {
814812 encodeULEB128(0, getStream()); // memory index
815813 write8(wasm::WASM_OPCODE_I32_CONST);
816814 encodeSLEB128(Segment.Offset, getStream()); // offset
863861 }
864862
865863 void WasmObjectWriter::writeLinkingMetaDataSection(
866 ArrayRef Segments, uint32_t DataSize,
867 ArrayRef> SymbolFlags,
864 uint32_t DataSize, ArrayRef SymbolInfos,
868865 ArrayRef> InitFuncs,
869 const std::map>& Comdats) {
866 const std::map> &Comdats) {
870867 SectionBookkeeping Section;
871868 startSection(Section, wasm::WASM_SEC_CUSTOM, "linking");
872869 SectionBookkeeping SubSection;
873870
874 if (SymbolFlags.size() != 0) {
875 startSection(SubSection, wasm::WASM_SYMBOL_INFO);
876 encodeULEB128(SymbolFlags.size(), getStream());
877 for (auto Pair: SymbolFlags) {
878 writeString(Pair.first);
879 encodeULEB128(Pair.second, getStream());
871 if (SymbolInfos.size() != 0) {
872 startSection(SubSection, wasm::WASM_SYMBOL_TABLE);
873 encodeULEB128(SymbolInfos.size(), getStream());
874 for (const wasm::WasmSymbolInfo &Sym : SymbolInfos) {
875 encodeULEB128(Sym.Kind, getStream());
876 encodeULEB128(Sym.Flags, getStream());
877 switch (Sym.Kind) {
878 case wasm::WASM_SYMBOL_TYPE_FUNCTION:
879 case wasm::WASM_SYMBOL_TYPE_GLOBAL:
880 encodeULEB128(Sym.ElementIndex, getStream());
881 if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
882 writeString(Sym.Name);
883 break;
884 case wasm::WASM_SYMBOL_TYPE_DATA:
885 writeString(Sym.Name);
886 if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
887 encodeULEB128(Sym.DataRef.Segment, getStream());
888 encodeULEB128(Sym.DataRef.Offset, getStream());
889 encodeULEB128(Sym.DataRef.Size, getStream());
890 }
891 break;
892 default:
893 llvm_unreachable("unexpected kind");
894 }
880895 }
881896 endSection(SubSection);
882897 }
887902 endSection(SubSection);
888903 }
889904
890 if (Segments.size()) {
905 if (DataSegments.size()) {
891906 startSection(SubSection, wasm::WASM_SEGMENT_INFO);
892 encodeULEB128(Segments.size(), getStream());
893 for (const WasmDataSegment &Segment : Segments) {
907 encodeULEB128(DataSegments.size(), getStream());
908 for (const WasmDataSegment &Segment : DataSegments) {
894909 writeString(Segment.Name);
895910 encodeULEB128(Segment.Alignment, getStream());
896911 encodeULEB128(Segment.Flags, getStream());
955970 const MCAsmLayout &Layout) {
956971 DEBUG(dbgs() << "WasmObjectWriter::writeObject\n");
957972 MCContext &Ctx = Asm.getContext();
958 int32_t PtrType = is64Bit() ? wasm::WASM_TYPE_I64 : wasm::WASM_TYPE_I32;
959973
960974 // Collect information from the available symbols.
961975 SmallVector Functions;
962976 SmallVector TableElems;
963977 SmallVector Imports;
964978 SmallVector Exports;
965 SmallVector<std::pair, 4> SymbolFlags;
979 SmallVector<wasm::WasmSymbolInfo, 4> SymbolInfos;
966980 SmallVector, 2> InitFuncs;
967981 std::map> Comdats;
968 SmallVector DataSegments;
982 unsigned NumSymbols = 0;
969983 uint32_t DataSize = 0;
984
985 auto AddSymbol = [&](const MCSymbolWasm &WS) {
986 uint32_t Flags = 0;
987 if (WS.isWeak())
988 Flags |= wasm::WASM_SYMBOL_BINDING_WEAK;
989 if (WS.isHidden())
990 Flags |= wasm::WASM_SYMBOL_VISIBILITY_HIDDEN;
991 if (!WS.isExternal() && WS.isDefined())
992 Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL;
993 if (WS.isUndefined())
994 Flags |= wasm::WASM_SYMBOL_UNDEFINED;
995
996 wasm::WasmSymbolInfo Info;
997 Info.Name = WS.getName();
998 Info.Kind = WS.getType();
999 Info.Flags = Flags;
1000 if (!WS.isData())
1001 Info.ElementIndex = WasmIndices[&WS];
1002 else if (WS.isDefined())
1003 Info.DataRef = DataLocations[&WS];
1004 SymbolInfos.emplace_back(Info);
1005 SymbolIndices[&WS] = NumSymbols++;
1006 };
9701007
9711008 // For now, always emit the memory import, since loads and stores are not
9721009 // valid without it. In the future, we could perhaps be more clever and omit
10041041 continue;
10051042
10061043 // If the symbol is not defined in this translation unit, import it.
1007 if ((!WS.isDefined() && !WS.isComdat()) ||
1008 WS.isVariable()) {
1009 wasm::WasmImport Import;
1010 Import.Module = WS.getModuleName();
1011 Import.Field = WS.getName();
1012
1044 if (!WS.isDefined() && !WS.isComdat()) {
10131045 if (WS.isFunction()) {
1046 wasm::WasmImport Import;
1047 Import.Module = WS.getModuleName();
1048 Import.Field = WS.getName();
10141049 Import.Kind = wasm::WASM_EXTERNAL_FUNCTION;
10151050 Import.SigIndex = getFunctionType(WS);
1016 SymbolIndices[&WS] = NumFunctionImports;
1017 ++NumFunctionImports;
1018 } else {
1051 Imports.push_back(Import);
1052 WasmIndices[&WS] = NumFunctionImports++;
1053 } else if (WS.isGlobal()) {
1054 wasm::WasmImport Import;
1055 Import.Module = WS.getModuleName();
1056 Import.Field = WS.getName();
10191057 Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
1020 Import.Global.Type = PtrType;
1021 // If this global is the stack pointer, make it mutable.
1022 if (WS.getName() == "__stack_pointer")
1023 Import.Global.Mutable = true;
1024 else
1025 Import.Global.Mutable = false;
1026
1027 SymbolIndices[&WS] = NumGlobalImports;
1028 ++NumGlobalImports;
1058 Import.Global = WS.getGlobalType();
1059 Imports.push_back(Import);
1060 WasmIndices[&WS] = NumGlobalImports++;
10291061 }
10301062
1031 Imports.push_back(Import);
1063 // TODO(ncw) We shouldn't be adding the symbol to the symbol table here!
1064 // Instead it should be done by removing the "if (WS.isDefined())" block
1065 // in the big loop below (line ~1284). However - that would reorder all
1066 // the symbols and thus require all the tests to be updated. I think it's
1067 // better to make that change therefore in a future commit, to isolate
1068 // each test update from the change that caused it.
1069 AddSymbol(WS);
10321070 }
10331071 }
10341072
10521090 Segment.Alignment = Section.getAlignment();
10531091 Segment.Flags = 0;
10541092 DataSize += Segment.Data.size();
1055 Section.setMemoryOffset(Segment.Offset);
1093 Section.setSegmentIndex(SegmentIndex);
10561094
10571095 if (const MCSymbolWasm *C = Section.getGroup()) {
10581096 Comdats[C->getName()].emplace_back(
10771115 << " isHidden=" << WS.isHidden()
10781116 << " isVariable=" << WS.isVariable() << "\n");
10791117
1080 if (WS.isWeak() || WS.isHidden()) {
1081 uint32_t Flags = (WS.isWeak() ? wasm::WASM_SYMBOL_BINDING_WEAK : 0) |
1082 (WS.isHidden() ? wasm::WASM_SYMBOL_VISIBILITY_HIDDEN : 0);
1083 SymbolFlags.emplace_back(WS.getName(), Flags);
1084 }
1085
10861118 if (WS.isVariable())
10871119 continue;
1088
1089 unsigned Index;
1120 if (WS.isComdat() && !WS.isDefined())
1121 continue;
10901122
10911123 if (WS.isFunction()) {
1124 unsigned Index;
10921125 if (WS.isDefined()) {
10931126 if (WS.getOffset() != 0)
10941127 report_fatal_error(
10981131 report_fatal_error(
10991132 "function symbols must have a size set with .size");
11001133
1101 // A definition. Take the next available index.
1134 // A definition. Write out the function body.
11021135 Index = NumFunctionImports + Functions.size();
1103
1104 // Prepare the function.
11051136 WasmFunction Func;
11061137 Func.Type = getFunctionType(WS);
11071138 Func.Sym = &WS;
1108 SymbolIndices[&WS] = Index;
1139 WasmIndices[&WS] = Index;
11091140 Functions.push_back(Func);
1141
1142 auto &Section = static_cast(WS.getSection());
1143 if (const MCSymbolWasm *C = Section.getGroup()) {
1144 Comdats[C->getName()].emplace_back(
1145 WasmComdatEntry{wasm::WASM_COMDAT_FUNCTION, Index});
1146 }
11101147 } else {
11111148 // An import; the index was assigned above.
1112 Index = SymbolIndices.find(&WS)->second;
1149 Index = WasmIndices.find(&WS)->second;
11131150 }
11141151
11151152 DEBUG(dbgs() << " -> function index: " << Index << "\n");
1116 } else {
1153 } else if (WS.isData()) {
11171154 if (WS.isTemporary() && !WS.getSize())
11181155 continue;
11191156
1120 if (!WS.isDefined())
1157 if (!WS.isDefined()) {
1158 DEBUG(dbgs() << " -> segment index: -1");
11211159 continue;
1160 }
11221161
11231162 if (!WS.getSize())
11241163 report_fatal_error("data symbols must have a size set with .size: " +
11281167 if (!WS.getSize()->evaluateAsAbsolute(Size, Layout))
11291168 report_fatal_error(".size expression must be evaluatable");
11301169
1131 // For each global, prepare a corresponding wasm global holding its
1132 // address. For externals these will also be named exports.
1133 Index = NumGlobalImports + Globals.size();
11341170 auto &DataSection = static_cast(WS.getSection());
11351171 assert(DataSection.isWasmData());
11361172
1137 WasmGlobal Global;
1138 Global.Type.Type = PtrType;
1139 Global.Type.Mutable = false;
1140 Global.InitialValue = DataSection.getMemoryOffset() + Layout.getSymbolOffset(WS);
1141 SymbolIndices[&WS] = Index;
1142 DEBUG(dbgs() << " -> global index: " << Index << "\n");
1143 Globals.push_back(Global);
1144 }
1145
1146 // If the symbol is visible outside this translation unit, export it.
1147 if (WS.isDefined()) {
1148 wasm::WasmExport Export;
1149 Export.Name = WS.getName();
1150 Export.Index = Index;
1151 if (WS.isFunction())
1152 Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
1153 else
1154 Export.Kind = wasm::WASM_EXTERNAL_GLOBAL;
1155 DEBUG(dbgs() << " -> export " << Exports.size() << "\n");
1156 Exports.push_back(Export);
1157
1158 if (!WS.isExternal())
1159 SymbolFlags.emplace_back(WS.getName(), wasm::WASM_SYMBOL_BINDING_LOCAL);
1160
1161 if (WS.isFunction()) {
1162 auto &Section = static_cast(WS.getSection());
1163 if (const MCSymbolWasm *C = Section.getGroup())
1164 Comdats[C->getName()].emplace_back(
1165 WasmComdatEntry{wasm::WASM_COMDAT_FUNCTION, Index});
1173 // For each data symbol, export it in the symtab as a reference to the
1174 // corresponding Wasm data segment.
1175 wasm::WasmDataReference Ref = wasm::WasmDataReference{
1176 DataSection.getSegmentIndex(),
1177 static_cast(Layout.getSymbolOffset(WS)),
1178 static_cast(Size)};
1179 DataLocations[&WS] = Ref;
1180 DEBUG(dbgs() << " -> segment index: " << Ref.Segment);
1181 } else {
1182 // A "true" Wasm global (currently just __stack_pointer)
1183 unsigned WasmIndex;
1184 if (WS.isDefined()) {
1185 report_fatal_error("don't yet support defined globals");
1186 } else {
1187 // An import; the index was assigned above
1188 WasmIndex = WasmIndices.find(&WS)->second;
11661189 }
1167 }
1190
1191 DEBUG(dbgs() << " -> global index: " << WasmIndex << "\n");
1192 }
1193
1194 if (WS.isDefined())
1195 AddSymbol(WS);
11681196 }
11691197
11701198 // Handle weak aliases. We need to process these in a separate pass because
11801208 const auto &WS = static_cast(S);
11811209 const MCSymbolWasm *ResolvedSym = ResolveSymbol(WS);
11821210 DEBUG(dbgs() << WS.getName() << ": weak alias of '" << *ResolvedSym << "'\n");
1183 assert(SymbolIndices.count(ResolvedSym) > 0);
1184 uint32_t Index = SymbolIndices.find(ResolvedSym)->second;
1185 DEBUG(dbgs() << " -> index:" << Index << "\n");
1186
1187 wasm::WasmExport Export;
1188 Export.Name = WS.getName();
1189 Export.Index = Index;
1190 if (WS.isFunction())
1191 Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
1192 else
1193 Export.Kind = wasm::WASM_EXTERNAL_GLOBAL;
1194 DEBUG(dbgs() << " -> export " << Exports.size() << "\n");
1195 Exports.push_back(Export);
1196
1197 if (!WS.isExternal())
1198 SymbolFlags.emplace_back(WS.getName(), wasm::WASM_SYMBOL_BINDING_LOCAL);
1211
1212 if (WS.isFunction()) {
1213 assert(WasmIndices.count(ResolvedSym) > 0);
1214 uint32_t WasmIndex = WasmIndices.find(ResolvedSym)->second;
1215 WasmIndices[&WS] = WasmIndex;
1216 DEBUG(dbgs() << " -> index:" << WasmIndex << "\n");
1217 } else if (WS.isData()) {
1218 assert(DataLocations.count(ResolvedSym) > 0);
1219 const wasm::WasmDataReference &Ref =
1220 DataLocations.find(ResolvedSym)->second;
1221 DataLocations[&WS] = Ref;
1222 DEBUG(dbgs() << " -> index:" << Ref.Segment << "\n");
1223 } else {
1224 report_fatal_error("don't yet support global aliases");
1225 }
1226
1227 AddSymbol(WS);
11991228 }
12001229
12011230 {
12081237 return;
12091238 assert(Rel.Symbol->isFunction());
12101239 const MCSymbolWasm &WS = *ResolveSymbol(*Rel.Symbol);
1211 uint32_t SymbolIndex = SymbolIndices.find(&WS)->second;
1240 uint32_t FunctionIndex = WasmIndices.find(&WS)->second;
12121241 uint32_t TableIndex = TableElems.size() + kInitialTableOffset;
12131242 if (TableIndices.try_emplace(&WS, TableIndex).second) {
12141243 DEBUG(dbgs() << " -> adding " << WS.getName()
12151244 << " to table: " << TableIndex << "\n");
1216 TableElems.push_back(SymbolIndex);
1245 TableElems.push_back(FunctionIndex);
12171246 registerFunctionType(WS);
12181247 }
12191248 };
12861315 writeExportSection(Exports);
12871316 writeElemSection(TableElems);
12881317 writeCodeSection(Asm, Layout, Functions);
1289 writeDataSection(DataSegments);
1318 writeDataSection();
12901319 writeCodeRelocSection();
12911320 writeDataRelocSection();
1292 writeLinkingMetaDataSection(DataSegments, DataSize, SymbolFlags,
1293 InitFuncs, Comdats);
1321 writeLinkingMetaDataSection(DataSize, SymbolInfos, InitFuncs, Comdats);
12941322
12951323 // TODO: Translate the .comment section to the output.
12961324 // TODO: Translate debug sections to the output.
316316 return Error::success();
317317 }
318318
319 void WasmObjectFile::populateSymbolTable() {
320 // Add imports to symbol table
321 size_t GlobalIndex = 0;
322 size_t FunctionIndex = 0;
323 for (const wasm::WasmImport& Import : Imports) {
324 switch (Import.Kind) {
325 case wasm::WASM_EXTERNAL_GLOBAL:
326 assert(Import.Global.Type == wasm::WASM_TYPE_I32);
327 SymbolMap.try_emplace(Import.Field, Symbols.size());
328 Symbols.emplace_back(Import.Field, WasmSymbol::SymbolType::GLOBAL_IMPORT,
329 GlobalIndex++);
330 DEBUG(dbgs() << "Adding import: " << Symbols.back()
331 << " sym index:" << Symbols.size() << "\n");
332 break;
333 case wasm::WASM_EXTERNAL_FUNCTION:
334 SymbolMap.try_emplace(Import.Field, Symbols.size());
335 Symbols.emplace_back(Import.Field,
336 WasmSymbol::SymbolType::FUNCTION_IMPORT,
337 FunctionIndex++, Import.SigIndex);
338 DEBUG(dbgs() << "Adding import: " << Symbols.back()
339 << " sym index:" << Symbols.size() << "\n");
340 break;
341 default:
342 break;
343 }
344 }
345
346 // Add exports to symbol table
347 for (const wasm::WasmExport& Export : Exports) {
348 if (Export.Kind == wasm::WASM_EXTERNAL_FUNCTION ||
349 Export.Kind == wasm::WASM_EXTERNAL_GLOBAL) {
350 WasmSymbol::SymbolType ExportType =
351 Export.Kind == wasm::WASM_EXTERNAL_FUNCTION
352 ? WasmSymbol::SymbolType::FUNCTION_EXPORT
353 : WasmSymbol::SymbolType::GLOBAL_EXPORT;
354 auto Pair = SymbolMap.try_emplace(Export.Name, Symbols.size());
355 if (Pair.second) {
356 Symbols.emplace_back(Export.Name, ExportType, Export.Index);
357 DEBUG(dbgs() << "Adding export: " << Symbols.back()
358 << " sym index:" << Symbols.size() << "\n");
359 } else {
360 uint32_t SymIndex = Pair.first->second;
361 const WasmSymbol &OldSym = Symbols[SymIndex];
362 WasmSymbol NewSym(Export.Name, ExportType, Export.Index);
363 NewSym.setAltIndex(OldSym.ElementIndex);
364 Symbols[SymIndex] = NewSym;
365
366 DEBUG(dbgs() << "Replacing existing symbol: " << NewSym
367 << " sym index:" << SymIndex << "\n");
368 }
369 }
370 if (Export.Kind == wasm::WASM_EXTERNAL_FUNCTION &&
371 isDefinedFunctionIndex(Export.Index)) {
372 auto &Function = getDefinedFunction(Export.Index);
373 if (Function.Name.empty()) {
374 // Use the export's name to set a name for the Function, but only if one
375 // hasn't already been set.
376 Function.Name = Export.Name;
377 }
378 }
379 }
380 }
381
382319 Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr,
383320 const uint8_t *End) {
384321 HasLinkingSection = true;
387324 "Linking data must come after code section", object_error::parse_failed);
388325 }
389326
390 // Only populate the symbol table with imports and exports if the object
391 // has a linking section (i.e. its a relocatable object file). Otherwise
392 // the global might not represent symbols at all.
393 populateSymbolTable();
394
395327 while (Ptr < End) {
396328 uint8_t Type = readVarint7(Ptr);
397329 uint32_t Size = readVaruint32(Ptr);
398330 const uint8_t *SubSectionEnd = Ptr + Size;
399331 switch (Type) {
400 case wasm::WASM_SYMBOL_INFO: {
401 uint32_t Count = readVaruint32(Ptr);
402 while (Count--) {
403 StringRef Symbol = readString(Ptr);
404 uint32_t Flags = readVaruint32(Ptr);
405 auto iter = SymbolMap.find(Symbol);
406 if (iter == SymbolMap.end()) {
407 return make_error(
408 "Invalid symbol name in linking section: " + Symbol,
409 object_error::parse_failed);
410 }
411 uint32_t SymIndex = iter->second;
412 assert(SymIndex < Symbols.size());
413 Symbols[SymIndex].Flags = Flags;
414 DEBUG(dbgs() << "Set symbol flags index:"
415 << SymIndex << " name:"
416 << Symbols[SymIndex].Name << " expected:"
417 << Symbol << " flags: " << Flags << "\n");
418 }
419 break;
420 }
332 case wasm::WASM_SYMBOL_TABLE:
333 if (Error Err = parseLinkingSectionSymtab(Ptr, SubSectionEnd))
334 return Err;
335 break;
421336 case wasm::WASM_DATA_SIZE:
422337 LinkingData.DataSize = readVaruint32(Ptr);
423338 break;
439354 for (uint32_t i = 0; i < Count; i++) {
440355 wasm::WasmInitFunc Init;
441356 Init.Priority = readVaruint32(Ptr);
442 Init.FunctionIndex = readVaruint32(Ptr);
443 if (!isValidFunctionIndex(Init.FunctionIndex))
444 return make_error("Invalid function index: " +
445 Twine(Init.FunctionIndex),
357 Init.Symbol = readVaruint32(Ptr);
358 if (!isValidFunctionSymbolIndex(Init.Symbol))
359 return make_error("Invalid function symbol: " +
360 Twine(Init.Symbol),
446361 object_error::parse_failed);
447362 LinkingData.InitFunctions.emplace_back(Init);
448363 }
463378 if (Ptr != End)
464379 return make_error("Linking section ended prematurely",
465380 object_error::parse_failed);
381 return Error::success();
382 }
383
384 Error WasmObjectFile::parseLinkingSectionSymtab(const uint8_t *&Ptr,
385 const uint8_t *End) {
386 uint32_t Count = readVaruint32(Ptr);
387 LinkingData.SymbolTable.reserve(Count);
388 Symbols.reserve(Count);
389 StringSet<> SymbolNames;
390
391 std::vector ImportedGlobals;
392 std::vector ImportedFunctions;
393 ImportedGlobals.reserve(Imports.size());
394 ImportedFunctions.reserve(Imports.size());
395 for (auto &I : Imports) {
396 if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
397 ImportedFunctions.emplace_back(&I);
398 else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL)
399 ImportedGlobals.emplace_back(&I);
400 }
401
402 while (Count--) {
403 wasm::WasmSymbolInfo Info;
404 const wasm::WasmSignature *FunctionType = nullptr;
405 const wasm::WasmGlobalType *GlobalType = nullptr;
406
407 Info.Kind = readUint8(Ptr);
408 Info.Flags = readVaruint32(Ptr);
409 bool IsDefined = (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0;
410
411 switch (Info.Kind) {
412 case wasm::WASM_SYMBOL_TYPE_FUNCTION:
413 Info.ElementIndex = readVaruint32(Ptr);
414 if (!isValidFunctionIndex(Info.ElementIndex) ||
415 IsDefined != isDefinedFunctionIndex(Info.ElementIndex))
416 return make_error("invalid function symbol index",
417 object_error::parse_failed);
418 if (IsDefined) {
419 Info.Name = readString(Ptr);
420 unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions;
421 FunctionType = &Signatures[FunctionTypes[FuncIndex]];
422 auto &Function = Functions[FuncIndex];
423 if (Function.Name.empty()) {
424 // Use the symbol's name to set a name for the Function, but only if
425 // one hasn't already been set.
426 Function.Name = Info.Name;
427 }
428 } else {
429 wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
430 FunctionType = &Signatures[Import.SigIndex];
431 Info.Name = Import.Field;
432 }
433 break;
434
435 case wasm::WASM_SYMBOL_TYPE_GLOBAL:
436 Info.ElementIndex = readVaruint32(Ptr);
437 if (!isValidGlobalIndex(Info.ElementIndex) ||
438 IsDefined != isDefinedGlobalIndex(Info.ElementIndex))
439 return make_error("invalid global symbol index",
440 object_error::parse_failed);
441 if (IsDefined) {
442 Info.Name = readString(Ptr);
443 unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals;
444 GlobalType = &Globals[GlobalIndex].Type;
445 } else {
446 wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
447 Info.Name = Import.Field;
448 GlobalType = &Import.Global;
449 }
450 break;
451
452 case wasm::WASM_SYMBOL_TYPE_DATA:
453 Info.Name = readString(Ptr);
454 if (IsDefined) {
455 uint32_t Index = readVaruint32(Ptr);
456 if (Index >= DataSegments.size())
457 return make_error("invalid data symbol index",
458 object_error::parse_failed);
459 uint32_t Offset = readVaruint32(Ptr);
460 uint32_t Size = readVaruint32(Ptr);
461 if (Offset + Size > DataSegments[Index].Data.Content.size())
462 return make_error("invalid data symbol index",
463 object_error::parse_failed);
464 Info.DataRef = wasm::WasmDataReference{Index, Offset, Size};
465 }
466 break;
467
468 default:
469 return make_error("Invalid symbol type",
470 object_error::parse_failed);
471 }
472
473 if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
474 wasm::WASM_SYMBOL_BINDING_LOCAL &&
475 !SymbolNames.insert(Info.Name).second)
476 return make_error("Duplicate symbol name " +
477 Twine(Info.Name),
478 object_error::parse_failed);
479 LinkingData.SymbolTable.emplace_back(Info);
480 Symbols.emplace_back(LinkingData.SymbolTable.back(), FunctionType,
481 GlobalType);
482 DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
483 }
484
466485 return Error::success();
467486 }
468487
705724 }
706725
707726 Error WasmObjectFile::parseGlobalSection(const uint8_t *Ptr, const uint8_t *End) {
727 GlobalSection = Sections.size();
708728 uint32_t Count = readVaruint32(Ptr);
709729 Globals.reserve(Count);
710730 while (Count--) {
736756 return make_error("Invalid function export",
737757 object_error::parse_failed);
738758 break;
739 case wasm::WASM_EXTERNAL_GLOBAL: {
740 if (Ex.Index >= Globals.size() + NumImportedGlobals)
759 case wasm::WASM_EXTERNAL_GLOBAL:
760 if (!isValidGlobalIndex(Ex.Index))
741761 return make_error("Invalid global export",
742762 object_error::parse_failed);
743763 break;
744 }
745764 case wasm::WASM_EXTERNAL_MEMORY:
746765 case wasm::WASM_EXTERNAL_TABLE:
747766 break;
758777 }
759778
760779 bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const {
761 return Index < FunctionTypes.size() + NumImportedFunctions;
780 return Index < NumImportedFunctions + FunctionTypes.size();
762781 }
763782
764783 bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const {
765784 return Index >= NumImportedFunctions && isValidFunctionIndex(Index);
766785 }
767786
768 wasm::WasmFunction& WasmObjectFile::getDefinedFunction(uint32_t Index) {
787 bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const {
788 return Index < NumImportedGlobals + Globals.size();
789 }
790
791 bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {
792 return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
793 }
794
795 bool WasmObjectFile::isValidFunctionSymbolIndex(uint32_t Index) const {
796 return Index < Symbols.size() && Symbols[Index].isTypeFunction();
797 }
798
799 wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) {
769800 assert(isDefinedFunctionIndex(Index));
770801 return Functions[Index - NumImportedFunctions];
802 }
803
804 wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) {
805 assert(isDefinedGlobalIndex(Index));
806 return Globals[Index - NumImportedGlobals];
771807 }
772808
773809 Error WasmObjectFile::parseStartSection(const uint8_t *Ptr, const uint8_t *End) {
887923 Result |= SymbolRef::SF_Global;
888924 if (Sym.isHidden())
889925 Result |= SymbolRef::SF_Hidden;
890
891 switch (Sym.Type) {
892 case WasmSymbol::SymbolType::FUNCTION_IMPORT:
893 Result |= SymbolRef::SF_Undefined | SymbolRef::SF_Executable;
894 break;
895 case WasmSymbol::SymbolType::FUNCTION_EXPORT:
926 if (!Sym.isDefined())
927 Result |= SymbolRef::SF_Undefined;
928 if (Sym.isTypeFunction())
896929 Result |= SymbolRef::SF_Executable;
897 break;
898 case WasmSymbol::SymbolType::GLOBAL_IMPORT:
899 Result |= SymbolRef::SF_Undefined;
900 break;
901 case WasmSymbol::SymbolType::GLOBAL_EXPORT:
902 break;
903 }
904
905930 return Result;
906931 }
907932
926951 }
927952
928953 Expected WasmObjectFile::getSymbolName(DataRefImpl Symb) const {
929 return getWasmSymbol(Symb).Name;
954 return getWasmSymbol(Symb).Info.Name;
930955 }
931956
932957 Expected WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const {
934959 }
935960
936961 uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol& Sym) const {
937 switch (Sym.Type) {
938 case WasmSymbol::SymbolType::FUNCTION_IMPORT:
939 case WasmSymbol::SymbolType::GLOBAL_IMPORT:
940 case WasmSymbol::SymbolType::FUNCTION_EXPORT:
941 return Sym.ElementIndex;
942 case WasmSymbol::SymbolType::GLOBAL_EXPORT: {
943 uint32_t GlobalIndex = Sym.ElementIndex - NumImportedGlobals;
944 assert(GlobalIndex < Globals.size());
945 const wasm::WasmGlobal &Global = Globals[GlobalIndex];
946 // WasmSymbols correspond only to I32_CONST globals
947 assert(Global.InitExpr.Opcode == wasm::WASM_OPCODE_I32_CONST);
948 return Global.InitExpr.Value.Int32;
962 switch (Sym.Info.Kind) {
963 case wasm::WASM_SYMBOL_TYPE_FUNCTION:
964 case wasm::WASM_SYMBOL_TYPE_GLOBAL:
965 return Sym.Info.ElementIndex;
966 case wasm::WASM_SYMBOL_TYPE_DATA: {
967 // The value of a data symbol is the segment offset, plus the symbol
968 // offset within the segment.
969 uint32_t SegmentIndex = Sym.Info.DataRef.Segment;
970 const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data;
971 assert(Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST);
972 return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset;
949973 }
950974 }
951975 llvm_unreachable("invalid symbol type");
969993 WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
970994 const WasmSymbol &Sym = getWasmSymbol(Symb);
971995
972 switch (Sym.Type) {
973 case WasmSymbol::SymbolType::FUNCTION_IMPORT:
974 case WasmSymbol::SymbolType::FUNCTION_EXPORT:
996 switch (Sym.Info.Kind) {
997 case wasm::WASM_SYMBOL_TYPE_FUNCTION:
975998 return SymbolRef::ST_Function;
976 case WasmSymbol::SymbolType::GLOBAL_IMPORT:
977 case WasmSymbol::SymbolType::GLOBAL_EXPORT:
999 case wasm::WASM_SYMBOL_TYPE_GLOBAL:
1000 return SymbolRef::ST_Other;
1001 case wasm::WASM_SYMBOL_TYPE_DATA:
9781002 return SymbolRef::ST_Data;
9791003 }
9801004
9841008
9851009 Expected
9861010 WasmObjectFile::getSymbolSection(DataRefImpl Symb) const {
1011 const WasmSymbol& Sym = getWasmSymbol(Symb);
1012 if (Sym.isUndefined())
1013 return section_end();
1014
9871015 DataRefImpl Ref;
988 const WasmSymbol& Sym = getWasmSymbol(Symb);
989 if (Sym.Type == WasmSymbol::SymbolType::GLOBAL_EXPORT)
1016 switch (Sym.Info.Kind) {
1017 case wasm::WASM_SYMBOL_TYPE_FUNCTION:
1018 Ref.d.a = CodeSection;
1019 break;
1020 case wasm::WASM_SYMBOL_TYPE_GLOBAL:
1021 Ref.d.a = GlobalSection;
1022 break;
1023 case wasm::WASM_SYMBOL_TYPE_DATA:
9901024 Ref.d.a = DataSection;
991 else if (Sym.Type == WasmSymbol::SymbolType::FUNCTION_EXPORT)
992 Ref.d.a = CodeSection;
993 else
994 return section_end();
1025 break;
1026 default:
1027 llvm_unreachable("Unknown WasmSymbol::SymbolType");
1028 }
9951029 return section_iterator(SectionRef(Ref, this));
9961030 }
9971031
5757 commonSectionMapping(IO, Section);
5858 IO.mapRequired("Name", Section.Name);
5959 IO.mapRequired("DataSize", Section.DataSize);
60 IO.mapOptional("SymbolInfo", Section.SymbolInfos);
60 IO.mapOptional("SymbolTable", Section.SymbolTable);
6161 IO.mapOptional("SegmentInfo", Section.SegmentInfos);
6262 IO.mapOptional("InitFunctions", Section.InitFunctions);
6363 IO.mapOptional("Comdats", Section.Comdats);
365365 void MappingTraits::mapping(
366366 IO &IO, WasmYAML::InitFunction &Init) {
367367 IO.mapRequired("Priority", Init.Priority);
368 IO.mapRequired("FunctionIndex", Init.FunctionIndex);
368 IO.mapRequired("Symbol", Init.Symbol);
369369 }
370370
371371 void ScalarEnumerationTraits::enumeration(
390390
391391 void MappingTraits::mapping(IO &IO,
392392 WasmYAML::SymbolInfo &Info) {
393 IO.mapRequired("Index", Info.Index);
394 IO.mapRequired("Kind", Info.Kind);
393395 IO.mapRequired("Name", Info.Name);
394396 IO.mapRequired("Flags", Info.Flags);
397 if (Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION) {
398 IO.mapRequired("Function", Info.ElementIndex);
399 } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL) {
400 IO.mapRequired("Global", Info.ElementIndex);
401 } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) {
402 if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
403 IO.mapRequired("Segment", Info.DataRef.Segment);
404 IO.mapOptional("Offset", Info.DataRef.Offset, 0u);
405 IO.mapRequired("Size", Info.DataRef.Size);
406 }
407 } else {
408 llvm_unreachable("unsupported symbol kind");
409 }
395410 }
396411
397412 void ScalarBitSetTraits::bitset(
413428 BCaseMask(BINDING_MASK, BINDING_LOCAL);
414429 //BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT);
415430 BCaseMask(VISIBILITY_MASK, VISIBILITY_HIDDEN);
431 BCaseMask(UNDEFINED, UNDEFINED);
416432 #undef BCaseMask
433 }
434
435 void ScalarEnumerationTraits::enumeration(
436 IO &IO, WasmYAML::SymbolKind &Kind) {
437 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_SYMBOL_TYPE_##X);
438 ECase(FUNCTION);
439 ECase(DATA);
440 ECase(GLOBAL);
441 #undef ECase
417442 }
418443
419444 void ScalarEnumerationTraits::enumeration(
214214
215215 WasmSym->setParams(std::move(ValParams));
216216 WasmSym->setReturns(std::move(ValResults));
217 WasmSym->setIsFunction(true);
217 WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
218218 }
219219
220220 void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) {
7373
7474 WasmSym->setReturns(std::move(Returns));
7575 WasmSym->setParams(std::move(Params));
76 WasmSym->setIsFunction(true);
76 WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
7777 }
7878
7979 return WasmSym;
9090 const WebAssemblySubtarget &Subtarget = Printer.getSubtarget();
9191
9292 // __stack_pointer is a global variable; all other external symbols used by
93 // CodeGen are functions.
94 if (strcmp(Name, "__stack_pointer") == 0)
93 // CodeGen are functions. It's OK to hardcode knowledge of specific symbols
94 // here; this method is precisely there for fetching the signatures of known
95 // Clang-provided symbols.
96 if (strcmp(Name, "__stack_pointer") == 0) {
97 wasm::ValType iPTR =
98 Subtarget.hasAddr64() ? wasm::ValType::I64 : wasm::ValType::I32;
99 WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
100 WasmSym->setGlobalType(wasm::WasmGlobalType{int32_t(iPTR), true});
95101 return WasmSym;
102 }
96103
97104 SmallVector Returns;
98105 SmallVector Params;
100107
101108 WasmSym->setReturns(std::move(Returns));
102109 WasmSym->setParams(std::move(Params));
103 WasmSym->setIsFunction(true);
110 WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
104111
105112 return WasmSym;
106113 }
188195 MCSymbolWasm *WasmSym = cast(Sym);
189196 WasmSym->setReturns(std::move(Returns));
190197 WasmSym->setParams(std::move(Params));
191 WasmSym->setIsFunction(true);
198 WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
192199
193200 const MCExpr *Expr =
194201 MCSymbolRefExpr::create(WasmSym,
1414 ; CHECK: - Type: CUSTOM
1515 ; CHECK-NEXT: Name: linking
1616 ; CHECK-NEXT: DataSize: 2
17 ; CHECK-NEXT: SymbolInfo:
18 ; CHECK-NEXT: - Name: gBd
17 ; CHECK-NEXT: SymbolTable:
18 ; CHECK-NEXT: - Index: 0
19 ; CHECK-NEXT: Kind: DATA
20 ; CHECK-NEXT: Name: gBd
1921 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
22 ; CHECK-NEXT: Segment: 0
23 ; CHECK-NEXT: Size: 2
2024 ; CHECK-NEXT: SegmentInfo:
2125 ; CHECK-NEXT: - Index: 0
2226 ; CHECK-NEXT: Name: .data
88 @foo = global %union.u1 zeroinitializer, align 1
99 @bar = global %union.u1 zeroinitializer, align 1
1010
11 ; CHECK: - Type: GLOBAL
12 ; CHECK-NEXT: Globals:
13 ; CHECK-NEXT: - Index: 0
14 ; CHECK-NEXT: Type: I32
15 ; CHECK-NEXT: Mutable: false
16 ; CHECK-NEXT: InitExpr:
17 ; CHECK-NEXT: Opcode: I32_CONST
18 ; CHECK-NEXT: Value: 0
19 ; CHECK-NEXT: - Index: 1
20 ; CHECK-NEXT: Type: I32
21 ; CHECK-NEXT: Mutable: false
22 ; CHECK-NEXT: InitExpr:
23 ; CHECK-NEXT: Opcode: I32_CONST
24 ; CHECK-NEXT: Value: 4
25 ; CHECK-NEXT: - Index: 2
26 ; CHECK-NEXT: Type: I32
27 ; CHECK-NEXT: Mutable: false
28 ; CHECK-NEXT: InitExpr:
29 ; CHECK-NEXT: Opcode: I32_CONST
30 ; CHECK-NEXT: Value: 8
31 ; CHECK-NEXT: - Index: 3
32 ; CHECK-NEXT: Type: I32
33 ; CHECK-NEXT: Mutable: false
34 ; CHECK-NEXT: InitExpr:
35 ; CHECK-NEXT: Opcode: I32_CONST
36 ; CHECK-NEXT: Value: 9
37 ; CHECK-NEXT: - Type: EXPORT
38 ; CHECK-NEXT: Exports:
39 ; CHECK-NEXT: - Name: g0
40 ; CHECK-NEXT: Kind: GLOBAL
41 ; CHECK-NEXT: Index: 0
42 ; CHECK-NEXT: - Name: g1
43 ; CHECK-NEXT: Kind: GLOBAL
44 ; CHECK-NEXT: Index: 1
45 ; CHECK-NEXT: - Name: foo
46 ; CHECK-NEXT: Kind: GLOBAL
47 ; CHECK-NEXT: Index: 2
48 ; CHECK-NEXT: - Name: bar
49 ; CHECK-NEXT: Kind: GLOBAL
50 ; CHECK-NEXT: Index: 3
51 ; CHECK-NEXT: - Type: DATA
52 ; CHECK-NEXT: Segments:
11 ; CHECK: - Type: DATA
12 ; CHECK-NEXT: Segments:
5313 ; CHECK-NEXT: - SectionOffset: 6
5414 ; CHECK-NEXT: MemoryIndex: 0
55 ; CHECK-NEXT: Offset:
15 ; CHECK-NEXT: Offset:
5616 ; CHECK-NEXT: Opcode: I32_CONST
5717 ; CHECK-NEXT: Value: 0
5818 ; CHECK-NEXT: Content: '00000000'
5919 ; CHECK-NEXT: - SectionOffset: 15
6020 ; CHECK-NEXT: MemoryIndex: 0
61 ; CHECK-NEXT: Offset:
21 ; CHECK-NEXT: Offset:
6222 ; CHECK-NEXT: Opcode: I32_CONST
6323 ; CHECK-NEXT: Value: 4
6424 ; CHECK-NEXT: Content: '00000000'
6525 ; CHECK-NEXT: - SectionOffset: 24
6626 ; CHECK-NEXT: MemoryIndex: 0
67 ; CHECK-NEXT: Offset:
27 ; CHECK-NEXT: Offset:
6828 ; CHECK-NEXT: Opcode: I32_CONST
6929 ; CHECK-NEXT: Value: 8
70 ; CHECK-NEXT: Content: '00'
71 ; CHECK-NEXT: - SectionOffset: 30
30 ; CHECK-NEXT: Content: ''
31 ; CHECK-NEXT: - SectionOffset: 29
7232 ; CHECK-NEXT: MemoryIndex: 0
73 ; CHECK-NEXT: Offset:
33 ; CHECK-NEXT: Offset:
7434 ; CHECK-NEXT: Opcode: I32_CONST
75 ; CHECK-NEXT: Value: 9
76 ; CHECK-NEXT: Content: '00'
35 ; CHECK-NEXT: Value: 8
36 ; CHECK-NEXT: Content: ''
7737 ; CHECK-NEXT: - Type: CUSTOM
7838 ; CHECK-NEXT: Name: linking
79 ; CHECK-NEXT: DataSize: 10
39 ; CHECK-NEXT: DataSize: 8
40 ; CHECK-NEXT: SymbolTable:
41 ; CHECK-NEXT: - Index: 0
42 ; CHECK-NEXT: Kind: DATA
43 ; CHECK-NEXT: Name: g0
44 ; CHECK-NEXT: Flags: [ ]
45 ; CHECK-NEXT: Segment: 0
46 ; CHECK-NEXT: Size: 4
47 ; CHECK-NEXT: - Index: 1
48 ; CHECK-NEXT: Kind: DATA
49 ; CHECK-NEXT: Name: g1
50 ; CHECK-NEXT: Flags: [ ]
51 ; CHECK-NEXT: Segment: 1
52 ; CHECK-NEXT: Size: 4
53 ; CHECK-NEXT: - Index: 2
54 ; CHECK-NEXT: Kind: DATA
55 ; CHECK-NEXT: Name: foo
56 ; CHECK-NEXT: Flags: [ ]
57 ; CHECK-NEXT: Segment: 2
58 ; CHECK-NEXT: Size: 0
59 ; CHECK-NEXT: - Index: 3
60 ; CHECK-NEXT: Kind: DATA
61 ; CHECK-NEXT: Name: bar
62 ; CHECK-NEXT: Flags: [ ]
63 ; CHECK-NEXT: Segment: 3
64 ; CHECK-NEXT: Size: 0
8065 ; CHECK-NEXT: SegmentInfo:
8166 ; CHECK-NEXT: - Index: 0
8267 ; CHECK-NEXT: Name: .bss.g0
4949 ; CHECK-NEXT: SigIndex: 0
5050 ; CHECK-NEXT: - Type: FUNCTION
5151 ; CHECK-NEXT: FunctionTypes: [ 0, 0, 0 ]
52 ; CHECK-NEXT: - Type: GLOBAL
53 ; CHECK-NEXT: Globals:
54 ; CHECK-NEXT: - Index: 0
55 ; CHECK-NEXT: Type: I32
56 ; CHECK-NEXT: Mutable: false
57 ; CHECK-NEXT: InitExpr:
58 ; CHECK-NEXT: Opcode: I32_CONST
59 ; CHECK-NEXT: Value: 0
60 ; CHECK-NEXT: - Type: EXPORT
61 ; CHECK-NEXT: Exports:
62 ; CHECK-NEXT: - Name: callImport
63 ; CHECK-NEXT: Kind: FUNCTION
64 ; CHECK-NEXT: Index: 1
65 ; CHECK-NEXT: - Name: basicInlineFn
66 ; CHECK-NEXT: Kind: FUNCTION
67 ; CHECK-NEXT: Index: 2
68 ; CHECK-NEXT: - Name: sharedFn
69 ; CHECK-NEXT: Kind: FUNCTION
70 ; CHECK-NEXT: Index: 3
71 ; CHECK-NEXT: - Name: constantData
72 ; CHECK-NEXT: Kind: GLOBAL
73 ; CHECK-NEXT: Index: 0
7452 ; CHECK-NEXT: - Type: CODE
7553 ; CHECK-NEXT: Relocations:
7654 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
9775 ; CHECK-NEXT: - Type: CUSTOM
9876 ; CHECK-NEXT: Name: linking
9977 ; CHECK-NEXT: DataSize: 3
100 ; CHECK-NEXT: SymbolInfo:
101 ; CHECK-NEXT: - Name: basicInlineFn
102 ; CHECK-NEXT: Flags: [ BINDING_WEAK ]
103 ; CHECK-NEXT: - Name: sharedFn
104 ; CHECK-NEXT: Flags: [ BINDING_WEAK ]
105 ; CHECK-NEXT: - Name: constantData
106 ; CHECK-NEXT: Flags: [ BINDING_WEAK ]
78 ; CHECK-NEXT: SymbolTable:
79 ; CHECK-NEXT: - Index: 0
80 ; CHECK-NEXT: Kind: FUNCTION
81 ; CHECK-NEXT: Name: funcImport
82 ; CHECK-NEXT: Flags: [ UNDEFINED ]
83 ; CHECK-NEXT: Function: 0
84 ; CHECK-NEXT: - Index: 1
85 ; CHECK-NEXT: Kind: FUNCTION
86 ; CHECK-NEXT: Name: callImport
87 ; CHECK-NEXT: Flags: [ ]
88 ; CHECK-NEXT: Function: 1
89 ; CHECK-NEXT: - Index: 2
90 ; CHECK-NEXT: Kind: FUNCTION
91 ; CHECK-NEXT: Name: basicInlineFn
92 ; CHECK-NEXT: Flags: [ BINDING_WEAK ]
93 ; CHECK-NEXT: Function: 2
94 ; CHECK-NEXT: - Index: 3
95 ; CHECK-NEXT: Kind: FUNCTION
96 ; CHECK-NEXT: Name: sharedFn
97 ; CHECK-NEXT: Flags: [ BINDING_WEAK ]
98 ; CHECK-NEXT: Function: 3
99 ; CHECK-NEXT: - Index: 4
100 ; CHECK-NEXT: Kind: DATA
101 ; CHECK-NEXT: Name: constantData
102 ; CHECK-NEXT: Flags: [ BINDING_WEAK ]
103 ; CHECK-NEXT: Segment: 0
104 ; CHECK-NEXT: Size: 3
107105 ; CHECK-NEXT: SegmentInfo:
108106 ; CHECK-NEXT: - Index: 0
109107 ; CHECK-NEXT: Name: .rodata.constantData
110108 ; CHECK-NEXT: Alignment: 1
111109 ; CHECK-NEXT: Flags: [ ]
112110 ; CHECK-NEXT: Comdats:
113 ; CHECK-NEXT: - Name: basicInlineFn
111 ; CHECK-NEXT: Name: basicInlineFn
114112 ; CHECK-NEXT: Entries:
115113 ; CHECK-NEXT: - Kind: FUNCTION
116114 ; CHECK-NEXT: Index: 2
117 ; CHECK-NEXT: - Name: sharedComdat
115 ; CHECK-NEXT: Name: sharedComdat
118116 ; CHECK-NEXT: Entries:
119117 ; CHECK-NEXT: - Kind: FUNCTION
120118 ; CHECK-NEXT: Index: 3
88 @global2 = global i64 7, align 8, section ".sec1"
99 @global3 = global i32 8, align 8, section ".sec2"
1010
11 ; CHECK: - Type: GLOBAL
12 ; CHECK-NEXT: Globals:
13 ; CHECK-NEXT: - Index: 0
14 ; CHECK-NEXT: Type: I32
15 ; CHECK-NEXT: Mutable: false
16 ; CHECK-NEXT: InitExpr:
17 ; CHECK-NEXT: Opcode: I32_CONST
18 ; CHECK-NEXT: Value: 0
19 ; CHECK-NEXT: - Index: 1
20 ; CHECK-NEXT: Type: I32
21 ; CHECK-NEXT: Mutable: false
22 ; CHECK-NEXT: InitExpr:
23 ; CHECK-NEXT: Opcode: I32_CONST
24 ; CHECK-NEXT: Value: 8
25 ; CHECK-NEXT: - Index: 2
26 ; CHECK-NEXT: Type: I32
27 ; CHECK-NEXT: Mutable: false
28 ; CHECK-NEXT: InitExpr:
29 ; CHECK-NEXT: Opcode: I32_CONST
30 ; CHECK-NEXT: Value: 16
31 ; CHECK-NEXT: - Index: 3
32 ; CHECK-NEXT: Type: I32
33 ; CHECK-NEXT: Mutable: false
34 ; CHECK-NEXT: InitExpr:
35 ; CHECK-NEXT: Opcode: I32_CONST
36 ; CHECK-NEXT: Value: 24
37 ; CHECK-NEXT: - Type: EXPORT
38 ; CHECK-NEXT: Exports:
39 ; CHECK-NEXT: - Name: global0
40 ; CHECK-NEXT: Kind: GLOBAL
41 ; CHECK-NEXT: Index: 0
42 ; CHECK-NEXT: - Name: global1
43 ; CHECK-NEXT: Kind: GLOBAL
44 ; CHECK-NEXT: Index: 1
45 ; CHECK-NEXT: - Name: global2
46 ; CHECK-NEXT: Kind: GLOBAL
47 ; CHECK-NEXT: Index: 2
48 ; CHECK-NEXT: - Name: global3
49 ; CHECK-NEXT: Kind: GLOBAL
50 ; CHECK-NEXT: Index: 3
51 ; CHECK-NEXT: - Type: DATA
11
12 ; CHECK: - Type: DATA
5213 ; CHECK-NEXT: Segments:
5314 ; CHECK-NEXT: - SectionOffset: 6
5415 ; CHECK-NEXT: MemoryIndex: 0
6829 ; CHECK-NEXT: Opcode: I32_CONST
6930 ; CHECK-NEXT: Value: 24
7031 ; CHECK-NEXT: Content: '08000000'
71
72 ; CHECK: - Type: CUSTOM
32 ; CHECK-NEXT: - Type: CUSTOM
7333 ; CHECK-NEXT: Name: linking
7434 ; CHECK-NEXT: DataSize: 28
35 ; CHECK-NEXT: SymbolTable:
36 ; CHECK-NEXT: - Index: 0
37 ; CHECK-NEXT: Kind: DATA
38 ; CHECK-NEXT: Name: global0
39 ; CHECK-NEXT: Flags: [ ]
40 ; CHECK-NEXT: Segment: 0
41 ; CHECK-NEXT: Size: 4
42 ; CHECK-NEXT: - Index: 1
43 ; CHECK-NEXT: Kind: DATA
44 ; CHECK-NEXT: Name: global1
45 ; CHECK-NEXT: Flags: [ ]
46 ; CHECK-NEXT: Segment: 1
47 ; CHECK-NEXT: Size: 8
48 ; CHECK-NEXT: - Index: 2
49 ; CHECK-NEXT: Kind: DATA
50 ; CHECK-NEXT: Name: global2
51 ; CHECK-NEXT: Flags: [ ]
52 ; CHECK-NEXT: Segment: 1
53 ; CHECK-NEXT: Offset: 8
54 ; CHECK-NEXT: Size: 8
55 ; CHECK-NEXT: - Index: 3
56 ; CHECK-NEXT: Kind: DATA
57 ; CHECK-NEXT: Name: global3
58 ; CHECK-NEXT: Flags: [ ]
59 ; CHECK-NEXT: Segment: 2
60 ; CHECK-NEXT: Size: 4
7561 ; CHECK-NEXT: SegmentInfo:
7662 ; CHECK-NEXT: - Index: 0
7763 ; CHECK-NEXT: Name: .data.global0
2929 ; CHECK: }
3030
3131 ; CHECK: Relocations [
32 ; CHECK: Section (6) CODE {
32 ; CHECK: Section (5) CODE {
3333 ; CHECK: Relocation {
3434 ; CHECK: Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB (0)
3535 ; CHECK: Offset: 0x4
4343 ; CHECK: Relocation {
4444 ; CHECK: Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB (1)
4545 ; CHECK: Offset: 0x1E
46 ; CHECK: Index: 0x2
46 ; CHECK: Index: 0x3
4747 ; CHECK: }
4848 ; CHECK: }
3737 ; CHECK-NEXT: Kind: FUNCTION
3838 ; CHECK-NEXT: SigIndex: 1
3939 ; CHECK-NEXT: - Module: env
40 ; CHECK-NEXT: Field: __dso_handle
41 ; CHECK-NEXT: Kind: GLOBAL
42 ; CHECK-NEXT: GlobalType: I32
43 ; CHECK-NEXT: GlobalMutable: false
44 ; CHECK-NEXT: - Module: env
4540 ; CHECK-NEXT: Field: __cxa_atexit
4641 ; CHECK-NEXT: Kind: FUNCTION
4742 ; CHECK-NEXT: SigIndex: 2
5954 ; CHECK-NEXT: SigIndex: 1
6055 ; CHECK-NEXT: - Type: FUNCTION
6156 ; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 1 ]
62 ; CHECK-NEXT: - Type: GLOBAL
63 ; CHECK-NEXT: Globals:
64 ; CHECK-NEXT: - Index: 1
65 ; CHECK-NEXT: Type: I32
66 ; CHECK-NEXT: Mutable: false
67 ; CHECK-NEXT: InitExpr:
68 ; CHECK-NEXT: Opcode: I32_CONST
69 ; CHECK-NEXT: Value: 0
70 ; CHECK-NEXT: - Type: EXPORT
71 ; CHECK-NEXT: Exports:
72 ; CHECK-NEXT: - Name: .Lcall_dtors.42
73 ; CHECK-NEXT: Kind: FUNCTION
74 ; CHECK-NEXT: Index: 5
75 ; CHECK-NEXT: - Name: .Lregister_call_dtors.42
76 ; CHECK-NEXT: Kind: FUNCTION
77 ; CHECK-NEXT: Index: 6
78 ; CHECK-NEXT: - Name: .Lcall_dtors
79 ; CHECK-NEXT: Kind: FUNCTION
80 ; CHECK-NEXT: Index: 7
81 ; CHECK-NEXT: - Name: .Lregister_call_dtors
82 ; CHECK-NEXT: Kind: FUNCTION
83 ; CHECK-NEXT: Index: 8
84 ; CHECK-NEXT: - Name: global1
85 ; CHECK-NEXT: Kind: GLOBAL
86 ; CHECK-NEXT: Index: 1
8757 ; CHECK-NEXT: - Type: ELEM
8858 ; CHECK-NEXT: Segments:
8959 ; CHECK-NEXT: - Offset:
9666 ; CHECK-NEXT: Index: 0
9767 ; CHECK-NEXT: Offset: 0x00000004
9868 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
99 ; CHECK-NEXT: Index: 5
69 ; CHECK-NEXT: Index: 6
10070 ; CHECK-NEXT: Offset: 0x0000000F
10171 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
102 ; CHECK-NEXT: Index: 0
72 ; CHECK-NEXT: Index: 1
10373 ; CHECK-NEXT: Offset: 0x00000017
10474 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
105 ; CHECK-NEXT: Index: 1
75 ; CHECK-NEXT: Index: 2
10676 ; CHECK-NEXT: Offset: 0x0000001D
10777 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
108 ; CHECK-NEXT: Index: 2
78 ; CHECK-NEXT: Index: 3
10979 ; CHECK-NEXT: Offset: 0x0000002C
11080 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB
111 ; CHECK-NEXT: Index: 7
81 ; CHECK-NEXT: Index: 8
11282 ; CHECK-NEXT: Offset: 0x00000037
11383 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB
114 ; CHECK-NEXT: Index: 0
84 ; CHECK-NEXT: Index: 1
11585 ; CHECK-NEXT: Offset: 0x0000003F
11686 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
117 ; CHECK-NEXT: Index: 1
87 ; CHECK-NEXT: Index: 2
11888 ; CHECK-NEXT: Offset: 0x00000045
11989 ; CHECK-NEXT: Functions:
12090 ; CHECK-NEXT: - Index: 5
140110 ; CHECK-NEXT: - Type: CUSTOM
141111 ; CHECK-NEXT: Name: linking
142112 ; CHECK-NEXT: DataSize: 4
143 ; CHECK-NEXT: SymbolInfo:
144 ; CHECK-NEXT: - Name: __dso_handle
145 ; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ]
146 ; CHECK-NEXT: - Name: .Lcall_dtors.42
113 ; CHECK-NEXT: SymbolTable:
114 ; CHECK-NEXT: - Index: 0
115 ; CHECK-NEXT: Kind: FUNCTION
116 ; CHECK-NEXT: Name: func3
117 ; CHECK-NEXT: Flags: [ UNDEFINED ]
118 ; CHECK-NEXT: Function: 0
119 ; CHECK-NEXT: - Index: 1
120 ; CHECK-NEXT: Kind: DATA
121 ; CHECK-NEXT: Name: __dso_handle
122 ; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN, UNDEFINED ]
123 ; CHECK-NEXT: - Index: 2
124 ; CHECK-NEXT: Kind: FUNCTION
125 ; CHECK-NEXT: Name: __cxa_atexit
126 ; CHECK-NEXT: Flags: [ UNDEFINED ]
127 ; CHECK-NEXT: Function: 1
128 ; CHECK-NEXT: - Index: 3
129 ; CHECK-NEXT: Kind: FUNCTION
130 ; CHECK-NEXT: Name: func2
131 ; CHECK-NEXT: Flags: [ UNDEFINED ]
132 ; CHECK-NEXT: Function: 2
133 ; CHECK-NEXT: - Index: 4
134 ; CHECK-NEXT: Kind: FUNCTION
135 ; CHECK-NEXT: Name: func1
136 ; CHECK-NEXT: Flags: [ UNDEFINED ]
137 ; CHECK-NEXT: Function: 3
138 ; CHECK-NEXT: - Index: 5
139 ; CHECK-NEXT: Kind: FUNCTION
140 ; CHECK-NEXT: Name: func0
141 ; CHECK-NEXT: Flags: [ UNDEFINED ]
142 ; CHECK-NEXT: Function: 4
143 ; CHECK-NEXT: - Index: 6
144 ; CHECK-NEXT: Kind: FUNCTION
145 ; CHECK-NEXT: Name: .Lcall_dtors.42
147146 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ]
148 ; CHECK-NEXT: - Name: .Lregister_call_dtors.42
147 ; CHECK-NEXT: Function: 5
148 ; CHECK-NEXT: - Index: 7
149 ; CHECK-NEXT: Kind: FUNCTION
150 ; CHECK-NEXT: Name: .Lregister_call_dtors.42
149151 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ]
150 ; CHECK-NEXT: - Name: .Lcall_dtors
152 ; CHECK-NEXT: Function: 6
153 ; CHECK-NEXT: - Index: 8
154 ; CHECK-NEXT: Kind: FUNCTION
155 ; CHECK-NEXT: Name: .Lcall_dtors
151156 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ]
152 ; CHECK-NEXT: - Name: .Lregister_call_dtors
157 ; CHECK-NEXT: Function: 7
158 ; CHECK-NEXT: - Index: 9
159 ; CHECK-NEXT: Kind: FUNCTION
160 ; CHECK-NEXT: Name: .Lregister_call_dtors
153161 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ]
162 ; CHECK-NEXT: Function: 8
163 ; CHECK-NEXT: - Index: 10
164 ; CHECK-NEXT: Kind: DATA
165 ; CHECK-NEXT: Name: global1
166 ; CHECK-NEXT: Flags: [ ]
167 ; CHECK-NEXT: Segment: 0
168 ; CHECK-NEXT: Size: 4
154169 ; CHECK-NEXT: SegmentInfo:
155170 ; CHECK-NEXT: - Index: 0
156171 ; CHECK-NEXT: Name: .data.global1
158173 ; CHECK-NEXT: Flags: [ ]
159174 ; CHECK-NEXT: InitFunctions:
160175 ; CHECK-NEXT: - Priority: 42
161 ; CHECK-NEXT: FunctionIndex: 3
176 ; CHECK-NEXT: Symbol: 4
162177 ; CHECK-NEXT: - Priority: 42
163 ; CHECK-NEXT: FunctionIndex: 6
178 ; CHECK-NEXT: Symbol: 7
164179 ; CHECK-NEXT: - Priority: 65535
165 ; CHECK-NEXT: FunctionIndex: 4
180 ; CHECK-NEXT: Symbol: 5
166181 ; CHECK-NEXT: - Priority: 65535
167 ; CHECK-NEXT: FunctionIndex: 8
182 ; CHECK-NEXT: Symbol: 9
168183 ; CHECK-NEXT: ...
2323
2424 ; CHECK: Format: WASM
2525 ; CHECK: Relocations [
26 ; CHECK-NEXT: Section (6) CODE {
26 ; CHECK-NEXT: Section (4) CODE {
2727 ; CHECK-NEXT: Relocation {
2828 ; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB (3)
2929 ; CHECK-NEXT: Offset: 0x9
30 ; CHECK-NEXT: Index: 0x0
30 ; CHECK-NEXT: Index: 0x3
3131 ; CHECK-NEXT: Addend: 0
3232 ; CHECK-NEXT: }
3333 ; CHECK-NEXT: Relocation {
3434 ; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB (3)
3535 ; CHECK-NEXT: Offset: 0x14
36 ; CHECK-NEXT: Index: 0x1
36 ; CHECK-NEXT: Index: 0x4
3737 ; CHECK-NEXT: Addend: 0
3838 ; CHECK-NEXT: }
3939 ; CHECK-NEXT: Relocation {
1212
1313 ; CHECK: Format: WASM
1414 ; CHECK: Relocations [
15 ; CHECK-NEXT: Section (4) DATA {
15 ; CHECK-NEXT: Section (2) DATA {
1616 ; CHECK-NEXT: Relocation {
1717 ; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 (5)
1818 ; CHECK-NEXT: Offset: 0x13
2828 ; CHECK: Type: FUNCTION (0x3)
2929 ; CHECK: }
3030 ; CHECK: Section {
31 ; CHECK: Type: GLOBAL (0x6)
32 ; CHECK: }
33 ; CHECK: Section {
34 ; CHECK: Type: EXPORT (0x7)
35 ; CHECK: }
36 ; CHECK: Section {
3731 ; CHECK: Type: CODE (0xA)
3832 ; CHECK: }
3933 ; CHECK: Section {
88 @b = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str2, i32 0, i32 0), align 8
99
1010
11 ; CHECK: - Type: GLOBAL
12 ; CHECK-NEXT: Globals:
13 ; CHECK-NEXT: - Index: 0
14 ; CHECK-NEXT: Type: I32
15 ; CHECK-NEXT: Mutable: false
16 ; CHECK-NEXT: InitExpr:
17 ; CHECK-NEXT: Opcode: I32_CONST
18 ; CHECK-NEXT: Value: 0
19 ; CHECK-NEXT: - Index: 1
20 ; CHECK-NEXT: Type: I32
21 ; CHECK-NEXT: Mutable: false
22 ; CHECK-NEXT: InitExpr:
23 ; CHECK-NEXT: Opcode: I32_CONST
24 ; CHECK-NEXT: Value: 6
25 ; CHECK-NEXT: - Index: 2
26 ; CHECK-NEXT: Type: I32
27 ; CHECK-NEXT: Mutable: false
28 ; CHECK-NEXT: InitExpr:
29 ; CHECK-NEXT: Opcode: I32_CONST
30 ; CHECK-NEXT: Value: 16
31 ; CHECK-NEXT: - Index: 3
32 ; CHECK-NEXT: Type: I32
33 ; CHECK-NEXT: Mutable: false
34 ; CHECK-NEXT: InitExpr:
35 ; CHECK-NEXT: Opcode: I32_CONST
36 ; CHECK-NEXT: Value: 24
37 ; CHECK-NEXT: - Type: EXPORT
38 ; CHECK-NEXT: Exports:
39 ; CHECK-NEXT: - Name: .L.str1
40 ; CHECK-NEXT: Kind: GLOBAL
41 ; CHECK-NEXT: Index: 0
42 ; CHECK-NEXT: - Name: .L.str2
43 ; CHECK-NEXT: Kind: GLOBAL
44 ; CHECK-NEXT: Index: 1
45 ; CHECK-NEXT: - Name: a
46 ; CHECK-NEXT: Kind: GLOBAL
47 ; CHECK-NEXT: Index: 2
48 ; CHECK-NEXT: - Name: b
49 ; CHECK-NEXT: Kind: GLOBAL
50 ; CHECK-NEXT: Index: 3
51 ; CHECK-NEXT: - Type: DATA
11 ; CHECK: - Type: DATA
5212 ; CHECK-NEXT: Relocations:
5313 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
5414 ; CHECK-NEXT: Index: 0
8444 ; CHECK-NEXT: - Type: CUSTOM
8545 ; CHECK-NEXT: Name: linking
8646 ; CHECK-NEXT: DataSize: 28
87 ; CHECK-NEXT: SymbolInfo:
88 ; CHECK-NEXT: - Name: .L.str1
47 ; CHECK-NEXT: SymbolTable:
48 ; CHECK-NEXT: - Index: 0
49 ; CHECK-NEXT: Kind: DATA
50 ; CHECK-NEXT: Name: .L.str1
8951 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ]
90 ; CHECK-NEXT: - Name: .L.str2
52 ; CHECK-NEXT: Segment: 0
53 ; CHECK-NEXT: Size: 6
54 ; CHECK-NEXT: - Index: 1
55 ; CHECK-NEXT: Kind: DATA
56 ; CHECK-NEXT: Name: .L.str2
9157 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ]
58 ; CHECK-NEXT: Segment: 1
59 ; CHECK-NEXT: Size: 6
60 ; CHECK-NEXT: - Index: 2
61 ; CHECK-NEXT: Kind: DATA
62 ; CHECK-NEXT: Name: a
63 ; CHECK-NEXT: Flags: [ ]
64 ; CHECK-NEXT: Segment: 2
65 ; CHECK-NEXT: Size: 4
66 ; CHECK-NEXT: - Index: 3
67 ; CHECK-NEXT: Kind: DATA
68 ; CHECK-NEXT: Name: b
69 ; CHECK-NEXT: Flags: [ ]
70 ; CHECK-NEXT: Segment: 3
71 ; CHECK-NEXT: Size: 4
9272 ; CHECK-NEXT: SegmentInfo:
9373 ; CHECK-NEXT: - Index: 0
9474 ; CHECK-NEXT: Name: .rodata..L.str1
1616 ; CHECK: - Type: CUSTOM
1717 ; CHECK-NEXT: Name: linking
1818 ; CHECK-NEXT: DataSize: 0
19 ; CHECK-NEXT: SymbolInfo:
20 ; CHECK-NEXT: - Name: hiddenVis
19 ; CHECK-NEXT: SymbolTable:
20 ; CHECK-NEXT: - Index: 0
21 ; CHECK-NEXT: Kind: FUNCTION
22 ; CHECK-NEXT: Name: defaultVis
23 ; CHECK-NEXT: Flags: [ ]
24 ; CHECK-NEXT: Function: 0
25 ; CHECK-NEXT: - Index: 1
26 ; CHECK-NEXT: Kind: FUNCTION
27 ; CHECK-NEXT: Name: hiddenVis
2128 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
29 ; CHECK-NEXT: Function: 1
2230 ; CHECK-NEXT: ...
6464 ; CHECK-NEXT: ElemType: ANYFUNC
6565 ; CHECK-NEXT: Limits:
6666 ; CHECK-NEXT: Initial: 0x00000001
67 ; CHECK-NEXT: - Module: env
68 ; CHECK-NEXT: Field: foo_alias
69 ; CHECK-NEXT: Kind: FUNCTION
70 ; CHECK-NEXT: SigIndex: 0
71 ; CHECK-NEXT: - Module: env
72 ; CHECK-NEXT: Field: bar_alias
73 ; CHECK-NEXT: Kind: GLOBAL
74 ; CHECK-NEXT: GlobalType: I32
75 ; CHECK-NEXT: GlobalMutable: false
7667 ; CHECK-NEXT: - Type: FUNCTION
7768 ; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ]
78 ; CHECK-NEXT: - Type: GLOBAL
79 ; CHECK-NEXT: Globals:
80 ; CHECK-NEXT: - Index: 1
81 ; CHECK-NEXT: Type: I32
82 ; CHECK-NEXT: Mutable: false
83 ; CHECK-NEXT: InitExpr:
84 ; CHECK-NEXT: Opcode: I32_CONST
85 ; CHECK-NEXT: Value: 8
86 ; CHECK-NEXT: - Index: 2
87 ; CHECK-NEXT: Type: I32
88 ; CHECK-NEXT: Mutable: false
89 ; CHECK-NEXT: InitExpr:
90 ; CHECK-NEXT: Opcode: I32_CONST
91 ; CHECK-NEXT: Value: 16
92 ; CHECK-NEXT: - Index: 3
93 ; CHECK-NEXT: Type: I32
94 ; CHECK-NEXT: Mutable: false
95 ; CHECK-NEXT: InitExpr:
96 ; CHECK-NEXT: Opcode: I32_CONST
97 ; CHECK-NEXT: Value: 0
98 ; CHECK-NEXT: - Type: EXPORT
99 ; CHECK-NEXT: Exports:
100 ; CHECK-NEXT: - Name: foo
101 ; CHECK-NEXT: Kind: FUNCTION
102 ; CHECK-NEXT: Index: 1
103 ; CHECK-NEXT: - Name: call_direct
104 ; CHECK-NEXT: Kind: FUNCTION
105 ; CHECK-NEXT: Index: 2
106 ; CHECK-NEXT: - Name: call_alias
107 ; CHECK-NEXT: Kind: FUNCTION
108 ; CHECK-NEXT: Index: 3
109 ; CHECK-NEXT: - Name: call_direct_ptr
110 ; CHECK-NEXT: Kind: FUNCTION
111 ; CHECK-NEXT: Index: 4
112 ; CHECK-NEXT: - Name: direct_address
113 ; CHECK-NEXT: Kind: GLOBAL
114 ; CHECK-NEXT: Index: 1
115 ; CHECK-NEXT: - Name: call_alias_ptr
116 ; CHECK-NEXT: Kind: FUNCTION
117 ; CHECK-NEXT: Index: 5
118 ; CHECK-NEXT: - Name: alias_address
119 ; CHECK-NEXT: Kind: GLOBAL
120 ; CHECK-NEXT: Index: 2
121 ; CHECK-NEXT: - Name: bar
122 ; CHECK-NEXT: Kind: GLOBAL
123 ; CHECK-NEXT: Index: 3
124 ; CHECK-NEXT: - Name: foo_alias
125 ; CHECK-NEXT: Kind: FUNCTION
126 ; CHECK-NEXT: Index: 1
127 ; CHECK-NEXT: - Name: bar_alias
128 ; CHECK-NEXT: Kind: GLOBAL
129 ; CHECK-NEXT: Index: 3
13069 ; CHECK-NEXT: - Type: ELEM
13170 ; CHECK-NEXT: Segments:
13271 ; CHECK-NEXT: - Offset:
13372 ; CHECK-NEXT: Opcode: I32_CONST
13473 ; CHECK-NEXT: Value: 1
135 ; CHECK-NEXT: Functions: [ 1 ]
74 ; CHECK-NEXT: Functions: [ 0 ]
13675 ; CHECK-NEXT: - Type: CODE
13776 ; CHECK-NEXT: Relocations:
13877 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
139 ; CHECK-NEXT: Index: 1
78 ; CHECK-NEXT: Index: 0
14079 ; CHECK-NEXT: Offset: 0x00000009
14180 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
142 ; CHECK-NEXT: Index: 0
81 ; CHECK-NEXT: Index: 8
14382 ; CHECK-NEXT: Offset: 0x00000012
14483 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
145 ; CHECK-NEXT: Index: 1
84 ; CHECK-NEXT: Index: 4
14685 ; CHECK-NEXT: Offset: 0x0000001E
14786 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TYPE_INDEX_LEB
14887 ; CHECK-NEXT: Index: 0
14988 ; CHECK-NEXT: Offset: 0x00000024
15089 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB
151 ; CHECK-NEXT: Index: 2
90 ; CHECK-NEXT: Index: 6
15291 ; CHECK-NEXT: Offset: 0x00000031
15392 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TYPE_INDEX_LEB
15493 ; CHECK-NEXT: Index: 0
15594 ; CHECK-NEXT: Offset: 0x00000037
15695 ; CHECK-NEXT: Functions:
96 ; CHECK-NEXT: - Index: 0
97 ; CHECK-NEXT: Locals:
98 ; CHECK-NEXT: Body: 41000B
15799 ; CHECK-NEXT: - Index: 1
158100 ; CHECK-NEXT: Locals:
159 ; CHECK-NEXT: Body: 41000B
101 ; CHECK-NEXT: Body: 1080808080000B
160102 ; CHECK-NEXT: - Index: 2
161103 ; CHECK-NEXT: Locals:
162 ; CHECK-NEXT: Body: 1081808080000B
104 ; CHECK-NEXT: Body: 1080808080000B
163105 ; CHECK-NEXT: - Index: 3
164106 ; CHECK-NEXT: Locals:
165 ; CHECK-NEXT: Body: 1080808080000B
107 ; CHECK-NEXT: Body: 410028028880808000118080808000000B
166108 ; CHECK-NEXT: - Index: 4
167 ; CHECK-NEXT: Locals:
168 ; CHECK-NEXT: Body: 410028028880808000118080808000000B
169 ; CHECK-NEXT: - Index: 5
170109 ; CHECK-NEXT: Locals:
171110 ; CHECK-NEXT: Body: 410028029080808000118080808000000B
172111 ; CHECK-NEXT: - Type: DATA
173112 ; CHECK-NEXT: Relocations:
174113 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
175 ; CHECK-NEXT: Index: 1
114 ; CHECK-NEXT: Index: 0
176115 ; CHECK-NEXT: Offset: 0x0000000F
177116 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
178 ; CHECK-NEXT: Index: 0
117 ; CHECK-NEXT: Index: 8
179118 ; CHECK-NEXT: Offset: 0x00000018
180119 ; CHECK-NEXT: Segments:
181120 ; CHECK-NEXT: - SectionOffset: 6
199138 ; CHECK-NEXT: - Type: CUSTOM
200139 ; CHECK-NEXT: Name: linking
201140 ; CHECK-NEXT: DataSize: 20
202 ; CHECK-NEXT: SymbolInfo:
203 ; CHECK-NEXT: - Name: foo_alias
141 ; CHECK-NEXT: SymbolTable:
142 ; CHECK-NEXT: - Index: 0
143 ; CHECK-NEXT: Kind: FUNCTION
144 ; CHECK-NEXT: Name: foo
145 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
146 ; CHECK-NEXT: Function: 0
147 ; CHECK-NEXT: - Index: 1
148 ; CHECK-NEXT: Kind: FUNCTION
149 ; CHECK-NEXT: Name: call_direct
150 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
151 ; CHECK-NEXT: Function: 1
152 ; CHECK-NEXT: - Index: 2
153 ; CHECK-NEXT: Kind: FUNCTION
154 ; CHECK-NEXT: Name: call_alias
155 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
156 ; CHECK-NEXT: Function: 2
157 ; CHECK-NEXT: - Index: 3
158 ; CHECK-NEXT: Kind: FUNCTION
159 ; CHECK-NEXT: Name: call_direct_ptr
160 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
161 ; CHECK-NEXT: Function: 3
162 ; CHECK-NEXT: - Index: 4
163 ; CHECK-NEXT: Kind: DATA
164 ; CHECK-NEXT: Name: direct_address
165 ; CHECK-NEXT: Flags: [ ]
166 ; CHECK-NEXT: Segment: 1
167 ; CHECK-NEXT: Size: 4
168 ; CHECK-NEXT: - Index: 5
169 ; CHECK-NEXT: Kind: FUNCTION
170 ; CHECK-NEXT: Name: call_alias_ptr
171 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
172 ; CHECK-NEXT: Function: 4
173 ; CHECK-NEXT: - Index: 6
174 ; CHECK-NEXT: Kind: DATA
175 ; CHECK-NEXT: Name: alias_address
176 ; CHECK-NEXT: Flags: [ ]
177 ; CHECK-NEXT: Segment: 2
178 ; CHECK-NEXT: Size: 4
179 ; CHECK-NEXT: - Index: 7
180 ; CHECK-NEXT: Kind: DATA
181 ; CHECK-NEXT: Name: bar
182 ; CHECK-NEXT: Flags: [ ]
183 ; CHECK-NEXT: Segment: 0
184 ; CHECK-NEXT: Size: 4
185 ; CHECK-NEXT: - Index: 8
186 ; CHECK-NEXT: Kind: FUNCTION
187 ; CHECK-NEXT: Name: foo_alias
204188 ; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ]
205 ; CHECK-NEXT: - Name: bar_alias
189 ; CHECK-NEXT: Function: 0
190 ; CHECK-NEXT: - Index: 9
191 ; CHECK-NEXT: Kind: DATA
192 ; CHECK-NEXT: Name: bar_alias
206193 ; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ]
207 ; CHECK-NEXT: - Name: foo
208 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
209 ; CHECK-NEXT: - Name: call_direct
210 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
211 ; CHECK-NEXT: - Name: call_alias
212 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
213 ; CHECK-NEXT: - Name: call_direct_ptr
214 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
215 ; CHECK-NEXT: - Name: call_alias_ptr
216 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
194 ; CHECK-NEXT: Segment: 0
195 ; CHECK-NEXT: Size: 4
217196 ; CHECK-NEXT: SegmentInfo:
218197 ; CHECK-NEXT: - Index: 0
219198 ; CHECK-NEXT: Name: .data.bar
230209 ; CHECK-NEXT: ...
231210
232211 ; CHECK-SYMS: SYMBOL TABLE:
233 ; CHECK-SYMS-NEXT: 00000001 gw F CODE .hidden foo_alias
234 ; CHECK-SYMS-NEXT: 00000000 gw DATA .hidden bar_alias
235 ; CHECK-SYMS-NEXT: 00000001 g F CODE .hidden foo
236 ; CHECK-SYMS-NEXT: 00000002 g F CODE .hidden call_direct
237 ; CHECK-SYMS-NEXT: 00000003 g F CODE .hidden call_alias
238 ; CHECK-SYMS-NEXT: 00000004 g F CODE .hidden call_direct_ptr
212 ; CHECK-SYMS-NEXT: 00000000 g F CODE .hidden foo
213 ; CHECK-SYMS-NEXT: 00000001 g F CODE .hidden call_direct
214 ; CHECK-SYMS-NEXT: 00000002 g F CODE .hidden call_alias
215 ; CHECK-SYMS-NEXT: 00000003 g F CODE .hidden call_direct_ptr
239216 ; CHECK-SYMS-NEXT: 00000008 g DATA direct_address
240 ; CHECK-SYMS-NEXT: 00000005 g F CODE .hidden call_alias_ptr
217 ; CHECK-SYMS-NEXT: 00000004 g F CODE .hidden call_alias_ptr
241218 ; CHECK-SYMS-NEXT: 00000010 g DATA alias_address
242219 ; CHECK-SYMS-NEXT: 00000000 g DATA bar
220 ; CHECK-SYMS-NEXT: 00000000 gw F CODE .hidden foo_alias
221 ; CHECK-SYMS-NEXT: 00000000 gw DATA .hidden bar_alias
1717 ; CHECK-NEXT: Field: __linear_memory
1818 ; CHECK: - Module: env
1919 ; CHECK-NEXT: Field: __indirect_function_table
20 ; CHECK: - Module: env
21 ; CHECK-NEXT: Field: weak_external_data
22 ; CHECK-NEXT: Kind: GLOBAL
23 ; CHECK-NEXT: GlobalType: I32
24 ; CHECK-NEXT: GlobalMutable: false
2520
2621
2722 ; CHECK: - Type: CUSTOM
2823 ; CHECK-NEXT: Name: linking
2924 ; CHECK-NEXT: DataSize: 0
30 ; CHECK-NEXT: SymbolInfo:
31 ; CHECK-NEXT: - Name: weak_external_data
32 ; CHECK-NEXT: Flags: [ BINDING_WEAK ]
33 ; CHECK-NEXT: - Name: weak_function
25 ; CHECK-NEXT: SymbolTable:
26 ; CHECK-NEXT: - Index: 0
27 ; CHECK-NEXT: Kind: DATA
28 ; CHECK-NEXT: Name: weak_external_data
29 ; CHECK-NEXT: Flags: [ BINDING_WEAK, UNDEFINED ]
30 ; CHECK-NEXT: - Index: 1
31 ; CHECK-NEXT: Kind: FUNCTION
32 ; CHECK-NEXT: Name: weak_function
3433 ; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ]
34 ; CHECK-NEXT: Function: 0
3535 ; CHECK-NEXT: ...
5858 COFF32-NEXT: 00000000 T _main
5959 COFF32-NEXT: U _puts
6060
61 WASM: U SomeOtherFunction
61
62 WASM: 00000000 d .L.str
63 WASM-NEXT: U SomeOtherFunction
6264 WASM-NEXT: 00000002 T main
6365 WASM-NEXT: U puts
6466 WASM-NEXT: 00000010 D var
67
6568
6669 COFF64: 00000000 d .data
6770 COFF64-NEXT: 00000000 t .text
644644 ELF-AVR-NEXT: Section: .data
645645 ELF-AVR-NEXT: Value: 0x0000000000800060
646646
647
647648 WASM: --- !WASM
648649 WASM-NEXT: FileHeader:
649650 WASM-NEXT: Version: 0x00000001
650 WASM: - Type: EXPORT
651 WASM-NEXT: Exports:
652 WASM-NEXT: - Name: main
653 WASM-NEXT: Kind: FUNCTION
654 WASM-NEXT: Index: 2
655 WASM-NEXT: - Name: var
656 WASM-NEXT: Kind: GLOBAL
657 WASM-NEXT: Index: 1
651 WASM: - Type: CUSTOM
652 WASM-NEXT: Name: linking
653 WASM-NEXT: DataSize: 20
654 WASM-NEXT: SymbolTable:
655 WASM-NEXT: - Index: 0
656 WASM-NEXT: Kind: FUNCTION
657 WASM-NEXT: Name: puts
658 WASM-NEXT: Flags: [ UNDEFINED ]
659 WASM-NEXT: Function: 0
660 WASM-NEXT: - Index: 1
661 WASM: Name: SomeOtherFunction
662 WASM: - Index: 2
663 WASM: Name: main
664 WASM: - Index: 3
665 WASM-NEXT: Kind: DATA
666 WASM-NEXT: Name: .L.str
667 WASM-NEXT: Flags: [ BINDING_LOCAL ]
668 WASM-NEXT: Segment: 0
669 WASM-NEXT: Size: 13
670 WASM-NEXT: - Index: 4
671 WASM: Name: var
672 WASM: SegmentInfo:
673 WASM-NEXT: - Index: 0
674 WASM-NEXT: Name: .rodata..L.str
675 WASM-NEXT: Alignment: 1
676 WASM-NEXT: Flags: [ ]
677 WASM-NEXT: - Index: 1
678 WASM: ...
679
658680
659681 ELF-X86-64-UNWIND: - Name: .eh_frame
660682 ELF-X86-64-UNWIND-NEXT: Type: SHT_X86_64_UNWIND
5959 ELF-MIPSEL: R_MIPS_CALL16 SomeOtherFunction
6060
6161 WASM: CODE
62 WASM-NEXT: R_WEBASSEMBLY_MEMORY_ADDR_SLEB 0+0
62 WASM-NEXT: R_WEBASSEMBLY_MEMORY_ADDR_SLEB 3+0
6363 WASM-NEXT: R_WEBASSEMBLY_FUNCTION_INDEX_LEB 0+0
6464 WASM-NEXT: R_WEBASSEMBLY_FUNCTION_INDEX_LEB 1+0
6565
2929 - Type: CUSTOM
3030 Name: linking
3131 DataSize: 999
32 SymbolInfo:
33 - Name: bar
34 Flags: [ BINDING_WEAK ]
32 SymbolTable:
33 - Index: 0
34 Kind: FUNCTION
35 Name: bar
36 Flags: [ BINDING_WEAK, UNDEFINED ]
37 Function: 0
3538 SegmentInfo:
3639 - Index: 0
3740 Alignment: 4
4346 Name: moredata
4447 InitFunctions:
4548 - Priority: 1
46 FunctionIndex: 0
49 Symbol: 0
4750 ...
4851 # CHECK: - Type: CUSTOM
4952 # CHECK-NEXT: Name: linking
5053 # CHECK-NEXT: DataSize: 999
51 # CHECK-NEXT: SymbolInfo:
52 # CHECK-NEXT: - Name: bar
53 # CHECK-NEXT: Flags: [ BINDING_WEAK ]
54 # CHECK-NEXT: SymbolTable:
55 # CHECK-NEXT: - Index: 0
56 # CHECK-NEXT: Kind: FUNCTION
57 # CHECK-NEXT: Name: bar
58 # CHECK-NEXT: Flags: [ BINDING_WEAK, UNDEFINED ]
59 # CHECK-NEXT: Function: 0
5460 # CHECK-NEXT: SegmentInfo:
5561 # CHECK-NEXT: - Index: 0
5662 # CHECK-NEXT: Name: mydata
6268 # CHECK-NEXT: Flags: [ ]
6369 # CHECK-NEXT: InitFunctions:
6470 # CHECK-NEXT: - Priority: 1
65 # CHECK-NEXT: FunctionIndex: 0
71 # CHECK-NEXT: Symbol: 0
6672 # CHECK-NEXT: ...
3636 - Type: CUSTOM
3737 Name: linking
3838 DataSize: 10
39 SymbolInfo:
40 - Name: function_export
39 SymbolTable:
40 - Index: 0
41 Kind: FUNCTION
42 Name: function_export
4143 Flags: [ BINDING_WEAK ]
42 - Name: global_export
44 Function: 0
45 - Index: 1
46 Kind: GLOBAL
47 Name: global_export
4348 Flags: [ BINDING_WEAK ]
49 Global: 0
4450 ...
4551 # CHECK: --- !WASM
4652 # CHECK: FileHeader:
5763 # CHECK: - Type: CUSTOM
5864 # CHECK: Name: linking
5965 # CHECK: DataSize: 10
60 # CHECK: SymbolInfo:
61 # CHECK: - Name: function_export
62 # CHECK: Flags: [ BINDING_WEAK ]
63 # CHECK: - Name: global_export
64 # CHECK: Flags: [ BINDING_WEAK ]
66 # CHECK: SymbolTable:
67 # CHECK: - Index: 0
68 # CHECK: Kind: FUNCTION
69 # CHECK: Name: function_export
70 # CHECK: Flags: [ BINDING_WEAK ]
71 # CHECK: Function: 0
72 # CHECK: - Index: 1
73 # CHECK: Kind: GLOBAL
74 # CHECK: Name: global_export
75 # CHECK: Flags: [ BINDING_WEAK ]
76 # CHECK: Global: 0
0 # RUN: yaml2obj < %s | llvm-nm - | FileCheck -strict-whitespace %s
11
2 # That wasm exports of functions and globals are displayed as global data and
3 # code symbols.
2 # Check that wasm exports of functions/globals/data are displayed correctly
43
54 --- !WASM
65 FileHeader:
1211 ReturnType: I32
1312 ParamTypes:
1413 - I32
15 - Type: IMPORT
16 Imports:
17 - Module: env
18 Field: fimport
19 Kind: FUNCTION
20 SigIndex: 0
21 - Module: env
22 Field: gimport
23 Kind: GLOBAL
24 GlobalType: I32
25 GlobalMutable: false
2614 - Type: FUNCTION
27 FunctionTypes: [ 0, 0, 0, 0, 0 ]
15 FunctionTypes: [ 0 ]
2816 - Type: GLOBAL
2917 Globals:
30 - Index: 1
18 - Index: 0
3119 Type: I32
3220 Mutable: false
3321 InitExpr:
3422 Opcode: I64_CONST
3523 Value: 32
36 - Index: 2
37 Type: I32
38 Mutable: false
39 InitExpr:
40 Opcode: I32_CONST
41 Value: 64
42 - Index: 3
43 Type: I32
44 Mutable: false
45 InitExpr:
46 Opcode: I32_CONST
47 Value: 1024
48 - Type: EXPORT
49 Exports:
50 - Name: foo
51 Kind: FUNCTION
52 Index: 0x00000004
53 - Name: bar
54 Kind: GLOBAL
55 Index: 0x00000003
5624 - Type: CODE
5725 Functions:
58 - Index: 1
26 - Index: 0
5927 Locals:
6028 Body: 00
61 - Index: 2
62 Locals:
63 Body: 00
64 - Index: 3
65 Locals:
66 Body: 00
67 - Index: 4
68 Locals:
69 Body: 00
70 - Index: 5
71 Locals:
72 Body: 00
29 - Type: DATA
30 Segments:
31 - SectionOffset: 6
32 MemoryIndex: 0
33 Offset:
34 Opcode: I32_CONST
35 Value: 0
36 Content: '616263'
7337 - Type: CUSTOM
74 Name: "linking"
75 DataSize: 0
38 Name: linking
39 DataSize: 3
40 SymbolTable:
41 - Index: 0
42 Kind: FUNCTION
43 Name: fexport
44 Flags: [ ]
45 Function: 0
46 - Index: 1
47 Kind: GLOBAL
48 Name: gexport
49 Flags: [ ]
50 Global: 0
51 - Index: 2
52 Kind: DATA
53 Name: dexport
54 Flags: [ ]
55 Segment: 0
56 Size: 3
57 SegmentInfo:
58 - Index: 0
59 Name: .rodata.constantData
60 Alignment: 1
61 Flags: [ ]
7662
77 # CHECK: 00000400 D bar
78 # CHECK-NEXT: U fimport
79 # CHECK-NEXT: 00000004 T foo
80 # CHECK-NEXT: U gimport
63 # CHECK: 00000000 D dexport
64 # CHECK-NEXT: 00000000 T fexport
65 # CHECK-NEXT: 00000000 D gexport
0 # RUN: yaml2obj < %s | llvm-nm - | FileCheck -strict-whitespace %s
1
2 # Check that wasm import of functions/globals/data are displayed correctly
13
24 --- !WASM
35 FileHeader:
1214 - Type: IMPORT
1315 Imports:
1416 - Module: env
15 Field: foo
17 Field: fimport
1618 Kind: FUNCTION
1719 SigIndex: 0
1820 - Module: env
19 Field: bar
21 Field: gimport
2022 Kind: GLOBAL
2123 GlobalType: I32
2224 GlobalMutable: false
2325 - Type: CUSTOM
24 Name: "linking"
25 DataSize: 0
26 Name: linking
27 DataSize: 3
28 SymbolTable:
29 - Index: 0
30 Kind: FUNCTION
31 Name: fimport
32 Flags: [ UNDEFINED ]
33 Function: 0
34 - Index: 1
35 Kind: GLOBAL
36 Name: gimport
37 Flags: [ UNDEFINED ]
38 Global: 0
39 - Index: 2
40 Kind: DATA
41 Name: dimport
42 Flags: [ UNDEFINED ]
2643
27 # CHECK: U bar
28 # CHECK: U foo
44 # CHECK: U dimport
45 # CHECK-NEXT: U fimport
46 # CHECK-NEXT: U gimport
0 # RUN: yaml2obj < %s | llvm-nm - | FileCheck -strict-whitespace %s
11
2 # That wasm exports of functions and globals are displayed as global data and
3 # code symbols.
2 # Check that wasm weak function/global/data symbols are displayed correctly
43
54 --- !WASM
65 FileHeader:
1918 Kind: FUNCTION
2019 SigIndex: 0
2120 - Module: env
22 Field: weak_import_data
21 Field: weak_import_global
2322 Kind: GLOBAL
2423 GlobalType: I32
2524 GlobalMutable: false
2625 - Type: FUNCTION
27 FunctionTypes: [ 0, 0, 0, 0 ]
26 FunctionTypes: [ 0 ]
2827 - Type: GLOBAL
2928 Globals:
3029 - Index: 1
3332 InitExpr:
3433 Opcode: I64_CONST
3534 Value: 32
36 - Index: 2
37 Type: I32
38 Mutable: false
39 InitExpr:
40 Opcode: I32_CONST
41 Value: 64
42 - Index: 3
43 Type: I32
44 Mutable: false
45 InitExpr:
46 Opcode: I32_CONST
47 Value: 1024
48 - Type: EXPORT
49 Exports:
50 - Name: weak_global_func
51 Kind: FUNCTION
52 Index: 0x00000004
53 - Name: weak_global_data
54 Kind: GLOBAL
55 Index: 0x00000003
5635 - Type: CODE
5736 Functions:
5837 - Index: 1
5938 Locals:
6039 Body: 00
61 - Index: 2
62 Locals:
63 Body: 00
64 - Index: 3
65 Locals:
66 Body: 00
67 - Index: 4
68 Locals:
69 Body: 00
40 - Type: DATA
41 Segments:
42 - SectionOffset: 6
43 MemoryIndex: 0
44 Offset:
45 Opcode: I32_CONST
46 Value: 0
47 Content: '616263'
7048 - Type: CUSTOM
7149 Name: linking
72 DataSize: 0
73 SymbolInfo:
74 - Name: weak_global_func
75 Flags: [ BINDING_WEAK ]
76 - Name: weak_global_data
77 Flags: [ BINDING_WEAK ]
78 - Name: weak_import_func
79 Flags: [ BINDING_WEAK ]
80 - Name: weak_import_data
81 Flags: [ BINDING_WEAK ]
50 DataSize: 3
51 SymbolTable:
52 - Index: 0
53 Kind: DATA
54 Name: weak_defined_data
55 Flags: [ BINDING_WEAK ]
56 Segment: 0
57 Size: 3
58 - Index: 1
59 Kind: FUNCTION
60 Name: weak_defined_func
61 Flags: [ BINDING_WEAK ]
62 Function: 1
63 - Index: 2
64 Kind: GLOBAL
65 Name: weak_defined_global
66 Flags: [ BINDING_WEAK ]
67 Global: 1
68 - Index: 3
69 Kind: DATA
70 Name: weak_import_data
71 Flags: [ BINDING_WEAK, UNDEFINED ]
72 - Index: 4
73 Kind: FUNCTION
74 Name: weak_import_func
75 Flags: [ BINDING_WEAK, UNDEFINED ]
76 Function: 0
77 - Index: 5
78 Kind: GLOBAL
79 Name: weak_import_global
80 Flags: [ BINDING_WEAK, UNDEFINED ]
81 Global: 0
82 SegmentInfo:
83 - Index: 0
84 Name: .rodata.constantData
85 Alignment: 1
86 Flags: [ ]
8287
83 # CHECK: 00000400 W weak_global_data
84 # CHECK: 00000004 W weak_global_func
85 # CHECK: w weak_import_data
86 # CHECK: w weak_import_func
88
89 # CHECK: 00000000 W weak_defined_data
90 # CHECK-NEXT: 00000001 W weak_defined_func
91 # CHECK-NEXT: 00000001 W weak_defined_global
92 # CHECK-NEXT: w weak_import_data
93 # CHECK-NEXT: w weak_import_func
94 # CHECK-NEXT: w weak_import_global
33 CHECK-NEXT: 00000000 g F *UND* puts
44 CHECK-NEXT: 00000000 g F *UND* SomeOtherFunction
55 CHECK-NEXT: 00000002 g F CODE main
6 CHECK-NEXT: 00000000 l DATA .L.str
67 CHECK-NEXT: 00000010 g DATA var
7
11
22 # CHECK: Sections:
33 # CHECK-NEXT: Idx Name Size Address Type
4 # CHECK-NEXT: 0 TYPE 0000000e 0000000000000000
5 # CHECK-NEXT: 1 IMPORT 00000024 0000000000000000
6 # CHECK-NEXT: 2 FUNCTION 00000002 0000000000000000
7 # CHECK-NEXT: 3 TABLE 00000004 0000000000000000
8 # CHECK-NEXT: 4 MEMORY 00000003 0000000000000000
9 # CHECK-NEXT: 5 GLOBAL 0000000b 0000000000000000
10 # CHECK-NEXT: 6 EXPORT 0000000e 0000000000000000
11 # CHECK-NEXT: 7 CODE 00000019 0000000000000000 TEXT
12 # CHECK-NEXT: 8 DATA 0000001a 0000000000000000 DATA
13 # CHECK-NEXT: 9 name 0000002b 0000000000000000
14 # CHECK-NEXT: 10 reloc.CODE 00000017 0000000000000000
15 # CHECK-NEXT: 11 linking 00000016 0000000000000000
4 # CHECK-NEXT: 0 TYPE 0000000e 0000000000000000
5 # CHECK-NEXT: 1 IMPORT 0000005d 0000000000000000
6 # CHECK-NEXT: 2 FUNCTION 00000002 0000000000000000
7 # CHECK-NEXT: 3 CODE 00000019 0000000000000000 TEXT
8 # CHECK-NEXT: 4 DATA 0000001c 0000000000000000 DATA
9 # CHECK-NEXT: 5 reloc.CODE 00000017 0000000000000000
10 # CHECK-NEXT: 6 linking 0000005c 0000000000000000
1611
1712 # RUN: llvm-objdump -p %p/Inputs/trivial.obj.wasm | FileCheck %s -check-prefix CHECK-HEADER
1813
286286 MACHO-ARM-NEXT: ]
287287
288288 WASM: Relocations [
289 WASM-NEXT: Section (8) CODE {
289 WASM-NEXT: Section (4) CODE {
290290 WASM-NEXT: Relocation {
291291 WASM-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB (4)
292292 WASM-NEXT: Offset: 0x4
293 WASM-NEXT: Index: 0x0
293 WASM-NEXT: Index: 0x3
294294 WASM-NEXT: Addend: 0
295295 WASM-NEXT: }
296296 WASM-NEXT: Relocation {
500500 WASM-NEXT: }
501501 WASM-NEXT: Section {
502502 WASM-NEXT: Type: IMPORT (0x2)
503 WASM-NEXT: Size: 36
503 WASM-NEXT: Size: 93
504504 WASM-NEXT: Offset: 28
505505 WASM-NEXT: }
506506 WASM-NEXT: Section {
507507 WASM-NEXT: Type: FUNCTION (0x3)
508508 WASM-NEXT: Size: 2
509 WASM-NEXT: Offset: 70
510 WASM-NEXT: }
511 WASM-NEXT: Section {
512 WASM-NEXT: Type: TABLE (0x4)
513 WASM-NEXT: Size: 4
514 WASM-NEXT: Offset: 78
515 WASM-NEXT: }
516 WASM-NEXT: Section {
517 WASM-NEXT: Type: MEMORY (0x5)
518 WASM-NEXT: Size: 3
519 WASM-NEXT: Offset: 88
520 WASM-NEXT: Memories [
521 WASM-NEXT: Memory {
522 WASM-NEXT: InitialPages: 1
523 WASM-NEXT: }
524 WASM-NEXT: ]
525 WASM-NEXT: }
526 WASM-NEXT: Section {
527 WASM-NEXT: Type: GLOBAL (0x6)
528 WASM-NEXT: Size: 6
529 WASM-NEXT: Offset: 97
530 WASM-NEXT: }
531 WASM-NEXT: Section {
532 WASM-NEXT: Type: EXPORT (0x7)
533 WASM-NEXT: Size: 8
534 WASM-NEXT: Offset: 109
509 WASM-NEXT: Offset: 127
535510 WASM-NEXT: }
536511 WASM-NEXT: Section {
537512 WASM-NEXT: Type: CODE (0xA)
538513 WASM-NEXT: Size: 25
539 WASM-NEXT: Offset: 123
514 WASM-NEXT: Offset: 135
540515 WASM-NEXT: }
541516 WASM-NEXT: Section {
542517 WASM-NEXT: Type: DATA (0xB)
543518 WASM-NEXT: Size: 19
544 WASM-NEXT: Offset: 154
519 WASM-NEXT: Offset: 166
545520 WASM-NEXT: Segments [
546521 WASM-NEXT: Segment {
522 WASM-NEXT: Name: .rodata..L.str
547523 WASM-NEXT: Size: 13
548524 WASM-NEXT: Offset: 0
549525 WASM-NEXT: }
551527 WASM-NEXT: }
552528 WASM-NEXT: Section {
553529 WASM-NEXT: Type: CUSTOM (0x0)
554 WASM-NEXT: Size: 43
555 WASM-NEXT: Offset: 179
556 WASM-NEXT: Name: name
530 WASM-NEXT: Size: 23
531 WASM-NEXT: Offset: 191
532 WASM-NEXT: Name: reloc.CODE
557533 WASM-NEXT: }
558534 WASM-NEXT: Section {
559535 WASM-NEXT: Type: CUSTOM (0x0)
560 WASM-NEXT: Size: 23
561 WASM-NEXT: Offset: 228
562 WASM-NEXT: Name: reloc.CODE
563 WASM-NEXT: }
564 WASM-NEXT: Section {
565 WASM-NEXT: Type: CUSTOM (0x0)
566 WASM-NEXT: Size: 22
567 WASM-NEXT: Offset: 257
536 WASM-NEXT: Size: 72
537 WASM-NEXT: Offset: 220
568538 WASM-NEXT: Name: linking
569539 WASM-NEXT: DataSize: 13
570540 WASM-NEXT: }
7373 WASM: Symbols [
7474 WASM-NEXT: Symbol {
7575 WASM-NEXT: Name: puts
76 WASM-NEXT: Type: FUNCTION_IMPORT (0x0)
76 WASM-NEXT: Type: FUNCTION (0x0)
77 WASM-NEXT: Flags: 0x10
78 WASM-NEXT: }
79 WASM-NEXT: Symbol {
80 WASM-NEXT: Name: SomeOtherFunction
81 WASM-NEXT: Type: FUNCTION (0x0)
82 WASM-NEXT: Flags: 0x10
83 WASM-NEXT: }
84 WASM-NEXT: Symbol {
85 WASM-NEXT: Name: main
86 WASM-NEXT: Type: FUNCTION (0x0)
7787 WASM-NEXT: Flags: 0x0
7888 WASM-NEXT: }
7989 WASM-NEXT: Symbol {
80 WASM-NEXT: Name: SomeOtherFunction
81 WASM-NEXT: Type: FUNCTION_IMPORT (0x0)
82 WASM-NEXT: Flags: 0x0
83 WASM-NEXT: }
84 WASM-NEXT: Symbol {
85 WASM-NEXT: Name: main
86 WASM-NEXT: Type: FUNCTION_EXPORT (0x1)
87 WASM-NEXT: Flags: 0x0
90 WASM-NEXT: Name: .L.str
91 WASM-NEXT: Type: DATA (0x1)
92 WASM-NEXT: Flags: 0x2
8893 WASM-NEXT: }
8994 WASM-NEXT: ]
2222 namespace {
2323
2424 static const EnumEntry WasmSymbolTypes[] = {
25 #define ENUM_ENTRY(X) { #X, static_cast(WasmSymbol::SymbolType::X) }
26 ENUM_ENTRY(FUNCTION_IMPORT),
27 ENUM_ENTRY(FUNCTION_EXPORT),
28 ENUM_ENTRY(GLOBAL_IMPORT),
29 ENUM_ENTRY(GLOBAL_EXPORT),
25 #define ENUM_ENTRY(X) { #X, wasm::WASM_SYMBOL_TYPE_##X }
26 ENUM_ENTRY(FUNCTION),
27 ENUM_ENTRY(DATA),
28 ENUM_ENTRY(GLOBAL),
3029 #undef ENUM_ENTRY
3130 };
3231
157156 if (!LinkingData.InitFunctions.empty()) {
158157 ListScope Group(W, "InitFunctions");
159158 for (const wasm::WasmInitFunc &F: LinkingData.InitFunctions)
160 W.startLine() << F.FunctionIndex << " (priority=" << F.Priority
161 << ")\n";
159 W.startLine() << F.Symbol << " (priority=" << F.Priority << ")\n";
162160 }
163161 }
164162 break;
202200 void WasmDumper::printSymbol(const SymbolRef &Sym) {
203201 DictScope D(W, "Symbol");
204202 WasmSymbol Symbol = Obj->getWasmSymbol(Sym.getRawDataRefImpl());
205 W.printString("Name", Symbol.Name);
206 W.printEnum("Type", static_cast(Symbol.Type), makeArrayRef(WasmSymbolTypes));
207 W.printHex("Flags", Symbol.Flags);
203 W.printString("Name", Symbol.Info.Name);
204 W.printEnum("Type", Symbol.Info.Kind, makeArrayRef(WasmSymbolTypes));
205 W.printHex("Flags", Symbol.Info.Flags);
208206 }
209207
210208 }
9090 }
9191 SegmentIndex++;
9292 }
93 for (const object::SymbolRef& Sym: Obj.symbols()) {
94 const object::WasmSymbol Symbol = Obj.getWasmSymbol(Sym);
95 if (Symbol.Flags != 0) {
96 WasmYAML::SymbolInfo Info{Symbol.Name, Symbol.Flags};
97 LinkingSec->SymbolInfos.emplace_back(Info);
98 }
93 uint32_t SymbolIndex = 0;
94 for (const wasm::WasmSymbolInfo &Symbol : Obj.linkingData().SymbolTable) {
95 WasmYAML::SymbolInfo Info;
96 Info.Index = SymbolIndex++;
97 Info.Kind = static_cast(Symbol.Kind);
98 Info.Name = Symbol.Name;
99 Info.Flags = Symbol.Flags;
100 switch (Symbol.Kind) {
101 case wasm::WASM_SYMBOL_TYPE_DATA:
102 Info.DataRef = Symbol.DataRef;
103 break;
104 case wasm::WASM_SYMBOL_TYPE_FUNCTION:
105 case wasm::WASM_SYMBOL_TYPE_GLOBAL:
106 Info.ElementIndex = Symbol.ElementIndex;
107 break;
108 }
109 LinkingSec->SymbolTable.emplace_back(Info);
99110 }
100111 LinkingSec->DataSize = Obj.linkingData().DataSize;
101112 for (const wasm::WasmInitFunc &Func : Obj.linkingData().InitFunctions) {
102 WasmYAML::InitFunction F{Func.Priority, Func.FunctionIndex};
113 WasmYAML::InitFunction F{Func.Priority, Func.Symbol};
103114 LinkingSec->InitFunctions.emplace_back(F);
104115 }
105116 CustomSec = std::move(LinkingSec);
1111 ///
1212 //===----------------------------------------------------------------------===//
1313 //
14
1415 #include "llvm/ObjectYAML/ObjectYAML.h"
1516 #include "llvm/Support/Endian.h"
1617 #include "llvm/Support/LEB128.h"
139140 encodeULEB128(Section.DataSize, SubSection.GetStream());
140141 SubSection.Done();
141142
142 // SYMBOL_INFO subsection
143 if (Section.SymbolInfos.size()) {
144 encodeULEB128(wasm::WASM_SYMBOL_INFO, OS);
145
146 encodeULEB128(Section.SymbolInfos.size(), SubSection.GetStream());
147 for (const WasmYAML::SymbolInfo &Info : Section.SymbolInfos) {
148 writeStringRef(Info.Name, SubSection.GetStream());
143 // SYMBOL_TABLE subsection
144 if (Section.SymbolTable.size()) {
145 encodeULEB128(wasm::WASM_SYMBOL_TABLE, OS);
146
147 encodeULEB128(Section.SymbolTable.size(), SubSection.GetStream());
148 #ifndef _NDEBUG
149 uint32_t SymbolIndex = 0;
150 #endif
151 for (const WasmYAML::SymbolInfo &Info : Section.SymbolTable) {
152 assert(Info.Index == SymbolIndex++);
153 encodeULEB128(Info.Kind, SubSection.GetStream());
149154 encodeULEB128(Info.Flags, SubSection.GetStream());
155 switch (Info.Kind) {
156 case wasm::WASM_SYMBOL_TYPE_FUNCTION:
157 case wasm::WASM_SYMBOL_TYPE_GLOBAL:
158 encodeULEB128(Info.ElementIndex, SubSection.GetStream());
159 if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
160 writeStringRef(Info.Name, SubSection.GetStream());
161 break;
162 case wasm::WASM_SYMBOL_TYPE_DATA:
163 writeStringRef(Info.Name, SubSection.GetStream());
164 if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
165 encodeULEB128(Info.DataRef.Segment, SubSection.GetStream());
166 encodeULEB128(Info.DataRef.Offset, SubSection.GetStream());
167 encodeULEB128(Info.DataRef.Size, SubSection.GetStream());
168 }
169 break;
170 default:
171 llvm_unreachable("unexpected kind");
172 }
150173 }
151174
152175 SubSection.Done();
170193 encodeULEB128(Section.InitFunctions.size(), SubSection.GetStream());
171194 for (const WasmYAML::InitFunction &Func : Section.InitFunctions) {
172195 encodeULEB128(Func.Priority, SubSection.GetStream());
173 encodeULEB128(Func.FunctionIndex, SubSection.GetStream());
196 encodeULEB128(Func.Symbol, SubSection.GetStream());
174197 }
175198 SubSection.Done();
176199 }