Skip to content

Commit 0add92f

Browse files
DianaChenigcbot
authored andcommitted
IGA fix for Fedora build and several code cleanup
- Fix build break on Fedora - Improved the iga::FixupPath - Fix possible nullptr - Minor fix for send decoder
1 parent d52ed1b commit 0add92f

File tree

7 files changed

+182
-29
lines changed

7 files changed

+182
-29
lines changed

visa/iga/IGAExe/io.hpp

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ SPDX-License-Identifier: MIT
1313
#include <fstream>
1414
#include <iostream>
1515
#include <locale>
16+
#include <string>
1617
#include <vector>
1718

1819
#include "fatal.hpp"
1920
#include "system.hpp"
2021

2122

2223
static inline void readBinaryStream(
23-
const char *streamName,
24+
const std::string &streamName,
2425
std::istream &is,
2526
std::vector<unsigned char> &bin)
2627
{
@@ -33,7 +34,8 @@ static inline void readBinaryStream(
3334
}
3435
bin.push_back((char)chr);
3536
}
36-
fatalExitWithMessage(streamName, ": error reading ");
37+
fatalExitWithMessage(
38+
streamName, ": error reading (", iga::LastErrorString(), ")");
3739
}
3840

3941
#define IGA_STDIN_FILENAME std::string("std::cin")
@@ -47,84 +49,91 @@ static inline std::vector<unsigned char> readBinaryStreamStdin()
4749
}
4850

4951
static inline void readBinaryFile(
50-
const char *fileName, std::vector<unsigned char> &bin)
52+
const std::string &fileName, std::vector<unsigned char> &bin)
5153
{
5254
std::ifstream is(fileName, std::ios::binary);
53-
if (!is.is_open()) {
54-
fatalExitWithMessage(fileName, ": failed to open file");
55+
if (!is.good()) {
56+
fatalExitWithMessage(
57+
fileName, ": failed to open file (", iga::LastErrorString(), ")");
5558
}
5659
readBinaryStream(fileName, is, bin);
5760
}
5861

5962
static inline std::string readTextStream(
60-
const char *streamName,
63+
const std::string &streamName,
6164
std::istream &is)
6265
{
6366
std::string s;
6467
is.clear();
6568
s.append(std::istreambuf_iterator<char>(is),
6669
std::istreambuf_iterator<char>());
6770
if (!is.good()) {
68-
fatalExitWithMessage(streamName, ": error reading");
71+
fatalExitWithMessage(
72+
streamName, ": error reading (", iga::LastErrorString(), ")");
6973
}
7074
return s;
7175
}
7276

73-
static inline std::string readTextFile(
74-
const char *fileName)
77+
static inline std::string readTextFile(const std::string &fileName)
7578
{
7679
std::ifstream file(fileName);
7780
if (!file.good()) {
78-
fatalExitWithMessage(fileName, ": failed to open file");
81+
fatalExitWithMessage(
82+
fileName, ": failed to open file (", iga::LastErrorString(), ")");
7983
}
80-
return readTextStream(fileName,file);
84+
return readTextStream(fileName, file);
8185
}
8286

8387
static inline void writeTextStream(
84-
const char *streamName, std::ostream &os, const char *output)
88+
const std::string &streamName, std::ostream &os, const char *output)
8589
{
8690
os.clear();
8791
os << output;
8892
if (!os.good()) {
89-
fatalExitWithMessage(streamName, ": error writing");
93+
fatalExitWithMessage(
94+
streamName, ": error writing (", iga::LastErrorString(), ")");
9095
}
9196
}
9297

93-
static inline void writeTextFile(const char *fileName, const char *output)
98+
static inline void writeTextFile(
99+
const std::string &fileName, const char *output)
94100
{
95101
std::ofstream file(fileName);
96102
if (!file.good()) {
97-
fatalExitWithMessage(fileName, ": failed to open file");
103+
fatalExitWithMessage(
104+
fileName, ": failed to open file (", iga::LastErrorString(), ")");
98105
}
99106
writeTextStream(fileName, file, output);
100107
}
101108

102109
static inline void writeBinaryStream(
103-
const char *streamName,
110+
const std::string &streamName,
104111
std::ostream &os,
105112
const void *bits,
106113
size_t bitsLen)
107114
{
108115
os.clear();
109116
os.write((const char *)bits, bitsLen);
110117
if (!os.good()) {
111-
fatalExitWithMessage(streamName, ": error writing stream");
118+
fatalExitWithMessage(
119+
streamName, ": error writing stream (", iga::LastErrorString(), ")");
112120
}
113121
}
114122

115123
static inline void writeBinaryFile(
116-
const char *fileName,
117-
const void *bits,
118-
size_t bitsLen)
124+
const std::string &fileName,
125+
const void *bits,
126+
size_t bitsLen)
119127
{
120-
std::ofstream file(fileName,std::ios::binary);
128+
std::ofstream file(fileName, std::ios::binary);
121129
if (!file.good()) {
122-
fatalExitWithMessage(fileName, ": failed to open file");
130+
fatalExitWithMessage(
131+
fileName, ": failed to open file (", iga::LastErrorString(), ")");
123132
}
124-
writeBinaryStream(fileName,file,bits,bitsLen);
133+
writeBinaryStream(fileName, file, bits, bitsLen);
125134
}
126135

