intel/gpu_dump: fix argument passing
[mesa.git] / src / intel / tools / i965_disasm.c
1 /*
2 * Copyright © 2018 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <getopt.h>
28
29 #include "compiler/brw_eu.h"
30 #include "dev/gen_device_info.h"
31
32 /* Return size of file in bytes pointed by fp */
33 static size_t
34 i965_disasm_get_file_size(FILE *fp)
35 {
36 size_t size;
37
38 fseek(fp, 0L, SEEK_END);
39 size = ftell(fp);
40 fseek(fp, 0L, SEEK_SET);
41
42 return size;
43 }
44
45 static void *
46 i965_disasm_read_binary(FILE *fp, size_t *end)
47 {
48 size_t size;
49 void *assembly;
50
51 *end = i965_disasm_get_file_size(fp);
52 if (!*end)
53 return NULL;
54
55 assembly = malloc(*end + 1);
56 if (assembly == NULL)
57 return NULL;
58
59 size = fread(assembly, *end, 1, fp);
60 fclose(fp);
61 if (!size) {
62 free(assembly);
63 return NULL;
64 }
65 return assembly;
66 }
67
68 static struct gen_device_info *
69 i965_disasm_init(uint16_t pci_id)
70 {
71 struct gen_device_info *devinfo;
72
73 devinfo = malloc(sizeof *devinfo);
74 if (devinfo == NULL)
75 return NULL;
76
77 if (!gen_get_device_info(pci_id, devinfo)) {
78 fprintf(stderr, "can't find device information: pci_id=0x%x\n",
79 pci_id);
80 exit(EXIT_FAILURE);
81 }
82
83 /* initialize compaction table in order to handle compacted instructions */
84 brw_init_compaction_tables(devinfo);
85
86 return devinfo;
87 }
88
89 static void
90 print_help(const char *progname, FILE *file)
91 {
92 fprintf(file,
93 "Usage: %s [OPTION]...\n"
94 "Disassemble i965 instructions from binary file.\n\n"
95 " --help display this help and exit\n"
96 " --binary-path=PATH read binary file from binary file PATH\n"
97 " --gen=platform disassemble instructions for given \n"
98 " platform (3 letter platform name)\n",
99 progname);
100 }
101
102 int main(int argc, char *argv[])
103 {
104 FILE *fp = NULL;
105 void *assembly = NULL;
106 char *binary_path = NULL;
107 size_t start = 0, end = 0;
108 uint16_t pci_id = 0;
109 int c, i;
110 struct gen_device_info *devinfo;
111
112 bool help = false;
113 const struct option i965_disasm_opts[] = {
114 { "help", no_argument, (int *) &help, true },
115 { "binary-path", required_argument, NULL, 'b' },
116 { "gen", required_argument, NULL, 'g'},
117 { NULL, 0, NULL, 0 }
118 };
119
120 i = 0;
121 while ((c = getopt_long(argc, argv, "", i965_disasm_opts, &i)) != -1) {
122 switch (c) {
123 case 'g': {
124 const int id = gen_device_name_to_pci_device_id(optarg);
125 if (id < 0) {
126 fprintf(stderr, "can't parse gen: '%s', expected 3 letter "
127 "platform name\n", optarg);
128 /* Clean up binary path if given pci id is wrong */
129 if (binary_path) {
130 free(binary_path);
131 fclose(fp);
132 }
133 exit(EXIT_FAILURE);
134 } else {
135 pci_id = id;
136 }
137 break;
138 }
139 case 'b':
140 binary_path = strdup(optarg);
141 fp = fopen(binary_path, "rb");
142 if (!fp) {
143 fprintf(stderr, "Unable to read input binary file : %s\n",
144 binary_path);
145 /* free binary_path if path is wrong */
146 free(binary_path);
147 exit(EXIT_FAILURE);
148 }
149 break;
150 default:
151 /* Clean up binary path if given option is wrong */
152 if (binary_path) {
153 free(binary_path);
154 fclose(fp);
155 }
156 break;
157 }
158 }
159
160 if (help || !binary_path || !pci_id) {
161 print_help(argv[0], stderr);
162 exit(0);
163 }
164
165 devinfo = i965_disasm_init(pci_id);
166 if (!devinfo) {
167 fprintf(stderr, "Unable to allocate memory for "
168 "gen_device_info struct instance.\n");
169 exit(EXIT_FAILURE);
170 }
171
172 assembly = i965_disasm_read_binary(fp, &end);
173 if (!assembly) {
174 if (end)
175 fprintf(stderr, "Unable to allocate buffer to read binary file\n");
176 else
177 fprintf(stderr, "Input file is empty\n");
178
179 exit(EXIT_FAILURE);
180 }
181
182 /* Disassemble i965 instructions from buffer assembly */
183 brw_disassemble(devinfo, assembly, start, end, stdout);
184
185 free(binary_path);
186 free(assembly);
187 free(devinfo);
188
189 return EXIT_SUCCESS;
190 }