Index: third_party/mach_override/libudis86/input.c |
diff --git a/third_party/mach_override/libudis86/input.c b/third_party/mach_override/libudis86/input.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..58457a58482c5e6a233668ded212a4a875a865d4 |
--- /dev/null |
+++ b/third_party/mach_override/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 |
+*/ |