mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[llvm-cov gcov] Support GCC 12 format
GCC 12 will change the length field to represent the number of bytes instead of 32-bit words. This avoids padding for strings.
This commit is contained in:
parent
f02bea7812
commit
9e8233e08c
@ -42,7 +42,7 @@ class GCOVBlock;
|
||||
|
||||
namespace GCOV {
|
||||
|
||||
enum GCOVVersion { V304, V407, V408, V800, V900 };
|
||||
enum GCOVVersion { V304, V407, V408, V800, V900, V1200 };
|
||||
|
||||
/// A struct for passing gcov options between functions.
|
||||
struct Options {
|
||||
@ -108,7 +108,7 @@ public:
|
||||
}
|
||||
|
||||
/// readGCOVVersion - Read GCOV version.
|
||||
bool readGCOVVersion(GCOV::GCOVVersion &Version) {
|
||||
bool readGCOVVersion(GCOV::GCOVVersion &version) {
|
||||
std::string str(de.getBytes(cursor, 4));
|
||||
if (str.size() != 4)
|
||||
return false;
|
||||
@ -117,24 +117,27 @@ public:
|
||||
int ver = str[0] >= 'A'
|
||||
? (str[0] - 'A') * 100 + (str[1] - '0') * 10 + str[2] - '0'
|
||||
: (str[0] - '0') * 10 + str[2] - '0';
|
||||
if (ver >= 90) {
|
||||
if (ver >= 120) {
|
||||
this->version = version = GCOV::V1200;
|
||||
return true;
|
||||
} else if (ver >= 90) {
|
||||
// PR gcov-profile/84846, r269678
|
||||
Version = GCOV::V900;
|
||||
this->version = version = GCOV::V900;
|
||||
return true;
|
||||
} else if (ver >= 80) {
|
||||
// PR gcov-profile/48463
|
||||
Version = GCOV::V800;
|
||||
this->version = version = GCOV::V800;
|
||||
return true;
|
||||
} else if (ver >= 48) {
|
||||
// r189778: the exit block moved from the last to the second.
|
||||
Version = GCOV::V408;
|
||||
this->version = version = GCOV::V408;
|
||||
return true;
|
||||
} else if (ver >= 47) {
|
||||
// r173147: split checksum into cfg checksum and line checksum.
|
||||
Version = GCOV::V407;
|
||||
this->version = version = GCOV::V407;
|
||||
return true;
|
||||
} else if (ver >= 34) {
|
||||
Version = GCOV::V304;
|
||||
this->version = version = GCOV::V304;
|
||||
return true;
|
||||
}
|
||||
errs() << "unexpected version: " << str << "\n";
|
||||
@ -167,11 +170,14 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readString(StringRef &Str) {
|
||||
bool readString(StringRef &str) {
|
||||
uint32_t len;
|
||||
if (!readInt(len) || len == 0)
|
||||
return false;
|
||||
Str = de.getBytes(cursor, len * 4).split('\0').first;
|
||||
if (version >= GCOV::V1200)
|
||||
str = de.getBytes(cursor, len).drop_back();
|
||||
else
|
||||
str = de.getBytes(cursor, len * 4).split('\0').first;
|
||||
return bool(cursor);
|
||||
}
|
||||
|
||||
@ -180,6 +186,7 @@ public:
|
||||
|
||||
private:
|
||||
MemoryBuffer *Buffer;
|
||||
GCOV::GCOVVersion version{};
|
||||
};
|
||||
|
||||
/// GCOVFile - Collects coverage information for one pair of coverage file
|
||||
@ -199,7 +206,7 @@ public:
|
||||
|
||||
public:
|
||||
bool GCNOInitialized = false;
|
||||
GCOV::GCOVVersion version;
|
||||
GCOV::GCOVVersion version{};
|
||||
uint32_t checksum = 0;
|
||||
StringRef cwd;
|
||||
SmallVector<std::unique_ptr<GCOVFunction>, 16> functions;
|
||||
|
@ -115,6 +115,7 @@ bool GCOVFile::readGCNO(GCOVBuffer &buf) {
|
||||
while ((tag = buf.getWord())) {
|
||||
if (!buf.readInt(length))
|
||||
return false;
|
||||
uint32_t pos = buf.cursor.tell();
|
||||
if (tag == GCOV_TAG_FUNCTION) {
|
||||
functions.push_back(std::make_unique<GCOVFunction>(*this));
|
||||
fn = functions.back().get();
|
||||
@ -162,7 +163,9 @@ bool GCOVFile::readGCNO(GCOVBuffer &buf) {
|
||||
return false;
|
||||
}
|
||||
GCOVBlock *src = fn->blocks[srcNo].get();
|
||||
for (uint32_t i = 0, e = (length - 1) / 2; i != e; ++i) {
|
||||
const uint32_t e =
|
||||
version >= GCOV::V1200 ? (length / 4 - 1) / 2 : (length - 1) / 2;
|
||||
for (uint32_t i = 0; i != e; ++i) {
|
||||
uint32_t dstNo = buf.getWord(), flags = buf.getWord();
|
||||
GCOVBlock *dst = fn->blocks[dstNo].get();
|
||||
auto arc = std::make_unique<GCOVArc>(*src, *dst, flags);
|
||||
@ -194,6 +197,10 @@ bool GCOVFile::readGCNO(GCOVBuffer &buf) {
|
||||
}
|
||||
}
|
||||
}
|
||||
pos += version >= GCOV::V1200 ? length : 4 * length;
|
||||
if (pos < buf.cursor.tell())
|
||||
return false;
|
||||
buf.de.skip(buf.cursor, pos - buf.cursor.tell());
|
||||
}
|
||||
|
||||
GCNOInitialized = true;
|
||||
@ -268,11 +275,14 @@ bool GCOVFile::readGCDA(GCOVBuffer &buf) {
|
||||
}
|
||||
}
|
||||
} else if (tag == GCOV_TAG_COUNTER_ARCS && fn) {
|
||||
if (length != 2 * fn->arcs.size()) {
|
||||
uint32_t expected = 2 * fn->arcs.size();
|
||||
if (version >= GCOV::V1200)
|
||||
expected *= 4;
|
||||
if (length != expected) {
|
||||
errs() << fn->Name
|
||||
<< format(
|
||||
": GCOV_TAG_COUNTER_ARCS mismatch, got %u, expected %u\n",
|
||||
length, unsigned(2 * fn->arcs.size()));
|
||||
length, expected);
|
||||
return false;
|
||||
}
|
||||
for (std::unique_ptr<GCOVArc> &arc : fn->arcs) {
|
||||
@ -296,7 +306,7 @@ bool GCOVFile::readGCDA(GCOVBuffer &buf) {
|
||||
fn->treeArcs[i - 1]->src.count += fn->treeArcs[i - 1]->count;
|
||||
}
|
||||
}
|
||||
pos += 4 * length;
|
||||
pos += version >= GCOV::V1200 ? length : 4 * length;
|
||||
if (pos < buf.cursor.tell())
|
||||
return false;
|
||||
buf.de.skip(buf.cursor, pos - buf.cursor.tell());
|
||||
|
BIN
test/tools/llvm-cov/gcov/Inputs/gcov-12.gcda
Normal file
BIN
test/tools/llvm-cov/gcov/Inputs/gcov-12.gcda
Normal file
Binary file not shown.
BIN
test/tools/llvm-cov/gcov/Inputs/gcov-12.gcno
Normal file
BIN
test/tools/llvm-cov/gcov/Inputs/gcov-12.gcno
Normal file
Binary file not shown.
32
test/tools/llvm-cov/gcov/gcov-12.c
Normal file
32
test/tools/llvm-cov/gcov/gcov-12.c
Normal file
@ -0,0 +1,32 @@
|
||||
/// Test that llvm-cov supports gcov 12 compatible format.
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
int main() { // GCOV: 1: [[@LINE]]:int main
|
||||
double a[11], result; // GCOV-NEXT: -: [[@LINE]]:
|
||||
for (int i = 0; i < 11; i++) // GCOV-NEXT: 12: [[@LINE]]:
|
||||
scanf("%lf", &a[i]); // GCOV-NEXT: 11: [[@LINE]]:
|
||||
for (int i = 10; i >= 0; i--) { // GCOV-NEXT: 12: [[@LINE]]:
|
||||
result = sqrt(fabs(a[i])) + 5 * pow(a[i], 3); // GCOV-NEXT: 11: [[@LINE]]:
|
||||
printf("\nf(%d) = ", i); // GCOV-NEXT: 11: [[@LINE]]:
|
||||
if (result > 400) printf("Overflow!"); // GCOV-NEXT: 11: [[@LINE]]:
|
||||
else printf("%lf", result); // GCOV-NEXT: 4: [[@LINE]]:
|
||||
} // GCOV-NEXT: -: [[@LINE]]:
|
||||
return 0; // GCOV-NEXT: 1: [[@LINE]]:
|
||||
} // GCOV-NEXT: -: [[@LINE]]:
|
||||
|
||||
// RUN: rm -rf %t && mkdir %t && cd %t
|
||||
// RUN: cp %s %p/Inputs/gcov-12.gc* .
|
||||
|
||||
// RUN: llvm-cov gcov gcov-12.c | FileCheck %s
|
||||
// CHECK: File 'gcov-12.c'
|
||||
// CHECK-NEXT: Lines executed:100.00% of 9
|
||||
// CHECK-NEXT: Creating 'gcov-12.c.gcov'
|
||||
|
||||
// RUN: FileCheck --input-file=%t/gcov-12.c.gcov --check-prefix=HEADER %s
|
||||
// RUN: FileCheck --input-file=%t/gcov-12.c.gcov --check-prefix=GCOV %s
|
||||
|
||||
// HEADER: {{^}} -: 0:Source:gcov-12.c
|
||||
// HEADER-NEXT: -: 0:Graph:gcov-12.gcno
|
||||
// HEADER-NEXT: -: 0:Data:gcov-12.gcda
|
||||
// HEADER-NEXT: -: 0:Runs:1{{$}}
|
||||
// HEADER-NEXT: -: 1:/// Test that llvm-cov
|
Loading…
Reference in New Issue
Block a user