]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/xray/xray_utils.cc
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / xray / xray_utils.cc
1 //===-- xray_utils.cc -------------------------------------------*- C++ -*-===//
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 part of XRay, a dynamic runtime instrumentation system.
11 //
12 //===----------------------------------------------------------------------===//
13 #include "xray_utils.h"
14
15 #include "sanitizer_common/sanitizer_common.h"
16 #include "xray_defs.h"
17 #include "xray_flags.h"
18 #include <cstdio>
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <iterator>
22 #include <stdlib.h>
23 #include <sys/types.h>
24 #include <tuple>
25 #include <unistd.h>
26 #include <utility>
27
28 namespace __xray {
29
30 void printToStdErr(const char *Buffer) XRAY_NEVER_INSTRUMENT {
31   fprintf(stderr, "%s", Buffer);
32 }
33
34 void retryingWriteAll(int Fd, const char *Begin, const char *End) XRAY_NEVER_INSTRUMENT {
35   if (Begin == End)
36     return;
37   auto TotalBytes = std::distance(Begin, End);
38   while (auto Written = write(Fd, Begin, TotalBytes)) {
39     if (Written < 0) {
40       if (errno == EINTR)
41         continue; // Try again.
42       Report("Failed to write; errno = %d\n", errno);
43       return;
44     }
45     TotalBytes -= Written;
46     if (TotalBytes == 0)
47       break;
48     Begin += Written;
49   }
50 }
51
52 std::pair<ssize_t, bool> retryingReadSome(int Fd, char *Begin,
53                                           char *End) XRAY_NEVER_INSTRUMENT {
54   auto BytesToRead = std::distance(Begin, End);
55   ssize_t BytesRead;
56   ssize_t TotalBytesRead = 0;
57   while (BytesToRead && (BytesRead = read(Fd, Begin, BytesToRead))) {
58     if (BytesRead == -1) {
59       if (errno == EINTR)
60         continue;
61       Report("Read error; errno = %d\n", errno);
62       return std::make_pair(TotalBytesRead, false);
63     }
64
65     TotalBytesRead += BytesRead;
66     BytesToRead -= BytesRead;
67     Begin += BytesRead;
68   }
69   return std::make_pair(TotalBytesRead, true);
70 }
71
72 bool readValueFromFile(const char *Filename,
73                        long long *Value) XRAY_NEVER_INSTRUMENT {
74   int Fd = open(Filename, O_RDONLY | O_CLOEXEC);
75   if (Fd == -1)
76     return false;
77   static constexpr size_t BufSize = 256;
78   char Line[BufSize] = {};
79   ssize_t BytesRead;
80   bool Success;
81   std::tie(BytesRead, Success) = retryingReadSome(Fd, Line, Line + BufSize);
82   if (!Success)
83     return false;
84   close(Fd);
85   const char *End = nullptr;
86   long long Tmp = internal_simple_strtoll(Line, &End, 10);
87   bool Result = false;
88   if (Line[0] != '\0' && (*End == '\n' || *End == '\0')) {
89     *Value = Tmp;
90     Result = true;
91   }
92   return Result;
93 }
94
95 int getLogFD() XRAY_NEVER_INSTRUMENT {
96   // Open a temporary file once for the log.
97   char TmpFilename[256] = {};
98   char TmpWildcardPattern[] = "XXXXXX";
99   auto **Argv = GetArgv();
100   const char *Progname = !Argv ? "(unknown)" : Argv[0];
101   const char *LastSlash = internal_strrchr(Progname, '/');
102
103   if (LastSlash != nullptr)
104     Progname = LastSlash + 1;
105
106   const int HalfLength = sizeof(TmpFilename) / 2 - sizeof(TmpWildcardPattern);
107   int NeededLength = internal_snprintf(
108       TmpFilename, sizeof(TmpFilename), "%.*s%.*s.%s", HalfLength,
109       flags()->xray_logfile_base, HalfLength, Progname, TmpWildcardPattern);
110   if (NeededLength > int(sizeof(TmpFilename))) {
111     Report("XRay log file name too long (%d): %s\n", NeededLength, TmpFilename);
112     return -1;
113   }
114   int Fd = mkstemp(TmpFilename);
115   if (Fd == -1) {
116     Report("XRay: Failed opening temporary file '%s'; not logging events.\n",
117            TmpFilename);
118     return -1;
119   }
120   if (Verbosity())
121     Report("XRay: Log file in '%s'\n", TmpFilename);
122
123   return Fd;
124 }
125
126 } // namespace __xray