Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/wasm/Relocations.cpp
Line
Count
Source
1
//===- Relocations.cpp ----------------------------------------------------===//
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
#include "Relocations.h"
10
11
#include "InputChunks.h"
12
#include "SyntheticSections.h"
13
14
using namespace llvm;
15
using namespace llvm::wasm;
16
17
using namespace lld;
18
using namespace lld::wasm;
19
20
71
static bool requiresGOTAccess(const Symbol *sym) {
21
71
  return config->isPic && 
!sym->isHidden()12
&&
!sym->isLocal()6
;
22
71
}
23
24
23
static bool allowUndefined(const Symbol* sym) {
25
23
  // Historically --allow-undefined doesn't work for data symbols since we don't
26
23
  // have any way to represent these as imports in the final binary.  The idea
27
23
  // behind allowing undefined symbols is to allow importing these symbols from
28
23
  // the embedder and we can't do this for data symbols (at least not without
29
23
  // compiling with -fPIC)
30
23
  if (isa<DataSymbol>(sym))
31
2
    return false;
32
21
  return (config->allowUndefined ||
33
21
          
config->allowUndefinedSymbols.count(sym->getName()) != 06
);
34
21
}
35
36
23
static void reportUndefined(const Symbol* sym) {
37
23
  assert(sym->isUndefined());
38
23
  assert(!sym->isWeak());
39
23
  if (!allowUndefined(sym))
40
6
    error(toString(sym->getFile()) + ": undefined symbol: " + toString(*sym));
41
23
}
42
43
1.22k
void lld::wasm::scanRelocations(InputChunk *chunk) {
44
1.22k
  if (!chunk->live)
45
437
    return;
46
790
  ObjFile *file = chunk->file;
47
790
  ArrayRef<WasmSignature> types = file->getWasmObj()->types();
48
790
  for (const WasmRelocation &reloc : chunk->getRelocations()) {
49
472
    if (reloc.Type == R_WASM_TYPE_INDEX_LEB) {
50
16
      // Mark target type as live
51
16
      file->typeMap[reloc.Index] =
52
16
          out.typeSec->registerType(types[reloc.Index]);
53
16
      file->typeIsUsed[reloc.Index] = true;
54
16
      continue;
55
16
    }
56
456
57
456
    // Other relocation types all have a corresponding symbol
58
456
    Symbol *sym = file->getSymbols()[reloc.Index];
59
456
60
456
    switch (reloc.Type) {
61
456
    case R_WASM_TABLE_INDEX_I32:
62
63
    case R_WASM_TABLE_INDEX_SLEB:
63
63
    case R_WASM_TABLE_INDEX_REL_SLEB:
64
63
      if (requiresGOTAccess(sym))
65
1
        break;
66
62
      out.elemSec->addEntry(cast<FunctionSymbol>(sym));
67
62
      break;
68
62
    case R_WASM_GLOBAL_INDEX_LEB:
69
47
      if (!isa<GlobalSymbol>(sym))
70
5
        out.importSec->addGOTEntry(sym);
71
47
      break;
72
456
    }
73
456
74
456
    if (config->isPic) {
75
25
      switch (reloc.Type) {
76
25
      case R_WASM_TABLE_INDEX_SLEB:
77
1
      case R_WASM_MEMORY_ADDR_SLEB:
78
1
      case R_WASM_MEMORY_ADDR_LEB:
79
1
        // Certain relocation types can't be used when building PIC output,
80
1
        // since they would require absolute symbol addresses at link time.
81
1
        error(toString(file) + ": relocation " + relocTypeToString(reloc.Type) +
82
1
              " cannot be used against symbol " + toString(*sym) +
83
1
              "; recompile with -fPIC");
84
1
        break;
85
8
      case R_WASM_TABLE_INDEX_I32:
86
8
      case R_WASM_MEMORY_ADDR_I32:
87
8
        // These relocation types are only present in the data section and
88
8
        // will be converted into code by `generateRelocationCode`.  This code
89
8
        // requires the symbols to have GOT entires.
90
8
        if (requiresGOTAccess(sym))
91
5
          out.importSec->addGOTEntry(sym);
92
8
        break;
93
431
      }
94
431
    } else {
95
431
      // Report undefined symbols
96
431
      if (sym->isUndefined() && 
!config->relocatable51
&&
!sym->isWeak()24
)
97
23
        reportUndefined(sym);
98
431
    }
99
456
100
456
  }
101
790
}