127-
static inline bool doesFileExist(const char *fileName) {
136+
static inline bool doesFileExist(const std::string &fileName) {
128137
return iga::DoesFileExist(fileName);
129138
}
130139

visa/iga/IGALibrary/IR/RegDeps.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ SPDX-License-Identifier: MIT
1010
#include "../asserts.hpp"
1111
#include "../bits.hpp"
1212

13+
#include <cstring>
1314
#include <limits>
1415
#include <sstream>
15-
#include <cstring>
1616

1717
using namespace iga;
1818

visa/iga/IGALibrary/api/kv.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ uint32_t kv_get_send_descs(
365365
return n;
366366
}
367367

368+
368369
void kv_get_send_indirect_descs(
369370
const kv_t *kv, int32_t pc,
370371
uint8_t *ex_desc_reg, uint8_t *ex_desc_subreg,
@@ -396,6 +397,7 @@ void kv_get_send_indirect_descs(
396397
}
397398
}
398399

400+
399401
/******************** KernelView analysis APIs *******************************/
400402
static const Instruction *getInstruction(const kv_t *kv, int32_t pc)
401403
{

visa/iga/IGALibrary/api/kv.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,13 @@ IGA_API uint32_t kv_get_send_descs(
212212
uint32_t *ex_desc,
213213
uint32_t *desc);
214214

215+
216+
/*
217+
* Returns the indirect descriptor registers for a send message.
218+
* The function fails silently if the PC is invalid or a nullptr is passed.
219+
* Registers are assigned KV_INVALID_REG on other failures otherwise they
220+
* hold the index register and subregister (e.g. a0.2) would have 0 and 2.
221+
*/
215222
IGA_API void kv_get_send_indirect_descs(
216223
const kv_t *kv,
217224
int32_t pc,

visa/iga/IGALibrary/api/kv.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,23 @@ class KernelView
279279
return kv_get_send_descs(m_kv, pc, ex_desc, desc);
280280
}
281281

282+
282283
/*************************Analysis APIs **********************************/
283284

284285
// Returns the number of expicit sources this instruction has.
285286
int32_t getNumberOfSources(int32_t pc) const {
286287
return kv_get_number_sources(m_kv, pc);
287288
}
288289

290+
// Determines if the given send instruction is on ExBSO mode.
291+
// Return 1 if true, 0 if false
292+
// Return -1 if not success
293+
int32_t getSendExBso(int32_t pc) const {
294+
int32_t exbso = -1;
295+
if (kv_get_send_exbso(m_kv, pc, &exbso) != kv_status_t::KV_SUCCESS)
296+
return -1;
297+
return exbso;
298+
}
289299

290300
// Fetches the message type for send/sends instructions.
291301
//

visa/iga/IGALibrary/system.cpp

Lines changed: 119 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ SPDX-License-Identifier: MIT
66
77
============================= end_copyright_notice ===========================*/
88

9+
#include "asserts.hpp"
910
#include "system.hpp"
1011

1112
#ifdef _WIN32
@@ -23,8 +24,14 @@ SPDX-License-Identifier: MIT
2324
#include <sys/types.h>
2425
#include <sys/stat.h>
2526
#include <unistd.h>
27+
#include <errno.h>
28+
#include <string.h> // strerror_r
2629
#endif
30+
#include <algorithm>
2731
#include <iostream>
32+
#include <sstream>
33+
#include <string>
34+
#include <vector>
2835

2936
using namespace iga;
3037

@@ -94,15 +101,15 @@ void iga::SetStdinBinary()
94101
#endif
95102
}
96103

97-
bool iga::DoesFileExist(const char *path)
104+
bool iga::DoesFileExist(const std::string &path)
98105
{
99106
#ifdef _WIN32
100-
DWORD dwAttrib = GetFileAttributesA(path);
107+
DWORD dwAttrib = GetFileAttributesA(path.c_str());
101108
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
102109
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
103110
#else
104111
struct stat sb = {0};
105-
if (stat(path, &sb) != 0) {
112+
if (stat(path.c_str(), &sb) != 0) {
106113
return false;
107114
}
108115
return S_ISREG(sb.st_mode);
@@ -225,3 +232,112 @@ void iga::EmitYellowText(std::ostream &os, const std::string &s) {
225232
StreamColorSetter scs(os, StreamColorSetter::YELLOW);
226233
os << s;
227234
}
235+
236+
unsigned iga::LastError()
237+
{
238+
#ifdef _WIN32
239+
return (unsigned)GetLastError();
240+
#else
241+
return (unsigned)errno;
242+
#endif // _WIN32
243+
}
244+
245+
std::string iga::FormatLastError(unsigned errCode)
246+
{
247+
std::string msg;
248+
char buf[256] {0};
249+
char *errMsg = nullptr;
250+
#ifdef _WIN32
251+
errMsg = &buf[0];
252+
FormatMessageA(
253+
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
254+
NULL,
255+
errCode,
256+
0,
257+
(LPTSTR)&errMsg,
258+
sizeof(buf),
259+
NULL);
260+
if (errMsg)
261+
msg = errMsg;
262+
#else
263+
errMsg = strerror_r(errCode, buf, sizeof(buf));
264+
#endif // _WIN32
265+
if (errMsg == nullptr || errMsg[0] == 0)
266+
return "???";
267+
return std::string(errMsg);
268+
}
269+
270+
std::string iga::FixupPath(const std::string &path)
271+
{
272+
#ifdef _WIN32
273+
// Windows paths can be a mess due to the 260 MAX_PATH limit.
274+
// This fails in the guts on the Windows path expansion (of .) and
275+
// normalization of path component separates (/ to \) etc.
276+
// (You'd experience std::ofstream to just fail to open a file.)
277+
// We work around this here by normalizing and expanding the path to an
278+
// absolute path.
279+
//
280+
// The approach here is to expand the path to a normalized absolute path.
281+
// This is a bit pesky because GetFullPathNameA is limited to 260 chars.
282+
// So we must use GetFullPathNameW. We will.
283+
// 0. manually replace / with \
284+
// 1. convert the path to absolute using GetFullPathNameW
285+
// (GetFullPathNameA is still limited to 260)
286+
// 2. convert back to UTF-8
287+
// 3. prefix a \\?\ so that CreateFile (under std::ofstream) won't
288+
// attempt to expand any relative components and choke due to length.
289+
//
290+
// If someone can come up with something better please let me know.
291+
if (path.substr(0, 2) == "\\\\") {
292+
// Network or UNC path (e.g. \\?\...) can be ignored...
293+
return path;
294+
}
295+
296+
std::string noSlashes = path;
297+
std::replace(noSlashes.begin(), noSlashes.end(), '/', '\\');
298+
const char *pathCstr = noSlashes.c_str();
299+
auto retMbtwc = MultiByteToWideChar(CP_ACP, 0, pathCstr, -1, nullptr, 0);
300+
if (retMbtwc <= 0) {
301+
auto err = GetLastError();
302+
std::stringstream ess;
303+
ess << "iga::FixupPath:MultiByteToWideChar: " << err;
304+
IGA_FATAL(ess.str().c_str());
305+
}
306+
std::vector<wchar_t> wPath;
307+
wPath.resize(retMbtwc);
308+
MultiByteToWideChar(
309+
CP_ACP, 0, pathCstr, -1, wPath.data(), (int)wPath.size());
310+
311+
std::wstring absPathW;
312+
wchar_t wbuf[256];
313+
auto retGfpn = GetFullPathNameW(
314+
wPath.data(),
315+
(unsigned)sizeof(wbuf)/sizeof(wbuf[0]) - 1, wbuf, nullptr);
316+
if (retGfpn == 0) {
317+
auto err = GetLastError();
318+
std::stringstream ess;
319+
ess << "iga::FixupPath:GetFullPathNameW: " << err;
320+
IGA_FATAL(ess.str().c_str());
321+
return "";
322+
} else if (retGfpn >= sizeof(wbuf)/sizeof(wbuf[0]) - 1) {
323+
std::vector<wchar_t> vec;
324+
vec.resize(retGfpn + 1);
325+
retGfpn = GetFullPathNameW(
326+
wPath.data(), (unsigned)vec.size() - 1, vec.data(), nullptr);
327+
absPathW = vec.data();
328+
} else {
329+
absPathW = wbuf;
330+
}
331+
int sizeNeeded = WideCharToMultiByte(
332+
CP_ACP, 0, &absPathW[0], (int)absPathW.size(),
333+
NULL, 0, NULL, NULL);
334+
std::string absPathA(sizeNeeded, 0);
335+
WideCharToMultiByte(
336+
CP_ACP, 0, &absPathW[0], (int)absPathW.size(),
337+
&absPathA[0], sizeNeeded, NULL, NULL);
338+
absPathA = "\\\\?\\" + absPathA;
339+
return absPathA;
340+
#else
341+
return path;
342+
#endif // _WIN32
343+
}

visa/iga/IGALibrary/system.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,23 @@ namespace iga
2222

2323
// bool LookupEnvironmentVariable(const char *key, std::string &value);
2424
// bool IsDirectory(const char *path);
25-
bool DoesFileExist(const char *path);
25+
bool DoesFileExist(const std::string &path);
2626

2727
// For older Windows console compatibility
2828
void EmitRedText(std::ostream &os, const std::string &s);
2929
void EmitGreenText(std::ostream &os, const std::string &s);
3030
void EmitYellowText(std::ostream &os, const std::string &s);
3131

3232
bool DebuggerAttached();
33+
34+
// maps to GetLastError() or errno
35+
unsigned LastError();
36+
std::string FormatLastError(unsigned);
37+
static inline std::string LastErrorString() {return FormatLastError(LastError());}
38+
39+
// deals with large Windows paths on Windows platforms
40+
// identity function on other platforms
41+
std::string FixupPath(const std::string &path);
3342
}
3443

3544
#endif // SYSTEM_HPP

0 commit comments

Comments
 (0)