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

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

CLRadeonExtender: GCNDisasm: Increase outBufSize and increase buffer reservation size.

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    size_t globalDataSize;  ///< global (constants for kernels) data size
321    const cxbyte* globalData;   ///< global (constants for kernels) data
322    std::vector<GalliumDisasmKernelInput> kernels;    ///< list of input kernels
323    size_t codeSize;    ///< code size
324    const cxbyte* code; ///< code
325};
326
327/// disassembler input for raw code
328struct RawCodeInput
329{
330    GPUDeviceType deviceType;   ///< GPU device type
331    size_t codeSize;            ///< code size
332    const cxbyte* code;         ///< code
333};
334
335/// disassembler class
336class Disassembler: public NonCopyableAndNonMovable
337{
338private:
339    friend class ISADisassembler;
340    std::unique_ptr<ISADisassembler> isaDisassembler;
341    bool fromBinary;
342    BinaryFormat binaryFormat;
343    union {
344        const AmdDisasmInput* amdInput;
345        const AmdCL2DisasmInput* amdCL2Input;
346        const GalliumDisasmInput* galliumInput;
347        const ROCmDisasmInput* rocmInput;
348        const RawCodeInput* rawInput;
349    };
350    std::ostream& output;
351    Flags flags;
352    size_t sectionCount;
353public:
354    /// constructor for 32-bit GPU binary
355    /**
356     * \param binary main GPU binary
357     * \param output output stream
358     * \param flags flags for disassembler
359     */
360    Disassembler(const AmdMainGPUBinary32& binary, std::ostream& output,
361                 Flags flags = 0);
362    /// constructor for 64-bit GPU binary
363    /**
364     * \param binary main GPU binary
365     * \param output output stream
366     * \param flags flags for disassembler
367     */
368    Disassembler(const AmdMainGPUBinary64& binary, std::ostream& output,
369                 Flags flags = 0);
370    /// constructor for AMD OpenCL 2.0 GPU binary 32-bit
371    /**
372     * \param binary main GPU binary
373     * \param output output stream
374     * \param flags flags for disassembler
375     * \param driverVersion driverVersion (0 - detected by disassembler)
376     */
377    Disassembler(const AmdCL2MainGPUBinary32& binary, std::ostream& output,
378                 Flags flags = 0, cxuint driverVersion = 0);
379    /// constructor for AMD OpenCL 2.0 GPU binary 64-bit
380    /**
381     * \param binary main GPU binary
382     * \param output output stream
383     * \param flags flags for disassembler
384     * \param driverVersion driverVersion (0 - detected by disassembler)
385     */
386    Disassembler(const AmdCL2MainGPUBinary64& binary, std::ostream& output,
387                 Flags flags = 0, cxuint driverVersion = 0);
388    /// constructor for ROCm GPU binary
389    /**
390     * \param binary main GPU binary
391     * \param output output stream
392     * \param flags flags for disassembler
393     */
394    Disassembler(const ROCmBinary& binary, std::ostream& output, Flags flags = 0);
395    /// constructor for AMD disassembler input
396    /**
397     * \param disasmInput disassembler input object
398     * \param output output stream
399     * \param flags flags for disassembler
400     */
401    Disassembler(const AmdDisasmInput* disasmInput, std::ostream& output,
402                 Flags flags = 0);
403    /// constructor for AMD OpenCL 2.0 disassembler input
404    /**
405     * \param disasmInput disassembler input object
406     * \param output output stream
407     * \param flags flags for disassembler
408     */
409    Disassembler(const AmdCL2DisasmInput* disasmInput, std::ostream& output,
410                 Flags flags = 0);
411    /// constructor for ROCMm disassembler input
412    /**
413     * \param disasmInput disassembler input object
414     * \param output output stream
415     * \param flags flags for disassembler
416     */
417    Disassembler(const ROCmDisasmInput* disasmInput, std::ostream& output,
418                 Flags flags = 0);
419   
420    /// constructor for bit GPU binary from Gallium
421    /**
422     * \param deviceType GPU device type
423     * \param binary main GPU binary
424     * \param output output stream
425     * \param flags flags for disassembler
426     */
427    Disassembler(GPUDeviceType deviceType, const GalliumBinary& binary,
428                 std::ostream& output, Flags flags = 0);
429   
430    /// constructor for Gallium disassembler input
431    /**
432     * \param disasmInput disassembler input object
433     * \param output output stream
434     * \param flags flags for disassembler
435     */
436    Disassembler(const GalliumDisasmInput* disasmInput, std::ostream& output,
437                 Flags flags = 0);
438   
439    /// constructor for raw code
440    Disassembler(GPUDeviceType deviceType, size_t rawCodeSize, const cxbyte* rawCode,
441                 std::ostream& output, Flags flags = 0);
442   
443    ~Disassembler();
444   
445    /// disassembles input
446    void disassemble();
447   
448    /// get disassemblers flags
449    Flags getFlags() const
450    { return flags; }
451    /// get disassemblers flags
452    void setFlags(Flags flags)
453    { this->flags = flags; }
454   
455    /// get deviceType
456    GPUDeviceType getDeviceType() const;
457   
458    /// get disassembler input
459    const AmdDisasmInput* getAmdInput() const
460    { return amdInput; }
461   
462    /// get disassembler input
463    const AmdCL2DisasmInput* getAmdCL2Input() const
464    { return amdCL2Input; }
465   
466    /// get disassembler input
467    const GalliumDisasmInput* getGalliumInput() const
468    { return galliumInput; }
469   
470    /// get output stream
471    const std::ostream& getOutput() const
472    { return output; }
473    /// get output stream
474    std::ostream& getOutput()
475    { return output; }
476};
477
478};
479
480#endif
Note: See TracBrowser for help on using the repository browser.