Coverage Report

Created: 2018-10-23 15:26

/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
//                             The LLVM Linker
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 "MinGW.h"
11
#include "SymbolTable.h"
12
#include "lld/Common/ErrorHandler.h"
13
#include "llvm/Object/COFF.h"
14
#include "llvm/Support/Path.h"
15
#include "llvm/Support/raw_ostream.h"
16
17
using namespace lld;
18
using namespace lld::coff;
19
using namespace llvm;
20
using namespace llvm::COFF;
21
22
14
void AutoExporter::initSymbolExcludes() {
23
14
  ExcludeSymbolPrefixes = {
24
14
      // Import symbols
25
14
      "__imp_",
26
14
      "__IMPORT_DESCRIPTOR_",
27
14
      // Extra import symbols from GNU import libraries
28
14
      "__nm_",
29
14
      // C++ symbols
30
14
      "__rtti_",
31
14
      "__builtin_",
32
14
      // Artifical symbols such as .refptr
33
14
      ".",
34
14
  };
35
14
  ExcludeSymbolSuffixes = {
36
14
      "_iname",
37
14
      "_NULL_THUNK_DATA",
38
14
  };
39
14
  if (Config->Machine == I386) {
40
3
    ExcludeSymbols = {
41
3
        "__NULL_IMPORT_DESCRIPTOR",
42
3
        "__pei386_runtime_relocator",
43
3
        "_do_pseudo_reloc",
44
3
        "_impure_ptr",
45
3
        "__impure_ptr",
46
3
        "__fmode",
47
3
        "_environ",
48
3
        "___dso_handle",
49
3
        // These are the MinGW names that differ from the standard
50
3
        // ones (lacking an extra underscore).
51
3
        "_DllMain@12",
52
3
        "_DllEntryPoint@12",
53
3
        "_DllMainCRTStartup@12",
54
3
    };
55
3
    ExcludeSymbolPrefixes.insert("__head_");
56
11
  } else {
57
11
    ExcludeSymbols = {
58
11
        "__NULL_IMPORT_DESCRIPTOR",
59
11
        "_pei386_runtime_relocator",
60
11
        "do_pseudo_reloc",
61
11
        "impure_ptr",
62
11
        "_impure_ptr",
63
11
        "_fmode",
64
11
        "environ",
65
11
        "__dso_handle",
66
11
        // These are the MinGW names that differ from the standard
67
11
        // ones (lacking an extra underscore).
68
11
        "DllMain",
69
11
        "DllEntryPoint",
70
11
        "DllMainCRTStartup",
71
11
    };
72
11
    ExcludeSymbolPrefixes.insert("_head_");
73
11
  }
74
14
}
75
76
535
AutoExporter::AutoExporter() {
77
535
  ExcludeLibs = {
78
535
      "libgcc",
79
535
      "libgcc_s",
80
535
      "libstdc++",
81
535
      "libmingw32",
82
535
      "libmingwex",
83
535
      "libg2c",
84
535
      "libsupc++",
85
535
      "libobjc",
86
535
      "libgcj",
87
535
      "libclang_rt.builtins-aarch64",
88
535
      "libclang_rt.builtins-arm",
89
535
      "libclang_rt.builtins-i386",
90
535
      "libclang_rt.builtins-x86_64",
91
535
      "libc++",
92
535
      "libc++abi",
93
535
      "libunwind",
94
535
      "libmsvcrt",
95
535
      "libucrtbase",
96
535
  };
97
535
  ExcludeObjects = {
98
535
      "crt0.o",
99
535
      "crt1.o",
100
535
      "crt1u.o",
101
535
      "crt2.o",
102
535
      "crt2u.o",
103
535
      "dllcrt1.o",
104
535
      "dllcrt2.o",
105
535
      "gcrt0.o",
106
535
      "gcrt1.o",
107
535
      "gcrt2.o",
108
535
      "crtbegin.o",
109
535
      "crtend.o",
110
535
  };
111
535
}
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
247
bool AutoExporter::shouldExport(Defined *Sym) const {
121
247
  if (!Sym || 
!Sym->isLive()241
||
!Sym->getChunk()235
)
122
202
    return false;
123
45
124
45
  // Only allow the symbol kinds that make sense to export; in particular,
125
45
  // disallow import symbols.
126
45
  if (!isa<DefinedRegular>(Sym) && 
!isa<DefinedCommon>(Sym)2
)
127
2
    return false;
128
43
  if (ExcludeSymbols.count(Sym->getName()))
129
9
    return false;
130
34
131
34
  for (StringRef Prefix : ExcludeSymbolPrefixes.keys())
132
223
    if (Sym->getName().startswith(Prefix))
133
4
      return false;
134
34
  
for (StringRef Suffix : ExcludeSymbolSuffixes.keys())30
135
59
    if (Sym->getName().endswith(Suffix))
136
1
      return false;
137
30
138
30
  // If a corresponding __imp_ symbol exists and is defined, don't export it.
139
30
  
if (29
Symtab->find(("__imp_" + Sym->getName()).str())29
)
140
2
    return false;
141
27
142
27
  // Check that file is non-null before dereferencing it, symbols not
143
27
  // originating in regular object files probably shouldn't be exported.
144
27
  if (!Sym->getFile())
145
0
    return false;
146
27
147
27
  StringRef LibName = sys::path::filename(Sym->getFile()->ParentName);
148
27
149
27
  // Drop the file extension.
150
27
  LibName = LibName.substr(0, LibName.rfind('.'));
151
27
  if (!LibName.empty())
152
2
    return !ExcludeLibs.count(LibName);
153
25
154
25
  StringRef FileName = sys::path::filename(Sym->getFile()->getName());
155
25
  return !ExcludeObjects.count(FileName);
156
25
}
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
}