Coverage Report

Created: 2019-01-21 03:01

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/COFF/MinGW.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- MinGW.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 "MinGW.h"
10
#include "SymbolTable.h"
11
#include "lld/Common/ErrorHandler.h"
12
#include "llvm/Object/COFF.h"
13
#include "llvm/Support/Path.h"
14
#include "llvm/Support/raw_ostream.h"
15
16
using namespace lld;
17
using namespace lld::coff;
18
using namespace llvm;
19
using namespace llvm::COFF;
20
21
15
void AutoExporter::initSymbolExcludes() {
22
15
  ExcludeSymbolPrefixes = {
23
15
      // Import symbols
24
15
      "__imp_",
25
15
      "__IMPORT_DESCRIPTOR_",
26
15
      // Extra import symbols from GNU import libraries
27
15
      "__nm_",
28
15
      // C++ symbols
29
15
      "__rtti_",
30
15
      "__builtin_",
31
15
      // Artifical symbols such as .refptr
32
15
      ".",
33
15
  };
34
15
  ExcludeSymbolSuffixes = {
35
15
      "_iname",
36
15
      "_NULL_THUNK_DATA",
37
15
  };
38
15
  if (Config->Machine == I386) {
39
4
    ExcludeSymbols = {
40
4
        "__NULL_IMPORT_DESCRIPTOR",
41
4
        "__pei386_runtime_relocator",
42
4
        "_do_pseudo_reloc",
43
4
        "_impure_ptr",
44
4
        "__impure_ptr",
45
4
        "__fmode",
46
4
        "_environ",
47
4
        "___dso_handle",
48
4
        // These are the MinGW names that differ from the standard
49
4
        // ones (lacking an extra underscore).
50
4
        "_DllMain@12",
51
4
        "_DllEntryPoint@12",
52
4
        "_DllMainCRTStartup@12",
53
4
    };
54
4
    ExcludeSymbolPrefixes.insert("__head_");
55
11
  } else {
56
11
    ExcludeSymbols = {
57
11
        "__NULL_IMPORT_DESCRIPTOR",
58
11
        "_pei386_runtime_relocator",
59
11
        "do_pseudo_reloc",
60
11
        "impure_ptr",
61
11
        "_impure_ptr",
62
11
        "_fmode",
63
11
        "environ",
64
11
        "__dso_handle",
65
11
        // These are the MinGW names that differ from the standard
66
11
        // ones (lacking an extra underscore).
67
11
        "DllMain",
68
11
        "DllEntryPoint",
69
11
        "DllMainCRTStartup",
70
11
    };
71
11
    ExcludeSymbolPrefixes.insert("_head_");
72
11
  }
73
15
}
74
75
551
AutoExporter::AutoExporter() {
76
551
  ExcludeLibs = {
77
551
      "libgcc",
78
551
      "libgcc_s",
79
551
      "libstdc++",
80
551
      "libmingw32",
81
551
      "libmingwex",
82
551
      "libg2c",
83
551
      "libsupc++",
84
551
      "libobjc",
85
551
      "libgcj",
86
551
      "libclang_rt.builtins",
87
551
      "libclang_rt.builtins-aarch64",
88
551
      "libclang_rt.builtins-arm",
89
551
      "libclang_rt.builtins-i386",
90
551
      "libclang_rt.builtins-x86_64",
91
551
      "libc++",
92
551
      "libc++abi",
93
551
      "libunwind",
94
551
      "libmsvcrt",
95
551
      "libucrtbase",
96
551
  };
97
551
  ExcludeObjects = {
98
551
      "crt0.o",
99
551
      "crt1.o",
100
551
      "crt1u.o",
101
551
      "crt2.o",
102
551
      "crt2u.o",
103
551
      "dllcrt1.o",
104
551
      "dllcrt2.o",
105
551
      "gcrt0.o",
106
551
      "gcrt1.o",
107
551
      "gcrt2.o",
108
551
      "crtbegin.o",
109
551
      "crtend.o",
110
551
  };
111
551
}
112
113
4
void AutoExporter::addWholeArchive(StringRef Path) {
114
4
  StringRef LibName = sys::path::filename(Path);
115
4
  // Drop the file extension, to match the processing below.
116
4
  LibName = LibName.substr(0, LibName.rfind('.'));
117
4
  ExcludeLibs.erase(LibName);
118
4
}
119
120
263
bool AutoExporter::shouldExport(Defined *Sym) const {
121
263
  if (!Sym || 
!Sym->isLive()257
||
!Sym->getChunk()251
)
122
217
    return false;
123
46
124
46
  // Only allow the symbol kinds that make sense to export; in particular,
125
46
  // disallow import symbols.
126
46
  if (!isa<DefinedRegular>(Sym) && 
!isa<DefinedCommon>(Sym)2
)
127
2
    return false;
128
44
  if (ExcludeSymbols.count(Sym->getName()))
129
9
    return false;
130
35
131
35
  for (StringRef Prefix : ExcludeSymbolPrefixes.keys())
132
230
    if (Sym->getName().startswith(Prefix))
133
4
      return false;
134
35
  
for (StringRef Suffix : ExcludeSymbolSuffixes.keys())31
135
61
    if (Sym->getName().endswith(Suffix))
136
1
      return false;
137
31
138
31
  // If a corresponding __imp_ symbol exists and is defined, don't export it.
139
31
  
if (30
Symtab->find(("__imp_" + Sym->getName()).str())30
)
140
2
    return false;
141
28
142
28
  // Check that file is non-null before dereferencing it, symbols not
143
28
  // originating in regular object files probably shouldn't be exported.
144
28
  if (!Sym->getFile())
145
0
    return false;
146
28
147
28
  StringRef LibName = sys::path::filename(Sym->getFile()->ParentName);
148
28
149
28
  // Drop the file extension.
150
28
  LibName = LibName.substr(0, LibName.rfind('.'));
151
28
  if (!LibName.empty())
152
2
    return !ExcludeLibs.count(LibName);
153
26
154
26
  StringRef FileName = sys::path::filename(Sym->getFile()->getName());
155
26
  return !ExcludeObjects.count(FileName);
156
26
}
157
158
4
void coff::writeDefFile(StringRef Name) {
159
4
  std::error_code EC;
160
4
  raw_fd_ostream OS(Name, EC, sys::fs::F_None);
161
4
  if (EC)
162
0
    fatal("cannot open " + Name + ": " + EC.message());
163
4
164
4
  OS << "EXPORTS\n";
165
9
  for (Export &E : Config->Exports) {
166
9
    OS << "    " << E.ExportName << " "
167
9
       << "@" << E.Ordinal;
168
9
    if (auto *Def = dyn_cast_or_null<Defined>(E.Sym)) {
169
9
      if (Def && Def->getChunk() &&
170
9
          !(Def->getChunk()->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
171
0
        OS << " DATA";
172
9
    }
173
9
    OS << "\n";
174
9
  }
175
4
}