1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* udis86 - libudis86/input.c 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Copyright (c) 2002-2009 Vivek Thampi 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * All rights reserved. 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without modification, 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * are permitted provided that the following conditions are met: 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * * Redistributions of source code must retain the above copyright notice, 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * this list of conditions and the following disclaimer. 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * * Redistributions in binary form must reproduce the above copyright notice, 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * this list of conditions and the following disclaimer in the documentation 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * and/or other materials provided with the distribution. 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extern.h" 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "types.h" 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "input.h" 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "udint.h" 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * inp_init 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Initializes the input system. 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static void 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)inp_init(struct ud *u) 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_curr = 0; 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_fill = 0; 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_ctr = 0; 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_end = 0; 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* ----------------------------------------------------------------------------- 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * inp_buff_hook() - Hook for buffered inputs. 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ----------------------------------------------------------------------------- 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static int 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)inp_buff_hook(struct ud* u) 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (u->inp_buff < u->inp_buff_end) 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return *u->inp_buff++; 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else return -1; 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef __UD_STANDALONE__ 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* ----------------------------------------------------------------------------- 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * inp_file_hook() - Hook for FILE inputs. 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ----------------------------------------------------------------------------- 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static int 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)inp_file_hook(struct ud* u) 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return fgetc(u->inp_file); 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif /* __UD_STANDALONE__*/ 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* ============================================================================= 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ud_inp_set_hook() - Sets input hook. 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ============================================================================= 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*)) 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_hook = hook; 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inp_init(u); 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* ============================================================================= 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ud_inp_set_buffer() - Set buffer as input. 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ============================================================================= 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ud_set_input_buffer(register struct ud* u, const uint8_t* buf, size_t len) 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_hook = inp_buff_hook; 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_buff = buf; 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_buff_end = buf + len; 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inp_init(u); 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef __UD_STANDALONE__ 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* ============================================================================= 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ud_input_set_file() - Set buffer as input. 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ============================================================================= 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ud_set_input_file(register struct ud* u, FILE* f) 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_hook = inp_file_hook; 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_file = f; 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) inp_init(u); 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif /* __UD_STANDALONE__ */ 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* ============================================================================= 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ud_input_skip() - Skip n input bytes. 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ============================================================================= 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ud_input_skip(struct ud* u, size_t n) 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) while (n--) { 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_hook(u); 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* ============================================================================= 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ud_input_end() - Test for end of input. 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ============================================================================= 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ud_input_end(const struct ud* u) 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return (u->inp_curr == u->inp_fill) && u->inp_end; 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ud_inp_next 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Loads and returns the next byte from input. 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * inp_curr and inp_fill are pointers to the cache. The program is 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * written based on the property that they are 8-bits in size, and 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * will eventually wrap around forming a circular buffer. So, the 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * size of the cache is 256 in size, kind of unnecessary yet 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * optimal. 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * A buffer inp_sess stores the bytes disassembled for a single 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * session. 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)uint8_t 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ud_inp_next(struct ud* u) 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int c = -1; 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* if current pointer is not upto the fill point in the 148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * input cache. 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (u->inp_curr != u->inp_fill) { 151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) c = u->inp_cache[ ++u->inp_curr ]; 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* if !end-of-input, call the input hook and get a byte */ 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (u->inp_end || (c = u->inp_hook(u)) == -1) { 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* end-of-input, mark it as an error, since the decoder, 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * expected a byte more. 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UDERR(u, "byte expected, eoi received"); 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* flag end of input */ 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_end = 1; 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* increment pointers, we have a new byte. */ 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_curr = ++u->inp_fill; 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* add the byte to the cache */ 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_cache[u->inp_fill] = c; 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* record bytes input per decode-session. */ 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u->inp_sess[u->inp_ctr++] = c; 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* return byte */ 170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return (uint8_t) c; 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* 174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)vim: set ts=2 sw=2 expandtab 175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)*/ 176