source: CLRX/CLRadeonExtender/trunk/tests/amdbin/ROCmBinGen.cpp @ 2576

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

CLRadeonExtender: ROCmBinGen: Adding extra sections and symbols to binary.

File size: 5.2 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 <iostream>
22#include <sstream>
23#include <memory>
24#include <CLRX/utils/Containers.h>
25#include <CLRX/amdbin/ROCmBinaries.h>
26
27using namespace CLRX;
28
29static const char* origBinaryFiles[1] =
30{
31    CLRX_SOURCE_DIR "/tests/amdbin/rocmbins/consttest1-kaveri.hsaco.regen"
32};
33
34static ROCmInput genROCmInput(const ROCmBinary& binary)
35{
36    uint32_t archMajor = 0;
37    ROCmInput rocmInput;
38    try
39    {
40        const auto& commentHdr = binary.getSectionHeader(".comment");
41        rocmInput.commentSize = ULEV(commentHdr.sh_size);
42        rocmInput.comment = (const char*)binary.getSectionContent(".comment");
43    }
44    catch(...)
45    {
46        rocmInput.commentSize = 0;
47        rocmInput.comment = NULL;
48    }
49    rocmInput.archMinor = 0;
50    rocmInput.archStepping = 0;
51   
52    {
53        const cxbyte* noteContent = (const cxbyte*)binary.getNotes();
54        if (noteContent==nullptr)
55            throw Exception("Missing notes in inner binary!");
56        size_t notesSize = binary.getNotesSize();
57        // find note about AMDGPU
58        for (size_t offset = 0; offset < notesSize; )
59        {
60            const Elf64_Nhdr* nhdr = (const Elf64_Nhdr*)(noteContent + offset);
61            size_t namesz = ULEV(nhdr->n_namesz);
62            size_t descsz = ULEV(nhdr->n_descsz);
63            if (usumGt(offset, namesz+descsz, notesSize))
64                throw Exception("Note offset+size out of range");
65            if (ULEV(nhdr->n_type) == 0x3 && namesz==4 && descsz>=0x1a &&
66                ::strcmp((const char*)noteContent+offset+sizeof(Elf64_Nhdr), "AMD")==0)
67            {    // AMDGPU type
68                const uint32_t* content = (const uint32_t*)
69                        (noteContent+offset+sizeof(Elf64_Nhdr) + 4);
70                archMajor = ULEV(content[1]);
71                rocmInput.archMinor = ULEV(content[2]);
72                rocmInput.archStepping = ULEV(content[3]);
73            }
74            size_t align = (((namesz+descsz)&3)!=0) ? 4-((namesz+descsz)&3) : 0;
75            offset += sizeof(Elf64_Nhdr) + namesz + descsz + align;
76        }
77    }
78    // determine device type
79    rocmInput.deviceType = GPUDeviceType::CAPE_VERDE;
80    if (archMajor==0)
81        rocmInput.deviceType = GPUDeviceType::CAPE_VERDE;
82    else if (archMajor==7)
83        rocmInput.deviceType = GPUDeviceType::BONAIRE;
84    else if (archMajor==8)
85        rocmInput.deviceType = GPUDeviceType::ICELAND;
86   
87    rocmInput.codeSize = binary.getCodeSize();
88    rocmInput.code = binary.getCode();
89   
90    // get ROCm symbol
91    const size_t codeOffset = binary.getCode()-binary.getBinaryCode();
92    for (size_t i = 0; i < binary.getRegionsNum(); i++)
93    {
94        const ROCmRegion& region = binary.getRegion(i);
95        rocmInput.symbols.push_back({region.regionName, region.offset-codeOffset,
96                    region.size, region.isKernel});
97    }
98    return rocmInput;
99}
100
101static void testOrigBinary(cxuint testCase, const char* origBinaryFilename)
102{
103    Array<cxbyte> inputData;
104    Array<cxbyte> output;
105    std::string origBinFilenameStr(origBinaryFilename);
106    filesystemPath(origBinFilenameStr); // convert to system path (native separators)
107   
108    inputData = loadDataFromFile(origBinFilenameStr.c_str());
109    ROCmBinary rocmBin(inputData.size(), inputData.data(), 0);
110   
111    ROCmInput rocmInput = genROCmInput(rocmBin);
112    ROCmBinGenerator binGen(&rocmInput);
113    binGen.generate(output);
114   
115    if (output.size() != inputData.size())
116    {
117        std::ostringstream oss;
118            oss << "Failed for #" << testCase << " file=" << origBinaryFilename <<
119                    ": expectedSize=" << inputData.size() <<
120                    ", resultSize=" << output.size();
121        throw Exception(oss.str());
122    }
123    for (size_t i = 0; i < inputData.size(); i++)
124        if (output[i] != inputData[i])
125        {
126            std::ostringstream oss;
127            oss << "Failed for #" << testCase << " file=" << origBinaryFilename <<
128                    ": byte=" << i;
129            throw Exception(oss.str());
130        }
131}
132
133int main(int argc, const char** argv)
134{
135    int retVal = 0;
136    for (cxuint i = 0; i < sizeof(origBinaryFiles)/sizeof(const char*); i++)
137        try
138        { testOrigBinary(i, origBinaryFiles[i]); }
139        catch(const std::exception& ex)
140        {
141            std::cerr << ex.what() << std::endl;
142            retVal = 1;
143        }
144    return retVal;
145}
Note: See TracBrowser for help on using the repository browser.