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

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

CLRadeonExtender: Small fixes in ROCmBinaries. remove obsolete flags arguments from getGalliumDisasmInputFromBinary.
First code in DisasmROCm. Add ROCm to binary type list.

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