Path: blob/21.2-virgl/src/intel/tools/i965_disasm.c
4547 views
/*1* Copyright © 2018 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include <stdio.h>24#include <stdlib.h>25#include <string.h>26#include <getopt.h>2728#include "compiler/brw_eu.h"29#include "dev/intel_device_info.h"30#include "util/u_dynarray.h"3132enum opt_input_type {33OPT_INPUT_BINARY,34OPT_INPUT_C_LITERAL,35};3637static enum opt_input_type input_type = OPT_INPUT_BINARY;3839/* Return size of file in bytes pointed by fp */40static long41i965_disasm_get_file_size(FILE *fp)42{43long size;4445fseek(fp, 0L, SEEK_END);46size = ftell(fp);47fseek(fp, 0L, SEEK_SET);4849return size;50}5152/* Read hex file which should be in following format:53* for example :54* { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }55*/56static void *57i965_disasm_read_c_literal_file(FILE *fp, size_t *end)58{59struct util_dynarray assembly = {};60uint32_t temp[2];6162if (fscanf(fp, " { ") == EOF) {63fprintf(stderr, "Couldn't find opening `{`\n");64return NULL;65}6667if (fscanf(fp, "0x%x , 0x%x", &temp[0], &temp[1]) == 2) {68util_dynarray_append(&assembly, uint32_t, temp[0]);69util_dynarray_append(&assembly, uint32_t, temp[1]);70} else {71fprintf(stderr, "Couldn't read hex values\n");72return NULL;73}7475while (fscanf(fp, " , 0x%x , 0x%x ", &temp[0], &temp[1]) == 2) {76util_dynarray_append(&assembly, uint32_t, temp[0]);77util_dynarray_append(&assembly, uint32_t, temp[1]);78}7980if (fscanf(fp, "}") == EOF) {81fprintf(stderr, "Couldn't find closing `}`\n");82return NULL;83}8485*end = assembly.size;86return assembly.data;87}8889static void *90i965_disasm_read_binary(FILE *fp, size_t *end)91{92size_t size;93void *assembly;9495long sz = i965_disasm_get_file_size(fp);96if (sz < 0)97return NULL;9899*end = (size_t)sz;100if (!*end)101return NULL;102103assembly = malloc(*end + 1);104if (assembly == NULL)105return NULL;106107size = fread(assembly, *end, 1, fp);108if (!size) {109free(assembly);110return NULL;111}112return assembly;113}114115static struct intel_device_info *116i965_disasm_init(uint16_t pci_id)117{118struct intel_device_info *devinfo;119120devinfo = malloc(sizeof *devinfo);121if (devinfo == NULL)122return NULL;123124if (!intel_get_device_info_from_pci_id(pci_id, devinfo)) {125fprintf(stderr, "can't find device information: pci_id=0x%x\n",126pci_id);127exit(EXIT_FAILURE);128}129130return devinfo;131}132133static void134print_help(const char *progname, FILE *file)135{136fprintf(file,137"Usage: %s [OPTION]...\n"138"Disassemble i965 instructions from binary file.\n\n"139" --help display this help and exit\n"140" --input-path=PATH read binary file from binary file PATH\n"141" --type=INPUT_TYPE INPUT_TYPE can be 'bin' (default if omitted),\n"142" 'c_literal'.\n"143" --gen=platform disassemble instructions for given \n"144" platform (3 letter platform name)\n",145progname);146}147148int main(int argc, char *argv[])149{150FILE *fp = NULL;151void *assembly = NULL;152char *file_path = NULL;153size_t start = 0, end = 0;154uint16_t pci_id = 0;155int c;156struct intel_device_info *devinfo = NULL;157int result = EXIT_FAILURE;158159bool help = false;160const struct option i965_disasm_opts[] = {161{ "help", no_argument, (int *) &help, true },162{ "input-path", required_argument, NULL, 'i' },163{ "type", required_argument, NULL, 't' },164{ "gen", required_argument, NULL, 'g'},165{ NULL, 0, NULL, 0 }166};167168while ((c = getopt_long(argc, argv, ":i:t:g:h", i965_disasm_opts, NULL)) != -1) {169switch (c) {170case 'g': {171const int id = intel_device_name_to_pci_device_id(optarg);172if (id < 0) {173fprintf(stderr, "can't parse gen: '%s', expected 3 letter "174"platform name\n", optarg);175goto end;176} else {177pci_id = id;178}179break;180}181case 'i':182file_path = strdup(optarg);183fp = fopen(file_path, "r");184if (!fp) {185fprintf(stderr, "Unable to read input file : %s\n",186file_path);187goto end;188}189break;190case 't':191if (strcmp(optarg, "c_literal") == 0) {192input_type = OPT_INPUT_C_LITERAL;193} else if (strcmp(optarg, "bin") == 0) {194input_type = OPT_INPUT_BINARY;195} else {196fprintf(stderr, "invalid value for --type: %s\n", optarg);197goto end;198}199break;200case 'h':201help = true;202print_help(argv[0], stderr);203goto end;204case 0:205break;206case ':':207fprintf(stderr, "%s: option `-%c' requires an argument\n",208argv[0], optopt);209goto end;210case '?':211default:212fprintf(stderr, "%s: option `-%c' is invalid: ignored\n",213argv[0], optopt);214goto end;215}216}217218if (help || !file_path || !pci_id) {219print_help(argv[0], stderr);220exit(0);221}222223devinfo = i965_disasm_init(pci_id);224if (!devinfo) {225fprintf(stderr, "Unable to allocate memory for "226"intel_device_info struct instance.\n");227goto end;228}229230if (input_type == OPT_INPUT_BINARY)231assembly = i965_disasm_read_binary(fp, &end);232else if (input_type == OPT_INPUT_C_LITERAL)233assembly = i965_disasm_read_c_literal_file(fp, &end);234235if (!assembly) {236if (end)237fprintf(stderr, "Unable to allocate buffer to read input file\n");238else239fprintf(stderr, "Failed to read input file\n");240241goto end;242}243244/* Disassemble i965 instructions from buffer assembly */245brw_disassemble_with_labels(devinfo, assembly, start, end, stdout);246247result = EXIT_SUCCESS;248249end:250if (fp)251fclose(fp);252253free(file_path);254free(assembly);255free(devinfo);256257exit(result);258}259260261