source: CLRX/CLRadeonExtender/trunk/programs/clrxdisasm.cpp @ 2571

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

CLRadeonExtender: Fixed binFlags for ROCm in clrxdisasm. Add example for ROCm to DisasmDataTest?.

File size: 7.9 KB
Line 
1/*
2 *  CLRadeonExtender - Unofficial OpenCL Radeon Extensions Library
3 *  Copyright (C) 2014-2016 Mateusz Szpakowski
4 *
5 *  This program is free software; you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation; either version 2 of the License, or
8 *  (at your option) any later version.
9 *
10 *  This program 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
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License along
16 *  with this program; if not, write to the Free Software Foundation, Inc.,
17 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#include <CLRX/Config.h>
21#include <iostream>
22#include <memory>
23#include <CLRX/utils/Utilities.h>
24#include <CLRX/utils/CLIParser.h>
25#include <CLRX/amdbin/AmdBinaries.h>
26#include <CLRX/amdbin/AmdCL2Binaries.h>
27#include <CLRX/amdbin/ROCmBinaries.h>
28#include <CLRX/amdbin/GalliumBinaries.h>
29#include <CLRX/amdasm/Disassembler.h>
30
31using namespace CLRX;
32
33static const CLIOption programOptions[] =
34{
35    { "metadata", 'm', CLIArgType::NONE, false, false, "dump object metadata", nullptr },
36    { "data", 'd', CLIArgType::NONE, false, false, "dump global data", nullptr },
37    { "calNotes", 'c', CLIArgType::NONE, false, false, "dump ATI CAL notes", nullptr },
38    { "config", 'C', CLIArgType::NONE, false, false, "dump kernel configuration", nullptr },
39    { "setup", 's', CLIArgType::NONE, false, false, "dump kernel setup", nullptr },
40    { "floats", 'f', CLIArgType::NONE, false, false, "display float literals", nullptr },
41    { "hexcode", 'h', CLIArgType::NONE, false, false,
42        "display hexadecimal instr. codes", nullptr },
43    { "all", 'a', CLIArgType::NONE, false, false,
44        "dump all (including hexcode and float literals)", nullptr },
45    { "raw", 'r', CLIArgType::NONE, false, false, "treat input as raw GCN code", nullptr },
46    { "gpuType", 'g', CLIArgType::TRIMMED_STRING, false, false,
47        "set GPU type for Gallium/raw binaries", "DEVICE" },
48    { "arch", 'A', CLIArgType::TRIMMED_STRING, false, false,
49        "set GPU architecture for Gallium/raw binaries", "ARCH" },
50    { "buggyFPLit", 0, CLIArgType::NONE, false, false,
51        "use old and buggy fplit rules", nullptr },
52    CLRX_CLI_AUTOHELP
53    { nullptr, 0 }
54};
55
56int main(int argc, const char** argv)
57try
58{
59    CLIParser cli("clrxdisasm", programOptions, argc, argv);
60    cli.parse();
61    if (cli.handleHelpOrUsage())
62        return 0;
63   
64    if (cli.getArgsNum() == 0)
65    {
66        std::cerr << "No input files." << std::endl;
67        return 1;
68    }
69   
70    Flags disasmFlags = DISASM_DUMPCODE;
71    if (cli.hasShortOption('a'))
72        disasmFlags = DISASM_ALL;
73    else
74        disasmFlags |= (cli.hasShortOption('m')?DISASM_METADATA:0) |
75            (cli.hasShortOption('d')?DISASM_DUMPDATA:0) |
76            (cli.hasShortOption('c')?DISASM_CALNOTES:0) |
77            (cli.hasShortOption('s')?DISASM_SETUP:0) |
78            (cli.hasShortOption('f')?DISASM_FLOATLITS:0) |
79            (cli.hasShortOption('h')?DISASM_HEXCODE:0);
80     disasmFlags |= (cli.hasShortOption('C')?DISASM_CONFIG:0) |
81             (cli.hasLongOption("buggyFPLit")?DISASM_BUGGYFPLIT:0);
82   
83    GPUDeviceType gpuDeviceType = GPUDeviceType::CAPE_VERDE;
84    const bool fromRawCode = cli.hasShortOption('r');
85    if (cli.hasShortOption('g'))
86        gpuDeviceType = getGPUDeviceTypeFromName(cli.getShortOptArg<const char*>('g'));
87    else if (cli.hasShortOption('A'))
88        gpuDeviceType = getLowestGPUDeviceTypeFromArchitecture(
89                    getGPUArchitectureFromName(cli.getShortOptArg<const char*>('A')));
90   
91    int ret = 0;
92    for (const char* const* args = cli.getArgs();*args != nullptr; args++)
93    {
94        std::cout << "/* Disassembling '" << *args << "\' */" << std::endl;
95        Array<cxbyte> binaryData;
96        std::unique_ptr<AmdMainBinaryBase> base = nullptr;
97        try
98        {
99            binaryData = loadDataFromFile(*args);
100           
101            if (!fromRawCode)
102            {
103                Flags binFlags = AMDBIN_CREATE_KERNELINFO | AMDBIN_CREATE_KERNELINFOMAP |
104                        AMDBIN_CREATE_INNERBINMAP | AMDBIN_CREATE_KERNELHEADERS |
105                        AMDBIN_CREATE_KERNELHEADERMAP;
106                if ((disasmFlags & (DISASM_CALNOTES|DISASM_CONFIG)) != 0)
107                    binFlags |= AMDBIN_INNER_CREATE_CALNOTES;
108                if ((disasmFlags & (DISASM_METADATA|DISASM_CONFIG)) != 0)
109                    binFlags |= AMDBIN_CREATE_INFOSTRINGS;
110               
111                if (isAmdBinary(binaryData.size(), binaryData.data()))
112                {   // if amd binary
113                    base.reset(createAmdBinaryFromCode(binaryData.size(),
114                            binaryData.data(), binFlags));
115                    if (base->getType() == AmdMainType::GPU_BINARY)
116                    {
117                        AmdMainGPUBinary32* amdGpuBin =
118                                static_cast<AmdMainGPUBinary32*>(base.get());
119                        Disassembler disasm(*amdGpuBin, std::cout, disasmFlags);
120                        disasm.disassemble();
121                    }
122                    else if (base->getType() == AmdMainType::GPU_64_BINARY)
123                    {
124                        AmdMainGPUBinary64* amdGpuBin =
125                                static_cast<AmdMainGPUBinary64*>(base.get());
126                        Disassembler disasm(*amdGpuBin, std::cout, disasmFlags);
127                        disasm.disassemble();
128                    }
129                    else
130                        throw Exception("This is not AMDGPU binary file!");
131                }
132                else if (isAmdCL2Binary(binaryData.size(), binaryData.data()))
133                {   // AMD OpenCL 2.0 binary
134                    binFlags |= AMDCL2BIN_INNER_CREATE_KERNELDATA |
135                                AMDCL2BIN_INNER_CREATE_KERNELDATAMAP |
136                                AMDCL2BIN_INNER_CREATE_KERNELSTUBS;
137                    AmdCL2MainGPUBinary amdBin(binaryData.size(),
138                                       binaryData.data(), binFlags);
139                    Disassembler disasm(amdBin, std::cout, disasmFlags);
140                    disasm.disassemble();
141                }
142                else if (isROCmBinary(binaryData.size(), binaryData.data()))
143                {   // ROCm binary
144                    binFlags = ROCMBIN_CREATE_REGIONMAP;
145                    ROCmBinary rocmBin(binaryData.size(), binaryData.data(), binFlags);
146                    Disassembler disasm(rocmBin, std::cout, disasmFlags);
147                    disasm.disassemble();
148                }
149                else // if gallium binary
150                {
151                    GalliumBinary galliumBin(binaryData.size(),binaryData.data(), 0);
152                    Disassembler disasm(gpuDeviceType, galliumBin, std::cout, disasmFlags);
153                    disasm.disassemble();
154                }
155            }
156            else
157            {   /* raw binaries */
158                Disassembler disasm(gpuDeviceType, binaryData.size(), binaryData.data(),
159                        std::cout, disasmFlags);
160                disasm.disassemble();
161            }
162        }
163        catch(const std::exception& ex)
164        {
165            ret = 1;
166            std::cout << "/* ERROR for '" << *args << "\' */" << std::endl;
167            std::cerr << "Error during disassemblying '" << *args << "': " <<
168                    ex.what() << std::endl;
169        }
170    }
171   
172    return ret;
173}
174catch(const Exception& ex)
175{
176    std::cerr << ex.what() << std::endl;
177    return 1;
178}
179catch(const std::bad_alloc& ex)
180{
181    std::cerr << "Out of memory" << std::endl;
182    return 1;
183}
184catch(const std::exception& ex)
185{
186    std::cerr << "System exception: " << ex.what() << std::endl;
187    return 1;
188}
189catch(...)
190{
191    std::cerr << "Unknown exception" << std::endl;
192    return 1;
193}
Note: See TracBrowser for help on using the repository browser.