Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- WebAssemblyWasmObjectWriter.cpp - WebAssembly Wasm Writer ---------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// This file handles Wasm-specific object emission, converting LLVM's
11
/// internal fixups into the appropriate relocations.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#include "MCTargetDesc/WebAssemblyFixupKinds.h"
16
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
17
#include "llvm/BinaryFormat/Wasm.h"
18
#include "llvm/MC/MCAsmBackend.h"
19
#include "llvm/MC/MCFixup.h"
20
#include "llvm/MC/MCFixupKindInfo.h"
21
#include "llvm/MC/MCObjectWriter.h"
22
#include "llvm/MC/MCSectionWasm.h"
23
#include "llvm/MC/MCSymbolWasm.h"
24
#include "llvm/MC/MCValue.h"
25
#include "llvm/MC/MCWasmObjectWriter.h"
26
#include "llvm/Support/Casting.h"
27
#include "llvm/Support/ErrorHandling.h"
28
29
using namespace llvm;
30
31
namespace {
32
class WebAssemblyWasmObjectWriter final : public MCWasmObjectTargetWriter {
33
public:
34
  explicit WebAssemblyWasmObjectWriter(bool Is64Bit);
35
36
private:
37
  unsigned getRelocType(const MCValue &Target,
38
                        const MCFixup &Fixup) const override;
39
};
40
} // end anonymous namespace
41
42
WebAssemblyWasmObjectWriter::WebAssemblyWasmObjectWriter(bool Is64Bit)
43
443
    : MCWasmObjectTargetWriter(Is64Bit) {}
44
45
120
static const MCSection *getFixupSection(const MCExpr *Expr) {
46
120
  if (auto SyExp = dyn_cast<MCSymbolRefExpr>(Expr)) {
47
110
    if (SyExp->getSymbol().isInSection())
48
97
      return &SyExp->getSymbol().getSection();
49
13
    return nullptr;
50
13
  }
51
10
52
10
  if (auto BinOp = dyn_cast<MCBinaryExpr>(Expr)) {
53
5
    auto SectionLHS = getFixupSection(BinOp->getLHS());
54
5
    auto SectionRHS = getFixupSection(BinOp->getRHS());
55
5
    return SectionLHS == SectionRHS ? 
nullptr2
:
SectionLHS3
;
56
5
  }
57
5
58
5
  if (auto UnOp = dyn_cast<MCUnaryExpr>(Expr))
59
0
    return getFixupSection(UnOp->getSubExpr());
60
5
61
5
  return nullptr;
62
5
}
63
64
unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
65
532
                                                   const MCFixup &Fixup) const {
66
532
  const MCSymbolRefExpr *RefA = Target.getSymA();
67
532
  assert(RefA);
68
532
  auto& SymA = cast<MCSymbolWasm>(RefA->getSymbol());
69
532
70
532
  MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
71
532
72
532
  switch (Modifier) {
73
532
    case MCSymbolRefExpr::VK_GOT:
74
8
      return wasm::R_WASM_GLOBAL_INDEX_LEB;
75
532
    case MCSymbolRefExpr::VK_WASM_TBREL:
76
2
      assert(SymA.isFunction());
77
2
      return wasm::R_WASM_TABLE_INDEX_REL_SLEB;
78
532
    case MCSymbolRefExpr::VK_WASM_MBREL:
79
3
      assert(SymA.isData());
80
3
      return wasm::R_WASM_MEMORY_ADDR_REL_SLEB;
81
532
    case MCSymbolRefExpr::VK_WASM_TYPEINDEX:
82
16
      return wasm::R_WASM_TYPE_INDEX_LEB;
83
532
    default:
84
503
      break;
85
503
  }
86
503
87
503
  switch (unsigned(Fixup.getKind())) {
88
503
  case WebAssembly::fixup_sleb128_i32:
89
61
    if (SymA.isFunction())
90
29
      return wasm::R_WASM_TABLE_INDEX_SLEB;
91
32
    return wasm::R_WASM_MEMORY_ADDR_SLEB;
92
32
  case WebAssembly::fixup_sleb128_i64:
93
0
    llvm_unreachable("fixup_sleb128_i64 not implemented yet");
94
310
  case WebAssembly::fixup_uleb128_i32:
95
310
    if (SymA.isGlobal())
96
34
      return wasm::R_WASM_GLOBAL_INDEX_LEB;
97
276
    if (SymA.isFunction())
98
115
      return wasm::R_WASM_FUNCTION_INDEX_LEB;
99
161
    if (SymA.isEvent())
100
7
      return wasm::R_WASM_EVENT_INDEX_LEB;
101
154
    return wasm::R_WASM_MEMORY_ADDR_LEB;
102
154
  case FK_Data_4:
103
132
    if (SymA.isFunction())
104
22
      return wasm::R_WASM_TABLE_INDEX_I32;
105
110
    if (auto Section = static_cast<const MCSectionWasm *>(
106
97
            getFixupSection(Fixup.getValue()))) {
107
97
      if (Section->getKind().isText())
108
26
        return wasm::R_WASM_FUNCTION_OFFSET_I32;
109
71
      else if (!Section->isWasmData())
110
58
        return wasm::R_WASM_SECTION_OFFSET_I32;
111
26
    }
112
26
    return wasm::R_WASM_MEMORY_ADDR_I32;
113
26
  default:
114
0
    llvm_unreachable("unimplemented fixup kind");
115
503
  }
116
503
}
117
118
std::unique_ptr<MCObjectTargetWriter>
119
443
llvm::createWebAssemblyWasmObjectWriter(bool Is64Bit) {
120
443
  return llvm::make_unique<WebAssemblyWasmObjectWriter>(Is64Bit);
121
443
}