Files
rocm-systems/projects/rocr-runtime/samples/common/elf_utils.cpp
T
Ding, Wei (xN/A) TX 3b84f5a4f6 ECR #333755 - Added two HSA samples: MatrixMultiplication, MatrixTranspose
[git-p4: depot-paths = "//depot/stg/hsa/drivers/hsa/runtime/": change = 1124951]


[ROCm/ROCR-Runtime commit: 9d9ea2ad3b]
2015-02-25 13:05:59 -05:00

223 خطوط
7.3 KiB
C++

/* Copyright 2014 HSA Foundation Inc. All Rights Reserved.
*
* HSAF is granting you permission to use this software and documentation (if
* any) (collectively, the "Materials") pursuant to the terms and conditions
* of the Software License Agreement included with the Materials. If you do
* not have a copy of the Software License Agreement, contact the HSA Foundation for a copy.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution
* 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
* CONTRIBUTORS 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 WITH THE SOFTWARE.
*/
#include <stdlib.h>
#include <libelf.h>
#include <string.h>
#include <stdio.h>
#include "hsa.h"
#include "elf_utils.h"
#include "hsa_ext_finalize.h"
enum {
SECTION_HSA_DATA = 0,
SECTION_HSA_CODE,
SECTION_HSA_OPERAND,
};
typedef struct SectionDesc SectionDesc;
struct SectionDesc {
int sectionId;
const char *brigName;
const char *bifName;
}
sectionDescs[] = {
{ SECTION_HSA_DATA, "hsa_data",".brig_hsa_data" },
{ SECTION_HSA_CODE, "hsa_code",".brig_hsa_code" },
{ SECTION_HSA_OPERAND,"hsa_operand",".brig_hsa_operand"},
};
extern int fileno(FILE* stream);
const SectionDesc* get_section_desc(int sectionId) {
const int NUM_PREDEFINED_SECTIONS = sizeof(sectionDescs)/sizeof(sectionDescs[0]);
for(int i=0; i<NUM_PREDEFINED_SECTIONS; ++i) {
if (sectionDescs[i].sectionId == sectionId) {
return &sectionDescs[i];
}
}
return NULL;
}
static Elf_Scn* extract_elf_section (Elf *elfP,
Elf_Data *secHdr,
const SectionDesc* desc) {
int cnt = 0;
Elf_Scn* scn = NULL;
Elf32_Shdr* shdr = NULL;
char* sectionName = NULL;
/* Iterate thru the elf sections */
for (cnt = 1, scn = NULL; scn = elf_nextscn(elfP, scn); cnt++) {
if (((shdr = elf32_getshdr(scn)) == NULL)) {
return NULL;
}
sectionName = (char *)secHdr->d_buf + shdr->sh_name;
if (sectionName &&
((strcmp(sectionName, desc->brigName) == 0) ||
(strcmp(sectionName, desc->bifName) == 0))) {
return scn;
}
}
return NULL;
}
/* Extract section and copy into HsaBrig */
static status_t extract_section_and_copy (Elf *elfP,
Elf_Data *secHdr,
const SectionDesc* desc,
hsa_ext_brig_module_t* brig_module,
hsa_ext_brig_section_id_t section_id) {
Elf_Scn* scn = NULL;
Elf_Data* data = NULL;
void* address_to_copy;
size_t section_size=0;
scn = extract_elf_section(elfP, secHdr, desc);
if (scn) {
if ((data = elf_getdata(scn, NULL)) == NULL) {
return STATUS_UNKNOWN;
}
section_size = data->d_size;
if (section_size > 0) {
address_to_copy = malloc(section_size);
memcpy(address_to_copy, data->d_buf, section_size);
}
}
if ((!scn || section_size == 0)) {
return STATUS_UNKNOWN;
}
/* Create a section header */
brig_module->section[section_id] = (hsa_ext_brig_section_header_t*) address_to_copy;
return STATUS_SUCCESS;
}
/* Reads binary of BRIG and BIF format */
status_t read_binary(hsa_ext_brig_module_t **brig_module_t, FILE* binary) {
/* Create the brig_module */
uint32_t number_of_sections = 3;
hsa_ext_brig_module_t* brig_module;
brig_module = (hsa_ext_brig_module_t*)
(malloc (sizeof(hsa_ext_brig_module_t) + sizeof(void*)*number_of_sections));
brig_module->section_count = number_of_sections;
status_t status;
Elf* elfP = NULL;
Elf32_Ehdr* ehdr = NULL;
Elf_Data *secHdr = NULL;
Elf_Scn* scn = NULL;
int fd;
if (elf_version ( EV_CURRENT ) == EV_NONE) {
return STATUS_KERNEL_ELF_INITIALIZATION_FAILED;
}
fd = fileno(binary);
if ((elfP = elf_begin(fd, ELF_C_READ, (Elf *)0)) == NULL) {
return STATUS_KERNEL_INVALID_ELF_CONTAINER;
}
if (elf_kind (elfP) != ELF_K_ELF) {
return STATUS_KERNEL_INVALID_ELF_CONTAINER;
}
if (((ehdr = elf32_getehdr(elfP)) == NULL) ||
((scn = elf_getscn(elfP, ehdr->e_shstrndx)) == NULL) ||
((secHdr = elf_getdata(scn, NULL)) == NULL)) {
return STATUS_KERNEL_INVALID_SECTION_HEADER;
}
status = extract_section_and_copy(elfP,
secHdr,
get_section_desc(SECTION_HSA_DATA),
brig_module,
HSA_EXT_BRIG_SECTION_DATA);
if (status != STATUS_SUCCESS) {
return STATUS_KERNEL_MISSING_DATA_SECTION;
}
status = extract_section_and_copy(elfP,
secHdr,
get_section_desc(SECTION_HSA_CODE),
brig_module,
HSA_EXT_BRIG_SECTION_CODE);
if (status != STATUS_SUCCESS) {
return STATUS_KERNEL_MISSING_CODE_SECTION;
}
status = extract_section_and_copy(elfP,
secHdr,
get_section_desc(SECTION_HSA_OPERAND),
brig_module,
HSA_EXT_BRIG_SECTION_OPERAND);
if (status != STATUS_SUCCESS) {
return STATUS_KERNEL_MISSING_OPERAND_SECTION;
}
elf_end(elfP);
*brig_module_t = brig_module;
return STATUS_SUCCESS;
}
status_t create_brig_module_from_brig_file(const char* file_name, hsa_ext_brig_module_t** brig_module) {
FILE *fp = fopen(file_name, "rb");
status_t status = read_binary(brig_module, fp);
if (status != STATUS_SUCCESS) {
printf("Could not create BRIG module: %d\n", status);
if (status == STATUS_KERNEL_INVALID_SECTION_HEADER ||
status == STATUS_KERNEL_ELF_INITIALIZATION_FAILED ||
status == STATUS_KERNEL_INVALID_ELF_CONTAINER) {
printf("The ELF file is invalid or possibley corrupted.\n");
}
if (status == STATUS_KERNEL_MISSING_DATA_SECTION ||
status == STATUS_KERNEL_MISSING_CODE_SECTION ||
status == STATUS_KERNEL_MISSING_OPERAND_SECTION) {
printf("One or more ELF sections are missing. Use readelf command to \
to check if hsa_data, hsa_code and hsa_operands exist.\n");
}
}
fclose(fp);
return status;
}
void destroy_brig_module(hsa_ext_brig_module_t* brig_module) {
for (int i=0; i<brig_module->section_count; i++) {
free (brig_module->section[i]);
}
free (brig_module);
}