Index: src/trusted/validator/x86/testing/enuminsts/nacl_tester.c |
diff --git a/src/trusted/validator/x86/testing/enuminsts/nacl_tester.c b/src/trusted/validator/x86/testing/enuminsts/nacl_tester.c |
deleted file mode 100644 |
index 10e286c98c5c1ae65968f40f1431211afeaaad3b..0000000000000000000000000000000000000000 |
--- a/src/trusted/validator/x86/testing/enuminsts/nacl_tester.c |
+++ /dev/null |
@@ -1,331 +0,0 @@ |
-/* |
- * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
- * Use of this source code is governed by a BSD-style license that can be |
- * found in the LICENSE file. |
- */ |
- |
-/* |
- * nacl_tester.c |
- * Uses the NaCl x86 validator/decoder to implement a NaClEnumeratorDecoder. |
- */ |
-#ifndef NACL_TRUSTED_BUT_NOT_TCB |
-#error("This file is not meant for use in the TCB.") |
-#endif |
- |
-#include "native_client/src/trusted/validator/x86/testing/enuminsts/enuminsts.h" |
- |
-#include <ctype.h> |
-#include <string.h> |
-#include "native_client/src/trusted/validator_x86/ncenuminsts.h" |
-#include "native_client/src/trusted/validator/x86/testing/enuminsts/str_utils.h" |
- |
-#define kBufferSize 1024 |
- |
-/* Defines the virtual table for the nacl decoder. */ |
-struct { |
- /* The virtual table that implements this decoder. */ |
- NaClEnumeratorDecoder _base; |
- /* Defines the NaCl state to use to parse instructions. */ |
- NaClInstStruct *_inst; |
- /* Defines if we are ignoring the instruction (i.e. an instruction |
- * that isn't xed implemented. |
- */ |
- Bool _ignore_instruction; |
- /* Defines the pc address associated with the instruction. */ |
- NaClPcAddress _pc_address; |
- /* If non-empty, the corresponding disassembly. */ |
- char _disassembly[kBufferSize]; |
- /* If non-empty, the simplified corresponding assembly, where |
- * the opcode byte sequence has been removed. |
- */ |
- char _simplified_disassembly[kBufferSize]; |
- /* If non-empty, the corresponding instruction mnemonic. */ |
- char _mnemonic[kBufferSize]; |
- /* if non-empty, the lowercase mnemonic. */ |
- char _mnemonic_lower[kBufferSize]; |
- /* If non-empty, stores the operands of the corresponding instruction. */ |
- char _operands[kBufferSize]; |
- /* True if we should translate special opcodes to matching xed nops. */ |
- Bool _translate_to_xed_nops; |
- /* True if we shouldn't accept instructions that aren't also implemented |
- * in xed. |
- */ |
- Bool _ignore_instructions_not_xed_implemented; |
-} nacl_decoder; |
- |
-static Bool IsInstLegal(const NaClEnumerator *enumerator) { |
- UNREFERENCED_PARAMETER(enumerator); |
-#if 0 |
- /* This forces an incorrect legality report for 00 24 c2, useful for */ |
- /* testing that related problems are being reported. */ |
- if (enumerator->_itext[0] == 0 && |
- enumerator->_itext[1] == 0x24 && |
- enumerator->_itext[2] == 0xc2) return 0; |
-#endif |
- return !nacl_decoder._ignore_instruction && |
- NaClInstDecodesCorrectly(nacl_decoder._inst); |
-} |
- |
-/* Instructions we assume that the NaCl validator accept and are valid, but |
- * are not legal according to xed. |
- */ |
-static Bool NaClIsntXedImplemented(const NaClEnumerator *enumerator) { |
- static const char* nacl_but_not_xed[] = { |
- "Pf2iw", |
- "Pf2id" |
- }; |
- const char* name = NaClOpcodeName(nacl_decoder._inst); |
- size_t i; |
- UNREFERENCED_PARAMETER(enumerator); |
- for (i = 0; i < NACL_ARRAY_SIZE(nacl_but_not_xed); ++i) { |
- if (0 == strcmp(name, nacl_but_not_xed[i])) { |
- return TRUE; |
- } |
- } |
- return FALSE; |
-} |
- |
-/* Defines the funcdtion to parse the first instruction. */ |
-static void ParseInst(const NaClEnumerator* enumerator, |
- const int pc_address) { |
- nacl_decoder._inst = NULL; |
- nacl_decoder._ignore_instruction = FALSE; |
- nacl_decoder._pc_address = pc_address; |
- nacl_decoder._disassembly[0] = 0; |
- nacl_decoder._simplified_disassembly[0] = 0; |
- nacl_decoder._mnemonic[0] = 0; |
- nacl_decoder._mnemonic_lower[0] = 0; |
- nacl_decoder._operands[0] = 0; |
- nacl_decoder._inst = |
- NaClParseInst((uint8_t *)enumerator->_itext, |
- enumerator->_num_bytes, pc_address); |
- if (nacl_decoder._ignore_instructions_not_xed_implemented && |
- IsInstLegal(enumerator)) { |
- nacl_decoder._ignore_instruction = NaClIsntXedImplemented(enumerator); |
- } |
-} |
- |
- |
-/* Returns the disassembled instruction. */ |
-static const char* Disassemble(const NaClEnumerator* enumerator) { |
- char* stmp; |
- |
- UNREFERENCED_PARAMETER(enumerator); |
- /* First see if we have cached it. If so, return it. */ |
- if (nacl_decoder._disassembly[0] != 0) return nacl_decoder._disassembly; |
- |
- stmp = NaClInstToStr(nacl_decoder._inst); |
- cstrncpy(nacl_decoder._disassembly, stmp, kBufferSize); |
- free(stmp); |
- return nacl_decoder._disassembly; |
-} |
- |
-/* Returns the lower case name of the instruction. */ |
-static const char* GetInstMnemonicLower(const NaClEnumerator* enumerator) { |
- char mnemonic[kBufferSize]; |
- size_t i; |
- |
- UNREFERENCED_PARAMETER(enumerator); |
- if (nacl_decoder._mnemonic_lower[0] != 0) |
- return nacl_decoder._mnemonic_lower; |
- |
- cstrncpy(mnemonic, NaClOpcodeName(nacl_decoder._inst), kBufferSize); |
- for (i = 0; i < kBufferSize; ++i) { |
- mnemonic[i] = tolower(mnemonic[i]); |
- if (mnemonic[i] == '\0') break; |
- } |
- cstrncpy(nacl_decoder._mnemonic_lower, mnemonic, kBufferSize); |
- return nacl_decoder._mnemonic_lower; |
-} |
- |
-/* Defines nacl/xed mnemonic renaming pairs. */ |
-typedef struct { |
- const char* nacl_name; |
- const char* xed_name; |
-} NaClToXedPairs; |
- |
-/* Returns the disassembled instruction with the opcode byte sequence |
- * removed. |
- */ |
-static const char* SimplifiedDisassembly(const NaClEnumerator *enumerator) { |
- const char* disassembly; |
- const char* mnemonic; |
- const char* start; |
- |
- /* First see if we have cache it. If so, return it. */ |
- if (nacl_decoder._simplified_disassembly[0] != 0) |
- return nacl_decoder._simplified_disassembly; |
- |
- /* Take first guess of simplified assembly. */ |
- /* Find start of instruction mnemonic, and define as start of simplified |
- * disassembly. |
- */ |
- disassembly = Disassemble(enumerator); |
- mnemonic = GetInstMnemonicLower(enumerator); |
- start = strfind(disassembly, mnemonic); |
- if (NULL == start) { |
- /* Don't know how to simplify, give up and just use disassembly. */ |
- cstrncpy(nacl_decoder._simplified_disassembly, disassembly, kBufferSize); |
- return nacl_decoder._simplified_disassembly; |
- } |
- cstrncpy(nacl_decoder._simplified_disassembly, start, kBufferSize); |
- rstrip(nacl_decoder._simplified_disassembly); |
- |
- /* Now handle special cases where we should treat the nacl instruction as a |
- * nop, so that they will match xed instructions. |
- */ |
- if (nacl_decoder._translate_to_xed_nops) { |
- static const NaClToXedPairs pairs[] = { |
- { "xchg %eax, %eax" , "nop" }, |
- { "xchg %rax, %rax" , "nop" }, |
- { "xchg %ax, %ax" , "nop" }, |
- }; |
- size_t i; |
- char buf[kBufferSize]; |
- const char* desc = strfind(nacl_decoder._simplified_disassembly, mnemonic); |
- if (NULL == desc) return nacl_decoder._simplified_disassembly; |
- cstrncpy(buf, desc, kBufferSize); |
- rstrip(buf); |
- for (i = 0; i < NACL_ARRAY_SIZE(pairs); ++i) { |
- if (0 == strcmp(nacl_decoder._simplified_disassembly, |
- pairs[i].nacl_name)) { |
- cstrncpy(nacl_decoder._simplified_disassembly, |
- pairs[i].xed_name, kBufferSize); |
- cstrncpy(nacl_decoder._mnemonic, pairs[i].xed_name, kBufferSize); |
- } |
- } |
- } |
- return nacl_decoder._simplified_disassembly; |
-} |
- |
-/* Returns the mnemonic name for the disassembled instruction. */ |
-static const char* GetInstMnemonic(const NaClEnumerator* enumerator) { |
- char mnemonic[kBufferSize]; |
- const char* disassembly; |
- |
- /* First see if we have cached it. If so, return it. */ |
- if (nacl_decoder._mnemonic[0] != 0) return nacl_decoder._mnemonic; |
- |
- /* Force simplifications if needed. Use mnemonic if defined. */ |
- disassembly = SimplifiedDisassembly(enumerator); |
- (void) disassembly; /* TODO(bradchen): use or remove this variable */ |
- if (nacl_decoder._mnemonic[0] != 0) return nacl_decoder._mnemonic; |
- |
- /* If reached, we haven't cached it, so find the name from the |
- * disassembled instruction and cache it. |
- */ |
- cstrncpy(mnemonic, GetInstMnemonicLower(enumerator), kBufferSize); |
- |
- /* Now fix mnemonic to corresponding xed name if needed. */ |
- if ((mnemonic[0] == 'p') && (mnemonic[1] == 'f') && (mnemonic[2] == 'r')) { |
- static const NaClToXedPairs pairs[] = { |
- { "pfrsqrt", "pfsqrt" }, |
- { "pfrcpit1", "pfcpit1" } |
- }; |
- size_t i; |
- for (i = 0; i < NACL_ARRAY_SIZE(pairs); ++i) { |
- if (0 == strcmp(mnemonic, pairs[i].nacl_name)) { |
- const char* start = |
- strfind(nacl_decoder._simplified_disassembly, mnemonic); |
- if (NULL != start) { |
- /* replace nacl_name with xed name in simplified disassembly. */ |
- cstrncpy(mnemonic, pairs[i].xed_name, kBufferSize); |
- } |
- } |
- } |
- } |
- |
- /* Install mnemonic and return. */ |
- cstrncpy(nacl_decoder._mnemonic, mnemonic, kBufferSize); |
- return nacl_decoder._mnemonic; |
-} |
- |
-/* Returns the text for the operands. To be used by the driver |
- * to compare accross decoders. |
- */ |
-static const char* GetInstOperandsText(const NaClEnumerator* enumerator) { |
- char operands[kBufferSize]; |
- const char* disassembly; |
- const char* after_mnemonic; |
- |
- /* First see if we have cached it. If so, return it. */ |
- if (nacl_decoder._operands[0] != 0) return nacl_decoder._operands; |
- |
- disassembly = SimplifiedDisassembly(enumerator); |
- after_mnemonic = strskip(disassembly, GetInstMnemonicLower(enumerator)); |
- if (NULL == after_mnemonic) after_mnemonic = disassembly; |
- cstrncpy(operands, after_mnemonic, kBufferSize); |
- strnzapchar(operands, '%'); |
- strnzapchar(operands, '\n'); |
- cstrncpy(nacl_decoder._operands, strip(operands), kBufferSize); |
- return nacl_decoder._operands; |
-} |
- |
-/* Prints out the disassembled instruction. */ |
-static void PrintInst(const NaClEnumerator* enumerator) { |
- printf(" NaCl: %s", Disassemble(enumerator)); |
-} |
- |
-/* Returns the number of bytes in the disassembled instruction. */ |
-static size_t InstLength(const NaClEnumerator* enumerator) { |
- UNREFERENCED_PARAMETER(enumerator); |
-#if 0 |
- /* This forces an incorrect length report for 00 24 c2, useful for */ |
- /* testing that length problems are being reported. */ |
- if (enumerator->_itext[0] == 0 && |
- enumerator->_itext[1] == 0x24 && |
- enumerator->_itext[2] == 0xc2) return 4; |
-#endif |
- return (size_t) NaClInstLength(nacl_decoder._inst); |
-} |
- |
-/* Returns true if the instruction decodes, and static (single instruction) |
- * validator tests pass. |
- */ |
-static Bool MaybeInstValidates(const NaClEnumerator *enumerator) { |
- return NaClInstValidates((uint8_t*) enumerator->_itext, |
- NaClInstLength(nacl_decoder._inst), |
- nacl_decoder._pc_address, |
- nacl_decoder._inst); |
-} |
- |
-/* Runs the validator on the given code segment. */ |
-static Bool SegmentValidates(const NaClEnumerator *enumerator, |
- const uint8_t* segment, |
- const size_t size, |
- const int pc_address) { |
- UNREFERENCED_PARAMETER(enumerator); |
- return NaClSegmentValidates((uint8_t*) segment, size, pc_address); |
-} |
- |
-/* Installs NaCl-specific flags. */ |
-static void InstallFlag(const NaClEnumerator* enumerator, |
- const char* flag_name, |
- const void* flag_address) { |
- UNREFERENCED_PARAMETER(enumerator); |
- if (0 == strcmp(flag_name, "--nops")) { |
- nacl_decoder._translate_to_xed_nops = *((Bool*) flag_address); |
- } else if (0 == strcmp(flag_name, "--xedimplemented")) { |
- nacl_decoder._ignore_instructions_not_xed_implemented = |
- *((Bool*) flag_address); |
- } |
-} |
- |
-/* Generates a decoder for the (sel_ldr) nacl validator. */ |
-NaClEnumeratorDecoder* RegisterNaClDecoder(void) { |
- nacl_decoder._base._id_name = "nacl"; |
- nacl_decoder._base._parse_inst_fn = ParseInst; |
- nacl_decoder._base._inst_length_fn = InstLength; |
- nacl_decoder._base._print_inst_fn = PrintInst; |
- nacl_decoder._base._get_inst_mnemonic_fn = GetInstMnemonic; |
- nacl_decoder._base._get_inst_num_operands_fn = NULL; |
- nacl_decoder._base._get_inst_operands_text_fn = GetInstOperandsText; |
- nacl_decoder._base._writes_to_reserved_reg_fn = NULL; |
- nacl_decoder._base._is_inst_legal_fn = IsInstLegal; |
- nacl_decoder._base._maybe_inst_validates_fn = MaybeInstValidates; |
- nacl_decoder._base._segment_validates_fn = SegmentValidates; |
- nacl_decoder._base._install_flag_fn = InstallFlag; |
- nacl_decoder._base._usage_message = |
- "Runs nacl decoder to decode instructions"; |
- return &nacl_decoder._base; |
-} |