mirror of
https://github.com/yasm/yasm
synced 2026-08-26 22:26:05 -04:00
Modify so that almost everything passes LCLint with the options in lclint.sh.
This is actually worthwhile; I found and fixed a few bugs/edge cases while doing this. For more information on LCLint, see <http://lclint.cs.virginia.edu/>. svn path=/trunk/yasm/; revision=335
This commit is contained in:
parent
fc603c2900
commit
8178f883a5
102 changed files with 1075 additions and 728 deletions
|
|
@ -23,7 +23,7 @@
|
|||
#define YASM_BC_INT_H
|
||||
|
||||
struct effaddr {
|
||||
expr *disp; /* address displacement */
|
||||
/*@only@*/ /*@null@*/ expr *disp; /* address displacement */
|
||||
unsigned char len; /* length of disp (in bytes), 0 if unknown,
|
||||
* 0xff if unknown and required to be >0.
|
||||
*/
|
||||
|
|
@ -32,11 +32,13 @@ struct effaddr {
|
|||
|
||||
/* architecture-dependent data may be appended */
|
||||
};
|
||||
void *ea_get_data(effaddr *);
|
||||
#define ea_get_data(x) (void *)(((char *)x)+sizeof(effaddr))
|
||||
const void *ea_get_const_data(const effaddr *);
|
||||
#define ea_get_const_data(x) (const void *)(((const char *)x)+sizeof(effaddr))
|
||||
|
||||
struct immval {
|
||||
expr *val;
|
||||
/*@only@*/ /*@null@*/ expr *val;
|
||||
|
||||
unsigned char len; /* length of val (in bytes), 0 if unknown */
|
||||
unsigned char isneg; /* the value has been explicitly negated */
|
||||
|
|
@ -46,18 +48,18 @@ struct immval {
|
|||
};
|
||||
|
||||
struct bytecode {
|
||||
STAILQ_ENTRY(bytecode) link;
|
||||
/*@reldef@*/ STAILQ_ENTRY(bytecode) link;
|
||||
|
||||
bytecode_type type;
|
||||
|
||||
expr *multiple; /* number of times bytecode is repeated,
|
||||
NULL=1 */
|
||||
/* number of times bytecode is repeated, NULL=1. */
|
||||
/*@only@*/ /*@null@*/ expr *multiple;
|
||||
|
||||
unsigned long len; /* total length of entire bytecode (including
|
||||
multiple copies), 0 if unknown */
|
||||
|
||||
/* where it came from */
|
||||
const char *filename;
|
||||
/*@dependent@*/ /*@null@*/ const char *filename;
|
||||
unsigned int lineno;
|
||||
|
||||
/* other assembler state info */
|
||||
|
|
@ -65,7 +67,9 @@ struct bytecode {
|
|||
|
||||
/* architecture-dependent data may be appended */
|
||||
};
|
||||
void *bc_get_data(bytecode *);
|
||||
#define bc_get_data(x) (void *)(((char *)x)+sizeof(bytecode))
|
||||
const void *bc_get_const_data(const bytecode *);
|
||||
#define bc_get_const_data(x) (const void *)(((const char *)x)+sizeof(bytecode))
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ const char * BitVector_Version (void); /* returns version string */
|
|||
N_int BitVector_Word_Bits (void); /* returns # of bits in machine word */
|
||||
N_int BitVector_Long_Bits (void); /* returns # of bits in unsigned long */
|
||||
|
||||
wordptr BitVector_Create(N_int bits, boolean clear); /* malloc */
|
||||
/*@only@*/ wordptr BitVector_Create(N_int bits, boolean clear); /* malloc */
|
||||
|
||||
/* ===> OBJECT METHODS: <=== */
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ wordptr BitVector_Clone (wordptr addr); /* makes exact duplicate */
|
|||
wordptr BitVector_Concat (wordptr X, wordptr Y); /* returns concatenation */
|
||||
|
||||
wordptr BitVector_Resize (wordptr oldaddr, N_int bits); /* realloc */
|
||||
void BitVector_Destroy (wordptr addr); /* free */
|
||||
void BitVector_Destroy (/*@only@*/ wordptr addr); /* free */
|
||||
|
||||
/* ===> bit vector copy function: */
|
||||
|
||||
|
|
@ -150,20 +150,20 @@ void BitVector_Reverse (wordptr X, wordptr Y);
|
|||
|
||||
/* ===> bit vector interval operations and functions: */
|
||||
|
||||
void BitVector_Interval_Empty (wordptr addr, N_int lower, N_int upper);
|
||||
void BitVector_Interval_Fill (wordptr addr, N_int lower, N_int upper);
|
||||
void BitVector_Interval_Flip (wordptr addr, N_int lower, N_int upper);
|
||||
void BitVector_Interval_Reverse (wordptr addr, N_int lower, N_int upper);
|
||||
void BitVector_Interval_Empty (/*@out@*/ wordptr addr, N_int lower, N_int upper);
|
||||
void BitVector_Interval_Fill (/*@out@*/ wordptr addr, N_int lower, N_int upper);
|
||||
void BitVector_Interval_Flip (/*@out@*/ wordptr addr, N_int lower, N_int upper);
|
||||
void BitVector_Interval_Reverse (/*@out@*/ wordptr addr, N_int lower, N_int upper);
|
||||
|
||||
boolean BitVector_interval_scan_inc(wordptr addr, N_int start,
|
||||
N_intptr min, N_intptr max);
|
||||
boolean BitVector_interval_scan_dec(wordptr addr, N_int start,
|
||||
N_intptr min, N_intptr max);
|
||||
|
||||
void BitVector_Interval_Copy (wordptr X, wordptr Y, N_int Xoffset,
|
||||
void BitVector_Interval_Copy (/*@out@*/ wordptr X, wordptr Y, N_int Xoffset,
|
||||
N_int Yoffset, N_int length);
|
||||
|
||||
wordptr BitVector_Interval_Substitute(wordptr X, wordptr Y,
|
||||
wordptr BitVector_Interval_Substitute(/*@out@*/ wordptr X, wordptr Y,
|
||||
N_int Xoffset, N_int Xlength,
|
||||
N_int Yoffset, N_int Ylength);
|
||||
|
||||
|
|
@ -178,42 +178,42 @@ Z_int BitVector_Compare (wordptr X, wordptr Y); /* X <,=,> Y ? */
|
|||
|
||||
/* ===> bit vector string conversion functions: */
|
||||
|
||||
charptr BitVector_to_Hex (wordptr addr);
|
||||
ErrCode BitVector_from_Hex(wordptr addr, charptr string);
|
||||
/*@only@*/ charptr BitVector_to_Hex (wordptr addr);
|
||||
ErrCode BitVector_from_Hex(/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
ErrCode BitVector_from_Oct(wordptr addr, charptr string);
|
||||
ErrCode BitVector_from_Oct(/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
charptr BitVector_to_Bin (wordptr addr);
|
||||
ErrCode BitVector_from_Bin(wordptr addr, charptr string);
|
||||
/*@only@*/ charptr BitVector_to_Bin (wordptr addr);
|
||||
ErrCode BitVector_from_Bin(/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
charptr BitVector_to_Dec (wordptr addr);
|
||||
ErrCode BitVector_from_Dec(wordptr addr, charptr string);
|
||||
/*@only@*/ charptr BitVector_to_Dec (wordptr addr);
|
||||
ErrCode BitVector_from_Dec(/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
charptr BitVector_to_Enum (wordptr addr);
|
||||
ErrCode BitVector_from_Enum(wordptr addr, charptr string);
|
||||
/*@only@*/ charptr BitVector_to_Enum (wordptr addr);
|
||||
ErrCode BitVector_from_Enum(/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
void BitVector_Dispose (charptr string);
|
||||
void BitVector_Dispose (/*@only@*/ /*@out@*/ charptr string);
|
||||
|
||||
/* ===> bit vector bit operations, functions & tests: */
|
||||
|
||||
void BitVector_Bit_Off (wordptr addr, N_int indx); /* X = X \ {x} */
|
||||
void BitVector_Bit_On (wordptr addr, N_int indx); /* X = X + {x} */
|
||||
boolean BitVector_bit_flip(wordptr addr, N_int indx); /* X=(X+{x})\(X*{x}) */
|
||||
void BitVector_Bit_Off (/*@out@*/ wordptr addr, N_int indx); /* X = X \ {x} */
|
||||
void BitVector_Bit_On (/*@out@*/ wordptr addr, N_int indx); /* X = X + {x} */
|
||||
boolean BitVector_bit_flip(/*@out@*/ wordptr addr, N_int indx); /* X=(X+{x})\(X*{x}) */
|
||||
|
||||
boolean BitVector_bit_test(wordptr addr, N_int indx); /* {x} in X ? */
|
||||
|
||||
void BitVector_Bit_Copy(wordptr addr, N_int indx, boolean bit);
|
||||
void BitVector_Bit_Copy(/*@out@*/ wordptr addr, N_int indx, boolean bit);
|
||||
|
||||
/* ===> bit vector bit shift & rotate functions: */
|
||||
|
||||
void BitVector_LSB (wordptr addr, boolean bit);
|
||||
void BitVector_MSB (wordptr addr, boolean bit);
|
||||
void BitVector_LSB (/*@out@*/ wordptr addr, boolean bit);
|
||||
void BitVector_MSB (/*@out@*/ wordptr addr, boolean bit);
|
||||
boolean BitVector_lsb (wordptr addr);
|
||||
boolean BitVector_msb (wordptr addr);
|
||||
boolean BitVector_rotate_left (wordptr addr);
|
||||
boolean BitVector_rotate_right(wordptr addr);
|
||||
boolean BitVector_shift_left (wordptr addr, boolean carry_in);
|
||||
boolean BitVector_shift_right (wordptr addr, boolean carry_in);
|
||||
boolean /*@alt void@*/ BitVector_rotate_left (wordptr addr);
|
||||
boolean /*@alt void@*/ BitVector_rotate_right(wordptr addr);
|
||||
boolean /*@alt void@*/ BitVector_shift_left (wordptr addr, boolean carry_in);
|
||||
boolean /*@alt void@*/ BitVector_shift_right (wordptr addr, boolean carry_in);
|
||||
void BitVector_Move_Left (wordptr addr, N_int bits);
|
||||
void BitVector_Move_Right (wordptr addr, N_int bits);
|
||||
|
||||
|
|
@ -226,15 +226,15 @@ void BitVector_Delete (wordptr addr, N_int offset, N_int count,
|
|||
|
||||
/* ===> bit vector arithmetic: */
|
||||
|
||||
boolean BitVector_increment (wordptr addr); /* X++ */
|
||||
boolean BitVector_decrement (wordptr addr); /* X-- */
|
||||
boolean /*@alt void@*/ BitVector_increment (wordptr addr); /* X++ */
|
||||
boolean /*@alt void@*/ BitVector_decrement (wordptr addr); /* X-- */
|
||||
|
||||
boolean BitVector_compute (wordptr X, wordptr Y, wordptr Z, boolean minus,
|
||||
boolean *carry);
|
||||
boolean BitVector_add (wordptr X, wordptr Y, wordptr Z, boolean *carry);
|
||||
boolean BitVector_sub (wordptr X, wordptr Y, wordptr Z, boolean *carry);
|
||||
boolean BitVector_inc (wordptr X, wordptr Y);
|
||||
boolean BitVector_dec (wordptr X, wordptr Y);
|
||||
boolean /*@alt void@*/ BitVector_compute (wordptr X, wordptr Y, wordptr Z, boolean minus,
|
||||
/*@out@*/ boolean *carry);
|
||||
boolean /*@alt void@*/ BitVector_add (wordptr X, wordptr Y, wordptr Z, /*@out@*/ boolean *carry);
|
||||
boolean /*@alt void@*/ BitVector_sub (wordptr X, wordptr Y, wordptr Z, /*@out@*/ boolean *carry);
|
||||
boolean /*@alt void@*/ BitVector_inc (wordptr X, wordptr Y);
|
||||
boolean /*@alt void@*/ BitVector_dec (wordptr X, wordptr Y);
|
||||
|
||||
void BitVector_Negate (wordptr X, wordptr Y);
|
||||
void BitVector_Absolute(wordptr X, wordptr Y);
|
||||
|
|
@ -249,7 +249,7 @@ ErrCode BitVector_Power (wordptr X, wordptr Y, wordptr Z);
|
|||
/* ===> direct memory access functions: */
|
||||
|
||||
void BitVector_Block_Store (wordptr addr, charptr buffer, N_int length);
|
||||
charptr BitVector_Block_Read (wordptr addr, N_intptr length);
|
||||
charptr BitVector_Block_Read (wordptr addr, /*@out@*/ N_intptr length);
|
||||
|
||||
/* ===> word array functions: */
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "globals.h"
|
||||
#include "errwarn.h"
|
||||
|
|
@ -35,13 +35,13 @@ RCSID("$IdPath$");
|
|||
|
||||
|
||||
struct dataval {
|
||||
STAILQ_ENTRY(dataval) link;
|
||||
/*@reldef@*/ STAILQ_ENTRY(dataval) link;
|
||||
|
||||
enum { DV_EMPTY, DV_EXPR, DV_STRING } type;
|
||||
|
||||
union {
|
||||
expr *expn;
|
||||
char *str_val;
|
||||
/*@only@*/ expr *expn;
|
||||
/*@only@*/ char *str_val;
|
||||
} data;
|
||||
};
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ typedef struct bytecode_data {
|
|||
} bytecode_data;
|
||||
|
||||
typedef struct bytecode_reserve {
|
||||
expr *numitems; /* number of items to reserve */
|
||||
/*@only@*/ expr *numitems; /* number of items to reserve */
|
||||
unsigned char itemsize; /* size of each item (in bytes) */
|
||||
} bytecode_reserve;
|
||||
|
||||
|
|
@ -77,6 +77,8 @@ imm_new_int(unsigned long int_val)
|
|||
im->len = 4;
|
||||
|
||||
im->isneg = 0;
|
||||
im->f_len = 0;
|
||||
im->f_sign = 0;
|
||||
|
||||
return im;
|
||||
}
|
||||
|
|
@ -89,6 +91,8 @@ imm_new_expr(expr *expr_ptr)
|
|||
im->val = expr_ptr;
|
||||
im->len = 0;
|
||||
im->isneg = 0;
|
||||
im->f_len = 0;
|
||||
im->f_sign = 0;
|
||||
|
||||
return im;
|
||||
}
|
||||
|
|
@ -143,7 +147,7 @@ bc_new_common(bytecode_type type, size_t datasize)
|
|||
}
|
||||
|
||||
bytecode *
|
||||
bc_new_data(datavalhead *datahead, unsigned long size)
|
||||
bc_new_data(datavalhead *datahead, unsigned char size)
|
||||
{
|
||||
bytecode *bc = bc_new_common(BC_DATA, sizeof(bytecode_data));
|
||||
bytecode_data *data = bc_get_data(bc);
|
||||
|
|
@ -155,12 +159,14 @@ bc_new_data(datavalhead *datahead, unsigned long size)
|
|||
}
|
||||
|
||||
bytecode *
|
||||
bc_new_reserve(expr *numitems, unsigned long itemsize)
|
||||
bc_new_reserve(expr *numitems, unsigned char itemsize)
|
||||
{
|
||||
bytecode *bc = bc_new_common(BC_RESERVE, sizeof(bytecode_reserve));
|
||||
bytecode_reserve *reserve = bc_get_data(bc);
|
||||
|
||||
/*@-mustfree@*/
|
||||
reserve->numitems = numitems;
|
||||
/*@=mustfree@*/
|
||||
reserve->itemsize = itemsize;
|
||||
|
||||
return bc;
|
||||
|
|
@ -199,7 +205,8 @@ bc_delete(bytecode *bc)
|
|||
}
|
||||
|
||||
int
|
||||
bc_get_offset(section *sect, bytecode *bc, unsigned long *ret_val)
|
||||
bc_get_offset(/*@unused@*/ section *sect, /*@unused@*/ bytecode *bc,
|
||||
/*@unused@*/ unsigned long *ret_val)
|
||||
{
|
||||
return 0; /* TODO */
|
||||
}
|
||||
|
|
@ -256,7 +263,6 @@ bc_parser_finalize(bytecode *bc)
|
|||
case BC_EMPTY:
|
||||
/* FIXME: delete it (probably in bytecodes_ level, not here */
|
||||
InternalError(_("got empty bytecode in parser_finalize"));
|
||||
break;
|
||||
default:
|
||||
if (bc->type < cur_arch->bc.type_max)
|
||||
cur_arch->bc.bc_parser_finalize(bc);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
typedef struct effaddr effaddr;
|
||||
typedef struct immval immval;
|
||||
typedef STAILQ_HEAD(datavalhead, dataval) datavalhead;
|
||||
typedef /*@reldef@*/ STAILQ_HEAD(datavalhead, dataval) datavalhead;
|
||||
typedef struct dataval dataval;
|
||||
|
||||
/* Additional types may be architecture-defined starting at
|
||||
|
|
@ -37,24 +37,26 @@ typedef enum {
|
|||
} bytecode_type;
|
||||
#define BYTECODE_TYPE_BASE BC_RESERVE+1
|
||||
|
||||
immval *imm_new_int(unsigned long int_val);
|
||||
immval *imm_new_expr(expr *e);
|
||||
/*@only@*/ immval *imm_new_int(unsigned long int_val);
|
||||
/*@only@*/ immval *imm_new_expr(/*@keep@*/ expr *e);
|
||||
|
||||
void ea_set_len(effaddr *ea, unsigned char len);
|
||||
void ea_set_nosplit(effaddr *ea, unsigned char nosplit);
|
||||
|
||||
void bc_set_multiple(bytecode *bc, expr *e);
|
||||
void bc_set_multiple(bytecode *bc, /*@keep@*/ expr *e);
|
||||
|
||||
bytecode *bc_new_common(bytecode_type type, size_t datasize);
|
||||
bytecode *bc_new_data(datavalhead *datahead, unsigned long size);
|
||||
bytecode *bc_new_reserve(expr *numitems, unsigned long itemsize);
|
||||
/*@only@*/ bytecode *bc_new_common(bytecode_type type, size_t datasize);
|
||||
/*@only@*/ bytecode *bc_new_data(datavalhead *datahead, unsigned char size);
|
||||
/*@only@*/ bytecode *bc_new_reserve(/*@keep@*/ expr *numitems,
|
||||
unsigned char itemsize);
|
||||
|
||||
void bc_delete(bytecode *bc);
|
||||
void bc_delete(/*@only@*/ /*@null@*/ bytecode *bc);
|
||||
|
||||
/* Gets the offset of the bytecode specified by bc if possible.
|
||||
* Return value is IF POSSIBLE, not the value.
|
||||
*/
|
||||
int bc_get_offset(section *sect, bytecode *bc, unsigned long *ret_val);
|
||||
int bc_get_offset(section *sect, bytecode *bc,
|
||||
/*@out@*/ unsigned long *ret_val);
|
||||
|
||||
void bc_print(const bytecode *bc);
|
||||
|
||||
|
|
@ -71,17 +73,19 @@ void bcs_delete(bytecodehead *headp);
|
|||
* this function. If bc was actually appended (it wasn't NULL or empty),
|
||||
* then returns bc, otherwise returns NULL.
|
||||
*/
|
||||
bytecode *bcs_append(bytecodehead *headp, bytecode *bc);
|
||||
/*@only@*/ /*@null@*/ bytecode *bcs_append(bytecodehead *headp,
|
||||
/*@returned@*/ /*@only@*/ /*@null@*/
|
||||
bytecode *bc);
|
||||
|
||||
void bcs_print(const bytecodehead *headp);
|
||||
|
||||
void bcs_parser_finalize(bytecodehead *headp);
|
||||
|
||||
dataval *dv_new_expr(expr *expn);
|
||||
dataval *dv_new_float(floatnum *flt);
|
||||
dataval *dv_new_string(char *str_val);
|
||||
dataval *dv_new_expr(/*@keep@*/ expr *expn);
|
||||
dataval *dv_new_float(/*@keep@*/ floatnum *flt);
|
||||
dataval *dv_new_string(/*@keep@*/ char *str_val);
|
||||
|
||||
/* void dvs_initialize(datavalhead *headp); */
|
||||
void dvs_initialize(datavalhead *headp);
|
||||
#define dvs_initialize(headp) STAILQ_INIT(headp)
|
||||
|
||||
void dvs_delete(datavalhead *headp);
|
||||
|
|
@ -92,7 +96,8 @@ void dvs_delete(datavalhead *headp);
|
|||
* this function. If dv was actually appended (it wasn't NULL), then
|
||||
* returns dv, otherwise returns NULL.
|
||||
*/
|
||||
dataval *dvs_append(datavalhead *headp, dataval *dv);
|
||||
/*@null@*/ dataval *dvs_append(datavalhead *headp,
|
||||
/*@returned@*/ /*@null@*/ dataval *dv);
|
||||
|
||||
void dvs_print(const datavalhead *head);
|
||||
|
||||
|
|
|
|||
|
|
@ -169,8 +169,8 @@ struct { \
|
|||
*/
|
||||
#define STAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *stqh_first;/* first element */ \
|
||||
struct type **stqh_last;/* addr of last next element */ \
|
||||
/*@reldef@*/ struct type *stqh_first;/* first element */ \
|
||||
/*@reldef@*/ struct type **stqh_last;/* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define STAILQ_HEAD_INITIALIZER(head) \
|
||||
|
|
@ -178,7 +178,7 @@ struct name { \
|
|||
|
||||
#define STAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *stqe_next; /* next element */ \
|
||||
/*@reldef@*/ struct type *stqe_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -188,7 +188,9 @@ struct { \
|
|||
|
||||
#define STAILQ_INIT(head) do { \
|
||||
(head)->stqh_first = NULL; \
|
||||
/*@-immediatetrans@*/ \
|
||||
(head)->stqh_last = &(head)->stqh_first; \
|
||||
/*@=immediatetrans@*/ \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_FIRST(head) ((head)->stqh_first)
|
||||
|
|
@ -210,8 +212,10 @@ struct { \
|
|||
|
||||
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
(elm)->field.stqe_next = NULL; \
|
||||
/*@-onlytrans -mustfree -immediatetrans@*/ \
|
||||
*(head)->stqh_last = (elm); \
|
||||
(head)->stqh_last = &(elm)->field.stqe_next; \
|
||||
/*@=onlytrans =mustfree =immediatetrans@*/ \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@ typedef struct optimizer optimizer;
|
|||
typedef struct objfmt objfmt;
|
||||
|
||||
typedef struct bytecode bytecode;
|
||||
typedef STAILQ_HEAD(bytecodehead, bytecode) bytecodehead;
|
||||
typedef /*@reldef@*/ STAILQ_HEAD(bytecodehead, bytecode) bytecodehead;
|
||||
|
||||
typedef struct section section;
|
||||
typedef STAILQ_HEAD(sectionhead, section) sectionhead;
|
||||
typedef /*@reldef@*/ STAILQ_HEAD(sectionhead, section) sectionhead;
|
||||
|
||||
typedef struct symrec symrec;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,13 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stdarg.h>
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#ifdef gettext_noop
|
||||
|
|
@ -50,20 +51,22 @@ static unsigned int warning_count = 0;
|
|||
* When adding a string here, keep errwarn.h in sync! */
|
||||
|
||||
/* Fatal error messages. Match up with fatal_num enum in errwarn.h. */
|
||||
/*@-observertrans@*/
|
||||
static const char *fatal_msgs[] = {
|
||||
N_("unknown"),
|
||||
N_("out of memory")
|
||||
};
|
||||
/*@=observertrans@*/
|
||||
|
||||
typedef STAILQ_HEAD(errwarnhead_s, errwarn_s) errwarnhead;
|
||||
errwarnhead *errwarns = (errwarnhead *)NULL;
|
||||
typedef /*@reldef@*/ STAILQ_HEAD(errwarnhead_s, errwarn_s) errwarnhead;
|
||||
static /*@only@*/ /*@null@*/ errwarnhead *errwarns = (errwarnhead *)NULL;
|
||||
|
||||
typedef struct errwarn_s {
|
||||
STAILQ_ENTRY(errwarn_s) link;
|
||||
/*@reldef@*/ STAILQ_ENTRY(errwarn_s) link;
|
||||
|
||||
enum { WE_ERROR, WE_WARNING } type;
|
||||
|
||||
const char *filename;
|
||||
/*@dependent@*/ const char *filename;
|
||||
unsigned long line;
|
||||
/* FIXME: This should not be a fixed size. But we don't have vasprintf()
|
||||
* right now. */
|
||||
|
|
@ -168,12 +171,16 @@ Error(const char *fmt, ...)
|
|||
we->line = line_number;
|
||||
}
|
||||
|
||||
assert(we != NULL);
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsprintf(we->msg, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
/*@-branchstate@*/
|
||||
if (!previous_error_parser)
|
||||
STAILQ_INSERT_TAIL(errwarns, we, link);
|
||||
/*@=branchstate@*/
|
||||
|
||||
previous_error_line = line_number;
|
||||
previous_error_parser = 0;
|
||||
|
|
@ -241,7 +248,7 @@ ErrorAt(const char *filename, unsigned long line, const char *fmt, ...)
|
|||
/* XXX: Should insert into list instead of printing immediately */
|
||||
va_list ap;
|
||||
|
||||
fprintf(stderr, "%s:%lu: ", filename, line);
|
||||
fprintf(stderr, "%s:%lu: ", filename?filename:"(NULL)", line);
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
|
|
@ -254,7 +261,8 @@ WarningAt(const char *filename, unsigned long line, const char *fmt, ...)
|
|||
/* XXX: Should insert into list instead of printing immediately */
|
||||
va_list ap;
|
||||
|
||||
fprintf(stderr, "%s:%lu: %s ", filename, line, _("warning:"));
|
||||
fprintf(stderr, "%s:%lu: %s ", filename?filename:"NULL", line,
|
||||
_("warning:"));
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
|
|
|
|||
|
|
@ -30,30 +30,33 @@ typedef enum {
|
|||
FATAL_NOMEM
|
||||
} fatal_num;
|
||||
|
||||
char *conv_unprint(char ch);
|
||||
/*@shared@*/ char *conv_unprint(char ch);
|
||||
|
||||
void ParserError(const char *);
|
||||
|
||||
void InternalError_(const char *file, unsigned int line, const char *message);
|
||||
/*@exits@*/ void InternalError_(const char *file, unsigned int line,
|
||||
const char *message);
|
||||
#define InternalError(msg) InternalError_(__FILE__, __LINE__, msg)
|
||||
|
||||
void Fatal(fatal_num);
|
||||
void Error(const char *, ...);
|
||||
void Warning(const char *, ...);
|
||||
/*@exits@*/ void Fatal(fatal_num);
|
||||
void Error(const char *, ...) /*@printflike@*/;
|
||||
void Warning(const char *, ...) /*@printflike@*/;
|
||||
|
||||
/* Use Error() and Warning() instead of ErrorAt() and WarningAt() when being
|
||||
* called in line order from a parser. The *At() functions are much slower,
|
||||
* at least in the current implementation.
|
||||
*/
|
||||
void ErrorAt(const char *filename, unsigned long line, const char *, ...);
|
||||
void WarningAt(const char *filename, unsigned long line, const char *, ...);
|
||||
void ErrorAt(/*@null@*/ const char *filename, unsigned long line, const char *,
|
||||
...) /*@printflike@*/;
|
||||
void WarningAt(/*@null@*/ const char *filename, unsigned long line,
|
||||
const char *, ...) /*@printflike@*/;
|
||||
|
||||
/* These two functions immediately output the error or warning, with no file
|
||||
* or line information. They should be used for errors and warnings outside
|
||||
* the parser stage (at program startup, for instance).
|
||||
*/
|
||||
void ErrorNow(const char *, ...);
|
||||
void WarningNow(const char *, ...);
|
||||
void ErrorNow(const char *, ...) /*@printflike@*/;
|
||||
void WarningNow(const char *, ...) /*@printflike@*/;
|
||||
|
||||
/* Returns total number of errors to this point in assembly. */
|
||||
unsigned int OutputAllErrorWarning(void);
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ struct ExprItem {
|
|||
*/
|
||||
struct expr {
|
||||
ExprOp op;
|
||||
const char *filename;
|
||||
/*@dependent@*/ /*@null@*/ const char *filename;
|
||||
unsigned long line;
|
||||
int numterms;
|
||||
ExprItem terms[2]; /* structure may be extended to include more */
|
||||
|
|
@ -63,14 +63,19 @@ struct expr {
|
|||
*
|
||||
* Stops early (and returns 1) if func returns 1. Otherwise returns 0.
|
||||
*/
|
||||
int expr_traverse_leaves_in(expr *e, void *d,
|
||||
int (*func) (ExprItem *ei, void *d));
|
||||
int expr_traverse_leaves_in(expr *e, /*@null@*/ void *d,
|
||||
int (*func) (/*@null@*/ ExprItem *ei,
|
||||
/*@null@*/ void *d));
|
||||
|
||||
/* Transform negatives throughout an entire expn tree */
|
||||
expr *expr_xform_neg_tree(expr *e);
|
||||
/*@only@*/ /*@null@*/ expr *expr_xform_neg_tree(/*@returned@*/ /*@only@*/
|
||||
/*@null@*/ expr *e);
|
||||
|
||||
/* Level an entire expn tree */
|
||||
expr *expr_level_tree(expr *e, int fold_const, int simplify_ident);
|
||||
/*@only@*/ /*@null@*/ expr *expr_level_tree(/*@returned@*/ /*@only@*/
|
||||
/*@null@*/ expr *e,
|
||||
int fold_const,
|
||||
int simplify_ident);
|
||||
|
||||
/* Reorder terms of e into canonical order. Only reorders if reordering
|
||||
* doesn't change meaning of expression. (eg, doesn't reorder SUB).
|
||||
|
|
@ -82,7 +87,7 @@ expr *expr_level_tree(expr *e, int fold_const, int simplify_ident);
|
|||
void expr_order_terms(expr *e);
|
||||
|
||||
/* Copy entire expression EXCEPT for index "except" at *top level only*. */
|
||||
expr *expr_copy_except(const expr *e, int except);
|
||||
/*@null@*/ expr *expr_copy_except(const expr *e, int except);
|
||||
|
||||
int expr_contains(expr *e, ExprType t);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "bitvect.h"
|
||||
|
||||
|
|
@ -34,15 +34,17 @@ RCSID("$IdPath$");
|
|||
#include "expr-int.h"
|
||||
|
||||
|
||||
static int expr_traverse_nodes_post(expr *e, void *d,
|
||||
int (*func) (expr *e, void *d));
|
||||
static int expr_traverse_nodes_post(/*@null@*/ expr *e, /*@null@*/ void *d,
|
||||
int (*func) (/*@null@*/ expr *e,
|
||||
/*@null@*/ void *d));
|
||||
|
||||
/* allocate a new expression node, with children as defined.
|
||||
* If it's a unary operator, put the element in left and set right=NULL. */
|
||||
/*@-usedef@*/
|
||||
expr *
|
||||
expr_new(ExprOp op, ExprItem *left, ExprItem *right)
|
||||
{
|
||||
expr *ptr;
|
||||
expr *ptr, *sube;
|
||||
ptr = xmalloc(sizeof(expr));
|
||||
|
||||
ptr->op = op;
|
||||
|
|
@ -59,9 +61,11 @@ expr_new(ExprOp op, ExprItem *left, ExprItem *right)
|
|||
*/
|
||||
while (ptr->terms[0].type == EXPR_EXPR &&
|
||||
ptr->terms[0].data.expn->op == EXPR_IDENT) {
|
||||
expr *sube = ptr->terms[0].data.expn;
|
||||
sube = ptr->terms[0].data.expn;
|
||||
ptr->terms[0] = sube->terms[0]; /* structure copy */
|
||||
/*@-usereleased@*/
|
||||
xfree(sube);
|
||||
/*@=usereleased@*/
|
||||
}
|
||||
} else {
|
||||
InternalError(_("Right side of expression must exist"));
|
||||
|
|
@ -77,9 +81,11 @@ expr_new(ExprOp op, ExprItem *left, ExprItem *right)
|
|||
*/
|
||||
while (ptr->terms[1].type == EXPR_EXPR &&
|
||||
ptr->terms[1].data.expn->op == EXPR_IDENT) {
|
||||
expr *sube = ptr->terms[1].data.expn;
|
||||
sube = ptr->terms[1].data.expn;
|
||||
ptr->terms[1] = sube->terms[0]; /* structure copy */
|
||||
/*@-usereleased@*/
|
||||
xfree(sube);
|
||||
/*@=usereleased@*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,6 +94,7 @@ expr_new(ExprOp op, ExprItem *left, ExprItem *right)
|
|||
|
||||
return ptr;
|
||||
}
|
||||
/*@=usedef@*/
|
||||
|
||||
/* helpers */
|
||||
ExprItem *
|
||||
|
|
@ -148,7 +155,7 @@ expr_xform_neg_item(expr *e, ExprItem *ei)
|
|||
sube->line = e->line;
|
||||
sube->numterms = 2;
|
||||
sube->terms[0].type = EXPR_INT;
|
||||
sube->terms[0].data.intn = intnum_new_int(-1);
|
||||
sube->terms[0].data.intn = intnum_new_int((unsigned long)-1);
|
||||
sube->terms[1] = *ei; /* structure copy */
|
||||
|
||||
/* Replace original ExprItem with subexp */
|
||||
|
|
@ -162,8 +169,8 @@ expr_xform_neg_item(expr *e, ExprItem *ei)
|
|||
*
|
||||
* Returns a possibly reallocated e.
|
||||
*/
|
||||
static expr *
|
||||
expr_xform_neg_helper(expr *e)
|
||||
static /*@only@*/ expr *
|
||||
expr_xform_neg_helper(/*@returned@*/ /*@only@*/ expr *e)
|
||||
{
|
||||
expr *ne;
|
||||
int i;
|
||||
|
|
@ -197,7 +204,7 @@ expr_xform_neg_helper(expr *e)
|
|||
e->op = EXPR_MUL;
|
||||
e->numterms = 2;
|
||||
e->terms[1].type = EXPR_INT;
|
||||
e->terms[1].data.intn = intnum_new_int(-1);
|
||||
e->terms[1].data.intn = intnum_new_int((unsigned long)-1);
|
||||
break;
|
||||
default:
|
||||
/* Everything else. MUL will be combined when it's leveled.
|
||||
|
|
@ -209,7 +216,7 @@ expr_xform_neg_helper(expr *e)
|
|||
ne->line = e->line;
|
||||
ne->numterms = 2;
|
||||
ne->terms[0].type = EXPR_INT;
|
||||
ne->terms[0].data.intn = intnum_new_int(-1);
|
||||
ne->terms[0].data.intn = intnum_new_int((unsigned long)-1);
|
||||
ne->terms[1].type = EXPR_EXPR;
|
||||
ne->terms[1].data.expn = e;
|
||||
return ne;
|
||||
|
|
@ -225,8 +232,8 @@ expr_xform_neg_helper(expr *e)
|
|||
*
|
||||
* Returns a possibly reallocated e.
|
||||
*/
|
||||
static expr *
|
||||
expr_xform_neg(expr *e)
|
||||
static /*@only@*/ expr *
|
||||
expr_xform_neg(/*@returned@*/ /*@only@*/ expr *e)
|
||||
{
|
||||
switch (e->op) {
|
||||
case EXPR_NEG:
|
||||
|
|
@ -385,8 +392,10 @@ expr_simplify_identity(expr *e, int numterms, int int_term)
|
|||
*
|
||||
* Returns a possibly reallocated e.
|
||||
*/
|
||||
static expr *
|
||||
expr_level_op(expr *e, int fold_const, int simplify_ident)
|
||||
/*@-mustfree@*/
|
||||
static /*@only@*/ expr *
|
||||
expr_level_op(/*@returned@*/ /*@only@*/ expr *e, int fold_const,
|
||||
int simplify_ident)
|
||||
{
|
||||
int i, j, o, fold_numterms, level_numterms, level_fold_numterms;
|
||||
int first_int_term = -1;
|
||||
|
|
@ -546,6 +555,7 @@ expr_level_op(expr *e, int fold_const, int simplify_ident)
|
|||
|
||||
return e;
|
||||
}
|
||||
/*@=mustfree@*/
|
||||
|
||||
/* Level an entire expn tree */
|
||||
expr *
|
||||
|
|
@ -603,7 +613,7 @@ expr_order_terms(expr *e)
|
|||
* stable sort (multiple terms of same type are kept in the same
|
||||
* order).
|
||||
*/
|
||||
mergesort(e->terms, e->numterms, sizeof(ExprItem),
|
||||
mergesort(e->terms, (size_t)e->numterms, sizeof(ExprItem),
|
||||
expr_order_terms_compare);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -666,7 +676,7 @@ expr_copy(const expr *e)
|
|||
}
|
||||
|
||||
static int
|
||||
expr_delete_each(expr *e, void *d)
|
||||
expr_delete_each(/*@only@*/ expr *e, /*@unused@*/ void *d)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<e->numterms; i++) {
|
||||
|
|
@ -685,11 +695,13 @@ expr_delete_each(expr *e, void *d)
|
|||
return 0; /* don't stop recursion */
|
||||
}
|
||||
|
||||
/*@-mustfree@*/
|
||||
void
|
||||
expr_delete(expr *e)
|
||||
{
|
||||
expr_traverse_nodes_post(e, NULL, expr_delete_each);
|
||||
}
|
||||
/*@=mustfree@*/
|
||||
|
||||
static int
|
||||
expr_contains_callback(ExprItem *ei, void *d)
|
||||
|
|
@ -705,7 +717,7 @@ expr_contains(expr *e, ExprType t)
|
|||
}
|
||||
|
||||
static int
|
||||
expr_expand_equ_callback(ExprItem *ei, void *d)
|
||||
expr_expand_equ_callback(ExprItem *ei, /*@unused@*/ void *d)
|
||||
{
|
||||
const expr *equ_expr;
|
||||
if (ei->type == EXPR_SYM) {
|
||||
|
|
@ -731,7 +743,8 @@ expr_expand_equ(expr *e)
|
|||
* Stops early (and returns 1) if func returns 1. Otherwise returns 0.
|
||||
*/
|
||||
static int
|
||||
expr_traverse_nodes_post(expr *e, void *d, int (*func) (expr *e, void *d))
|
||||
expr_traverse_nodes_post(expr *e, void *d,
|
||||
int (*func) (/*@null@*/ expr *e, /*@null@*/ void *d))
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -756,7 +769,8 @@ expr_traverse_nodes_post(expr *e, void *d, int (*func) (expr *e, void *d))
|
|||
*/
|
||||
int
|
||||
expr_traverse_leaves_in(expr *e, void *d,
|
||||
int (*func) (ExprItem *ei, void *d))
|
||||
int (*func) (/*@null@*/ ExprItem *ei,
|
||||
/*@null@*/ void *d))
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -784,6 +798,7 @@ expr_simplify(expr *e)
|
|||
return e;
|
||||
}
|
||||
|
||||
/*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/
|
||||
const intnum *
|
||||
expr_get_intnum(expr **ep)
|
||||
{
|
||||
|
|
@ -794,6 +809,7 @@ expr_get_intnum(expr **ep)
|
|||
else
|
||||
return (intnum *)NULL;
|
||||
}
|
||||
/*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/
|
||||
|
||||
void
|
||||
expr_print(expr *e)
|
||||
|
|
|
|||
|
|
@ -24,13 +24,14 @@
|
|||
|
||||
typedef struct ExprItem ExprItem;
|
||||
|
||||
expr *expr_new(ExprOp, ExprItem *, ExprItem *);
|
||||
/*@only@*/ expr *expr_new(ExprOp, /*@only@*/ ExprItem *,
|
||||
/*@only@*/ /*@null@*/ ExprItem *);
|
||||
|
||||
ExprItem *ExprSym(symrec *);
|
||||
ExprItem *ExprExpr(expr *);
|
||||
ExprItem *ExprInt(intnum *);
|
||||
ExprItem *ExprFloat(floatnum *);
|
||||
ExprItem *ExprReg(unsigned char reg, unsigned char size);
|
||||
/*@only@*/ ExprItem *ExprSym(/*@keep@*/ symrec *);
|
||||
/*@only@*/ ExprItem *ExprExpr(/*@keep@*/ expr *);
|
||||
/*@only@*/ ExprItem *ExprInt(/*@keep@*/ intnum *);
|
||||
/*@only@*/ ExprItem *ExprFloat(/*@keep@*/ floatnum *);
|
||||
/*@only@*/ ExprItem *ExprReg(unsigned char reg, unsigned char size);
|
||||
|
||||
#define expr_new_tree(l,o,r) \
|
||||
expr_new ((o), ExprExpr(l), ExprExpr(r))
|
||||
|
|
@ -40,9 +41,9 @@ ExprItem *ExprReg(unsigned char reg, unsigned char size);
|
|||
expr_new (EXPR_IDENT, (r), (ExprItem *)NULL)
|
||||
|
||||
/* allocates and makes an exact duplicate of e */
|
||||
expr *expr_copy(const expr *e);
|
||||
/*@null@*/ expr *expr_copy(const expr *e);
|
||||
|
||||
void expr_delete(expr *e);
|
||||
void expr_delete(/*@only@*/ /*@null@*/ expr *e);
|
||||
|
||||
/* Expands all (symrec) equ's in the expression into full expression
|
||||
* instances.
|
||||
|
|
@ -52,13 +53,14 @@ void expr_expand_equ(expr *e);
|
|||
/* Simplifies the expression e as much as possible, eliminating extraneous
|
||||
* branches and simplifying integer-only subexpressions.
|
||||
*/
|
||||
expr *expr_simplify(expr *e);
|
||||
/*@only@*/ /*@null@*/ expr *expr_simplify(/*@returned@*/ /*@only@*/ /*@null@*/
|
||||
expr *e);
|
||||
|
||||
/* Gets the integer value of e if the expression is just an integer. If the
|
||||
* expression is more complex (contains anything other than integers, ie
|
||||
* floats, non-valued labels, registers), returns NULL.
|
||||
*/
|
||||
const intnum *expr_get_intnum(expr **ep);
|
||||
/*@dependent@*/ /*@null@*/ const intnum *expr_get_intnum(expr **ep);
|
||||
|
||||
void expr_print(expr *);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "file.h"
|
||||
|
||||
|
|
@ -38,13 +38,13 @@ fwrite_short(unsigned short val, FILE *f)
|
|||
size_t
|
||||
fwrite_long(unsigned long val, FILE *f)
|
||||
{
|
||||
if (fputc(val & 0xFF, f) == EOF)
|
||||
if (fputc((int)(val & 0xFF), f) == EOF)
|
||||
return 0;
|
||||
if (fputc((val >> 8) & 0xFF, f) == EOF)
|
||||
if (fputc((int)((val >> 8) & 0xFF), f) == EOF)
|
||||
return 0;
|
||||
if (fputc((val >> 16) & 0xFF, f) == EOF)
|
||||
if (fputc((int)((val >> 16) & 0xFF), f) == EOF)
|
||||
return 0;
|
||||
if (fputc((val >> 24) & 0xFF, f) == EOF)
|
||||
if (fputc((int)((val >> 24) & 0xFF), f) == EOF)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
/* These functions only work properly if p is an (unsigned char *) */
|
||||
|
||||
#define WRITE_BYTE(ptr, val) \
|
||||
*((ptr)++) = (val) & 0xFF
|
||||
*((ptr)++) = (unsigned char)((val) & 0xFF)
|
||||
|
||||
#define WRITE_SHORT(ptr, val) \
|
||||
do { \
|
||||
|
|
@ -101,10 +101,10 @@ size_t fwrite_long(unsigned long val, FILE *f);
|
|||
|
||||
#define LOAD_LONG(val, ptr) \
|
||||
do { \
|
||||
(val) = *(ptr) & 0xFF; \
|
||||
(val) |= (*((ptr)+1) & 0xFF) << 8; \
|
||||
(val) |= (*((ptr)+2) & 0xFF) << 16; \
|
||||
(val) |= (*((ptr)+3) & 0xFF) << 24; \
|
||||
(val) = (unsigned long)(*(ptr) & 0xFF); \
|
||||
(val) |= (unsigned long)((*((ptr)+1) & 0xFF) << 8); \
|
||||
(val) |= (unsigned long)((*((ptr)+2) & 0xFF) << 16); \
|
||||
(val) |= (unsigned long)((*((ptr)+3) & 0xFF) << 24); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ RCSID("$IdPath$");
|
|||
* Mantissa does NOT have an implied one bit (it's explicit).
|
||||
*/
|
||||
struct floatnum {
|
||||
wordptr mantissa; /* Allocated to MANT_BITS bits */
|
||||
/*@only@*/ wordptr mantissa; /* Allocated to MANT_BITS bits */
|
||||
unsigned short exponent;
|
||||
unsigned char sign;
|
||||
unsigned char flags;
|
||||
|
|
@ -84,7 +84,9 @@ typedef struct POT_Entry_Source_s {
|
|||
* entry[12-n] = 10 ** (-2 ** n) for 0 <= n <= 12.
|
||||
* entry[13] = 1.0
|
||||
*/
|
||||
static POT_Entry *POT_TableN = (POT_Entry *)NULL;
|
||||
/*@-nullassign@*/
|
||||
static /*@only@*/ POT_Entry *POT_TableN = (POT_Entry *)NULL;
|
||||
/*@=nullassign@*/
|
||||
static POT_Entry_Source POT_TableN_Source[] = {
|
||||
{{0xe3,0x2d,0xde,0x9f,0xce,0xd2,0xc8,0x04,0xdd,0xa6},0x4ad8}, /* 1e-4096 */
|
||||
{{0x25,0x49,0xe4,0x2d,0x36,0x34,0x4f,0x53,0xae,0xce},0x656b}, /* 1e-2048 */
|
||||
|
|
@ -112,7 +114,7 @@ static POT_Entry_Source POT_TableN_Source[] = {
|
|||
* before the table. This -1 entry is created at runtime by duplicating the
|
||||
* 0 entry.
|
||||
*/
|
||||
static POT_Entry *POT_TableP;
|
||||
static /*@only@*/ POT_Entry *POT_TableP;
|
||||
static POT_Entry_Source POT_TableP_Source[] = {
|
||||
{{0x4c,0xc9,0x9a,0x97,0x20,0x8a,0x02,0x52,0x60,0xc4},0xb525}, /* 1e+4096 */
|
||||
{{0x4d,0xa7,0xe4,0x5d,0x3d,0xc5,0x5d,0x3b,0x8b,0x9e},0x9a92}, /* 1e+2048 */
|
||||
|
|
@ -131,7 +133,7 @@ static POT_Entry_Source POT_TableP_Source[] = {
|
|||
};
|
||||
|
||||
static void
|
||||
POT_Table_Init_Entry(POT_Entry *e, POT_Entry_Source *s, int dec_exp)
|
||||
POT_Table_Init_Entry(/*@out@*/ POT_Entry *e, POT_Entry_Source *s, int dec_exp)
|
||||
{
|
||||
/* Save decimal exponent */
|
||||
e->dec_exponent = dec_exp;
|
||||
|
|
@ -150,10 +152,12 @@ POT_Table_Init_Entry(POT_Entry *e, POT_Entry_Source *s, int dec_exp)
|
|||
e->f.flags = 0;
|
||||
}
|
||||
|
||||
/*@-compdef@*/
|
||||
static void
|
||||
POT_Table_Init(void)
|
||||
/*@globals undef POT_TableN, undef POT_TableP @*/
|
||||
{
|
||||
unsigned int dec_exp = 1;
|
||||
int dec_exp = 1;
|
||||
int i;
|
||||
|
||||
/* Allocate space for two POT tables */
|
||||
|
|
@ -177,11 +181,12 @@ POT_Table_Init(void)
|
|||
/* Offset POT_TableP so that [0] becomes [-1] */
|
||||
POT_TableP++;
|
||||
}
|
||||
/*@=compdef@*/
|
||||
|
||||
static void
|
||||
floatnum_normalize(floatnum *flt)
|
||||
{
|
||||
int norm_amt;
|
||||
long norm_amt;
|
||||
|
||||
if (BitVector_is_empty(flt->mantissa)) {
|
||||
flt->exponent = 0;
|
||||
|
|
@ -191,9 +196,9 @@ floatnum_normalize(floatnum *flt)
|
|||
/* Look for the highest set bit, shift to make it the MSB, and adjust
|
||||
* exponent. Don't let exponent go negative. */
|
||||
norm_amt = (MANT_BITS-1)-Set_Max(flt->mantissa);
|
||||
if (norm_amt > flt->exponent)
|
||||
norm_amt = flt->exponent;
|
||||
BitVector_Move_Left(flt->mantissa, norm_amt);
|
||||
if (norm_amt > (long)flt->exponent)
|
||||
norm_amt = (long)flt->exponent;
|
||||
BitVector_Move_Left(flt->mantissa, (N_int)norm_amt);
|
||||
flt->exponent -= norm_amt;
|
||||
}
|
||||
|
||||
|
|
@ -201,9 +206,9 @@ floatnum_normalize(floatnum *flt)
|
|||
static void
|
||||
floatnum_mul(floatnum *acc, const floatnum *op)
|
||||
{
|
||||
int exp;
|
||||
long exp;
|
||||
wordptr product, op1, op2;
|
||||
int norm_amt;
|
||||
long norm_amt;
|
||||
|
||||
/* Compute the new sign */
|
||||
acc->sign ^= op->sign;
|
||||
|
|
@ -231,14 +236,14 @@ floatnum_mul(floatnum *acc, const floatnum *op)
|
|||
}
|
||||
|
||||
/* Add one to the final exponent, as the multiply shifts one extra time. */
|
||||
acc->exponent = exp+1;
|
||||
acc->exponent = (unsigned short)(exp+1);
|
||||
|
||||
/* Allocate space for the multiply result */
|
||||
product = BitVector_Create((MANT_BITS+1)*2, FALSE);
|
||||
product = BitVector_Create((N_int)((MANT_BITS+1)*2), FALSE);
|
||||
|
||||
/* Allocate 1-bit-longer fields to force the operands to be unsigned */
|
||||
op1 = BitVector_Create(MANT_BITS+1, FALSE);
|
||||
op2 = BitVector_Create(MANT_BITS+1, FALSE);
|
||||
op1 = BitVector_Create((N_int)(MANT_BITS+1), FALSE);
|
||||
op2 = BitVector_Create((N_int)(MANT_BITS+1), FALSE);
|
||||
|
||||
/* Make the operands unsigned after copying from original operands */
|
||||
BitVector_Copy(op1, acc->mantissa);
|
||||
|
|
@ -256,9 +261,9 @@ floatnum_mul(floatnum *acc, const floatnum *op)
|
|||
* exponent. Don't let exponent go negative.
|
||||
*/
|
||||
norm_amt = (MANT_BITS*2-1)-Set_Max(product);
|
||||
if (norm_amt > acc->exponent)
|
||||
norm_amt = acc->exponent;
|
||||
BitVector_Move_Left(product, norm_amt);
|
||||
if (norm_amt > (long)acc->exponent)
|
||||
norm_amt = (long)acc->exponent;
|
||||
BitVector_Move_Left(product, (N_int)norm_amt);
|
||||
acc->exponent -= norm_amt;
|
||||
|
||||
/* Store the highest bits of the result */
|
||||
|
|
@ -338,7 +343,7 @@ floatnum_new(const char *str)
|
|||
|
||||
/* Add in current digit */
|
||||
BitVector_Empty(operand[0]);
|
||||
BitVector_Chunk_Store(operand[0], 4, 0, *str-'0');
|
||||
BitVector_Chunk_Store(operand[0], 4, 0, (N_long)(*str-'0'));
|
||||
carry = 0;
|
||||
BitVector_add(flt->mantissa, operand[1], operand[0], &carry);
|
||||
} else {
|
||||
|
|
@ -374,7 +379,7 @@ floatnum_new(const char *str)
|
|||
|
||||
/* Add in current digit */
|
||||
BitVector_Empty(operand[0]);
|
||||
BitVector_Chunk_Store(operand[0], 4, 0, *str-'0');
|
||||
BitVector_Chunk_Store(operand[0], 4, 0, (N_long)(*str-'0'));
|
||||
carry = 0;
|
||||
BitVector_add(flt->mantissa, operand[1], operand[0], &carry);
|
||||
}
|
||||
|
|
@ -405,7 +410,8 @@ floatnum_new(const char *str)
|
|||
|
||||
return flt;
|
||||
}
|
||||
flt->exponent = 0x7FFF+(MANT_BITS-1); /* Exponent if already norm. */
|
||||
/* Exponent if already norm. */
|
||||
flt->exponent = (unsigned short)(0x7FFF+(MANT_BITS-1));
|
||||
floatnum_normalize(flt);
|
||||
|
||||
/* The number is normalized. Now multiply by 10 the number of times
|
||||
|
|
@ -480,7 +486,7 @@ floatnum_delete(floatnum *flt)
|
|||
}
|
||||
|
||||
void
|
||||
floatnum_calc(floatnum *acc, ExprOp op, floatnum *operand)
|
||||
floatnum_calc(floatnum *acc, ExprOp op, /*@unused@*/ floatnum *operand)
|
||||
{
|
||||
if (op != EXPR_NEG)
|
||||
Error(_("Unsupported floating-point arithmetic operation"));
|
||||
|
|
@ -512,22 +518,25 @@ floatnum_get_int(const floatnum *flt, unsigned long *ret_val)
|
|||
* Returns 0 on success, 1 if overflow, -1 if underflow.
|
||||
*/
|
||||
static int
|
||||
floatnum_get_common(const floatnum *flt, unsigned char *ptr, int byte_size,
|
||||
int mant_bits, int implicit1, int exp_bits)
|
||||
floatnum_get_common(const floatnum *flt, /*@out@*/ unsigned char *ptr,
|
||||
N_int byte_size, N_int mant_bits, int implicit1,
|
||||
N_int exp_bits)
|
||||
{
|
||||
int exponent = flt->exponent;
|
||||
long exponent = (long)flt->exponent;
|
||||
wordptr output;
|
||||
charptr buf;
|
||||
unsigned int len;
|
||||
unsigned int overflow = 0, underflow = 0, retval = 0;
|
||||
int exp_bias = (1<<(exp_bits-1))-1;
|
||||
int exp_inf = (1<<exp_bits)-1;
|
||||
unsigned int overflow = 0, underflow = 0;
|
||||
int retval = 0;
|
||||
long exp_bias = (1<<(exp_bits-1))-1;
|
||||
long exp_inf = (1<<exp_bits)-1;
|
||||
|
||||
output = BitVector_Create(byte_size*8, TRUE);
|
||||
|
||||
/* copy mantissa */
|
||||
BitVector_Interval_Copy(output, flt->mantissa, 0,
|
||||
(MANT_BITS-implicit1)-mant_bits, mant_bits);
|
||||
(N_int)((MANT_BITS-implicit1)-mant_bits),
|
||||
mant_bits);
|
||||
|
||||
/* round mantissa */
|
||||
if (BitVector_bit_test(flt->mantissa, (MANT_BITS-implicit1)-(mant_bits+1)))
|
||||
|
|
@ -568,7 +577,7 @@ floatnum_get_common(const floatnum *flt, unsigned char *ptr, int byte_size,
|
|||
}
|
||||
|
||||
/* move exponent into place */
|
||||
BitVector_Chunk_Store(output, exp_bits, mant_bits, exponent);
|
||||
BitVector_Chunk_Store(output, exp_bits, mant_bits, (N_long)exponent);
|
||||
|
||||
/* merge in sign bit */
|
||||
BitVector_Bit_Copy(output, byte_size*8-1, flt->sign);
|
||||
|
|
@ -631,13 +640,14 @@ floatnum_get_sized(const floatnum *flt, unsigned char *ptr, size_t size)
|
|||
return floatnum_get_common(flt, ptr, 10, 64, 0, 15);
|
||||
default:
|
||||
InternalError(_("Invalid float conversion size"));
|
||||
/*@notreached@*/
|
||||
return 1; /* never reached, but silence GCC warning */
|
||||
}
|
||||
}
|
||||
|
||||
/* 1 if the size is valid, 0 if it isn't */
|
||||
int
|
||||
floatnum_check_size(const floatnum *flt, size_t size)
|
||||
floatnum_check_size(/*@unused@*/ const floatnum *flt, size_t size)
|
||||
{
|
||||
switch (size) {
|
||||
case 4:
|
||||
|
|
@ -658,7 +668,7 @@ floatnum_print(const floatnum *flt)
|
|||
|
||||
/* Internal format */
|
||||
str = BitVector_to_Hex(flt->mantissa);
|
||||
printf("%c %s *2^%04x\n", flt->sign?'-':'+', str, flt->exponent);
|
||||
printf("%c %s *2^%04x\n", flt->sign?'-':'+', (char *)str, flt->exponent);
|
||||
xfree(str);
|
||||
|
||||
/* 32-bit (single precision) format */
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@
|
|||
#ifndef YASM_FLOATNUM_H
|
||||
#define YASM_FLOATNUM_H
|
||||
|
||||
floatnum *floatnum_new(const char *str);
|
||||
floatnum *floatnum_copy(const floatnum *flt);
|
||||
void floatnum_delete(floatnum *flt);
|
||||
/*@only@*/ floatnum *floatnum_new(const char *str);
|
||||
/*@only@*/ floatnum *floatnum_copy(const floatnum *flt);
|
||||
void floatnum_delete(/*@only@*/ floatnum *flt);
|
||||
|
||||
/* calculation function: acc = acc op operand */
|
||||
void floatnum_calc(floatnum *acc, ExprOp op, floatnum *operand);
|
||||
|
|
@ -38,12 +38,13 @@ void floatnum_calc(floatnum *acc, ExprOp op, floatnum *operand);
|
|||
/* Essentially a convert to single-precision and return as 32-bit value.
|
||||
* The 32-bit value is a "standard" C value (eg, of unknown endian).
|
||||
*/
|
||||
int floatnum_get_int(const floatnum *flt, unsigned long *ret_val);
|
||||
int floatnum_get_int(const floatnum *flt, /*@out@*/ unsigned long *ret_val);
|
||||
|
||||
/* ptr will point to the Intel-format little-endian byte string after a
|
||||
* successful call (eg, [0] should be the first byte output to the file).
|
||||
*/
|
||||
int floatnum_get_sized(const floatnum *flt, unsigned char *ptr, size_t size);
|
||||
int floatnum_get_sized(const floatnum *flt, /*@out@*/ unsigned char *ptr,
|
||||
size_t size);
|
||||
|
||||
/* Basic check to see if size is even valid for flt conversion (doesn't
|
||||
* actually check for underflow/overflow but rather checks for size=4,8,10).
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ intnum_new_bin(char *str)
|
|||
intnum *intn = xmalloc(sizeof(intnum));
|
||||
wordptr bv;
|
||||
|
||||
intn->origsize = strlen(str);
|
||||
intn->origsize = (unsigned char)strlen(str);
|
||||
|
||||
if(intn->origsize > BITVECT_ALLOC_SIZE)
|
||||
Warning(_("Numeric constant too large for internal format"));
|
||||
|
|
@ -140,6 +140,7 @@ intnum_new_hex(char *str)
|
|||
return intn;
|
||||
}
|
||||
|
||||
/*@-usedef -compdef -uniondef@*/
|
||||
intnum *
|
||||
intnum_new_charconst_nasm(const char *str)
|
||||
{
|
||||
|
|
@ -157,18 +158,22 @@ intnum_new_charconst_nasm(const char *str)
|
|||
case 4:
|
||||
intn->val.ul |= (unsigned long)str[3];
|
||||
intn->val.ul <<= 8;
|
||||
/*@fallthrough@*/
|
||||
case 3:
|
||||
intn->val.ul |= (unsigned long)str[2];
|
||||
intn->val.ul <<= 8;
|
||||
/*@fallthrough@*/
|
||||
case 2:
|
||||
intn->val.ul |= (unsigned long)str[1];
|
||||
intn->val.ul <<= 8;
|
||||
/*@fallthrough@*/
|
||||
case 1:
|
||||
intn->val.ul |= (unsigned long)str[0];
|
||||
}
|
||||
|
||||
return intn;
|
||||
}
|
||||
/*@=usedef =compdef =uniondef@*/
|
||||
|
||||
intnum *
|
||||
intnum_new_int(unsigned long i)
|
||||
|
|
@ -209,11 +214,12 @@ intnum_delete(intnum *intn)
|
|||
xfree(intn);
|
||||
}
|
||||
|
||||
/*@-nullderef -nullpass -branchstate@*/
|
||||
void
|
||||
intnum_calc(intnum *acc, ExprOp op, intnum *operand)
|
||||
{
|
||||
wordptr result = (wordptr)NULL, op1 = (wordptr)NULL, op2 = (wordptr)NULL;
|
||||
wordptr spare;
|
||||
wordptr spare = (wordptr)NULL;
|
||||
boolean carry;
|
||||
|
||||
/* upsize to bitvector op if one of two parameters is bitvector already.
|
||||
|
|
@ -326,7 +332,7 @@ intnum_calc(intnum *acc, ExprOp op, intnum *operand)
|
|||
if (result) {
|
||||
if (operand->type == INTNUM_UL) {
|
||||
BitVector_Copy(result, op1);
|
||||
BitVector_Move_Left(result, operand->val.ul);
|
||||
BitVector_Move_Left(result, (N_int)operand->val.ul);
|
||||
} else /* don't even bother, just zero result */
|
||||
BitVector_Empty(result);
|
||||
} else
|
||||
|
|
@ -336,7 +342,7 @@ intnum_calc(intnum *acc, ExprOp op, intnum *operand)
|
|||
if (result) {
|
||||
if (operand->type == INTNUM_UL) {
|
||||
BitVector_Copy(result, op1);
|
||||
BitVector_Move_Right(result, operand->val.ul);
|
||||
BitVector_Move_Right(result, (N_int)operand->val.ul);
|
||||
} else /* don't even bother, just zero result */
|
||||
BitVector_Empty(result);
|
||||
} else
|
||||
|
|
@ -441,6 +447,7 @@ intnum_calc(intnum *acc, ExprOp op, intnum *operand)
|
|||
}
|
||||
}
|
||||
}
|
||||
/*@=nullderef =nullpass =branchstate@*/
|
||||
|
||||
int
|
||||
intnum_is_zero(intnum *intn)
|
||||
|
|
@ -459,7 +466,7 @@ intnum_is_pos1(intnum *intn)
|
|||
int
|
||||
intnum_is_neg1(intnum *intn)
|
||||
{
|
||||
return ((intn->type == INTNUM_UL && intn->val.ul == -1) ||
|
||||
return ((intn->type == INTNUM_UL && (long)intn->val.ul == -1) ||
|
||||
(intn->type == INTNUM_BV && BitVector_is_full(intn->val.bv)));
|
||||
}
|
||||
|
||||
|
|
@ -473,6 +480,7 @@ intnum_get_uint(const intnum *intn)
|
|||
return BitVector_Chunk_Read(intn->val.bv, 32, 0);
|
||||
default:
|
||||
InternalError(_("unknown intnum type"));
|
||||
/*@notreached@*/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -497,9 +505,10 @@ intnum_get_int(const intnum *intn)
|
|||
BitVector_Destroy(abs_bv);
|
||||
return retval;
|
||||
} else
|
||||
return BitVector_Chunk_Read(intn->val.bv, 32, 0);
|
||||
return (long)BitVector_Chunk_Read(intn->val.bv, 32, 0);
|
||||
default:
|
||||
InternalError(_("unknown intnum type"));
|
||||
/*@notreached@*/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -522,7 +531,7 @@ intnum_get_sized(const intnum *intn, unsigned char *ptr, size_t size)
|
|||
break;
|
||||
case INTNUM_BV:
|
||||
buf = BitVector_Block_Read(intn->val.bv, &len);
|
||||
if (len < size)
|
||||
if (len < (unsigned int)size)
|
||||
InternalError(_("Invalid size specified (too large)"));
|
||||
memcpy(ptr, buf, size);
|
||||
xfree(buf);
|
||||
|
|
@ -571,7 +580,6 @@ intnum_check_size(const intnum *intn, size_t size, int is_signed)
|
|||
return retval;
|
||||
} else
|
||||
return (Set_Max(intn->val.bv) < size*8);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (intn->type) {
|
||||
|
|
@ -592,7 +600,6 @@ intnum_check_size(const intnum *intn, size_t size, int is_signed)
|
|||
return 1;
|
||||
else
|
||||
return (Set_Max(intn->val.bv) < size*8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -609,7 +616,7 @@ intnum_print(const intnum *intn)
|
|||
break;
|
||||
case INTNUM_BV:
|
||||
s = BitVector_to_Hex(intn->val.bv);
|
||||
printf("0x%s/%u", s, (unsigned int)intn->origsize);
|
||||
printf("0x%s/%u", (char *)s, (unsigned int)intn->origsize);
|
||||
xfree(s);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,15 +22,15 @@
|
|||
#ifndef YASM_INTNUM_H
|
||||
#define YASM_INTNUM_H
|
||||
|
||||
intnum *intnum_new_dec(char *str);
|
||||
intnum *intnum_new_bin(char *str);
|
||||
intnum *intnum_new_oct(char *str);
|
||||
intnum *intnum_new_hex(char *str);
|
||||
/*@only@*/ intnum *intnum_new_dec(char *str);
|
||||
/*@only@*/ intnum *intnum_new_bin(char *str);
|
||||
/*@only@*/ intnum *intnum_new_oct(char *str);
|
||||
/*@only@*/ intnum *intnum_new_hex(char *str);
|
||||
/* convert character constant to integer value, using NASM rules */
|
||||
intnum *intnum_new_charconst_nasm(const char *str);
|
||||
intnum *intnum_new_int(unsigned long i);
|
||||
intnum *intnum_copy(const intnum *intn);
|
||||
void intnum_delete(intnum *intn);
|
||||
/*@only@*/ intnum *intnum_new_charconst_nasm(const char *str);
|
||||
/*@only@*/ intnum *intnum_new_int(unsigned long i);
|
||||
/*@only@*/ intnum *intnum_copy(const intnum *intn);
|
||||
void intnum_delete(/*@only@*/ intnum *intn);
|
||||
|
||||
/* calculation function: acc = acc op operand */
|
||||
void intnum_calc(intnum *acc, ExprOp op, intnum *operand);
|
||||
|
|
|
|||
|
|
@ -20,30 +20,32 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "ternary.h"
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
|
||||
const char *in_filename = (const char *)NULL;
|
||||
/*@null@*/ /*@dependent@*/ const char *in_filename = (const char *)NULL;
|
||||
unsigned int line_number = 1;
|
||||
unsigned int asm_options = 0;
|
||||
|
||||
static ternary_tree filename_table = (ternary_tree)NULL;
|
||||
static /*@only@*/ /*@null@*/ ternary_tree filename_table = (ternary_tree)NULL;
|
||||
|
||||
void
|
||||
switch_filename(const char *filename)
|
||||
{
|
||||
char *copy = xstrdup(filename);
|
||||
in_filename = ternary_insert(&filename_table, filename, copy, 0);
|
||||
/*@-branchstate@*/
|
||||
if (in_filename != copy)
|
||||
xfree(copy);
|
||||
/*@=branchstate@*/
|
||||
}
|
||||
|
||||
static void
|
||||
filename_delete_one(void *d)
|
||||
filename_delete_one(/*@only@*/ void *d)
|
||||
{
|
||||
xfree(d);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#ifndef YASM_GLOBALS_H
|
||||
#define YASM_GLOBALS_H
|
||||
|
||||
extern const char *in_filename;
|
||||
/*@null@*/ /*@dependent@*/ extern const char *in_filename;
|
||||
extern unsigned int line_number;
|
||||
extern unsigned int asm_options;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ struct parser {
|
|||
preproc **preprocs;
|
||||
|
||||
/* Current preprocessor (set to the default at compile time) */
|
||||
preproc *current_pp;
|
||||
/*@dependent@*/ preproc *current_pp;
|
||||
|
||||
/* Main entrance point for the parser.
|
||||
*
|
||||
|
|
@ -60,7 +60,7 @@ struct parser {
|
|||
/* Sets current_pp within p by searching the preprocs list for a preproc
|
||||
* matching pp_keyword. Returns nonzero if no match was found.
|
||||
*/
|
||||
int parser_setpp(parser *p, const char *pp_keyword);
|
||||
int parser_setpp(/*@partial@*/ parser *p, const char *pp_keyword);
|
||||
|
||||
/* Lists preprocessors available for p. Calls printfunc with the name
|
||||
* and keyword of each available preprocessor.
|
||||
|
|
@ -70,7 +70,7 @@ void parser_listpp(parser *p,
|
|||
|
||||
/* Finds a parser based on its keyword. Returns NULL if no match was found.
|
||||
*/
|
||||
parser *find_parser(const char *keyword);
|
||||
/*@null@*/ parser *find_parser(const char *keyword);
|
||||
|
||||
/* Lists all available parsers. Calls printfunc with the name and keyword
|
||||
* of each available parser.
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ struct preproc {
|
|||
|
||||
/* Gets more preprocessed source code (up to max_size bytes) into buf.
|
||||
* Note that more than a single line may be returned in buf. */
|
||||
int (*input) (char *buf, int max_size);
|
||||
size_t (*input) (char *buf, size_t max_size);
|
||||
};
|
||||
|
||||
/* Available preprocessors */
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "globals.h"
|
||||
#include "errwarn.h"
|
||||
|
|
@ -32,7 +32,7 @@ RCSID("$IdPath$");
|
|||
|
||||
|
||||
struct section {
|
||||
STAILQ_ENTRY(section) link;
|
||||
/*@reldef@*/ STAILQ_ENTRY(section) link;
|
||||
|
||||
enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
|
||||
|
||||
|
|
@ -64,9 +64,12 @@ sections_initialize(sectionhead *headp, objfmt *of)
|
|||
s->name = xstrdup(of->default_section_name);
|
||||
bytecodes_initialize(&s->bc);
|
||||
|
||||
s->data.start = 0;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/*@-onlytrans@*/
|
||||
section *
|
||||
sections_switch(sectionhead *headp, objfmt *of, const char *name)
|
||||
{
|
||||
|
|
@ -102,8 +105,11 @@ sections_switch(sectionhead *headp, objfmt *of, const char *name)
|
|||
s->name = xstrdup(name);
|
||||
bytecodes_initialize(&s->bc);
|
||||
|
||||
s->data.start = 0;
|
||||
|
||||
return s;
|
||||
}
|
||||
/*@=onlytrans@*/
|
||||
|
||||
void
|
||||
sections_delete(sectionhead *headp)
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@
|
|||
|
||||
struct objfmt;
|
||||
|
||||
section *sections_initialize(sectionhead *headp, struct objfmt *of);
|
||||
/*@dependent@*/ section *sections_initialize(sectionhead *headp,
|
||||
struct objfmt *of);
|
||||
|
||||
section *sections_switch(sectionhead *headp, struct objfmt *of,
|
||||
const char *name);
|
||||
/*@dependent@*/ section *sections_switch(sectionhead *headp, struct objfmt *of,
|
||||
const char *name);
|
||||
|
||||
void sections_delete(sectionhead *headp);
|
||||
|
||||
|
|
@ -35,11 +36,11 @@ void sections_print(const sectionhead *headp);
|
|||
|
||||
void sections_parser_finalize(sectionhead *headp);
|
||||
|
||||
bytecodehead *section_get_bytecodes(section *sect);
|
||||
/*@dependent@*/ bytecodehead *section_get_bytecodes(section *sect);
|
||||
|
||||
const char *section_get_name(const section *sect);
|
||||
/*@observer@*/ const char *section_get_name(const section *sect);
|
||||
|
||||
void section_delete(section *sect);
|
||||
void section_delete(/*@only@*/ section *sect);
|
||||
|
||||
void section_print(const section *sect);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
|
||||
#ifdef USE_OUR_OWN_STRCASECMP
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
|
|
@ -48,6 +48,7 @@ static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93";
|
|||
*
|
||||
* If *stringp is NULL, strsep returns NULL.
|
||||
*/
|
||||
/*@-nullstate@*/
|
||||
char *
|
||||
strsep(char **stringp, const char *delim)
|
||||
{
|
||||
|
|
@ -74,3 +75,4 @@ strsep(char **stringp, const char *delim)
|
|||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
/*@=nullstate@*/
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "ternary.h"
|
||||
|
||||
|
|
@ -54,26 +54,22 @@ struct symrec {
|
|||
SymType type;
|
||||
SymStatus status;
|
||||
SymVisibility visibility;
|
||||
const char *filename; /* file and line */
|
||||
/*@dependent@*/ /*@null@*/ const char *filename; /* file and line */
|
||||
unsigned long line; /* symbol was first declared or used on */
|
||||
union {
|
||||
expr *expn; /* equ value */
|
||||
struct label_s { /* bytecode immediately preceding a label */
|
||||
section *sect;
|
||||
bytecode *bc;
|
||||
/*@dependent@*/ section *sect;
|
||||
/*@dependent@*/ /*@null@*/ bytecode *bc;
|
||||
} label;
|
||||
} value;
|
||||
};
|
||||
|
||||
/* private functions */
|
||||
static symrec *symrec_get_or_new(const char *name, int in_table);
|
||||
static symrec *symrec_define(const char *name, SymType type, int in_table);
|
||||
|
||||
/* The symbol table: a ternary tree. */
|
||||
static ternary_tree sym_table = (ternary_tree)NULL;
|
||||
static /*@only@*/ /*@null@*/ ternary_tree sym_table = (ternary_tree)NULL;
|
||||
|
||||
/* create a new symrec */
|
||||
static symrec *
|
||||
static /*@partial@*/ /*@dependent@*/ symrec *
|
||||
symrec_get_or_new(const char *name, int in_table)
|
||||
{
|
||||
symrec *rec, *rec2;
|
||||
|
|
@ -96,7 +92,9 @@ symrec_get_or_new(const char *name, int in_table)
|
|||
rec->line = line_number;
|
||||
rec->visibility = SYM_LOCAL;
|
||||
|
||||
/*@-freshtrans -mustfree@*/
|
||||
return rec;
|
||||
/*@=freshtrans =mustfree@*/
|
||||
}
|
||||
|
||||
/* Call a function with each symrec. Stops early if 0 returned by func.
|
||||
|
|
@ -116,7 +114,7 @@ symrec_use(const char *name)
|
|||
return rec;
|
||||
}
|
||||
|
||||
static symrec *
|
||||
static /*@dependent@*/ symrec *
|
||||
symrec_define(const char *name, SymType type, int in_table)
|
||||
{
|
||||
symrec *rec = symrec_get_or_new(name, in_table);
|
||||
|
|
@ -252,7 +250,7 @@ symrec_parser_finalize(void)
|
|||
}
|
||||
|
||||
static void
|
||||
symrec_delete_one(void *d)
|
||||
symrec_delete_one(/*@only@*/ void *d)
|
||||
{
|
||||
symrec *sym = d;
|
||||
xfree(sym->name);
|
||||
|
|
@ -323,5 +321,6 @@ symrec_print(const symrec *sym)
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
printf("Filename=\"%s\" Line Number=%lu\n", sym->filename, sym->line);
|
||||
printf("Filename=\"%s\" Line Number=%lu\n",
|
||||
sym->filename?sym->filename:"(NULL)", sym->line);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,12 +30,15 @@ typedef enum {
|
|||
SYM_EXTERN = 1 << 2 /* if it's declared EXTERN */
|
||||
} SymVisibility;
|
||||
|
||||
symrec *symrec_use(const char *name);
|
||||
symrec *symrec_define_equ(const char *name, expr *e);
|
||||
/*@dependent@*/ symrec *symrec_use(const char *name);
|
||||
/*@dependent@*/ symrec *symrec_define_equ(const char *name,
|
||||
/*@keep@*/ expr *e);
|
||||
/* in_table specifies if the label should be inserted into the symbol table. */
|
||||
symrec *symrec_define_label(const char *name, section *sect, bytecode *precbc,
|
||||
int in_table);
|
||||
symrec *symrec_declare(const char *name, SymVisibility vis);
|
||||
/*@dependent@*/ symrec *symrec_define_label(const char *name,
|
||||
/*@dependent@*/ section *sect,
|
||||
/*@dependent@*/ /*@null@*/
|
||||
bytecode *precbc, int in_table);
|
||||
/*@dependent@*/ symrec *symrec_declare(const char *name, SymVisibility vis);
|
||||
|
||||
/* Get the numeric 32-bit value of a symbol if possible.
|
||||
* Return value is IF POSSIBLE, not the value.
|
||||
|
|
@ -45,10 +48,10 @@ symrec *symrec_declare(const char *name, SymVisibility vis);
|
|||
int symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
|
||||
int resolve_label);
|
||||
|
||||
const char *symrec_get_name(const symrec *sym);
|
||||
/*@observer@*/ const char *symrec_get_name(const symrec *sym);
|
||||
SymVisibility symrec_get_visibility(const symrec *sym);
|
||||
|
||||
const expr *symrec_get_equ(const symrec *sym);
|
||||
/*@observer@*/ /*@null@*/ const expr *symrec_get_equ(const symrec *sym);
|
||||
|
||||
int /*@alt void@*/ symrec_foreach(int (*func) (symrec *sym));
|
||||
|
||||
|
|
|
|||
|
|
@ -43,13 +43,13 @@
|
|||
#endif
|
||||
#define _(String) gettext(String)
|
||||
|
||||
#if !defined(HAVE_MERGESORT)
|
||||
#if !defined(HAVE_MERGESORT) || defined(lint)
|
||||
int mergesort(void *base, size_t nmemb, size_t size,
|
||||
int (*compar)(const void *, const void *));
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRSEP) || defined(HAVE_GNU_C_LIBRARY)
|
||||
char *strsep(char **stringp, const char *delim);
|
||||
#if !defined(HAVE_STRSEP) || defined(HAVE_GNU_C_LIBRARY) || defined(lint)
|
||||
/*@null@*/ char *strsep(char **stringp, const char *delim);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCASECMP
|
||||
|
|
@ -64,12 +64,12 @@ char *strsep(char **stringp, const char *delim);
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_OUR_OWN_STRCASECMP) || defined(HAVE_GNU_C_LIBRARY)
|
||||
#if defined(USE_OUR_OWN_STRCASECMP) || defined(HAVE_GNU_C_LIBRARY) || defined(lint)
|
||||
int strcasecmp(const char *s1, const char *s2);
|
||||
int strncasecmp(const char *s1, const char *s2, size_t n);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_TOASCII) || defined(HAVE_GNU_C_LIBRARY)
|
||||
#if !defined(HAVE_TOASCII) || defined(HAVE_GNU_C_LIBRARY) || defined(lint)
|
||||
# define toascii(c) ((c) & 0x7F)
|
||||
#endif
|
||||
|
||||
|
|
@ -104,10 +104,10 @@ int strncasecmp(const char *s1, const char *s2, size_t n);
|
|||
/*@only@*/ char *xstrdup(const char *str);
|
||||
|
||||
/* Error-checking memory allocation routines in xmalloc.c. */
|
||||
/*@only@*/ void *xmalloc(size_t size);
|
||||
/*@only@*/ void *xcalloc(size_t nelem, size_t elsize);
|
||||
void *xrealloc(void *oldmem, size_t size);
|
||||
void xfree(/*@only@*/ void *p);
|
||||
/*@only@*/ /*@out@*/ void *xmalloc(size_t size);
|
||||
/*@only@*/ /*@out@*/ void *xcalloc(size_t nelem, size_t elsize);
|
||||
/*@out@*/ void *xrealloc(/*@returned@*/ /*@null@*/ void *oldmem, size_t size);
|
||||
void xfree(/*@only@*/ /*@out@*/ /*@null@*/ void *p);
|
||||
#endif
|
||||
|
||||
#include "coretype.h"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "bytecode.h"
|
||||
#include "arch.h"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "errwarn.h"
|
||||
#include "intnum.h"
|
||||
|
|
@ -34,13 +34,14 @@ RCSID("$IdPath$");
|
|||
#include "bc-int.h"
|
||||
|
||||
|
||||
/*@-compmempass -mustfree@*/
|
||||
bytecode *
|
||||
x86_bc_new_insn(x86_new_insn_data *d)
|
||||
{
|
||||
bytecode *bc;
|
||||
x86_insn *insn;
|
||||
|
||||
bc = bc_new_common(X86_BC_INSN, sizeof(x86_insn));
|
||||
bc = bc_new_common((bytecode_type)X86_BC_INSN, sizeof(x86_insn));
|
||||
insn = bc_get_data(bc);
|
||||
|
||||
insn->ea = d->ea;
|
||||
|
|
@ -70,14 +71,16 @@ x86_bc_new_insn(x86_new_insn_data *d)
|
|||
|
||||
return bc;
|
||||
}
|
||||
/*@=compmempass =mustfree@*/
|
||||
|
||||
/*@-compmempass -mustfree@*/
|
||||
bytecode *
|
||||
x86_bc_new_jmprel(x86_new_jmprel_data *d)
|
||||
{
|
||||
bytecode *bc;
|
||||
x86_jmprel *jmprel;
|
||||
|
||||
bc = bc_new_common(X86_BC_JMPREL, sizeof(x86_jmprel));
|
||||
bc = bc_new_common((bytecode_type)X86_BC_JMPREL, sizeof(x86_jmprel));
|
||||
jmprel = bc_get_data(bc);
|
||||
|
||||
jmprel->target = d->target->val;
|
||||
|
|
@ -106,6 +109,7 @@ x86_bc_new_jmprel(x86_new_jmprel_data *d)
|
|||
|
||||
return bc;
|
||||
}
|
||||
/*@=compmempass =mustfree@*/
|
||||
|
||||
void
|
||||
x86_ea_set_segment(effaddr *ea, unsigned char segment)
|
||||
|
|
@ -124,7 +128,7 @@ x86_ea_set_segment(effaddr *ea, unsigned char segment)
|
|||
}
|
||||
|
||||
effaddr *
|
||||
x86_ea_new_reg(unsigned long reg)
|
||||
x86_ea_new_reg(unsigned char reg)
|
||||
{
|
||||
effaddr *ea = xmalloc(sizeof(effaddr)+sizeof(x86_effaddr_data));
|
||||
x86_effaddr_data *ead = ea_get_data(ea);
|
||||
|
|
@ -162,6 +166,7 @@ x86_ea_new_expr(expr *e)
|
|||
return ea;
|
||||
}
|
||||
|
||||
/*@-compmempass@*/
|
||||
effaddr *
|
||||
x86_ea_new_imm(immval *imm, unsigned char im_len)
|
||||
{
|
||||
|
|
@ -180,6 +185,7 @@ x86_ea_new_imm(immval *imm, unsigned char im_len)
|
|||
|
||||
return ea;
|
||||
}
|
||||
/*@=compmempass@*/
|
||||
|
||||
effaddr *
|
||||
x86_bc_insn_get_ea(bytecode *bc)
|
||||
|
|
@ -189,7 +195,7 @@ x86_bc_insn_get_ea(bytecode *bc)
|
|||
if (!bc)
|
||||
return NULL;
|
||||
|
||||
if (bc->type != X86_BC_INSN)
|
||||
if ((x86_bytecode_type)bc->type != X86_BC_INSN)
|
||||
InternalError(_("Trying to get EA of non-instruction"));
|
||||
|
||||
return insn->ea;
|
||||
|
|
@ -204,7 +210,7 @@ x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
switch (bc->type) {
|
||||
switch ((x86_bytecode_type)bc->type) {
|
||||
case X86_BC_INSN:
|
||||
insn = bc_get_data(bc);
|
||||
insn->opersize = opersize;
|
||||
|
|
@ -215,7 +221,6 @@ x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize)
|
|||
break;
|
||||
default:
|
||||
InternalError(_("OperSize override applied to non-instruction"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +233,7 @@ x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
switch (bc->type) {
|
||||
switch ((x86_bytecode_type)bc->type) {
|
||||
case X86_BC_INSN:
|
||||
insn = bc_get_data(bc);
|
||||
insn->addrsize = addrsize;
|
||||
|
|
@ -239,7 +244,6 @@ x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize)
|
|||
break;
|
||||
default:
|
||||
InternalError(_("AddrSize override applied to non-instruction"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -253,7 +257,7 @@ x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
switch (bc->type) {
|
||||
switch ((x86_bytecode_type)bc->type) {
|
||||
case X86_BC_INSN:
|
||||
insn = bc_get_data(bc);
|
||||
lockrep_pre = &insn->lockrep_pre;
|
||||
|
|
@ -264,7 +268,6 @@ x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix)
|
|||
break;
|
||||
default:
|
||||
InternalError(_("LockRep prefix applied to non-instruction"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (*lockrep_pre != 0)
|
||||
|
|
@ -281,7 +284,7 @@ x86_bc_insn_set_shift_flag(bytecode *bc)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
if (bc->type != X86_BC_INSN)
|
||||
if ((x86_bytecode_type)bc->type != X86_BC_INSN)
|
||||
InternalError(_("Attempted to set shift flag on non-instruction"));
|
||||
|
||||
insn = bc_get_data(bc);
|
||||
|
|
@ -367,7 +370,10 @@ x86_bc_print(const bytecode *bc)
|
|||
printf(" (nil)\n");
|
||||
else {
|
||||
printf("\n Val=");
|
||||
expr_print(insn->imm->val);
|
||||
if (insn->imm->val)
|
||||
expr_print(insn->imm->val);
|
||||
else
|
||||
printf("(nil-SHOULDN'T HAPPEN)");
|
||||
printf("\n");
|
||||
printf(" Len=%u, IsNeg=%u\n",
|
||||
(unsigned int)insn->imm->len,
|
||||
|
|
@ -471,24 +477,28 @@ x86_bc_parser_finalize_insn(x86_insn *insn)
|
|||
|
||||
if (imm->val) {
|
||||
expr_expand_equ(imm->val);
|
||||
expr_simplify(imm->val);
|
||||
imm->val = expr_simplify(imm->val);
|
||||
}
|
||||
/* TODO: check imm f_len vs. len? */
|
||||
|
||||
/* Handle shift_op special-casing */
|
||||
/*@-nullstate@*/
|
||||
if (insn->shift_op && (num = expr_get_intnum(&imm->val))) {
|
||||
if (intnum_get_uint(num) == 1) {
|
||||
/* Use ,1 form: first copy ,1 opcode. */
|
||||
insn->opcode[0] = insn->opcode[1];
|
||||
/* Delete ModRM, as it's no longer needed */
|
||||
xfree(ea);
|
||||
insn->ea = (effaddr *)NULL;
|
||||
/* Delete Imm, as it's not needed */
|
||||
expr_delete(imm->val);
|
||||
xfree(imm);
|
||||
insn->imm = (immval *)NULL;
|
||||
/*@=nullstate@*/
|
||||
if (num) {
|
||||
if (intnum_get_uint(num) == 1) {
|
||||
/* Use ,1 form: first copy ,1 opcode. */
|
||||
insn->opcode[0] = insn->opcode[1];
|
||||
/* Delete ModRM, as it's no longer needed */
|
||||
xfree(ea);
|
||||
insn->ea = (effaddr *)NULL;
|
||||
/* Delete Imm, as it's not needed */
|
||||
expr_delete(imm->val);
|
||||
xfree(imm);
|
||||
insn->imm = (immval *)NULL;
|
||||
}
|
||||
insn->shift_op = 0;
|
||||
}
|
||||
insn->shift_op = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,11 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#include "bitvect.h"
|
||||
|
||||
|
|
@ -41,8 +45,8 @@ RCSID("$IdPath$");
|
|||
/* Only works if ei->type == EXPR_REG (doesn't check).
|
||||
* Overwrites ei with intnum of 0 (to eliminate regs from the final expr).
|
||||
*/
|
||||
static int *
|
||||
x86_expr_checkea_get_reg32(ExprItem *ei, void *d)
|
||||
static /*@null@*/ /*@dependent@*/ int *
|
||||
x86_expr_checkea_get_reg32(ExprItem *ei, /*returned*/ void *d)
|
||||
{
|
||||
int *data = d;
|
||||
int *ret;
|
||||
|
|
@ -68,12 +72,14 @@ typedef struct x86_checkea_reg16_data {
|
|||
/* Only works if ei->type == EXPR_REG (doesn't check).
|
||||
* Overwrites ei with intnum of 0 (to eliminate regs from the final expr).
|
||||
*/
|
||||
static int *
|
||||
static /*@null@*/ int *
|
||||
x86_expr_checkea_get_reg16(ExprItem *ei, void *d)
|
||||
{
|
||||
x86_checkea_reg16_data *data = d;
|
||||
/* in order: ax,cx,dx,bx,sp,bp,si,di */
|
||||
/*@-nullassign@*/
|
||||
static int *reg16[8] = {0,0,0,0,0,0,0,0};
|
||||
/*@=nullassign@*/
|
||||
int *ret;
|
||||
|
||||
reg16[3] = &data->bx;
|
||||
|
|
@ -187,6 +193,7 @@ x86_expr_checkea_distcheck_reg(expr **ep)
|
|||
for (i=0; i<e->terms[havereg_expr].data.expn->numterms; i++) {
|
||||
/* Copy everything EXCEPT havereg_expr term into new expression */
|
||||
ne = expr_copy_except(e, havereg_expr);
|
||||
assert(ne != NULL);
|
||||
/* Copy reg expr term into uncopied (empty) term in new expn */
|
||||
ne->terms[havereg_expr] =
|
||||
e->terms[havereg_expr].data.expn->terms[i]; /* struct copy */
|
||||
|
|
@ -200,7 +207,9 @@ x86_expr_checkea_distcheck_reg(expr **ep)
|
|||
e->terms[havereg_expr].type = EXPR_NONE; /* don't delete it! */
|
||||
expr_delete(e); /* but everything else */
|
||||
e = ne;
|
||||
/*@-onlytrans@*/
|
||||
*ep = ne;
|
||||
/*@=onlytrans@*/
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
|
@ -217,15 +226,18 @@ x86_expr_checkea_distcheck_reg(expr **ep)
|
|||
* and 2 if all values successfully determined and saved in data.
|
||||
*/
|
||||
static int
|
||||
x86_expr_checkea_getregusage(expr **ep, int *indexreg, void *data,
|
||||
x86_expr_checkea_getregusage(expr **ep, /*@null@*/ int *indexreg, void *data,
|
||||
int *(*get_reg)(ExprItem *ei, void *d))
|
||||
{
|
||||
int i;
|
||||
int *reg;
|
||||
expr *e;
|
||||
|
||||
/*@-unqualifiedtrans@*/
|
||||
*ep = expr_xform_neg_tree(*ep);
|
||||
*ep = expr_level_tree(*ep, 1, indexreg == 0);
|
||||
/*@=unqualifiedtrans@*/
|
||||
assert(*ep != NULL);
|
||||
e = *ep;
|
||||
switch (x86_expr_checkea_distcheck_reg(ep)) {
|
||||
case 0:
|
||||
|
|
@ -259,7 +271,7 @@ x86_expr_checkea_getregusage(expr **ep, int *indexreg, void *data,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
/*@fallthrough@*/
|
||||
case EXPR_IDENT:
|
||||
/* Check each term for register (and possible multiplier). */
|
||||
for (i=0; i<e->numterms; i++) {
|
||||
|
|
@ -323,10 +335,11 @@ x86_expr_checkea_getregusage(expr **ep, int *indexreg, void *data,
|
|||
* noreg=1 if the *ModRM byte* has no registers used.
|
||||
* isbpreg=1 if BP/EBP is the *only* register used within the *ModRM byte*.
|
||||
*/
|
||||
/*@-nullstate@*/
|
||||
static int
|
||||
x86_checkea_calc_displen(expr **ep, int wordsize, int noreg, int isbpreg,
|
||||
unsigned char *displen, unsigned char *modrm,
|
||||
unsigned char *v_modrm)
|
||||
x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg,
|
||||
int isbpreg, unsigned char *displen,
|
||||
unsigned char *modrm, unsigned char *v_modrm)
|
||||
{
|
||||
expr *e = *ep;
|
||||
const intnum *intn;
|
||||
|
|
@ -362,7 +375,7 @@ x86_checkea_calc_displen(expr **ep, int wordsize, int noreg, int isbpreg,
|
|||
/* make sure the displacement will fit in 16/32 bits if unsigned,
|
||||
* and 8 bits if signed.
|
||||
*/
|
||||
if (!intnum_check_size(intn, wordsize, 0) &&
|
||||
if (!intnum_check_size(intn, (size_t)wordsize, 0) &&
|
||||
!intnum_check_size(intn, 1, 1)) {
|
||||
ErrorAt(e->filename, e->line, _("invalid effective address"));
|
||||
return 0;
|
||||
|
|
@ -440,6 +453,7 @@ x86_checkea_calc_displen(expr **ep, int wordsize, int noreg, int isbpreg,
|
|||
|
||||
return 1;
|
||||
}
|
||||
/*@=nullstate@*/
|
||||
|
||||
static int
|
||||
x86_expr_checkea_getregsize_callback(ExprItem *ei, void *d)
|
||||
|
|
@ -645,7 +659,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
|
|||
*sib |= 040;
|
||||
/* Any scale field is valid, just leave at 0. */
|
||||
else {
|
||||
*sib |= (indexreg & 7) << 3; /* &7 to sanity check */
|
||||
*sib |= ((unsigned int)indexreg & 7) << 3;
|
||||
/* Set scale field, 1 case -> 0, so don't bother. */
|
||||
switch (reg32mult[indexreg]) {
|
||||
case 2:
|
||||
|
|
|
|||
|
|
@ -40,9 +40,9 @@ typedef struct x86_effaddr_data {
|
|||
} x86_effaddr_data;
|
||||
|
||||
typedef struct x86_insn {
|
||||
effaddr *ea; /* effective address */
|
||||
/*@null@*/ effaddr *ea; /* effective address */
|
||||
|
||||
immval *imm; /* immediate or relative value */
|
||||
/*@null@*/ immval *imm; /* immediate or relative value */
|
||||
|
||||
unsigned char opcode[3]; /* opcode */
|
||||
unsigned char opcode_len;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "bytecode.h"
|
||||
#include "arch.h"
|
||||
|
|
|
|||
|
|
@ -42,12 +42,12 @@ typedef struct x86_targetval {
|
|||
x86_jmprel_opcode_sel op_sel;
|
||||
} x86_targetval;
|
||||
|
||||
void x86_ea_set_segment(effaddr *ea, unsigned char segment);
|
||||
effaddr *x86_ea_new_reg(unsigned long reg);
|
||||
void x86_ea_set_segment(/*@null@*/ effaddr *ea, unsigned char segment);
|
||||
effaddr *x86_ea_new_reg(unsigned char reg);
|
||||
effaddr *x86_ea_new_imm(immval *imm, unsigned char im_len);
|
||||
effaddr *x86_ea_new_expr(expr *e);
|
||||
effaddr *x86_ea_new_expr(/*@keep@*/ expr *e);
|
||||
|
||||
effaddr *x86_bc_insn_get_ea(bytecode *bc);
|
||||
/*@null@*/ effaddr *x86_bc_insn_get_ea(bytecode *bc);
|
||||
|
||||
void x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize);
|
||||
void x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize);
|
||||
|
|
@ -62,8 +62,8 @@ void x86_set_jmprel_opcode_sel(x86_jmprel_opcode_sel *old_sel,
|
|||
* function (it doesn't make a copy).
|
||||
*/
|
||||
typedef struct x86_new_insn_data {
|
||||
effaddr *ea;
|
||||
immval *imm;
|
||||
/*@keep@*/ /*@null@*/ effaddr *ea;
|
||||
/*@keep@*/ /*@null@*/ immval *imm;
|
||||
unsigned char opersize;
|
||||
unsigned char op_len;
|
||||
unsigned char op[3];
|
||||
|
|
@ -78,7 +78,7 @@ bytecode *x86_bc_new_insn(x86_new_insn_data *d);
|
|||
* Pass 0 for the opcode_len if that version of the opcode doesn't exist.
|
||||
*/
|
||||
typedef struct x86_new_jmprel_data {
|
||||
x86_targetval *target;
|
||||
/*@keep@*/ x86_targetval *target;
|
||||
unsigned char short_op_len;
|
||||
unsigned char short_op[3];
|
||||
unsigned char near_op_len;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "errwarn.h"
|
||||
#include "intnum.h"
|
||||
|
|
@ -34,13 +34,14 @@ RCSID("$IdPath$");
|
|||
#include "bc-int.h"
|
||||
|
||||
|
||||
/*@-compmempass -mustfree@*/
|
||||
bytecode *
|
||||
x86_bc_new_insn(x86_new_insn_data *d)
|
||||
{
|
||||
bytecode *bc;
|
||||
x86_insn *insn;
|
||||
|
||||
bc = bc_new_common(X86_BC_INSN, sizeof(x86_insn));
|
||||
bc = bc_new_common((bytecode_type)X86_BC_INSN, sizeof(x86_insn));
|
||||
insn = bc_get_data(bc);
|
||||
|
||||
insn->ea = d->ea;
|
||||
|
|
@ -70,14 +71,16 @@ x86_bc_new_insn(x86_new_insn_data *d)
|
|||
|
||||
return bc;
|
||||
}
|
||||
/*@=compmempass =mustfree@*/
|
||||
|
||||
/*@-compmempass -mustfree@*/
|
||||
bytecode *
|
||||
x86_bc_new_jmprel(x86_new_jmprel_data *d)
|
||||
{
|
||||
bytecode *bc;
|
||||
x86_jmprel *jmprel;
|
||||
|
||||
bc = bc_new_common(X86_BC_JMPREL, sizeof(x86_jmprel));
|
||||
bc = bc_new_common((bytecode_type)X86_BC_JMPREL, sizeof(x86_jmprel));
|
||||
jmprel = bc_get_data(bc);
|
||||
|
||||
jmprel->target = d->target->val;
|
||||
|
|
@ -106,6 +109,7 @@ x86_bc_new_jmprel(x86_new_jmprel_data *d)
|
|||
|
||||
return bc;
|
||||
}
|
||||
/*@=compmempass =mustfree@*/
|
||||
|
||||
void
|
||||
x86_ea_set_segment(effaddr *ea, unsigned char segment)
|
||||
|
|
@ -124,7 +128,7 @@ x86_ea_set_segment(effaddr *ea, unsigned char segment)
|
|||
}
|
||||
|
||||
effaddr *
|
||||
x86_ea_new_reg(unsigned long reg)
|
||||
x86_ea_new_reg(unsigned char reg)
|
||||
{
|
||||
effaddr *ea = xmalloc(sizeof(effaddr)+sizeof(x86_effaddr_data));
|
||||
x86_effaddr_data *ead = ea_get_data(ea);
|
||||
|
|
@ -162,6 +166,7 @@ x86_ea_new_expr(expr *e)
|
|||
return ea;
|
||||
}
|
||||
|
||||
/*@-compmempass@*/
|
||||
effaddr *
|
||||
x86_ea_new_imm(immval *imm, unsigned char im_len)
|
||||
{
|
||||
|
|
@ -180,6 +185,7 @@ x86_ea_new_imm(immval *imm, unsigned char im_len)
|
|||
|
||||
return ea;
|
||||
}
|
||||
/*@=compmempass@*/
|
||||
|
||||
effaddr *
|
||||
x86_bc_insn_get_ea(bytecode *bc)
|
||||
|
|
@ -189,7 +195,7 @@ x86_bc_insn_get_ea(bytecode *bc)
|
|||
if (!bc)
|
||||
return NULL;
|
||||
|
||||
if (bc->type != X86_BC_INSN)
|
||||
if ((x86_bytecode_type)bc->type != X86_BC_INSN)
|
||||
InternalError(_("Trying to get EA of non-instruction"));
|
||||
|
||||
return insn->ea;
|
||||
|
|
@ -204,7 +210,7 @@ x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
switch (bc->type) {
|
||||
switch ((x86_bytecode_type)bc->type) {
|
||||
case X86_BC_INSN:
|
||||
insn = bc_get_data(bc);
|
||||
insn->opersize = opersize;
|
||||
|
|
@ -215,7 +221,6 @@ x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize)
|
|||
break;
|
||||
default:
|
||||
InternalError(_("OperSize override applied to non-instruction"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +233,7 @@ x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
switch (bc->type) {
|
||||
switch ((x86_bytecode_type)bc->type) {
|
||||
case X86_BC_INSN:
|
||||
insn = bc_get_data(bc);
|
||||
insn->addrsize = addrsize;
|
||||
|
|
@ -239,7 +244,6 @@ x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize)
|
|||
break;
|
||||
default:
|
||||
InternalError(_("AddrSize override applied to non-instruction"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -253,7 +257,7 @@ x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
switch (bc->type) {
|
||||
switch ((x86_bytecode_type)bc->type) {
|
||||
case X86_BC_INSN:
|
||||
insn = bc_get_data(bc);
|
||||
lockrep_pre = &insn->lockrep_pre;
|
||||
|
|
@ -264,7 +268,6 @@ x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix)
|
|||
break;
|
||||
default:
|
||||
InternalError(_("LockRep prefix applied to non-instruction"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (*lockrep_pre != 0)
|
||||
|
|
@ -281,7 +284,7 @@ x86_bc_insn_set_shift_flag(bytecode *bc)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
if (bc->type != X86_BC_INSN)
|
||||
if ((x86_bytecode_type)bc->type != X86_BC_INSN)
|
||||
InternalError(_("Attempted to set shift flag on non-instruction"));
|
||||
|
||||
insn = bc_get_data(bc);
|
||||
|
|
@ -367,7 +370,10 @@ x86_bc_print(const bytecode *bc)
|
|||
printf(" (nil)\n");
|
||||
else {
|
||||
printf("\n Val=");
|
||||
expr_print(insn->imm->val);
|
||||
if (insn->imm->val)
|
||||
expr_print(insn->imm->val);
|
||||
else
|
||||
printf("(nil-SHOULDN'T HAPPEN)");
|
||||
printf("\n");
|
||||
printf(" Len=%u, IsNeg=%u\n",
|
||||
(unsigned int)insn->imm->len,
|
||||
|
|
@ -471,24 +477,28 @@ x86_bc_parser_finalize_insn(x86_insn *insn)
|
|||
|
||||
if (imm->val) {
|
||||
expr_expand_equ(imm->val);
|
||||
expr_simplify(imm->val);
|
||||
imm->val = expr_simplify(imm->val);
|
||||
}
|
||||
/* TODO: check imm f_len vs. len? */
|
||||
|
||||
/* Handle shift_op special-casing */
|
||||
/*@-nullstate@*/
|
||||
if (insn->shift_op && (num = expr_get_intnum(&imm->val))) {
|
||||
if (intnum_get_uint(num) == 1) {
|
||||
/* Use ,1 form: first copy ,1 opcode. */
|
||||
insn->opcode[0] = insn->opcode[1];
|
||||
/* Delete ModRM, as it's no longer needed */
|
||||
xfree(ea);
|
||||
insn->ea = (effaddr *)NULL;
|
||||
/* Delete Imm, as it's not needed */
|
||||
expr_delete(imm->val);
|
||||
xfree(imm);
|
||||
insn->imm = (immval *)NULL;
|
||||
/*@=nullstate@*/
|
||||
if (num) {
|
||||
if (intnum_get_uint(num) == 1) {
|
||||
/* Use ,1 form: first copy ,1 opcode. */
|
||||
insn->opcode[0] = insn->opcode[1];
|
||||
/* Delete ModRM, as it's no longer needed */
|
||||
xfree(ea);
|
||||
insn->ea = (effaddr *)NULL;
|
||||
/* Delete Imm, as it's not needed */
|
||||
expr_delete(imm->val);
|
||||
xfree(imm);
|
||||
insn->imm = (immval *)NULL;
|
||||
}
|
||||
insn->shift_op = 0;
|
||||
}
|
||||
insn->shift_op = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,11 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#include "bitvect.h"
|
||||
|
||||
|
|
@ -41,8 +45,8 @@ RCSID("$IdPath$");
|
|||
/* Only works if ei->type == EXPR_REG (doesn't check).
|
||||
* Overwrites ei with intnum of 0 (to eliminate regs from the final expr).
|
||||
*/
|
||||
static int *
|
||||
x86_expr_checkea_get_reg32(ExprItem *ei, void *d)
|
||||
static /*@null@*/ /*@dependent@*/ int *
|
||||
x86_expr_checkea_get_reg32(ExprItem *ei, /*returned*/ void *d)
|
||||
{
|
||||
int *data = d;
|
||||
int *ret;
|
||||
|
|
@ -68,12 +72,14 @@ typedef struct x86_checkea_reg16_data {
|
|||
/* Only works if ei->type == EXPR_REG (doesn't check).
|
||||
* Overwrites ei with intnum of 0 (to eliminate regs from the final expr).
|
||||
*/
|
||||
static int *
|
||||
static /*@null@*/ int *
|
||||
x86_expr_checkea_get_reg16(ExprItem *ei, void *d)
|
||||
{
|
||||
x86_checkea_reg16_data *data = d;
|
||||
/* in order: ax,cx,dx,bx,sp,bp,si,di */
|
||||
/*@-nullassign@*/
|
||||
static int *reg16[8] = {0,0,0,0,0,0,0,0};
|
||||
/*@=nullassign@*/
|
||||
int *ret;
|
||||
|
||||
reg16[3] = &data->bx;
|
||||
|
|
@ -187,6 +193,7 @@ x86_expr_checkea_distcheck_reg(expr **ep)
|
|||
for (i=0; i<e->terms[havereg_expr].data.expn->numterms; i++) {
|
||||
/* Copy everything EXCEPT havereg_expr term into new expression */
|
||||
ne = expr_copy_except(e, havereg_expr);
|
||||
assert(ne != NULL);
|
||||
/* Copy reg expr term into uncopied (empty) term in new expn */
|
||||
ne->terms[havereg_expr] =
|
||||
e->terms[havereg_expr].data.expn->terms[i]; /* struct copy */
|
||||
|
|
@ -200,7 +207,9 @@ x86_expr_checkea_distcheck_reg(expr **ep)
|
|||
e->terms[havereg_expr].type = EXPR_NONE; /* don't delete it! */
|
||||
expr_delete(e); /* but everything else */
|
||||
e = ne;
|
||||
/*@-onlytrans@*/
|
||||
*ep = ne;
|
||||
/*@=onlytrans@*/
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
|
@ -217,15 +226,18 @@ x86_expr_checkea_distcheck_reg(expr **ep)
|
|||
* and 2 if all values successfully determined and saved in data.
|
||||
*/
|
||||
static int
|
||||
x86_expr_checkea_getregusage(expr **ep, int *indexreg, void *data,
|
||||
x86_expr_checkea_getregusage(expr **ep, /*@null@*/ int *indexreg, void *data,
|
||||
int *(*get_reg)(ExprItem *ei, void *d))
|
||||
{
|
||||
int i;
|
||||
int *reg;
|
||||
expr *e;
|
||||
|
||||
/*@-unqualifiedtrans@*/
|
||||
*ep = expr_xform_neg_tree(*ep);
|
||||
*ep = expr_level_tree(*ep, 1, indexreg == 0);
|
||||
/*@=unqualifiedtrans@*/
|
||||
assert(*ep != NULL);
|
||||
e = *ep;
|
||||
switch (x86_expr_checkea_distcheck_reg(ep)) {
|
||||
case 0:
|
||||
|
|
@ -259,7 +271,7 @@ x86_expr_checkea_getregusage(expr **ep, int *indexreg, void *data,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
/*@fallthrough@*/
|
||||
case EXPR_IDENT:
|
||||
/* Check each term for register (and possible multiplier). */
|
||||
for (i=0; i<e->numterms; i++) {
|
||||
|
|
@ -323,10 +335,11 @@ x86_expr_checkea_getregusage(expr **ep, int *indexreg, void *data,
|
|||
* noreg=1 if the *ModRM byte* has no registers used.
|
||||
* isbpreg=1 if BP/EBP is the *only* register used within the *ModRM byte*.
|
||||
*/
|
||||
/*@-nullstate@*/
|
||||
static int
|
||||
x86_checkea_calc_displen(expr **ep, int wordsize, int noreg, int isbpreg,
|
||||
unsigned char *displen, unsigned char *modrm,
|
||||
unsigned char *v_modrm)
|
||||
x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg,
|
||||
int isbpreg, unsigned char *displen,
|
||||
unsigned char *modrm, unsigned char *v_modrm)
|
||||
{
|
||||
expr *e = *ep;
|
||||
const intnum *intn;
|
||||
|
|
@ -362,7 +375,7 @@ x86_checkea_calc_displen(expr **ep, int wordsize, int noreg, int isbpreg,
|
|||
/* make sure the displacement will fit in 16/32 bits if unsigned,
|
||||
* and 8 bits if signed.
|
||||
*/
|
||||
if (!intnum_check_size(intn, wordsize, 0) &&
|
||||
if (!intnum_check_size(intn, (size_t)wordsize, 0) &&
|
||||
!intnum_check_size(intn, 1, 1)) {
|
||||
ErrorAt(e->filename, e->line, _("invalid effective address"));
|
||||
return 0;
|
||||
|
|
@ -440,6 +453,7 @@ x86_checkea_calc_displen(expr **ep, int wordsize, int noreg, int isbpreg,
|
|||
|
||||
return 1;
|
||||
}
|
||||
/*@=nullstate@*/
|
||||
|
||||
static int
|
||||
x86_expr_checkea_getregsize_callback(ExprItem *ei, void *d)
|
||||
|
|
@ -645,7 +659,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
|
|||
*sib |= 040;
|
||||
/* Any scale field is valid, just leave at 0. */
|
||||
else {
|
||||
*sib |= (indexreg & 7) << 3; /* &7 to sanity check */
|
||||
*sib |= ((unsigned int)indexreg & 7) << 3;
|
||||
/* Set scale field, 1 case -> 0, so don't bother. */
|
||||
switch (reg32mult[indexreg]) {
|
||||
case 2:
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "objfmt.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "objfmt.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -54,12 +54,13 @@ extern sectionhead nasm_parser_sections;
|
|||
extern section *nasm_parser_cur_section;
|
||||
extern char *nasm_parser_locallabel_base;
|
||||
|
||||
static bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
|
||||
static /*@null@*/ bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
|
||||
static bytecode *nasm_parser_temp_bc;
|
||||
|
||||
/* additional data declarations (dynamically generated) */
|
||||
/* @DATADECLS@ */
|
||||
|
||||
/*@-usedef -nullassign -memtrans -usereleased -compdef -mustfree@*/
|
||||
%}
|
||||
|
||||
%union {
|
||||
|
|
@ -539,6 +540,7 @@ instr: instrbase
|
|||
/* @INSTRUCTIONS@ */
|
||||
|
||||
%%
|
||||
/*@=usedef =nullassign =memtrans =usereleased =compdef =mustfree@*/
|
||||
|
||||
static void
|
||||
nasm_parser_directive(const char *name, const char *val)
|
||||
|
|
|
|||
|
|
@ -537,6 +537,7 @@ sub output_yacc ($@)
|
|||
for (my $i=0; $i < @opcodes; ++$i)
|
||||
{
|
||||
$opcodes[$i] =~ s/([0-9A-Fa-f]{2})/0x$1/g;
|
||||
$opcodes[$i] =~ s/(0x[0-9A-Fa-f]{2}.*\+)/(unsigned char)$1/g;
|
||||
# don't match $0.\d in the following rule.
|
||||
$opcodes[$i] =~ s/\$(\d+)(?!\.)/"\$".($1*2)/eg;
|
||||
push @args, "short_op[$i]=$opcodes[$i];";
|
||||
|
|
@ -565,6 +566,7 @@ sub output_yacc ($@)
|
|||
for (my $i=0; $i < @opcodes; ++$i)
|
||||
{
|
||||
$opcodes[$i] =~ s/([0-9A-Fa-f]{2})/0x$1/g;
|
||||
$opcodes[$i] =~ s/(0x[0-9A-Fa-f]{2}.*\+)/(unsigned char)$1/g;
|
||||
# don't match $0.\d in the following rule.
|
||||
$opcodes[$i] =~ s/\$(\d+)(?!\.)/"\$".($1*2)/eg;
|
||||
push @args, "near_op[$i]=$opcodes[$i];";
|
||||
|
|
@ -586,6 +588,12 @@ sub output_yacc ($@)
|
|||
# and add the data structure reference
|
||||
s/^/$datastructname./g foreach (@args);
|
||||
|
||||
if ($args[0] =~ m/\&\$/)
|
||||
{
|
||||
$args[0] = '/*@-immediatetrans@*/' . $args[0] .
|
||||
'/*@=immediatetrans@*/';
|
||||
}
|
||||
|
||||
# generate the grammar
|
||||
print GRAMMAR action ($rule, $tokens, $func, \@args, $count++);
|
||||
}
|
||||
|
|
@ -625,6 +633,7 @@ sub output_yacc ($@)
|
|||
for (my $i=0; $i < @opcodes; ++$i)
|
||||
{
|
||||
$opcodes[$i] =~ s/([0-9A-Fa-f]{2})/0x$1/g;
|
||||
$opcodes[$i] =~ s/(0x[0-9A-Fa-f]{2}.*\+)/(unsigned char)$1/g;
|
||||
# don't match $0.\d in the following rule.
|
||||
$opcodes[$i] =~ s/\$(\d+)(?!\.)/"\$".($1*2+$to)/eg;
|
||||
push @args, "op[$i]=$opcodes[$i];";
|
||||
|
|
@ -661,7 +670,7 @@ sub output_yacc ($@)
|
|||
$imm =~ s[^([0-9A-Fa-f]+),]
|
||||
[imm_new_int(0x$1),];
|
||||
$imm =~ s[^\$0.(\d+),]
|
||||
[imm_new_int(\$1\[$1\]),];
|
||||
[imm_new_int((unsigned long)\$1\[$1\]),];
|
||||
|
||||
# divide the second, and only the second, by 8 bits/byte
|
||||
$imm =~ s#(,\s*)(\d+)(s)?#$1 . ($2/8)#eg;
|
||||
|
|
|
|||
|
|
@ -54,12 +54,13 @@ extern sectionhead nasm_parser_sections;
|
|||
extern section *nasm_parser_cur_section;
|
||||
extern char *nasm_parser_locallabel_base;
|
||||
|
||||
static bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
|
||||
static /*@null@*/ bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
|
||||
static bytecode *nasm_parser_temp_bc;
|
||||
|
||||
/* additional data declarations (dynamically generated) */
|
||||
/* @DATADECLS@ */
|
||||
|
||||
/*@-usedef -nullassign -memtrans -usereleased -compdef -mustfree@*/
|
||||
%}
|
||||
|
||||
%union {
|
||||
|
|
@ -539,6 +540,7 @@ instr: instrbase
|
|||
/* @INSTRUCTIONS@ */
|
||||
|
||||
%%
|
||||
/*@=usedef =nullassign =memtrans =usereleased =compdef =mustfree@*/
|
||||
|
||||
static void
|
||||
nasm_parser_directive(const char *name, const char *val)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "errwarn.h"
|
||||
|
||||
|
|
@ -35,16 +35,17 @@ extern int nasm_parser_debug;
|
|||
|
||||
extern int nasm_parser_parse(void);
|
||||
|
||||
int (*nasm_parser_yyinput) (char *buf, int max_size);
|
||||
size_t (*nasm_parser_yyinput) (char *buf, size_t max_size);
|
||||
|
||||
objfmt *nasm_parser_objfmt;
|
||||
sectionhead nasm_parser_sections;
|
||||
section *nasm_parser_cur_section;
|
||||
/*@dependent@*/ section *nasm_parser_cur_section;
|
||||
|
||||
extern char *nasm_parser_locallabel_base;
|
||||
extern /*@only@*/ char *nasm_parser_locallabel_base;
|
||||
|
||||
static sectionhead *
|
||||
static /*@dependent@*/ sectionhead *
|
||||
nasm_parser_do_parse(parser *p, objfmt *of, FILE *f)
|
||||
/*@globals killed nasm_parser_locallabel_base @*/
|
||||
{
|
||||
p->current_pp->initialize(of, f);
|
||||
nasm_parser_in = f;
|
||||
|
|
@ -68,10 +69,12 @@ nasm_parser_do_parse(parser *p, objfmt *of, FILE *f)
|
|||
}
|
||||
|
||||
/* Define valid preprocessors to use with this parser */
|
||||
/*@-nullassign@*/
|
||||
static preproc *nasm_parser_preprocs[] = {
|
||||
&raw_preproc,
|
||||
NULL
|
||||
};
|
||||
/*@=nullassign@*/
|
||||
|
||||
/* Define parser structure -- see parser.h for details */
|
||||
parser nasm_parser = {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "errwarn.h"
|
||||
|
||||
|
|
@ -35,16 +35,17 @@ extern int nasm_parser_debug;
|
|||
|
||||
extern int nasm_parser_parse(void);
|
||||
|
||||
int (*nasm_parser_yyinput) (char *buf, int max_size);
|
||||
size_t (*nasm_parser_yyinput) (char *buf, size_t max_size);
|
||||
|
||||
objfmt *nasm_parser_objfmt;
|
||||
sectionhead nasm_parser_sections;
|
||||
section *nasm_parser_cur_section;
|
||||
/*@dependent@*/ section *nasm_parser_cur_section;
|
||||
|
||||
extern char *nasm_parser_locallabel_base;
|
||||
extern /*@only@*/ char *nasm_parser_locallabel_base;
|
||||
|
||||
static sectionhead *
|
||||
static /*@dependent@*/ sectionhead *
|
||||
nasm_parser_do_parse(parser *p, objfmt *of, FILE *f)
|
||||
/*@globals killed nasm_parser_locallabel_base @*/
|
||||
{
|
||||
p->current_pp->initialize(of, f);
|
||||
nasm_parser_in = f;
|
||||
|
|
@ -68,10 +69,12 @@ nasm_parser_do_parse(parser *p, objfmt *of, FILE *f)
|
|||
}
|
||||
|
||||
/* Define valid preprocessors to use with this parser */
|
||||
/*@-nullassign@*/
|
||||
static preproc *nasm_parser_preprocs[] = {
|
||||
&raw_preproc,
|
||||
NULL
|
||||
};
|
||||
/*@=nullassign@*/
|
||||
|
||||
/* Define parser structure -- see parser.h for details */
|
||||
parser nasm_parser = {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ RCSID("$IdPath$");
|
|||
|
||||
int nasm_parser_lex(void);
|
||||
|
||||
extern int (*nasm_parser_yyinput) (char *buf, int max_size);
|
||||
extern size_t (*nasm_parser_yyinput) (char *buf, size_t max_size);
|
||||
#undef YY_INPUT
|
||||
#define YY_INPUT(b, r, ms) (r = nasm_parser_yyinput(b, ms))
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "errwarn.h"
|
||||
|
||||
|
|
@ -33,16 +33,19 @@ static FILE *in;
|
|||
int isatty(int);
|
||||
|
||||
static void
|
||||
raw_preproc_initialize(objfmt *of, FILE *f)
|
||||
raw_preproc_initialize(/*@unused@*/ objfmt *of, FILE *f)
|
||||
{
|
||||
in = f;
|
||||
/*@-unrecog@*/
|
||||
is_interactive = f ? (isatty(fileno(f)) > 0) : 0;
|
||||
/*@=unrecog@*/
|
||||
}
|
||||
|
||||
static int
|
||||
raw_preproc_input(char *buf, int max_size)
|
||||
static size_t
|
||||
raw_preproc_input(char *buf, size_t max_size)
|
||||
{
|
||||
int c = '*', n;
|
||||
int c = '*';
|
||||
size_t n;
|
||||
|
||||
if (is_interactive) {
|
||||
for (n = 0; n < max_size && (c = getc(in)) != EOF && c != '\n'; n++)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "errwarn.h"
|
||||
|
||||
|
|
@ -33,16 +33,19 @@ static FILE *in;
|
|||
int isatty(int);
|
||||
|
||||
static void
|
||||
raw_preproc_initialize(objfmt *of, FILE *f)
|
||||
raw_preproc_initialize(/*@unused@*/ objfmt *of, FILE *f)
|
||||
{
|
||||
in = f;
|
||||
/*@-unrecog@*/
|
||||
is_interactive = f ? (isatty(fileno(f)) > 0) : 0;
|
||||
/*@=unrecog@*/
|
||||
}
|
||||
|
||||
static int
|
||||
raw_preproc_input(char *buf, int max_size)
|
||||
static size_t
|
||||
raw_preproc_input(char *buf, size_t max_size)
|
||||
{
|
||||
int c = '*', n;
|
||||
int c = '*';
|
||||
size_t n;
|
||||
|
||||
if (is_interactive) {
|
||||
for (n = 0; n < max_size && (c = getc(in)) != EOF && c != '\n'; n++)
|
||||
|
|
|
|||
2
splint.sh
Executable file
2
splint.sh
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
lclint -exportlocal -predbool -boolops +boolint +charint -retvalint -retvalother +ansilimits -I/usr/local/include -I.. -Iarch/x86 -I. -DHAVE_CONFIG_H -DHAVE_BOGUS_SYS_QUEUE_H -Dlint main.c options.c arch.c bytecode.c errwarn.c expr.c file.c floatnum.c globals.c intnum.c parser.c section.c arch/x86/arch.c arch/x86/bytecode.c arch/x86/expr.c objfmts/dbg/objfmt.c parsers/nasm/parser.c preprocs/raw/preproc.c parsers/nasm/bison.c symrec.c ternary.c
|
||||
|
|
@ -68,4 +68,5 @@ CFLAGS = @ANSI_CFLAGS@
|
|||
EXTRA_DIST = \
|
||||
strsep.c \
|
||||
mergesort.c \
|
||||
compat-queue.h
|
||||
compat-queue.h \
|
||||
lclint.sh
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "bytecode.h"
|
||||
#include "arch.h"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "errwarn.h"
|
||||
#include "intnum.h"
|
||||
|
|
@ -34,13 +34,14 @@ RCSID("$IdPath$");
|
|||
#include "bc-int.h"
|
||||
|
||||
|
||||
/*@-compmempass -mustfree@*/
|
||||
bytecode *
|
||||
x86_bc_new_insn(x86_new_insn_data *d)
|
||||
{
|
||||
bytecode *bc;
|
||||
x86_insn *insn;
|
||||
|
||||
bc = bc_new_common(X86_BC_INSN, sizeof(x86_insn));
|
||||
bc = bc_new_common((bytecode_type)X86_BC_INSN, sizeof(x86_insn));
|
||||
insn = bc_get_data(bc);
|
||||
|
||||
insn->ea = d->ea;
|
||||
|
|
@ -70,14 +71,16 @@ x86_bc_new_insn(x86_new_insn_data *d)
|
|||
|
||||
return bc;
|
||||
}
|
||||
/*@=compmempass =mustfree@*/
|
||||
|
||||
/*@-compmempass -mustfree@*/
|
||||
bytecode *
|
||||
x86_bc_new_jmprel(x86_new_jmprel_data *d)
|
||||
{
|
||||
bytecode *bc;
|
||||
x86_jmprel *jmprel;
|
||||
|
||||
bc = bc_new_common(X86_BC_JMPREL, sizeof(x86_jmprel));
|
||||
bc = bc_new_common((bytecode_type)X86_BC_JMPREL, sizeof(x86_jmprel));
|
||||
jmprel = bc_get_data(bc);
|
||||
|
||||
jmprel->target = d->target->val;
|
||||
|
|
@ -106,6 +109,7 @@ x86_bc_new_jmprel(x86_new_jmprel_data *d)
|
|||
|
||||
return bc;
|
||||
}
|
||||
/*@=compmempass =mustfree@*/
|
||||
|
||||
void
|
||||
x86_ea_set_segment(effaddr *ea, unsigned char segment)
|
||||
|
|
@ -124,7 +128,7 @@ x86_ea_set_segment(effaddr *ea, unsigned char segment)
|
|||
}
|
||||
|
||||
effaddr *
|
||||
x86_ea_new_reg(unsigned long reg)
|
||||
x86_ea_new_reg(unsigned char reg)
|
||||
{
|
||||
effaddr *ea = xmalloc(sizeof(effaddr)+sizeof(x86_effaddr_data));
|
||||
x86_effaddr_data *ead = ea_get_data(ea);
|
||||
|
|
@ -162,6 +166,7 @@ x86_ea_new_expr(expr *e)
|
|||
return ea;
|
||||
}
|
||||
|
||||
/*@-compmempass@*/
|
||||
effaddr *
|
||||
x86_ea_new_imm(immval *imm, unsigned char im_len)
|
||||
{
|
||||
|
|
@ -180,6 +185,7 @@ x86_ea_new_imm(immval *imm, unsigned char im_len)
|
|||
|
||||
return ea;
|
||||
}
|
||||
/*@=compmempass@*/
|
||||
|
||||
effaddr *
|
||||
x86_bc_insn_get_ea(bytecode *bc)
|
||||
|
|
@ -189,7 +195,7 @@ x86_bc_insn_get_ea(bytecode *bc)
|
|||
if (!bc)
|
||||
return NULL;
|
||||
|
||||
if (bc->type != X86_BC_INSN)
|
||||
if ((x86_bytecode_type)bc->type != X86_BC_INSN)
|
||||
InternalError(_("Trying to get EA of non-instruction"));
|
||||
|
||||
return insn->ea;
|
||||
|
|
@ -204,7 +210,7 @@ x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
switch (bc->type) {
|
||||
switch ((x86_bytecode_type)bc->type) {
|
||||
case X86_BC_INSN:
|
||||
insn = bc_get_data(bc);
|
||||
insn->opersize = opersize;
|
||||
|
|
@ -215,7 +221,6 @@ x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize)
|
|||
break;
|
||||
default:
|
||||
InternalError(_("OperSize override applied to non-instruction"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +233,7 @@ x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
switch (bc->type) {
|
||||
switch ((x86_bytecode_type)bc->type) {
|
||||
case X86_BC_INSN:
|
||||
insn = bc_get_data(bc);
|
||||
insn->addrsize = addrsize;
|
||||
|
|
@ -239,7 +244,6 @@ x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize)
|
|||
break;
|
||||
default:
|
||||
InternalError(_("AddrSize override applied to non-instruction"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -253,7 +257,7 @@ x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
switch (bc->type) {
|
||||
switch ((x86_bytecode_type)bc->type) {
|
||||
case X86_BC_INSN:
|
||||
insn = bc_get_data(bc);
|
||||
lockrep_pre = &insn->lockrep_pre;
|
||||
|
|
@ -264,7 +268,6 @@ x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix)
|
|||
break;
|
||||
default:
|
||||
InternalError(_("LockRep prefix applied to non-instruction"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (*lockrep_pre != 0)
|
||||
|
|
@ -281,7 +284,7 @@ x86_bc_insn_set_shift_flag(bytecode *bc)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
if (bc->type != X86_BC_INSN)
|
||||
if ((x86_bytecode_type)bc->type != X86_BC_INSN)
|
||||
InternalError(_("Attempted to set shift flag on non-instruction"));
|
||||
|
||||
insn = bc_get_data(bc);
|
||||
|
|
@ -367,7 +370,10 @@ x86_bc_print(const bytecode *bc)
|
|||
printf(" (nil)\n");
|
||||
else {
|
||||
printf("\n Val=");
|
||||
expr_print(insn->imm->val);
|
||||
if (insn->imm->val)
|
||||
expr_print(insn->imm->val);
|
||||
else
|
||||
printf("(nil-SHOULDN'T HAPPEN)");
|
||||
printf("\n");
|
||||
printf(" Len=%u, IsNeg=%u\n",
|
||||
(unsigned int)insn->imm->len,
|
||||
|
|
@ -471,24 +477,28 @@ x86_bc_parser_finalize_insn(x86_insn *insn)
|
|||
|
||||
if (imm->val) {
|
||||
expr_expand_equ(imm->val);
|
||||
expr_simplify(imm->val);
|
||||
imm->val = expr_simplify(imm->val);
|
||||
}
|
||||
/* TODO: check imm f_len vs. len? */
|
||||
|
||||
/* Handle shift_op special-casing */
|
||||
/*@-nullstate@*/
|
||||
if (insn->shift_op && (num = expr_get_intnum(&imm->val))) {
|
||||
if (intnum_get_uint(num) == 1) {
|
||||
/* Use ,1 form: first copy ,1 opcode. */
|
||||
insn->opcode[0] = insn->opcode[1];
|
||||
/* Delete ModRM, as it's no longer needed */
|
||||
xfree(ea);
|
||||
insn->ea = (effaddr *)NULL;
|
||||
/* Delete Imm, as it's not needed */
|
||||
expr_delete(imm->val);
|
||||
xfree(imm);
|
||||
insn->imm = (immval *)NULL;
|
||||
/*@=nullstate@*/
|
||||
if (num) {
|
||||
if (intnum_get_uint(num) == 1) {
|
||||
/* Use ,1 form: first copy ,1 opcode. */
|
||||
insn->opcode[0] = insn->opcode[1];
|
||||
/* Delete ModRM, as it's no longer needed */
|
||||
xfree(ea);
|
||||
insn->ea = (effaddr *)NULL;
|
||||
/* Delete Imm, as it's not needed */
|
||||
expr_delete(imm->val);
|
||||
xfree(imm);
|
||||
insn->imm = (immval *)NULL;
|
||||
}
|
||||
insn->shift_op = 0;
|
||||
}
|
||||
insn->shift_op = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,11 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#include "bitvect.h"
|
||||
|
||||
|
|
@ -41,8 +45,8 @@ RCSID("$IdPath$");
|
|||
/* Only works if ei->type == EXPR_REG (doesn't check).
|
||||
* Overwrites ei with intnum of 0 (to eliminate regs from the final expr).
|
||||
*/
|
||||
static int *
|
||||
x86_expr_checkea_get_reg32(ExprItem *ei, void *d)
|
||||
static /*@null@*/ /*@dependent@*/ int *
|
||||
x86_expr_checkea_get_reg32(ExprItem *ei, /*returned*/ void *d)
|
||||
{
|
||||
int *data = d;
|
||||
int *ret;
|
||||
|
|
@ -68,12 +72,14 @@ typedef struct x86_checkea_reg16_data {
|
|||
/* Only works if ei->type == EXPR_REG (doesn't check).
|
||||
* Overwrites ei with intnum of 0 (to eliminate regs from the final expr).
|
||||
*/
|
||||
static int *
|
||||
static /*@null@*/ int *
|
||||
x86_expr_checkea_get_reg16(ExprItem *ei, void *d)
|
||||
{
|
||||
x86_checkea_reg16_data *data = d;
|
||||
/* in order: ax,cx,dx,bx,sp,bp,si,di */
|
||||
/*@-nullassign@*/
|
||||
static int *reg16[8] = {0,0,0,0,0,0,0,0};
|
||||
/*@=nullassign@*/
|
||||
int *ret;
|
||||
|
||||
reg16[3] = &data->bx;
|
||||
|
|
@ -187,6 +193,7 @@ x86_expr_checkea_distcheck_reg(expr **ep)
|
|||
for (i=0; i<e->terms[havereg_expr].data.expn->numterms; i++) {
|
||||
/* Copy everything EXCEPT havereg_expr term into new expression */
|
||||
ne = expr_copy_except(e, havereg_expr);
|
||||
assert(ne != NULL);
|
||||
/* Copy reg expr term into uncopied (empty) term in new expn */
|
||||
ne->terms[havereg_expr] =
|
||||
e->terms[havereg_expr].data.expn->terms[i]; /* struct copy */
|
||||
|
|
@ -200,7 +207,9 @@ x86_expr_checkea_distcheck_reg(expr **ep)
|
|||
e->terms[havereg_expr].type = EXPR_NONE; /* don't delete it! */
|
||||
expr_delete(e); /* but everything else */
|
||||
e = ne;
|
||||
/*@-onlytrans@*/
|
||||
*ep = ne;
|
||||
/*@=onlytrans@*/
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
|
@ -217,15 +226,18 @@ x86_expr_checkea_distcheck_reg(expr **ep)
|
|||
* and 2 if all values successfully determined and saved in data.
|
||||
*/
|
||||
static int
|
||||
x86_expr_checkea_getregusage(expr **ep, int *indexreg, void *data,
|
||||
x86_expr_checkea_getregusage(expr **ep, /*@null@*/ int *indexreg, void *data,
|
||||
int *(*get_reg)(ExprItem *ei, void *d))
|
||||
{
|
||||
int i;
|
||||
int *reg;
|
||||
expr *e;
|
||||
|
||||
/*@-unqualifiedtrans@*/
|
||||
*ep = expr_xform_neg_tree(*ep);
|
||||
*ep = expr_level_tree(*ep, 1, indexreg == 0);
|
||||
/*@=unqualifiedtrans@*/
|
||||
assert(*ep != NULL);
|
||||
e = *ep;
|
||||
switch (x86_expr_checkea_distcheck_reg(ep)) {
|
||||
case 0:
|
||||
|
|
@ -259,7 +271,7 @@ x86_expr_checkea_getregusage(expr **ep, int *indexreg, void *data,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
/*@fallthrough@*/
|
||||
case EXPR_IDENT:
|
||||
/* Check each term for register (and possible multiplier). */
|
||||
for (i=0; i<e->numterms; i++) {
|
||||
|
|
@ -323,10 +335,11 @@ x86_expr_checkea_getregusage(expr **ep, int *indexreg, void *data,
|
|||
* noreg=1 if the *ModRM byte* has no registers used.
|
||||
* isbpreg=1 if BP/EBP is the *only* register used within the *ModRM byte*.
|
||||
*/
|
||||
/*@-nullstate@*/
|
||||
static int
|
||||
x86_checkea_calc_displen(expr **ep, int wordsize, int noreg, int isbpreg,
|
||||
unsigned char *displen, unsigned char *modrm,
|
||||
unsigned char *v_modrm)
|
||||
x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg,
|
||||
int isbpreg, unsigned char *displen,
|
||||
unsigned char *modrm, unsigned char *v_modrm)
|
||||
{
|
||||
expr *e = *ep;
|
||||
const intnum *intn;
|
||||
|
|
@ -362,7 +375,7 @@ x86_checkea_calc_displen(expr **ep, int wordsize, int noreg, int isbpreg,
|
|||
/* make sure the displacement will fit in 16/32 bits if unsigned,
|
||||
* and 8 bits if signed.
|
||||
*/
|
||||
if (!intnum_check_size(intn, wordsize, 0) &&
|
||||
if (!intnum_check_size(intn, (size_t)wordsize, 0) &&
|
||||
!intnum_check_size(intn, 1, 1)) {
|
||||
ErrorAt(e->filename, e->line, _("invalid effective address"));
|
||||
return 0;
|
||||
|
|
@ -440,6 +453,7 @@ x86_checkea_calc_displen(expr **ep, int wordsize, int noreg, int isbpreg,
|
|||
|
||||
return 1;
|
||||
}
|
||||
/*@=nullstate@*/
|
||||
|
||||
static int
|
||||
x86_expr_checkea_getregsize_callback(ExprItem *ei, void *d)
|
||||
|
|
@ -645,7 +659,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
|
|||
*sib |= 040;
|
||||
/* Any scale field is valid, just leave at 0. */
|
||||
else {
|
||||
*sib |= (indexreg & 7) << 3; /* &7 to sanity check */
|
||||
*sib |= ((unsigned int)indexreg & 7) << 3;
|
||||
/* Set scale field, 1 case -> 0, so don't bother. */
|
||||
switch (reg32mult[indexreg]) {
|
||||
case 2:
|
||||
|
|
|
|||
|
|
@ -40,9 +40,9 @@ typedef struct x86_effaddr_data {
|
|||
} x86_effaddr_data;
|
||||
|
||||
typedef struct x86_insn {
|
||||
effaddr *ea; /* effective address */
|
||||
/*@null@*/ effaddr *ea; /* effective address */
|
||||
|
||||
immval *imm; /* immediate or relative value */
|
||||
/*@null@*/ immval *imm; /* immediate or relative value */
|
||||
|
||||
unsigned char opcode[3]; /* opcode */
|
||||
unsigned char opcode_len;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "bytecode.h"
|
||||
#include "arch.h"
|
||||
|
|
|
|||
|
|
@ -42,12 +42,12 @@ typedef struct x86_targetval {
|
|||
x86_jmprel_opcode_sel op_sel;
|
||||
} x86_targetval;
|
||||
|
||||
void x86_ea_set_segment(effaddr *ea, unsigned char segment);
|
||||
effaddr *x86_ea_new_reg(unsigned long reg);
|
||||
void x86_ea_set_segment(/*@null@*/ effaddr *ea, unsigned char segment);
|
||||
effaddr *x86_ea_new_reg(unsigned char reg);
|
||||
effaddr *x86_ea_new_imm(immval *imm, unsigned char im_len);
|
||||
effaddr *x86_ea_new_expr(expr *e);
|
||||
effaddr *x86_ea_new_expr(/*@keep@*/ expr *e);
|
||||
|
||||
effaddr *x86_bc_insn_get_ea(bytecode *bc);
|
||||
/*@null@*/ effaddr *x86_bc_insn_get_ea(bytecode *bc);
|
||||
|
||||
void x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize);
|
||||
void x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize);
|
||||
|
|
@ -62,8 +62,8 @@ void x86_set_jmprel_opcode_sel(x86_jmprel_opcode_sel *old_sel,
|
|||
* function (it doesn't make a copy).
|
||||
*/
|
||||
typedef struct x86_new_insn_data {
|
||||
effaddr *ea;
|
||||
immval *imm;
|
||||
/*@keep@*/ /*@null@*/ effaddr *ea;
|
||||
/*@keep@*/ /*@null@*/ immval *imm;
|
||||
unsigned char opersize;
|
||||
unsigned char op_len;
|
||||
unsigned char op[3];
|
||||
|
|
@ -78,7 +78,7 @@ bytecode *x86_bc_new_insn(x86_new_insn_data *d);
|
|||
* Pass 0 for the opcode_len if that version of the opcode doesn't exist.
|
||||
*/
|
||||
typedef struct x86_new_jmprel_data {
|
||||
x86_targetval *target;
|
||||
/*@keep@*/ x86_targetval *target;
|
||||
unsigned char short_op_len;
|
||||
unsigned char short_op[3];
|
||||
unsigned char near_op_len;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "errwarn.h"
|
||||
#include "intnum.h"
|
||||
|
|
@ -34,13 +34,14 @@ RCSID("$IdPath$");
|
|||
#include "bc-int.h"
|
||||
|
||||
|
||||
/*@-compmempass -mustfree@*/
|
||||
bytecode *
|
||||
x86_bc_new_insn(x86_new_insn_data *d)
|
||||
{
|
||||
bytecode *bc;
|
||||
x86_insn *insn;
|
||||
|
||||
bc = bc_new_common(X86_BC_INSN, sizeof(x86_insn));
|
||||
bc = bc_new_common((bytecode_type)X86_BC_INSN, sizeof(x86_insn));
|
||||
insn = bc_get_data(bc);
|
||||
|
||||
insn->ea = d->ea;
|
||||
|
|
@ -70,14 +71,16 @@ x86_bc_new_insn(x86_new_insn_data *d)
|
|||
|
||||
return bc;
|
||||
}
|
||||
/*@=compmempass =mustfree@*/
|
||||
|
||||
/*@-compmempass -mustfree@*/
|
||||
bytecode *
|
||||
x86_bc_new_jmprel(x86_new_jmprel_data *d)
|
||||
{
|
||||
bytecode *bc;
|
||||
x86_jmprel *jmprel;
|
||||
|
||||
bc = bc_new_common(X86_BC_JMPREL, sizeof(x86_jmprel));
|
||||
bc = bc_new_common((bytecode_type)X86_BC_JMPREL, sizeof(x86_jmprel));
|
||||
jmprel = bc_get_data(bc);
|
||||
|
||||
jmprel->target = d->target->val;
|
||||
|
|
@ -106,6 +109,7 @@ x86_bc_new_jmprel(x86_new_jmprel_data *d)
|
|||
|
||||
return bc;
|
||||
}
|
||||
/*@=compmempass =mustfree@*/
|
||||
|
||||
void
|
||||
x86_ea_set_segment(effaddr *ea, unsigned char segment)
|
||||
|
|
@ -124,7 +128,7 @@ x86_ea_set_segment(effaddr *ea, unsigned char segment)
|
|||
}
|
||||
|
||||
effaddr *
|
||||
x86_ea_new_reg(unsigned long reg)
|
||||
x86_ea_new_reg(unsigned char reg)
|
||||
{
|
||||
effaddr *ea = xmalloc(sizeof(effaddr)+sizeof(x86_effaddr_data));
|
||||
x86_effaddr_data *ead = ea_get_data(ea);
|
||||
|
|
@ -162,6 +166,7 @@ x86_ea_new_expr(expr *e)
|
|||
return ea;
|
||||
}
|
||||
|
||||
/*@-compmempass@*/
|
||||
effaddr *
|
||||
x86_ea_new_imm(immval *imm, unsigned char im_len)
|
||||
{
|
||||
|
|
@ -180,6 +185,7 @@ x86_ea_new_imm(immval *imm, unsigned char im_len)
|
|||
|
||||
return ea;
|
||||
}
|
||||
/*@=compmempass@*/
|
||||
|
||||
effaddr *
|
||||
x86_bc_insn_get_ea(bytecode *bc)
|
||||
|
|
@ -189,7 +195,7 @@ x86_bc_insn_get_ea(bytecode *bc)
|
|||
if (!bc)
|
||||
return NULL;
|
||||
|
||||
if (bc->type != X86_BC_INSN)
|
||||
if ((x86_bytecode_type)bc->type != X86_BC_INSN)
|
||||
InternalError(_("Trying to get EA of non-instruction"));
|
||||
|
||||
return insn->ea;
|
||||
|
|
@ -204,7 +210,7 @@ x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
switch (bc->type) {
|
||||
switch ((x86_bytecode_type)bc->type) {
|
||||
case X86_BC_INSN:
|
||||
insn = bc_get_data(bc);
|
||||
insn->opersize = opersize;
|
||||
|
|
@ -215,7 +221,6 @@ x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize)
|
|||
break;
|
||||
default:
|
||||
InternalError(_("OperSize override applied to non-instruction"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -228,7 +233,7 @@ x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
switch (bc->type) {
|
||||
switch ((x86_bytecode_type)bc->type) {
|
||||
case X86_BC_INSN:
|
||||
insn = bc_get_data(bc);
|
||||
insn->addrsize = addrsize;
|
||||
|
|
@ -239,7 +244,6 @@ x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize)
|
|||
break;
|
||||
default:
|
||||
InternalError(_("AddrSize override applied to non-instruction"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -253,7 +257,7 @@ x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
switch (bc->type) {
|
||||
switch ((x86_bytecode_type)bc->type) {
|
||||
case X86_BC_INSN:
|
||||
insn = bc_get_data(bc);
|
||||
lockrep_pre = &insn->lockrep_pre;
|
||||
|
|
@ -264,7 +268,6 @@ x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix)
|
|||
break;
|
||||
default:
|
||||
InternalError(_("LockRep prefix applied to non-instruction"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (*lockrep_pre != 0)
|
||||
|
|
@ -281,7 +284,7 @@ x86_bc_insn_set_shift_flag(bytecode *bc)
|
|||
if (!bc)
|
||||
return;
|
||||
|
||||
if (bc->type != X86_BC_INSN)
|
||||
if ((x86_bytecode_type)bc->type != X86_BC_INSN)
|
||||
InternalError(_("Attempted to set shift flag on non-instruction"));
|
||||
|
||||
insn = bc_get_data(bc);
|
||||
|
|
@ -367,7 +370,10 @@ x86_bc_print(const bytecode *bc)
|
|||
printf(" (nil)\n");
|
||||
else {
|
||||
printf("\n Val=");
|
||||
expr_print(insn->imm->val);
|
||||
if (insn->imm->val)
|
||||
expr_print(insn->imm->val);
|
||||
else
|
||||
printf("(nil-SHOULDN'T HAPPEN)");
|
||||
printf("\n");
|
||||
printf(" Len=%u, IsNeg=%u\n",
|
||||
(unsigned int)insn->imm->len,
|
||||
|
|
@ -471,24 +477,28 @@ x86_bc_parser_finalize_insn(x86_insn *insn)
|
|||
|
||||
if (imm->val) {
|
||||
expr_expand_equ(imm->val);
|
||||
expr_simplify(imm->val);
|
||||
imm->val = expr_simplify(imm->val);
|
||||
}
|
||||
/* TODO: check imm f_len vs. len? */
|
||||
|
||||
/* Handle shift_op special-casing */
|
||||
/*@-nullstate@*/
|
||||
if (insn->shift_op && (num = expr_get_intnum(&imm->val))) {
|
||||
if (intnum_get_uint(num) == 1) {
|
||||
/* Use ,1 form: first copy ,1 opcode. */
|
||||
insn->opcode[0] = insn->opcode[1];
|
||||
/* Delete ModRM, as it's no longer needed */
|
||||
xfree(ea);
|
||||
insn->ea = (effaddr *)NULL;
|
||||
/* Delete Imm, as it's not needed */
|
||||
expr_delete(imm->val);
|
||||
xfree(imm);
|
||||
insn->imm = (immval *)NULL;
|
||||
/*@=nullstate@*/
|
||||
if (num) {
|
||||
if (intnum_get_uint(num) == 1) {
|
||||
/* Use ,1 form: first copy ,1 opcode. */
|
||||
insn->opcode[0] = insn->opcode[1];
|
||||
/* Delete ModRM, as it's no longer needed */
|
||||
xfree(ea);
|
||||
insn->ea = (effaddr *)NULL;
|
||||
/* Delete Imm, as it's not needed */
|
||||
expr_delete(imm->val);
|
||||
xfree(imm);
|
||||
insn->imm = (immval *)NULL;
|
||||
}
|
||||
insn->shift_op = 0;
|
||||
}
|
||||
insn->shift_op = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,11 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#include "bitvect.h"
|
||||
|
||||
|
|
@ -41,8 +45,8 @@ RCSID("$IdPath$");
|
|||
/* Only works if ei->type == EXPR_REG (doesn't check).
|
||||
* Overwrites ei with intnum of 0 (to eliminate regs from the final expr).
|
||||
*/
|
||||
static int *
|
||||
x86_expr_checkea_get_reg32(ExprItem *ei, void *d)
|
||||
static /*@null@*/ /*@dependent@*/ int *
|
||||
x86_expr_checkea_get_reg32(ExprItem *ei, /*returned*/ void *d)
|
||||
{
|
||||
int *data = d;
|
||||
int *ret;
|
||||
|
|
@ -68,12 +72,14 @@ typedef struct x86_checkea_reg16_data {
|
|||
/* Only works if ei->type == EXPR_REG (doesn't check).
|
||||
* Overwrites ei with intnum of 0 (to eliminate regs from the final expr).
|
||||
*/
|
||||
static int *
|
||||
static /*@null@*/ int *
|
||||
x86_expr_checkea_get_reg16(ExprItem *ei, void *d)
|
||||
{
|
||||
x86_checkea_reg16_data *data = d;
|
||||
/* in order: ax,cx,dx,bx,sp,bp,si,di */
|
||||
/*@-nullassign@*/
|
||||
static int *reg16[8] = {0,0,0,0,0,0,0,0};
|
||||
/*@=nullassign@*/
|
||||
int *ret;
|
||||
|
||||
reg16[3] = &data->bx;
|
||||
|
|
@ -187,6 +193,7 @@ x86_expr_checkea_distcheck_reg(expr **ep)
|
|||
for (i=0; i<e->terms[havereg_expr].data.expn->numterms; i++) {
|
||||
/* Copy everything EXCEPT havereg_expr term into new expression */
|
||||
ne = expr_copy_except(e, havereg_expr);
|
||||
assert(ne != NULL);
|
||||
/* Copy reg expr term into uncopied (empty) term in new expn */
|
||||
ne->terms[havereg_expr] =
|
||||
e->terms[havereg_expr].data.expn->terms[i]; /* struct copy */
|
||||
|
|
@ -200,7 +207,9 @@ x86_expr_checkea_distcheck_reg(expr **ep)
|
|||
e->terms[havereg_expr].type = EXPR_NONE; /* don't delete it! */
|
||||
expr_delete(e); /* but everything else */
|
||||
e = ne;
|
||||
/*@-onlytrans@*/
|
||||
*ep = ne;
|
||||
/*@=onlytrans@*/
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
|
@ -217,15 +226,18 @@ x86_expr_checkea_distcheck_reg(expr **ep)
|
|||
* and 2 if all values successfully determined and saved in data.
|
||||
*/
|
||||
static int
|
||||
x86_expr_checkea_getregusage(expr **ep, int *indexreg, void *data,
|
||||
x86_expr_checkea_getregusage(expr **ep, /*@null@*/ int *indexreg, void *data,
|
||||
int *(*get_reg)(ExprItem *ei, void *d))
|
||||
{
|
||||
int i;
|
||||
int *reg;
|
||||
expr *e;
|
||||
|
||||
/*@-unqualifiedtrans@*/
|
||||
*ep = expr_xform_neg_tree(*ep);
|
||||
*ep = expr_level_tree(*ep, 1, indexreg == 0);
|
||||
/*@=unqualifiedtrans@*/
|
||||
assert(*ep != NULL);
|
||||
e = *ep;
|
||||
switch (x86_expr_checkea_distcheck_reg(ep)) {
|
||||
case 0:
|
||||
|
|
@ -259,7 +271,7 @@ x86_expr_checkea_getregusage(expr **ep, int *indexreg, void *data,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* FALLTHROUGH */
|
||||
/*@fallthrough@*/
|
||||
case EXPR_IDENT:
|
||||
/* Check each term for register (and possible multiplier). */
|
||||
for (i=0; i<e->numterms; i++) {
|
||||
|
|
@ -323,10 +335,11 @@ x86_expr_checkea_getregusage(expr **ep, int *indexreg, void *data,
|
|||
* noreg=1 if the *ModRM byte* has no registers used.
|
||||
* isbpreg=1 if BP/EBP is the *only* register used within the *ModRM byte*.
|
||||
*/
|
||||
/*@-nullstate@*/
|
||||
static int
|
||||
x86_checkea_calc_displen(expr **ep, int wordsize, int noreg, int isbpreg,
|
||||
unsigned char *displen, unsigned char *modrm,
|
||||
unsigned char *v_modrm)
|
||||
x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg,
|
||||
int isbpreg, unsigned char *displen,
|
||||
unsigned char *modrm, unsigned char *v_modrm)
|
||||
{
|
||||
expr *e = *ep;
|
||||
const intnum *intn;
|
||||
|
|
@ -362,7 +375,7 @@ x86_checkea_calc_displen(expr **ep, int wordsize, int noreg, int isbpreg,
|
|||
/* make sure the displacement will fit in 16/32 bits if unsigned,
|
||||
* and 8 bits if signed.
|
||||
*/
|
||||
if (!intnum_check_size(intn, wordsize, 0) &&
|
||||
if (!intnum_check_size(intn, (size_t)wordsize, 0) &&
|
||||
!intnum_check_size(intn, 1, 1)) {
|
||||
ErrorAt(e->filename, e->line, _("invalid effective address"));
|
||||
return 0;
|
||||
|
|
@ -440,6 +453,7 @@ x86_checkea_calc_displen(expr **ep, int wordsize, int noreg, int isbpreg,
|
|||
|
||||
return 1;
|
||||
}
|
||||
/*@=nullstate@*/
|
||||
|
||||
static int
|
||||
x86_expr_checkea_getregsize_callback(ExprItem *ei, void *d)
|
||||
|
|
@ -645,7 +659,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
|
|||
*sib |= 040;
|
||||
/* Any scale field is valid, just leave at 0. */
|
||||
else {
|
||||
*sib |= (indexreg & 7) << 3; /* &7 to sanity check */
|
||||
*sib |= ((unsigned int)indexreg & 7) << 3;
|
||||
/* Set scale field, 1 case -> 0, so don't bother. */
|
||||
switch (reg32mult[indexreg]) {
|
||||
case 2:
|
||||
|
|
|
|||
16
src/bc-int.h
16
src/bc-int.h
|
|
@ -23,7 +23,7 @@
|
|||
#define YASM_BC_INT_H
|
||||
|
||||
struct effaddr {
|
||||
expr *disp; /* address displacement */
|
||||
/*@only@*/ /*@null@*/ expr *disp; /* address displacement */
|
||||
unsigned char len; /* length of disp (in bytes), 0 if unknown,
|
||||
* 0xff if unknown and required to be >0.
|
||||
*/
|
||||
|
|
@ -32,11 +32,13 @@ struct effaddr {
|
|||
|
||||
/* architecture-dependent data may be appended */
|
||||
};
|
||||
void *ea_get_data(effaddr *);
|
||||
#define ea_get_data(x) (void *)(((char *)x)+sizeof(effaddr))
|
||||
const void *ea_get_const_data(const effaddr *);
|
||||
#define ea_get_const_data(x) (const void *)(((const char *)x)+sizeof(effaddr))
|
||||
|
||||
struct immval {
|
||||
expr *val;
|
||||
/*@only@*/ /*@null@*/ expr *val;
|
||||
|
||||
unsigned char len; /* length of val (in bytes), 0 if unknown */
|
||||
unsigned char isneg; /* the value has been explicitly negated */
|
||||
|
|
@ -46,18 +48,18 @@ struct immval {
|
|||
};
|
||||
|
||||
struct bytecode {
|
||||
STAILQ_ENTRY(bytecode) link;
|
||||
/*@reldef@*/ STAILQ_ENTRY(bytecode) link;
|
||||
|
||||
bytecode_type type;
|
||||
|
||||
expr *multiple; /* number of times bytecode is repeated,
|
||||
NULL=1 */
|
||||
/* number of times bytecode is repeated, NULL=1. */
|
||||
/*@only@*/ /*@null@*/ expr *multiple;
|
||||
|
||||
unsigned long len; /* total length of entire bytecode (including
|
||||
multiple copies), 0 if unknown */
|
||||
|
||||
/* where it came from */
|
||||
const char *filename;
|
||||
/*@dependent@*/ /*@null@*/ const char *filename;
|
||||
unsigned int lineno;
|
||||
|
||||
/* other assembler state info */
|
||||
|
|
@ -65,7 +67,9 @@ struct bytecode {
|
|||
|
||||
/* architecture-dependent data may be appended */
|
||||
};
|
||||
void *bc_get_data(bytecode *);
|
||||
#define bc_get_data(x) (void *)(((char *)x)+sizeof(bytecode))
|
||||
const void *bc_get_const_data(const bytecode *);
|
||||
#define bc_get_const_data(x) (const void *)(((const char *)x)+sizeof(bytecode))
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ const char * BitVector_Version (void); /* returns version string */
|
|||
N_int BitVector_Word_Bits (void); /* returns # of bits in machine word */
|
||||
N_int BitVector_Long_Bits (void); /* returns # of bits in unsigned long */
|
||||
|
||||
wordptr BitVector_Create(N_int bits, boolean clear); /* malloc */
|
||||
/*@only@*/ wordptr BitVector_Create(N_int bits, boolean clear); /* malloc */
|
||||
|
||||
/* ===> OBJECT METHODS: <=== */
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ wordptr BitVector_Clone (wordptr addr); /* makes exact duplicate */
|
|||
wordptr BitVector_Concat (wordptr X, wordptr Y); /* returns concatenation */
|
||||
|
||||
wordptr BitVector_Resize (wordptr oldaddr, N_int bits); /* realloc */
|
||||
void BitVector_Destroy (wordptr addr); /* free */
|
||||
void BitVector_Destroy (/*@only@*/ wordptr addr); /* free */
|
||||
|
||||
/* ===> bit vector copy function: */
|
||||
|
||||
|
|
@ -150,20 +150,20 @@ void BitVector_Reverse (wordptr X, wordptr Y);
|
|||
|
||||
/* ===> bit vector interval operations and functions: */
|
||||
|
||||
void BitVector_Interval_Empty (wordptr addr, N_int lower, N_int upper);
|
||||
void BitVector_Interval_Fill (wordptr addr, N_int lower, N_int upper);
|
||||
void BitVector_Interval_Flip (wordptr addr, N_int lower, N_int upper);
|
||||
void BitVector_Interval_Reverse (wordptr addr, N_int lower, N_int upper);
|
||||
void BitVector_Interval_Empty (/*@out@*/ wordptr addr, N_int lower, N_int upper);
|
||||
void BitVector_Interval_Fill (/*@out@*/ wordptr addr, N_int lower, N_int upper);
|
||||
void BitVector_Interval_Flip (/*@out@*/ wordptr addr, N_int lower, N_int upper);
|
||||
void BitVector_Interval_Reverse (/*@out@*/ wordptr addr, N_int lower, N_int upper);
|
||||
|
||||
boolean BitVector_interval_scan_inc(wordptr addr, N_int start,
|
||||
N_intptr min, N_intptr max);
|
||||
boolean BitVector_interval_scan_dec(wordptr addr, N_int start,
|
||||
N_intptr min, N_intptr max);
|
||||
|
||||
void BitVector_Interval_Copy (wordptr X, wordptr Y, N_int Xoffset,
|
||||
void BitVector_Interval_Copy (/*@out@*/ wordptr X, wordptr Y, N_int Xoffset,
|
||||
N_int Yoffset, N_int length);
|
||||
|
||||
wordptr BitVector_Interval_Substitute(wordptr X, wordptr Y,
|
||||
wordptr BitVector_Interval_Substitute(/*@out@*/ wordptr X, wordptr Y,
|
||||
N_int Xoffset, N_int Xlength,
|
||||
N_int Yoffset, N_int Ylength);
|
||||
|
||||
|
|
@ -178,42 +178,42 @@ Z_int BitVector_Compare (wordptr X, wordptr Y); /* X <,=,> Y ? */
|
|||
|
||||
/* ===> bit vector string conversion functions: */
|
||||
|
||||
charptr BitVector_to_Hex (wordptr addr);
|
||||
ErrCode BitVector_from_Hex(wordptr addr, charptr string);
|
||||
/*@only@*/ charptr BitVector_to_Hex (wordptr addr);
|
||||
ErrCode BitVector_from_Hex(/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
ErrCode BitVector_from_Oct(wordptr addr, charptr string);
|
||||
ErrCode BitVector_from_Oct(/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
charptr BitVector_to_Bin (wordptr addr);
|
||||
ErrCode BitVector_from_Bin(wordptr addr, charptr string);
|
||||
/*@only@*/ charptr BitVector_to_Bin (wordptr addr);
|
||||
ErrCode BitVector_from_Bin(/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
charptr BitVector_to_Dec (wordptr addr);
|
||||
ErrCode BitVector_from_Dec(wordptr addr, charptr string);
|
||||
/*@only@*/ charptr BitVector_to_Dec (wordptr addr);
|
||||
ErrCode BitVector_from_Dec(/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
charptr BitVector_to_Enum (wordptr addr);
|
||||
ErrCode BitVector_from_Enum(wordptr addr, charptr string);
|
||||
/*@only@*/ charptr BitVector_to_Enum (wordptr addr);
|
||||
ErrCode BitVector_from_Enum(/*@out@*/ wordptr addr, charptr string);
|
||||
|
||||
void BitVector_Dispose (charptr string);
|
||||
void BitVector_Dispose (/*@only@*/ /*@out@*/ charptr string);
|
||||
|
||||
/* ===> bit vector bit operations, functions & tests: */
|
||||
|
||||
void BitVector_Bit_Off (wordptr addr, N_int indx); /* X = X \ {x} */
|
||||
void BitVector_Bit_On (wordptr addr, N_int indx); /* X = X + {x} */
|
||||
boolean BitVector_bit_flip(wordptr addr, N_int indx); /* X=(X+{x})\(X*{x}) */
|
||||
void BitVector_Bit_Off (/*@out@*/ wordptr addr, N_int indx); /* X = X \ {x} */
|
||||
void BitVector_Bit_On (/*@out@*/ wordptr addr, N_int indx); /* X = X + {x} */
|
||||
boolean BitVector_bit_flip(/*@out@*/ wordptr addr, N_int indx); /* X=(X+{x})\(X*{x}) */
|
||||
|
||||
boolean BitVector_bit_test(wordptr addr, N_int indx); /* {x} in X ? */
|
||||
|
||||
void BitVector_Bit_Copy(wordptr addr, N_int indx, boolean bit);
|
||||
void BitVector_Bit_Copy(/*@out@*/ wordptr addr, N_int indx, boolean bit);
|
||||
|
||||
/* ===> bit vector bit shift & rotate functions: */
|
||||
|
||||
void BitVector_LSB (wordptr addr, boolean bit);
|
||||
void BitVector_MSB (wordptr addr, boolean bit);
|
||||
void BitVector_LSB (/*@out@*/ wordptr addr, boolean bit);
|
||||
void BitVector_MSB (/*@out@*/ wordptr addr, boolean bit);
|
||||
boolean BitVector_lsb (wordptr addr);
|
||||
boolean BitVector_msb (wordptr addr);
|
||||
boolean BitVector_rotate_left (wordptr addr);
|
||||
boolean BitVector_rotate_right(wordptr addr);
|
||||
boolean BitVector_shift_left (wordptr addr, boolean carry_in);
|
||||
boolean BitVector_shift_right (wordptr addr, boolean carry_in);
|
||||
boolean /*@alt void@*/ BitVector_rotate_left (wordptr addr);
|
||||
boolean /*@alt void@*/ BitVector_rotate_right(wordptr addr);
|
||||
boolean /*@alt void@*/ BitVector_shift_left (wordptr addr, boolean carry_in);
|
||||
boolean /*@alt void@*/ BitVector_shift_right (wordptr addr, boolean carry_in);
|
||||
void BitVector_Move_Left (wordptr addr, N_int bits);
|
||||
void BitVector_Move_Right (wordptr addr, N_int bits);
|
||||
|
||||
|
|
@ -226,15 +226,15 @@ void BitVector_Delete (wordptr addr, N_int offset, N_int count,
|
|||
|
||||
/* ===> bit vector arithmetic: */
|
||||
|
||||
boolean BitVector_increment (wordptr addr); /* X++ */
|
||||
boolean BitVector_decrement (wordptr addr); /* X-- */
|
||||
boolean /*@alt void@*/ BitVector_increment (wordptr addr); /* X++ */
|
||||
boolean /*@alt void@*/ BitVector_decrement (wordptr addr); /* X-- */
|
||||
|
||||
boolean BitVector_compute (wordptr X, wordptr Y, wordptr Z, boolean minus,
|
||||
boolean *carry);
|
||||
boolean BitVector_add (wordptr X, wordptr Y, wordptr Z, boolean *carry);
|
||||
boolean BitVector_sub (wordptr X, wordptr Y, wordptr Z, boolean *carry);
|
||||
boolean BitVector_inc (wordptr X, wordptr Y);
|
||||
boolean BitVector_dec (wordptr X, wordptr Y);
|
||||
boolean /*@alt void@*/ BitVector_compute (wordptr X, wordptr Y, wordptr Z, boolean minus,
|
||||
/*@out@*/ boolean *carry);
|
||||
boolean /*@alt void@*/ BitVector_add (wordptr X, wordptr Y, wordptr Z, /*@out@*/ boolean *carry);
|
||||
boolean /*@alt void@*/ BitVector_sub (wordptr X, wordptr Y, wordptr Z, /*@out@*/ boolean *carry);
|
||||
boolean /*@alt void@*/ BitVector_inc (wordptr X, wordptr Y);
|
||||
boolean /*@alt void@*/ BitVector_dec (wordptr X, wordptr Y);
|
||||
|
||||
void BitVector_Negate (wordptr X, wordptr Y);
|
||||
void BitVector_Absolute(wordptr X, wordptr Y);
|
||||
|
|
@ -249,7 +249,7 @@ ErrCode BitVector_Power (wordptr X, wordptr Y, wordptr Z);
|
|||
/* ===> direct memory access functions: */
|
||||
|
||||
void BitVector_Block_Store (wordptr addr, charptr buffer, N_int length);
|
||||
charptr BitVector_Block_Read (wordptr addr, N_intptr length);
|
||||
charptr BitVector_Block_Read (wordptr addr, /*@out@*/ N_intptr length);
|
||||
|
||||
/* ===> word array functions: */
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "globals.h"
|
||||
#include "errwarn.h"
|
||||
|
|
@ -35,13 +35,13 @@ RCSID("$IdPath$");
|
|||
|
||||
|
||||
struct dataval {
|
||||
STAILQ_ENTRY(dataval) link;
|
||||
/*@reldef@*/ STAILQ_ENTRY(dataval) link;
|
||||
|
||||
enum { DV_EMPTY, DV_EXPR, DV_STRING } type;
|
||||
|
||||
union {
|
||||
expr *expn;
|
||||
char *str_val;
|
||||
/*@only@*/ expr *expn;
|
||||
/*@only@*/ char *str_val;
|
||||
} data;
|
||||
};
|
||||
|
||||
|
|
@ -54,7 +54,7 @@ typedef struct bytecode_data {
|
|||
} bytecode_data;
|
||||
|
||||
typedef struct bytecode_reserve {
|
||||
expr *numitems; /* number of items to reserve */
|
||||
/*@only@*/ expr *numitems; /* number of items to reserve */
|
||||
unsigned char itemsize; /* size of each item (in bytes) */
|
||||
} bytecode_reserve;
|
||||
|
||||
|
|
@ -77,6 +77,8 @@ imm_new_int(unsigned long int_val)
|
|||
im->len = 4;
|
||||
|
||||
im->isneg = 0;
|
||||
im->f_len = 0;
|
||||
im->f_sign = 0;
|
||||
|
||||
return im;
|
||||
}
|
||||
|
|
@ -89,6 +91,8 @@ imm_new_expr(expr *expr_ptr)
|
|||
im->val = expr_ptr;
|
||||
im->len = 0;
|
||||
im->isneg = 0;
|
||||
im->f_len = 0;
|
||||
im->f_sign = 0;
|
||||
|
||||
return im;
|
||||
}
|
||||
|
|
@ -143,7 +147,7 @@ bc_new_common(bytecode_type type, size_t datasize)
|
|||
}
|
||||
|
||||
bytecode *
|
||||
bc_new_data(datavalhead *datahead, unsigned long size)
|
||||
bc_new_data(datavalhead *datahead, unsigned char size)
|
||||
{
|
||||
bytecode *bc = bc_new_common(BC_DATA, sizeof(bytecode_data));
|
||||
bytecode_data *data = bc_get_data(bc);
|
||||
|
|
@ -155,12 +159,14 @@ bc_new_data(datavalhead *datahead, unsigned long size)
|
|||
}
|
||||
|
||||
bytecode *
|
||||
bc_new_reserve(expr *numitems, unsigned long itemsize)
|
||||
bc_new_reserve(expr *numitems, unsigned char itemsize)
|
||||
{
|
||||
bytecode *bc = bc_new_common(BC_RESERVE, sizeof(bytecode_reserve));
|
||||
bytecode_reserve *reserve = bc_get_data(bc);
|
||||
|
||||
/*@-mustfree@*/
|
||||
reserve->numitems = numitems;
|
||||
/*@=mustfree@*/
|
||||
reserve->itemsize = itemsize;
|
||||
|
||||
return bc;
|
||||
|
|
@ -199,7 +205,8 @@ bc_delete(bytecode *bc)
|
|||
}
|
||||
|
||||
int
|
||||
bc_get_offset(section *sect, bytecode *bc, unsigned long *ret_val)
|
||||
bc_get_offset(/*@unused@*/ section *sect, /*@unused@*/ bytecode *bc,
|
||||
/*@unused@*/ unsigned long *ret_val)
|
||||
{
|
||||
return 0; /* TODO */
|
||||
}
|
||||
|
|
@ -256,7 +263,6 @@ bc_parser_finalize(bytecode *bc)
|
|||
case BC_EMPTY:
|
||||
/* FIXME: delete it (probably in bytecodes_ level, not here */
|
||||
InternalError(_("got empty bytecode in parser_finalize"));
|
||||
break;
|
||||
default:
|
||||
if (bc->type < cur_arch->bc.type_max)
|
||||
cur_arch->bc.bc_parser_finalize(bc);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
typedef struct effaddr effaddr;
|
||||
typedef struct immval immval;
|
||||
typedef STAILQ_HEAD(datavalhead, dataval) datavalhead;
|
||||
typedef /*@reldef@*/ STAILQ_HEAD(datavalhead, dataval) datavalhead;
|
||||
typedef struct dataval dataval;
|
||||
|
||||
/* Additional types may be architecture-defined starting at
|
||||
|
|
@ -37,24 +37,26 @@ typedef enum {
|
|||
} bytecode_type;
|
||||
#define BYTECODE_TYPE_BASE BC_RESERVE+1
|
||||
|
||||
immval *imm_new_int(unsigned long int_val);
|
||||
immval *imm_new_expr(expr *e);
|
||||
/*@only@*/ immval *imm_new_int(unsigned long int_val);
|
||||
/*@only@*/ immval *imm_new_expr(/*@keep@*/ expr *e);
|
||||
|
||||
void ea_set_len(effaddr *ea, unsigned char len);
|
||||
void ea_set_nosplit(effaddr *ea, unsigned char nosplit);
|
||||
|
||||
void bc_set_multiple(bytecode *bc, expr *e);
|
||||
void bc_set_multiple(bytecode *bc, /*@keep@*/ expr *e);
|
||||
|
||||
bytecode *bc_new_common(bytecode_type type, size_t datasize);
|
||||
bytecode *bc_new_data(datavalhead *datahead, unsigned long size);
|
||||
bytecode *bc_new_reserve(expr *numitems, unsigned long itemsize);
|
||||
/*@only@*/ bytecode *bc_new_common(bytecode_type type, size_t datasize);
|
||||
/*@only@*/ bytecode *bc_new_data(datavalhead *datahead, unsigned char size);
|
||||
/*@only@*/ bytecode *bc_new_reserve(/*@keep@*/ expr *numitems,
|
||||
unsigned char itemsize);
|
||||
|
||||
void bc_delete(bytecode *bc);
|
||||
void bc_delete(/*@only@*/ /*@null@*/ bytecode *bc);
|
||||
|
||||
/* Gets the offset of the bytecode specified by bc if possible.
|
||||
* Return value is IF POSSIBLE, not the value.
|
||||
*/
|
||||
int bc_get_offset(section *sect, bytecode *bc, unsigned long *ret_val);
|
||||
int bc_get_offset(section *sect, bytecode *bc,
|
||||
/*@out@*/ unsigned long *ret_val);
|
||||
|
||||
void bc_print(const bytecode *bc);
|
||||
|
||||
|
|
@ -71,17 +73,19 @@ void bcs_delete(bytecodehead *headp);
|
|||
* this function. If bc was actually appended (it wasn't NULL or empty),
|
||||
* then returns bc, otherwise returns NULL.
|
||||
*/
|
||||
bytecode *bcs_append(bytecodehead *headp, bytecode *bc);
|
||||
/*@only@*/ /*@null@*/ bytecode *bcs_append(bytecodehead *headp,
|
||||
/*@returned@*/ /*@only@*/ /*@null@*/
|
||||
bytecode *bc);
|
||||
|
||||
void bcs_print(const bytecodehead *headp);
|
||||
|
||||
void bcs_parser_finalize(bytecodehead *headp);
|
||||
|
||||
dataval *dv_new_expr(expr *expn);
|
||||
dataval *dv_new_float(floatnum *flt);
|
||||
dataval *dv_new_string(char *str_val);
|
||||
dataval *dv_new_expr(/*@keep@*/ expr *expn);
|
||||
dataval *dv_new_float(/*@keep@*/ floatnum *flt);
|
||||
dataval *dv_new_string(/*@keep@*/ char *str_val);
|
||||
|
||||
/* void dvs_initialize(datavalhead *headp); */
|
||||
void dvs_initialize(datavalhead *headp);
|
||||
#define dvs_initialize(headp) STAILQ_INIT(headp)
|
||||
|
||||
void dvs_delete(datavalhead *headp);
|
||||
|
|
@ -92,7 +96,8 @@ void dvs_delete(datavalhead *headp);
|
|||
* this function. If dv was actually appended (it wasn't NULL), then
|
||||
* returns dv, otherwise returns NULL.
|
||||
*/
|
||||
dataval *dvs_append(datavalhead *headp, dataval *dv);
|
||||
/*@null@*/ dataval *dvs_append(datavalhead *headp,
|
||||
/*@returned@*/ /*@null@*/ dataval *dv);
|
||||
|
||||
void dvs_print(const datavalhead *head);
|
||||
|
||||
|
|
|
|||
|
|
@ -169,8 +169,8 @@ struct { \
|
|||
*/
|
||||
#define STAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *stqh_first;/* first element */ \
|
||||
struct type **stqh_last;/* addr of last next element */ \
|
||||
/*@reldef@*/ struct type *stqh_first;/* first element */ \
|
||||
/*@reldef@*/ struct type **stqh_last;/* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define STAILQ_HEAD_INITIALIZER(head) \
|
||||
|
|
@ -178,7 +178,7 @@ struct name { \
|
|||
|
||||
#define STAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *stqe_next; /* next element */ \
|
||||
/*@reldef@*/ struct type *stqe_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -188,7 +188,9 @@ struct { \
|
|||
|
||||
#define STAILQ_INIT(head) do { \
|
||||
(head)->stqh_first = NULL; \
|
||||
/*@-immediatetrans@*/ \
|
||||
(head)->stqh_last = &(head)->stqh_first; \
|
||||
/*@=immediatetrans@*/ \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_FIRST(head) ((head)->stqh_first)
|
||||
|
|
@ -210,8 +212,10 @@ struct { \
|
|||
|
||||
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
(elm)->field.stqe_next = NULL; \
|
||||
/*@-onlytrans -mustfree -immediatetrans@*/ \
|
||||
*(head)->stqh_last = (elm); \
|
||||
(head)->stqh_last = &(elm)->field.stqe_next; \
|
||||
/*@=onlytrans =mustfree =immediatetrans@*/ \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@ typedef struct optimizer optimizer;
|
|||
typedef struct objfmt objfmt;
|
||||
|
||||
typedef struct bytecode bytecode;
|
||||
typedef STAILQ_HEAD(bytecodehead, bytecode) bytecodehead;
|
||||
typedef /*@reldef@*/ STAILQ_HEAD(bytecodehead, bytecode) bytecodehead;
|
||||
|
||||
typedef struct section section;
|
||||
typedef STAILQ_HEAD(sectionhead, section) sectionhead;
|
||||
typedef /*@reldef@*/ STAILQ_HEAD(sectionhead, section) sectionhead;
|
||||
|
||||
typedef struct symrec symrec;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,13 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stdarg.h>
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#ifdef gettext_noop
|
||||
|
|
@ -50,20 +51,22 @@ static unsigned int warning_count = 0;
|
|||
* When adding a string here, keep errwarn.h in sync! */
|
||||
|
||||
/* Fatal error messages. Match up with fatal_num enum in errwarn.h. */
|
||||
/*@-observertrans@*/
|
||||
static const char *fatal_msgs[] = {
|
||||
N_("unknown"),
|
||||
N_("out of memory")
|
||||
};
|
||||
/*@=observertrans@*/
|
||||
|
||||
typedef STAILQ_HEAD(errwarnhead_s, errwarn_s) errwarnhead;
|
||||
errwarnhead *errwarns = (errwarnhead *)NULL;
|
||||
typedef /*@reldef@*/ STAILQ_HEAD(errwarnhead_s, errwarn_s) errwarnhead;
|
||||
static /*@only@*/ /*@null@*/ errwarnhead *errwarns = (errwarnhead *)NULL;
|
||||
|
||||
typedef struct errwarn_s {
|
||||
STAILQ_ENTRY(errwarn_s) link;
|
||||
/*@reldef@*/ STAILQ_ENTRY(errwarn_s) link;
|
||||
|
||||
enum { WE_ERROR, WE_WARNING } type;
|
||||
|
||||
const char *filename;
|
||||
/*@dependent@*/ const char *filename;
|
||||
unsigned long line;
|
||||
/* FIXME: This should not be a fixed size. But we don't have vasprintf()
|
||||
* right now. */
|
||||
|
|
@ -168,12 +171,16 @@ Error(const char *fmt, ...)
|
|||
we->line = line_number;
|
||||
}
|
||||
|
||||
assert(we != NULL);
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsprintf(we->msg, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
/*@-branchstate@*/
|
||||
if (!previous_error_parser)
|
||||
STAILQ_INSERT_TAIL(errwarns, we, link);
|
||||
/*@=branchstate@*/
|
||||
|
||||
previous_error_line = line_number;
|
||||
previous_error_parser = 0;
|
||||
|
|
@ -241,7 +248,7 @@ ErrorAt(const char *filename, unsigned long line, const char *fmt, ...)
|
|||
/* XXX: Should insert into list instead of printing immediately */
|
||||
va_list ap;
|
||||
|
||||
fprintf(stderr, "%s:%lu: ", filename, line);
|
||||
fprintf(stderr, "%s:%lu: ", filename?filename:"(NULL)", line);
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
|
|
@ -254,7 +261,8 @@ WarningAt(const char *filename, unsigned long line, const char *fmt, ...)
|
|||
/* XXX: Should insert into list instead of printing immediately */
|
||||
va_list ap;
|
||||
|
||||
fprintf(stderr, "%s:%lu: %s ", filename, line, _("warning:"));
|
||||
fprintf(stderr, "%s:%lu: %s ", filename?filename:"NULL", line,
|
||||
_("warning:"));
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
|
|
|
|||
|
|
@ -30,30 +30,33 @@ typedef enum {
|
|||
FATAL_NOMEM
|
||||
} fatal_num;
|
||||
|
||||
char *conv_unprint(char ch);
|
||||
/*@shared@*/ char *conv_unprint(char ch);
|
||||
|
||||
void ParserError(const char *);
|
||||
|
||||
void InternalError_(const char *file, unsigned int line, const char *message);
|
||||
/*@exits@*/ void InternalError_(const char *file, unsigned int line,
|
||||
const char *message);
|
||||
#define InternalError(msg) InternalError_(__FILE__, __LINE__, msg)
|
||||
|
||||
void Fatal(fatal_num);
|
||||
void Error(const char *, ...);
|
||||
void Warning(const char *, ...);
|
||||
/*@exits@*/ void Fatal(fatal_num);
|
||||
void Error(const char *, ...) /*@printflike@*/;
|
||||
void Warning(const char *, ...) /*@printflike@*/;
|
||||
|
||||
/* Use Error() and Warning() instead of ErrorAt() and WarningAt() when being
|
||||
* called in line order from a parser. The *At() functions are much slower,
|
||||
* at least in the current implementation.
|
||||
*/
|
||||
void ErrorAt(const char *filename, unsigned long line, const char *, ...);
|
||||
void WarningAt(const char *filename, unsigned long line, const char *, ...);
|
||||
void ErrorAt(/*@null@*/ const char *filename, unsigned long line, const char *,
|
||||
...) /*@printflike@*/;
|
||||
void WarningAt(/*@null@*/ const char *filename, unsigned long line,
|
||||
const char *, ...) /*@printflike@*/;
|
||||
|
||||
/* These two functions immediately output the error or warning, with no file
|
||||
* or line information. They should be used for errors and warnings outside
|
||||
* the parser stage (at program startup, for instance).
|
||||
*/
|
||||
void ErrorNow(const char *, ...);
|
||||
void WarningNow(const char *, ...);
|
||||
void ErrorNow(const char *, ...) /*@printflike@*/;
|
||||
void WarningNow(const char *, ...) /*@printflike@*/;
|
||||
|
||||
/* Returns total number of errors to this point in assembly. */
|
||||
unsigned int OutputAllErrorWarning(void);
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ struct ExprItem {
|
|||
*/
|
||||
struct expr {
|
||||
ExprOp op;
|
||||
const char *filename;
|
||||
/*@dependent@*/ /*@null@*/ const char *filename;
|
||||
unsigned long line;
|
||||
int numterms;
|
||||
ExprItem terms[2]; /* structure may be extended to include more */
|
||||
|
|
@ -63,14 +63,19 @@ struct expr {
|
|||
*
|
||||
* Stops early (and returns 1) if func returns 1. Otherwise returns 0.
|
||||
*/
|
||||
int expr_traverse_leaves_in(expr *e, void *d,
|
||||
int (*func) (ExprItem *ei, void *d));
|
||||
int expr_traverse_leaves_in(expr *e, /*@null@*/ void *d,
|
||||
int (*func) (/*@null@*/ ExprItem *ei,
|
||||
/*@null@*/ void *d));
|
||||
|
||||
/* Transform negatives throughout an entire expn tree */
|
||||
expr *expr_xform_neg_tree(expr *e);
|
||||
/*@only@*/ /*@null@*/ expr *expr_xform_neg_tree(/*@returned@*/ /*@only@*/
|
||||
/*@null@*/ expr *e);
|
||||
|
||||
/* Level an entire expn tree */
|
||||
expr *expr_level_tree(expr *e, int fold_const, int simplify_ident);
|
||||
/*@only@*/ /*@null@*/ expr *expr_level_tree(/*@returned@*/ /*@only@*/
|
||||
/*@null@*/ expr *e,
|
||||
int fold_const,
|
||||
int simplify_ident);
|
||||
|
||||
/* Reorder terms of e into canonical order. Only reorders if reordering
|
||||
* doesn't change meaning of expression. (eg, doesn't reorder SUB).
|
||||
|
|
@ -82,7 +87,7 @@ expr *expr_level_tree(expr *e, int fold_const, int simplify_ident);
|
|||
void expr_order_terms(expr *e);
|
||||
|
||||
/* Copy entire expression EXCEPT for index "except" at *top level only*. */
|
||||
expr *expr_copy_except(const expr *e, int except);
|
||||
/*@null@*/ expr *expr_copy_except(const expr *e, int except);
|
||||
|
||||
int expr_contains(expr *e, ExprType t);
|
||||
|
||||
|
|
|
|||
56
src/expr.c
56
src/expr.c
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "bitvect.h"
|
||||
|
||||
|
|
@ -34,15 +34,17 @@ RCSID("$IdPath$");
|
|||
#include "expr-int.h"
|
||||
|
||||
|
||||
static int expr_traverse_nodes_post(expr *e, void *d,
|
||||
int (*func) (expr *e, void *d));
|
||||
static int expr_traverse_nodes_post(/*@null@*/ expr *e, /*@null@*/ void *d,
|
||||
int (*func) (/*@null@*/ expr *e,
|
||||
/*@null@*/ void *d));
|
||||
|
||||
/* allocate a new expression node, with children as defined.
|
||||
* If it's a unary operator, put the element in left and set right=NULL. */
|
||||
/*@-usedef@*/
|
||||
expr *
|
||||
expr_new(ExprOp op, ExprItem *left, ExprItem *right)
|
||||
{
|
||||
expr *ptr;
|
||||
expr *ptr, *sube;
|
||||
ptr = xmalloc(sizeof(expr));
|
||||
|
||||
ptr->op = op;
|
||||
|
|
@ -59,9 +61,11 @@ expr_new(ExprOp op, ExprItem *left, ExprItem *right)
|
|||
*/
|
||||
while (ptr->terms[0].type == EXPR_EXPR &&
|
||||
ptr->terms[0].data.expn->op == EXPR_IDENT) {
|
||||
expr *sube = ptr->terms[0].data.expn;
|
||||
sube = ptr->terms[0].data.expn;
|
||||
ptr->terms[0] = sube->terms[0]; /* structure copy */
|
||||
/*@-usereleased@*/
|
||||
xfree(sube);
|
||||
/*@=usereleased@*/
|
||||
}
|
||||
} else {
|
||||
InternalError(_("Right side of expression must exist"));
|
||||
|
|
@ -77,9 +81,11 @@ expr_new(ExprOp op, ExprItem *left, ExprItem *right)
|
|||
*/
|
||||
while (ptr->terms[1].type == EXPR_EXPR &&
|
||||
ptr->terms[1].data.expn->op == EXPR_IDENT) {
|
||||
expr *sube = ptr->terms[1].data.expn;
|
||||
sube = ptr->terms[1].data.expn;
|
||||
ptr->terms[1] = sube->terms[0]; /* structure copy */
|
||||
/*@-usereleased@*/
|
||||
xfree(sube);
|
||||
/*@=usereleased@*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,6 +94,7 @@ expr_new(ExprOp op, ExprItem *left, ExprItem *right)
|
|||
|
||||
return ptr;
|
||||
}
|
||||
/*@=usedef@*/
|
||||
|
||||
/* helpers */
|
||||
ExprItem *
|
||||
|
|
@ -148,7 +155,7 @@ expr_xform_neg_item(expr *e, ExprItem *ei)
|
|||
sube->line = e->line;
|
||||
sube->numterms = 2;
|
||||
sube->terms[0].type = EXPR_INT;
|
||||
sube->terms[0].data.intn = intnum_new_int(-1);
|
||||
sube->terms[0].data.intn = intnum_new_int((unsigned long)-1);
|
||||
sube->terms[1] = *ei; /* structure copy */
|
||||
|
||||
/* Replace original ExprItem with subexp */
|
||||
|
|
@ -162,8 +169,8 @@ expr_xform_neg_item(expr *e, ExprItem *ei)
|
|||
*
|
||||
* Returns a possibly reallocated e.
|
||||
*/
|
||||
static expr *
|
||||
expr_xform_neg_helper(expr *e)
|
||||
static /*@only@*/ expr *
|
||||
expr_xform_neg_helper(/*@returned@*/ /*@only@*/ expr *e)
|
||||
{
|
||||
expr *ne;
|
||||
int i;
|
||||
|
|
@ -197,7 +204,7 @@ expr_xform_neg_helper(expr *e)
|
|||
e->op = EXPR_MUL;
|
||||
e->numterms = 2;
|
||||
e->terms[1].type = EXPR_INT;
|
||||
e->terms[1].data.intn = intnum_new_int(-1);
|
||||
e->terms[1].data.intn = intnum_new_int((unsigned long)-1);
|
||||
break;
|
||||
default:
|
||||
/* Everything else. MUL will be combined when it's leveled.
|
||||
|
|
@ -209,7 +216,7 @@ expr_xform_neg_helper(expr *e)
|
|||
ne->line = e->line;
|
||||
ne->numterms = 2;
|
||||
ne->terms[0].type = EXPR_INT;
|
||||
ne->terms[0].data.intn = intnum_new_int(-1);
|
||||
ne->terms[0].data.intn = intnum_new_int((unsigned long)-1);
|
||||
ne->terms[1].type = EXPR_EXPR;
|
||||
ne->terms[1].data.expn = e;
|
||||
return ne;
|
||||
|
|
@ -225,8 +232,8 @@ expr_xform_neg_helper(expr *e)
|
|||
*
|
||||
* Returns a possibly reallocated e.
|
||||
*/
|
||||
static expr *
|
||||
expr_xform_neg(expr *e)
|
||||
static /*@only@*/ expr *
|
||||
expr_xform_neg(/*@returned@*/ /*@only@*/ expr *e)
|
||||
{
|
||||
switch (e->op) {
|
||||
case EXPR_NEG:
|
||||
|
|
@ -385,8 +392,10 @@ expr_simplify_identity(expr *e, int numterms, int int_term)
|
|||
*
|
||||
* Returns a possibly reallocated e.
|
||||
*/
|
||||
static expr *
|
||||
expr_level_op(expr *e, int fold_const, int simplify_ident)
|
||||
/*@-mustfree@*/
|
||||
static /*@only@*/ expr *
|
||||
expr_level_op(/*@returned@*/ /*@only@*/ expr *e, int fold_const,
|
||||
int simplify_ident)
|
||||
{
|
||||
int i, j, o, fold_numterms, level_numterms, level_fold_numterms;
|
||||
int first_int_term = -1;
|
||||
|
|
@ -546,6 +555,7 @@ expr_level_op(expr *e, int fold_const, int simplify_ident)
|
|||
|
||||
return e;
|
||||
}
|
||||
/*@=mustfree@*/
|
||||
|
||||
/* Level an entire expn tree */
|
||||
expr *
|
||||
|
|
@ -603,7 +613,7 @@ expr_order_terms(expr *e)
|
|||
* stable sort (multiple terms of same type are kept in the same
|
||||
* order).
|
||||
*/
|
||||
mergesort(e->terms, e->numterms, sizeof(ExprItem),
|
||||
mergesort(e->terms, (size_t)e->numterms, sizeof(ExprItem),
|
||||
expr_order_terms_compare);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -666,7 +676,7 @@ expr_copy(const expr *e)
|
|||
}
|
||||
|
||||
static int
|
||||
expr_delete_each(expr *e, void *d)
|
||||
expr_delete_each(/*@only@*/ expr *e, /*@unused@*/ void *d)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<e->numterms; i++) {
|
||||
|
|
@ -685,11 +695,13 @@ expr_delete_each(expr *e, void *d)
|
|||
return 0; /* don't stop recursion */
|
||||
}
|
||||
|
||||
/*@-mustfree@*/
|
||||
void
|
||||
expr_delete(expr *e)
|
||||
{
|
||||
expr_traverse_nodes_post(e, NULL, expr_delete_each);
|
||||
}
|
||||
/*@=mustfree@*/
|
||||
|
||||
static int
|
||||
expr_contains_callback(ExprItem *ei, void *d)
|
||||
|
|
@ -705,7 +717,7 @@ expr_contains(expr *e, ExprType t)
|
|||
}
|
||||
|
||||
static int
|
||||
expr_expand_equ_callback(ExprItem *ei, void *d)
|
||||
expr_expand_equ_callback(ExprItem *ei, /*@unused@*/ void *d)
|
||||
{
|
||||
const expr *equ_expr;
|
||||
if (ei->type == EXPR_SYM) {
|
||||
|
|
@ -731,7 +743,8 @@ expr_expand_equ(expr *e)
|
|||
* Stops early (and returns 1) if func returns 1. Otherwise returns 0.
|
||||
*/
|
||||
static int
|
||||
expr_traverse_nodes_post(expr *e, void *d, int (*func) (expr *e, void *d))
|
||||
expr_traverse_nodes_post(expr *e, void *d,
|
||||
int (*func) (/*@null@*/ expr *e, /*@null@*/ void *d))
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -756,7 +769,8 @@ expr_traverse_nodes_post(expr *e, void *d, int (*func) (expr *e, void *d))
|
|||
*/
|
||||
int
|
||||
expr_traverse_leaves_in(expr *e, void *d,
|
||||
int (*func) (ExprItem *ei, void *d))
|
||||
int (*func) (/*@null@*/ ExprItem *ei,
|
||||
/*@null@*/ void *d))
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -784,6 +798,7 @@ expr_simplify(expr *e)
|
|||
return e;
|
||||
}
|
||||
|
||||
/*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/
|
||||
const intnum *
|
||||
expr_get_intnum(expr **ep)
|
||||
{
|
||||
|
|
@ -794,6 +809,7 @@ expr_get_intnum(expr **ep)
|
|||
else
|
||||
return (intnum *)NULL;
|
||||
}
|
||||
/*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/
|
||||
|
||||
void
|
||||
expr_print(expr *e)
|
||||
|
|
|
|||
22
src/expr.h
22
src/expr.h
|
|
@ -24,13 +24,14 @@
|
|||
|
||||
typedef struct ExprItem ExprItem;
|
||||
|
||||
expr *expr_new(ExprOp, ExprItem *, ExprItem *);
|
||||
/*@only@*/ expr *expr_new(ExprOp, /*@only@*/ ExprItem *,
|
||||
/*@only@*/ /*@null@*/ ExprItem *);
|
||||
|
||||
ExprItem *ExprSym(symrec *);
|
||||
ExprItem *ExprExpr(expr *);
|
||||
ExprItem *ExprInt(intnum *);
|
||||
ExprItem *ExprFloat(floatnum *);
|
||||
ExprItem *ExprReg(unsigned char reg, unsigned char size);
|
||||
/*@only@*/ ExprItem *ExprSym(/*@keep@*/ symrec *);
|
||||
/*@only@*/ ExprItem *ExprExpr(/*@keep@*/ expr *);
|
||||
/*@only@*/ ExprItem *ExprInt(/*@keep@*/ intnum *);
|
||||
/*@only@*/ ExprItem *ExprFloat(/*@keep@*/ floatnum *);
|
||||
/*@only@*/ ExprItem *ExprReg(unsigned char reg, unsigned char size);
|
||||
|
||||
#define expr_new_tree(l,o,r) \
|
||||
expr_new ((o), ExprExpr(l), ExprExpr(r))
|
||||
|
|
@ -40,9 +41,9 @@ ExprItem *ExprReg(unsigned char reg, unsigned char size);
|
|||
expr_new (EXPR_IDENT, (r), (ExprItem *)NULL)
|
||||
|
||||
/* allocates and makes an exact duplicate of e */
|
||||
expr *expr_copy(const expr *e);
|
||||
/*@null@*/ expr *expr_copy(const expr *e);
|
||||
|
||||
void expr_delete(expr *e);
|
||||
void expr_delete(/*@only@*/ /*@null@*/ expr *e);
|
||||
|
||||
/* Expands all (symrec) equ's in the expression into full expression
|
||||
* instances.
|
||||
|
|
@ -52,13 +53,14 @@ void expr_expand_equ(expr *e);
|
|||
/* Simplifies the expression e as much as possible, eliminating extraneous
|
||||
* branches and simplifying integer-only subexpressions.
|
||||
*/
|
||||
expr *expr_simplify(expr *e);
|
||||
/*@only@*/ /*@null@*/ expr *expr_simplify(/*@returned@*/ /*@only@*/ /*@null@*/
|
||||
expr *e);
|
||||
|
||||
/* Gets the integer value of e if the expression is just an integer. If the
|
||||
* expression is more complex (contains anything other than integers, ie
|
||||
* floats, non-valued labels, registers), returns NULL.
|
||||
*/
|
||||
const intnum *expr_get_intnum(expr **ep);
|
||||
/*@dependent@*/ /*@null@*/ const intnum *expr_get_intnum(expr **ep);
|
||||
|
||||
void expr_print(expr *);
|
||||
|
||||
|
|
|
|||
10
src/file.c
10
src/file.c
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "file.h"
|
||||
|
||||
|
|
@ -38,13 +38,13 @@ fwrite_short(unsigned short val, FILE *f)
|
|||
size_t
|
||||
fwrite_long(unsigned long val, FILE *f)
|
||||
{
|
||||
if (fputc(val & 0xFF, f) == EOF)
|
||||
if (fputc((int)(val & 0xFF), f) == EOF)
|
||||
return 0;
|
||||
if (fputc((val >> 8) & 0xFF, f) == EOF)
|
||||
if (fputc((int)((val >> 8) & 0xFF), f) == EOF)
|
||||
return 0;
|
||||
if (fputc((val >> 16) & 0xFF, f) == EOF)
|
||||
if (fputc((int)((val >> 16) & 0xFF), f) == EOF)
|
||||
return 0;
|
||||
if (fputc((val >> 24) & 0xFF, f) == EOF)
|
||||
if (fputc((int)((val >> 24) & 0xFF), f) == EOF)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
10
src/file.h
10
src/file.h
|
|
@ -25,7 +25,7 @@
|
|||
/* These functions only work properly if p is an (unsigned char *) */
|
||||
|
||||
#define WRITE_BYTE(ptr, val) \
|
||||
*((ptr)++) = (val) & 0xFF
|
||||
*((ptr)++) = (unsigned char)((val) & 0xFF)
|
||||
|
||||
#define WRITE_SHORT(ptr, val) \
|
||||
do { \
|
||||
|
|
@ -101,10 +101,10 @@ size_t fwrite_long(unsigned long val, FILE *f);
|
|||
|
||||
#define LOAD_LONG(val, ptr) \
|
||||
do { \
|
||||
(val) = *(ptr) & 0xFF; \
|
||||
(val) |= (*((ptr)+1) & 0xFF) << 8; \
|
||||
(val) |= (*((ptr)+2) & 0xFF) << 16; \
|
||||
(val) |= (*((ptr)+3) & 0xFF) << 24; \
|
||||
(val) = (unsigned long)(*(ptr) & 0xFF); \
|
||||
(val) |= (unsigned long)((*((ptr)+1) & 0xFF) << 8); \
|
||||
(val) |= (unsigned long)((*((ptr)+2) & 0xFF) << 16); \
|
||||
(val) |= (unsigned long)((*((ptr)+3) & 0xFF) << 24); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ RCSID("$IdPath$");
|
|||
* Mantissa does NOT have an implied one bit (it's explicit).
|
||||
*/
|
||||
struct floatnum {
|
||||
wordptr mantissa; /* Allocated to MANT_BITS bits */
|
||||
/*@only@*/ wordptr mantissa; /* Allocated to MANT_BITS bits */
|
||||
unsigned short exponent;
|
||||
unsigned char sign;
|
||||
unsigned char flags;
|
||||
|
|
@ -84,7 +84,9 @@ typedef struct POT_Entry_Source_s {
|
|||
* entry[12-n] = 10 ** (-2 ** n) for 0 <= n <= 12.
|
||||
* entry[13] = 1.0
|
||||
*/
|
||||
static POT_Entry *POT_TableN = (POT_Entry *)NULL;
|
||||
/*@-nullassign@*/
|
||||
static /*@only@*/ POT_Entry *POT_TableN = (POT_Entry *)NULL;
|
||||
/*@=nullassign@*/
|
||||
static POT_Entry_Source POT_TableN_Source[] = {
|
||||
{{0xe3,0x2d,0xde,0x9f,0xce,0xd2,0xc8,0x04,0xdd,0xa6},0x4ad8}, /* 1e-4096 */
|
||||
{{0x25,0x49,0xe4,0x2d,0x36,0x34,0x4f,0x53,0xae,0xce},0x656b}, /* 1e-2048 */
|
||||
|
|
@ -112,7 +114,7 @@ static POT_Entry_Source POT_TableN_Source[] = {
|
|||
* before the table. This -1 entry is created at runtime by duplicating the
|
||||
* 0 entry.
|
||||
*/
|
||||
static POT_Entry *POT_TableP;
|
||||
static /*@only@*/ POT_Entry *POT_TableP;
|
||||
static POT_Entry_Source POT_TableP_Source[] = {
|
||||
{{0x4c,0xc9,0x9a,0x97,0x20,0x8a,0x02,0x52,0x60,0xc4},0xb525}, /* 1e+4096 */
|
||||
{{0x4d,0xa7,0xe4,0x5d,0x3d,0xc5,0x5d,0x3b,0x8b,0x9e},0x9a92}, /* 1e+2048 */
|
||||
|
|
@ -131,7 +133,7 @@ static POT_Entry_Source POT_TableP_Source[] = {
|
|||
};
|
||||
|
||||
static void
|
||||
POT_Table_Init_Entry(POT_Entry *e, POT_Entry_Source *s, int dec_exp)
|
||||
POT_Table_Init_Entry(/*@out@*/ POT_Entry *e, POT_Entry_Source *s, int dec_exp)
|
||||
{
|
||||
/* Save decimal exponent */
|
||||
e->dec_exponent = dec_exp;
|
||||
|
|
@ -150,10 +152,12 @@ POT_Table_Init_Entry(POT_Entry *e, POT_Entry_Source *s, int dec_exp)
|
|||
e->f.flags = 0;
|
||||
}
|
||||
|
||||
/*@-compdef@*/
|
||||
static void
|
||||
POT_Table_Init(void)
|
||||
/*@globals undef POT_TableN, undef POT_TableP @*/
|
||||
{
|
||||
unsigned int dec_exp = 1;
|
||||
int dec_exp = 1;
|
||||
int i;
|
||||
|
||||
/* Allocate space for two POT tables */
|
||||
|
|
@ -177,11 +181,12 @@ POT_Table_Init(void)
|
|||
/* Offset POT_TableP so that [0] becomes [-1] */
|
||||
POT_TableP++;
|
||||
}
|
||||
/*@=compdef@*/
|
||||
|
||||
static void
|
||||
floatnum_normalize(floatnum *flt)
|
||||
{
|
||||
int norm_amt;
|
||||
long norm_amt;
|
||||
|
||||
if (BitVector_is_empty(flt->mantissa)) {
|
||||
flt->exponent = 0;
|
||||
|
|
@ -191,9 +196,9 @@ floatnum_normalize(floatnum *flt)
|
|||
/* Look for the highest set bit, shift to make it the MSB, and adjust
|
||||
* exponent. Don't let exponent go negative. */
|
||||
norm_amt = (MANT_BITS-1)-Set_Max(flt->mantissa);
|
||||
if (norm_amt > flt->exponent)
|
||||
norm_amt = flt->exponent;
|
||||
BitVector_Move_Left(flt->mantissa, norm_amt);
|
||||
if (norm_amt > (long)flt->exponent)
|
||||
norm_amt = (long)flt->exponent;
|
||||
BitVector_Move_Left(flt->mantissa, (N_int)norm_amt);
|
||||
flt->exponent -= norm_amt;
|
||||
}
|
||||
|
||||
|
|
@ -201,9 +206,9 @@ floatnum_normalize(floatnum *flt)
|
|||
static void
|
||||
floatnum_mul(floatnum *acc, const floatnum *op)
|
||||
{
|
||||
int exp;
|
||||
long exp;
|
||||
wordptr product, op1, op2;
|
||||
int norm_amt;
|
||||
long norm_amt;
|
||||
|
||||
/* Compute the new sign */
|
||||
acc->sign ^= op->sign;
|
||||
|
|
@ -231,14 +236,14 @@ floatnum_mul(floatnum *acc, const floatnum *op)
|
|||
}
|
||||
|
||||
/* Add one to the final exponent, as the multiply shifts one extra time. */
|
||||
acc->exponent = exp+1;
|
||||
acc->exponent = (unsigned short)(exp+1);
|
||||
|
||||
/* Allocate space for the multiply result */
|
||||
product = BitVector_Create((MANT_BITS+1)*2, FALSE);
|
||||
product = BitVector_Create((N_int)((MANT_BITS+1)*2), FALSE);
|
||||
|
||||
/* Allocate 1-bit-longer fields to force the operands to be unsigned */
|
||||
op1 = BitVector_Create(MANT_BITS+1, FALSE);
|
||||
op2 = BitVector_Create(MANT_BITS+1, FALSE);
|
||||
op1 = BitVector_Create((N_int)(MANT_BITS+1), FALSE);
|
||||
op2 = BitVector_Create((N_int)(MANT_BITS+1), FALSE);
|
||||
|
||||
/* Make the operands unsigned after copying from original operands */
|
||||
BitVector_Copy(op1, acc->mantissa);
|
||||
|
|
@ -256,9 +261,9 @@ floatnum_mul(floatnum *acc, const floatnum *op)
|
|||
* exponent. Don't let exponent go negative.
|
||||
*/
|
||||
norm_amt = (MANT_BITS*2-1)-Set_Max(product);
|
||||
if (norm_amt > acc->exponent)
|
||||
norm_amt = acc->exponent;
|
||||
BitVector_Move_Left(product, norm_amt);
|
||||
if (norm_amt > (long)acc->exponent)
|
||||
norm_amt = (long)acc->exponent;
|
||||
BitVector_Move_Left(product, (N_int)norm_amt);
|
||||
acc->exponent -= norm_amt;
|
||||
|
||||
/* Store the highest bits of the result */
|
||||
|
|
@ -338,7 +343,7 @@ floatnum_new(const char *str)
|
|||
|
||||
/* Add in current digit */
|
||||
BitVector_Empty(operand[0]);
|
||||
BitVector_Chunk_Store(operand[0], 4, 0, *str-'0');
|
||||
BitVector_Chunk_Store(operand[0], 4, 0, (N_long)(*str-'0'));
|
||||
carry = 0;
|
||||
BitVector_add(flt->mantissa, operand[1], operand[0], &carry);
|
||||
} else {
|
||||
|
|
@ -374,7 +379,7 @@ floatnum_new(const char *str)
|
|||
|
||||
/* Add in current digit */
|
||||
BitVector_Empty(operand[0]);
|
||||
BitVector_Chunk_Store(operand[0], 4, 0, *str-'0');
|
||||
BitVector_Chunk_Store(operand[0], 4, 0, (N_long)(*str-'0'));
|
||||
carry = 0;
|
||||
BitVector_add(flt->mantissa, operand[1], operand[0], &carry);
|
||||
}
|
||||
|
|
@ -405,7 +410,8 @@ floatnum_new(const char *str)
|
|||
|
||||
return flt;
|
||||
}
|
||||
flt->exponent = 0x7FFF+(MANT_BITS-1); /* Exponent if already norm. */
|
||||
/* Exponent if already norm. */
|
||||
flt->exponent = (unsigned short)(0x7FFF+(MANT_BITS-1));
|
||||
floatnum_normalize(flt);
|
||||
|
||||
/* The number is normalized. Now multiply by 10 the number of times
|
||||
|
|
@ -480,7 +486,7 @@ floatnum_delete(floatnum *flt)
|
|||
}
|
||||
|
||||
void
|
||||
floatnum_calc(floatnum *acc, ExprOp op, floatnum *operand)
|
||||
floatnum_calc(floatnum *acc, ExprOp op, /*@unused@*/ floatnum *operand)
|
||||
{
|
||||
if (op != EXPR_NEG)
|
||||
Error(_("Unsupported floating-point arithmetic operation"));
|
||||
|
|
@ -512,22 +518,25 @@ floatnum_get_int(const floatnum *flt, unsigned long *ret_val)
|
|||
* Returns 0 on success, 1 if overflow, -1 if underflow.
|
||||
*/
|
||||
static int
|
||||
floatnum_get_common(const floatnum *flt, unsigned char *ptr, int byte_size,
|
||||
int mant_bits, int implicit1, int exp_bits)
|
||||
floatnum_get_common(const floatnum *flt, /*@out@*/ unsigned char *ptr,
|
||||
N_int byte_size, N_int mant_bits, int implicit1,
|
||||
N_int exp_bits)
|
||||
{
|
||||
int exponent = flt->exponent;
|
||||
long exponent = (long)flt->exponent;
|
||||
wordptr output;
|
||||
charptr buf;
|
||||
unsigned int len;
|
||||
unsigned int overflow = 0, underflow = 0, retval = 0;
|
||||
int exp_bias = (1<<(exp_bits-1))-1;
|
||||
int exp_inf = (1<<exp_bits)-1;
|
||||
unsigned int overflow = 0, underflow = 0;
|
||||
int retval = 0;
|
||||
long exp_bias = (1<<(exp_bits-1))-1;
|
||||
long exp_inf = (1<<exp_bits)-1;
|
||||
|
||||
output = BitVector_Create(byte_size*8, TRUE);
|
||||
|
||||
/* copy mantissa */
|
||||
BitVector_Interval_Copy(output, flt->mantissa, 0,
|
||||
(MANT_BITS-implicit1)-mant_bits, mant_bits);
|
||||
(N_int)((MANT_BITS-implicit1)-mant_bits),
|
||||
mant_bits);
|
||||
|
||||
/* round mantissa */
|
||||
if (BitVector_bit_test(flt->mantissa, (MANT_BITS-implicit1)-(mant_bits+1)))
|
||||
|
|
@ -568,7 +577,7 @@ floatnum_get_common(const floatnum *flt, unsigned char *ptr, int byte_size,
|
|||
}
|
||||
|
||||
/* move exponent into place */
|
||||
BitVector_Chunk_Store(output, exp_bits, mant_bits, exponent);
|
||||
BitVector_Chunk_Store(output, exp_bits, mant_bits, (N_long)exponent);
|
||||
|
||||
/* merge in sign bit */
|
||||
BitVector_Bit_Copy(output, byte_size*8-1, flt->sign);
|
||||
|
|
@ -631,13 +640,14 @@ floatnum_get_sized(const floatnum *flt, unsigned char *ptr, size_t size)
|
|||
return floatnum_get_common(flt, ptr, 10, 64, 0, 15);
|
||||
default:
|
||||
InternalError(_("Invalid float conversion size"));
|
||||
/*@notreached@*/
|
||||
return 1; /* never reached, but silence GCC warning */
|
||||
}
|
||||
}
|
||||
|
||||
/* 1 if the size is valid, 0 if it isn't */
|
||||
int
|
||||
floatnum_check_size(const floatnum *flt, size_t size)
|
||||
floatnum_check_size(/*@unused@*/ const floatnum *flt, size_t size)
|
||||
{
|
||||
switch (size) {
|
||||
case 4:
|
||||
|
|
@ -658,7 +668,7 @@ floatnum_print(const floatnum *flt)
|
|||
|
||||
/* Internal format */
|
||||
str = BitVector_to_Hex(flt->mantissa);
|
||||
printf("%c %s *2^%04x\n", flt->sign?'-':'+', str, flt->exponent);
|
||||
printf("%c %s *2^%04x\n", flt->sign?'-':'+', (char *)str, flt->exponent);
|
||||
xfree(str);
|
||||
|
||||
/* 32-bit (single precision) format */
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@
|
|||
#ifndef YASM_FLOATNUM_H
|
||||
#define YASM_FLOATNUM_H
|
||||
|
||||
floatnum *floatnum_new(const char *str);
|
||||
floatnum *floatnum_copy(const floatnum *flt);
|
||||
void floatnum_delete(floatnum *flt);
|
||||
/*@only@*/ floatnum *floatnum_new(const char *str);
|
||||
/*@only@*/ floatnum *floatnum_copy(const floatnum *flt);
|
||||
void floatnum_delete(/*@only@*/ floatnum *flt);
|
||||
|
||||
/* calculation function: acc = acc op operand */
|
||||
void floatnum_calc(floatnum *acc, ExprOp op, floatnum *operand);
|
||||
|
|
@ -38,12 +38,13 @@ void floatnum_calc(floatnum *acc, ExprOp op, floatnum *operand);
|
|||
/* Essentially a convert to single-precision and return as 32-bit value.
|
||||
* The 32-bit value is a "standard" C value (eg, of unknown endian).
|
||||
*/
|
||||
int floatnum_get_int(const floatnum *flt, unsigned long *ret_val);
|
||||
int floatnum_get_int(const floatnum *flt, /*@out@*/ unsigned long *ret_val);
|
||||
|
||||
/* ptr will point to the Intel-format little-endian byte string after a
|
||||
* successful call (eg, [0] should be the first byte output to the file).
|
||||
*/
|
||||
int floatnum_get_sized(const floatnum *flt, unsigned char *ptr, size_t size);
|
||||
int floatnum_get_sized(const floatnum *flt, /*@out@*/ unsigned char *ptr,
|
||||
size_t size);
|
||||
|
||||
/* Basic check to see if size is even valid for flt conversion (doesn't
|
||||
* actually check for underflow/overflow but rather checks for size=4,8,10).
|
||||
|
|
|
|||
|
|
@ -20,30 +20,32 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "ternary.h"
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
|
||||
const char *in_filename = (const char *)NULL;
|
||||
/*@null@*/ /*@dependent@*/ const char *in_filename = (const char *)NULL;
|
||||
unsigned int line_number = 1;
|
||||
unsigned int asm_options = 0;
|
||||
|
||||
static ternary_tree filename_table = (ternary_tree)NULL;
|
||||
static /*@only@*/ /*@null@*/ ternary_tree filename_table = (ternary_tree)NULL;
|
||||
|
||||
void
|
||||
switch_filename(const char *filename)
|
||||
{
|
||||
char *copy = xstrdup(filename);
|
||||
in_filename = ternary_insert(&filename_table, filename, copy, 0);
|
||||
/*@-branchstate@*/
|
||||
if (in_filename != copy)
|
||||
xfree(copy);
|
||||
/*@=branchstate@*/
|
||||
}
|
||||
|
||||
static void
|
||||
filename_delete_one(void *d)
|
||||
filename_delete_one(/*@only@*/ void *d)
|
||||
{
|
||||
xfree(d);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#ifndef YASM_GLOBALS_H
|
||||
#define YASM_GLOBALS_H
|
||||
|
||||
extern const char *in_filename;
|
||||
/*@null@*/ /*@dependent@*/ extern const char *in_filename;
|
||||
extern unsigned int line_number;
|
||||
extern unsigned int asm_options;
|
||||
|
||||
|
|
|
|||
29
src/intnum.c
29
src/intnum.c
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ intnum_new_bin(char *str)
|
|||
intnum *intn = xmalloc(sizeof(intnum));
|
||||
wordptr bv;
|
||||
|
||||
intn->origsize = strlen(str);
|
||||
intn->origsize = (unsigned char)strlen(str);
|
||||
|
||||
if(intn->origsize > BITVECT_ALLOC_SIZE)
|
||||
Warning(_("Numeric constant too large for internal format"));
|
||||
|
|
@ -140,6 +140,7 @@ intnum_new_hex(char *str)
|
|||
return intn;
|
||||
}
|
||||
|
||||
/*@-usedef -compdef -uniondef@*/
|
||||
intnum *
|
||||
intnum_new_charconst_nasm(const char *str)
|
||||
{
|
||||
|
|
@ -157,18 +158,22 @@ intnum_new_charconst_nasm(const char *str)
|
|||
case 4:
|
||||
intn->val.ul |= (unsigned long)str[3];
|
||||
intn->val.ul <<= 8;
|
||||
/*@fallthrough@*/
|
||||
case 3:
|
||||
intn->val.ul |= (unsigned long)str[2];
|
||||
intn->val.ul <<= 8;
|
||||
/*@fallthrough@*/
|
||||
case 2:
|
||||
intn->val.ul |= (unsigned long)str[1];
|
||||
intn->val.ul <<= 8;
|
||||
/*@fallthrough@*/
|
||||
case 1:
|
||||
intn->val.ul |= (unsigned long)str[0];
|
||||
}
|
||||
|
||||
return intn;
|
||||
}
|
||||
/*@=usedef =compdef =uniondef@*/
|
||||
|
||||
intnum *
|
||||
intnum_new_int(unsigned long i)
|
||||
|
|
@ -209,11 +214,12 @@ intnum_delete(intnum *intn)
|
|||
xfree(intn);
|
||||
}
|
||||
|
||||
/*@-nullderef -nullpass -branchstate@*/
|
||||
void
|
||||
intnum_calc(intnum *acc, ExprOp op, intnum *operand)
|
||||
{
|
||||
wordptr result = (wordptr)NULL, op1 = (wordptr)NULL, op2 = (wordptr)NULL;
|
||||
wordptr spare;
|
||||
wordptr spare = (wordptr)NULL;
|
||||
boolean carry;
|
||||
|
||||
/* upsize to bitvector op if one of two parameters is bitvector already.
|
||||
|
|
@ -326,7 +332,7 @@ intnum_calc(intnum *acc, ExprOp op, intnum *operand)
|
|||
if (result) {
|
||||
if (operand->type == INTNUM_UL) {
|
||||
BitVector_Copy(result, op1);
|
||||
BitVector_Move_Left(result, operand->val.ul);
|
||||
BitVector_Move_Left(result, (N_int)operand->val.ul);
|
||||
} else /* don't even bother, just zero result */
|
||||
BitVector_Empty(result);
|
||||
} else
|
||||
|
|
@ -336,7 +342,7 @@ intnum_calc(intnum *acc, ExprOp op, intnum *operand)
|
|||
if (result) {
|
||||
if (operand->type == INTNUM_UL) {
|
||||
BitVector_Copy(result, op1);
|
||||
BitVector_Move_Right(result, operand->val.ul);
|
||||
BitVector_Move_Right(result, (N_int)operand->val.ul);
|
||||
} else /* don't even bother, just zero result */
|
||||
BitVector_Empty(result);
|
||||
} else
|
||||
|
|
@ -441,6 +447,7 @@ intnum_calc(intnum *acc, ExprOp op, intnum *operand)
|
|||
}
|
||||
}
|
||||
}
|
||||
/*@=nullderef =nullpass =branchstate@*/
|
||||
|
||||
int
|
||||
intnum_is_zero(intnum *intn)
|
||||
|
|
@ -459,7 +466,7 @@ intnum_is_pos1(intnum *intn)
|
|||
int
|
||||
intnum_is_neg1(intnum *intn)
|
||||
{
|
||||
return ((intn->type == INTNUM_UL && intn->val.ul == -1) ||
|
||||
return ((intn->type == INTNUM_UL && (long)intn->val.ul == -1) ||
|
||||
(intn->type == INTNUM_BV && BitVector_is_full(intn->val.bv)));
|
||||
}
|
||||
|
||||
|
|
@ -473,6 +480,7 @@ intnum_get_uint(const intnum *intn)
|
|||
return BitVector_Chunk_Read(intn->val.bv, 32, 0);
|
||||
default:
|
||||
InternalError(_("unknown intnum type"));
|
||||
/*@notreached@*/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -497,9 +505,10 @@ intnum_get_int(const intnum *intn)
|
|||
BitVector_Destroy(abs_bv);
|
||||
return retval;
|
||||
} else
|
||||
return BitVector_Chunk_Read(intn->val.bv, 32, 0);
|
||||
return (long)BitVector_Chunk_Read(intn->val.bv, 32, 0);
|
||||
default:
|
||||
InternalError(_("unknown intnum type"));
|
||||
/*@notreached@*/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -522,7 +531,7 @@ intnum_get_sized(const intnum *intn, unsigned char *ptr, size_t size)
|
|||
break;
|
||||
case INTNUM_BV:
|
||||
buf = BitVector_Block_Read(intn->val.bv, &len);
|
||||
if (len < size)
|
||||
if (len < (unsigned int)size)
|
||||
InternalError(_("Invalid size specified (too large)"));
|
||||
memcpy(ptr, buf, size);
|
||||
xfree(buf);
|
||||
|
|
@ -571,7 +580,6 @@ intnum_check_size(const intnum *intn, size_t size, int is_signed)
|
|||
return retval;
|
||||
} else
|
||||
return (Set_Max(intn->val.bv) < size*8);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (intn->type) {
|
||||
|
|
@ -592,7 +600,6 @@ intnum_check_size(const intnum *intn, size_t size, int is_signed)
|
|||
return 1;
|
||||
else
|
||||
return (Set_Max(intn->val.bv) < size*8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -609,7 +616,7 @@ intnum_print(const intnum *intn)
|
|||
break;
|
||||
case INTNUM_BV:
|
||||
s = BitVector_to_Hex(intn->val.bv);
|
||||
printf("0x%s/%u", s, (unsigned int)intn->origsize);
|
||||
printf("0x%s/%u", (char *)s, (unsigned int)intn->origsize);
|
||||
xfree(s);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
16
src/intnum.h
16
src/intnum.h
|
|
@ -22,15 +22,15 @@
|
|||
#ifndef YASM_INTNUM_H
|
||||
#define YASM_INTNUM_H
|
||||
|
||||
intnum *intnum_new_dec(char *str);
|
||||
intnum *intnum_new_bin(char *str);
|
||||
intnum *intnum_new_oct(char *str);
|
||||
intnum *intnum_new_hex(char *str);
|
||||
/*@only@*/ intnum *intnum_new_dec(char *str);
|
||||
/*@only@*/ intnum *intnum_new_bin(char *str);
|
||||
/*@only@*/ intnum *intnum_new_oct(char *str);
|
||||
/*@only@*/ intnum *intnum_new_hex(char *str);
|
||||
/* convert character constant to integer value, using NASM rules */
|
||||
intnum *intnum_new_charconst_nasm(const char *str);
|
||||
intnum *intnum_new_int(unsigned long i);
|
||||
intnum *intnum_copy(const intnum *intn);
|
||||
void intnum_delete(intnum *intn);
|
||||
/*@only@*/ intnum *intnum_new_charconst_nasm(const char *str);
|
||||
/*@only@*/ intnum *intnum_new_int(unsigned long i);
|
||||
/*@only@*/ intnum *intnum_copy(const intnum *intn);
|
||||
void intnum_delete(/*@only@*/ intnum *intn);
|
||||
|
||||
/* calculation function: acc = acc op operand */
|
||||
void intnum_calc(intnum *acc, ExprOp op, intnum *operand);
|
||||
|
|
|
|||
2
src/lclint.sh
Executable file
2
src/lclint.sh
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
lclint -exportlocal -predbool -boolops +boolint +charint -retvalint -retvalother +ansilimits -I/usr/local/include -I.. -Iarch/x86 -I. -DHAVE_CONFIG_H -DHAVE_BOGUS_SYS_QUEUE_H -Dlint main.c options.c arch.c bytecode.c errwarn.c expr.c file.c floatnum.c globals.c intnum.c parser.c section.c arch/x86/arch.c arch/x86/bytecode.c arch/x86/expr.c objfmts/dbg/objfmt.c parsers/nasm/parser.c preprocs/raw/preproc.c parsers/nasm/bison.c symrec.c ternary.c
|
||||
|
|
@ -20,30 +20,32 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "ternary.h"
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
|
||||
const char *in_filename = (const char *)NULL;
|
||||
/*@null@*/ /*@dependent@*/ const char *in_filename = (const char *)NULL;
|
||||
unsigned int line_number = 1;
|
||||
unsigned int asm_options = 0;
|
||||
|
||||
static ternary_tree filename_table = (ternary_tree)NULL;
|
||||
static /*@only@*/ /*@null@*/ ternary_tree filename_table = (ternary_tree)NULL;
|
||||
|
||||
void
|
||||
switch_filename(const char *filename)
|
||||
{
|
||||
char *copy = xstrdup(filename);
|
||||
in_filename = ternary_insert(&filename_table, filename, copy, 0);
|
||||
/*@-branchstate@*/
|
||||
if (in_filename != copy)
|
||||
xfree(copy);
|
||||
/*@=branchstate@*/
|
||||
}
|
||||
|
||||
static void
|
||||
filename_delete_one(void *d)
|
||||
filename_delete_one(/*@only@*/ void *d)
|
||||
{
|
||||
xfree(d);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#ifndef YASM_GLOBALS_H
|
||||
#define YASM_GLOBALS_H
|
||||
|
||||
extern const char *in_filename;
|
||||
/*@null@*/ /*@dependent@*/ extern const char *in_filename;
|
||||
extern unsigned int line_number;
|
||||
extern unsigned int asm_options;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "objfmt.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "objfmt.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
|
|
@ -32,10 +32,12 @@ RCSID("$IdPath$");
|
|||
* Someday change this if we dynamically load parsers at runtime.
|
||||
* Could improve this a little by generating automatically at build-time.
|
||||
*/
|
||||
/*@-nullassign@*/
|
||||
static parser *parsers[] = {
|
||||
&nasm_parser,
|
||||
NULL
|
||||
};
|
||||
/*@=nullassign@*/
|
||||
|
||||
int
|
||||
parser_setpp(parser *p, const char *pp_keyword)
|
||||
|
|
@ -45,7 +47,9 @@ parser_setpp(parser *p, const char *pp_keyword)
|
|||
/* We're just doing a linear search, as preprocs should be short */
|
||||
for (i = 0; p->preprocs[i]; i++) {
|
||||
if (strcasecmp(p->preprocs[i]->keyword, pp_keyword) == 0) {
|
||||
/*@-unqualifiedtrans@*/
|
||||
p->current_pp = p->preprocs[i];
|
||||
/*@=unqualifiedtrans@*/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -73,7 +77,9 @@ find_parser(const char *keyword)
|
|||
/* We're just doing a linear search, as there aren't many parsers */
|
||||
for (i = 0; parsers[i]; i++) {
|
||||
if (strcasecmp(parsers[i]->keyword, keyword) == 0)
|
||||
/*@-unqualifiedtrans@*/
|
||||
return parsers[i];
|
||||
/*@=unqualifiedtrans@*/
|
||||
}
|
||||
|
||||
/* no match found */
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ struct parser {
|
|||
preproc **preprocs;
|
||||
|
||||
/* Current preprocessor (set to the default at compile time) */
|
||||
preproc *current_pp;
|
||||
/*@dependent@*/ preproc *current_pp;
|
||||
|
||||
/* Main entrance point for the parser.
|
||||
*
|
||||
|
|
@ -60,7 +60,7 @@ struct parser {
|
|||
/* Sets current_pp within p by searching the preprocs list for a preproc
|
||||
* matching pp_keyword. Returns nonzero if no match was found.
|
||||
*/
|
||||
int parser_setpp(parser *p, const char *pp_keyword);
|
||||
int parser_setpp(/*@partial@*/ parser *p, const char *pp_keyword);
|
||||
|
||||
/* Lists preprocessors available for p. Calls printfunc with the name
|
||||
* and keyword of each available preprocessor.
|
||||
|
|
@ -70,7 +70,7 @@ void parser_listpp(parser *p,
|
|||
|
||||
/* Finds a parser based on its keyword. Returns NULL if no match was found.
|
||||
*/
|
||||
parser *find_parser(const char *keyword);
|
||||
/*@null@*/ parser *find_parser(const char *keyword);
|
||||
|
||||
/* Lists all available parsers. Calls printfunc with the name and keyword
|
||||
* of each available parser.
|
||||
|
|
|
|||
|
|
@ -54,12 +54,13 @@ extern sectionhead nasm_parser_sections;
|
|||
extern section *nasm_parser_cur_section;
|
||||
extern char *nasm_parser_locallabel_base;
|
||||
|
||||
static bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
|
||||
static /*@null@*/ bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
|
||||
static bytecode *nasm_parser_temp_bc;
|
||||
|
||||
/* additional data declarations (dynamically generated) */
|
||||
/* @DATADECLS@ */
|
||||
|
||||
/*@-usedef -nullassign -memtrans -usereleased -compdef -mustfree@*/
|
||||
%}
|
||||
|
||||
%union {
|
||||
|
|
@ -539,6 +540,7 @@ instr: instrbase
|
|||
/* @INSTRUCTIONS@ */
|
||||
|
||||
%%
|
||||
/*@=usedef =nullassign =memtrans =usereleased =compdef =mustfree@*/
|
||||
|
||||
static void
|
||||
nasm_parser_directive(const char *name, const char *val)
|
||||
|
|
|
|||
|
|
@ -537,6 +537,7 @@ sub output_yacc ($@)
|
|||
for (my $i=0; $i < @opcodes; ++$i)
|
||||
{
|
||||
$opcodes[$i] =~ s/([0-9A-Fa-f]{2})/0x$1/g;
|
||||
$opcodes[$i] =~ s/(0x[0-9A-Fa-f]{2}.*\+)/(unsigned char)$1/g;
|
||||
# don't match $0.\d in the following rule.
|
||||
$opcodes[$i] =~ s/\$(\d+)(?!\.)/"\$".($1*2)/eg;
|
||||
push @args, "short_op[$i]=$opcodes[$i];";
|
||||
|
|
@ -565,6 +566,7 @@ sub output_yacc ($@)
|
|||
for (my $i=0; $i < @opcodes; ++$i)
|
||||
{
|
||||
$opcodes[$i] =~ s/([0-9A-Fa-f]{2})/0x$1/g;
|
||||
$opcodes[$i] =~ s/(0x[0-9A-Fa-f]{2}.*\+)/(unsigned char)$1/g;
|
||||
# don't match $0.\d in the following rule.
|
||||
$opcodes[$i] =~ s/\$(\d+)(?!\.)/"\$".($1*2)/eg;
|
||||
push @args, "near_op[$i]=$opcodes[$i];";
|
||||
|
|
@ -586,6 +588,12 @@ sub output_yacc ($@)
|
|||
# and add the data structure reference
|
||||
s/^/$datastructname./g foreach (@args);
|
||||
|
||||
if ($args[0] =~ m/\&\$/)
|
||||
{
|
||||
$args[0] = '/*@-immediatetrans@*/' . $args[0] .
|
||||
'/*@=immediatetrans@*/';
|
||||
}
|
||||
|
||||
# generate the grammar
|
||||
print GRAMMAR action ($rule, $tokens, $func, \@args, $count++);
|
||||
}
|
||||
|
|
@ -625,6 +633,7 @@ sub output_yacc ($@)
|
|||
for (my $i=0; $i < @opcodes; ++$i)
|
||||
{
|
||||
$opcodes[$i] =~ s/([0-9A-Fa-f]{2})/0x$1/g;
|
||||
$opcodes[$i] =~ s/(0x[0-9A-Fa-f]{2}.*\+)/(unsigned char)$1/g;
|
||||
# don't match $0.\d in the following rule.
|
||||
$opcodes[$i] =~ s/\$(\d+)(?!\.)/"\$".($1*2+$to)/eg;
|
||||
push @args, "op[$i]=$opcodes[$i];";
|
||||
|
|
@ -661,7 +670,7 @@ sub output_yacc ($@)
|
|||
$imm =~ s[^([0-9A-Fa-f]+),]
|
||||
[imm_new_int(0x$1),];
|
||||
$imm =~ s[^\$0.(\d+),]
|
||||
[imm_new_int(\$1\[$1\]),];
|
||||
[imm_new_int((unsigned long)\$1\[$1\]),];
|
||||
|
||||
# divide the second, and only the second, by 8 bits/byte
|
||||
$imm =~ s#(,\s*)(\d+)(s)?#$1 . ($2/8)#eg;
|
||||
|
|
|
|||
|
|
@ -54,12 +54,13 @@ extern sectionhead nasm_parser_sections;
|
|||
extern section *nasm_parser_cur_section;
|
||||
extern char *nasm_parser_locallabel_base;
|
||||
|
||||
static bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
|
||||
static /*@null@*/ bytecode *nasm_parser_prev_bc = (bytecode *)NULL;
|
||||
static bytecode *nasm_parser_temp_bc;
|
||||
|
||||
/* additional data declarations (dynamically generated) */
|
||||
/* @DATADECLS@ */
|
||||
|
||||
/*@-usedef -nullassign -memtrans -usereleased -compdef -mustfree@*/
|
||||
%}
|
||||
|
||||
%union {
|
||||
|
|
@ -539,6 +540,7 @@ instr: instrbase
|
|||
/* @INSTRUCTIONS@ */
|
||||
|
||||
%%
|
||||
/*@=usedef =nullassign =memtrans =usereleased =compdef =mustfree@*/
|
||||
|
||||
static void
|
||||
nasm_parser_directive(const char *name, const char *val)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "errwarn.h"
|
||||
|
||||
|
|
@ -35,16 +35,17 @@ extern int nasm_parser_debug;
|
|||
|
||||
extern int nasm_parser_parse(void);
|
||||
|
||||
int (*nasm_parser_yyinput) (char *buf, int max_size);
|
||||
size_t (*nasm_parser_yyinput) (char *buf, size_t max_size);
|
||||
|
||||
objfmt *nasm_parser_objfmt;
|
||||
sectionhead nasm_parser_sections;
|
||||
section *nasm_parser_cur_section;
|
||||
/*@dependent@*/ section *nasm_parser_cur_section;
|
||||
|
||||
extern char *nasm_parser_locallabel_base;
|
||||
extern /*@only@*/ char *nasm_parser_locallabel_base;
|
||||
|
||||
static sectionhead *
|
||||
static /*@dependent@*/ sectionhead *
|
||||
nasm_parser_do_parse(parser *p, objfmt *of, FILE *f)
|
||||
/*@globals killed nasm_parser_locallabel_base @*/
|
||||
{
|
||||
p->current_pp->initialize(of, f);
|
||||
nasm_parser_in = f;
|
||||
|
|
@ -68,10 +69,12 @@ nasm_parser_do_parse(parser *p, objfmt *of, FILE *f)
|
|||
}
|
||||
|
||||
/* Define valid preprocessors to use with this parser */
|
||||
/*@-nullassign@*/
|
||||
static preproc *nasm_parser_preprocs[] = {
|
||||
&raw_preproc,
|
||||
NULL
|
||||
};
|
||||
/*@=nullassign@*/
|
||||
|
||||
/* Define parser structure -- see parser.h for details */
|
||||
parser nasm_parser = {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "errwarn.h"
|
||||
|
||||
|
|
@ -35,16 +35,17 @@ extern int nasm_parser_debug;
|
|||
|
||||
extern int nasm_parser_parse(void);
|
||||
|
||||
int (*nasm_parser_yyinput) (char *buf, int max_size);
|
||||
size_t (*nasm_parser_yyinput) (char *buf, size_t max_size);
|
||||
|
||||
objfmt *nasm_parser_objfmt;
|
||||
sectionhead nasm_parser_sections;
|
||||
section *nasm_parser_cur_section;
|
||||
/*@dependent@*/ section *nasm_parser_cur_section;
|
||||
|
||||
extern char *nasm_parser_locallabel_base;
|
||||
extern /*@only@*/ char *nasm_parser_locallabel_base;
|
||||
|
||||
static sectionhead *
|
||||
static /*@dependent@*/ sectionhead *
|
||||
nasm_parser_do_parse(parser *p, objfmt *of, FILE *f)
|
||||
/*@globals killed nasm_parser_locallabel_base @*/
|
||||
{
|
||||
p->current_pp->initialize(of, f);
|
||||
nasm_parser_in = f;
|
||||
|
|
@ -68,10 +69,12 @@ nasm_parser_do_parse(parser *p, objfmt *of, FILE *f)
|
|||
}
|
||||
|
||||
/* Define valid preprocessors to use with this parser */
|
||||
/*@-nullassign@*/
|
||||
static preproc *nasm_parser_preprocs[] = {
|
||||
&raw_preproc,
|
||||
NULL
|
||||
};
|
||||
/*@=nullassign@*/
|
||||
|
||||
/* Define parser structure -- see parser.h for details */
|
||||
parser nasm_parser = {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ RCSID("$IdPath$");
|
|||
|
||||
int nasm_parser_lex(void);
|
||||
|
||||
extern int (*nasm_parser_yyinput) (char *buf, int max_size);
|
||||
extern size_t (*nasm_parser_yyinput) (char *buf, size_t max_size);
|
||||
#undef YY_INPUT
|
||||
#define YY_INPUT(b, r, ms) (r = nasm_parser_yyinput(b, ms))
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ struct preproc {
|
|||
|
||||
/* Gets more preprocessed source code (up to max_size bytes) into buf.
|
||||
* Note that more than a single line may be returned in buf. */
|
||||
int (*input) (char *buf, int max_size);
|
||||
size_t (*input) (char *buf, size_t max_size);
|
||||
};
|
||||
|
||||
/* Available preprocessors */
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "errwarn.h"
|
||||
|
||||
|
|
@ -33,16 +33,19 @@ static FILE *in;
|
|||
int isatty(int);
|
||||
|
||||
static void
|
||||
raw_preproc_initialize(objfmt *of, FILE *f)
|
||||
raw_preproc_initialize(/*@unused@*/ objfmt *of, FILE *f)
|
||||
{
|
||||
in = f;
|
||||
/*@-unrecog@*/
|
||||
is_interactive = f ? (isatty(fileno(f)) > 0) : 0;
|
||||
/*@=unrecog@*/
|
||||
}
|
||||
|
||||
static int
|
||||
raw_preproc_input(char *buf, int max_size)
|
||||
static size_t
|
||||
raw_preproc_input(char *buf, size_t max_size)
|
||||
{
|
||||
int c = '*', n;
|
||||
int c = '*';
|
||||
size_t n;
|
||||
|
||||
if (is_interactive) {
|
||||
for (n = 0; n < max_size && (c = getc(in)) != EOF && c != '\n'; n++)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "errwarn.h"
|
||||
|
||||
|
|
@ -33,16 +33,19 @@ static FILE *in;
|
|||
int isatty(int);
|
||||
|
||||
static void
|
||||
raw_preproc_initialize(objfmt *of, FILE *f)
|
||||
raw_preproc_initialize(/*@unused@*/ objfmt *of, FILE *f)
|
||||
{
|
||||
in = f;
|
||||
/*@-unrecog@*/
|
||||
is_interactive = f ? (isatty(fileno(f)) > 0) : 0;
|
||||
/*@=unrecog@*/
|
||||
}
|
||||
|
||||
static int
|
||||
raw_preproc_input(char *buf, int max_size)
|
||||
static size_t
|
||||
raw_preproc_input(char *buf, size_t max_size)
|
||||
{
|
||||
int c = '*', n;
|
||||
int c = '*';
|
||||
size_t n;
|
||||
|
||||
if (is_interactive) {
|
||||
for (n = 0; n < max_size && (c = getc(in)) != EOF && c != '\n'; n++)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "globals.h"
|
||||
#include "errwarn.h"
|
||||
|
|
@ -32,7 +32,7 @@ RCSID("$IdPath$");
|
|||
|
||||
|
||||
struct section {
|
||||
STAILQ_ENTRY(section) link;
|
||||
/*@reldef@*/ STAILQ_ENTRY(section) link;
|
||||
|
||||
enum { SECTION_GENERAL, SECTION_ABSOLUTE } type;
|
||||
|
||||
|
|
@ -64,9 +64,12 @@ sections_initialize(sectionhead *headp, objfmt *of)
|
|||
s->name = xstrdup(of->default_section_name);
|
||||
bytecodes_initialize(&s->bc);
|
||||
|
||||
s->data.start = 0;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/*@-onlytrans@*/
|
||||
section *
|
||||
sections_switch(sectionhead *headp, objfmt *of, const char *name)
|
||||
{
|
||||
|
|
@ -102,8 +105,11 @@ sections_switch(sectionhead *headp, objfmt *of, const char *name)
|
|||
s->name = xstrdup(name);
|
||||
bytecodes_initialize(&s->bc);
|
||||
|
||||
s->data.start = 0;
|
||||
|
||||
return s;
|
||||
}
|
||||
/*@=onlytrans@*/
|
||||
|
||||
void
|
||||
sections_delete(sectionhead *headp)
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@
|
|||
|
||||
struct objfmt;
|
||||
|
||||
section *sections_initialize(sectionhead *headp, struct objfmt *of);
|
||||
/*@dependent@*/ section *sections_initialize(sectionhead *headp,
|
||||
struct objfmt *of);
|
||||
|
||||
section *sections_switch(sectionhead *headp, struct objfmt *of,
|
||||
const char *name);
|
||||
/*@dependent@*/ section *sections_switch(sectionhead *headp, struct objfmt *of,
|
||||
const char *name);
|
||||
|
||||
void sections_delete(sectionhead *headp);
|
||||
|
||||
|
|
@ -35,11 +36,11 @@ void sections_print(const sectionhead *headp);
|
|||
|
||||
void sections_parser_finalize(sectionhead *headp);
|
||||
|
||||
bytecodehead *section_get_bytecodes(section *sect);
|
||||
/*@dependent@*/ bytecodehead *section_get_bytecodes(section *sect);
|
||||
|
||||
const char *section_get_name(const section *sect);
|
||||
/*@observer@*/ const char *section_get_name(const section *sect);
|
||||
|
||||
void section_delete(section *sect);
|
||||
void section_delete(/*@only@*/ section *sect);
|
||||
|
||||
void section_print(const section *sect);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
|
||||
#ifdef USE_OUR_OWN_STRCASECMP
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
|
|
@ -48,6 +48,7 @@ static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93";
|
|||
*
|
||||
* If *stringp is NULL, strsep returns NULL.
|
||||
*/
|
||||
/*@-nullstate@*/
|
||||
char *
|
||||
strsep(char **stringp, const char *delim)
|
||||
{
|
||||
|
|
@ -74,3 +75,4 @@ strsep(char **stringp, const char *delim)
|
|||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
/*@=nullstate@*/
|
||||
|
|
|
|||
25
src/symrec.c
25
src/symrec.c
|
|
@ -20,7 +20,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#include "ternary.h"
|
||||
|
||||
|
|
@ -54,26 +54,22 @@ struct symrec {
|
|||
SymType type;
|
||||
SymStatus status;
|
||||
SymVisibility visibility;
|
||||
const char *filename; /* file and line */
|
||||
/*@dependent@*/ /*@null@*/ const char *filename; /* file and line */
|
||||
unsigned long line; /* symbol was first declared or used on */
|
||||
union {
|
||||
expr *expn; /* equ value */
|
||||
struct label_s { /* bytecode immediately preceding a label */
|
||||
section *sect;
|
||||
bytecode *bc;
|
||||
/*@dependent@*/ section *sect;
|
||||
/*@dependent@*/ /*@null@*/ bytecode *bc;
|
||||
} label;
|
||||
} value;
|
||||
};
|
||||
|
||||
/* private functions */
|
||||
static symrec *symrec_get_or_new(const char *name, int in_table);
|
||||
static symrec *symrec_define(const char *name, SymType type, int in_table);
|
||||
|
||||
/* The symbol table: a ternary tree. */
|
||||
static ternary_tree sym_table = (ternary_tree)NULL;
|
||||
static /*@only@*/ /*@null@*/ ternary_tree sym_table = (ternary_tree)NULL;
|
||||
|
||||
/* create a new symrec */
|
||||
static symrec *
|
||||
static /*@partial@*/ /*@dependent@*/ symrec *
|
||||
symrec_get_or_new(const char *name, int in_table)
|
||||
{
|
||||
symrec *rec, *rec2;
|
||||
|
|
@ -96,7 +92,9 @@ symrec_get_or_new(const char *name, int in_table)
|
|||
rec->line = line_number;
|
||||
rec->visibility = SYM_LOCAL;
|
||||
|
||||
/*@-freshtrans -mustfree@*/
|
||||
return rec;
|
||||
/*@=freshtrans =mustfree@*/
|
||||
}
|
||||
|
||||
/* Call a function with each symrec. Stops early if 0 returned by func.
|
||||
|
|
@ -116,7 +114,7 @@ symrec_use(const char *name)
|
|||
return rec;
|
||||
}
|
||||
|
||||
static symrec *
|
||||
static /*@dependent@*/ symrec *
|
||||
symrec_define(const char *name, SymType type, int in_table)
|
||||
{
|
||||
symrec *rec = symrec_get_or_new(name, in_table);
|
||||
|
|
@ -252,7 +250,7 @@ symrec_parser_finalize(void)
|
|||
}
|
||||
|
||||
static void
|
||||
symrec_delete_one(void *d)
|
||||
symrec_delete_one(/*@only@*/ void *d)
|
||||
{
|
||||
symrec *sym = d;
|
||||
xfree(sym->name);
|
||||
|
|
@ -323,5 +321,6 @@ symrec_print(const symrec *sym)
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
printf("Filename=\"%s\" Line Number=%lu\n", sym->filename, sym->line);
|
||||
printf("Filename=\"%s\" Line Number=%lu\n",
|
||||
sym->filename?sym->filename:"(NULL)", sym->line);
|
||||
}
|
||||
|
|
|
|||
17
src/symrec.h
17
src/symrec.h
|
|
@ -30,12 +30,15 @@ typedef enum {
|
|||
SYM_EXTERN = 1 << 2 /* if it's declared EXTERN */
|
||||
} SymVisibility;
|
||||
|
||||
symrec *symrec_use(const char *name);
|
||||
symrec *symrec_define_equ(const char *name, expr *e);
|
||||
/*@dependent@*/ symrec *symrec_use(const char *name);
|
||||
/*@dependent@*/ symrec *symrec_define_equ(const char *name,
|
||||
/*@keep@*/ expr *e);
|
||||
/* in_table specifies if the label should be inserted into the symbol table. */
|
||||
symrec *symrec_define_label(const char *name, section *sect, bytecode *precbc,
|
||||
int in_table);
|
||||
symrec *symrec_declare(const char *name, SymVisibility vis);
|
||||
/*@dependent@*/ symrec *symrec_define_label(const char *name,
|
||||
/*@dependent@*/ section *sect,
|
||||
/*@dependent@*/ /*@null@*/
|
||||
bytecode *precbc, int in_table);
|
||||
/*@dependent@*/ symrec *symrec_declare(const char *name, SymVisibility vis);
|
||||
|
||||
/* Get the numeric 32-bit value of a symbol if possible.
|
||||
* Return value is IF POSSIBLE, not the value.
|
||||
|
|
@ -45,10 +48,10 @@ symrec *symrec_declare(const char *name, SymVisibility vis);
|
|||
int symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
|
||||
int resolve_label);
|
||||
|
||||
const char *symrec_get_name(const symrec *sym);
|
||||
/*@observer@*/ const char *symrec_get_name(const symrec *sym);
|
||||
SymVisibility symrec_get_visibility(const symrec *sym);
|
||||
|
||||
const expr *symrec_get_equ(const symrec *sym);
|
||||
/*@observer@*/ /*@null@*/ const expr *symrec_get_equ(const symrec *sym);
|
||||
|
||||
int /*@alt void@*/ symrec_foreach(int (*func) (symrec *sym));
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,11 @@
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
USA. */
|
||||
#include "util.h"
|
||||
RCSID("$IdPath$");
|
||||
/*@unused@*/ RCSID("$IdPath$");
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
# include <assert.h>
|
||||
#endif
|
||||
|
||||
#include "errwarn.h"
|
||||
|
||||
|
|
@ -30,7 +34,7 @@ RCSID("$IdPath$");
|
|||
|
||||
/* Non-recursive so we don't waste stack space/time on large
|
||||
insertions. */
|
||||
|
||||
/*@-compmempass@*/
|
||||
void *
|
||||
ternary_insert (ternary_tree * root, const char *s, void *data, int replace)
|
||||
{
|
||||
|
|
@ -51,7 +55,12 @@ ternary_insert (ternary_tree * root, const char *s, void *data, int replace)
|
|||
if (*s++ == 0)
|
||||
{
|
||||
if (replace)
|
||||
curr->eqkid = (ternary_tree) data;
|
||||
{
|
||||
xfree(curr->eqkid);
|
||||
/*@-temptrans@*/
|
||||
curr->eqkid = (ternary_tree) data;
|
||||
/*@=temptrans@*/
|
||||
}
|
||||
return (void *) curr->eqkid;
|
||||
}
|
||||
pcurr = &(curr->eqkid);
|
||||
|
|
@ -89,10 +98,12 @@ ternary_insert (ternary_tree * root, const char *s, void *data, int replace)
|
|||
pcurr = &(curr->eqkid);
|
||||
}
|
||||
}
|
||||
/*@=compmempass@*/
|
||||
|
||||
/* Free the ternary search tree rooted at p. */
|
||||
void
|
||||
ternary_cleanup (ternary_tree p, void (*data_cleanup)(void *d))
|
||||
ternary_cleanup (ternary_tree p, void (*data_cleanup)(/*@dependent@*/
|
||||
/*@null@*/ void *d))
|
||||
{
|
||||
if (p)
|
||||
{
|
||||
|
|
@ -110,13 +121,14 @@ ternary_cleanup (ternary_tree p, void (*data_cleanup)(void *d))
|
|||
void *
|
||||
ternary_search (ternary_tree p, const char *s)
|
||||
{
|
||||
ternary_tree curr;
|
||||
/*@null@*/ ternary_tree curr;
|
||||
int diff, spchar;
|
||||
spchar = *s;
|
||||
curr = p;
|
||||
/* Loop while we haven't hit a NULL node or returned */
|
||||
while (curr)
|
||||
{
|
||||
assert(curr != NULL);
|
||||
/* Calculate the difference */
|
||||
diff = spchar - curr->splitchar;
|
||||
/* Handle the equal case */
|
||||
|
|
@ -139,7 +151,7 @@ ternary_search (ternary_tree p, const char *s)
|
|||
|
||||
/* For those who care, the recursive version of the search. Useful if
|
||||
you want a starting point for pmsearch or nearsearch. */
|
||||
static void *
|
||||
static /*@dependent@*/ /*@null@*/ void *
|
||||
ternary_recursivesearch (ternary_tree p, const char *s)
|
||||
{
|
||||
if (!p)
|
||||
|
|
@ -159,7 +171,8 @@ ternary_recursivesearch (ternary_tree p, const char *s)
|
|||
/* Traverse over tree, calling callback function for each leaf.
|
||||
Stops early if func returns 0. */
|
||||
int
|
||||
ternary_traverse (ternary_tree p, int (*func) (void *d))
|
||||
ternary_traverse (ternary_tree p, int (*func) (/*@dependent@*/ /*@null@*/
|
||||
void *d))
|
||||
{
|
||||
if (!p)
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -22,14 +22,14 @@
|
|||
#define YASM_TERNARY_H
|
||||
/* Ternary search trees */
|
||||
|
||||
typedef struct ternary_node_def *ternary_tree;
|
||||
typedef /*@null@*/ struct ternary_node_def *ternary_tree;
|
||||
|
||||
typedef struct ternary_node_def
|
||||
{
|
||||
char splitchar;
|
||||
ternary_tree lokid;
|
||||
ternary_tree eqkid;
|
||||
ternary_tree hikid;
|
||||
/*@null@*/ ternary_tree lokid;
|
||||
/*@owned@*/ /*@null@*/ ternary_tree eqkid;
|
||||
/*@null@*/ ternary_tree hikid;
|
||||
}
|
||||
ternary_node;
|
||||
|
||||
|
|
@ -38,17 +38,22 @@ ternary_node;
|
|||
already there, and replace is 0.
|
||||
Otherwise, replaces if it it exists, inserts if it doesn't, and
|
||||
returns the data you passed in. */
|
||||
void *ternary_insert (ternary_tree *p, const char *s, void *data, int replace);
|
||||
/*@dependent@*/ void *ternary_insert (ternary_tree *p, const char *s,
|
||||
void *data, int replace);
|
||||
|
||||
/* Delete the ternary search tree rooted at P.
|
||||
Does NOT delete the data you associated with the strings. */
|
||||
void ternary_cleanup (ternary_tree p, void (*data_cleanup)(void *d));
|
||||
void ternary_cleanup (/*@only@*/ ternary_tree p,
|
||||
void (*data_cleanup)(/*@dependent@*/ /*@null@*/
|
||||
void *d));
|
||||
|
||||
/* Search the ternary tree for string S, returning the data associated
|
||||
with it if found. */
|
||||
void *ternary_search (ternary_tree p, const char *s);
|
||||
/*@dependent@*/ /*@null@*/ void *ternary_search (ternary_tree p,
|
||||
const char *s);
|
||||
|
||||
/* Traverse over tree, calling callback function for each leaf.
|
||||
Stops early if func returns 0. */
|
||||
int ternary_traverse (ternary_tree p, int (*func) (void *d));
|
||||
int ternary_traverse (ternary_tree p, int (*func) (/*@dependent@*/ /*@null@*/
|
||||
void *d));
|
||||
#endif
|
||||
|
|
|
|||
18
src/util.h
18
src/util.h
|
|
@ -43,13 +43,13 @@
|
|||
#endif
|
||||
#define _(String) gettext(String)
|
||||
|
||||
#if !defined(HAVE_MERGESORT)
|
||||
#if !defined(HAVE_MERGESORT) || defined(lint)
|
||||
int mergesort(void *base, size_t nmemb, size_t size,
|
||||
int (*compar)(const void *, const void *));
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRSEP) || defined(HAVE_GNU_C_LIBRARY)
|
||||
char *strsep(char **stringp, const char *delim);
|
||||
#if !defined(HAVE_STRSEP) || defined(HAVE_GNU_C_LIBRARY) || defined(lint)
|
||||
/*@null@*/ char *strsep(char **stringp, const char *delim);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCASECMP
|
||||
|
|
@ -64,12 +64,12 @@ char *strsep(char **stringp, const char *delim);
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(USE_OUR_OWN_STRCASECMP) || defined(HAVE_GNU_C_LIBRARY)
|
||||
#if defined(USE_OUR_OWN_STRCASECMP) || defined(HAVE_GNU_C_LIBRARY) || defined(lint)
|
||||
int strcasecmp(const char *s1, const char *s2);
|
||||
int strncasecmp(const char *s1, const char *s2, size_t n);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_TOASCII) || defined(HAVE_GNU_C_LIBRARY)
|
||||
#if !defined(HAVE_TOASCII) || defined(HAVE_GNU_C_LIBRARY) || defined(lint)
|
||||
# define toascii(c) ((c) & 0x7F)
|
||||
#endif
|
||||
|
||||
|
|
@ -104,10 +104,10 @@ int strncasecmp(const char *s1, const char *s2, size_t n);
|
|||
/*@only@*/ char *xstrdup(const char *str);
|
||||
|
||||
/* Error-checking memory allocation routines in xmalloc.c. */
|
||||
/*@only@*/ void *xmalloc(size_t size);
|
||||
/*@only@*/ void *xcalloc(size_t nelem, size_t elsize);
|
||||
void *xrealloc(void *oldmem, size_t size);
|
||||
void xfree(/*@only@*/ void *p);
|
||||
/*@only@*/ /*@out@*/ void *xmalloc(size_t size);
|
||||
/*@only@*/ /*@out@*/ void *xcalloc(size_t nelem, size_t elsize);
|
||||
/*@out@*/ void *xrealloc(/*@returned@*/ /*@null@*/ void *oldmem, size_t size);
|
||||
void xfree(/*@only@*/ /*@out@*/ /*@null@*/ void *p);
|
||||
#endif
|
||||
|
||||
#include "coretype.h"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue