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

Last change on this file since 3150 was 3150, checked in by matszpk, 2 years ago

CLRadeonExtender: CLRX: small typos. GalliumBinary/GalliumDisasm?: Add support new LLVM 3.9.0 (spilledGPR info) and new Mesa3D 17.0.

File size: 16.3 KB
Line 
1/*
2 *  CLRadeonExtender - Unofficial OpenCL Radeon Extensions Library
3 *  Copyright (C) 2014-2017 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
71public:
72    typedef std::vector<size_t>::const_iterator LabelIter;  ///< label iterator
73   
74    /// named label iterator
75    typedef std::vector<std::pair<size_t, CString> >::const_iterator NamedLabelIter;
76protected:
77    /// internal relocation structure
78    struct Relocation
79    {
80        size_t symbol;   ///< symbol index
81        RelocType type; ///< relocation type
82        int64_t addend; ///< relocation addend
83    };
84   
85    /// relocation iterator
86    typedef std::vector<std::pair<size_t, Relocation> >::const_iterator RelocIter;
87   
88    Disassembler& disassembler; ///< disassembler instance
89    size_t startOffset; ///< start offset
90    size_t labelStartOffset; /// < start offset of labels
91    size_t inputSize;   ///< size of input
92    const cxbyte* input;    ///< input code
93    bool dontPrintLabelsAfterCode;
94    std::vector<size_t> labels; ///< list of local labels
95    std::vector<std::pair<size_t, CString> > namedLabels;   ///< named labels
96    std::vector<CString> relSymbols;    ///< symbols used by relocations
97    std::vector<std::pair<size_t, Relocation> > relocations;    ///< relocations
98    FastOutputBuffer output;    ///< output buffer
99   
100    /// constructor
101    explicit ISADisassembler(Disassembler& disassembler, cxuint outBufSize = 600);
102   
103    /// write location in the code
104    void writeLocation(size_t pos);
105    /// write relocation to current place in instruction
106    bool writeRelocation(size_t pos, RelocIter& relocIter);
107   
108public:
109    virtual ~ISADisassembler();
110   
111    /// write all labels before specified position
112    void writeLabelsToPosition(size_t pos, LabelIter& labelIter,
113               NamedLabelIter& namedLabelIter);
114    /// write all labels to end
115    void writeLabelsToEnd(size_t start, LabelIter labelIter, NamedLabelIter namedLabelIter);
116   
117    /// set input code
118    void setInput(size_t inputSize, const cxbyte* input, size_t startOffset = 0,
119        size_t labelStartOffset = 0)
120    {
121        this->inputSize = inputSize;
122        this->input = input;
123        this->startOffset = startOffset;
124        this->labelStartOffset = labelStartOffset;
125    }
126   
127    void setDontPrintLabels(bool after)
128    { dontPrintLabelsAfterCode = after; }
129   
130    /// analyze code before disassemblying
131    virtual void analyzeBeforeDisassemble() = 0;
132   
133    /// first part before disassemble - clear numbered labels
134    void clearNumberedLabels();
135    /// last part before disassemble - prepare labels (sorting)
136    void prepareLabelsAndRelocations();
137    /// makes some things before disassemblying
138    void beforeDisassemble();
139    /// disassembles input code
140    virtual void disassemble() = 0;
141
142    /// add named label to list (must be called before disassembly)
143    void addNamedLabel(size_t pos, const CString& name)
144    { namedLabels.push_back(std::make_pair(pos, name)); }
145    /// add named label to list (must be called before disassembly)
146    void addNamedLabel(size_t pos, CString&& name)
147    { namedLabels.push_back(std::make_pair(pos, name)); }
148   
149    /// add symbol to relocations
150    size_t addRelSymbol(const CString& symName)
151    {
152        size_t index = relSymbols.size();
153        relSymbols.push_back(symName);
154        return index;
155    }
156    /// add relocation
157    void addRelocation(size_t offset, RelocType type, size_t symIndex, int64_t addend)
158    { relocations.push_back(std::make_pair(offset, Relocation{symIndex, type, addend})); }
159    /// clear all relocations
160    void clearRelocations()
161    {
162        relSymbols.clear();
163        relocations.clear();
164    }
165   
166    const std::vector<size_t>& getLabels() const
167    { return labels; }
168    const std::vector<std::pair<size_t, CString> >& getNamedLabels() const
169    { return namedLabels; }
170   
171    void flushOutput()
172    { return output.flush(); }
173};
174
175/// GCN architectur dissassembler
176class GCNDisassembler: public ISADisassembler
177{
178private:
179    bool instrOutOfCode;
180   
181    friend struct GCNDisasmUtils; // INTERNAL LOGIC
182public:
183    /// constructor
184    GCNDisassembler(Disassembler& disassembler);
185    /// destructor
186    ~GCNDisassembler();
187   
188    /// analyze code before disassemblying
189    void analyzeBeforeDisassemble();
190    /// disassemble code
191    void disassemble();
192};
193
194/// single kernel input for disassembler
195/** all pointer members holds only pointers that should be freed by your routines.
196 * No management of data */
197struct AmdDisasmKernelInput
198{
199    CString kernelName; ///< kernel name
200    size_t metadataSize;    ///< metadata size
201    const char* metadata;   ///< kernel's metadata
202    size_t headerSize;  ///< kernel header size
203    const cxbyte* header;   ///< kernel header size
204    std::vector<CALNoteInput> calNotes;   ///< ATI CAL notes
205    size_t dataSize;    ///< data (from inner binary) size
206    const cxbyte* data; ///< data from inner binary
207    size_t codeSize;    ///< size of code of kernel
208    const cxbyte* code; ///< code of kernel
209};
210
211/// whole disassembler input (for AMD Catalyst driver GPU binaries)
212/** all pointer members holds only pointers that should be freed by your routines.
213 * No management of data */
214struct AmdDisasmInput
215{
216    GPUDeviceType deviceType;   ///< GPU device type
217    bool is64BitMode;       ///< true if 64-bit mode of addressing
218    CString driverInfo; ///< driver info (for AMD Catalyst drivers)
219    CString compileOptions; ///< compile options which used by in clBuildProgram
220    size_t globalDataSize;  ///< global (constants for kernels) data size
221    const cxbyte* globalData;   ///< global (constants for kernels) data
222    std::vector<AmdDisasmKernelInput> kernels;    ///< kernel inputs
223};
224
225/// relocation with addend
226struct AmdCL2RelaEntry
227{
228    size_t offset;  ///< offset
229    RelocType type; ///< relocation type
230    cxuint symbol;  ///< symbol
231    int64_t addend; ///< addend
232};
233
234/// single kernel input for disassembler
235/** all pointer members holds only pointers that should be freed by your routines.
236 * No management of data */
237struct AmdCL2DisasmKernelInput
238{
239    CString kernelName; ///< kernel name
240    size_t metadataSize;    ///< metadata size
241    const cxbyte* metadata;   ///< kernel's metadata
242    size_t isaMetadataSize;    ///< metadata size
243    const cxbyte* isaMetadata;   ///< kernel's metadata
244    size_t setupSize;    ///< data (from inner binary) size
245    const cxbyte* setup; ///< data from inner binary
246    size_t stubSize;    ///< data (from inner binary) size
247    const cxbyte* stub; ///< data from inner binary
248    std::vector<AmdCL2RelaEntry> textRelocs;    ///< text relocations
249    size_t codeSize;    ///< size of code of kernel
250    const cxbyte* code; ///< code of kernel
251};
252
253/// whole disassembler input (for AMD Catalyst driver GPU binaries)
254/** all pointer members holds only pointers that should be freed by your routines.
255 * No management of data */
256struct AmdCL2DisasmInput
257{
258    GPUDeviceType deviceType;   ///< GPU device type
259    uint32_t archMinor;     ///< GPU arch minor
260    uint32_t archStepping;     ///< GPU arch stepping
261    bool is64BitMode;       ///< true if 64-bit mode of addressing
262    cxuint driverVersion; ///< driver version
263    CString compileOptions; ///< compile options which used by in clBuildProgram
264    CString aclVersionString; ///< acl version string
265    size_t globalDataSize;  ///< global (constants for kernels) data size
266    const cxbyte* globalData;   ///< global (constants for kernels) data
267    size_t rwDataSize;  ///< global rw data size
268    const cxbyte* rwData;   ///< global rw data data
269    size_t bssAlignment;    ///< alignment of global bss section
270    size_t bssSize;         ///< size of global bss section
271    size_t samplerInitSize;     ///< sampler init data size
272    const cxbyte* samplerInit;  ///< sampler init data
273   
274    /// sampler relocations
275    std::vector<std::pair<size_t, size_t> > samplerRelocs;
276    std::vector<AmdCL2DisasmKernelInput> kernels;    ///< kernel inputs
277};
278
279struct ROCmDisasmKernelInput
280{
281    CString kernelName; ///< kernel name
282    const cxbyte* setup;
283    size_t codeSize;
284    size_t offset;
285};
286
287/// disasm ROCm region
288struct ROCmDisasmRegionInput
289{
290    CString regionName; ///< region name
291    size_t size;    ///< region size
292    size_t offset;  ///< region offset in code
293    ROCmRegionType type ;  ///< type
294};
295
296struct ROCmDisasmInput
297{
298    GPUDeviceType deviceType;   ///< GPU device type
299    uint32_t archMinor;     ///< GPU arch minor
300    uint32_t archStepping;     ///< GPU arch stepping
301    std::vector<ROCmDisasmRegionInput> regions;  ///< regions
302    size_t codeSize;    ///< code size
303    const cxbyte* code; ///< code
304};
305
306/// disasm kernel info structure (Gallium binaries)
307struct GalliumDisasmKernelInput
308{
309    CString kernelName;   ///< kernel's name
310    GalliumProgInfoEntry progInfo[3];   ///< program info for kernel
311    uint32_t offset;    ///< offset of kernel code
312    std::vector<GalliumArgInfo> argInfos;   ///< arguments
313};
314
315/// whole disassembler input (for Gallium driver GPU binaries)
316struct GalliumDisasmInput
317{
318    GPUDeviceType deviceType;   ///< GPU device type
319    bool is64BitMode;       ///< true if 64-bit mode of addressing
320    bool isLLVM390;
321    bool isMesa170;
322    size_t globalDataSize;  ///< global (constants for kernels) data size
323    const cxbyte* globalData;   ///< global (constants for kernels) data
324    std::vector<GalliumDisasmKernelInput> kernels;    ///< list of input kernels
325    size_t codeSize;    ///< code size
326    const cxbyte* code; ///< code
327};
328
329/// disassembler input for raw code
330struct RawCodeInput
331{
332    GPUDeviceType deviceType;   ///< GPU device type
333    size_t codeSize;            ///< code size
334    const cxbyte* code;         ///< code
335};
336
337/// disassembler class
338class Disassembler: public NonCopyableAndNonMovable
339{
340private:
341    friend class ISADisassembler;
342    std::unique_ptr<ISADisassembler> isaDisassembler;
343    bool fromBinary;
344    BinaryFormat binaryFormat;
345    union {
346        const AmdDisasmInput* amdInput;
347        const AmdCL2DisasmInput* amdCL2Input;
348        const GalliumDisasmInput* galliumInput;
349        const ROCmDisasmInput* rocmInput;
350        const RawCodeInput* rawInput;
351    };
352    std::ostream& output;
353    Flags flags;
354    size_t sectionCount;
355public:
356    /// constructor for 32-bit GPU binary
357    /**
358     * \param binary main GPU binary
359     * \param output output stream
360     * \param flags flags for disassembler
361     */
362    Disassembler(const AmdMainGPUBinary32& binary, std::ostream& output,
363                 Flags flags = 0);
364    /// constructor for 64-bit GPU binary
365    /**
366     * \param binary main GPU binary
367     * \param output output stream
368     * \param flags flags for disassembler
369     */
370    Disassembler(const AmdMainGPUBinary64& binary, std::ostream& output,
371                 Flags flags = 0);
372    /// constructor for AMD OpenCL 2.0 GPU binary 32-bit
373    /**
374     * \param binary main GPU binary
375     * \param output output stream
376     * \param flags flags for disassembler
377     * \param driverVersion driverVersion (0 - detected by disassembler)
378     */
379    Disassembler(const AmdCL2MainGPUBinary32& binary, std::ostream& output,
380                 Flags flags = 0, cxuint driverVersion = 0);
381    /// constructor for AMD OpenCL 2.0 GPU binary 64-bit
382    /**
383     * \param binary main GPU binary
384     * \param output output stream
385     * \param flags flags for disassembler
386     * \param driverVersion driverVersion (0 - detected by disassembler)
387     */
388    Disassembler(const AmdCL2MainGPUBinary64& binary, std::ostream& output,
389                 Flags flags = 0, cxuint driverVersion = 0);
390    /// constructor for ROCm GPU binary
391    /**
392     * \param binary main GPU binary
393     * \param output output stream
394     * \param flags flags for disassembler
395     */
396    Disassembler(const ROCmBinary& binary, std::ostream& output, Flags flags = 0);
397    /// constructor for AMD disassembler input
398    /**
399     * \param disasmInput disassembler input object
400     * \param output output stream
401     * \param flags flags for disassembler
402     */
403    Disassembler(const AmdDisasmInput* disasmInput, std::ostream& output,
404                 Flags flags = 0);
405    /// constructor for AMD OpenCL 2.0 disassembler input
406    /**
407     * \param disasmInput disassembler input object
408     * \param output output stream
409     * \param flags flags for disassembler
410     */
411    Disassembler(const AmdCL2DisasmInput* disasmInput, std::ostream& output,
412                 Flags flags = 0);
413    /// constructor for ROCMm disassembler input
414    /**
415     * \param disasmInput disassembler input object
416     * \param output output stream
417     * \param flags flags for disassembler
418     */
419    Disassembler(const ROCmDisasmInput* disasmInput, std::ostream& output,
420                 Flags flags = 0);
421   
422    /// constructor for bit GPU binary from Gallium
423    /**
424     * \param deviceType GPU device type
425     * \param binary main GPU binary
426     * \param output output stream
427     * \param flags flags for disassembler
428     */
429    Disassembler(GPUDeviceType deviceType, const GalliumBinary& binary,
430                 std::ostream& output, Flags flags = 0);
431   
432    /// constructor for Gallium disassembler input
433    /**
434     * \param disasmInput disassembler input object
435     * \param output output stream
436     * \param flags flags for disassembler
437     */
438    Disassembler(const GalliumDisasmInput* disasmInput, std::ostream& output,
439                 Flags flags = 0);
440   
441    /// constructor for raw code
442    Disassembler(GPUDeviceType deviceType, size_t rawCodeSize, const cxbyte* rawCode,
443                 std::ostream& output, Flags flags = 0);
444   
445    ~Disassembler();
446   
447    /// disassembles input
448    void disassemble();
449   
450    /// get disassemblers flags
451    Flags getFlags() const
452    { return flags; }
453    /// get disassemblers flags
454    void setFlags(Flags flags)
455    { this->flags = flags; }
456   
457    /// get deviceType
458    GPUDeviceType getDeviceType() const;
459   
460    /// get disassembler input
461    const AmdDisasmInput* getAmdInput() const
462    { return amdInput; }
463   
464    /// get disassembler input
465    const AmdCL2DisasmInput* getAmdCL2Input() const
466    { return amdCL2Input; }
467   
468    /// get disassembler input
469    const GalliumDisasmInput* getGalliumInput() const
470    { return galliumInput; }
471   
472    /// get output stream
473    const std::ostream& getOutput() const
474    { return output; }
475    /// get output stream
476    std::ostream& getOutput()
477    { return output; }
478};
479
480};
481
482#endif
Note: See TracBrowser for help on using the repository browser.