mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-15 13:01:45 +08:00

- 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
119 lines
5.0 KiB
C++
119 lines
5.0 KiB
C++
/*
|
|
* Copyright (c) 2017 - 2018, Intel Corporation
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included
|
|
* in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
#include "writer.h"
|
|
#include <cstring>
|
|
|
|
// Need for linux compatibility with memcpy_s
|
|
#include "runtime/helpers/string.h"
|
|
|
|
namespace CLElfLib {
|
|
void CElfWriter::resolveBinary(ElfBinaryStorage &binary) {
|
|
SElf64SectionHeader *curSectionHeader = nullptr;
|
|
char *data = 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
|
|
while (nodeQueue.empty() == false) {
|
|
// Copy data into the section header
|
|
const auto &queueFront = nodeQueue.front();
|
|
|
|
curSectionHeader->Type = queueFront.type;
|
|
curSectionHeader->Flags = queueFront.flag;
|
|
curSectionHeader->DataSize = queueFront.dataSize;
|
|
curSectionHeader->DataOffset = data - binary.data();
|
|
curSectionHeader->Name = static_cast<Elf64_Word>(curString - stringTable);
|
|
curSectionHeader = reinterpret_cast<SElf64SectionHeader *>(reinterpret_cast<unsigned char *>(curSectionHeader) + sizeof(SElf64SectionHeader));
|
|
|
|
// copy the data, move the data pointer
|
|
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) {
|
|
// Setup the identity
|
|
binary.Identity[ELFConstants::idIdxMagic0] = ELFConstants::elfMag0;
|
|
binary.Identity[ELFConstants::idIdxMagic1] = ELFConstants::elfMag1;
|
|
binary.Identity[ELFConstants::idIdxMagic2] = ELFConstants::elfMag2;
|
|
binary.Identity[ELFConstants::idIdxMagic3] = ELFConstants::elfMag3;
|
|
binary.Identity[ELFConstants::idIdxClass] = static_cast<uint32_t>(E_EH_CLASS::EH_CLASS_64);
|
|
binary.Identity[ELFConstants::idIdxVersion] = static_cast<uint32_t>(E_EHT_VERSION::EH_VERSION_CURRENT);
|
|
|
|
// Add other non-zero info
|
|
binary.Type = type;
|
|
binary.Machine = machine;
|
|
binary.Flags = static_cast<uint32_t>(flag);
|
|
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
|
|
}
|
|
} // namespace CLElfLib
|