1/* udis86 - libudis86/input.c 2 * 3 * Copyright (c) 2002-2009 Vivek Thampi 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without modification, 7 * are permitted provided that the following conditions are met: 8 * 9 * * Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 19 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26#include "config.h" 27 28#if USE(UDIS86) 29 30#include "udis86_extern.h" 31#include "udis86_types.h" 32#include "udis86_input.h" 33 34/* ----------------------------------------------------------------------------- 35 * inp_buff_hook() - Hook for buffered inputs. 36 * ----------------------------------------------------------------------------- 37 */ 38static int 39inp_buff_hook(struct ud* u) 40{ 41 if (u->inp_buff < u->inp_buff_end) 42 return *u->inp_buff++; 43 else return -1; 44} 45 46#ifndef __UD_STANDALONE__ 47/* ----------------------------------------------------------------------------- 48 * inp_file_hook() - Hook for FILE inputs. 49 * ----------------------------------------------------------------------------- 50 */ 51static int 52inp_file_hook(struct ud* u) 53{ 54 return fgetc(u->inp_file); 55} 56#endif /* __UD_STANDALONE__*/ 57 58/* ============================================================================= 59 * ud_inp_set_hook() - Sets input hook. 60 * ============================================================================= 61 */ 62extern void 63ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*)) 64{ 65 u->inp_hook = hook; 66 ud_inp_init(u); 67} 68 69extern void 70ud_set_user_opaque_data( struct ud * u, void * opaque ) 71{ 72 u->user_opaque_data = opaque; 73} 74 75extern void * 76ud_get_user_opaque_data( struct ud * u ) 77{ 78 return u->user_opaque_data; 79} 80 81/* ============================================================================= 82 * ud_inp_set_buffer() - Set buffer as input. 83 * ============================================================================= 84 */ 85extern void 86ud_set_input_buffer(register struct ud* u, uint8_t* buf, size_t len) 87{ 88 u->inp_hook = inp_buff_hook; 89 u->inp_buff = buf; 90 u->inp_buff_end = buf + len; 91 ud_inp_init(u); 92} 93 94#ifndef __UD_STANDALONE__ 95/* ============================================================================= 96 * ud_input_set_file() - Set buffer as input. 97 * ============================================================================= 98 */ 99extern void 100ud_set_input_file(register struct ud* u, FILE* f) 101{ 102 u->inp_hook = inp_file_hook; 103 u->inp_file = f; 104 ud_inp_init(u); 105} 106#endif /* __UD_STANDALONE__ */ 107 108/* ============================================================================= 109 * ud_input_skip() - Skip n input bytes. 110 * ============================================================================= 111 */ 112extern void 113ud_input_skip(struct ud* u, size_t n) 114{ 115 while (n--) { 116 u->inp_hook(u); 117 } 118} 119 120/* ============================================================================= 121 * ud_input_end() - Test for end of input. 122 * ============================================================================= 123 */ 124extern int 125ud_input_end(struct ud* u) 126{ 127 return (u->inp_curr == u->inp_fill) && u->inp_end; 128} 129 130/* ----------------------------------------------------------------------------- 131 * ud_inp_next() - Loads and returns the next byte from input. 132 * 133 * inp_curr and inp_fill are pointers to the cache. The program is written based 134 * on the property that they are 8-bits in size, and will eventually wrap around 135 * forming a circular buffer. So, the size of the cache is 256 in size, kind of 136 * unnecessary yet optimized. 137 * 138 * A buffer inp_sess stores the bytes disassembled for a single session. 139 * ----------------------------------------------------------------------------- 140 */ 141extern uint8_t ud_inp_next(struct ud* u) 142{ 143 int c = -1; 144 /* if current pointer is not upto the fill point in the 145 * input cache. 146 */ 147 if ( u->inp_curr != u->inp_fill ) { 148 c = u->inp_cache[ ++u->inp_curr ]; 149 /* if !end-of-input, call the input hook and get a byte */ 150 } else if ( u->inp_end || ( c = u->inp_hook( u ) ) == -1 ) { 151 /* end-of-input, mark it as an error, since the decoder, 152 * expected a byte more. 153 */ 154 u->error = 1; 155 /* flag end of input */ 156 u->inp_end = 1; 157 return 0; 158 } else { 159 /* increment pointers, we have a new byte. */ 160 u->inp_curr = ++u->inp_fill; 161 /* add the byte to the cache */ 162 u->inp_cache[ u->inp_fill ] = c; 163 } 164 /* record bytes input per decode-session. */ 165 u->inp_sess[ u->inp_ctr++ ] = c; 166 /* return byte */ 167 return ( uint8_t ) c; 168} 169 170/* ----------------------------------------------------------------------------- 171 * ud_inp_back() - Move back a single byte in the stream. 172 * ----------------------------------------------------------------------------- 173 */ 174extern void 175ud_inp_back(struct ud* u) 176{ 177 if ( u->inp_ctr > 0 ) { 178 --u->inp_curr; 179 --u->inp_ctr; 180 } 181} 182 183/* ----------------------------------------------------------------------------- 184 * ud_inp_peek() - Peek into the next byte in source. 185 * ----------------------------------------------------------------------------- 186 */ 187extern uint8_t 188ud_inp_peek(struct ud* u) 189{ 190 uint8_t r = ud_inp_next(u); 191 if ( !u->error ) ud_inp_back(u); /* Don't backup if there was an error */ 192 return r; 193} 194 195/* ----------------------------------------------------------------------------- 196 * ud_inp_move() - Move ahead n input bytes. 197 * ----------------------------------------------------------------------------- 198 */ 199extern void 200ud_inp_move(struct ud* u, size_t n) 201{ 202 while (n--) 203 ud_inp_next(u); 204} 205 206/*------------------------------------------------------------------------------ 207 * ud_inp_uintN() - return uintN from source. 208 *------------------------------------------------------------------------------ 209 */ 210extern uint8_t 211ud_inp_uint8(struct ud* u) 212{ 213 return ud_inp_next(u); 214} 215 216extern uint16_t 217ud_inp_uint16(struct ud* u) 218{ 219 uint16_t r, ret; 220 221 ret = ud_inp_next(u); 222 r = ud_inp_next(u); 223 return ret | (r << 8); 224} 225 226extern uint32_t 227ud_inp_uint32(struct ud* u) 228{ 229 uint32_t r, ret; 230 231 ret = ud_inp_next(u); 232 r = ud_inp_next(u); 233 ret = ret | (r << 8); 234 r = ud_inp_next(u); 235 ret = ret | (r << 16); 236 r = ud_inp_next(u); 237 return ret | (r << 24); 238} 239 240extern uint64_t 241ud_inp_uint64(struct ud* u) 242{ 243 uint64_t r, ret; 244 245 ret = ud_inp_next(u); 246 r = ud_inp_next(u); 247 ret = ret | (r << 8); 248 r = ud_inp_next(u); 249 ret = ret | (r << 16); 250 r = ud_inp_next(u); 251 ret = ret | (r << 24); 252 r = ud_inp_next(u); 253 ret = ret | (r << 32); 254 r = ud_inp_next(u); 255 ret = ret | (r << 40); 256 r = ud_inp_next(u); 257 ret = ret | (r << 48); 258 r = ud_inp_next(u); 259 return ret | (r << 56); 260} 261 262#endif // USE(UDIS86) 263