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

Last change on this file since 2498 was 2498, checked in by matszpk, 3 years ago

CLRadeonExtender: Refactor AMDBIN* flags for AmdCL2Binaries module.

File size: 7.5 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/GalliumBinaries.h>
27#include <CLRX/amdasm/Disassembler.h>
28
29using namespace CLRX;
30
31static const CLIOption programOptions[] =
32{
33    { "metadata", 'm', CLIArgType::NONE, false, false, "dump object metadata", nullptr },
34    { "data", 'd', CLIArgType::NONE, false, false, "dump global data", nullptr },
35    { "calNotes", 'c', CLIArgType::NONE, false, false, "dump ATI CAL notes", nullptr },
36    { "config", 'C', CLIArgType::NONE, false, false, "dump kernel configuration", nullptr },
37    { "setup", 's', CLIArgType::NONE, false, false, "dump kernel setup", nullptr },
38    { "floats", 'f', CLIArgType::NONE, false, false, "display float literals", nullptr },
39    { "hexcode", 'h', CLIArgType::NONE, false, false,
40        "display hexadecimal instr. codes", nullptr },
41    { "all", 'a', CLIArgType::NONE, false, false,
42        "dump all (including hexcode and float literals)", nullptr },
43    { "raw", 'r', CLIArgType::NONE, false, false, "treat input as raw GCN code", nullptr },
44    { "gpuType", 'g', CLIArgType::TRIMMED_STRING, false, false,
45        "set GPU type for Gallium/raw binaries", "DEVICE" },
46    { "arch", 'A', CLIArgType::TRIMMED_STRING, false, false,
47        "set GPU architecture for Gallium/raw binaries", "ARCH" },
48    { "buggyFPLit", 0, CLIArgType::NONE, false, false,
49        "use old and buggy fplit rules", nullptr },
50    CLRX_CLI_AUTOHELP
51    { nullptr, 0 }
52};
53
54int main(int argc, const char** argv)
55try
56{
57    CLIParser cli("clrxdisasm", programOptions, argc, argv);
58    cli.parse();
59    if (cli.handleHelpOrUsage())
60        return 0;
61   
62    if (cli.getArgsNum() == 0)
63    {
64        std::cerr << "No input files." << std::endl;
65        return 1;
66    }
67   
68    Flags disasmFlags = DISASM_DUMPCODE;
69    if (cli.hasShortOption('a'))
70        disasmFlags = DISASM_ALL;
71    else
72        disasmFlags |= (cli.hasShortOption('m')?DISASM_METADATA:0) |
73            (cli.hasShortOption('d')?DISASM_DUMPDATA:0) |
74            (cli.hasShortOption('c')?DISASM_CALNOTES:0) |
75            (cli.hasShortOption('s')?DISASM_SETUP:0) |
76            (cli.hasShortOption('f')?DISASM_FLOATLITS:0) |
77            (cli.hasShortOption('h')?DISASM_HEXCODE:0);
78     disasmFlags |= (cli.hasShortOption('C')?DISASM_CONFIG:0) |
79             (cli.hasLongOption("buggyFPLit")?DISASM_BUGGYFPLIT:0);
80   
81    GPUDeviceType gpuDeviceType = GPUDeviceType::CAPE_VERDE;
82    const bool fromRawCode = cli.hasShortOption('r');
83    if (cli.hasShortOption('g'))
84        gpuDeviceType = getGPUDeviceTypeFromName(cli.getShortOptArg<const char*>('g'));
85    else if (cli.hasShortOption('A'))
86        gpuDeviceType = getLowestGPUDeviceTypeFromArchitecture(
87                    getGPUArchitectureFromName(cli.getShortOptArg<const char*>('A')));
88   
89    int ret = 0;
90    for (const char* const* args = cli.getArgs();*args != nullptr; args++)
91    {
92        std::cout << "/* Disassembling '" << *args << "\' */" << std::endl;
93        Array<cxbyte> binaryData;
94        std::unique_ptr<AmdMainBinaryBase> base = nullptr;
95        try
96        {
97            binaryData = loadDataFromFile(*args);
98           
99            if (!fromRawCode)
100            {
101                Flags binFlags = AMDBIN_CREATE_KERNELINFO | AMDBIN_CREATE_KERNELINFOMAP |
102                        AMDBIN_CREATE_INNERBINMAP | AMDBIN_CREATE_KERNELHEADERS |
103                        AMDBIN_CREATE_KERNELHEADERMAP;
104                if ((disasmFlags & (DISASM_CALNOTES|DISASM_CONFIG)) != 0)
105                    binFlags |= AMDBIN_INNER_CREATE_CALNOTES;
106                if ((disasmFlags & (DISASM_METADATA|DISASM_CONFIG)) != 0)
107                    binFlags |= AMDBIN_CREATE_INFOSTRINGS;
108               
109                if (isAmdBinary(binaryData.size(), binaryData.data()))
110                {   // if amd binary
111                    base.reset(createAmdBinaryFromCode(binaryData.size(),
112                            binaryData.data(), binFlags));
113                    if (base->getType() == AmdMainType::GPU_BINARY)
114                    {
115                        AmdMainGPUBinary32* amdGpuBin =
116                                static_cast<AmdMainGPUBinary32*>(base.get());
117                        Disassembler disasm(*amdGpuBin, std::cout, disasmFlags);
118                        disasm.disassemble();
119                    }
120                    else if (base->getType() == AmdMainType::GPU_64_BINARY)
121                    {
122                        AmdMainGPUBinary64* amdGpuBin =
123                                static_cast<AmdMainGPUBinary64*>(base.get());
124                        Disassembler disasm(*amdGpuBin, std::cout, disasmFlags);
125                        disasm.disassemble();
126                    }
127                    else
128                        throw Exception("This is not AMDGPU binary file!");
129                }
130                else if (isAmdCL2Binary(binaryData.size(), binaryData.data()))
131                {   // AMD OpenCL 2.0 binary
132                    binFlags |= AMDCL2BIN_INNER_CREATE_KERNELDATA |
133                                AMDCL2BIN_INNER_CREATE_KERNELDATAMAP |
134                                AMDCL2BIN_INNER_CREATE_KERNELSTUBS;
135                    AmdCL2MainGPUBinary amdBin(binaryData.size(),
136                                       binaryData.data(), binFlags);
137                    Disassembler disasm(amdBin, std::cout, disasmFlags);
138                    disasm.disassemble();
139                }
140                else // if gallium binary
141                {
142                    GalliumBinary galliumBin(binaryData.size(),binaryData.data(), 0);
143                    Disassembler disasm(gpuDeviceType, galliumBin, std::cout, disasmFlags);
144                    disasm.disassemble();
145                }
146            }
147            else
148            {   /* raw binaries */
149                Disassembler disasm(gpuDeviceType, binaryData.size(), binaryData.data(),
150                        std::cout, disasmFlags);
151                disasm.disassemble();
152            }
153        }
154        catch(const std::exception& ex)
155        {
156            ret = 1;
157            std::cout << "/* ERROR for '" << *args << "\' */" << std::endl;
158            std::cerr << "Error during disassemblying '" << *args << "': " <<
159                    ex.what() << std::endl;
160        }
161    }
162   
163    return ret;
164}
165catch(const Exception& ex)
166{
167    std::cerr << ex.what() << std::endl;
168    return 1;
169}
170catch(const std::bad_alloc& ex)
171{
172    std::cerr << "Out of memory" << std::endl;
173    return 1;
174}
175catch(const std::exception& ex)
176{
177    std::cerr << "System exception: " << ex.what() << std::endl;
178    return 1;
179}
180catch(...)
181{
182    std::cerr << "Unknown exception" << std::endl;
183    return 1;
184}
Note: See TracBrowser for help on using the repository browser.