LCOV - code coverage report
Current view: top level - lib/Target/WebAssembly/MCTargetDesc - WebAssemblyWasmObjectWriter.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 29 36 80.6 %
Date: 2018-10-20 13:21:21 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- WebAssemblyWasmObjectWriter.cpp - WebAssembly Wasm Writer ---------===//
       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             : /// \file
      11             : /// This file handles Wasm-specific object emission, converting LLVM's
      12             : /// internal fixups into the appropriate relocations.
      13             : ///
      14             : //===----------------------------------------------------------------------===//
      15             : 
      16             : #include "MCTargetDesc/WebAssemblyFixupKinds.h"
      17             : #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
      18             : #include "llvm/BinaryFormat/Wasm.h"
      19             : #include "llvm/MC/MCAsmBackend.h"
      20             : #include "llvm/MC/MCFixup.h"
      21             : #include "llvm/MC/MCFixupKindInfo.h"
      22             : #include "llvm/MC/MCObjectWriter.h"
      23             : #include "llvm/MC/MCSectionWasm.h"
      24             : #include "llvm/MC/MCSymbolWasm.h"
      25             : #include "llvm/MC/MCValue.h"
      26             : #include "llvm/MC/MCWasmObjectWriter.h"
      27             : #include "llvm/Support/Casting.h"
      28             : #include "llvm/Support/ErrorHandling.h"
      29             : 
      30             : using namespace llvm;
      31             : 
      32             : namespace {
      33           0 : class WebAssemblyWasmObjectWriter final : public MCWasmObjectTargetWriter {
      34             : public:
      35             :   explicit WebAssemblyWasmObjectWriter(bool Is64Bit);
      36             : 
      37             : private:
      38             :   unsigned getRelocType(const MCValue &Target,
      39             :                         const MCFixup &Fixup) const override;
      40             : };
      41             : } // end anonymous namespace
      42             : 
      43           0 : WebAssemblyWasmObjectWriter::WebAssemblyWasmObjectWriter(bool Is64Bit)
      44           0 :     : MCWasmObjectTargetWriter(Is64Bit) {}
      45             : 
      46             : // Test whether the given expression computes a function address.
      47         444 : static bool IsFunctionExpr(const MCExpr *Expr) {
      48             :   if (auto SyExp = dyn_cast<MCSymbolRefExpr>(Expr))
      49         872 :     return cast<MCSymbolWasm>(SyExp->getSymbol()).isFunction();
      50             : 
      51             :   if (auto BinOp = dyn_cast<MCBinaryExpr>(Expr))
      52           4 :     return IsFunctionExpr(BinOp->getLHS()) != IsFunctionExpr(BinOp->getRHS());
      53             : 
      54             :   if (auto UnOp = dyn_cast<MCUnaryExpr>(Expr))
      55           0 :     return IsFunctionExpr(UnOp->getSubExpr());
      56             : 
      57             :   return false;
      58             : }
      59             : 
      60             : static bool IsFunctionType(const MCValue &Target) {
      61             :   const MCSymbolRefExpr *RefA = Target.getSymA();
      62         247 :   return RefA && RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX;
      63             : }
      64             : 
      65         113 : static const MCSection *GetFixupSection(const MCExpr *Expr) {
      66             :   if (auto SyExp = dyn_cast<MCSymbolRefExpr>(Expr)) {
      67         105 :     if (SyExp->getSymbol().isInSection())
      68          95 :       return &SyExp->getSymbol().getSection();
      69             :     return nullptr;
      70             :   }
      71             : 
      72             :   if (auto BinOp = dyn_cast<MCBinaryExpr>(Expr)) {
      73           4 :     auto SectionLHS = GetFixupSection(BinOp->getLHS());
      74           4 :     auto SectionRHS = GetFixupSection(BinOp->getRHS());
      75           5 :     return SectionLHS == SectionRHS ? nullptr : SectionLHS;
      76             :   }
      77             : 
      78             :   if (auto UnOp = dyn_cast<MCUnaryExpr>(Expr))
      79           0 :     return GetFixupSection(UnOp->getSubExpr());
      80             : 
      81             :   return nullptr;
      82             : }
      83             : 
      84             : static bool IsGlobalType(const MCValue &Target) {
      85         267 :   const MCSymbolRefExpr *RefA = Target.getSymA();
      86         267 :   return RefA && RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_GLOBAL;
      87             : }
      88             : 
      89         436 : unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
      90             :                                                    const MCFixup &Fixup) const {
      91             :   // WebAssembly functions are not allocated in the data address space. To
      92             :   // resolve a pointer to a function, we must use a special relocation type.
      93         436 :   bool IsFunction = IsFunctionExpr(Fixup.getValue());
      94             : 
      95         436 :   switch (unsigned(Fixup.getKind())) {
      96          49 :   case WebAssembly::fixup_code_sleb128_i32:
      97          49 :     if (IsFunction)
      98          27 :       return wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB;
      99             :     return wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB;
     100             :   case WebAssembly::fixup_code_sleb128_i64:
     101             :     llvm_unreachable("fixup_sleb128_i64 not implemented yet");
     102             :   case WebAssembly::fixup_code_uleb128_i32:
     103             :     if (IsGlobalType(Target))
     104             :       return wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB;
     105             :     if (IsFunctionType(Target))
     106             :       return wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB;
     107         236 :     if (IsFunction)
     108          93 :       return wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB;
     109             :     return wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB;
     110         120 :   case FK_Data_4:
     111         120 :     if (IsFunction)
     112             :       return wasm::R_WEBASSEMBLY_TABLE_INDEX_I32;
     113         105 :     if (auto Section = static_cast<const MCSectionWasm *>(
     114         105 :             GetFixupSection(Fixup.getValue()))) {
     115          95 :       if (Section->getKind().isText())
     116             :         return wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32;
     117          69 :       else if (!Section->isWasmData())
     118          58 :         return wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32;
     119             :     }
     120             :     return wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32;
     121             :   case FK_Data_8:
     122             :     llvm_unreachable("FK_Data_8 not implemented yet");
     123           0 :   default:
     124           0 :     llvm_unreachable("unimplemented fixup kind");
     125             :   }
     126             : }
     127             : 
     128             : std::unique_ptr<MCObjectTargetWriter>
     129         307 : llvm::createWebAssemblyWasmObjectWriter(bool Is64Bit) {
     130         307 :   return llvm::make_unique<WebAssemblyWasmObjectWriter>(Is64Bit);
     131             : }

Generated by: LCOV version 1.13