diff --git a/libudis86/input.c b/libudis86/input.c new file mode 100644 index 0000000..58457a5 --- /dev/null +++ b/libudis86/input.c @@ -0,0 +1,175 @@ +/* udis86 - libudis86/input.c + * + * Copyright (c) 2002-2009 Vivek Thampi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "extern.h" +#include "types.h" +#include "input.h" +#include "udint.h" + +/* + * inp_init + * Initializes the input system. + */ +static void +inp_init(struct ud *u) +{ + u->inp_curr = 0; + u->inp_fill = 0; + u->inp_ctr = 0; + u->inp_end = 0; +} + + +/* ----------------------------------------------------------------------------- + * inp_buff_hook() - Hook for buffered inputs. + * ----------------------------------------------------------------------------- + */ +static int +inp_buff_hook(struct ud* u) +{ + if (u->inp_buff < u->inp_buff_end) + return *u->inp_buff++; + else return -1; +} + +#ifndef __UD_STANDALONE__ +/* ----------------------------------------------------------------------------- + * inp_file_hook() - Hook for FILE inputs. + * ----------------------------------------------------------------------------- + */ +static int +inp_file_hook(struct ud* u) +{ + return fgetc(u->inp_file); +} +#endif /* __UD_STANDALONE__*/ + +/* ============================================================================= + * ud_inp_set_hook() - Sets input hook. + * ============================================================================= + */ +void +ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*)) +{ + u->inp_hook = hook; + inp_init(u); +} + +/* ============================================================================= + * ud_inp_set_buffer() - Set buffer as input. + * ============================================================================= + */ +void +ud_set_input_buffer(register struct ud* u, const uint8_t* buf, size_t len) +{ + u->inp_hook = inp_buff_hook; + u->inp_buff = buf; + u->inp_buff_end = buf + len; + inp_init(u); +} + +#ifndef __UD_STANDALONE__ +/* ============================================================================= + * ud_input_set_file() - Set buffer as input. + * ============================================================================= + */ +void +ud_set_input_file(register struct ud* u, FILE* f) +{ + u->inp_hook = inp_file_hook; + u->inp_file = f; + inp_init(u); +} +#endif /* __UD_STANDALONE__ */ + +/* ============================================================================= + * ud_input_skip() - Skip n input bytes. + * ============================================================================= + */ +void +ud_input_skip(struct ud* u, size_t n) +{ + while (n--) { + u->inp_hook(u); + } +} + +/* ============================================================================= + * ud_input_end() - Test for end of input. + * ============================================================================= + */ +int +ud_input_end(const struct ud* u) +{ + return (u->inp_curr == u->inp_fill) && u->inp_end; +} + + +/* + * ud_inp_next + * Loads and returns the next byte from input. + * + * inp_curr and inp_fill are pointers to the cache. The program is + * written based on the property that they are 8-bits in size, and + * will eventually wrap around forming a circular buffer. So, the + * size of the cache is 256 in size, kind of unnecessary yet + * optimal. + * + * A buffer inp_sess stores the bytes disassembled for a single + * session. + */ +uint8_t +ud_inp_next(struct ud* u) +{ + int c = -1; + /* if current pointer is not upto the fill point in the + * input cache. + */ + if (u->inp_curr != u->inp_fill) { + c = u->inp_cache[ ++u->inp_curr ]; + /* if !end-of-input, call the input hook and get a byte */ + } else if (u->inp_end || (c = u->inp_hook(u)) == -1) { + /* end-of-input, mark it as an error, since the decoder, + * expected a byte more. + */ + UDERR(u, "byte expected, eoi received"); + /* flag end of input */ + u->inp_end = 1; + return 0; + } else { + /* increment pointers, we have a new byte. */ + u->inp_curr = ++u->inp_fill; + /* add the byte to the cache */ + u->inp_cache[u->inp_fill] = c; + } + /* record bytes input per decode-session. */ + u->inp_sess[u->inp_ctr++] = c; + /* return byte */ + return (uint8_t) c; +} + +/* +vim: set ts=2 sw=2 expandtab +*/ diff --git a/libudis86/syn.c b/libudis86/syn.c index 1b9e1d4..10855a7 100644 --- a/libudis86/syn.c +++ b/libudis86/syn.c @@ -137,7 +137,11 @@ ud_syn_print_addr(struct ud *u, uint64_t addr) name = u->sym_resolver(u, addr, &offset); if (name) { if (offset) { - ud_asmprintf(u, "%s%+" FMT64 "d", name, offset); +#if __WIN32__ || __CYGWIN__ || MINGW32 + ud_asmprintf(u, "%s%+I64d", name, (long long)offset); +#else + ud_asmprintf(u, "%s%+lld", name, (long long)offset); +#endif } else { ud_asmprintf(u, "%s", name); } diff --git a/libudis86/types.h b/libudis86/types.h index 69072ca..6648943 100644 --- a/libudis86/types.h +++ b/libudis86/types.h @@ -181,9 +181,13 @@ struct ud size_t inp_buf_size; size_t inp_buf_index; uint8_t inp_curr; - size_t inp_ctr; + uint8_t inp_fill; + uint8_t inp_ctr; + const uint8_t* inp_buff; + const uint8_t* inp_buff_end; + uint8_t inp_end; + uint8_t inp_cache[256]; uint8_t inp_sess[64]; - int inp_end; int inp_peek; void (*translator)(struct ud*); diff --git a/scripts/ud_opcode.py b/scripts/ud_opcode.py index fe1833d..a2f1a0b 100644 --- a/scripts/ud_opcode.py +++ b/scripts/ud_opcode.py @@ -193,7 +193,7 @@ def meta(self): def __str__(self): - return "table-%s" % self._typ + return "table-{}".format(self._typ) def add(self, opc, obj): @@ -208,7 +208,7 @@ def lookup(self, opc): typ = UdOpcodeTable.getOpcodeTyp(opc) idx = UdOpcodeTable.getOpcodeIdx(opc) if self._typ != typ: - raise UdOpcodeTable.CollisionError("%s <-> %s" % (self._typ, typ)) + raise UdOpcodeTable.CollisionError("{} <-> {}".format(self._typ, typ)) return self._entries.get(idx, None) @@ -219,13 +219,13 @@ def entryAt(self, index): """ if index < self.size(): return self._entries.get(index, None) - raise self.IndexError("index out of bounds: %s" % index) + raise self.IndexError("index out of bounds: {}".format(index)) def setEntryAt(self, index, obj): if index < self.size(): self._entries[index] = obj else: - raise self.IndexError("index out of bounds: %s" % index) + raise self.IndexError("index out of bounds: {}".format(index)) @classmethod def getOpcodeTyp(cls, opc): @@ -550,26 +550,26 @@ def printWalk(tbl, indent=""): entries = tbl.entries() for k, e in entries: if isinstance(e, UdOpcodeTable): - self.log("%s |-<%02x> %s" % (indent, k, e)) + self.log("{} |-<{}> {}".format(indent, k, e)) printWalk(e, indent + " |") elif isinstance(e, UdInsnDef): - self.log("%s |-<%02x> %s" % (indent, k, e)) + self.log("{} |-<{}> {}".format(indent, k, e)) printWalk(self.root) def printStats(self): tables = self.getTableList() self.log("stats: ") - self.log(" Num tables = %d" % len(tables)) - self.log(" Num insnDefs = %d" % len(self.getInsnList())) - self.log(" Num insns = %d" % len(self.getMnemonicsList())) + self.log(" Num tables = {}".format(len(tables))) + self.log(" Num insnDefs = {}".format(len(self.getInsnList()))) + self.log(" Num insns = {}".format(len(self.getMnemonicsList()))) totalSize = 0 totalEntries = 0 for table in tables: totalSize += table.size() totalEntries += table.numEntries() - self.log(" Packing Ratio = %d%%" % ((totalEntries * 100) / totalSize)) + self.log(" Packing Ratio = {}%".format(((totalEntries * 100) / totalSize))) self.log("--------------------") self.pprint() @@ -593,7 +593,7 @@ def parseOptableXML(xml): if not insnNode.localName: continue if insnNode.localName != "instruction": - raise Exception("warning: invalid insn node - %s" % insnNode.localName) + raise Exception("warning: invalid insn node - {}".format(insnNode.localName)) mnemonic = insnNode.getElementsByTagName('mnemonic')[0].firstChild.data vendor, cpuid = '', []