17ec681f3Smrg/* 27ec681f3Smrg * Copyright (C) 2021 Collabora, Ltd. 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 97ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice (including the next 127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 137ec681f3Smrg * Software. 147ec681f3Smrg * 157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 207ec681f3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 217ec681f3Smrg * SOFTWARE. 227ec681f3Smrg */ 237ec681f3Smrg 247ec681f3Smrg#include <stdio.h> 257ec681f3Smrg#include <inttypes.h> 267ec681f3Smrg#include "disassemble.h" 277ec681f3Smrg 287ec681f3Smrgstatic inline uint8_t 297ec681f3Smrgparse_nibble(const char c) 307ec681f3Smrg{ 317ec681f3Smrg return (c >= 'a') ? 10 + (c - 'a') : (c - '0'); 327ec681f3Smrg} 337ec681f3Smrg 347ec681f3Smrg/* Given a little endian 8 byte hexdump, parse out the 64-bit value */ 357ec681f3Smrgstatic uint64_t 367ec681f3Smrgparse_hex(const char *in) 377ec681f3Smrg{ 387ec681f3Smrg uint64_t v = 0; 397ec681f3Smrg 407ec681f3Smrg for (unsigned i = 0; i < 8; ++i) { 417ec681f3Smrg uint8_t byte = (parse_nibble(in[0]) << 4) | parse_nibble(in[1]); 427ec681f3Smrg v |= ((uint64_t) byte) << (8 * i); 437ec681f3Smrg 447ec681f3Smrg /* Skip the space after the byte */ 457ec681f3Smrg in += 3; 467ec681f3Smrg } 477ec681f3Smrg 487ec681f3Smrg return v; 497ec681f3Smrg} 507ec681f3Smrg 517ec681f3Smrgint 527ec681f3Smrgmain(int argc, const char **argv) 537ec681f3Smrg{ 547ec681f3Smrg if (argc < 2) { 557ec681f3Smrg fprintf(stderr, "Expected case list\n"); 567ec681f3Smrg return 1; 577ec681f3Smrg } 587ec681f3Smrg 597ec681f3Smrg FILE *fp = fopen(argv[1], "r"); 607ec681f3Smrg 617ec681f3Smrg if (fp == NULL) { 627ec681f3Smrg fprintf(stderr, "Could not open the case list"); 637ec681f3Smrg return 1; 647ec681f3Smrg } 657ec681f3Smrg 667ec681f3Smrg char line[128]; 677ec681f3Smrg unsigned nr_fail = 0, nr_pass = 0; 687ec681f3Smrg 697ec681f3Smrg while (fgets(line, sizeof(line), fp) != NULL) { 707ec681f3Smrg char *output = NULL; 717ec681f3Smrg size_t sz = 0; 727ec681f3Smrg size_t len = strlen(line); 737ec681f3Smrg 747ec681f3Smrg /* Skip empty lines */ 757ec681f3Smrg if (len <= 1) 767ec681f3Smrg continue; 777ec681f3Smrg 787ec681f3Smrg /* Check for buffer overflow */ 797ec681f3Smrg if (len < 28) { 807ec681f3Smrg fprintf(stderr, "Invalid reference %s\n", line); 817ec681f3Smrg nr_fail++; 827ec681f3Smrg } 837ec681f3Smrg 847ec681f3Smrg uint64_t bin = parse_hex(line); 857ec681f3Smrg FILE *outputp = open_memstream(&output, &sz); 867ec681f3Smrg va_disasm_instr(outputp, bin); 877ec681f3Smrg fprintf(outputp, "\n"); 887ec681f3Smrg fclose(outputp); 897ec681f3Smrg 907ec681f3Smrg /* Skip hexdump: 8 bytes * (2 nibbles + 1 space) + 3 spaces */ 917ec681f3Smrg const char *reference = line + 27; 927ec681f3Smrg bool fail = strcmp(reference, output); 937ec681f3Smrg 947ec681f3Smrg if (fail) { 957ec681f3Smrg printf("Got %sExpected %s\n", output, reference); 967ec681f3Smrg nr_fail++; 977ec681f3Smrg } else { 987ec681f3Smrg nr_pass++; 997ec681f3Smrg } 1007ec681f3Smrg 1017ec681f3Smrg free(output); 1027ec681f3Smrg } 1037ec681f3Smrg 1047ec681f3Smrg printf("Passed %u/%u tests.\n", nr_pass, nr_pass + nr_fail); 1057ec681f3Smrg fclose(fp); 1067ec681f3Smrg 1077ec681f3Smrg return nr_fail ? 1 : 0; 1087ec681f3Smrg} 109