source: CLRX/CLRadeonExtender/trunk/amdasm/DisasmROCm.cpp @ 2517

Last change on this file since 2517 was 2517, checked in by matszpk, 4 years ago

CLRadeonExtender: Add code to handle ROCm in Disassembler. simplify getROCmDisasmInputFromBinary declaration.

File size: 4.6 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 <cstdint>
22#include <cstdio>
23#include <string>
24#include <ostream>
25#include <memory>
26#include <vector>
27#include <utility>
28#include <CLRX/utils/Utilities.h>
29#include <CLRX/utils/MemAccess.h>
30#include <CLRX/amdbin/ROCmBinaries.h>
31#include <CLRX/amdasm/Disassembler.h>
32#include <CLRX/utils/GPUId.h>
33#include "DisasmInternals.h"
34
35using namespace CLRX;
36
37struct AMDGPUArchValues
38{
39    uint32_t major;
40    uint32_t minor;
41    uint32_t stepping;
42};
43
44static const AMDGPUArchValues amdGpuArchValuesTbl[] =
45{
46    { 0, 0, 0 }, // GPUDeviceType::CAPE_VERDE
47    { 0, 0, 0 }, // GPUDeviceType::PITCAIRN
48    { 0, 0, 0 }, // GPUDeviceType::TAHITI
49    { 0, 0, 0 }, // GPUDeviceType::OLAND
50    { 7, 0, 0 }, // GPUDeviceType::BONAIRE
51    { 7, 0, 0 }, // GPUDeviceType::SPECTRE
52    { 7, 0, 0 }, // GPUDeviceType::SPOOKY
53    { 7, 0, 0 }, // GPUDeviceType::KALINDI
54    { 0, 0, 0 }, // GPUDeviceType::HAINAN
55    { 7, 0, 1 }, // GPUDeviceType::HAWAII
56    { 8, 0, 0 }, // GPUDeviceType::ICELAND
57    { 8, 0, 0 }, // GPUDeviceType::TONGA
58    { 7, 0, 0 }, // GPUDeviceType::MULLINS
59    { 8, 0, 4 }, // GPUDeviceType::FIJI
60    { 8, 0, 1 }, // GPUDeviceType::CARRIZO
61    { 0, 0, 0 }, // GPUDeviceType::DUMMY
62    { 0, 0, 0 }, // GPUDeviceType::GOOSE
63    { 0, 0, 0 }, // GPUDeviceType::HORSE
64    { 8, 1, 0 }, // GPUDeviceType::STONEY
65    { 8, 0, 4 }, // GPUDeviceType::ELLESMERE
66    { 8, 0, 4 } // GPUDeviceType::BAFFIN
67};
68
69ROCmDisasmInput* CLRX::getROCmDisasmInputFromBinary(const ROCmBinary& binary)
70{
71    std::unique_ptr<ROCmDisasmInput> input(new ROCmDisasmInput);
72    uint32_t archMajor = 0;
73    const uint16_t textIndex = binary.getSectionIndex(".text");
74   
75    {
76        const cxbyte* noteContent = binary.getSectionContent(".note");
77        size_t notesSize = binary.getSectionHeader(".note").sh_size;
78        // find note about AMDGPU
79        for (size_t offset = 0; offset < notesSize; )
80        {
81            const Elf64_Nhdr* nhdr = (const Elf64_Nhdr*)(noteContent + offset);
82            size_t namesz = ULEV(nhdr->n_namesz);
83            size_t descsz = ULEV(nhdr->n_descsz);
84            if (usumGt(offset, namesz+descsz, notesSize))
85                throw Exception("Note offset+size out of range");
86            if (ULEV(nhdr->n_type) == 0x3 && namesz==4 && descsz>=0x1a &&
87                ::strcmp((const char*)noteContent+offset+sizeof(Elf64_Nhdr), "AMD")==0)
88            {    // AMDGPU type
89                const uint32_t* content = (const uint32_t*)
90                        (noteContent+offset+sizeof(Elf64_Nhdr) + 4);
91                archMajor = ULEV(content[1]);
92                input->archMinor = ULEV(content[2]);
93                input->archStepping = ULEV(content[3]);
94            }
95            size_t align = (((namesz+descsz)&3)!=0) ? 4-((namesz+descsz)&3) : 0;
96            offset += sizeof(Elf64_Nhdr) + namesz + descsz + align;
97        }
98    }
99    // determine device type
100    cxuint deviceNumber = 0;
101    for (deviceNumber = 0; deviceNumber <= cxuint(GPUDeviceType::GPUDEVICE_MAX);
102                 deviceNumber++)
103        if (amdGpuArchValuesTbl[deviceNumber].major==archMajor &&
104            amdGpuArchValuesTbl[deviceNumber].minor==input->archMinor &&
105            amdGpuArchValuesTbl[deviceNumber].stepping==input->archStepping)
106            break;
107    if (deviceNumber > cxuint(GPUDeviceType::GPUDEVICE_MAX))
108        throw Exception("Can't determine device type from arch values!");
109    input->deviceType = GPUDeviceType(deviceNumber);
110   
111    input->code = binary.getSectionContent(textIndex);
112    input->codeSize = ULEV(binary.getSectionHeader(textIndex).sh_size);
113    return input.release();
114}
115
116void CLRX::disassembleROCm(std::ostream& output, const ROCmDisasmInput* rocmInput,
117           ISADisassembler* isaDisassembler, size_t& sectionCount, Flags flags)
118{
119}
Note: See TracBrowser for help on using the repository browser.