mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-20 00:24:58 +08:00
Reimplementation of Elf Writer
- remove is_initialize pattern - add RAII - replace dynamic arrays with std::vector<char> - use fixed width integer types - remove c-style casting - reducing the number of code checks - add camelCase style Change-Id: If24a595f03865c59c86fed29db280de0084b5663
This commit is contained in:
committed by
sys_ocldev
parent
392277ff00
commit
8226269bbe
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@@ -1,4 +1,4 @@
|
|||||||
#!groovy
|
#!groovy
|
||||||
neoDependenciesRev='787198-1060'
|
neoDependenciesRev='787198-1060'
|
||||||
strategy='EQUAL'
|
strategy='EQUAL'
|
||||||
allowedCD=294
|
allowedCD=283
|
||||||
|
|||||||
331
elf/writer.cpp
331
elf/writer.cpp
@@ -20,266 +20,99 @@
|
|||||||
* OTHER DEALINGS IN THE SOFTWARE.
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include "writer.h"
|
#include "writer.h"
|
||||||
#include "runtime/helpers/string.h"
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace CLElfLib {
|
// Need for linux compatibility with memcpy_s
|
||||||
/******************************************************************************\
|
#include "runtime/helpers/string.h"
|
||||||
Constructor: CElfWriter::CElfWriter
|
|
||||||
\******************************************************************************/
|
|
||||||
CElfWriter::CElfWriter(
|
|
||||||
E_EH_TYPE type,
|
|
||||||
E_EH_MACHINE machine,
|
|
||||||
Elf64_Xword flags) {
|
|
||||||
m_type = type;
|
|
||||||
m_machine = machine;
|
|
||||||
m_flags = flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************\
|
namespace CLElfLib {
|
||||||
Destructor: CElfWriter::~CElfWriter
|
void CElfWriter::resolveBinary(ElfBinaryStorage &binary) {
|
||||||
\******************************************************************************/
|
SElf64SectionHeader *curSectionHeader = nullptr;
|
||||||
CElfWriter::~CElfWriter() {
|
char *data = nullptr;
|
||||||
SSectionNode *pNode = nullptr;
|
char *stringTable = nullptr;
|
||||||
|
char *curString = nullptr;
|
||||||
|
|
||||||
|
if (binary.size() < getTotalBinarySize()) {
|
||||||
|
binary.resize(getTotalBinarySize());
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a pointer to the first section header
|
||||||
|
curSectionHeader = reinterpret_cast<SElf64SectionHeader *>(binary.data() + sizeof(SElf64Header));
|
||||||
|
|
||||||
|
// get a pointer to the data
|
||||||
|
data = binary.data() +
|
||||||
|
sizeof(SElf64Header) +
|
||||||
|
((numSections + 1) * sizeof(SElf64SectionHeader)); // +1 to account for string table entry
|
||||||
|
|
||||||
|
// get a pointer to the string table
|
||||||
|
stringTable = binary.data() + sizeof(SElf64Header) +
|
||||||
|
((numSections + 1) * sizeof(SElf64SectionHeader)) + // +1 to account for string table entry
|
||||||
|
dataSize;
|
||||||
|
|
||||||
|
curString = stringTable;
|
||||||
|
|
||||||
// Walk through the section nodes
|
// Walk through the section nodes
|
||||||
while (m_nodeQueue.empty() == false) {
|
while (nodeQueue.empty() == false) {
|
||||||
pNode = m_nodeQueue.front();
|
// Copy data into the section header
|
||||||
m_nodeQueue.pop();
|
const auto &queueFront = nodeQueue.front();
|
||||||
|
|
||||||
// delete the node and it's data
|
curSectionHeader->Type = queueFront.type;
|
||||||
if (pNode) {
|
curSectionHeader->Flags = queueFront.flag;
|
||||||
if (pNode->pData) {
|
curSectionHeader->DataSize = queueFront.dataSize;
|
||||||
delete[] pNode->pData;
|
curSectionHeader->DataOffset = data - binary.data();
|
||||||
pNode->pData = nullptr;
|
curSectionHeader->Name = static_cast<Elf64_Word>(curString - stringTable);
|
||||||
}
|
curSectionHeader = reinterpret_cast<SElf64SectionHeader *>(reinterpret_cast<unsigned char *>(curSectionHeader) + sizeof(SElf64SectionHeader));
|
||||||
|
|
||||||
delete pNode;
|
// copy the data, move the data pointer
|
||||||
pNode = nullptr;
|
memcpy_s(data, queueFront.dataSize, queueFront.data.c_str(), queueFront.dataSize);
|
||||||
|
data += queueFront.dataSize;
|
||||||
|
|
||||||
|
// copy the name into the string table, move the string pointer
|
||||||
|
if (queueFront.name.size() > 0) {
|
||||||
|
memcpy_s(curString, queueFront.name.size(), queueFront.name.c_str(), queueFront.name.size());
|
||||||
|
curString += queueFront.name.size();
|
||||||
}
|
}
|
||||||
|
*(curString++) = '\0'; // NOLINT
|
||||||
|
|
||||||
|
nodeQueue.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add the string table section header
|
||||||
|
SElf64SectionHeader stringSectionHeader = {0};
|
||||||
|
stringSectionHeader.Type = E_SH_TYPE::SH_TYPE_STR_TBL;
|
||||||
|
stringSectionHeader.Flags = E_SH_FLAG::SH_FLAG_NONE;
|
||||||
|
stringSectionHeader.DataOffset = stringTable - &binary[0];
|
||||||
|
stringSectionHeader.DataSize = stringTableSize;
|
||||||
|
stringSectionHeader.Name = 0;
|
||||||
|
|
||||||
|
// Copy into the last section header
|
||||||
|
memcpy_s(curSectionHeader, sizeof(SElf64SectionHeader),
|
||||||
|
&stringSectionHeader, sizeof(SElf64SectionHeader));
|
||||||
|
|
||||||
|
// Add to our section number
|
||||||
|
numSections++;
|
||||||
|
|
||||||
|
// patch up the ELF header
|
||||||
|
patchElfHeader(*reinterpret_cast<SElf64Header *>(binary.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************\
|
void CElfWriter::patchElfHeader(SElf64Header &binary) {
|
||||||
Member Function: CElfWriter::Create
|
// Setup the identity
|
||||||
\******************************************************************************/
|
binary.Identity[ELFConstants::idIdxMagic0] = ELFConstants::elfMag0;
|
||||||
CElfWriter *CElfWriter::create(
|
binary.Identity[ELFConstants::idIdxMagic1] = ELFConstants::elfMag1;
|
||||||
E_EH_TYPE type,
|
binary.Identity[ELFConstants::idIdxMagic2] = ELFConstants::elfMag2;
|
||||||
E_EH_MACHINE machine,
|
binary.Identity[ELFConstants::idIdxMagic3] = ELFConstants::elfMag3;
|
||||||
Elf64_Xword flags) {
|
binary.Identity[ELFConstants::idIdxClass] = static_cast<uint32_t>(E_EH_CLASS::EH_CLASS_64);
|
||||||
CElfWriter *pWriter = new CElfWriter(type, machine, flags);
|
binary.Identity[ELFConstants::idIdxVersion] = static_cast<uint32_t>(E_EHT_VERSION::EH_VERSION_CURRENT);
|
||||||
|
|
||||||
if (!pWriter->initialize()) {
|
// Add other non-zero info
|
||||||
destroy(pWriter);
|
binary.Type = type;
|
||||||
}
|
binary.Machine = machine;
|
||||||
|
binary.Flags = static_cast<uint32_t>(flag);
|
||||||
return pWriter;
|
binary.ElfHeaderSize = static_cast<uint32_t>(sizeof(SElf64Header));
|
||||||
|
binary.SectionHeaderEntrySize = static_cast<uint32_t>(sizeof(SElf64SectionHeader));
|
||||||
|
binary.NumSectionHeaderEntries = numSections;
|
||||||
|
binary.SectionHeadersOffset = static_cast<uint32_t>(sizeof(SElf64Header));
|
||||||
|
binary.SectionNameTableIndex = numSections - 1; // last index
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************\
|
|
||||||
Member Function: CElfWriter::Delete
|
|
||||||
\******************************************************************************/
|
|
||||||
void CElfWriter::destroy(
|
|
||||||
CElfWriter *&pWriter) {
|
|
||||||
if (pWriter) {
|
|
||||||
delete pWriter;
|
|
||||||
pWriter = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************\
|
|
||||||
Member Function: CElfWriter::AddSection
|
|
||||||
\******************************************************************************/
|
|
||||||
bool CElfWriter::addSection(
|
|
||||||
SSectionNode *pSectionNode) {
|
|
||||||
bool retVal = true;
|
|
||||||
SSectionNode *pNode = nullptr;
|
|
||||||
size_t nameSize = 0;
|
|
||||||
unsigned int dataSize = 0;
|
|
||||||
|
|
||||||
// The section header must be non-NULL
|
|
||||||
if (pSectionNode) {
|
|
||||||
pNode = new SSectionNode();
|
|
||||||
if (!pNode)
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pNode->Flags = pSectionNode->Flags;
|
|
||||||
pNode->Type = pSectionNode->Type;
|
|
||||||
|
|
||||||
nameSize = pSectionNode->Name.size() + 1;
|
|
||||||
dataSize = pSectionNode->DataSize;
|
|
||||||
|
|
||||||
pNode->Name = pSectionNode->Name;
|
|
||||||
|
|
||||||
// ok to have NULL data
|
|
||||||
if (dataSize > 0) {
|
|
||||||
pNode->pData = new char[dataSize];
|
|
||||||
if (pNode->pData) {
|
|
||||||
memcpy_s(pNode->pData, dataSize, pSectionNode->pData, dataSize);
|
|
||||||
pNode->DataSize = dataSize;
|
|
||||||
} else {
|
|
||||||
retVal = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retVal) {
|
|
||||||
// push the node onto the queue
|
|
||||||
m_nodeQueue.push(pNode);
|
|
||||||
|
|
||||||
// increment the sizes for each section
|
|
||||||
m_dataSize += dataSize;
|
|
||||||
m_stringTableSize += nameSize;
|
|
||||||
m_numSections++;
|
|
||||||
} else {
|
|
||||||
delete pNode;
|
|
||||||
pNode = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************\
|
|
||||||
Member Function: CElfWriter::ResolveBinary
|
|
||||||
\******************************************************************************/
|
|
||||||
bool CElfWriter::resolveBinary(
|
|
||||||
char *const pBinary,
|
|
||||||
size_t &binarySize) {
|
|
||||||
bool retVal = true;
|
|
||||||
SSectionNode *pNode = nullptr;
|
|
||||||
SElf64SectionHeader *pCurSectionHeader = nullptr;
|
|
||||||
char *pData = nullptr;
|
|
||||||
char *pStringTable = nullptr;
|
|
||||||
char *pCurString = nullptr;
|
|
||||||
|
|
||||||
m_totalBinarySize =
|
|
||||||
sizeof(SElf64Header) +
|
|
||||||
((m_numSections + 1) * sizeof(SElf64SectionHeader)) + // +1 to account for string table entry
|
|
||||||
m_dataSize +
|
|
||||||
m_stringTableSize;
|
|
||||||
|
|
||||||
if (pBinary) {
|
|
||||||
// get a pointer to the first section header
|
|
||||||
pCurSectionHeader = reinterpret_cast<SElf64SectionHeader *>(pBinary + sizeof(SElf64Header));
|
|
||||||
|
|
||||||
// get a pointer to the data
|
|
||||||
pData = pBinary +
|
|
||||||
sizeof(SElf64Header) +
|
|
||||||
((m_numSections + 1) * sizeof(SElf64SectionHeader)); // +1 to account for string table entry
|
|
||||||
|
|
||||||
// get a pointer to the string table
|
|
||||||
pStringTable = pBinary + sizeof(SElf64Header) +
|
|
||||||
((m_numSections + 1) * sizeof(SElf64SectionHeader)) + // +1 to account for string table entry
|
|
||||||
m_dataSize;
|
|
||||||
|
|
||||||
pCurString = pStringTable;
|
|
||||||
|
|
||||||
// Walk through the section nodes
|
|
||||||
while (m_nodeQueue.empty() == false) {
|
|
||||||
pNode = m_nodeQueue.front();
|
|
||||||
|
|
||||||
if (pNode) {
|
|
||||||
m_nodeQueue.pop();
|
|
||||||
|
|
||||||
// Copy data into the section header
|
|
||||||
memset(pCurSectionHeader, 0, sizeof(SElf64SectionHeader));
|
|
||||||
pCurSectionHeader->Type = pNode->Type;
|
|
||||||
pCurSectionHeader->Flags = pNode->Flags;
|
|
||||||
pCurSectionHeader->DataSize = pNode->DataSize;
|
|
||||||
pCurSectionHeader->DataOffset = pData - pBinary;
|
|
||||||
pCurSectionHeader->Name = static_cast<Elf64_Word>(pCurString - pStringTable);
|
|
||||||
pCurSectionHeader = reinterpret_cast<SElf64SectionHeader *>(reinterpret_cast<unsigned char *>(pCurSectionHeader) + sizeof(SElf64SectionHeader));
|
|
||||||
|
|
||||||
// copy the data, move the data pointer
|
|
||||||
memcpy_s(pData, pNode->DataSize, pNode->pData, pNode->DataSize);
|
|
||||||
pData += pNode->DataSize;
|
|
||||||
|
|
||||||
// copy the name into the string table, move the string pointer
|
|
||||||
if (pNode->Name.size() > 0) {
|
|
||||||
memcpy_s(pCurString, pNode->Name.size(), pNode->Name.c_str(), pNode->Name.size());
|
|
||||||
pCurString += pNode->Name.size();
|
|
||||||
}
|
|
||||||
*(pCurString++) = '\0'; // NOLINT
|
|
||||||
|
|
||||||
// delete the node and it's data
|
|
||||||
if (pNode->pData) {
|
|
||||||
delete[] pNode->pData;
|
|
||||||
pNode->pData = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete pNode;
|
|
||||||
pNode = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the string table section header
|
|
||||||
SElf64SectionHeader stringSectionHeader = {0};
|
|
||||||
stringSectionHeader.Type = E_SH_TYPE::SH_TYPE_STR_TBL;
|
|
||||||
stringSectionHeader.Flags = E_SH_FLAG::SH_FLAG_NONE;
|
|
||||||
stringSectionHeader.DataOffset = pStringTable - pBinary;
|
|
||||||
stringSectionHeader.DataSize = m_stringTableSize;
|
|
||||||
stringSectionHeader.Name = 0;
|
|
||||||
|
|
||||||
// Copy into the last section header
|
|
||||||
memcpy_s(pCurSectionHeader, sizeof(SElf64SectionHeader),
|
|
||||||
&stringSectionHeader, sizeof(SElf64SectionHeader));
|
|
||||||
|
|
||||||
// Add to our section number
|
|
||||||
m_numSections++;
|
|
||||||
|
|
||||||
// patch up the ELF header
|
|
||||||
retVal = patchElfHeader(pBinary);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retVal) {
|
|
||||||
binarySize = m_totalBinarySize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************\
|
|
||||||
Member Function: CElfWriter::Initialize
|
|
||||||
\******************************************************************************/
|
|
||||||
bool CElfWriter::initialize() {
|
|
||||||
SSectionNode emptySection;
|
|
||||||
|
|
||||||
// Add an empty section 0 (points to "no-bits")
|
|
||||||
return addSection(&emptySection);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************\
|
|
||||||
Member Function: CElfWriter::PatchElfHeader
|
|
||||||
\******************************************************************************/
|
|
||||||
bool CElfWriter::patchElfHeader(char *const pBinary) {
|
|
||||||
SElf64Header *pElfHeader = reinterpret_cast<SElf64Header *>(pBinary);
|
|
||||||
|
|
||||||
if (pElfHeader) {
|
|
||||||
// Setup the identity
|
|
||||||
memset(pElfHeader, 0x00, sizeof(SElf64Header));
|
|
||||||
pElfHeader->Identity[ELFConstants::idIdxMagic0] = ELFConstants::elfMag0;
|
|
||||||
pElfHeader->Identity[ELFConstants::idIdxMagic1] = ELFConstants::elfMag1;
|
|
||||||
pElfHeader->Identity[ELFConstants::idIdxMagic2] = ELFConstants::elfMag2;
|
|
||||||
pElfHeader->Identity[ELFConstants::idIdxMagic3] = ELFConstants::elfMag3;
|
|
||||||
pElfHeader->Identity[ELFConstants::idIdxClass] = static_cast<uint32_t>(E_EH_CLASS::EH_CLASS_64);
|
|
||||||
pElfHeader->Identity[ELFConstants::idIdxVersion] = static_cast<uint32_t>(E_EHT_VERSION::EH_VERSION_CURRENT);
|
|
||||||
|
|
||||||
// Add other non-zero info
|
|
||||||
pElfHeader->Type = m_type;
|
|
||||||
pElfHeader->Machine = m_machine;
|
|
||||||
pElfHeader->Flags = static_cast<uint32_t>(m_flags);
|
|
||||||
pElfHeader->ElfHeaderSize = static_cast<uint32_t>(sizeof(SElf64Header));
|
|
||||||
pElfHeader->SectionHeaderEntrySize = static_cast<uint32_t>(sizeof(SElf64SectionHeader));
|
|
||||||
pElfHeader->NumSectionHeaderEntries = m_numSections;
|
|
||||||
pElfHeader->SectionHeadersOffset = static_cast<uint32_t>(sizeof(SElf64Header));
|
|
||||||
pElfHeader->SectionNameTableIndex = m_numSections - 1; // last index
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace CLElfLib
|
} // namespace CLElfLib
|
||||||
|
|||||||
97
elf/writer.h
97
elf/writer.h
@@ -24,35 +24,23 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#define ELF_CALL __stdcall
|
|
||||||
#else
|
|
||||||
#define ELF_CALL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace CLElfLib {
|
namespace CLElfLib {
|
||||||
static const unsigned int g_scElfHeaderAlignment = 16; // allocation alignment restriction
|
using ElfBinaryStorage = std::vector<char>;
|
||||||
static const unsigned int g_scInitialElfSize = 2048; // initial elf size (in bytes)
|
|
||||||
static const unsigned int g_scInitNumSectionHeaders = 8;
|
|
||||||
|
|
||||||
struct SSectionNode {
|
struct SSectionNode {
|
||||||
E_SH_TYPE Type;
|
E_SH_TYPE type = E_SH_TYPE::SH_TYPE_NULL;
|
||||||
E_SH_FLAG Flags;
|
E_SH_FLAG flag = E_SH_FLAG::SH_FLAG_NONE;
|
||||||
string Name;
|
std::string name;
|
||||||
char *pData;
|
std::string data;
|
||||||
unsigned int DataSize;
|
uint32_t dataSize = 0u;
|
||||||
|
|
||||||
SSectionNode() {
|
SSectionNode() = default;
|
||||||
Type = E_SH_TYPE::SH_TYPE_NULL;
|
|
||||||
Flags = E_SH_FLAG::SH_FLAG_NONE;
|
|
||||||
pData = nullptr;
|
|
||||||
DataSize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
~SSectionNode() {
|
template <typename T1, typename T2>
|
||||||
}
|
SSectionNode(E_SH_TYPE type, E_SH_FLAG flag, T1 &&name, T2 &&data, uint32_t dataSize)
|
||||||
|
: type(type), flag(flag), name(std::forward<T1>(name)), data(std::forward<T2>(data)), dataSize(dataSize) {}
|
||||||
|
|
||||||
|
~SSectionNode() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
@@ -60,46 +48,57 @@ struct SSectionNode {
|
|||||||
Class: CElfWriter
|
Class: CElfWriter
|
||||||
|
|
||||||
Description: Class to provide simpler interaction with the ELF standard
|
Description: Class to provide simpler interaction with the ELF standard
|
||||||
binary object. SElf64Header defines the ELF header type and
|
binary object. SElf64Header defines the ELF header type and
|
||||||
SElf64SectionHeader defines the section header type.
|
SElf64SectionHeader defines the section header type.
|
||||||
|
|
||||||
\******************************************************************************/
|
\******************************************************************************/
|
||||||
class CElfWriter {
|
class CElfWriter {
|
||||||
public:
|
public:
|
||||||
static CElfWriter *ELF_CALL create(
|
CElfWriter(
|
||||||
E_EH_TYPE type,
|
E_EH_TYPE type,
|
||||||
E_EH_MACHINE machine,
|
E_EH_MACHINE machine,
|
||||||
Elf64_Xword flags);
|
Elf64_Xword flag) : type(type), machine(machine), flag(flag) {
|
||||||
|
addSection(SSectionNode());
|
||||||
|
}
|
||||||
|
|
||||||
static void ELF_CALL destroy(CElfWriter *&pElfWriter);
|
~CElfWriter() {}
|
||||||
|
|
||||||
bool ELF_CALL addSection(
|
template <typename T>
|
||||||
SSectionNode *pSectionNode);
|
void addSection(T &§ionNode) {
|
||||||
|
size_t nameSize = 0;
|
||||||
|
uint32_t dataSize = 0;
|
||||||
|
|
||||||
bool ELF_CALL resolveBinary(
|
nameSize = sectionNode.name.size() + 1u;
|
||||||
char *const pBinary,
|
dataSize = sectionNode.dataSize;
|
||||||
size_t &dataSize);
|
|
||||||
|
|
||||||
bool ELF_CALL initialize();
|
// push the node onto the queue
|
||||||
bool ELF_CALL patchElfHeader(char *const pBinary);
|
nodeQueue.push(std::forward<T>(sectionNode));
|
||||||
|
|
||||||
|
// increment the sizes for each section
|
||||||
|
this->dataSize += dataSize;
|
||||||
|
stringTableSize += nameSize;
|
||||||
|
numSections++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resolveBinary(ElfBinaryStorage &binary);
|
||||||
|
|
||||||
|
size_t getTotalBinarySize() {
|
||||||
|
return sizeof(SElf64Header) +
|
||||||
|
((numSections + 1) * sizeof(SElf64SectionHeader)) + // +1 to account for string table entry
|
||||||
|
dataSize + stringTableSize;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ELF_CALL CElfWriter(
|
E_EH_TYPE type = E_EH_TYPE::EH_TYPE_NONE;
|
||||||
E_EH_TYPE type,
|
E_EH_MACHINE machine = E_EH_MACHINE::EH_MACHINE_NONE;
|
||||||
E_EH_MACHINE machine,
|
Elf64_Xword flag = 0U;
|
||||||
Elf64_Xword flags);
|
|
||||||
|
|
||||||
ELF_CALL ~CElfWriter();
|
std::queue<SSectionNode> nodeQueue;
|
||||||
|
|
||||||
E_EH_TYPE m_type = E_EH_TYPE::EH_TYPE_NONE;
|
uint32_t dataSize = 0U;
|
||||||
E_EH_MACHINE m_machine = E_EH_MACHINE::EH_MACHINE_NONE;
|
uint32_t numSections = 0U;
|
||||||
Elf64_Xword m_flags = 0U;
|
size_t stringTableSize = 0U;
|
||||||
|
|
||||||
std::queue<SSectionNode *> m_nodeQueue;
|
void patchElfHeader(SElf64Header &pBinary);
|
||||||
|
|
||||||
uint32_t m_dataSize = 0U;
|
|
||||||
uint32_t m_numSections = 0U;
|
|
||||||
size_t m_stringTableSize = 0U;
|
|
||||||
size_t m_totalBinarySize = 0U;
|
|
||||||
};
|
};
|
||||||
} // namespace CLElfLib
|
} // namespace CLElfLib
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ OfflineCompiler::OfflineCompiler() = default;
|
|||||||
OfflineCompiler::~OfflineCompiler() {
|
OfflineCompiler::~OfflineCompiler() {
|
||||||
delete[] irBinary;
|
delete[] irBinary;
|
||||||
delete[] genBinary;
|
delete[] genBinary;
|
||||||
delete[] elfBinary;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -613,7 +612,7 @@ std::string getDevicesTypes() {
|
|||||||
prefixes.push_back(hardwarePrefix[j]);
|
prefixes.push_back(hardwarePrefix[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ostringstream os;
|
std::ostringstream os;
|
||||||
for (auto it = prefixes.begin(); it != prefixes.end(); it++) {
|
for (auto it = prefixes.begin(); it != prefixes.end(); it++) {
|
||||||
if (it != prefixes.begin())
|
if (it != prefixes.begin())
|
||||||
os << ",";
|
os << ",";
|
||||||
@@ -675,60 +674,27 @@ void OfflineCompiler::storeBinary(
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
bool OfflineCompiler::generateElfBinary() {
|
bool OfflineCompiler::generateElfBinary() {
|
||||||
bool retVal = true;
|
bool retVal = true;
|
||||||
CLElfLib::CElfWriter *pElfWriter = nullptr;
|
|
||||||
|
|
||||||
if (!genBinary || !genBinarySize) {
|
if (!genBinary || !genBinarySize) {
|
||||||
retVal = false;
|
retVal = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retVal) {
|
if (retVal) {
|
||||||
pElfWriter = CLElfLib::CElfWriter::create(CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_EXECUTABLE, CLElfLib::E_EH_MACHINE::EH_MACHINE_NONE, 0);
|
CLElfLib::CElfWriter elfWriter(CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_EXECUTABLE, CLElfLib::E_EH_MACHINE::EH_MACHINE_NONE, 0);
|
||||||
|
|
||||||
if (pElfWriter) {
|
elfWriter.addSection(CLElfLib::SSectionNode(CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_OPTIONS, CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "BuildOptions", options, static_cast<uint32_t>(strlen(options.c_str()) + 1u)));
|
||||||
CLElfLib::SSectionNode sectionNode;
|
std::string irBinaryTemp = irBinary ? std::string(irBinary, irBinarySize) : "";
|
||||||
|
elfWriter.addSection(CLElfLib::SSectionNode(isSpirV ? CLElfLib::E_SH_TYPE::SH_TYPE_SPIRV : CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_LLVM_BINARY, CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "Intel(R) OpenCL LLVM Object", std::move(irBinaryTemp), static_cast<uint32_t>(irBinarySize)));
|
||||||
|
|
||||||
// Always add the options string
|
// Add the device binary if it exists
|
||||||
sectionNode.Name = "BuildOptions";
|
if (genBinary) {
|
||||||
sectionNode.Type = CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_OPTIONS;
|
std::string genBinaryTemp = genBinary ? std::string(genBinary, genBinarySize) : "";
|
||||||
sectionNode.pData = (char *)options.c_str();
|
elfWriter.addSection(CLElfLib::SSectionNode(CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_DEV_BINARY, CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "Intel(R) OpenCL Device Binary", std::move(genBinaryTemp), static_cast<uint32_t>(genBinarySize)));
|
||||||
sectionNode.DataSize = (uint32_t)(strlen(options.c_str()) + 1);
|
|
||||||
|
|
||||||
retVal = pElfWriter->addSection(§ionNode);
|
|
||||||
|
|
||||||
if (retVal) {
|
|
||||||
sectionNode.Name = "Intel(R) OpenCL LLVM Object";
|
|
||||||
sectionNode.Type = isSpirV ? CLElfLib::E_SH_TYPE::SH_TYPE_SPIRV : CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_LLVM_BINARY;
|
|
||||||
sectionNode.pData = irBinary;
|
|
||||||
sectionNode.DataSize = (uint32_t)irBinarySize;
|
|
||||||
retVal = pElfWriter->addSection(§ionNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the device binary if it exists
|
|
||||||
if (retVal && genBinary) {
|
|
||||||
sectionNode.Name = "Intel(R) OpenCL Device Binary";
|
|
||||||
sectionNode.Type = CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_DEV_BINARY;
|
|
||||||
sectionNode.pData = genBinary;
|
|
||||||
sectionNode.DataSize = (uint32_t)genBinarySize;
|
|
||||||
|
|
||||||
retVal = pElfWriter->addSection(§ionNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retVal) {
|
|
||||||
// get the size
|
|
||||||
retVal = pElfWriter->resolveBinary(elfBinary, elfBinarySize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retVal) {
|
|
||||||
// allocate the binary
|
|
||||||
elfBinary = new char[elfBinarySize];
|
|
||||||
|
|
||||||
retVal = pElfWriter->resolveBinary(elfBinary, elfBinarySize);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
retVal = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CLElfLib::CElfWriter::destroy(pElfWriter);
|
elfBinarySize = elfWriter.getTotalBinarySize();
|
||||||
|
elfBinary.resize(elfBinarySize);
|
||||||
|
elfWriter.resolveBinary(elfBinary);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
@@ -787,12 +753,12 @@ void OfflineCompiler::writeOutAllFiles() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elfBinary) {
|
if (!elfBinary.empty()) {
|
||||||
std::string elfOutputFile = generateFilePath(outputDirectory, fileBase, ".bin") + generateOptsSuffix();
|
std::string elfOutputFile = generateFilePath(outputDirectory, fileBase, ".bin") + generateOptsSuffix();
|
||||||
|
|
||||||
writeDataToFile(
|
writeDataToFile(
|
||||||
elfOutputFile.c_str(),
|
elfOutputFile.c_str(),
|
||||||
elfBinary,
|
elfBinary.data(),
|
||||||
elfBinarySize);
|
elfBinarySize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "cif/common/cif_main.h"
|
#include "cif/common/cif_main.h"
|
||||||
#include "ocl_igc_interface/igc_ocl_device_ctx.h"
|
#include "ocl_igc_interface/igc_ocl_device_ctx.h"
|
||||||
#include "ocl_igc_interface/fcl_ocl_device_ctx.h"
|
#include "ocl_igc_interface/fcl_ocl_device_ctx.h"
|
||||||
|
#include "elf/writer.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -104,7 +105,7 @@ class OfflineCompiler {
|
|||||||
bool inputFileLlvm = false;
|
bool inputFileLlvm = false;
|
||||||
bool inputFileSpirV = false;
|
bool inputFileSpirV = false;
|
||||||
|
|
||||||
char *elfBinary = nullptr;
|
CLElfLib::ElfBinaryStorage elfBinary;
|
||||||
size_t elfBinarySize = 0;
|
size_t elfBinarySize = 0;
|
||||||
char *genBinary = nullptr;
|
char *genBinary = nullptr;
|
||||||
size_t genBinarySize = 0;
|
size_t genBinarySize = 0;
|
||||||
|
|||||||
@@ -42,10 +42,8 @@ cl_int Program::compile(
|
|||||||
void *userData) {
|
void *userData) {
|
||||||
cl_int retVal = CL_SUCCESS;
|
cl_int retVal = CL_SUCCESS;
|
||||||
cl_program program;
|
cl_program program;
|
||||||
CLElfLib::CElfWriter *pElfWriter = nullptr;
|
|
||||||
Program *pHeaderProgObj;
|
Program *pHeaderProgObj;
|
||||||
size_t compileDataSize;
|
size_t compileDataSize;
|
||||||
char *pCompileData = nullptr;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (((deviceList == nullptr) && (numDevices != 0)) ||
|
if (((deviceList == nullptr) && (numDevices != 0)) ||
|
||||||
@@ -98,20 +96,12 @@ cl_int Program::compile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create ELF writer to process all sources to be compiled
|
// create ELF writer to process all sources to be compiled
|
||||||
pElfWriter = CLElfLib::CElfWriter::create(CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_SOURCE, CLElfLib::E_EH_MACHINE::EH_MACHINE_NONE, 0);
|
CLElfLib::CElfWriter elfWriter(CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_SOURCE, CLElfLib::E_EH_MACHINE::EH_MACHINE_NONE, 0);
|
||||||
UNRECOVERABLE_IF(pElfWriter == nullptr);
|
|
||||||
|
|
||||||
CLElfLib::SSectionNode sectionNode;
|
CLElfLib::SSectionNode sectionNode(CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_SOURCE, CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "CLMain", sourceCode, static_cast<uint32_t>(sourceCode.size() + 1u));
|
||||||
|
|
||||||
// create main section
|
|
||||||
sectionNode.Name = "CLMain";
|
|
||||||
sectionNode.pData = (char *)sourceCode.c_str();
|
|
||||||
sectionNode.DataSize = (unsigned int)(strlen(sourceCode.c_str()) + 1);
|
|
||||||
sectionNode.Flags = CLElfLib::E_SH_FLAG::SH_FLAG_NONE;
|
|
||||||
sectionNode.Type = CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_SOURCE;
|
|
||||||
|
|
||||||
// add main program's source
|
// add main program's source
|
||||||
pElfWriter->addSection(§ionNode);
|
elfWriter.addSection(sectionNode);
|
||||||
|
|
||||||
for (cl_uint i = 0; i < numInputHeaders; i++) {
|
for (cl_uint i = 0; i < numInputHeaders; i++) {
|
||||||
program = inputHeaders[i];
|
program = inputHeaders[i];
|
||||||
@@ -124,23 +114,25 @@ cl_int Program::compile(
|
|||||||
retVal = CL_INVALID_PROGRAM;
|
retVal = CL_INVALID_PROGRAM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sectionNode.Name = headerIncludeNames[i];
|
sectionNode.name = headerIncludeNames[i];
|
||||||
sectionNode.Type = CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_HEADER;
|
sectionNode.type = CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_HEADER;
|
||||||
sectionNode.Flags = CLElfLib::E_SH_FLAG::SH_FLAG_NONE;
|
sectionNode.flag = CLElfLib::E_SH_FLAG::SH_FLAG_NONE;
|
||||||
// collect required data from the header
|
// collect required data from the header
|
||||||
retVal = pHeaderProgObj->getSource(sectionNode.pData, sectionNode.DataSize);
|
retVal = pHeaderProgObj->getSource(sectionNode.data);
|
||||||
if (retVal != CL_SUCCESS) {
|
if (retVal != CL_SUCCESS) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pElfWriter->addSection(§ionNode);
|
|
||||||
|
sectionNode.dataSize = static_cast<uint32_t>(sectionNode.data.size());
|
||||||
|
elfWriter.addSection(sectionNode);
|
||||||
}
|
}
|
||||||
if (retVal != CL_SUCCESS) {
|
if (retVal != CL_SUCCESS) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pElfWriter->resolveBinary(nullptr, compileDataSize);
|
compileDataSize = elfWriter.getTotalBinarySize();
|
||||||
pCompileData = new char[compileDataSize];
|
std::vector<char> compileData(compileDataSize);
|
||||||
pElfWriter->resolveBinary(pCompileData, compileDataSize);
|
elfWriter.resolveBinary(compileData);
|
||||||
|
|
||||||
CompilerInterface *pCompilerInterface = getCompilerInterface();
|
CompilerInterface *pCompilerInterface = getCompilerInterface();
|
||||||
if (!pCompilerInterface) {
|
if (!pCompilerInterface) {
|
||||||
@@ -168,12 +160,12 @@ cl_int Program::compile(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inputArgs.pInput = pCompileData;
|
inputArgs.pInput = compileData.data();
|
||||||
inputArgs.InputSize = (uint32_t)compileDataSize;
|
inputArgs.InputSize = static_cast<uint32_t>(compileDataSize);
|
||||||
inputArgs.pOptions = options.c_str();
|
inputArgs.pOptions = options.c_str();
|
||||||
inputArgs.OptionsSize = (uint32_t)options.length();
|
inputArgs.OptionsSize = static_cast<uint32_t>(options.length());
|
||||||
inputArgs.pInternalOptions = internalOptions.c_str();
|
inputArgs.pInternalOptions = internalOptions.c_str();
|
||||||
inputArgs.InternalOptionsSize = (uint32_t)internalOptions.length();
|
inputArgs.InternalOptionsSize = static_cast<uint32_t>(internalOptions.length());
|
||||||
inputArgs.pTracingOptions = nullptr;
|
inputArgs.pTracingOptions = nullptr;
|
||||||
inputArgs.TracingOptionsCount = 0;
|
inputArgs.TracingOptionsCount = 0;
|
||||||
|
|
||||||
@@ -192,8 +184,6 @@ cl_int Program::compile(
|
|||||||
programBinaryType = CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT;
|
programBinaryType = CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLElfLib::CElfWriter::destroy(pElfWriter);
|
|
||||||
delete[] pCompileData;
|
|
||||||
internalOptions.clear();
|
internalOptions.clear();
|
||||||
|
|
||||||
if (funcNotify != nullptr) {
|
if (funcNotify != nullptr) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Intel Corporation
|
* Copyright (c) 2017 - 2018, Intel Corporation
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -48,7 +48,7 @@ cl_int Program::getInfo(cl_program_info paramName, size_t paramValueSize,
|
|||||||
|
|
||||||
case CL_PROGRAM_BINARIES:
|
case CL_PROGRAM_BINARIES:
|
||||||
resolveProgramBinary();
|
resolveProgramBinary();
|
||||||
pSrc = elfBinary;
|
pSrc = elfBinary.data();
|
||||||
retSize = sizeof(void **);
|
retSize = sizeof(void **);
|
||||||
srcSize = elfBinarySize;
|
srcSize = elfBinarySize;
|
||||||
if (paramValue != nullptr) {
|
if (paramValue != nullptr) {
|
||||||
|
|||||||
@@ -40,12 +40,9 @@ cl_int Program::link(
|
|||||||
void *userData) {
|
void *userData) {
|
||||||
cl_int retVal = CL_SUCCESS;
|
cl_int retVal = CL_SUCCESS;
|
||||||
cl_program program;
|
cl_program program;
|
||||||
CLElfLib::CElfWriter *pElfWriter = nullptr;
|
|
||||||
Program *pInputProgObj;
|
Program *pInputProgObj;
|
||||||
size_t dataSize;
|
size_t dataSize;
|
||||||
char *pData = nullptr;
|
|
||||||
bool isCreateLibrary;
|
bool isCreateLibrary;
|
||||||
CLElfLib::SSectionNode sectionNode;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (((deviceList == nullptr) && (numDevices != 0)) ||
|
if (((deviceList == nullptr) && (numDevices != 0)) ||
|
||||||
@@ -81,7 +78,7 @@ cl_int Program::link(
|
|||||||
|
|
||||||
buildStatus = CL_BUILD_IN_PROGRESS;
|
buildStatus = CL_BUILD_IN_PROGRESS;
|
||||||
|
|
||||||
pElfWriter = CLElfLib::CElfWriter::create(CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_OBJECTS, CLElfLib::E_EH_MACHINE::EH_MACHINE_NONE, 0);
|
CLElfLib::CElfWriter elfWriter(CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_OBJECTS, CLElfLib::E_EH_MACHINE::EH_MACHINE_NONE, 0);
|
||||||
|
|
||||||
StackVec<const Program *, 16> inputProgramsInternal;
|
StackVec<const Program *, 16> inputProgramsInternal;
|
||||||
for (cl_uint i = 0; i < numInputPrograms; i++) {
|
for (cl_uint i = 0; i < numInputPrograms; i++) {
|
||||||
@@ -100,25 +97,17 @@ cl_int Program::link(
|
|||||||
retVal = CL_INVALID_PROGRAM;
|
retVal = CL_INVALID_PROGRAM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sectionNode.Name = "";
|
|
||||||
if (pInputProgObj->getIsSpirV()) {
|
|
||||||
sectionNode.Type = CLElfLib::E_SH_TYPE::SH_TYPE_SPIRV;
|
|
||||||
} else {
|
|
||||||
sectionNode.Type = CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_LLVM_BINARY;
|
|
||||||
}
|
|
||||||
sectionNode.Flags = CLElfLib::E_SH_FLAG::SH_FLAG_NONE;
|
|
||||||
sectionNode.pData = pInputProgObj->irBinary;
|
|
||||||
sectionNode.DataSize = static_cast<unsigned int>(pInputProgObj->irBinarySize);
|
|
||||||
|
|
||||||
pElfWriter->addSection(§ionNode);
|
elfWriter.addSection(CLElfLib::SSectionNode(pInputProgObj->getIsSpirV() ? CLElfLib::E_SH_TYPE::SH_TYPE_SPIRV : CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_LLVM_BINARY,
|
||||||
|
CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "", std::string(pInputProgObj->irBinary, pInputProgObj->irBinarySize), static_cast<uint32_t>(pInputProgObj->irBinarySize)));
|
||||||
}
|
}
|
||||||
if (retVal != CL_SUCCESS) {
|
if (retVal != CL_SUCCESS) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pElfWriter->resolveBinary(nullptr, dataSize);
|
dataSize = elfWriter.getTotalBinarySize();
|
||||||
pData = new char[dataSize];
|
CLElfLib::ElfBinaryStorage data(dataSize);
|
||||||
pElfWriter->resolveBinary(pData, dataSize);
|
elfWriter.resolveBinary(data);
|
||||||
|
|
||||||
CompilerInterface *pCompilerInterface = getCompilerInterface();
|
CompilerInterface *pCompilerInterface = getCompilerInterface();
|
||||||
if (!pCompilerInterface) {
|
if (!pCompilerInterface) {
|
||||||
@@ -128,7 +117,7 @@ cl_int Program::link(
|
|||||||
|
|
||||||
TranslationArgs inputArgs = {};
|
TranslationArgs inputArgs = {};
|
||||||
|
|
||||||
inputArgs.pInput = pData;
|
inputArgs.pInput = data.data();
|
||||||
inputArgs.InputSize = (uint32_t)dataSize;
|
inputArgs.InputSize = (uint32_t)dataSize;
|
||||||
inputArgs.pOptions = options.c_str();
|
inputArgs.pOptions = options.c_str();
|
||||||
inputArgs.OptionsSize = (uint32_t)options.length();
|
inputArgs.OptionsSize = (uint32_t)options.length();
|
||||||
@@ -173,8 +162,6 @@ cl_int Program::link(
|
|||||||
buildStatus = CL_BUILD_SUCCESS;
|
buildStatus = CL_BUILD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLElfLib::CElfWriter::destroy(pElfWriter);
|
|
||||||
delete[] pData;
|
|
||||||
internalOptions.clear();
|
internalOptions.clear();
|
||||||
|
|
||||||
if (funcNotify != nullptr) {
|
if (funcNotify != nullptr) {
|
||||||
|
|||||||
@@ -45,13 +45,8 @@ cl_int Program::processElfBinary(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (retVal == CL_SUCCESS) {
|
if (retVal == CL_SUCCESS) {
|
||||||
delete[] elfBinary;
|
|
||||||
elfBinarySize = 0;
|
|
||||||
|
|
||||||
elfBinary = new char[binarySize];
|
|
||||||
|
|
||||||
elfBinarySize = binarySize;
|
elfBinarySize = binarySize;
|
||||||
memcpy_s(elfBinary, elfBinarySize, pBinary, binarySize);
|
elfBinary = CLElfLib::ElfBinaryStorage(reinterpret_cast<const char *>(pBinary), reinterpret_cast<const char *>(reinterpret_cast<const char *>(pBinary) + binarySize));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retVal == CL_SUCCESS) {
|
if (retVal == CL_SUCCESS) {
|
||||||
@@ -148,13 +143,10 @@ cl_int Program::processElfBinary(
|
|||||||
}
|
}
|
||||||
|
|
||||||
cl_int Program::resolveProgramBinary() {
|
cl_int Program::resolveProgramBinary() {
|
||||||
cl_int retVal = CL_SUCCESS;
|
|
||||||
CLElfLib::E_EH_TYPE headerType;
|
CLElfLib::E_EH_TYPE headerType;
|
||||||
CLElfLib::CElfWriter *pElfWriter = nullptr;
|
|
||||||
|
|
||||||
if (isProgramBinaryResolved == false) {
|
if (isProgramBinaryResolved == false) {
|
||||||
delete[] elfBinary;
|
elfBinary.clear();
|
||||||
elfBinary = nullptr;
|
|
||||||
elfBinarySize = 0;
|
elfBinarySize = 0;
|
||||||
|
|
||||||
switch (programBinaryType) {
|
switch (programBinaryType) {
|
||||||
@@ -162,7 +154,7 @@ cl_int Program::resolveProgramBinary() {
|
|||||||
headerType = CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_EXECUTABLE;
|
headerType = CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_EXECUTABLE;
|
||||||
|
|
||||||
if (!genBinary || !genBinarySize) {
|
if (!genBinary || !genBinarySize) {
|
||||||
retVal = CL_INVALID_BINARY;
|
return CL_INVALID_BINARY;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -170,7 +162,7 @@ cl_int Program::resolveProgramBinary() {
|
|||||||
headerType = CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_LIBRARY;
|
headerType = CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_LIBRARY;
|
||||||
|
|
||||||
if (!irBinary || !irBinarySize) {
|
if (!irBinary || !irBinarySize) {
|
||||||
retVal = CL_INVALID_BINARY;
|
return CL_INVALID_BINARY;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -178,89 +170,40 @@ cl_int Program::resolveProgramBinary() {
|
|||||||
headerType = CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_OBJECTS;
|
headerType = CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_OBJECTS;
|
||||||
|
|
||||||
if (!irBinary || !irBinarySize) {
|
if (!irBinary || !irBinarySize) {
|
||||||
retVal = CL_INVALID_BINARY;
|
return CL_INVALID_BINARY;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
retVal = CL_INVALID_BINARY;
|
return CL_INVALID_BINARY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retVal == CL_SUCCESS) {
|
CLElfLib::CElfWriter elfWriter(headerType, CLElfLib::E_EH_MACHINE::EH_MACHINE_NONE, 0);
|
||||||
pElfWriter = CLElfLib::CElfWriter::create(headerType, CLElfLib::E_EH_MACHINE::EH_MACHINE_NONE, 0);
|
|
||||||
|
|
||||||
if (pElfWriter) {
|
elfWriter.addSection(CLElfLib::SSectionNode(CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_OPTIONS, CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "BuildOptions", options, static_cast<uint32_t>(strlen(options.c_str()) + 1u)));
|
||||||
CLElfLib::SSectionNode sectionNode;
|
std::string irBinaryTemp = irBinary ? std::string(irBinary, irBinarySize) : "";
|
||||||
|
// Add the LLVM component if available
|
||||||
// Always add the options string
|
elfWriter.addSection(CLElfLib::SSectionNode(getIsSpirV() ? CLElfLib::E_SH_TYPE::SH_TYPE_SPIRV : CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_LLVM_BINARY, CLElfLib::E_SH_FLAG::SH_FLAG_NONE,
|
||||||
sectionNode.Name = "BuildOptions";
|
headerType == CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_LIBRARY ? "Intel(R) OpenCL LLVM Archive" : "Intel(R) OpenCL LLVM Object", std::move(irBinaryTemp), static_cast<uint32_t>(irBinarySize)));
|
||||||
sectionNode.Type = CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_OPTIONS;
|
// Add the device binary if it exists
|
||||||
sectionNode.pData = (char *)options.c_str();
|
if (genBinary) {
|
||||||
sectionNode.DataSize = (uint32_t)(strlen(options.c_str()) + 1);
|
std::string genBinaryTemp = genBinary ? std::string(genBinary, genBinarySize) : "";
|
||||||
|
elfWriter.addSection(CLElfLib::SSectionNode(CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_DEV_BINARY, CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "Intel(R) OpenCL Device Binary", std::move(genBinaryTemp), static_cast<uint32_t>(genBinarySize)));
|
||||||
auto elfRetVal = pElfWriter->addSection(§ionNode);
|
|
||||||
|
|
||||||
if (elfRetVal) {
|
|
||||||
// Add the LLVM component if available
|
|
||||||
if (getIsSpirV()) {
|
|
||||||
sectionNode.Type = CLElfLib::E_SH_TYPE::SH_TYPE_SPIRV;
|
|
||||||
} else {
|
|
||||||
sectionNode.Type = CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_LLVM_BINARY;
|
|
||||||
}
|
|
||||||
if (headerType == CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_LIBRARY) {
|
|
||||||
sectionNode.Name = "Intel(R) OpenCL LLVM Archive";
|
|
||||||
sectionNode.pData = (char *)irBinary;
|
|
||||||
sectionNode.DataSize = (uint32_t)irBinarySize;
|
|
||||||
elfRetVal = pElfWriter->addSection(§ionNode);
|
|
||||||
} else {
|
|
||||||
sectionNode.Name = "Intel(R) OpenCL LLVM Object";
|
|
||||||
sectionNode.pData = (char *)irBinary;
|
|
||||||
sectionNode.DataSize = (uint32_t)irBinarySize;
|
|
||||||
elfRetVal = pElfWriter->addSection(§ionNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the device binary if it exists
|
|
||||||
if (elfRetVal && genBinary) {
|
|
||||||
sectionNode.Name = "Intel(R) OpenCL Device Binary";
|
|
||||||
sectionNode.Type = CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_DEV_BINARY;
|
|
||||||
sectionNode.pData = (char *)genBinary;
|
|
||||||
sectionNode.DataSize = (uint32_t)genBinarySize;
|
|
||||||
|
|
||||||
elfRetVal = pElfWriter->addSection(§ionNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the device debug data if it exists
|
|
||||||
if (elfRetVal && (debugData != nullptr)) {
|
|
||||||
sectionNode.Name = "Intel(R) OpenCL Device Debug";
|
|
||||||
sectionNode.Type = CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_DEV_DEBUG;
|
|
||||||
sectionNode.pData = debugData;
|
|
||||||
sectionNode.DataSize = (uint32_t)debugDataSize;
|
|
||||||
elfRetVal = pElfWriter->addSection(§ionNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elfRetVal) {
|
|
||||||
elfRetVal = pElfWriter->resolveBinary(elfBinary, elfBinarySize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elfRetVal) {
|
|
||||||
elfBinary = new char[elfBinarySize];
|
|
||||||
|
|
||||||
elfRetVal = pElfWriter->resolveBinary(elfBinary, elfBinarySize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elfRetVal) {
|
|
||||||
isProgramBinaryResolved = true;
|
|
||||||
} else {
|
|
||||||
retVal = CL_INVALID_BINARY;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
retVal = CL_OUT_OF_HOST_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLElfLib::CElfWriter::destroy(pElfWriter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the device debug data if it exists
|
||||||
|
if (debugData != nullptr) {
|
||||||
|
std::string debugDataTemp = debugData ? std::string(debugData, debugDataSize) : "";
|
||||||
|
elfWriter.addSection(CLElfLib::SSectionNode(CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_DEV_DEBUG, CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "Intel(R) OpenCL Device Debug", std::move(debugDataTemp), static_cast<uint32_t>(debugDataSize)));
|
||||||
|
}
|
||||||
|
|
||||||
|
elfBinarySize = elfWriter.getTotalBinarySize();
|
||||||
|
elfBinary = CLElfLib::ElfBinaryStorage(elfBinarySize);
|
||||||
|
elfWriter.resolveBinary(elfBinary);
|
||||||
|
isProgramBinaryResolved = true;
|
||||||
|
} else {
|
||||||
|
return CL_OUT_OF_HOST_MEMORY;
|
||||||
}
|
}
|
||||||
return retVal;
|
return CL_SUCCESS;
|
||||||
}
|
}
|
||||||
} // namespace OCLRT
|
} // namespace OCLRT
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ Program::Program(Context *context, bool isBuiltIn) : context(context), isBuiltIn
|
|||||||
blockKernelManager = new BlockKernelManager();
|
blockKernelManager = new BlockKernelManager();
|
||||||
pDevice = context ? context->getDevice(0) : nullptr;
|
pDevice = context ? context->getDevice(0) : nullptr;
|
||||||
numDevices = 1;
|
numDevices = 1;
|
||||||
elfBinary = nullptr;
|
|
||||||
elfBinarySize = 0;
|
elfBinarySize = 0;
|
||||||
genBinary = nullptr;
|
genBinary = nullptr;
|
||||||
genBinarySize = 0;
|
genBinarySize = 0;
|
||||||
@@ -115,8 +114,6 @@ Program::~Program() {
|
|||||||
delete[] debugData;
|
delete[] debugData;
|
||||||
debugData = nullptr;
|
debugData = nullptr;
|
||||||
|
|
||||||
delete[] elfBinary;
|
|
||||||
elfBinary = nullptr;
|
|
||||||
elfBinarySize = 0;
|
elfBinarySize = 0;
|
||||||
|
|
||||||
cleanCurrentKernelInfo();
|
cleanCurrentKernelInfo();
|
||||||
@@ -170,8 +167,6 @@ cl_int Program::createProgramFromBinary(
|
|||||||
cl_int Program::rebuildProgramFromIr() {
|
cl_int Program::rebuildProgramFromIr() {
|
||||||
cl_int retVal = CL_SUCCESS;
|
cl_int retVal = CL_SUCCESS;
|
||||||
size_t dataSize;
|
size_t dataSize;
|
||||||
char *pData = nullptr;
|
|
||||||
CLElfLib::CElfWriter *pElfWriter = nullptr;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (!Program::isValidLlvmBinary(irBinary, irBinarySize)) {
|
if (!Program::isValidLlvmBinary(irBinary, irBinarySize)) {
|
||||||
@@ -182,20 +177,14 @@ cl_int Program::rebuildProgramFromIr() {
|
|||||||
isSpirV = true;
|
isSpirV = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pElfWriter = CLElfLib::CElfWriter::create(CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_OBJECTS, CLElfLib::E_EH_MACHINE::EH_MACHINE_NONE, 0);
|
CLElfLib::CElfWriter elfWriter(CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_OBJECTS, CLElfLib::E_EH_MACHINE::EH_MACHINE_NONE, 0);
|
||||||
UNRECOVERABLE_IF(pElfWriter == nullptr);
|
|
||||||
|
|
||||||
CLElfLib::SSectionNode sectionNode;
|
elfWriter.addSection(CLElfLib::SSectionNode(isSpirV ? CLElfLib::E_SH_TYPE::SH_TYPE_SPIRV : CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_LLVM_BINARY,
|
||||||
sectionNode.Name = "";
|
CLElfLib::E_SH_FLAG::SH_FLAG_NONE, "", std::string(irBinary, irBinarySize), static_cast<uint32_t>(irBinarySize)));
|
||||||
sectionNode.Type = isSpirV ? CLElfLib::E_SH_TYPE::SH_TYPE_SPIRV : CLElfLib::E_SH_TYPE::SH_TYPE_OPENCL_LLVM_BINARY;
|
|
||||||
sectionNode.Flags = CLElfLib::E_SH_FLAG::SH_FLAG_NONE;
|
|
||||||
sectionNode.pData = irBinary;
|
|
||||||
sectionNode.DataSize = static_cast<unsigned int>(irBinarySize);
|
|
||||||
pElfWriter->addSection(§ionNode);
|
|
||||||
|
|
||||||
pElfWriter->resolveBinary(nullptr, dataSize);
|
dataSize = elfWriter.getTotalBinarySize();
|
||||||
pData = new char[dataSize];
|
CLElfLib::ElfBinaryStorage data(dataSize);
|
||||||
pElfWriter->resolveBinary(pData, dataSize);
|
elfWriter.resolveBinary(data);
|
||||||
|
|
||||||
CompilerInterface *pCompilerInterface = getCompilerInterface();
|
CompilerInterface *pCompilerInterface = getCompilerInterface();
|
||||||
if (nullptr == pCompilerInterface) {
|
if (nullptr == pCompilerInterface) {
|
||||||
@@ -204,12 +193,12 @@ cl_int Program::rebuildProgramFromIr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TranslationArgs inputArgs = {};
|
TranslationArgs inputArgs = {};
|
||||||
inputArgs.pInput = pData;
|
inputArgs.pInput = data.data();
|
||||||
inputArgs.InputSize = static_cast<unsigned int>(dataSize);
|
inputArgs.InputSize = static_cast<uint32_t>(dataSize);
|
||||||
inputArgs.pOptions = options.c_str();
|
inputArgs.pOptions = options.c_str();
|
||||||
inputArgs.OptionsSize = static_cast<unsigned int>(options.length());
|
inputArgs.OptionsSize = static_cast<uint32_t>(options.length());
|
||||||
inputArgs.pInternalOptions = internalOptions.c_str();
|
inputArgs.pInternalOptions = internalOptions.c_str();
|
||||||
inputArgs.InternalOptionsSize = static_cast<unsigned int>(internalOptions.length());
|
inputArgs.InternalOptionsSize = static_cast<uint32_t>(internalOptions.length());
|
||||||
inputArgs.pTracingOptions = nullptr;
|
inputArgs.pTracingOptions = nullptr;
|
||||||
inputArgs.TracingOptionsCount = 0;
|
inputArgs.TracingOptionsCount = 0;
|
||||||
|
|
||||||
@@ -228,9 +217,6 @@ cl_int Program::rebuildProgramFromIr() {
|
|||||||
isProgramBinaryResolved = true;
|
isProgramBinaryResolved = true;
|
||||||
} while (false);
|
} while (false);
|
||||||
|
|
||||||
CLElfLib::CElfWriter::destroy(pElfWriter);
|
|
||||||
delete[] pData;
|
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,6 +260,16 @@ cl_int Program::getSource(char *&pBinary, unsigned int &dataSize) const {
|
|||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cl_int Program::getSource(std::string &binary) const {
|
||||||
|
cl_int retVal = CL_INVALID_PROGRAM;
|
||||||
|
binary = {};
|
||||||
|
if (!sourceCode.empty()) {
|
||||||
|
binary = sourceCode;
|
||||||
|
retVal = CL_SUCCESS;
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
void Program::storeGenBinary(
|
void Program::storeGenBinary(
|
||||||
const void *pSrc,
|
const void *pSrc,
|
||||||
const size_t srcSize) {
|
const size_t srcSize) {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "runtime/helpers/base_object.h"
|
#include "runtime/helpers/base_object.h"
|
||||||
#include "runtime/helpers/stdio.h"
|
#include "runtime/helpers/stdio.h"
|
||||||
#include "runtime/helpers/string_helpers.h"
|
#include "runtime/helpers/string_helpers.h"
|
||||||
|
#include "elf/writer.h"
|
||||||
#include "igfxfmid.h"
|
#include "igfxfmid.h"
|
||||||
#include "patch_list.h"
|
#include "patch_list.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -178,6 +179,8 @@ class Program : public BaseObject<_cl_program> {
|
|||||||
|
|
||||||
cl_int getSource(char *&pBinary, unsigned int &dataSize) const;
|
cl_int getSource(char *&pBinary, unsigned int &dataSize) const;
|
||||||
|
|
||||||
|
cl_int getSource(std::string &binary) const;
|
||||||
|
|
||||||
void storeGenBinary(const void *pSrc, const size_t srcSize);
|
void storeGenBinary(const void *pSrc, const size_t srcSize);
|
||||||
|
|
||||||
char *getGenBinary(size_t &genBinarySize) const {
|
char *getGenBinary(size_t &genBinarySize) const {
|
||||||
@@ -297,7 +300,7 @@ class Program : public BaseObject<_cl_program> {
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
cl_program_binary_type programBinaryType;
|
cl_program_binary_type programBinaryType;
|
||||||
bool isSpirV = false;
|
bool isSpirV = false;
|
||||||
char* elfBinary;
|
CLElfLib::ElfBinaryStorage elfBinary;
|
||||||
size_t elfBinarySize;
|
size_t elfBinarySize;
|
||||||
|
|
||||||
char* genBinary;
|
char* genBinary;
|
||||||
|
|||||||
@@ -39,17 +39,6 @@ struct ElfTests : public MemoryManagementFixture,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(ElfTests, Create_Delete_Writer_Simple) {
|
|
||||||
CElfWriter *pWriter = CElfWriter::create(
|
|
||||||
E_EH_TYPE::EH_TYPE_EXECUTABLE,
|
|
||||||
E_EH_MACHINE::EH_MACHINE_NONE,
|
|
||||||
0);
|
|
||||||
EXPECT_NE((CElfWriter *)NULL, pWriter);
|
|
||||||
|
|
||||||
CElfWriter::destroy(pWriter);
|
|
||||||
EXPECT_EQ((CElfWriter *)NULL, pWriter);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ElfTests, Create_Reader_NULL_Binary) {
|
TEST_F(ElfTests, Create_Reader_NULL_Binary) {
|
||||||
char *pBinary = NULL;
|
char *pBinary = NULL;
|
||||||
CElfReader *pReader = CElfReader::create(pBinary, 1);
|
CElfReader *pReader = CElfReader::create(pBinary, 1);
|
||||||
@@ -68,130 +57,75 @@ TEST_F(ElfTests, Create_Reader_Garbage_Binary) {
|
|||||||
delete[] pBinary;
|
delete[] pBinary;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ElfTests, Create_Delete_Reader_Writer_NoCheck) {
|
TEST_F(ElfTests, givenSectionDataWhenWriteToBinaryThenSectionIsAdded) {
|
||||||
CElfWriter *pWriter = CElfWriter::create(
|
class MockElfWriter : public CElfWriter {
|
||||||
E_EH_TYPE::EH_TYPE_EXECUTABLE,
|
public:
|
||||||
E_EH_MACHINE::EH_MACHINE_NONE,
|
MockElfWriter() : CElfWriter(E_EH_TYPE::EH_TYPE_EXECUTABLE, E_EH_MACHINE::EH_MACHINE_NONE, 0) {}
|
||||||
0);
|
using CElfWriter::nodeQueue;
|
||||||
EXPECT_NE((CElfWriter *)NULL, pWriter);
|
|
||||||
|
|
||||||
size_t dataSize;
|
|
||||||
pWriter->resolveBinary(NULL, dataSize);
|
|
||||||
|
|
||||||
char *pBinary = new char[dataSize];
|
|
||||||
if (pBinary) {
|
|
||||||
pWriter->resolveBinary(pBinary, dataSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
CElfReader *pReader = CElfReader::create(pBinary, dataSize);
|
|
||||||
ASSERT_NE(nullptr, pReader);
|
|
||||||
EXPECT_NE(nullptr, pReader->getElfHeader());
|
|
||||||
|
|
||||||
CElfReader::destroy(pReader);
|
|
||||||
EXPECT_EQ((CElfReader *)NULL, pReader);
|
|
||||||
|
|
||||||
CElfWriter::destroy(pWriter);
|
|
||||||
EXPECT_EQ((CElfWriter *)NULL, pWriter);
|
|
||||||
|
|
||||||
delete[] pBinary;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ElfTests, givenNullptrWriterWhenDestroyThenDontCrash) {
|
|
||||||
CElfWriter *ptr = nullptr;
|
|
||||||
CElfWriter::destroy(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ElfTests, givenElfWriterWhenNullptrThenFalseIsReturned) {
|
|
||||||
CElfWriter *pWriter = CElfWriter::create(
|
|
||||||
E_EH_TYPE::EH_TYPE_EXECUTABLE,
|
|
||||||
E_EH_MACHINE::EH_MACHINE_NONE,
|
|
||||||
0);
|
|
||||||
ASSERT_NE(nullptr, pWriter);
|
|
||||||
|
|
||||||
auto ret = pWriter->addSection(nullptr);
|
|
||||||
EXPECT_FALSE(ret);
|
|
||||||
|
|
||||||
CElfWriter::destroy(pWriter);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(ElfTests, givenElfWriterWhenSectionAndFailuresThenFalseIsReturned) {
|
|
||||||
InjectedFunction method = [](size_t failureIndex) {
|
|
||||||
CElfWriter *pWriter = CElfWriter::create(
|
|
||||||
E_EH_TYPE::EH_TYPE_EXECUTABLE,
|
|
||||||
E_EH_MACHINE::EH_MACHINE_NONE,
|
|
||||||
0);
|
|
||||||
if (nonfailingAllocation == failureIndex) {
|
|
||||||
ASSERT_NE(nullptr, pWriter);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pWriter != nullptr) {
|
|
||||||
char sectionData[16];
|
|
||||||
memset(sectionData, 0xdeadbeef, 4);
|
|
||||||
|
|
||||||
SSectionNode sectionNode;
|
|
||||||
sectionNode.DataSize = 16;
|
|
||||||
sectionNode.pData = sectionData;
|
|
||||||
sectionNode.Flags = E_SH_FLAG::SH_FLAG_WRITE;
|
|
||||||
sectionNode.Name = "Steve";
|
|
||||||
sectionNode.Type = E_SH_TYPE::SH_TYPE_OPENCL_SOURCE;
|
|
||||||
|
|
||||||
auto ret = pWriter->addSection(§ionNode);
|
|
||||||
if (nonfailingAllocation == failureIndex) {
|
|
||||||
EXPECT_TRUE(ret);
|
|
||||||
} else {
|
|
||||||
EXPECT_FALSE(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
CElfWriter::destroy(pWriter);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
injectFailures(method);
|
|
||||||
|
MockElfWriter writer;
|
||||||
|
std::string data{"data pattern"};
|
||||||
|
|
||||||
|
writer.addSection(SSectionNode(E_SH_TYPE::SH_TYPE_OPENCL_SOURCE, E_SH_FLAG::SH_FLAG_WRITE, "Steve", data, static_cast<uint32_t>(data.size())));
|
||||||
|
|
||||||
|
ASSERT_EQ(2u, writer.nodeQueue.size());
|
||||||
|
// remove first (default) section
|
||||||
|
writer.nodeQueue.pop();
|
||||||
|
EXPECT_EQ(E_SH_TYPE::SH_TYPE_OPENCL_SOURCE, writer.nodeQueue.front().type);
|
||||||
|
EXPECT_EQ(E_SH_FLAG::SH_FLAG_WRITE, writer.nodeQueue.front().flag);
|
||||||
|
EXPECT_EQ("Steve", writer.nodeQueue.front().name);
|
||||||
|
EXPECT_EQ(data, writer.nodeQueue.front().data);
|
||||||
|
EXPECT_EQ(static_cast<uint32_t>(data.size()), writer.nodeQueue.front().dataSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ElfTests, givenElfWriterWhenPatchNullptrThenFalseIsReturned) {
|
TEST_F(ElfTests, givenCElfWriterWhenPatchElfHeaderThenDefaultAreSet) {
|
||||||
CElfWriter *pWriter = CElfWriter::create(
|
class MockElfWriter : public CElfWriter {
|
||||||
E_EH_TYPE::EH_TYPE_EXECUTABLE,
|
public:
|
||||||
E_EH_MACHINE::EH_MACHINE_NONE,
|
MockElfWriter() : CElfWriter(E_EH_TYPE::EH_TYPE_EXECUTABLE, E_EH_MACHINE::EH_MACHINE_NONE, 0) {}
|
||||||
0);
|
using CElfWriter::patchElfHeader;
|
||||||
ASSERT_NE(nullptr, pWriter);
|
};
|
||||||
|
|
||||||
auto ret = pWriter->patchElfHeader(nullptr);
|
MockElfWriter writer;
|
||||||
EXPECT_FALSE(ret);
|
|
||||||
|
|
||||||
CElfWriter::destroy(pWriter);
|
SElf64Header elfHeader;
|
||||||
|
|
||||||
|
writer.patchElfHeader(elfHeader);
|
||||||
|
|
||||||
|
EXPECT_TRUE(elfHeader.Identity[ELFConstants::idIdxMagic0] == ELFConstants::elfMag0);
|
||||||
|
EXPECT_TRUE(elfHeader.Identity[ELFConstants::idIdxMagic1] == ELFConstants::elfMag1);
|
||||||
|
EXPECT_TRUE(elfHeader.Identity[ELFConstants::idIdxMagic2] == ELFConstants::elfMag2);
|
||||||
|
EXPECT_TRUE(elfHeader.Identity[ELFConstants::idIdxMagic3] == ELFConstants::elfMag3);
|
||||||
|
EXPECT_TRUE(elfHeader.Identity[ELFConstants::idIdxClass] == static_cast<uint32_t>(E_EH_CLASS::EH_CLASS_64));
|
||||||
|
EXPECT_TRUE(elfHeader.Identity[ELFConstants::idIdxVersion] == static_cast<uint32_t>(E_EHT_VERSION::EH_VERSION_CURRENT));
|
||||||
|
|
||||||
|
EXPECT_TRUE(elfHeader.Type == E_EH_TYPE::EH_TYPE_EXECUTABLE);
|
||||||
|
EXPECT_TRUE(elfHeader.Machine == E_EH_MACHINE::EH_MACHINE_NONE);
|
||||||
|
EXPECT_TRUE(elfHeader.Flags == static_cast<uint32_t>(0));
|
||||||
|
EXPECT_TRUE(elfHeader.ElfHeaderSize == static_cast<uint32_t>(sizeof(SElf64Header)));
|
||||||
|
EXPECT_TRUE(elfHeader.SectionHeaderEntrySize == static_cast<uint32_t>(sizeof(SElf64SectionHeader)));
|
||||||
|
EXPECT_TRUE(elfHeader.NumSectionHeaderEntries == 1);
|
||||||
|
EXPECT_TRUE(elfHeader.SectionHeadersOffset == static_cast<uint32_t>(sizeof(SElf64Header)));
|
||||||
|
EXPECT_TRUE(elfHeader.SectionNameTableIndex == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ElfTests, Write_Read_Section_Data_By_Name) {
|
TEST_F(ElfTests, givenSectionDataWhenWriteToBinaryThenSectionCanBeReadByName) {
|
||||||
CElfWriter *pWriter = CElfWriter::create(
|
CElfWriter writer(E_EH_TYPE::EH_TYPE_EXECUTABLE, E_EH_MACHINE::EH_MACHINE_NONE, 0);
|
||||||
E_EH_TYPE::EH_TYPE_EXECUTABLE,
|
|
||||||
E_EH_MACHINE::EH_MACHINE_NONE,
|
|
||||||
0);
|
|
||||||
EXPECT_NE((CElfWriter *)NULL, pWriter);
|
|
||||||
|
|
||||||
char sectionData[16];
|
char sectionData[16];
|
||||||
memset(sectionData, 0xdeadbeef, 4);
|
memset(sectionData, 0xdeadbeef, 4);
|
||||||
|
|
||||||
SSectionNode sectionNode;
|
writer.addSection(SSectionNode(E_SH_TYPE::SH_TYPE_OPENCL_SOURCE, E_SH_FLAG::SH_FLAG_WRITE, "Steve", std::string(sectionData, 16u), 16u));
|
||||||
sectionNode.DataSize = 16;
|
|
||||||
sectionNode.pData = sectionData;
|
|
||||||
sectionNode.Flags = E_SH_FLAG::SH_FLAG_WRITE;
|
|
||||||
sectionNode.Name = "Steve";
|
|
||||||
sectionNode.Type = E_SH_TYPE::SH_TYPE_OPENCL_SOURCE;
|
|
||||||
|
|
||||||
pWriter->addSection(§ionNode);
|
size_t binarySize = writer.getTotalBinarySize();
|
||||||
|
|
||||||
size_t binarySize;
|
ElfBinaryStorage binary(binarySize);
|
||||||
pWriter->resolveBinary(NULL, binarySize);
|
writer.resolveBinary(binary);
|
||||||
|
|
||||||
char *pBinary = new char[binarySize];
|
CElfReader *pReader = CElfReader::create(binary.data(), binarySize);
|
||||||
if (pBinary) {
|
EXPECT_NE((CElfReader *)nullptr, pReader);
|
||||||
pWriter->resolveBinary(pBinary, binarySize);
|
|
||||||
}
|
|
||||||
|
|
||||||
CElfReader *pReader = CElfReader::create(pBinary, binarySize);
|
char *pData = nullptr;
|
||||||
EXPECT_NE((CElfReader *)NULL, pReader);
|
|
||||||
|
|
||||||
char *pData = NULL;
|
|
||||||
size_t dataSize = 0;
|
size_t dataSize = 0;
|
||||||
auto retVal = pReader->getSectionData("Steve", pData, dataSize);
|
auto retVal = pReader->getSectionData("Steve", pData, dataSize);
|
||||||
|
|
||||||
@@ -202,45 +136,26 @@ TEST_F(ElfTests, Write_Read_Section_Data_By_Name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CElfReader::destroy(pReader);
|
CElfReader::destroy(pReader);
|
||||||
EXPECT_EQ((CElfReader *)NULL, pReader);
|
EXPECT_EQ((CElfReader *)nullptr, pReader);
|
||||||
|
|
||||||
CElfWriter::destroy(pWriter);
|
|
||||||
EXPECT_EQ((CElfWriter *)NULL, pWriter);
|
|
||||||
|
|
||||||
delete[] pBinary;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ElfTests, Write_Read_Section_Data_By_Index) {
|
TEST_F(ElfTests, givenSectionDataWhenWriteToBinaryThenSectionCanBeReadByID) {
|
||||||
CElfWriter *pWriter = CElfWriter::create(
|
CElfWriter writer(E_EH_TYPE::EH_TYPE_EXECUTABLE, E_EH_MACHINE::EH_MACHINE_NONE, 0);
|
||||||
E_EH_TYPE::EH_TYPE_EXECUTABLE,
|
|
||||||
E_EH_MACHINE::EH_MACHINE_NONE,
|
|
||||||
0);
|
|
||||||
EXPECT_NE((CElfWriter *)NULL, pWriter);
|
|
||||||
|
|
||||||
char sectionData[16];
|
char sectionData[16];
|
||||||
memset(sectionData, 0xdeadbeef, 4);
|
memset(sectionData, 0xdeadbeef, 4);
|
||||||
|
|
||||||
SSectionNode sectionNode;
|
writer.addSection(SSectionNode(E_SH_TYPE::SH_TYPE_OPENCL_SOURCE, E_SH_FLAG::SH_FLAG_WRITE, "", std::string(sectionData, 16u), 16u));
|
||||||
sectionNode.DataSize = 16;
|
|
||||||
sectionNode.pData = sectionData;
|
|
||||||
sectionNode.Flags = E_SH_FLAG::SH_FLAG_WRITE;
|
|
||||||
sectionNode.Name = "";
|
|
||||||
sectionNode.Type = E_SH_TYPE::SH_TYPE_OPENCL_SOURCE;
|
|
||||||
|
|
||||||
pWriter->addSection(§ionNode);
|
size_t binarySize = writer.getTotalBinarySize();
|
||||||
|
|
||||||
size_t binarySize;
|
ElfBinaryStorage binary(binarySize);
|
||||||
pWriter->resolveBinary(NULL, binarySize);
|
writer.resolveBinary(binary);
|
||||||
|
|
||||||
char *pBinary = new char[binarySize];
|
CElfReader *pReader = CElfReader::create(binary.data(), binarySize);
|
||||||
if (pBinary) {
|
EXPECT_NE((CElfReader *)nullptr, pReader);
|
||||||
pWriter->resolveBinary(pBinary, binarySize);
|
|
||||||
}
|
|
||||||
|
|
||||||
CElfReader *pReader = CElfReader::create(pBinary, binarySize);
|
char *pData = nullptr;
|
||||||
EXPECT_NE((CElfReader *)NULL, pReader);
|
|
||||||
|
|
||||||
char *pData = NULL;
|
|
||||||
size_t dataSize = 0;
|
size_t dataSize = 0;
|
||||||
auto retVal = pReader->getSectionData(1, pData, dataSize);
|
auto retVal = pReader->getSectionData(1, pData, dataSize);
|
||||||
|
|
||||||
@@ -251,10 +166,5 @@ TEST_F(ElfTests, Write_Read_Section_Data_By_Index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CElfReader::destroy(pReader);
|
CElfReader::destroy(pReader);
|
||||||
EXPECT_EQ((CElfReader *)NULL, pReader);
|
EXPECT_EQ((CElfReader *)nullptr, pReader);
|
||||||
|
}
|
||||||
CElfWriter::destroy(pWriter);
|
|
||||||
EXPECT_EQ((CElfWriter *)NULL, pWriter);
|
|
||||||
|
|
||||||
delete[] pBinary;
|
|
||||||
}
|
|
||||||
@@ -93,7 +93,7 @@ class MockOfflineCompiler : public OfflineCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *getElfBinary() {
|
char *getElfBinary() {
|
||||||
return elfBinary;
|
return elfBinary.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getElfBinarySize() {
|
size_t getElfBinarySize() {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ TEST_F(ProcessElfBinaryTests, NullBinary) {
|
|||||||
cl_int retVal = processElfBinary(nullptr, 0, binaryVersion);
|
cl_int retVal = processElfBinary(nullptr, 0, binaryVersion);
|
||||||
|
|
||||||
EXPECT_EQ(CL_INVALID_BINARY, retVal);
|
EXPECT_EQ(CL_INVALID_BINARY, retVal);
|
||||||
EXPECT_EQ(nullptr, elfBinary);
|
EXPECT_TRUE(elfBinary.empty());
|
||||||
EXPECT_EQ(0u, elfBinarySize);
|
EXPECT_EQ(0u, elfBinarySize);
|
||||||
EXPECT_NE(0u, binaryVersion);
|
EXPECT_NE(0u, binaryVersion);
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ TEST_F(ProcessElfBinaryTests, InvalidBinary) {
|
|||||||
cl_int retVal = processElfBinary(pBinary, binarySize, binaryVersion);
|
cl_int retVal = processElfBinary(pBinary, binarySize, binaryVersion);
|
||||||
|
|
||||||
EXPECT_EQ(CL_INVALID_BINARY, retVal);
|
EXPECT_EQ(CL_INVALID_BINARY, retVal);
|
||||||
EXPECT_EQ(nullptr, elfBinary);
|
EXPECT_TRUE(elfBinary.empty());
|
||||||
EXPECT_EQ(0u, elfBinarySize);
|
EXPECT_EQ(0u, elfBinarySize);
|
||||||
EXPECT_NE(0u, binaryVersion);
|
EXPECT_NE(0u, binaryVersion);
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ TEST_F(ProcessElfBinaryTests, ValidBinary) {
|
|||||||
cl_int retVal = processElfBinary(pBinary, binarySize, binaryVersion);
|
cl_int retVal = processElfBinary(pBinary, binarySize, binaryVersion);
|
||||||
|
|
||||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||||
EXPECT_EQ(0, memcmp(pBinary, elfBinary, binarySize));
|
EXPECT_EQ(0, memcmp(pBinary, elfBinary.data(), binarySize));
|
||||||
EXPECT_NE(0u, binaryVersion);
|
EXPECT_NE(0u, binaryVersion);
|
||||||
deleteDataReadFromFile(pBinary);
|
deleteDataReadFromFile(pBinary);
|
||||||
}
|
}
|
||||||
@@ -87,17 +87,17 @@ TEST_F(ProcessElfBinaryTests, ValidSpirvBinary) {
|
|||||||
//clGetProgramInfo => SPIR-V stored as ELF binary
|
//clGetProgramInfo => SPIR-V stored as ELF binary
|
||||||
cl_int retVal = resolveProgramBinary();
|
cl_int retVal = resolveProgramBinary();
|
||||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||||
EXPECT_NE(nullptr, elfBinary);
|
EXPECT_FALSE(elfBinary.empty());
|
||||||
EXPECT_NE(0u, elfBinarySize);
|
EXPECT_NE(0u, elfBinarySize);
|
||||||
|
|
||||||
//use ELF reader to parse and validate ELF binary
|
//use ELF reader to parse and validate ELF binary
|
||||||
CLElfLib::CElfReader *pElfReader = CLElfLib::CElfReader::create(
|
CLElfLib::CElfReader *pElfReader = CLElfLib::CElfReader::create(
|
||||||
reinterpret_cast<const char *>(elfBinary), elfBinarySize);
|
reinterpret_cast<const char *>(elfBinary.data()), elfBinarySize);
|
||||||
ASSERT_NE(nullptr, pElfReader);
|
ASSERT_NE(nullptr, pElfReader);
|
||||||
const CLElfLib::SElf64Header *pElfHeader = pElfReader->getElfHeader();
|
const CLElfLib::SElf64Header *pElfHeader = pElfReader->getElfHeader();
|
||||||
ASSERT_NE(nullptr, pElfHeader);
|
ASSERT_NE(nullptr, pElfHeader);
|
||||||
EXPECT_EQ(pElfHeader->Type, CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_LIBRARY);
|
EXPECT_EQ(pElfHeader->Type, CLElfLib::E_EH_TYPE::EH_TYPE_OPENCL_LIBRARY);
|
||||||
EXPECT_TRUE(CLElfLib::CElfReader::isValidElf64(elfBinary, elfBinarySize));
|
EXPECT_TRUE(CLElfLib::CElfReader::isValidElf64(elfBinary.data(), elfBinarySize));
|
||||||
|
|
||||||
//check if ELF binary contains section SH_TYPE_SPIRV
|
//check if ELF binary contains section SH_TYPE_SPIRV
|
||||||
bool hasSpirvSection = false;
|
bool hasSpirvSection = false;
|
||||||
@@ -115,7 +115,7 @@ TEST_F(ProcessElfBinaryTests, ValidSpirvBinary) {
|
|||||||
isSpirV = false;
|
isSpirV = false;
|
||||||
uint32_t elfBinaryVersion;
|
uint32_t elfBinaryVersion;
|
||||||
auto pElfBinary = std::unique_ptr<char>(new char[elfBinarySize]);
|
auto pElfBinary = std::unique_ptr<char>(new char[elfBinarySize]);
|
||||||
memcpy_s(pElfBinary.get(), elfBinarySize, elfBinary, elfBinarySize);
|
memcpy_s(pElfBinary.get(), elfBinarySize, elfBinary.data(), elfBinarySize);
|
||||||
retVal = processElfBinary(pElfBinary.get(), elfBinarySize, elfBinaryVersion);
|
retVal = processElfBinary(pElfBinary.get(), elfBinarySize, elfBinaryVersion);
|
||||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||||
EXPECT_TRUE(isSpirV);
|
EXPECT_TRUE(isSpirV);
|
||||||
@@ -151,7 +151,7 @@ TEST_P(ProcessElfBinaryTestsWithBinaryType, GivenBinaryTypeWhenResolveProgramThe
|
|||||||
memcpy_s(pTmpOptions, optionsSize, options.c_str(), optionsSize);
|
memcpy_s(pTmpOptions, optionsSize, options.c_str(), optionsSize);
|
||||||
|
|
||||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||||
EXPECT_EQ(0, memcmp(pBinary, elfBinary, binarySize));
|
EXPECT_EQ(0, memcmp(pBinary, elfBinary.data(), binarySize));
|
||||||
EXPECT_NE(0u, binaryVersion);
|
EXPECT_NE(0u, binaryVersion);
|
||||||
|
|
||||||
// delete program's elf reference to force a resolve
|
// delete program's elf reference to force a resolve
|
||||||
@@ -184,7 +184,7 @@ TEST_F(ProcessElfBinaryTests, BackToBack) {
|
|||||||
cl_int retVal = processElfBinary(pBinary, binarySize, binaryVersion);
|
cl_int retVal = processElfBinary(pBinary, binarySize, binaryVersion);
|
||||||
|
|
||||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||||
EXPECT_EQ(0, memcmp(pBinary, elfBinary, binarySize));
|
EXPECT_EQ(0, memcmp(pBinary, elfBinary.data(), binarySize));
|
||||||
EXPECT_NE(0u, binaryVersion);
|
EXPECT_NE(0u, binaryVersion);
|
||||||
deleteDataReadFromFile(pBinary);
|
deleteDataReadFromFile(pBinary);
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ TEST_F(ProcessElfBinaryTests, BackToBack) {
|
|||||||
retVal = processElfBinary(pBinary, binarySize, binaryVersion);
|
retVal = processElfBinary(pBinary, binarySize, binaryVersion);
|
||||||
|
|
||||||
EXPECT_EQ(CL_SUCCESS, retVal);
|
EXPECT_EQ(CL_SUCCESS, retVal);
|
||||||
EXPECT_EQ(0, memcmp(pBinary, elfBinary, binarySize));
|
EXPECT_EQ(0, memcmp(pBinary, elfBinary.data(), binarySize));
|
||||||
EXPECT_NE(0u, binaryVersion);
|
EXPECT_NE(0u, binaryVersion);
|
||||||
deleteDataReadFromFile(pBinary);
|
deleteDataReadFromFile(pBinary);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user