From 66c5d710bc95fc96b613e546fb7e3d4fc016205a Mon Sep 17 00:00:00 2001
From: foreman
Date: Fri, 11 Nov 2016 15:35:41 -0500
Subject: [PATCH] P4 to Git Change 1340262 by lmoriche@lmoriche_opencl_dev on
2016/11/11 15:10:03
SWDEV-105136 - Use the "execution" view rather than the "linking" view to find the metadata and size of the program scope variables.In the "execution" view, the section header table is optional, so we should iterate through the segments to add up the size of PT_LOAD segments with read but not execute flags. We will also find the metadata in the PT_NOTE segment.
Affected files ...
... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprogram.cpp#24 edit
... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.cpp#45 edit
---
rocclr/runtime/device/pal/palprogram.cpp | 67 +++++++++++++----------
rocclr/runtime/device/rocm/rocprogram.cpp | 67 +++++++++++++----------
2 files changed, 76 insertions(+), 58 deletions(-)
diff --git a/rocclr/runtime/device/pal/palprogram.cpp b/rocclr/runtime/device/pal/palprogram.cpp
index 62a448ede8..cf4b276d04 100644
--- a/rocclr/runtime/device/pal/palprogram.cpp
+++ b/rocclr/runtime/device/pal/palprogram.cpp
@@ -1562,44 +1562,53 @@ LightningProgram::setKernels(
buildLog_ += "Error while reading the ELF program binary\n";
return false;
}
- size_t shstrndx;
- if (elf_getshdrstrndx(e, &shstrndx) != 0) {
+
+ size_t numpHdrs;
+ if (elf_getphdrnum(e, &numpHdrs) != 0) {
buildLog_ += "Error while reading the ELF program binary\n";
return false;
}
- // Iterate over the sections
- for (Elf_Scn* scn = elf_nextscn(e, 0); scn; scn = elf_nextscn(e, scn)) {
- GElf_Shdr shdr;
- if (gelf_getshdr(scn, &shdr) != &shdr) {
+ for (size_t i = 0; i < numpHdrs; ++i) {
+ GElf_Phdr pHdr;
+ if (gelf_getphdr(e, i, &pHdr) != &pHdr) {
continue;
}
- // Skip non-program sections
- if (shdr.sh_type != SHT_PROGBITS) {
- continue;
- }
- // Accumulate the size of A & !X sections
- if ((shdr.sh_flags & SHF_ALLOC) && !(shdr.sh_flags & SHF_EXECINSTR)) {
- progvarsTotalSize += shdr.sh_size;
- }
- // Check if this is the metadata section
- const char* name = elf_strptr(e, shstrndx , shdr.sh_name);
- if (name && !strcmp(name, ".AMDGPU.runtime_metadata")) {
- // Assume a single Elf_Data, the parser will fail if it isn't
- Elf_Data* data = elf_getdata(scn, NULL);
- if (!data) {
- buildLog_ += "Error while reading ELF program binary " \
- "runtime metadata section\n";
- return false;
- }
+ // Look for the runtime metadata note
+ if (pHdr.p_type == PT_NOTE && pHdr.p_align >= sizeof(int)) {
+ // Iterate over the notes in this segment
+ address ptr = (address) binary + pHdr.p_offset;
+ address segmentEnd = ptr + pHdr.p_filesz;
- metadata_ = new amd::hsa::code::Program::Metadata();
- if (!metadata_ || !metadata_->ReadFrom(data->d_buf, data->d_size)) {
- buildLog_ += "Error while parsing ELF program binary " \
- "runtime metadata section\n";
- return false;
+ while (ptr < segmentEnd) {
+ Elf_Note* note = (Elf_Note*) ptr;
+ address name = (address) ¬e[1];
+ address desc = name + amd::alignUp(note->n_namesz, sizeof(int));
+
+ if (note->n_type == 7 /*NT_AMDGPU_HSA_RUNTIME_METADATA_1_0*/
+ && note->n_namesz == sizeof "AMD"
+ && !memcmp(name, "AMD", note->n_namesz)) {
+ metadata_ = new amd::hsa::code::Program::Metadata();
+ if (metadata_ && metadata_->ReadFrom(desc,note->n_descsz)) {
+ // We've found and loaded the runtime metadata, exit the
+ // note record loop now.
+ break;
+ }
+
+ buildLog_ += "Error while parsing ELF program binary " \
+ "runtime metadata section\n";
+ return false;
+ }
+ ptr += sizeof(*note)
+ + amd::alignUp(note->n_namesz, sizeof(int))
+ + amd::alignUp(note->n_descsz, sizeof(int));
}
}
+ // Accumulate the size of R & !X loadable segments
+ else if (pHdr.p_type == PT_LOAD
+ && (pHdr.p_flags & PF_R) && !(pHdr.p_flags & PF_X)) {
+ progvarsTotalSize += pHdr.p_memsz;
+ }
}
elf_end(e);
diff --git a/rocclr/runtime/device/rocm/rocprogram.cpp b/rocclr/runtime/device/rocm/rocprogram.cpp
index b2086611f8..afee39998f 100644
--- a/rocclr/runtime/device/rocm/rocprogram.cpp
+++ b/rocclr/runtime/device/rocm/rocprogram.cpp
@@ -967,44 +967,53 @@ HSAILProgram::setKernels_LC(amd::option::Options *options, void* binary, size_t
buildLog_ += "Error while reading the ELF program binary\n";
return false;
}
- size_t shstrndx;
- if (elf_getshdrstrndx(e, &shstrndx) != 0) {
+
+ size_t numpHdrs;
+ if (elf_getphdrnum(e, &numpHdrs) != 0) {
buildLog_ += "Error while reading the ELF program binary\n";
return false;
}
- // Iterate over the sections
- for (Elf_Scn* scn = elf_nextscn(e, 0); scn; scn = elf_nextscn(e, scn)) {
- GElf_Shdr shdr;
- if (gelf_getshdr(scn, &shdr) != &shdr) {
+ for (size_t i = 0; i < numpHdrs; ++i) {
+ GElf_Phdr pHdr;
+ if (gelf_getphdr(e, i, &pHdr) != &pHdr) {
continue;
}
- // Skip non-program sections
- if (shdr.sh_type != SHT_PROGBITS) {
- continue;
- }
- // Accumulate the size of A & !X sections
- if ((shdr.sh_flags & SHF_ALLOC) && !(shdr.sh_flags & SHF_EXECINSTR)) {
- progvarsTotalSize += shdr.sh_size;
- }
- // Check if this is the metadata section
- const char* name = elf_strptr(e, shstrndx , shdr.sh_name);
- if (name && !strcmp(name, ".AMDGPU.runtime_metadata")) {
- // Assume a single Elf_Data, the parser will fail if it isn't
- Elf_Data* data = elf_getdata(scn, NULL);
- if (!data) {
- buildLog_ += "Error while reading ELF program binary " \
- "runtime metadata section\n";
- return false;
- }
+ // Look for the runtime metadata note
+ if (pHdr.p_type == PT_NOTE && pHdr.p_align >= sizeof(int)) {
+ // Iterate over the notes in this segment
+ address ptr = (address) binary + pHdr.p_offset;
+ address segmentEnd = ptr + pHdr.p_filesz;
- metadata_ = new amd::hsa::code::Program::Metadata();
- if (!metadata_ || !metadata_->ReadFrom(data->d_buf, data->d_size)) {
- buildLog_ += "Error while parsing ELF program binary " \
- "runtime metadata section\n";
- return false;
+ while (ptr < segmentEnd) {
+ Elf_Note* note = (Elf_Note*) ptr;
+ address name = (address) ¬e[1];
+ address desc = name + amd::alignUp(note->n_namesz, sizeof(int));
+
+ if (note->n_type == 7 /*NT_AMDGPU_HSA_RUNTIME_METADATA_1_0*/
+ && note->n_namesz == sizeof "AMD"
+ && !memcmp(name, "AMD", note->n_namesz)) {
+ metadata_ = new amd::hsa::code::Program::Metadata();
+ if (metadata_ && metadata_->ReadFrom(desc,note->n_descsz)) {
+ // We've found and loaded the runtime metadata, exit the
+ // note record loop now.
+ break;
+ }
+
+ buildLog_ += "Error while parsing ELF program binary " \
+ "runtime metadata section\n";
+ return false;
+ }
+ ptr += sizeof(*note)
+ + amd::alignUp(note->n_namesz, sizeof(int))
+ + amd::alignUp(note->n_descsz, sizeof(int));
}
}
+ // Accumulate the size of R & !X loadable segments
+ else if (pHdr.p_type == PT_LOAD
+ && (pHdr.p_flags & PF_R) && !(pHdr.p_flags & PF_X)) {
+ progvarsTotalSize += pHdr.p_memsz;
+ }
}
elf_end(e);