/* Extract and analyze information from the program binary associated with 'kernel_name' */ void si_opencl_kernel_load(struct si_opencl_kernel_t *kernel, char *kernel_name) { struct si_opencl_program_t *program; char symbol_name[MAX_STRING_SIZE]; char name[MAX_STRING_SIZE]; /* First */ strncpy(kernel->name, kernel_name, MAX_STRING_SIZE); program = si_opencl_repo_get_object(si_emu->opencl_repo, si_opencl_object_program, kernel->program_id); /* Read 'metadata' symbol */ snprintf(symbol_name, MAX_STRING_SIZE, "__OpenCL_%s_metadata", kernel_name); si_opencl_program_read_symbol(program, symbol_name, &kernel->metadata_buffer); /* Read 'kernel' symbol */ snprintf(symbol_name, MAX_STRING_SIZE, "__OpenCL_%s_kernel", kernel_name); si_opencl_program_read_symbol(program, symbol_name, &kernel->kernel_buffer); /* Read 'header' symbol */ snprintf(symbol_name, MAX_STRING_SIZE, "__OpenCL_%s_header", kernel_name); si_opencl_program_read_symbol(program, symbol_name, &kernel->header_buffer); /* Create and parse kernel binary (internal ELF). * The internal ELF is contained in the buffer pointer to by the 'kernel' symbol. */ snprintf(name, sizeof(name), "clKernel<%s>.InternalELF", kernel_name); kernel->bin_file = si_bin_file_create(kernel->kernel_buffer.ptr, kernel->kernel_buffer.size, name); /* Analyze 'metadata' file */ si_opencl_kernel_load_metadata(kernel); }
/* GPU disassembler tool */ void si_emu_disasm(char *path) { struct elf_file_t *elf_file; struct elf_symbol_t *symbol; struct elf_section_t *section; struct si_bin_file_t *amd_bin; char kernel_name[MAX_STRING_SIZE]; int i; /* Initialize disassembler */ si_disasm_init(); /* Decode external ELF */ elf_file = elf_file_create_from_path(path); for (i = 0; i < list_count(elf_file->symbol_table); i++) { /* Get symbol and section */ symbol = list_get(elf_file->symbol_table, i); section = list_get(elf_file->section_list, symbol->section); if (!section) continue; /* If symbol is '__OpenCL_XXX_kernel', it points to internal ELF */ if (str_prefix(symbol->name, "__OpenCL_") && str_suffix(symbol->name, "_kernel")) { /* Decode internal ELF */ str_substr(kernel_name, sizeof(kernel_name), symbol->name, 9, strlen(symbol->name) - 16); amd_bin = si_bin_file_create(section->buffer.ptr + symbol->value, symbol->size, kernel_name); /* Get kernel name */ printf("**\n** Disassembly for '__kernel %s'\n**\n\n", kernel_name); si_disasm_buffer(&amd_bin->enc_dict_entry_southern_islands->sec_text_buffer, stdout); printf("\n\n\n"); /* Free internal ELF */ si_bin_file_free(amd_bin); } } /* Free external ELF */ elf_file_free(elf_file); si_disasm_done(); /* End */ mhandle_done(); exit(0); }