1 //===- WasmObjectFile.cpp - Wasm object file implementation ---------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ADT/ArrayRef.h" 11 #include "llvm/ADT/DenseSet.h" 12 #include "llvm/ADT/STLExtras.h" 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/ADT/StringSet.h" 15 #include "llvm/ADT/Triple.h" 16 #include "llvm/BinaryFormat/Wasm.h" 17 #include "llvm/MC/SubtargetFeature.h" 18 #include "llvm/Object/Binary.h" 19 #include "llvm/Object/Error.h" 20 #include "llvm/Object/ObjectFile.h" 21 #include "llvm/Object/SymbolicFile.h" 22 #include "llvm/Object/Wasm.h" 23 #include "llvm/Support/Endian.h" 24 #include "llvm/Support/Error.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Support/LEB128.h" 27 #include <algorithm> 28 #include <cassert> 29 #include <cstdint> 30 #include <cstring> 31 #include <system_error> 32 33 #define DEBUG_TYPE "wasm-object" 34 35 using namespace llvm; 36 using namespace object; 37 38 void WasmSymbol::print(raw_ostream &Out) const { 39 Out << "Name=" << Info.Name 40 << ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind)) 41 << ", Flags=" << Info.Flags; 42 if (!isTypeData()) { 43 Out << ", ElemIndex=" << Info.ElementIndex; 44 } else if (isDefined()) { 45 Out << ", Segment=" << Info.DataRef.Segment; 46 Out << ", Offset=" << Info.DataRef.Offset; 47 Out << ", Size=" << Info.DataRef.Size; 48 } 49 } 50 51 Expected<std::unique_ptr<WasmObjectFile>> 52 ObjectFile::createWasmObjectFile(MemoryBufferRef Buffer) { 53 Error Err = Error::success(); 54 auto ObjectFile = llvm::make_unique<WasmObjectFile>(Buffer, Err); 55 if (Err) 56 return std::move(Err); 57 58 return std::move(ObjectFile); 59 } 60 61 #define VARINT7_MAX ((1<<7)-1) 62 #define VARINT7_MIN (-(1<<7)) 63 #define VARUINT7_MAX (1<<7) 64 #define VARUINT1_MAX (1) 65 66 static uint8_t readUint8(const uint8_t *&Ptr) { return *Ptr++; } 67 68 static uint32_t readUint32(const uint8_t *&Ptr) { 69 uint32_t Result = support::endian::read32le(Ptr); 70 Ptr += sizeof(Result); 71 return Result; 72 } 73 74 static int32_t readFloat32(const uint8_t *&Ptr) { 75 int32_t Result = 0; 76 memcpy(&Result, Ptr, sizeof(Result)); 77 Ptr += sizeof(Result); 78 return Result; 79 } 80 81 static int64_t readFloat64(const uint8_t *&Ptr) { 82 int64_t Result = 0; 83 memcpy(&Result, Ptr, sizeof(Result)); 84 Ptr += sizeof(Result); 85 return Result; 86 } 87 88 static uint64_t readULEB128(const uint8_t *&Ptr) { 89 unsigned Count; 90 uint64_t Result = decodeULEB128(Ptr, &Count); 91 Ptr += Count; 92 return Result; 93 } 94 95 static StringRef readString(const uint8_t *&Ptr) { 96 uint32_t StringLen = readULEB128(Ptr); 97 StringRef Return = StringRef(reinterpret_cast<const char *>(Ptr), StringLen); 98 Ptr += StringLen; 99 return Return; 100 } 101 102 static int64_t readLEB128(const uint8_t *&Ptr) { 103 unsigned Count; 104 uint64_t Result = decodeSLEB128(Ptr, &Count); 105 Ptr += Count; 106 return Result; 107 } 108 109 static uint8_t readVaruint1(const uint8_t *&Ptr) { 110 int64_t result = readLEB128(Ptr); 111 assert(result <= VARUINT1_MAX && result >= 0); 112 return result; 113 } 114 115 static int32_t readVarint32(const uint8_t *&Ptr) { 116 int64_t result = readLEB128(Ptr); 117 assert(result <= INT32_MAX && result >= INT32_MIN); 118 return result; 119 } 120 121 static uint32_t readVaruint32(const uint8_t *&Ptr) { 122 uint64_t result = readULEB128(Ptr); 123 assert(result <= UINT32_MAX); 124 return result; 125 } 126 127 static int64_t readVarint64(const uint8_t *&Ptr) { 128 return readLEB128(Ptr); 129 } 130 131 static uint8_t readOpcode(const uint8_t *&Ptr) { 132 return readUint8(Ptr); 133 } 134 135 static Error readInitExpr(wasm::WasmInitExpr &Expr, const uint8_t *&Ptr) { 136 Expr.Opcode = readOpcode(Ptr); 137 138 switch (Expr.Opcode) { 139 case wasm::WASM_OPCODE_I32_CONST: 140 Expr.Value.Int32 = readVarint32(Ptr); 141 break; 142 case wasm::WASM_OPCODE_I64_CONST: 143 Expr.Value.Int64 = readVarint64(Ptr); 144 break; 145 case wasm::WASM_OPCODE_F32_CONST: 146 Expr.Value.Float32 = readFloat32(Ptr); 147 break; 148 case wasm::WASM_OPCODE_F64_CONST: 149 Expr.Value.Float64 = readFloat64(Ptr); 150 break; 151 case wasm::WASM_OPCODE_GET_GLOBAL: 152 Expr.Value.Global = readULEB128(Ptr); 153 break; 154 default: 155 return make_error<GenericBinaryError>("Invalid opcode in init_expr", 156 object_error::parse_failed); 157 } 158 159 uint8_t EndOpcode = readOpcode(Ptr); 160 if (EndOpcode != wasm::WASM_OPCODE_END) { 161 return make_error<GenericBinaryError>("Invalid init_expr", 162 object_error::parse_failed); 163 } 164 return Error::success(); 165 } 166 167 static wasm::WasmLimits readLimits(const uint8_t *&Ptr) { 168 wasm::WasmLimits Result; 169 Result.Flags = readVaruint1(Ptr); 170 Result.Initial = readVaruint32(Ptr); 171 if (Result.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX) 172 Result.Maximum = readVaruint32(Ptr); 173 return Result; 174 } 175 176 static wasm::WasmTable readTable(const uint8_t *&Ptr) { 177 wasm::WasmTable Table; 178 Table.ElemType = readUint8(Ptr); 179 Table.Limits = readLimits(Ptr); 180 return Table; 181 } 182 183 static Error readSection(WasmSection &Section, const uint8_t *&Ptr, 184 const uint8_t *Start, const uint8_t *Eof) { 185 Section.Offset = Ptr - Start; 186 Section.Type = readUint8(Ptr); 187 uint32_t Size = readVaruint32(Ptr); 188 if (Size == 0) 189 return make_error<StringError>("Zero length section", 190 object_error::parse_failed); 191 if (Ptr + Size > Eof) 192 return make_error<StringError>("Section too large", 193 object_error::parse_failed); 194 if (Section.Type == wasm::WASM_SEC_CUSTOM) { 195 const uint8_t *NameStart = Ptr; 196 Section.Name = readString(Ptr); 197 Size -= Ptr - NameStart; 198 } 199 Section.Content = ArrayRef<uint8_t>(Ptr, Size); 200 Ptr += Size; 201 return Error::success(); 202 } 203 204 WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err) 205 : ObjectFile(Binary::ID_Wasm, Buffer) { 206 ErrorAsOutParameter ErrAsOutParam(&Err); 207 Header.Magic = getData().substr(0, 4); 208 if (Header.Magic != StringRef("\0asm", 4)) { 209 Err = make_error<StringError>("Bad magic number", 210 object_error::parse_failed); 211 return; 212 } 213 214 const uint8_t *Eof = getPtr(getData().size()); 215 const uint8_t *Ptr = getPtr(4); 216 217 if (Ptr + 4 > Eof) { 218 Err = make_error<StringError>("Missing version number", 219 object_error::parse_failed); 220 return; 221 } 222 223 Header.Version = readUint32(Ptr); 224 if (Header.Version != wasm::WasmVersion) { 225 Err = make_error<StringError>("Bad version number", 226 object_error::parse_failed); 227 return; 228 } 229 230 WasmSection Sec; 231 while (Ptr < Eof) { 232 if ((Err = readSection(Sec, Ptr, getPtr(0), Eof))) 233 return; 234 if ((Err = parseSection(Sec))) 235 return; 236 237 Sections.push_back(Sec); 238 } 239 } 240 241 Error WasmObjectFile::parseSection(WasmSection &Sec) { 242 const uint8_t* Start = Sec.Content.data(); 243 const uint8_t* End = Start + Sec.Content.size(); 244 switch (Sec.Type) { 245 case wasm::WASM_SEC_CUSTOM: 246 return parseCustomSection(Sec, Start, End); 247 case wasm::WASM_SEC_TYPE: 248 return parseTypeSection(Start, End); 249 case wasm::WASM_SEC_IMPORT: 250 return parseImportSection(Start, End); 251 case wasm::WASM_SEC_FUNCTION: 252 return parseFunctionSection(Start, End); 253 case wasm::WASM_SEC_TABLE: 254 return parseTableSection(Start, End); 255 case wasm::WASM_SEC_MEMORY: 256 return parseMemorySection(Start, End); 257 case wasm::WASM_SEC_GLOBAL: 258 return parseGlobalSection(Start, End); 259 case wasm::WASM_SEC_EXPORT: 260 return parseExportSection(Start, End); 261 case wasm::WASM_SEC_START: 262 return parseStartSection(Start, End); 263 case wasm::WASM_SEC_ELEM: 264 return parseElemSection(Start, End); 265 case wasm::WASM_SEC_CODE: 266 return parseCodeSection(Start, End); 267 case wasm::WASM_SEC_DATA: 268 return parseDataSection(Start, End); 269 default: 270 return make_error<GenericBinaryError>("Bad section type", 271 object_error::parse_failed); 272 } 273 } 274 275 Error WasmObjectFile::parseNameSection(const uint8_t *Ptr, const uint8_t *End) { 276 llvm::DenseSet<uint64_t> Seen; 277 if (Functions.size() != FunctionTypes.size()) { 278 return make_error<GenericBinaryError>("Names must come after code section", 279 object_error::parse_failed); 280 } 281 282 while (Ptr < End) { 283 uint8_t Type = readUint8(Ptr); 284 uint32_t Size = readVaruint32(Ptr); 285 const uint8_t *SubSectionEnd = Ptr + Size; 286 switch (Type) { 287 case wasm::WASM_NAMES_FUNCTION: { 288 uint32_t Count = readVaruint32(Ptr); 289 while (Count--) { 290 uint32_t Index = readVaruint32(Ptr); 291 if (!Seen.insert(Index).second) 292 return make_error<GenericBinaryError>("Function named more than once", 293 object_error::parse_failed); 294 StringRef Name = readString(Ptr); 295 if (!isValidFunctionIndex(Index) || Name.empty()) 296 return make_error<GenericBinaryError>("Invalid name entry", 297 object_error::parse_failed); 298 DebugNames.push_back(wasm::WasmFunctionName{Index, Name}); 299 if (isDefinedFunctionIndex(Index)) 300 getDefinedFunction(Index).DebugName = Name; 301 } 302 break; 303 } 304 // Ignore local names for now 305 case wasm::WASM_NAMES_LOCAL: 306 default: 307 Ptr += Size; 308 break; 309 } 310 if (Ptr != SubSectionEnd) 311 return make_error<GenericBinaryError>("Name sub-section ended prematurely", 312 object_error::parse_failed); 313 } 314 315 if (Ptr != End) 316 return make_error<GenericBinaryError>("Name section ended prematurely", 317 object_error::parse_failed); 318 return Error::success(); 319 } 320 321 Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr, 322 const uint8_t *End) { 323 HasLinkingSection = true; 324 if (Functions.size() != FunctionTypes.size()) { 325 return make_error<GenericBinaryError>( 326 "Linking data must come after code section", object_error::parse_failed); 327 } 328 329 LinkingData.Version = readVaruint32(Ptr); 330 if (LinkingData.Version != wasm::WasmMetadataVersion) { 331 return make_error<GenericBinaryError>( 332 "Unexpected metadata version: " + Twine(LinkingData.Version) + 333 " (Expected: " + Twine(wasm::WasmMetadataVersion) + ")", 334 object_error::parse_failed); 335 } 336 337 while (Ptr < End) { 338 uint8_t Type = readUint8(Ptr); 339 uint32_t Size = readVaruint32(Ptr); 340 const uint8_t *SubSectionEnd = Ptr + Size; 341 switch (Type) { 342 case wasm::WASM_SYMBOL_TABLE: 343 if (Error Err = parseLinkingSectionSymtab(Ptr, SubSectionEnd)) 344 return Err; 345 break; 346 case wasm::WASM_SEGMENT_INFO: { 347 uint32_t Count = readVaruint32(Ptr); 348 if (Count > DataSegments.size()) 349 return make_error<GenericBinaryError>("Too many segment names", 350 object_error::parse_failed); 351 for (uint32_t i = 0; i < Count; i++) { 352 DataSegments[i].Data.Name = readString(Ptr); 353 DataSegments[i].Data.Alignment = readVaruint32(Ptr); 354 DataSegments[i].Data.Flags = readVaruint32(Ptr); 355 } 356 break; 357 } 358 case wasm::WASM_INIT_FUNCS: { 359 uint32_t Count = readVaruint32(Ptr); 360 LinkingData.InitFunctions.reserve(Count); 361 for (uint32_t i = 0; i < Count; i++) { 362 wasm::WasmInitFunc Init; 363 Init.Priority = readVaruint32(Ptr); 364 Init.Symbol = readVaruint32(Ptr); 365 if (!isValidFunctionSymbol(Init.Symbol)) 366 return make_error<GenericBinaryError>("Invalid function symbol: " + 367 Twine(Init.Symbol), 368 object_error::parse_failed); 369 LinkingData.InitFunctions.emplace_back(Init); 370 } 371 break; 372 } 373 case wasm::WASM_COMDAT_INFO: 374 if (Error Err = parseLinkingSectionComdat(Ptr, SubSectionEnd)) 375 return Err; 376 break; 377 default: 378 Ptr += Size; 379 break; 380 } 381 if (Ptr != SubSectionEnd) 382 return make_error<GenericBinaryError>( 383 "Linking sub-section ended prematurely", object_error::parse_failed); 384 } 385 if (Ptr != End) 386 return make_error<GenericBinaryError>("Linking section ended prematurely", 387 object_error::parse_failed); 388 return Error::success(); 389 } 390 391 Error WasmObjectFile::parseLinkingSectionSymtab(const uint8_t *&Ptr, 392 const uint8_t *End) { 393 uint32_t Count = readVaruint32(Ptr); 394 LinkingData.SymbolTable.reserve(Count); 395 Symbols.reserve(Count); 396 StringSet<> SymbolNames; 397 398 std::vector<wasm::WasmImport *> ImportedGlobals; 399 std::vector<wasm::WasmImport *> ImportedFunctions; 400 ImportedGlobals.reserve(Imports.size()); 401 ImportedFunctions.reserve(Imports.size()); 402 for (auto &I : Imports) { 403 if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION) 404 ImportedFunctions.emplace_back(&I); 405 else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL) 406 ImportedGlobals.emplace_back(&I); 407 } 408 409 while (Count--) { 410 wasm::WasmSymbolInfo Info; 411 const wasm::WasmSignature *FunctionType = nullptr; 412 const wasm::WasmGlobalType *GlobalType = nullptr; 413 414 Info.Kind = readUint8(Ptr); 415 Info.Flags = readVaruint32(Ptr); 416 bool IsDefined = (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0; 417 418 switch (Info.Kind) { 419 case wasm::WASM_SYMBOL_TYPE_FUNCTION: 420 Info.ElementIndex = readVaruint32(Ptr); 421 if (!isValidFunctionIndex(Info.ElementIndex) || 422 IsDefined != isDefinedFunctionIndex(Info.ElementIndex)) 423 return make_error<GenericBinaryError>("invalid function symbol index", 424 object_error::parse_failed); 425 if (IsDefined) { 426 Info.Name = readString(Ptr); 427 unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions; 428 FunctionType = &Signatures[FunctionTypes[FuncIndex]]; 429 wasm::WasmFunction &Function = Functions[FuncIndex]; 430 if (Function.SymbolName.empty()) 431 Function.SymbolName = Info.Name; 432 } else { 433 wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex]; 434 FunctionType = &Signatures[Import.SigIndex]; 435 Info.Name = Import.Field; 436 Info.Module = Import.Module; 437 } 438 break; 439 440 case wasm::WASM_SYMBOL_TYPE_GLOBAL: 441 Info.ElementIndex = readVaruint32(Ptr); 442 if (!isValidGlobalIndex(Info.ElementIndex) || 443 IsDefined != isDefinedGlobalIndex(Info.ElementIndex)) 444 return make_error<GenericBinaryError>("invalid global symbol index", 445 object_error::parse_failed); 446 if (!IsDefined && 447 (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) == 448 wasm::WASM_SYMBOL_BINDING_WEAK) 449 return make_error<GenericBinaryError>("undefined weak global symbol", 450 object_error::parse_failed); 451 if (IsDefined) { 452 Info.Name = readString(Ptr); 453 unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals; 454 wasm::WasmGlobal &Global = Globals[GlobalIndex]; 455 GlobalType = &Global.Type; 456 if (Global.SymbolName.empty()) 457 Global.SymbolName = Info.Name; 458 } else { 459 wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex]; 460 Info.Name = Import.Field; 461 GlobalType = &Import.Global; 462 } 463 break; 464 465 case wasm::WASM_SYMBOL_TYPE_DATA: 466 Info.Name = readString(Ptr); 467 if (IsDefined) { 468 uint32_t Index = readVaruint32(Ptr); 469 if (Index >= DataSegments.size()) 470 return make_error<GenericBinaryError>("invalid data symbol index", 471 object_error::parse_failed); 472 uint32_t Offset = readVaruint32(Ptr); 473 uint32_t Size = readVaruint32(Ptr); 474 if (Offset + Size > DataSegments[Index].Data.Content.size()) 475 return make_error<GenericBinaryError>("invalid data symbol offset", 476 object_error::parse_failed); 477 Info.DataRef = wasm::WasmDataReference{Index, Offset, Size}; 478 } 479 break; 480 481 case wasm::WASM_SYMBOL_TYPE_SECTION: { 482 if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) != 483 wasm::WASM_SYMBOL_BINDING_LOCAL) 484 return make_error<GenericBinaryError>( 485 "Section symbols must have local binding", 486 object_error::parse_failed); 487 Info.ElementIndex = readVaruint32(Ptr); 488 // Use somewhat unique section name as symbol name. 489 StringRef SectionName = Sections[Info.ElementIndex].Name; 490 Info.Name = SectionName; 491 break; 492 } 493 494 default: 495 return make_error<GenericBinaryError>("Invalid symbol type", 496 object_error::parse_failed); 497 } 498 499 if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) != 500 wasm::WASM_SYMBOL_BINDING_LOCAL && 501 !SymbolNames.insert(Info.Name).second) 502 return make_error<GenericBinaryError>("Duplicate symbol name " + 503 Twine(Info.Name), 504 object_error::parse_failed); 505 LinkingData.SymbolTable.emplace_back(Info); 506 Symbols.emplace_back(LinkingData.SymbolTable.back(), FunctionType, 507 GlobalType); 508 LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n"); 509 } 510 511 return Error::success(); 512 } 513 514 Error WasmObjectFile::parseLinkingSectionComdat(const uint8_t *&Ptr, 515 const uint8_t *End) 516 { 517 uint32_t ComdatCount = readVaruint32(Ptr); 518 StringSet<> ComdatSet; 519 for (unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) { 520 StringRef Name = readString(Ptr); 521 if (Name.empty() || !ComdatSet.insert(Name).second) 522 return make_error<GenericBinaryError>("Bad/duplicate COMDAT name " + Twine(Name), 523 object_error::parse_failed); 524 LinkingData.Comdats.emplace_back(Name); 525 uint32_t Flags = readVaruint32(Ptr); 526 if (Flags != 0) 527 return make_error<GenericBinaryError>("Unsupported COMDAT flags", 528 object_error::parse_failed); 529 530 uint32_t EntryCount = readVaruint32(Ptr); 531 while (EntryCount--) { 532 unsigned Kind = readVaruint32(Ptr); 533 unsigned Index = readVaruint32(Ptr); 534 switch (Kind) { 535 default: 536 return make_error<GenericBinaryError>("Invalid COMDAT entry type", 537 object_error::parse_failed); 538 case wasm::WASM_COMDAT_DATA: 539 if (Index >= DataSegments.size()) 540 return make_error<GenericBinaryError>("COMDAT data index out of range", 541 object_error::parse_failed); 542 if (DataSegments[Index].Data.Comdat != UINT32_MAX) 543 return make_error<GenericBinaryError>("Data segment in two COMDATs", 544 object_error::parse_failed); 545 DataSegments[Index].Data.Comdat = ComdatIndex; 546 break; 547 case wasm::WASM_COMDAT_FUNCTION: 548 if (!isDefinedFunctionIndex(Index)) 549 return make_error<GenericBinaryError>("COMDAT function index out of range", 550 object_error::parse_failed); 551 if (getDefinedFunction(Index).Comdat != UINT32_MAX) 552 return make_error<GenericBinaryError>("Function in two COMDATs", 553 object_error::parse_failed); 554 getDefinedFunction(Index).Comdat = ComdatIndex; 555 break; 556 } 557 } 558 } 559 return Error::success(); 560 } 561 562 Error WasmObjectFile::parseRelocSection(StringRef Name, const uint8_t *Ptr, 563 const uint8_t *End) { 564 uint32_t SectionIndex = readVaruint32(Ptr); 565 if (SectionIndex >= Sections.size()) 566 return make_error<GenericBinaryError>("Invalid section index", 567 object_error::parse_failed); 568 WasmSection& Section = Sections[SectionIndex]; 569 uint32_t RelocCount = readVaruint32(Ptr); 570 uint32_t EndOffset = Section.Content.size(); 571 while (RelocCount--) { 572 wasm::WasmRelocation Reloc = {}; 573 Reloc.Type = readVaruint32(Ptr); 574 Reloc.Offset = readVaruint32(Ptr); 575 Reloc.Index = readVaruint32(Ptr); 576 switch (Reloc.Type) { 577 case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB: 578 case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB: 579 case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: 580 if (!isValidFunctionSymbol(Reloc.Index)) 581 return make_error<GenericBinaryError>("Bad relocation function index", 582 object_error::parse_failed); 583 break; 584 case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB: 585 if (Reloc.Index >= Signatures.size()) 586 return make_error<GenericBinaryError>("Bad relocation type index", 587 object_error::parse_failed); 588 break; 589 case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB: 590 if (!isValidGlobalSymbol(Reloc.Index)) 591 return make_error<GenericBinaryError>("Bad relocation global index", 592 object_error::parse_failed); 593 break; 594 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB: 595 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: 596 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32: 597 if (!isValidDataSymbol(Reloc.Index)) 598 return make_error<GenericBinaryError>("Bad relocation data index", 599 object_error::parse_failed); 600 Reloc.Addend = readVarint32(Ptr); 601 break; 602 case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: 603 if (!isValidFunctionSymbol(Reloc.Index)) 604 return make_error<GenericBinaryError>("Bad relocation function index", 605 object_error::parse_failed); 606 Reloc.Addend = readVarint32(Ptr); 607 break; 608 case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: 609 if (!isValidSectionSymbol(Reloc.Index)) 610 return make_error<GenericBinaryError>("Bad relocation section index", 611 object_error::parse_failed); 612 Reloc.Addend = readVarint32(Ptr); 613 break; 614 default: 615 return make_error<GenericBinaryError>("Bad relocation type: " + 616 Twine(Reloc.Type), 617 object_error::parse_failed); 618 } 619 620 // Relocations must fit inside the section, and must appear in order. They 621 // also shouldn't overlap a function/element boundary, but we don't bother 622 // to check that. 623 uint64_t Size = 5; 624 if (Reloc.Type == wasm::R_WEBASSEMBLY_TABLE_INDEX_I32 || 625 Reloc.Type == wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32 || 626 Reloc.Type == wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32 || 627 Reloc.Type == wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32) 628 Size = 4; 629 if (Reloc.Offset + Size > EndOffset) 630 return make_error<GenericBinaryError>("Bad relocation offset", 631 object_error::parse_failed); 632 633 Section.Relocations.push_back(Reloc); 634 } 635 if (Ptr != End) 636 return make_error<GenericBinaryError>("Reloc section ended prematurely", 637 object_error::parse_failed); 638 return Error::success(); 639 } 640 641 Error WasmObjectFile::parseCustomSection(WasmSection &Sec, 642 const uint8_t *Ptr, const uint8_t *End) { 643 if (Sec.Name == "name") { 644 if (Error Err = parseNameSection(Ptr, End)) 645 return Err; 646 } else if (Sec.Name == "linking") { 647 if (Error Err = parseLinkingSection(Ptr, End)) 648 return Err; 649 } else if (Sec.Name.startswith("reloc.")) { 650 if (Error Err = parseRelocSection(Sec.Name, Ptr, End)) 651 return Err; 652 } 653 return Error::success(); 654 } 655 656 Error WasmObjectFile::parseTypeSection(const uint8_t *Ptr, const uint8_t *End) { 657 uint32_t Count = readVaruint32(Ptr); 658 Signatures.reserve(Count); 659 while (Count--) { 660 wasm::WasmSignature Sig; 661 Sig.ReturnType = wasm::WASM_TYPE_NORESULT; 662 uint8_t Form = readUint8(Ptr); 663 if (Form != wasm::WASM_TYPE_FUNC) { 664 return make_error<GenericBinaryError>("Invalid signature type", 665 object_error::parse_failed); 666 } 667 uint32_t ParamCount = readVaruint32(Ptr); 668 Sig.ParamTypes.reserve(ParamCount); 669 while (ParamCount--) { 670 uint32_t ParamType = readUint8(Ptr); 671 Sig.ParamTypes.push_back(ParamType); 672 } 673 uint32_t ReturnCount = readVaruint32(Ptr); 674 if (ReturnCount) { 675 if (ReturnCount != 1) { 676 return make_error<GenericBinaryError>( 677 "Multiple return types not supported", object_error::parse_failed); 678 } 679 Sig.ReturnType = readUint8(Ptr); 680 } 681 Signatures.push_back(Sig); 682 } 683 if (Ptr != End) 684 return make_error<GenericBinaryError>("Type section ended prematurely", 685 object_error::parse_failed); 686 return Error::success(); 687 } 688 689 Error WasmObjectFile::parseImportSection(const uint8_t *Ptr, const uint8_t *End) { 690 uint32_t Count = readVaruint32(Ptr); 691 Imports.reserve(Count); 692 for (uint32_t i = 0; i < Count; i++) { 693 wasm::WasmImport Im; 694 Im.Module = readString(Ptr); 695 Im.Field = readString(Ptr); 696 Im.Kind = readUint8(Ptr); 697 switch (Im.Kind) { 698 case wasm::WASM_EXTERNAL_FUNCTION: 699 NumImportedFunctions++; 700 Im.SigIndex = readVaruint32(Ptr); 701 break; 702 case wasm::WASM_EXTERNAL_GLOBAL: 703 NumImportedGlobals++; 704 Im.Global.Type = readUint8(Ptr); 705 Im.Global.Mutable = readVaruint1(Ptr); 706 break; 707 case wasm::WASM_EXTERNAL_MEMORY: 708 Im.Memory = readLimits(Ptr); 709 break; 710 case wasm::WASM_EXTERNAL_TABLE: 711 Im.Table = readTable(Ptr); 712 if (Im.Table.ElemType != wasm::WASM_TYPE_ANYFUNC) 713 return make_error<GenericBinaryError>("Invalid table element type", 714 object_error::parse_failed); 715 break; 716 default: 717 return make_error<GenericBinaryError>( 718 "Unexpected import kind", object_error::parse_failed); 719 } 720 Imports.push_back(Im); 721 } 722 if (Ptr != End) 723 return make_error<GenericBinaryError>("Import section ended prematurely", 724 object_error::parse_failed); 725 return Error::success(); 726 } 727 728 Error WasmObjectFile::parseFunctionSection(const uint8_t *Ptr, const uint8_t *End) { 729 uint32_t Count = readVaruint32(Ptr); 730 FunctionTypes.reserve(Count); 731 uint32_t NumTypes = Signatures.size(); 732 while (Count--) { 733 uint32_t Type = readVaruint32(Ptr); 734 if (Type >= NumTypes) 735 return make_error<GenericBinaryError>("Invalid function type", 736 object_error::parse_failed); 737 FunctionTypes.push_back(Type); 738 } 739 if (Ptr != End) 740 return make_error<GenericBinaryError>("Function section ended prematurely", 741 object_error::parse_failed); 742 return Error::success(); 743 } 744 745 Error WasmObjectFile::parseTableSection(const uint8_t *Ptr, const uint8_t *End) { 746 uint32_t Count = readVaruint32(Ptr); 747 Tables.reserve(Count); 748 while (Count--) { 749 Tables.push_back(readTable(Ptr)); 750 if (Tables.back().ElemType != wasm::WASM_TYPE_ANYFUNC) { 751 return make_error<GenericBinaryError>("Invalid table element type", 752 object_error::parse_failed); 753 } 754 } 755 if (Ptr != End) 756 return make_error<GenericBinaryError>("Table section ended prematurely", 757 object_error::parse_failed); 758 return Error::success(); 759 } 760 761 Error WasmObjectFile::parseMemorySection(const uint8_t *Ptr, const uint8_t *End) { 762 uint32_t Count = readVaruint32(Ptr); 763 Memories.reserve(Count); 764 while (Count--) { 765 Memories.push_back(readLimits(Ptr)); 766 } 767 if (Ptr != End) 768 return make_error<GenericBinaryError>("Memory section ended prematurely", 769 object_error::parse_failed); 770 return Error::success(); 771 } 772 773 Error WasmObjectFile::parseGlobalSection(const uint8_t *Ptr, const uint8_t *End) { 774 GlobalSection = Sections.size(); 775 uint32_t Count = readVaruint32(Ptr); 776 Globals.reserve(Count); 777 while (Count--) { 778 wasm::WasmGlobal Global; 779 Global.Index = NumImportedGlobals + Globals.size(); 780 Global.Type.Type = readUint8(Ptr); 781 Global.Type.Mutable = readVaruint1(Ptr); 782 if (Error Err = readInitExpr(Global.InitExpr, Ptr)) 783 return Err; 784 Globals.push_back(Global); 785 } 786 if (Ptr != End) 787 return make_error<GenericBinaryError>("Global section ended prematurely", 788 object_error::parse_failed); 789 return Error::success(); 790 } 791 792 Error WasmObjectFile::parseExportSection(const uint8_t *Ptr, const uint8_t *End) { 793 uint32_t Count = readVaruint32(Ptr); 794 Exports.reserve(Count); 795 for (uint32_t i = 0; i < Count; i++) { 796 wasm::WasmExport Ex; 797 Ex.Name = readString(Ptr); 798 Ex.Kind = readUint8(Ptr); 799 Ex.Index = readVaruint32(Ptr); 800 switch (Ex.Kind) { 801 case wasm::WASM_EXTERNAL_FUNCTION: 802 if (!isValidFunctionIndex(Ex.Index)) 803 return make_error<GenericBinaryError>("Invalid function export", 804 object_error::parse_failed); 805 break; 806 case wasm::WASM_EXTERNAL_GLOBAL: 807 if (!isValidGlobalIndex(Ex.Index)) 808 return make_error<GenericBinaryError>("Invalid global export", 809 object_error::parse_failed); 810 break; 811 case wasm::WASM_EXTERNAL_MEMORY: 812 case wasm::WASM_EXTERNAL_TABLE: 813 break; 814 default: 815 return make_error<GenericBinaryError>( 816 "Unexpected export kind", object_error::parse_failed); 817 } 818 Exports.push_back(Ex); 819 } 820 if (Ptr != End) 821 return make_error<GenericBinaryError>("Export section ended prematurely", 822 object_error::parse_failed); 823 return Error::success(); 824 } 825 826 bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const { 827 return Index < NumImportedFunctions + FunctionTypes.size(); 828 } 829 830 bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const { 831 return Index >= NumImportedFunctions && isValidFunctionIndex(Index); 832 } 833 834 bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const { 835 return Index < NumImportedGlobals + Globals.size(); 836 } 837 838 bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const { 839 return Index >= NumImportedGlobals && isValidGlobalIndex(Index); 840 } 841 842 bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const { 843 return Index < Symbols.size() && Symbols[Index].isTypeFunction(); 844 } 845 846 bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const { 847 return Index < Symbols.size() && Symbols[Index].isTypeGlobal(); 848 } 849 850 bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const { 851 return Index < Symbols.size() && Symbols[Index].isTypeData(); 852 } 853 854 bool WasmObjectFile::isValidSectionSymbol(uint32_t Index) const { 855 return Index < Symbols.size() && Symbols[Index].isTypeSection(); 856 } 857 858 wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) { 859 assert(isDefinedFunctionIndex(Index)); 860 return Functions[Index - NumImportedFunctions]; 861 } 862 863 wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) { 864 assert(isDefinedGlobalIndex(Index)); 865 return Globals[Index - NumImportedGlobals]; 866 } 867 868 Error WasmObjectFile::parseStartSection(const uint8_t *Ptr, const uint8_t *End) { 869 StartFunction = readVaruint32(Ptr); 870 if (!isValidFunctionIndex(StartFunction)) 871 return make_error<GenericBinaryError>("Invalid start function", 872 object_error::parse_failed); 873 return Error::success(); 874 } 875 876 Error WasmObjectFile::parseCodeSection(const uint8_t *Ptr, const uint8_t *End) { 877 CodeSection = Sections.size(); 878 const uint8_t *CodeSectionStart = Ptr; 879 uint32_t FunctionCount = readVaruint32(Ptr); 880 if (FunctionCount != FunctionTypes.size()) { 881 return make_error<GenericBinaryError>("Invalid function count", 882 object_error::parse_failed); 883 } 884 885 while (FunctionCount--) { 886 wasm::WasmFunction Function; 887 const uint8_t *FunctionStart = Ptr; 888 uint32_t Size = readVaruint32(Ptr); 889 const uint8_t *FunctionEnd = Ptr + Size; 890 891 Function.CodeOffset = Ptr - FunctionStart; 892 Function.Index = NumImportedFunctions + Functions.size(); 893 Function.CodeSectionOffset = FunctionStart - CodeSectionStart; 894 Function.Size = FunctionEnd - FunctionStart; 895 896 uint32_t NumLocalDecls = readVaruint32(Ptr); 897 Function.Locals.reserve(NumLocalDecls); 898 while (NumLocalDecls--) { 899 wasm::WasmLocalDecl Decl; 900 Decl.Count = readVaruint32(Ptr); 901 Decl.Type = readUint8(Ptr); 902 Function.Locals.push_back(Decl); 903 } 904 905 uint32_t BodySize = FunctionEnd - Ptr; 906 Function.Body = ArrayRef<uint8_t>(Ptr, BodySize); 907 // This will be set later when reading in the linking metadata section. 908 Function.Comdat = UINT32_MAX; 909 Ptr += BodySize; 910 assert(Ptr == FunctionEnd); 911 Functions.push_back(Function); 912 } 913 if (Ptr != End) 914 return make_error<GenericBinaryError>("Code section ended prematurely", 915 object_error::parse_failed); 916 return Error::success(); 917 } 918 919 Error WasmObjectFile::parseElemSection(const uint8_t *Ptr, const uint8_t *End) { 920 uint32_t Count = readVaruint32(Ptr); 921 ElemSegments.reserve(Count); 922 while (Count--) { 923 wasm::WasmElemSegment Segment; 924 Segment.TableIndex = readVaruint32(Ptr); 925 if (Segment.TableIndex != 0) { 926 return make_error<GenericBinaryError>("Invalid TableIndex", 927 object_error::parse_failed); 928 } 929 if (Error Err = readInitExpr(Segment.Offset, Ptr)) 930 return Err; 931 uint32_t NumElems = readVaruint32(Ptr); 932 while (NumElems--) { 933 Segment.Functions.push_back(readVaruint32(Ptr)); 934 } 935 ElemSegments.push_back(Segment); 936 } 937 if (Ptr != End) 938 return make_error<GenericBinaryError>("Elem section ended prematurely", 939 object_error::parse_failed); 940 return Error::success(); 941 } 942 943 Error WasmObjectFile::parseDataSection(const uint8_t *Ptr, const uint8_t *End) { 944 DataSection = Sections.size(); 945 const uint8_t *Start = Ptr; 946 uint32_t Count = readVaruint32(Ptr); 947 DataSegments.reserve(Count); 948 while (Count--) { 949 WasmSegment Segment; 950 Segment.Data.MemoryIndex = readVaruint32(Ptr); 951 if (Error Err = readInitExpr(Segment.Data.Offset, Ptr)) 952 return Err; 953 uint32_t Size = readVaruint32(Ptr); 954 Segment.Data.Content = ArrayRef<uint8_t>(Ptr, Size); 955 // The rest of these Data fields are set later, when reading in the linking 956 // metadata section. 957 Segment.Data.Alignment = 0; 958 Segment.Data.Flags = 0; 959 Segment.Data.Comdat = UINT32_MAX; 960 Segment.SectionOffset = Ptr - Start; 961 Ptr += Size; 962 DataSegments.push_back(Segment); 963 } 964 if (Ptr != End) 965 return make_error<GenericBinaryError>("Data section ended prematurely", 966 object_error::parse_failed); 967 return Error::success(); 968 } 969 970 const uint8_t *WasmObjectFile::getPtr(size_t Offset) const { 971 return reinterpret_cast<const uint8_t *>(getData().substr(Offset, 1).data()); 972 } 973 974 const wasm::WasmObjectHeader &WasmObjectFile::getHeader() const { 975 return Header; 976 } 977 978 void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const { Symb.d.a++; } 979 980 uint32_t WasmObjectFile::getSymbolFlags(DataRefImpl Symb) const { 981 uint32_t Result = SymbolRef::SF_None; 982 const WasmSymbol &Sym = getWasmSymbol(Symb); 983 984 LLVM_DEBUG(dbgs() << "getSymbolFlags: ptr=" << &Sym << " " << Sym << "\n"); 985 if (Sym.isBindingWeak()) 986 Result |= SymbolRef::SF_Weak; 987 if (!Sym.isBindingLocal()) 988 Result |= SymbolRef::SF_Global; 989 if (Sym.isHidden()) 990 Result |= SymbolRef::SF_Hidden; 991 if (!Sym.isDefined()) 992 Result |= SymbolRef::SF_Undefined; 993 if (Sym.isTypeFunction()) 994 Result |= SymbolRef::SF_Executable; 995 return Result; 996 } 997 998 basic_symbol_iterator WasmObjectFile::symbol_begin() const { 999 DataRefImpl Ref; 1000 Ref.d.a = 0; 1001 return BasicSymbolRef(Ref, this); 1002 } 1003 1004 basic_symbol_iterator WasmObjectFile::symbol_end() const { 1005 DataRefImpl Ref; 1006 Ref.d.a = Symbols.size(); 1007 return BasicSymbolRef(Ref, this); 1008 } 1009 1010 const WasmSymbol &WasmObjectFile::getWasmSymbol(const DataRefImpl &Symb) const { 1011 return Symbols[Symb.d.a]; 1012 } 1013 1014 const WasmSymbol &WasmObjectFile::getWasmSymbol(const SymbolRef &Symb) const { 1015 return getWasmSymbol(Symb.getRawDataRefImpl()); 1016 } 1017 1018 Expected<StringRef> WasmObjectFile::getSymbolName(DataRefImpl Symb) const { 1019 return getWasmSymbol(Symb).Info.Name; 1020 } 1021 1022 Expected<uint64_t> WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const { 1023 return getSymbolValue(Symb); 1024 } 1025 1026 uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol& Sym) const { 1027 switch (Sym.Info.Kind) { 1028 case wasm::WASM_SYMBOL_TYPE_FUNCTION: 1029 case wasm::WASM_SYMBOL_TYPE_GLOBAL: 1030 return Sym.Info.ElementIndex; 1031 case wasm::WASM_SYMBOL_TYPE_DATA: { 1032 // The value of a data symbol is the segment offset, plus the symbol 1033 // offset within the segment. 1034 uint32_t SegmentIndex = Sym.Info.DataRef.Segment; 1035 const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data; 1036 assert(Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST); 1037 return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset; 1038 } 1039 case wasm::WASM_SYMBOL_TYPE_SECTION: 1040 return 0; 1041 } 1042 llvm_unreachable("invalid symbol type"); 1043 } 1044 1045 uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const { 1046 return getWasmSymbolValue(getWasmSymbol(Symb)); 1047 } 1048 1049 uint32_t WasmObjectFile::getSymbolAlignment(DataRefImpl Symb) const { 1050 llvm_unreachable("not yet implemented"); 1051 return 0; 1052 } 1053 1054 uint64_t WasmObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const { 1055 llvm_unreachable("not yet implemented"); 1056 return 0; 1057 } 1058 1059 Expected<SymbolRef::Type> 1060 WasmObjectFile::getSymbolType(DataRefImpl Symb) const { 1061 const WasmSymbol &Sym = getWasmSymbol(Symb); 1062 1063 switch (Sym.Info.Kind) { 1064 case wasm::WASM_SYMBOL_TYPE_FUNCTION: 1065 return SymbolRef::ST_Function; 1066 case wasm::WASM_SYMBOL_TYPE_GLOBAL: 1067 return SymbolRef::ST_Other; 1068 case wasm::WASM_SYMBOL_TYPE_DATA: 1069 return SymbolRef::ST_Data; 1070 case wasm::WASM_SYMBOL_TYPE_SECTION: 1071 return SymbolRef::ST_Debug; 1072 } 1073 1074 llvm_unreachable("Unknown WasmSymbol::SymbolType"); 1075 return SymbolRef::ST_Other; 1076 } 1077 1078 Expected<section_iterator> 1079 WasmObjectFile::getSymbolSection(DataRefImpl Symb) const { 1080 const WasmSymbol& Sym = getWasmSymbol(Symb); 1081 if (Sym.isUndefined()) 1082 return section_end(); 1083 1084 DataRefImpl Ref; 1085 switch (Sym.Info.Kind) { 1086 case wasm::WASM_SYMBOL_TYPE_FUNCTION: 1087 Ref.d.a = CodeSection; 1088 break; 1089 case wasm::WASM_SYMBOL_TYPE_GLOBAL: 1090 Ref.d.a = GlobalSection; 1091 break; 1092 case wasm::WASM_SYMBOL_TYPE_DATA: 1093 Ref.d.a = DataSection; 1094 break; 1095 case wasm::WASM_SYMBOL_TYPE_SECTION: { 1096 Ref.d.a = Sym.Info.ElementIndex; 1097 break; 1098 } 1099 default: 1100 llvm_unreachable("Unknown WasmSymbol::SymbolType"); 1101 } 1102 return section_iterator(SectionRef(Ref, this)); 1103 } 1104 1105 void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; } 1106 1107 std::error_code WasmObjectFile::getSectionName(DataRefImpl Sec, 1108 StringRef &Res) const { 1109 const WasmSection &S = Sections[Sec.d.a]; 1110 #define ECase(X) \ 1111 case wasm::WASM_SEC_##X: \ 1112 Res = #X; \ 1113 break 1114 switch (S.Type) { 1115 ECase(TYPE); 1116 ECase(IMPORT); 1117 ECase(FUNCTION); 1118 ECase(TABLE); 1119 ECase(MEMORY); 1120 ECase(GLOBAL); 1121 ECase(EXPORT); 1122 ECase(START); 1123 ECase(ELEM); 1124 ECase(CODE); 1125 ECase(DATA); 1126 case wasm::WASM_SEC_CUSTOM: 1127 Res = S.Name; 1128 break; 1129 default: 1130 return object_error::invalid_section_index; 1131 } 1132 #undef ECase 1133 return std::error_code(); 1134 } 1135 1136 uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { return 0; } 1137 1138 uint64_t WasmObjectFile::getSectionIndex(DataRefImpl Sec) const { 1139 return Sec.d.a; 1140 } 1141 1142 uint64_t WasmObjectFile::getSectionSize(DataRefImpl Sec) const { 1143 const WasmSection &S = Sections[Sec.d.a]; 1144 return S.Content.size(); 1145 } 1146 1147 std::error_code WasmObjectFile::getSectionContents(DataRefImpl Sec, 1148 StringRef &Res) const { 1149 const WasmSection &S = Sections[Sec.d.a]; 1150 // This will never fail since wasm sections can never be empty (user-sections 1151 // must have a name and non-user sections each have a defined structure). 1152 Res = StringRef(reinterpret_cast<const char *>(S.Content.data()), 1153 S.Content.size()); 1154 return std::error_code(); 1155 } 1156 1157 uint64_t WasmObjectFile::getSectionAlignment(DataRefImpl Sec) const { 1158 return 1; 1159 } 1160 1161 bool WasmObjectFile::isSectionCompressed(DataRefImpl Sec) const { 1162 return false; 1163 } 1164 1165 bool WasmObjectFile::isSectionText(DataRefImpl Sec) const { 1166 return getWasmSection(Sec).Type == wasm::WASM_SEC_CODE; 1167 } 1168 1169 bool WasmObjectFile::isSectionData(DataRefImpl Sec) const { 1170 return getWasmSection(Sec).Type == wasm::WASM_SEC_DATA; 1171 } 1172 1173 bool WasmObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; } 1174 1175 bool WasmObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; } 1176 1177 bool WasmObjectFile::isSectionBitcode(DataRefImpl Sec) const { return false; } 1178 1179 relocation_iterator WasmObjectFile::section_rel_begin(DataRefImpl Ref) const { 1180 DataRefImpl RelocRef; 1181 RelocRef.d.a = Ref.d.a; 1182 RelocRef.d.b = 0; 1183 return relocation_iterator(RelocationRef(RelocRef, this)); 1184 } 1185 1186 relocation_iterator WasmObjectFile::section_rel_end(DataRefImpl Ref) const { 1187 const WasmSection &Sec = getWasmSection(Ref); 1188 DataRefImpl RelocRef; 1189 RelocRef.d.a = Ref.d.a; 1190 RelocRef.d.b = Sec.Relocations.size(); 1191 return relocation_iterator(RelocationRef(RelocRef, this)); 1192 } 1193 1194 void WasmObjectFile::moveRelocationNext(DataRefImpl &Rel) const { 1195 Rel.d.b++; 1196 } 1197 1198 uint64_t WasmObjectFile::getRelocationOffset(DataRefImpl Ref) const { 1199 const wasm::WasmRelocation &Rel = getWasmRelocation(Ref); 1200 return Rel.Offset; 1201 } 1202 1203 symbol_iterator WasmObjectFile::getRelocationSymbol(DataRefImpl Ref) const { 1204 const wasm::WasmRelocation &Rel = getWasmRelocation(Ref); 1205 if (Rel.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB) 1206 return symbol_end(); 1207 DataRefImpl Sym; 1208 Sym.d.a = Rel.Index; 1209 Sym.d.b = 0; 1210 return symbol_iterator(SymbolRef(Sym, this)); 1211 } 1212 1213 uint64_t WasmObjectFile::getRelocationType(DataRefImpl Ref) const { 1214 const wasm::WasmRelocation &Rel = getWasmRelocation(Ref); 1215 return Rel.Type; 1216 } 1217 1218 void WasmObjectFile::getRelocationTypeName( 1219 DataRefImpl Ref, SmallVectorImpl<char> &Result) const { 1220 const wasm::WasmRelocation& Rel = getWasmRelocation(Ref); 1221 StringRef Res = "Unknown"; 1222 1223 #define WASM_RELOC(name, value) \ 1224 case wasm::name: \ 1225 Res = #name; \ 1226 break; 1227 1228 switch (Rel.Type) { 1229 #include "llvm/BinaryFormat/WasmRelocs.def" 1230 } 1231 1232 #undef WASM_RELOC 1233 1234 Result.append(Res.begin(), Res.end()); 1235 } 1236 1237 section_iterator WasmObjectFile::section_begin() const { 1238 DataRefImpl Ref; 1239 Ref.d.a = 0; 1240 return section_iterator(SectionRef(Ref, this)); 1241 } 1242 1243 section_iterator WasmObjectFile::section_end() const { 1244 DataRefImpl Ref; 1245 Ref.d.a = Sections.size(); 1246 return section_iterator(SectionRef(Ref, this)); 1247 } 1248 1249 uint8_t WasmObjectFile::getBytesInAddress() const { return 4; } 1250 1251 StringRef WasmObjectFile::getFileFormatName() const { return "WASM"; } 1252 1253 Triple::ArchType WasmObjectFile::getArch() const { return Triple::wasm32; } 1254 1255 SubtargetFeatures WasmObjectFile::getFeatures() const { 1256 return SubtargetFeatures(); 1257 } 1258 1259 bool WasmObjectFile::isRelocatableObject() const { 1260 return HasLinkingSection; 1261 } 1262 1263 const WasmSection &WasmObjectFile::getWasmSection(DataRefImpl Ref) const { 1264 assert(Ref.d.a < Sections.size()); 1265 return Sections[Ref.d.a]; 1266 } 1267 1268 const WasmSection & 1269 WasmObjectFile::getWasmSection(const SectionRef &Section) const { 1270 return getWasmSection(Section.getRawDataRefImpl()); 1271 } 1272 1273 const wasm::WasmRelocation & 1274 WasmObjectFile::getWasmRelocation(const RelocationRef &Ref) const { 1275 return getWasmRelocation(Ref.getRawDataRefImpl()); 1276 } 1277 1278 const wasm::WasmRelocation & 1279 WasmObjectFile::getWasmRelocation(DataRefImpl Ref) const { 1280 assert(Ref.d.a < Sections.size()); 1281 const WasmSection& Sec = Sections[Ref.d.a]; 1282 assert(Ref.d.b < Sec.Relocations.size()); 1283 return Sec.Relocations[Ref.d.b]; 1284 } 1285