OSDN Git Service

Try again to appease the FreeBSD bot.
[android-x86/external-llvm.git] / tools / sancov / sancov.cc
1 //===-- sancov.cc --------------------------------------------===//
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 // This file is a command-line tool for reading and analyzing sanitizer
11 // coverage.
12 //===----------------------------------------------------------------------===//
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/StringExtras.h"
15 #include "llvm/ADT/Twine.h"
16 #include "llvm/DebugInfo/Symbolize/Symbolize.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstPrinter.h"
22 #include "llvm/MC/MCInstrAnalysis.h"
23 #include "llvm/MC/MCInstrInfo.h"
24 #include "llvm/MC/MCObjectFileInfo.h"
25 #include "llvm/MC/MCRegisterInfo.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/Object/Archive.h"
28 #include "llvm/Object/Binary.h"
29 #include "llvm/Object/COFF.h"
30 #include "llvm/Object/ELFObjectFile.h"
31 #include "llvm/Object/MachO.h"
32 #include "llvm/Object/ObjectFile.h"
33 #include "llvm/Support/Casting.h"
34 #include "llvm/Support/CommandLine.h"
35 #include "llvm/Support/Errc.h"
36 #include "llvm/Support/ErrorOr.h"
37 #include "llvm/Support/FileSystem.h"
38 #include "llvm/Support/LineIterator.h"
39 #include "llvm/Support/MD5.h"
40 #include "llvm/Support/ManagedStatic.h"
41 #include "llvm/Support/MemoryBuffer.h"
42 #include "llvm/Support/Path.h"
43 #include "llvm/Support/PrettyStackTrace.h"
44 #include "llvm/Support/Regex.h"
45 #include "llvm/Support/SHA1.h"
46 #include "llvm/Support/Signals.h"
47 #include "llvm/Support/SourceMgr.h"
48 #include "llvm/Support/SpecialCaseList.h"
49 #include "llvm/Support/TargetRegistry.h"
50 #include "llvm/Support/TargetSelect.h"
51 #include "llvm/Support/ToolOutputFile.h"
52 #include "llvm/Support/YAMLParser.h"
53 #include "llvm/Support/raw_ostream.h"
54
55 #include <algorithm>
56 #include <set>
57 #include <stdio.h>
58 #include <string>
59 #include <utility>
60 #include <vector>
61
62 using namespace llvm;
63
64 namespace {
65
66 // --------- COMMAND LINE FLAGS ---------
67
68 enum ActionType {
69   CoveredFunctionsAction,
70   HtmlReportAction,
71   MergeAction,
72   NotCoveredFunctionsAction,
73   PrintAction,
74   PrintCovPointsAction,
75   StatsAction,
76   SymbolizeAction
77 };
78
79 cl::opt<ActionType> Action(
80     cl::desc("Action (required)"), cl::Required,
81     cl::values(
82         clEnumValN(PrintAction, "print", "Print coverage addresses"),
83         clEnumValN(PrintCovPointsAction, "print-coverage-pcs",
84                    "Print coverage instrumentation points addresses."),
85         clEnumValN(CoveredFunctionsAction, "covered-functions",
86                    "Print all covered funcions."),
87         clEnumValN(NotCoveredFunctionsAction, "not-covered-functions",
88                    "Print all not covered funcions."),
89         clEnumValN(StatsAction, "print-coverage-stats",
90                    "Print coverage statistics."),
91         clEnumValN(HtmlReportAction, "html-report",
92                    "REMOVED. Use -symbolize & coverage-report-server.py."),
93         clEnumValN(SymbolizeAction, "symbolize",
94                    "Produces a symbolized JSON report from binary report."),
95         clEnumValN(MergeAction, "merge", "Merges reports.")));
96
97 static cl::list<std::string>
98     ClInputFiles(cl::Positional, cl::OneOrMore,
99                  cl::desc("<action> <binary files...> <.sancov files...> "
100                           "<.symcov files...>"));
101
102 static cl::opt<bool> ClDemangle("demangle", cl::init(true),
103                                 cl::desc("Print demangled function name."));
104
105 static cl::opt<bool>
106     ClSkipDeadFiles("skip-dead-files", cl::init(true),
107                     cl::desc("Do not list dead source files in reports."));
108
109 static cl::opt<std::string> ClStripPathPrefix(
110     "strip_path_prefix", cl::init(""),
111     cl::desc("Strip this prefix from file paths in reports."));
112
113 static cl::opt<std::string>
114     ClBlacklist("blacklist", cl::init(""),
115                 cl::desc("Blacklist file (sanitizer blacklist format)."));
116
117 static cl::opt<bool> ClUseDefaultBlacklist(
118     "use_default_blacklist", cl::init(true), cl::Hidden,
119     cl::desc("Controls if default blacklist should be used."));
120
121 static const char *const DefaultBlacklistStr = "fun:__sanitizer_.*\n"
122                                                "src:/usr/include/.*\n"
123                                                "src:.*/libc\\+\\+/.*\n";
124
125 // --------- FORMAT SPECIFICATION ---------
126
127 struct FileHeader {
128   uint32_t Bitness;
129   uint32_t Magic;
130 };
131
132 static const uint32_t BinCoverageMagic = 0xC0BFFFFF;
133 static const uint32_t Bitness32 = 0xFFFFFF32;
134 static const uint32_t Bitness64 = 0xFFFFFF64;
135
136 static Regex SancovFileRegex("(.*)\\.[0-9]+\\.sancov");
137 static Regex SymcovFileRegex(".*\\.symcov");
138
139 // --------- MAIN DATASTRUCTURES ----------
140
141 // Contents of .sancov file: list of coverage point addresses that were
142 // executed.
143 struct RawCoverage {
144   explicit RawCoverage(std::unique_ptr<std::set<uint64_t>> Addrs)
145       : Addrs(std::move(Addrs)) {}
146
147   // Read binary .sancov file.
148   static ErrorOr<std::unique_ptr<RawCoverage>>
149   read(const std::string &FileName);
150
151   std::unique_ptr<std::set<uint64_t>> Addrs;
152 };
153
154 // Coverage point has an opaque Id and corresponds to multiple source locations.
155 struct CoveragePoint {
156   explicit CoveragePoint(const std::string &Id) : Id(Id) {}
157
158   std::string Id;
159   SmallVector<DILineInfo, 1> Locs;
160 };
161
162 // Symcov file content: set of covered Ids plus information about all available
163 // coverage points.
164 struct SymbolizedCoverage {
165   // Read json .symcov file.
166   static std::unique_ptr<SymbolizedCoverage> read(const std::string &InputFile);
167
168   std::set<std::string> CoveredIds;
169   std::string BinaryHash;
170   std::vector<CoveragePoint> Points;
171 };
172
173 struct CoverageStats {
174   size_t AllPoints;
175   size_t CovPoints;
176   size_t AllFns;
177   size_t CovFns;
178 };
179
180 // --------- ERROR HANDLING ---------
181
182 static void fail(const llvm::Twine &E) {
183   errs() << "Error: " << E << "\n";
184   exit(1);
185 }
186
187 static void failIf(bool B, const llvm::Twine &E) {
188   if (B)
189     fail(E);
190 }
191
192 static void failIfError(std::error_code Error) {
193   if (!Error)
194     return;
195   errs() << "Error: " << Error.message() << "(" << Error.value() << ")\n";
196   exit(1);
197 }
198
199 template <typename T> static void failIfError(const ErrorOr<T> &E) {
200   failIfError(E.getError());
201 }
202
203 static void failIfError(Error Err) {
204   if (Err) {
205     logAllUnhandledErrors(std::move(Err), errs(), "Error: ");
206     exit(1);
207   }
208 }
209
210 template <typename T> static void failIfError(Expected<T> &E) {
211   failIfError(E.takeError());
212 }
213
214 static void failIfNotEmpty(const llvm::Twine &E) {
215   if (E.str().empty())
216     return;
217   fail(E);
218 }
219
220 template <typename T>
221 static void failIfEmpty(const std::unique_ptr<T> &Ptr,
222                         const std::string &Message) {
223   if (Ptr.get())
224     return;
225   fail(Message);
226 }
227
228 // ----------- Coverage I/O ----------
229 template <typename T>
230 static void readInts(const char *Start, const char *End,
231                      std::set<uint64_t> *Ints) {
232   const T *S = reinterpret_cast<const T *>(Start);
233   const T *E = reinterpret_cast<const T *>(End);
234   std::copy(S, E, std::inserter(*Ints, Ints->end()));
235 }
236
237 ErrorOr<std::unique_ptr<RawCoverage>>
238 RawCoverage::read(const std::string &FileName) {
239   ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
240       MemoryBuffer::getFile(FileName);
241   if (!BufOrErr)
242     return BufOrErr.getError();
243   std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
244   if (Buf->getBufferSize() < 8) {
245     errs() << "File too small (<8): " << Buf->getBufferSize() << '\n';
246     return make_error_code(errc::illegal_byte_sequence);
247   }
248   const FileHeader *Header =
249       reinterpret_cast<const FileHeader *>(Buf->getBufferStart());
250
251   if (Header->Magic != BinCoverageMagic) {
252     errs() << "Wrong magic: " << Header->Magic << '\n';
253     return make_error_code(errc::illegal_byte_sequence);
254   }
255
256   auto Addrs = llvm::make_unique<std::set<uint64_t>>();
257
258   switch (Header->Bitness) {
259   case Bitness64:
260     readInts<uint64_t>(Buf->getBufferStart() + 8, Buf->getBufferEnd(),
261                        Addrs.get());
262     break;
263   case Bitness32:
264     readInts<uint32_t>(Buf->getBufferStart() + 8, Buf->getBufferEnd(),
265                        Addrs.get());
266     break;
267   default:
268     errs() << "Unsupported bitness: " << Header->Bitness << '\n';
269     return make_error_code(errc::illegal_byte_sequence);
270   }
271
272   return std::unique_ptr<RawCoverage>(new RawCoverage(std::move(Addrs)));
273 }
274
275 // Print coverage addresses.
276 raw_ostream &operator<<(raw_ostream &OS, const RawCoverage &CoverageData) {
277   for (auto Addr : *CoverageData.Addrs) {
278     OS << "0x";
279     OS.write_hex(Addr);
280     OS << "\n";
281   }
282   return OS;
283 }
284
285 static raw_ostream &operator<<(raw_ostream &OS, const CoverageStats &Stats) {
286   OS << "all-edges: " << Stats.AllPoints << "\n";
287   OS << "cov-edges: " << Stats.CovPoints << "\n";
288   OS << "all-functions: " << Stats.AllFns << "\n";
289   OS << "cov-functions: " << Stats.CovFns << "\n";
290   return OS;
291 }
292
293 // Helper for writing out JSON. Handles indents and commas using
294 // scope variables for objects and arrays.
295 class JSONWriter {
296 public:
297   JSONWriter(raw_ostream &Out) : OS(Out) {}
298   JSONWriter(const JSONWriter &) = delete;
299   ~JSONWriter() { OS << "\n"; }
300
301   void operator<<(StringRef S) { printJSONStringLiteral(S, OS); }
302
303   // Helper RAII class to output JSON objects.
304   class Object {
305   public:
306     Object(JSONWriter *W, raw_ostream &OS) : W(W), OS(OS) {
307       OS << "{";
308       W->Indent++;
309     }
310     Object(const Object &) = delete;
311     ~Object() {
312       W->Indent--;
313       OS << "\n";
314       W->indent();
315       OS << "}";
316     }
317
318     void key(StringRef Key) {
319       Index++;
320       if (Index > 0)
321         OS << ",";
322       OS << "\n";
323       W->indent();
324       printJSONStringLiteral(Key, OS);
325       OS << " : ";
326     }
327
328   private:
329     JSONWriter *W;
330     raw_ostream &OS;
331     int Index = -1;
332   };
333
334   std::unique_ptr<Object> object() { return make_unique<Object>(this, OS); }
335
336   // Helper RAII class to output JSON arrays.
337   class Array {
338   public:
339     Array(raw_ostream &OS) : OS(OS) { OS << "["; }
340     Array(const Array &) = delete;
341     ~Array() { OS << "]"; }
342     void next() {
343       Index++;
344       if (Index > 0)
345         OS << ", ";
346     }
347
348   private:
349     raw_ostream &OS;
350     int Index = -1;
351   };
352
353   std::unique_ptr<Array> array() { return make_unique<Array>(OS); }
354
355 private:
356   void indent() { OS.indent(Indent * 2); }
357
358   static void printJSONStringLiteral(StringRef S, raw_ostream &OS) {
359     if (S.find('"') == std::string::npos) {
360       OS << "\"" << S << "\"";
361       return;
362     }
363     OS << "\"";
364     for (char Ch : S.bytes()) {
365       if (Ch == '"')
366         OS << "\\";
367       OS << Ch;
368     }
369     OS << "\"";
370   }
371
372   raw_ostream &OS;
373   int Indent = 0;
374 };
375
376 // Output symbolized information for coverage points in JSON.
377 // Format:
378 // {
379 //   '<file_name>' : {
380 //     '<function_name>' : {
381 //       '<point_id'> : '<line_number>:'<column_number'.
382 //          ....
383 //       }
384 //    }
385 // }
386 static void operator<<(JSONWriter &W,
387                        const std::vector<CoveragePoint> &Points) {
388   // Group points by file.
389   auto ByFile(W.object());
390   std::map<std::string, std::vector<const CoveragePoint *>> PointsByFile;
391   for (const auto &Point : Points) {
392     for (const DILineInfo &Loc : Point.Locs) {
393       PointsByFile[Loc.FileName].push_back(&Point);
394     }
395   }
396
397   for (const auto &P : PointsByFile) {
398     std::string FileName = P.first;
399     ByFile->key(FileName);
400
401     // Group points by function.
402     auto ByFn(W.object());
403     std::map<std::string, std::vector<const CoveragePoint *>> PointsByFn;
404     for (auto PointPtr : P.second) {
405       for (const DILineInfo &Loc : PointPtr->Locs) {
406         PointsByFn[Loc.FunctionName].push_back(PointPtr);
407       }
408     }
409
410     for (const auto &P : PointsByFn) {
411       std::string FunctionName = P.first;
412       std::set<std::string> WrittenIds;
413
414       ByFn->key(FunctionName);
415
416       // Output <point_id> : "<line>:<col>".
417       auto ById(W.object());
418       for (const CoveragePoint *Point : P.second) {
419         for (const auto &Loc : Point->Locs) {
420           if (Loc.FileName != FileName || Loc.FunctionName != FunctionName)
421             continue;
422           if (WrittenIds.find(Point->Id) != WrittenIds.end())
423             continue;
424
425           WrittenIds.insert(Point->Id);
426           ById->key(Point->Id);
427           W << (utostr(Loc.Line) + ":" + utostr(Loc.Column));
428         }
429       }
430     }
431   }
432 }
433
434 static void operator<<(JSONWriter &W, const SymbolizedCoverage &C) {
435   auto O(W.object());
436
437   {
438     O->key("covered-points");
439     auto PointsArray(W.array());
440
441     for (const auto &P : C.CoveredIds) {
442       PointsArray->next();
443       W << P;
444     }
445   }
446
447   {
448     if (!C.BinaryHash.empty()) {
449       O->key("binary-hash");
450       W << C.BinaryHash;
451     }
452   }
453
454   {
455     O->key("point-symbol-info");
456     W << C.Points;
457   }
458 }
459
460 static std::string parseScalarString(yaml::Node *N) {
461   SmallString<64> StringStorage;
462   yaml::ScalarNode *S = dyn_cast<yaml::ScalarNode>(N);
463   failIf(!S, "expected string");
464   return S->getValue(StringStorage);
465 }
466
467 std::unique_ptr<SymbolizedCoverage>
468 SymbolizedCoverage::read(const std::string &InputFile) {
469   auto Coverage(make_unique<SymbolizedCoverage>());
470
471   std::map<std::string, CoveragePoint> Points;
472   ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
473       MemoryBuffer::getFile(InputFile);
474   failIfError(BufOrErr);
475
476   SourceMgr SM;
477   yaml::Stream S(**BufOrErr, SM);
478
479   yaml::document_iterator DI = S.begin();
480   failIf(DI == S.end(), "empty document: " + InputFile);
481   yaml::Node *Root = DI->getRoot();
482   failIf(!Root, "expecting root node: " + InputFile);
483   yaml::MappingNode *Top = dyn_cast<yaml::MappingNode>(Root);
484   failIf(!Top, "expecting mapping node: " + InputFile);
485
486   for (auto &KVNode : *Top) {
487     auto Key = parseScalarString(KVNode.getKey());
488
489     if (Key == "covered-points") {
490       yaml::SequenceNode *Points =
491           dyn_cast<yaml::SequenceNode>(KVNode.getValue());
492       failIf(!Points, "expected array: " + InputFile);
493
494       for (auto I = Points->begin(), E = Points->end(); I != E; ++I) {
495         Coverage->CoveredIds.insert(parseScalarString(&*I));
496       }
497     } else if (Key == "binary-hash") {
498       Coverage->BinaryHash = parseScalarString(KVNode.getValue());
499     } else if (Key == "point-symbol-info") {
500       yaml::MappingNode *PointSymbolInfo =
501           dyn_cast<yaml::MappingNode>(KVNode.getValue());
502       failIf(!PointSymbolInfo, "expected mapping node: " + InputFile);
503
504       for (auto &FileKVNode : *PointSymbolInfo) {
505         auto Filename = parseScalarString(FileKVNode.getKey());
506
507         yaml::MappingNode *FileInfo =
508             dyn_cast<yaml::MappingNode>(FileKVNode.getValue());
509         failIf(!FileInfo, "expected mapping node: " + InputFile);
510
511         for (auto &FunctionKVNode : *FileInfo) {
512           auto FunctionName = parseScalarString(FunctionKVNode.getKey());
513
514           yaml::MappingNode *FunctionInfo =
515               dyn_cast<yaml::MappingNode>(FunctionKVNode.getValue());
516           failIf(!FunctionInfo, "expected mapping node: " + InputFile);
517
518           for (auto &PointKVNode : *FunctionInfo) {
519             auto PointId = parseScalarString(PointKVNode.getKey());
520             auto Loc = parseScalarString(PointKVNode.getValue());
521
522             size_t ColonPos = Loc.find(':');
523             failIf(ColonPos == std::string::npos, "expected ':': " + InputFile);
524
525             auto LineStr = Loc.substr(0, ColonPos);
526             auto ColStr = Loc.substr(ColonPos + 1, Loc.size());
527
528             if (Points.find(PointId) == Points.end())
529               Points.insert(std::make_pair(PointId, CoveragePoint(PointId)));
530
531             DILineInfo LineInfo;
532             LineInfo.FileName = Filename;
533             LineInfo.FunctionName = FunctionName;
534             char *End;
535             LineInfo.Line = std::strtoul(LineStr.c_str(), &End, 10);
536             LineInfo.Column = std::strtoul(ColStr.c_str(), &End, 10);
537
538             CoveragePoint *CoveragePoint = &Points.find(PointId)->second;
539             CoveragePoint->Locs.push_back(LineInfo);
540           }
541         }
542       }
543     } else {
544       errs() << "Ignoring unknown key: " << Key << "\n";
545     }
546   }
547
548   for (auto &KV : Points) {
549     Coverage->Points.push_back(KV.second);
550   }
551
552   return Coverage;
553 }
554
555 // ---------- MAIN FUNCTIONALITY ----------
556
557 std::string stripPathPrefix(std::string Path) {
558   if (ClStripPathPrefix.empty())
559     return Path;
560   size_t Pos = Path.find(ClStripPathPrefix);
561   if (Pos == std::string::npos)
562     return Path;
563   return Path.substr(Pos + ClStripPathPrefix.size());
564 }
565
566 static std::unique_ptr<symbolize::LLVMSymbolizer> createSymbolizer() {
567   symbolize::LLVMSymbolizer::Options SymbolizerOptions;
568   SymbolizerOptions.Demangle = ClDemangle;
569   SymbolizerOptions.UseSymbolTable = true;
570   return std::unique_ptr<symbolize::LLVMSymbolizer>(
571       new symbolize::LLVMSymbolizer(SymbolizerOptions));
572 }
573
574 static std::string normalizeFilename(const std::string &FileName) {
575   SmallString<256> S(FileName);
576   sys::path::remove_dots(S, /* remove_dot_dot */ true);
577   return stripPathPrefix(S.str().str());
578 }
579
580 class Blacklists {
581 public:
582   Blacklists()
583       : DefaultBlacklist(createDefaultBlacklist()),
584         UserBlacklist(createUserBlacklist()) {}
585
586   bool isBlacklisted(const DILineInfo &I) {
587     if (DefaultBlacklist && DefaultBlacklist->inSection("fun", I.FunctionName))
588       return true;
589     if (DefaultBlacklist && DefaultBlacklist->inSection("src", I.FileName))
590       return true;
591     if (UserBlacklist && UserBlacklist->inSection("fun", I.FunctionName))
592       return true;
593     if (UserBlacklist && UserBlacklist->inSection("src", I.FileName))
594       return true;
595     return false;
596   }
597
598 private:
599   static std::unique_ptr<SpecialCaseList> createDefaultBlacklist() {
600     if (!ClUseDefaultBlacklist)
601       return std::unique_ptr<SpecialCaseList>();
602     std::unique_ptr<MemoryBuffer> MB =
603         MemoryBuffer::getMemBuffer(DefaultBlacklistStr);
604     std::string Error;
605     auto Blacklist = SpecialCaseList::create(MB.get(), Error);
606     failIfNotEmpty(Error);
607     return Blacklist;
608   }
609
610   static std::unique_ptr<SpecialCaseList> createUserBlacklist() {
611     if (ClBlacklist.empty())
612       return std::unique_ptr<SpecialCaseList>();
613
614     return SpecialCaseList::createOrDie({{ClBlacklist}});
615   }
616   std::unique_ptr<SpecialCaseList> DefaultBlacklist;
617   std::unique_ptr<SpecialCaseList> UserBlacklist;
618 };
619
620 static std::vector<CoveragePoint>
621 getCoveragePoints(const std::string &ObjectFile,
622                   const std::set<uint64_t> &Addrs,
623                   const std::set<uint64_t> &CoveredAddrs) {
624   std::vector<CoveragePoint> Result;
625   auto Symbolizer(createSymbolizer());
626   Blacklists B;
627
628   std::set<std::string> CoveredFiles;
629   if (ClSkipDeadFiles) {
630     for (auto Addr : CoveredAddrs) {
631       auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, Addr);
632       failIfError(LineInfo);
633       CoveredFiles.insert(LineInfo->FileName);
634       auto InliningInfo = Symbolizer->symbolizeInlinedCode(ObjectFile, Addr);
635       failIfError(InliningInfo);
636       for (uint32_t I = 0; I < InliningInfo->getNumberOfFrames(); ++I) {
637         auto FrameInfo = InliningInfo->getFrame(I);
638         CoveredFiles.insert(FrameInfo.FileName);
639       }
640     }
641   }
642
643   for (auto Addr : Addrs) {
644     std::set<DILineInfo> Infos; // deduplicate debug info.
645
646     auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, Addr);
647     failIfError(LineInfo);
648     if (ClSkipDeadFiles &&
649         CoveredFiles.find(LineInfo->FileName) == CoveredFiles.end())
650       continue;
651     LineInfo->FileName = normalizeFilename(LineInfo->FileName);
652     if (B.isBlacklisted(*LineInfo))
653       continue;
654
655     auto Id = utohexstr(Addr, true);
656     auto Point = CoveragePoint(Id);
657     Infos.insert(*LineInfo);
658     Point.Locs.push_back(*LineInfo);
659
660     auto InliningInfo = Symbolizer->symbolizeInlinedCode(ObjectFile, Addr);
661     failIfError(InliningInfo);
662     for (uint32_t I = 0; I < InliningInfo->getNumberOfFrames(); ++I) {
663       auto FrameInfo = InliningInfo->getFrame(I);
664       if (ClSkipDeadFiles &&
665           CoveredFiles.find(FrameInfo.FileName) == CoveredFiles.end())
666         continue;
667       FrameInfo.FileName = normalizeFilename(FrameInfo.FileName);
668       if (B.isBlacklisted(FrameInfo))
669         continue;
670       if (Infos.find(FrameInfo) == Infos.end()) {
671         Infos.insert(FrameInfo);
672         Point.Locs.push_back(FrameInfo);
673       }
674     }
675
676     Result.push_back(Point);
677   }
678
679   return Result;
680 }
681
682 static bool isCoveragePointSymbol(StringRef Name) {
683   return Name == "__sanitizer_cov" || Name == "__sanitizer_cov_with_check" ||
684          Name == "__sanitizer_cov_trace_func_enter" ||
685          Name == "__sanitizer_cov_trace_pc_guard" ||
686          // Mac has '___' prefix
687          Name == "___sanitizer_cov" || Name == "___sanitizer_cov_with_check" ||
688          Name == "___sanitizer_cov_trace_func_enter" ||
689          Name == "___sanitizer_cov_trace_pc_guard";
690 }
691
692 // Locate __sanitizer_cov* function addresses inside the stubs table on MachO.
693 static void findMachOIndirectCovFunctions(const object::MachOObjectFile &O,
694                                           std::set<uint64_t> *Result) {
695   MachO::dysymtab_command Dysymtab = O.getDysymtabLoadCommand();
696   MachO::symtab_command Symtab = O.getSymtabLoadCommand();
697
698   for (const auto &Load : O.load_commands()) {
699     if (Load.C.cmd == MachO::LC_SEGMENT_64) {
700       MachO::segment_command_64 Seg = O.getSegment64LoadCommand(Load);
701       for (unsigned J = 0; J < Seg.nsects; ++J) {
702         MachO::section_64 Sec = O.getSection64(Load, J);
703
704         uint32_t SectionType = Sec.flags & MachO::SECTION_TYPE;
705         if (SectionType == MachO::S_SYMBOL_STUBS) {
706           uint32_t Stride = Sec.reserved2;
707           uint32_t Cnt = Sec.size / Stride;
708           uint32_t N = Sec.reserved1;
709           for (uint32_t J = 0; J < Cnt && N + J < Dysymtab.nindirectsyms; J++) {
710             uint32_t IndirectSymbol =
711                 O.getIndirectSymbolTableEntry(Dysymtab, N + J);
712             uint64_t Addr = Sec.addr + J * Stride;
713             if (IndirectSymbol < Symtab.nsyms) {
714               object::SymbolRef Symbol = *(O.getSymbolByIndex(IndirectSymbol));
715               Expected<StringRef> Name = Symbol.getName();
716               failIfError(Name);
717               if (isCoveragePointSymbol(Name.get())) {
718                 Result->insert(Addr);
719               }
720             }
721           }
722         }
723       }
724     }
725     if (Load.C.cmd == MachO::LC_SEGMENT) {
726       errs() << "ERROR: 32 bit MachO binaries not supported\n";
727     }
728   }
729 }
730
731 // Locate __sanitizer_cov* function addresses that are used for coverage
732 // reporting.
733 static std::set<uint64_t>
734 findSanitizerCovFunctions(const object::ObjectFile &O) {
735   std::set<uint64_t> Result;
736
737   for (const object::SymbolRef &Symbol : O.symbols()) {
738     Expected<uint64_t> AddressOrErr = Symbol.getAddress();
739     failIfError(AddressOrErr);
740     uint64_t Address = AddressOrErr.get();
741
742     Expected<StringRef> NameOrErr = Symbol.getName();
743     failIfError(NameOrErr);
744     StringRef Name = NameOrErr.get();
745
746     if (!(Symbol.getFlags() & object::BasicSymbolRef::SF_Undefined) &&
747         isCoveragePointSymbol(Name)) {
748       Result.insert(Address);
749     }
750   }
751
752   if (const auto *CO = dyn_cast<object::COFFObjectFile>(&O)) {
753     for (const object::ExportDirectoryEntryRef &Export :
754          CO->export_directories()) {
755       uint32_t RVA;
756       std::error_code EC = Export.getExportRVA(RVA);
757       failIfError(EC);
758
759       StringRef Name;
760       EC = Export.getSymbolName(Name);
761       failIfError(EC);
762
763       if (isCoveragePointSymbol(Name))
764         Result.insert(CO->getImageBase() + RVA);
765     }
766   }
767
768   if (const auto *MO = dyn_cast<object::MachOObjectFile>(&O)) {
769     findMachOIndirectCovFunctions(*MO, &Result);
770   }
771
772   return Result;
773 }
774
775 // Locate addresses of all coverage points in a file. Coverage point
776 // is defined as the 'address of instruction following __sanitizer_cov
777 // call - 1'.
778 static void getObjectCoveragePoints(const object::ObjectFile &O,
779                                     std::set<uint64_t> *Addrs) {
780   Triple TheTriple("unknown-unknown-unknown");
781   TheTriple.setArch(Triple::ArchType(O.getArch()));
782   auto TripleName = TheTriple.getTriple();
783
784   std::string Error;
785   const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
786   failIfNotEmpty(Error);
787
788   std::unique_ptr<const MCSubtargetInfo> STI(
789       TheTarget->createMCSubtargetInfo(TripleName, "", ""));
790   failIfEmpty(STI, "no subtarget info for target " + TripleName);
791
792   std::unique_ptr<const MCRegisterInfo> MRI(
793       TheTarget->createMCRegInfo(TripleName));
794   failIfEmpty(MRI, "no register info for target " + TripleName);
795
796   std::unique_ptr<const MCAsmInfo> AsmInfo(
797       TheTarget->createMCAsmInfo(*MRI, TripleName));
798   failIfEmpty(AsmInfo, "no asm info for target " + TripleName);
799
800   std::unique_ptr<const MCObjectFileInfo> MOFI(new MCObjectFileInfo);
801   MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get());
802   std::unique_ptr<MCDisassembler> DisAsm(
803       TheTarget->createMCDisassembler(*STI, Ctx));
804   failIfEmpty(DisAsm, "no disassembler info for target " + TripleName);
805
806   std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
807   failIfEmpty(MII, "no instruction info for target " + TripleName);
808
809   std::unique_ptr<const MCInstrAnalysis> MIA(
810       TheTarget->createMCInstrAnalysis(MII.get()));
811   failIfEmpty(MIA, "no instruction analysis info for target " + TripleName);
812
813   auto SanCovAddrs = findSanitizerCovFunctions(O);
814   if (SanCovAddrs.empty())
815     fail("__sanitizer_cov* functions not found");
816
817   for (object::SectionRef Section : O.sections()) {
818     if (Section.isVirtual() || !Section.isText()) // llvm-objdump does the same.
819       continue;
820     uint64_t SectionAddr = Section.getAddress();
821     uint64_t SectSize = Section.getSize();
822     if (!SectSize)
823       continue;
824
825     StringRef BytesStr;
826     failIfError(Section.getContents(BytesStr));
827     ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(BytesStr.data()),
828                             BytesStr.size());
829
830     for (uint64_t Index = 0, Size = 0; Index < Section.getSize();
831          Index += Size) {
832       MCInst Inst;
833       if (!DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
834                                   SectionAddr + Index, nulls(), nulls())) {
835         if (Size == 0)
836           Size = 1;
837         continue;
838       }
839       uint64_t Addr = Index + SectionAddr;
840       // Sanitizer coverage uses the address of the next instruction - 1.
841       uint64_t CovPoint = Addr + Size - 1;
842       uint64_t Target;
843       if (MIA->isCall(Inst) &&
844           MIA->evaluateBranch(Inst, SectionAddr + Index, Size, Target) &&
845           SanCovAddrs.find(Target) != SanCovAddrs.end())
846         Addrs->insert(CovPoint);
847     }
848   }
849 }
850
851 static void
852 visitObjectFiles(const object::Archive &A,
853                  function_ref<void(const object::ObjectFile &)> Fn) {
854   Error Err = Error::success();
855   for (auto &C : A.children(Err)) {
856     Expected<std::unique_ptr<object::Binary>> ChildOrErr = C.getAsBinary();
857     failIfError(ChildOrErr);
858     if (auto *O = dyn_cast<object::ObjectFile>(&*ChildOrErr.get()))
859       Fn(*O);
860     else
861       failIfError(object::object_error::invalid_file_type);
862   }
863   failIfError(std::move(Err));
864 }
865
866 static void
867 visitObjectFiles(const std::string &FileName,
868                  function_ref<void(const object::ObjectFile &)> Fn) {
869   Expected<object::OwningBinary<object::Binary>> BinaryOrErr =
870       object::createBinary(FileName);
871   if (!BinaryOrErr)
872     failIfError(BinaryOrErr);
873
874   object::Binary &Binary = *BinaryOrErr.get().getBinary();
875   if (object::Archive *A = dyn_cast<object::Archive>(&Binary))
876     visitObjectFiles(*A, Fn);
877   else if (object::ObjectFile *O = dyn_cast<object::ObjectFile>(&Binary))
878     Fn(*O);
879   else
880     failIfError(object::object_error::invalid_file_type);
881 }
882
883 static std::set<uint64_t>
884 findSanitizerCovFunctions(const std::string &FileName) {
885   std::set<uint64_t> Result;
886   visitObjectFiles(FileName, [&](const object::ObjectFile &O) {
887     auto Addrs = findSanitizerCovFunctions(O);
888     Result.insert(Addrs.begin(), Addrs.end());
889   });
890   return Result;
891 }
892
893 // Locate addresses of all coverage points in a file. Coverage point
894 // is defined as the 'address of instruction following __sanitizer_cov
895 // call - 1'.
896 static std::set<uint64_t> findCoveragePointAddrs(const std::string &FileName) {
897   std::set<uint64_t> Result;
898   visitObjectFiles(FileName, [&](const object::ObjectFile &O) {
899     getObjectCoveragePoints(O, &Result);
900   });
901   return Result;
902 }
903
904 static void printCovPoints(const std::string &ObjFile, raw_ostream &OS) {
905   for (uint64_t Addr : findCoveragePointAddrs(ObjFile)) {
906     OS << "0x";
907     OS.write_hex(Addr);
908     OS << "\n";
909   }
910 }
911
912 static ErrorOr<bool> isCoverageFile(const std::string &FileName) {
913   auto ShortFileName = llvm::sys::path::filename(FileName);
914   if (!SancovFileRegex.match(ShortFileName))
915     return false;
916
917   ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
918       MemoryBuffer::getFile(FileName);
919   if (!BufOrErr) {
920     errs() << "Warning: " << BufOrErr.getError().message() << "("
921            << BufOrErr.getError().value()
922            << "), filename: " << llvm::sys::path::filename(FileName) << "\n";
923     return BufOrErr.getError();
924   }
925   std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
926   if (Buf->getBufferSize() < 8) {
927     return false;
928   }
929   const FileHeader *Header =
930       reinterpret_cast<const FileHeader *>(Buf->getBufferStart());
931   return Header->Magic == BinCoverageMagic;
932 }
933
934 static bool isSymbolizedCoverageFile(const std::string &FileName) {
935   auto ShortFileName = llvm::sys::path::filename(FileName);
936   return SymcovFileRegex.match(ShortFileName);
937 }
938
939 static std::unique_ptr<SymbolizedCoverage>
940 symbolize(const RawCoverage &Data, const std::string ObjectFile) {
941   auto Coverage = make_unique<SymbolizedCoverage>();
942
943   ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
944       MemoryBuffer::getFile(ObjectFile);
945   failIfError(BufOrErr);
946   SHA1 Hasher;
947   Hasher.update((*BufOrErr)->getBuffer());
948   Coverage->BinaryHash = toHex(Hasher.final());
949
950   Blacklists B;
951   auto Symbolizer(createSymbolizer());
952
953   for (uint64_t Addr : *Data.Addrs) {
954     auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, Addr);
955     failIfError(LineInfo);
956     if (B.isBlacklisted(*LineInfo))
957       continue;
958
959     Coverage->CoveredIds.insert(utohexstr(Addr, true));
960   }
961
962   std::set<uint64_t> AllAddrs = findCoveragePointAddrs(ObjectFile);
963   if (!std::includes(AllAddrs.begin(), AllAddrs.end(), Data.Addrs->begin(),
964                      Data.Addrs->end())) {
965     fail("Coverage points in binary and .sancov file do not match.");
966   }
967   Coverage->Points = getCoveragePoints(ObjectFile, AllAddrs, *Data.Addrs);
968   return Coverage;
969 }
970
971 struct FileFn {
972   bool operator<(const FileFn &RHS) const {
973     return std::tie(FileName, FunctionName) <
974            std::tie(RHS.FileName, RHS.FunctionName);
975   }
976
977   std::string FileName;
978   std::string FunctionName;
979 };
980
981 static std::set<FileFn>
982 computeFunctions(const std::vector<CoveragePoint> &Points) {
983   std::set<FileFn> Fns;
984   for (const auto &Point : Points) {
985     for (const auto &Loc : Point.Locs) {
986       Fns.insert(FileFn{Loc.FileName, Loc.FunctionName});
987     }
988   }
989   return Fns;
990 }
991
992 static std::set<FileFn>
993 computeNotCoveredFunctions(const SymbolizedCoverage &Coverage) {
994   auto Fns = computeFunctions(Coverage.Points);
995
996   for (const auto &Point : Coverage.Points) {
997     if (Coverage.CoveredIds.find(Point.Id) == Coverage.CoveredIds.end())
998       continue;
999
1000     for (const auto &Loc : Point.Locs) {
1001       Fns.erase(FileFn{Loc.FileName, Loc.FunctionName});
1002     }
1003   }
1004
1005   return Fns;
1006 }
1007
1008 static std::set<FileFn>
1009 computeCoveredFunctions(const SymbolizedCoverage &Coverage) {
1010   auto AllFns = computeFunctions(Coverage.Points);
1011   std::set<FileFn> Result;
1012
1013   for (const auto &Point : Coverage.Points) {
1014     if (Coverage.CoveredIds.find(Point.Id) == Coverage.CoveredIds.end())
1015       continue;
1016
1017     for (const auto &Loc : Point.Locs) {
1018       Result.insert(FileFn{Loc.FileName, Loc.FunctionName});
1019     }
1020   }
1021
1022   return Result;
1023 }
1024
1025 typedef std::map<FileFn, std::pair<uint32_t, uint32_t>> FunctionLocs;
1026 // finds first location in a file for each function.
1027 static FunctionLocs resolveFunctions(const SymbolizedCoverage &Coverage,
1028                                      const std::set<FileFn> &Fns) {
1029   FunctionLocs Result;
1030   for (const auto &Point : Coverage.Points) {
1031     for (const auto &Loc : Point.Locs) {
1032       FileFn Fn = FileFn{Loc.FileName, Loc.FunctionName};
1033       if (Fns.find(Fn) == Fns.end())
1034         continue;
1035
1036       auto P = std::make_pair(Loc.Line, Loc.Column);
1037       auto I = Result.find(Fn);
1038       if (I == Result.end() || I->second > P) {
1039         Result[Fn] = P;
1040       }
1041     }
1042   }
1043   return Result;
1044 }
1045
1046 static void printFunctionLocs(const FunctionLocs &FnLocs, raw_ostream &OS) {
1047   for (const auto &P : FnLocs) {
1048     OS << stripPathPrefix(P.first.FileName) << ":" << P.second.first << " "
1049        << P.first.FunctionName << "\n";
1050   }
1051 }
1052 CoverageStats computeStats(const SymbolizedCoverage &Coverage) {
1053   CoverageStats Stats = {Coverage.Points.size(), Coverage.CoveredIds.size(),
1054                          computeFunctions(Coverage.Points).size(),
1055                          computeCoveredFunctions(Coverage).size()};
1056   return Stats;
1057 }
1058
1059 // Print list of covered functions.
1060 // Line format: <file_name>:<line> <function_name>
1061 static void printCoveredFunctions(const SymbolizedCoverage &CovData,
1062                                   raw_ostream &OS) {
1063   auto CoveredFns = computeCoveredFunctions(CovData);
1064   printFunctionLocs(resolveFunctions(CovData, CoveredFns), OS);
1065 }
1066
1067 // Print list of not covered functions.
1068 // Line format: <file_name>:<line> <function_name>
1069 static void printNotCoveredFunctions(const SymbolizedCoverage &CovData,
1070                                      raw_ostream &OS) {
1071   auto NotCoveredFns = computeNotCoveredFunctions(CovData);
1072   printFunctionLocs(resolveFunctions(CovData, NotCoveredFns), OS);
1073 }
1074
1075 // Read list of files and merges their coverage info.
1076 static void readAndPrintRawCoverage(const std::vector<std::string> &FileNames,
1077                                     raw_ostream &OS) {
1078   std::vector<std::unique_ptr<RawCoverage>> Covs;
1079   for (const auto &FileName : FileNames) {
1080     auto Cov = RawCoverage::read(FileName);
1081     if (!Cov)
1082       continue;
1083     OS << *Cov.get();
1084   }
1085 }
1086
1087 static std::unique_ptr<SymbolizedCoverage>
1088 merge(const std::vector<std::unique_ptr<SymbolizedCoverage>> &Coverages) {
1089   auto Result = make_unique<SymbolizedCoverage>();
1090
1091   for (size_t I = 0; I < Coverages.size(); ++I) {
1092     const SymbolizedCoverage &Coverage = *Coverages[I];
1093     std::string Prefix;
1094     if (Coverages.size() > 1) {
1095       // prefix is not needed when there's only one file.
1096       Prefix = utostr(I);
1097     }
1098
1099     for (const auto &Id : Coverage.CoveredIds) {
1100       Result->CoveredIds.insert(Prefix + Id);
1101     }
1102
1103     for (const auto &CovPoint : Coverage.Points) {
1104       CoveragePoint NewPoint(CovPoint);
1105       NewPoint.Id = Prefix + CovPoint.Id;
1106       Result->Points.push_back(NewPoint);
1107     }
1108   }
1109
1110   if (Coverages.size() == 1) {
1111     Result->BinaryHash = Coverages[0]->BinaryHash;
1112   }
1113
1114   return Result;
1115 }
1116
1117 static std::unique_ptr<SymbolizedCoverage>
1118 readSymbolizeAndMergeCmdArguments(std::vector<std::string> FileNames) {
1119   std::vector<std::unique_ptr<SymbolizedCoverage>> Coverages;
1120
1121   {
1122     // Short name => file name.
1123     std::map<std::string, std::string> ObjFiles;
1124     std::string FirstObjFile;
1125     std::set<std::string> CovFiles;
1126
1127     // Partition input values into coverage/object files.
1128     for (const auto &FileName : FileNames) {
1129       if (isSymbolizedCoverageFile(FileName)) {
1130         Coverages.push_back(SymbolizedCoverage::read(FileName));
1131       }
1132
1133       auto ErrorOrIsCoverage = isCoverageFile(FileName);
1134       if (!ErrorOrIsCoverage)
1135         continue;
1136       if (ErrorOrIsCoverage.get()) {
1137         CovFiles.insert(FileName);
1138       } else {
1139         auto ShortFileName = llvm::sys::path::filename(FileName);
1140         if (ObjFiles.find(ShortFileName) != ObjFiles.end()) {
1141           fail("Duplicate binary file with a short name: " + ShortFileName);
1142         }
1143
1144         ObjFiles[ShortFileName] = FileName;
1145         if (FirstObjFile.empty())
1146           FirstObjFile = FileName;
1147       }
1148     }
1149
1150     SmallVector<StringRef, 2> Components;
1151
1152     // Object file => list of corresponding coverage file names.
1153     std::map<std::string, std::vector<std::string>> CoverageByObjFile;
1154     for (const auto &FileName : CovFiles) {
1155       auto ShortFileName = llvm::sys::path::filename(FileName);
1156       auto Ok = SancovFileRegex.match(ShortFileName, &Components);
1157       if (!Ok) {
1158         fail("Can't match coverage file name against "
1159              "<module_name>.<pid>.sancov pattern: " +
1160              FileName);
1161       }
1162
1163       auto Iter = ObjFiles.find(Components[1]);
1164       if (Iter == ObjFiles.end()) {
1165         fail("Object file for coverage not found: " + FileName);
1166       }
1167
1168       CoverageByObjFile[Iter->second].push_back(FileName);
1169     };
1170
1171     // Read raw coverage and symbolize it.
1172     for (const auto &Pair : CoverageByObjFile) {
1173       if (findSanitizerCovFunctions(Pair.first).empty()) {
1174         errs()
1175             << "Ignoring " << Pair.first
1176             << " and its coverage because  __sanitizer_cov* functions were not "
1177                "found.\n";
1178         continue;
1179       }
1180
1181       for (const std::string &CoverageFile : Pair.second) {
1182         auto DataOrError = RawCoverage::read(CoverageFile);
1183         failIfError(DataOrError);
1184         Coverages.push_back(symbolize(*DataOrError.get(), Pair.first));
1185       }
1186     }
1187   }
1188
1189   return merge(Coverages);
1190 }
1191
1192 } // namespace
1193
1194 int main(int Argc, char **Argv) {
1195   // Print stack trace if we signal out.
1196   sys::PrintStackTraceOnErrorSignal(Argv[0]);
1197   PrettyStackTraceProgram X(Argc, Argv);
1198   llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
1199
1200   llvm::InitializeAllTargetInfos();
1201   llvm::InitializeAllTargetMCs();
1202   llvm::InitializeAllDisassemblers();
1203
1204   cl::ParseCommandLineOptions(Argc, Argv, 
1205       "Sanitizer Coverage Processing Tool (sancov)\n\n"
1206       "  This tool can extract various coverage-related information from: \n"
1207       "  coverage-instrumented binary files, raw .sancov files and their "
1208       "symbolized .symcov version.\n"
1209       "  Depending on chosen action the tool expects different input files:\n"
1210       "    -print-coverage-pcs     - coverage-instrumented binary files\n"
1211       "    -print-coverage         - .sancov files\n"
1212       "    <other actions>         - .sancov files & corresponding binary "
1213       "files, .symcov files\n"
1214       );
1215
1216   // -print doesn't need object files.
1217   if (Action == PrintAction) {
1218     readAndPrintRawCoverage(ClInputFiles, outs());
1219     return 0;
1220   } else if (Action == PrintCovPointsAction) {
1221     // -print-coverage-points doesn't need coverage files.
1222     for (const std::string &ObjFile : ClInputFiles) {
1223       printCovPoints(ObjFile, outs());
1224     }
1225     return 0;
1226   }
1227
1228   auto Coverage = readSymbolizeAndMergeCmdArguments(ClInputFiles);
1229   failIf(!Coverage, "No valid coverage files given.");
1230
1231   switch (Action) {
1232   case CoveredFunctionsAction: {
1233     printCoveredFunctions(*Coverage, outs());
1234     return 0;
1235   }
1236   case NotCoveredFunctionsAction: {
1237     printNotCoveredFunctions(*Coverage, outs());
1238     return 0;
1239   }
1240   case StatsAction: {
1241     outs() << computeStats(*Coverage);
1242     return 0;
1243   }
1244   case MergeAction:
1245   case SymbolizeAction: { // merge & symbolize are synonims.
1246     JSONWriter W(outs());
1247     W << *Coverage;
1248     return 0;
1249   }
1250   case HtmlReportAction:
1251     errs() << "-html-report option is removed: "
1252               "use -symbolize & coverage-report-server.py instead\n";
1253     return 1;
1254   case PrintAction:
1255   case PrintCovPointsAction:
1256     llvm_unreachable("unsupported action");
1257   }
1258 }