mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-21 09:14:47 +08:00
feature: Improving elf rewriter - preserving strings
Original string section needs to be preserved so that symbol table does not get broken. Related-To: NEO-10190 Signed-off-by: Chodor, Jaroslaw <jaroslaw.chodor@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
fbb8fa7dea
commit
4116dd5c9e
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace NEO {
|
||||
@@ -25,15 +26,39 @@ struct StringSectionBuilder {
|
||||
undefStringIdx = 0U;
|
||||
}
|
||||
|
||||
void setInitialStringsTab(ArrayRef<const uint8_t> data) {
|
||||
DEBUG_BREAK_IF(stringTable.size() > 1);
|
||||
stringTable.assign(reinterpret_cast<const char *>(data.begin()), reinterpret_cast<const char *>(data.end()));
|
||||
if (stringTable.size() < 1) {
|
||||
stringTable.push_back('\0');
|
||||
}
|
||||
if (*stringTable.rbegin() != '\0') {
|
||||
stringTable.push_back('\0');
|
||||
}
|
||||
auto it = stringTable.begin() + 1;
|
||||
while (it != stringTable.end()) {
|
||||
stringOffsetsMap[std::string(&*it)] = static_cast<uint32_t>(it - stringTable.begin());
|
||||
while (*it != '\0') {
|
||||
++it;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t appendString(ConstStringRef str) {
|
||||
if (str.empty()) {
|
||||
return undefStringIdx;
|
||||
}
|
||||
auto existingEntry = stringOffsetsMap.find(str.str());
|
||||
if (stringOffsetsMap.end() != existingEntry) {
|
||||
return existingEntry->second;
|
||||
}
|
||||
uint32_t offset = static_cast<uint32_t>(stringTable.size());
|
||||
stringTable.insert(stringTable.end(), str.begin(), str.end());
|
||||
if (str[str.size() - 1] != '\0') {
|
||||
stringTable.push_back('\0');
|
||||
}
|
||||
stringOffsetsMap[str.str()] = offset;
|
||||
return offset;
|
||||
}
|
||||
|
||||
@@ -47,6 +72,7 @@ struct StringSectionBuilder {
|
||||
|
||||
protected:
|
||||
std::vector<char> stringTable;
|
||||
std::unordered_map<std::string, uint32_t> stringOffsetsMap;
|
||||
uint32_t undefStringIdx;
|
||||
};
|
||||
|
||||
@@ -55,6 +81,10 @@ struct ElfEncoder {
|
||||
ElfEncoder(bool addUndefSectionHeader = true, bool addHeaderSectionNamesSection = true,
|
||||
typename ElfSectionHeaderTypes<numBits>::AddrAlign defaultDataAlignment = 8U);
|
||||
|
||||
void setInitialStringsTab(ArrayRef<const uint8_t> data) {
|
||||
strSecBuilder.setInitialStringsTab(data);
|
||||
}
|
||||
|
||||
ElfSectionHeader<numBits> &appendSection(const ElfSectionHeader<numBits> §ionHeader, const ArrayRef<const uint8_t> sectionData);
|
||||
ElfProgramHeader<numBits> &appendSegment(const ElfProgramHeader<numBits> &programHeader, const ArrayRef<const uint8_t> segmentData);
|
||||
|
||||
|
||||
@@ -22,37 +22,37 @@ namespace NEO {
|
||||
|
||||
namespace Elf {
|
||||
|
||||
template <ElfIdentifierClass NumBits = NEO::Elf::EI_CLASS_64>
|
||||
template <ElfIdentifierClass numBits = NEO::Elf::EI_CLASS_64>
|
||||
struct MutableSectionHeader {
|
||||
MutableSectionHeader(const std::string &name, const NEO::Elf::ElfSectionHeader<NumBits> &header, const std::vector<uint8_t> &data)
|
||||
MutableSectionHeader(const std::string &name, const NEO::Elf::ElfSectionHeader<numBits> &header, const std::vector<uint8_t> &data)
|
||||
: name(name), header(header), data(data) {
|
||||
}
|
||||
std::string name;
|
||||
NEO::Elf::ElfSectionHeader<NumBits> header{};
|
||||
NEO::Elf::ElfSectionHeader<numBits> header{};
|
||||
std::vector<uint8_t> data;
|
||||
};
|
||||
|
||||
template <ElfIdentifierClass NumBits = NEO::Elf::EI_CLASS_64>
|
||||
template <ElfIdentifierClass numBits = NEO::Elf::EI_CLASS_64>
|
||||
struct MutableProgramHeader {
|
||||
MutableProgramHeader(const NEO::Elf::ElfProgramHeader<NumBits> &header, const std::vector<uint8_t> &data)
|
||||
MutableProgramHeader(const NEO::Elf::ElfProgramHeader<numBits> &header, const std::vector<uint8_t> &data)
|
||||
: header(header), data(data) {
|
||||
}
|
||||
NEO::Elf::ElfProgramHeader<NumBits> header = {};
|
||||
NEO::Elf::ElfProgramHeader<numBits> header = {};
|
||||
std::vector<uint8_t> data;
|
||||
MutableSectionHeader<NumBits> *referencedSectionData = nullptr;
|
||||
MutableSectionHeader<numBits> *referencedSectionData = nullptr;
|
||||
};
|
||||
|
||||
template <ElfIdentifierClass NumBits = NEO::Elf::EI_CLASS_64>
|
||||
template <ElfIdentifierClass numBits = NEO::Elf::EI_CLASS_64>
|
||||
struct ElfRewriter {
|
||||
using SectionId = uint32_t;
|
||||
|
||||
ElfRewriter(NEO::Elf::Elf<NumBits> &src) {
|
||||
ElfRewriter(NEO::Elf::Elf<numBits> &src) {
|
||||
elfFileHeader = *src.elfFileHeader;
|
||||
for (const auto &sh : src.sectionHeaders) {
|
||||
this->sectionHeaders.push_back(std::make_unique<MutableSectionHeader<NumBits>>(src.getName(sh.header->name), *sh.header, std::vector<uint8_t>{sh.data.begin(), sh.data.end()}));
|
||||
this->sectionHeaders.push_back(std::make_unique<MutableSectionHeader<numBits>>(src.getName(sh.header->name), *sh.header, std::vector<uint8_t>{sh.data.begin(), sh.data.end()}));
|
||||
}
|
||||
for (const auto &ph : src.programHeaders) {
|
||||
this->programHeaders.push_back(std::make_unique<MutableProgramHeader<NumBits>>(*ph.header, std::vector<uint8_t>{ph.data.begin(), ph.data.end()}));
|
||||
this->programHeaders.push_back(std::make_unique<MutableProgramHeader<numBits>>(*ph.header, std::vector<uint8_t>{ph.data.begin(), ph.data.end()}));
|
||||
for (const auto &sh : this->sectionHeaders) {
|
||||
if ((sh->header.offset == ph.header->offset) && (sh->header.size == ph.header->fileSz)) {
|
||||
(*this->programHeaders.rbegin())->referencedSectionData = sh.get();
|
||||
@@ -62,15 +62,20 @@ struct ElfRewriter {
|
||||
}
|
||||
|
||||
std::vector<uint8_t> encode() const {
|
||||
NEO::Elf::ElfEncoder<NumBits> encoder;
|
||||
NEO::Elf::ElfEncoder<numBits> encoder{};
|
||||
for (const auto &sh : this->sectionHeaders) {
|
||||
if (sh->header.type == SHT_STRTAB) {
|
||||
encoder.setInitialStringsTab(sh->data);
|
||||
}
|
||||
}
|
||||
encoder.getElfFileHeader() = elfFileHeader;
|
||||
std::unordered_map<MutableSectionHeader<NumBits> *, decltype(NEO::Elf::ElfSectionHeader<NumBits>::offset)> encodedSectionsOffsets;
|
||||
std::unordered_map<MutableSectionHeader<numBits> *, decltype(NEO::Elf::ElfSectionHeader<numBits>::offset)> encodedSectionsOffsets;
|
||||
for (const auto &sh : this->sectionHeaders) {
|
||||
if ((sh->header.type == SHT_NULL) || (sh->header.type == SHT_STRTAB)) {
|
||||
continue;
|
||||
}
|
||||
auto nameIdx = encoder.appendSectionName(sh->name);
|
||||
NEO::Elf::ElfSectionHeader<NumBits> header = sh->header;
|
||||
NEO::Elf::ElfSectionHeader<numBits> header = sh->header;
|
||||
header.name = nameIdx;
|
||||
encodedSectionsOffsets[sh.get()] = encoder.appendSection(header, sh->data).offset;
|
||||
}
|
||||
@@ -86,7 +91,7 @@ struct ElfRewriter {
|
||||
return encoder.encode();
|
||||
}
|
||||
|
||||
StackVec<SectionId, 16> findSections(typename ElfSectionHeaderTypes<NumBits>::Type type, ConstStringRef name) {
|
||||
StackVec<SectionId, 16> findSections(typename ElfSectionHeaderTypes<numBits>::Type type, ConstStringRef name) {
|
||||
StackVec<SectionId, 16> ret;
|
||||
for (size_t i = 0; i < this->sectionHeaders.size(); i++) {
|
||||
auto §ion = this->sectionHeaders[i];
|
||||
@@ -97,7 +102,7 @@ struct ElfRewriter {
|
||||
return ret;
|
||||
}
|
||||
|
||||
MutableSectionHeader<NumBits> &getSection(SectionId idx) {
|
||||
MutableSectionHeader<numBits> &getSection(SectionId idx) {
|
||||
return *sectionHeaders[idx];
|
||||
}
|
||||
|
||||
@@ -114,11 +119,11 @@ struct ElfRewriter {
|
||||
}
|
||||
}
|
||||
|
||||
ElfFileHeader<NumBits> elfFileHeader = {};
|
||||
ElfFileHeader<numBits> elfFileHeader = {};
|
||||
|
||||
protected:
|
||||
StackVec<std::unique_ptr<MutableSectionHeader<NumBits>>, 32> sectionHeaders;
|
||||
StackVec<std::unique_ptr<MutableProgramHeader<NumBits>>, 32> programHeaders;
|
||||
StackVec<std::unique_ptr<MutableSectionHeader<numBits>>, 32> sectionHeaders;
|
||||
StackVec<std::unique_ptr<MutableProgramHeader<numBits>>, 32> programHeaders;
|
||||
};
|
||||
|
||||
} // namespace Elf
|
||||
|
||||
Reference in New Issue
Block a user