source: CLRX/CLRadeonExtender/trunk/CLRX/amdasm/Disassembler.h @ 2517

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

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

File size: 14.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/*! \file Disassembler.h
20 * \brief an disassembler for Radeon GPU's
21 */
22
23#ifndef __CLRX_DISASSEMBLER_H__
24#define __CLRX_DISASSEMBLER_H__
25
26#include <CLRX/Config.h>
27#include <string>
28#include <istream>
29#include <ostream>
30#include <vector>
31#include <utility>
32#include <memory>
33#include <CLRX/amdbin/AmdBinaries.h>
34#include <CLRX/amdbin/AmdCL2Binaries.h>
35#include <CLRX/amdbin/ROCmBinaries.h>
36#include <CLRX/amdbin/GalliumBinaries.h>
37#include <CLRX/amdbin/AmdBinGen.h>
38#include <CLRX/amdasm/Commons.h>
39#include <CLRX/utils/Utilities.h>
40#include <CLRX/utils/InputOutput.h>
41
42/// main namespace
43namespace CLRX
44{
45
46class Disassembler;
47
48enum: Flags
49{
50    DISASM_DUMPCODE = 1,    ///< dump code
51    DISASM_METADATA = 2,    ///< dump metadatas
52    DISASM_DUMPDATA = 4,    ///< dump datas
53    DISASM_CALNOTES = 8,    ///< dump ATI CAL notes
54    DISASM_FLOATLITS = 16,  ///< print in comments float literals
55    DISASM_HEXCODE = 32,    ///< print on left side hexadecimal code
56    DISASM_SETUP = 64,
57    DISASM_CONFIG = 128,    ///< print kernel configuration instead raw data
58    DISASM_BUGGYFPLIT = 256,
59   
60    ///< all disassembler flags (without config)
61    DISASM_ALL = FLAGS_ALL&(~(DISASM_CONFIG|DISASM_BUGGYFPLIT))
62};
63
64struct GCNDisasmUtils;
65
66/// main class for
67class ISADisassembler: public NonCopyableAndNonMovable
68{
69private:
70    friend struct GCNDisasmUtils; // INTERNAL LOGIC
71protected:
72    /// internal relocation structure
73    struct Relocation
74    {
75        size_t symbol;   ///< symbol index
76        RelocType type; ///< relocation type
77        int64_t addend; ///< relocation addend
78    };
79   
80    typedef std::vector<size_t>::const_iterator LabelIter;  ///< label iterator
81   
82    /// relocation iterator
83    typedef std::vector<std::pair<size_t, Relocation> >::const_iterator RelocIter;
84   
85    /// named label iterator
86    typedef std::vector<std::pair<size_t, CString> >::const_iterator NamedLabelIter;
87   
88    Disassembler& disassembler; ///< disassembler instance
89    size_t inputSize;   ///< size of input
90    const cxbyte* input;    ///< input code
91    std::vector<size_t> labels; ///< list of local labels
92    std::vector<std::pair<size_t, CString> > namedLabels;   ///< named labels
93    std::vector<CString> relSymbols;    ///< symbols used by relocations
94    std::vector<std::pair<size_t, Relocation> > relocations;    ///< relocations
95    FastOutputBuffer output;    ///< output buffer
96   
97    /// constructor
98    explicit ISADisassembler(Disassembler& disassembler, cxuint outBufSize = 500);
99   
100    /// write all labels before specified position
101    void writeLabelsToPosition(size_t pos, LabelIter& labelIter,
102               NamedLabelIter& namedLabelIter);
103    /// write all labels to end
104    void writeLabelsToEnd(size_t start, LabelIter labelIter, NamedLabelIter namedLabelIter);
105    /// write location in the code
106    void writeLocation(size_t pos);
107    /// write relocation to current place in instruction
108    bool writeRelocation(size_t pos, RelocIter& relocIter);
109public:
110    virtual ~ISADisassembler();
111   
112    /// set input code
113    void setInput(size_t inputSize, const cxbyte* input)
114    {
115        this->inputSize = inputSize;
116        this->input = input;
117    }
118
119    /// makes some things before disassemblying
120    virtual void beforeDisassemble() = 0;
121    /// disassembles input code
122    virtual void disassemble() = 0;
123
124    /// add named label to list (must be called before disassembly)
125    void addNamedLabel(size_t pos, const CString& name)
126    { namedLabels.push_back(std::make_pair(pos, name)); }
127    /// add named label to list (must be called before disassembly)
128    void addNamedLabel(size_t pos, CString&& name)
129    { namedLabels.push_back(std::make_pair(pos, name)); }
130   
131    /// add symbol to relocations
132    size_t addRelSymbol(const CString& symName)
133    {
134        size_t index = relSymbols.size();
135        relSymbols.push_back(symName);
136        return index;
137    }
138    /// add relocation
139    void addRelocation(size_t offset, RelocType type, size_t symIndex, int64_t addend)
140    { relocations.push_back(std::make_pair(offset, Relocation{symIndex, type, addend})); }
141    /// clear all relocations
142    void clearRelocations()
143    {
144        relSymbols.clear();
145        relocations.clear();
146    }
147};
148
149/// GCN architectur dissassembler
150class GCNDisassembler: public ISADisassembler
151{
152private:
153    bool instrOutOfCode;
154   
155    friend struct GCNDisasmUtils; // INTERNAL LOGIC
156public:
157    /// constructor
158    GCNDisassembler(Disassembler& disassembler);
159    /// destructor
160    ~GCNDisassembler();
161   
162    /// routine called before main disassemblying
163    void beforeDisassemble();
164    /// disassemble code
165    void disassemble();
166};
167
168/// single kernel input for disassembler
169/** all pointer members holds only pointers that should be freed by your routines.
170 * No management of data */
171struct AmdDisasmKernelInput
172{
173    CString kernelName; ///< kernel name
174    size_t metadataSize;    ///< metadata size
175    const char* metadata;   ///< kernel's metadata
176    size_t headerSize;  ///< kernel header size
177    const cxbyte* header;   ///< kernel header size
178    std::vector<CALNoteInput> calNotes;   ///< ATI CAL notes
179    size_t dataSize;    ///< data (from inner binary) size
180    const cxbyte* data; ///< data from inner binary
181    size_t codeSize;    ///< size of code of kernel
182    const cxbyte* code; ///< code of kernel
183};
184
185/// whole disassembler input (for AMD Catalyst driver GPU binaries)
186/** all pointer members holds only pointers that should be freed by your routines.
187 * No management of data */
188struct AmdDisasmInput
189{
190    GPUDeviceType deviceType;   ///< GPU device type
191    bool is64BitMode;       ///< true if 64-bit mode of addressing
192    CString driverInfo; ///< driver info (for AMD Catalyst drivers)
193    CString compileOptions; ///< compile options which used by in clBuildProgram
194    size_t globalDataSize;  ///< global (constants for kernels) data size
195    const cxbyte* globalData;   ///< global (constants for kernels) data
196    std::vector<AmdDisasmKernelInput> kernels;    ///< kernel inputs
197};
198
199/// relocation with addend
200struct AmdCL2RelaEntry
201{
202    size_t offset;  ///< offset
203    RelocType type; ///< relocation type
204    cxuint symbol;  ///< symbol
205    int64_t addend; ///< addend
206};
207
208/// single kernel input for disassembler
209/** all pointer members holds only pointers that should be freed by your routines.
210 * No management of data */
211struct AmdCL2DisasmKernelInput
212{
213    CString kernelName; ///< kernel name
214    size_t metadataSize;    ///< metadata size
215    const cxbyte* metadata;   ///< kernel's metadata
216    size_t isaMetadataSize;    ///< metadata size
217    const cxbyte* isaMetadata;   ///< kernel's metadata
218    size_t setupSize;    ///< data (from inner binary) size
219    const cxbyte* setup; ///< data from inner binary
220    size_t stubSize;    ///< data (from inner binary) size
221    const cxbyte* stub; ///< data from inner binary
222    std::vector<AmdCL2RelaEntry> textRelocs;    ///< text relocations
223    size_t codeSize;    ///< size of code of kernel
224    const cxbyte* code; ///< code of kernel
225};
226
227/// whole disassembler input (for AMD Catalyst driver GPU binaries)
228/** all pointer members holds only pointers that should be freed by your routines.
229 * No management of data */
230struct AmdCL2DisasmInput
231{
232    GPUDeviceType deviceType;   ///< GPU device type
233    uint32_t archMinor;     ///< GPU arch minor
234    uint32_t archStepping;     ///< GPU arch stepping
235    cxuint driverVersion; ///< driver version
236    CString compileOptions; ///< compile options which used by in clBuildProgram
237    CString aclVersionString; ///< acl version string
238    size_t globalDataSize;  ///< global (constants for kernels) data size
239    const cxbyte* globalData;   ///< global (constants for kernels) data
240    size_t rwDataSize;  ///< global rw data size
241    const cxbyte* rwData;   ///< global rw data data
242    size_t bssAlignment;    ///< alignment of global bss section
243    size_t bssSize;         ///< size of global bss section
244    size_t samplerInitSize;     ///< sampler init data size
245    const cxbyte* samplerInit;  ///< sampler init data
246   
247    /// sampler relocations
248    std::vector<std::pair<size_t, size_t> > samplerRelocs;
249    std::vector<AmdCL2DisasmKernelInput> kernels;    ///< kernel inputs
250};
251
252struct ROCmDisasmKernelInput
253{
254    CString kernelName; ///< kernel name
255    const cxbyte* setup;
256    size_t codeSize;
257    size_t offset;
258};
259
260struct ROCmDisasmRegion
261{
262    size_t size;
263    size_t offset;
264    size_t kernelIndex;
265};
266
267struct ROCmDisasmInput
268{
269    GPUDeviceType deviceType;   ///< GPU device type
270    uint32_t archMinor;     ///< GPU arch minor
271    uint32_t archStepping;     ///< GPU arch stepping
272    std::vector<ROCmDisasmKernelInput> kernels;    ///< kernel inputs
273    std::vector<ROCmDisasmRegion> regions;  ///< regions
274    size_t codeSize;    ///< code size
275    const cxbyte* code; ///< code
276};
277
278/// disasm kernel info structure (Gallium binaries)
279struct GalliumDisasmKernelInput
280{
281    CString kernelName;   ///< kernel's name
282    GalliumProgInfoEntry progInfo[3];   ///< program info for kernel
283    uint32_t offset;    ///< offset of kernel code
284    std::vector<GalliumArgInfo> argInfos;   ///< arguments
285};
286
287/// whole disassembler input (for Gallium driver GPU binaries)
288struct GalliumDisasmInput
289{
290    GPUDeviceType deviceType;   ///< GPU device type
291    bool is64BitMode;       ///< true if 64-bit mode of addressing
292    size_t globalDataSize;  ///< global (constants for kernels) data size
293    const cxbyte* globalData;   ///< global (constants for kernels) data
294    std::vector<GalliumDisasmKernelInput> kernels;    ///< list of input kernels
295    size_t codeSize;    ///< code size
296    const cxbyte* code; ///< code
297};
298
299/// disassembler input for raw code
300struct RawCodeInput
301{
302    GPUDeviceType deviceType;   ///< GPU device type
303    size_t codeSize;            ///< code size
304    const cxbyte* code;         ///< code
305};
306
307/// disassembler class
308class Disassembler: public NonCopyableAndNonMovable
309{
310private:
311    friend class ISADisassembler;
312    std::unique_ptr<ISADisassembler> isaDisassembler;
313    bool fromBinary;
314    BinaryFormat binaryFormat;
315    union {
316        const AmdDisasmInput* amdInput;
317        const AmdCL2DisasmInput* amdCL2Input;
318        const GalliumDisasmInput* galliumInput;
319        const ROCmDisasmInput* rocmInput;
320        const RawCodeInput* rawInput;
321    };
322    std::ostream& output;
323    Flags flags;
324    size_t sectionCount;
325public:
326    /// constructor for 32-bit GPU binary
327    /**
328     * \param binary main GPU binary
329     * \param output output stream
330     * \param flags flags for disassembler
331     */
332    Disassembler(const AmdMainGPUBinary32& binary, std::ostream& output,
333                 Flags flags = 0);
334    /// constructor for 64-bit GPU binary
335    /**
336     * \param binary main GPU binary
337     * \param output output stream
338     * \param flags flags for disassembler
339     */
340    Disassembler(const AmdMainGPUBinary64& binary, std::ostream& output,
341                 Flags flags = 0);
342    /// constructor for AMD OpenCL 2.0 GPU binary
343    /**
344     * \param binary main GPU binary
345     * \param output output stream
346     * \param flags flags for disassembler
347     */
348    Disassembler(const AmdCL2MainGPUBinary& binary, std::ostream& output,
349                 Flags flags = 0);
350    /// constructor for ROCm GPU binary
351    /**
352     * \param binary main GPU binary
353     * \param output output stream
354     * \param flags flags for disassembler
355     */
356    Disassembler(const ROCmBinary& binary, std::ostream& output, Flags flags = 0);
357    /// constructor for AMD disassembler input
358    /**
359     * \param disasmInput disassembler input object
360     * \param output output stream
361     * \param flags flags for disassembler
362     */
363    Disassembler(const AmdDisasmInput* disasmInput, std::ostream& output,
364                 Flags flags = 0);
365    /// constructor for AMD OpenCL 2.0 disassembler input
366    /**
367     * \param disasmInput disassembler input object
368     * \param output output stream
369     * \param flags flags for disassembler
370     */
371    Disassembler(const AmdCL2DisasmInput* disasmInput, std::ostream& output,
372                 Flags flags = 0);
373    /// constructor for ROCMm disassembler input
374    /**
375     * \param disasmInput disassembler input object
376     * \param output output stream
377     * \param flags flags for disassembler
378     */
379    Disassembler(const ROCmDisasmInput* disasmInput, std::ostream& output,
380                 Flags flags = 0);
381   
382    /// constructor for bit GPU binary from Gallium
383    /**
384     * \param deviceType GPU device type
385     * \param binary main GPU binary
386     * \param output output stream
387     * \param flags flags for disassembler
388     */
389    Disassembler(GPUDeviceType deviceType, const GalliumBinary& binary,
390                 std::ostream& output, Flags flags = 0);
391   
392    /// constructor for Gallium disassembler input
393    /**
394     * \param disasmInput disassembler input object
395     * \param output output stream
396     * \param flags flags for disassembler
397     */
398    Disassembler(const GalliumDisasmInput* disasmInput, std::ostream& output,
399                 Flags flags = 0);
400   
401    /// constructor for raw code
402    Disassembler(GPUDeviceType deviceType, size_t rawCodeSize, const cxbyte* rawCode,
403                 std::ostream& output, Flags flags = 0);
404   
405    ~Disassembler();
406   
407    /// disassembles input
408    void disassemble();
409   
410    /// get disassemblers flags
411    Flags getFlags() const
412    { return flags; }
413    /// get disassemblers flags
414    void setFlags(Flags flags)
415    { this->flags = flags; }
416   
417    /// get deviceType
418    GPUDeviceType getDeviceType() const;
419   
420    /// get disassembler input
421    const AmdDisasmInput* getAmdInput() const
422    { return amdInput; }
423   
424    /// get disassembler input
425    const AmdCL2DisasmInput* getAmdCL2Input() const
426    { return amdCL2Input; }
427   
428    /// get disassembler input
429    const GalliumDisasmInput* getGalliumInput() const
430    { return galliumInput; }
431   
432    /// get output stream
433    const std::ostream& getOutput() const
434    { return output; }
435    /// get output stream
436    std::ostream& getOutput()
437    { return output; }
438};
439
440};
441
442#endif
Note: See TracBrowser for help on using the repository browser.