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

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

CLRadeonExtender: Update.

File size: 14.8 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
260/// disasm ROCm region
261struct ROCmDisasmRegionInput
262{
263    CString regionName; ///< region name
264    size_t size;    ///< region size
265    size_t offset;  ///< region offset in code
266    bool isKernel;  ///< true if kernel
267};
268
269struct ROCmDisasmInput
270{
271    GPUDeviceType deviceType;   ///< GPU device type
272    uint32_t archMinor;     ///< GPU arch minor
273    uint32_t archStepping;     ///< GPU arch stepping
274    std::vector<ROCmDisasmRegionInput> regions;  ///< regions
275    size_t codeSize;    ///< code size
276    const cxbyte* code; ///< code
277};
278
279/// disasm kernel info structure (Gallium binaries)
280struct GalliumDisasmKernelInput
281{
282    CString kernelName;   ///< kernel's name
283    GalliumProgInfoEntry progInfo[3];   ///< program info for kernel
284    uint32_t offset;    ///< offset of kernel code
285    std::vector<GalliumArgInfo> argInfos;   ///< arguments
286};
287
288/// whole disassembler input (for Gallium driver GPU binaries)
289struct GalliumDisasmInput
290{
291    GPUDeviceType deviceType;   ///< GPU device type
292    bool is64BitMode;       ///< true if 64-bit mode of addressing
293    size_t globalDataSize;  ///< global (constants for kernels) data size
294    const cxbyte* globalData;   ///< global (constants for kernels) data
295    std::vector<GalliumDisasmKernelInput> kernels;    ///< list of input kernels
296    size_t codeSize;    ///< code size
297    const cxbyte* code; ///< code
298};
299
300/// disassembler input for raw code
301struct RawCodeInput
302{
303    GPUDeviceType deviceType;   ///< GPU device type
304    size_t codeSize;            ///< code size
305    const cxbyte* code;         ///< code
306};
307
308/// disassembler class
309class Disassembler: public NonCopyableAndNonMovable
310{
311private:
312    friend class ISADisassembler;
313    std::unique_ptr<ISADisassembler> isaDisassembler;
314    bool fromBinary;
315    BinaryFormat binaryFormat;
316    union {
317        const AmdDisasmInput* amdInput;
318        const AmdCL2DisasmInput* amdCL2Input;
319        const GalliumDisasmInput* galliumInput;
320        const ROCmDisasmInput* rocmInput;
321        const RawCodeInput* rawInput;
322    };
323    std::ostream& output;
324    Flags flags;
325    size_t sectionCount;
326public:
327    /// constructor for 32-bit GPU binary
328    /**
329     * \param binary main GPU binary
330     * \param output output stream
331     * \param flags flags for disassembler
332     */
333    Disassembler(const AmdMainGPUBinary32& binary, std::ostream& output,
334                 Flags flags = 0);
335    /// constructor for 64-bit GPU binary
336    /**
337     * \param binary main GPU binary
338     * \param output output stream
339     * \param flags flags for disassembler
340     */
341    Disassembler(const AmdMainGPUBinary64& binary, std::ostream& output,
342                 Flags flags = 0);
343    /// constructor for AMD OpenCL 2.0 GPU binary
344    /**
345     * \param binary main GPU binary
346     * \param output output stream
347     * \param flags flags for disassembler
348     */
349    Disassembler(const AmdCL2MainGPUBinary& binary, std::ostream& output,
350                 Flags flags = 0);
351    /// constructor for ROCm GPU binary
352    /**
353     * \param binary main GPU binary
354     * \param output output stream
355     * \param flags flags for disassembler
356     */
357    Disassembler(const ROCmBinary& binary, std::ostream& output, Flags flags = 0);
358    /// constructor for AMD disassembler input
359    /**
360     * \param disasmInput disassembler input object
361     * \param output output stream
362     * \param flags flags for disassembler
363     */
364    Disassembler(const AmdDisasmInput* disasmInput, std::ostream& output,
365                 Flags flags = 0);
366    /// constructor for AMD OpenCL 2.0 disassembler input
367    /**
368     * \param disasmInput disassembler input object
369     * \param output output stream
370     * \param flags flags for disassembler
371     */
372    Disassembler(const AmdCL2DisasmInput* disasmInput, std::ostream& output,
373                 Flags flags = 0);
374    /// constructor for ROCMm disassembler input
375    /**
376     * \param disasmInput disassembler input object
377     * \param output output stream
378     * \param flags flags for disassembler
379     */
380    Disassembler(const ROCmDisasmInput* disasmInput, std::ostream& output,
381                 Flags flags = 0);
382   
383    /// constructor for bit GPU binary from Gallium
384    /**
385     * \param deviceType GPU device type
386     * \param binary main GPU binary
387     * \param output output stream
388     * \param flags flags for disassembler
389     */
390    Disassembler(GPUDeviceType deviceType, const GalliumBinary& binary,
391                 std::ostream& output, Flags flags = 0);
392   
393    /// constructor for Gallium disassembler input
394    /**
395     * \param disasmInput disassembler input object
396     * \param output output stream
397     * \param flags flags for disassembler
398     */
399    Disassembler(const GalliumDisasmInput* disasmInput, std::ostream& output,
400                 Flags flags = 0);
401   
402    /// constructor for raw code
403    Disassembler(GPUDeviceType deviceType, size_t rawCodeSize, const cxbyte* rawCode,
404                 std::ostream& output, Flags flags = 0);
405   
406    ~Disassembler();
407   
408    /// disassembles input
409    void disassemble();
410   
411    /// get disassemblers flags
412    Flags getFlags() const
413    { return flags; }
414    /// get disassemblers flags
415    void setFlags(Flags flags)
416    { this->flags = flags; }
417   
418    /// get deviceType
419    GPUDeviceType getDeviceType() const;
420   
421    /// get disassembler input
422    const AmdDisasmInput* getAmdInput() const
423    { return amdInput; }
424   
425    /// get disassembler input
426    const AmdCL2DisasmInput* getAmdCL2Input() const
427    { return amdCL2Input; }
428   
429    /// get disassembler input
430    const GalliumDisasmInput* getGalliumInput() const
431    { return galliumInput; }
432   
433    /// get output stream
434    const std::ostream& getOutput() const
435    { return output; }
436    /// get output stream
437    std::ostream& getOutput()
438    { return output; }
439};
440
441};
442
443#endif
Note: See TracBrowser for help on using the repository browser.