source: CLRX/CLRadeonExtender/trunk/amdbin/ROCmBinaries.cpp @ 2503

Last change on this file since 2503 was 2503, checked in by matszpk, 3 years ago

CLRadeonExtender: Add sanity checking for kernel's offsets (ROCm).

File size: 3.7 KB
Line 
1/*
2 *  CLRadeonExtender - Unofficial OpenCL Radeon Extensions Library
3 *  Copyright (C) 2014-2016 Mateusz Szpakowski
4 *
5 *  This library is free software; you can redistribute it and/or
6 *  modify it under the terms of the GNU Lesser General Public
7 *  License as published by the Free Software Foundation; either
8 *  version 2.1 of the License, or (at your option) any later version.
9 *
10 *  This library is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 *  Lesser General Public License for more details.
14 *
15 *  You should have received a copy of the GNU Lesser General Public
16 *  License along with this library; if not, write to the Free Software
17 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19
20#include <CLRX/Config.h>
21#include <cstdlib>
22#include <cstring>
23#include <climits>
24#include <cstdint>
25#include <map>
26#include <utility>
27#include <vector>
28#include <CLRX/amdbin/Elf.h>
29#include <CLRX/utils/Utilities.h>
30#include <CLRX/utils/MemAccess.h>
31#include <CLRX/amdbin/ROCmBinaries.h>
32
33using namespace CLRX;
34
35ROCmBinary::ROCmBinary(size_t binaryCodeSize, cxbyte* binaryCode, Flags creationFlags)
36        : ElfBinary64(binaryCodeSize, binaryCode, creationFlags),
37          kernelsNum(0), codeSize(0), code(nullptr)
38{
39    cxuint textIndex = SHN_UNDEF;
40    try
41    { textIndex = getSectionIndex(".text"); }
42    catch(const Exception& ex)
43    { } // ignore failed
44    if (textIndex!=SHN_UNDEF)
45    {
46        code = getSectionContent(textIndex);
47        codeSize = ULEV(getSectionHeader(textIndex).sh_size);
48    }
49   
50    kernelsNum = 0;
51    const size_t symbolsNum = getSymbolsNum();
52    for (size_t i = 0; i < symbolsNum; i++)
53    {
54        const Elf64_Sym& sym = getSymbol(i);
55        if (sym.st_shndx==textIndex)
56            kernelsNum++;
57    }
58    if (code==nullptr && kernelsNum!=0)
59        throw Exception("No code if kernels number is not zero");
60    kernels.reset(new ROCmKernel[kernelsNum]);
61    size_t j = 0;
62    std::unique_ptr<uint64_t[]> kernelOffsets(new uint64_t[kernelsNum]);
63    for (size_t i = 0; i < symbolsNum; i++)
64    {
65        const Elf64_Sym& sym = getSymbol(i);
66        if (sym.st_shndx!=textIndex)
67            continue;
68        const size_t value = ULEV(sym.st_value);
69        if (value+0x100 > codeSize)
70            throw Exception("Kernel offset is too big!");
71        kernelOffsets[j] = value;
72        kernels[j++] = { getSymbolName(i), code+value, code+value+0x100 };
73    }
74    std::sort(kernelOffsets.get(), kernelOffsets.get()+kernelsNum);
75    // checking distance between kernels
76    for (size_t i = 1; i < kernelsNum; i++)
77        if (kernelOffsets[i-1]+0x100 > kernelOffsets[i])
78            throw Exception("Kernel size is too small!");
79   
80    if (hasKernelMap())
81    {   // create kernels map
82        kernelsMap.resize(kernelsNum);
83        for (size_t i = 0; i < kernelsNum; i++)
84            kernelsMap[i] = std::make_pair(kernels[i].kernelName, i);
85        mapSort(kernelsMap.begin(), kernelsMap.end());
86    }
87}
88
89const ROCmKernel& ROCmBinary::getKernel(const char* name) const
90{
91    KernelMap::const_iterator it = binaryMapFind(kernelsMap.begin(),
92                             kernelsMap.end(), name);
93    if (it == kernelsMap.end())
94        throw Exception("Can't find kernel name");
95    return kernels[it->second];
96}
97
98bool CLRX::isROCmBinary(size_t binarySize, const cxbyte* binary)
99{
100    if (!isElfBinary(binarySize, binary))
101        return false;
102        return false;
103    if (binary[EI_CLASS] != ELFCLASS64)
104        return false;
105    const Elf64_Ehdr* ehdr = reinterpret_cast<const Elf64_Ehdr*>(binary);
106    if (ULEV(ehdr->e_machine) != 0xe0 || ULEV(ehdr->e_flags)!=0)
107        return false;
108    return true;
109}
Note: See TracBrowser for help on using the repository browser.