union {
/*@only@*/ yasm_expr *expn;
- /*@only@*/ char *str_val;
+ struct {
+ /*@only@*/ char *contents;
+ size_t len;
+ } str;
} data;
};
yasm_datavalhead datahead;
/* final (converted) size of each element (in bytes) */
- unsigned char size;
+ unsigned int size;
+
+ /* append a zero byte after each element? */
+ int append_zero;
} bytecode_data;
typedef struct bytecode_leb128 {
{
const bytecode_data *bc_data = (const bytecode_data *)contents;
fprintf(f, "%*s_Data_\n", indent_level, "");
- fprintf(f, "%*sFinal Element Size=%u\n", indent_level+1, "",
- (unsigned int)bc_data->size);
+ fprintf(f, "%*sFinal Element Size=%u\n", indent_level+1, "", bc_data->size);
+ fprintf(f, "%*sAppend Zero=%i\n", indent_level+1, "", bc_data->append_zero);
fprintf(f, "%*sElements:\n", indent_level+1, "");
yasm_dvs_print(&bc_data->datahead, f, indent_level+2);
}
bc->len += bc_data->size;
break;
case DV_STRING:
- slen = strlen(dv->data.str_val);
+ slen = dv->data.str.len;
/* find count, rounding up to nearest multiple of size */
slen = (slen + bc_data->size - 1) / bc_data->size;
bc->len += slen*bc_data->size;
break;
}
+ if (bc_data->append_zero)
+ bc->len++;
}
return YASM_BC_RESOLVE_MIN_LEN;
*bufp += bc_data->size;
break;
case DV_STRING:
- slen = strlen(dv->data.str_val);
- strncpy((char *)*bufp, dv->data.str_val, slen);
+ slen = dv->data.str.len;
+ memcpy(*bufp, dv->data.str.contents, slen);
*bufp += slen;
/* pad with 0's to nearest multiple of size */
slen %= bc_data->size;
}
break;
}
+ if (bc_data->append_zero)
+ YASM_WRITE_8(*bufp, 0);
}
return 0;
yasm_bytecode *
yasm_bc_create_data(yasm_datavalhead *datahead, unsigned int size,
- unsigned long line)
+ int append_zero, unsigned long line)
{
bytecode_data *data = yasm_xmalloc(sizeof(bytecode_data));
data->datahead = *datahead;
- data->size = (unsigned char)size;
+ data->size = size;
+ data->append_zero = append_zero;
return yasm_bc_create_common(&bc_data_callback, data, line);
}
}
yasm_dataval *
-yasm_dv_create_string(char *str_val)
+yasm_dv_create_string(char *contents, size_t len)
{
yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
retval->type = DV_STRING;
- retval->data.str_val = str_val;
+ retval->data.str.contents = contents;
+ retval->data.str.len = len;
return retval;
}
yasm_expr_destroy(cur->data.expn);
break;
case DV_STRING:
- yasm_xfree(cur->data.str_val);
+ yasm_xfree(cur->data.str.contents);
break;
default:
break;
fprintf(f, "\n");
break;
case DV_STRING:
- fprintf(f, "%*sString=%s\n", indent_level, "",
- cur->data.str_val);
+ fprintf(f, "%*sLength=%lu\n", indent_level, "",
+ (unsigned long)cur->data.str.len);
+ fprintf(f, "%*sString=\"%s\"\n", indent_level, "",
+ cur->data.str.contents);
break;
}
}
static yasm_bytecode *gas_parser_align(yasm_parser_gas *parser_gas,
yasm_valparamhead *valparams,
int power2);
-static yasm_bytecode *gas_define_strings(yasm_parser_gas *parser_gas,
- yasm_valparamhead *vps, int withzero);
-static yasm_bytecode *gas_define_data(yasm_parser_gas *parser_gas,
- yasm_valparamhead *vps,
- unsigned int size);
-static yasm_bytecode *gas_define_leb128(yasm_parser_gas *parser_gas,
- yasm_valparamhead *vps,
- int sign);
static void gas_parser_directive
(yasm_parser_gas *parser_gas, const char *name,
yasm_valparamhead *valparams,
yasm_expr *exp;
yasm_bytecode *bc;
yasm_valparamhead valparams;
+ yasm_datavalhead datavals;
+ yasm_dataval *dv;
struct {
yasm_insn_operands operands;
int num_operands;
} insn_operands;
yasm_insn_operand *insn_operand;
+ struct {
+ char *contents;
+ size_t len;
+ } str;
}
%token <intn> INTNUM
%token <flt> FLTNUM
-%token <str_val> STRING
+%token <str> STRING
%token <int_info> SIZE_OVERRIDE
%token <int_info> DECLARE_DATA
%token <int_info> RESERVE_SPACE
%type <ea> memaddr
%type <exp> expr regmemexpr
%type <sym> explabel
-%type <valparams> strvals datavals strvals2 datavals2
+%type <valparams> dirvals dirvals2
+%type <datavals> strvals datavals strvals2 datavals2
%type <insn_operands> operands
%type <insn_operand> operand
define_label(parser_gas, $1, 0);
}
/* Alignment directives */
- | DIR_ALIGN datavals2 {
+ | DIR_ALIGN dirvals2 {
/* FIXME: Whether this is power-of-two or not depends on arch and
* objfmt.
*/
$$ = gas_parser_align(parser_gas, &$2, 0);
}
- | DIR_P2ALIGN datavals2 {
+ | DIR_P2ALIGN dirvals2 {
$$ = gas_parser_align(parser_gas, &$2, 1);
}
- | DIR_BALIGN datavals2 {
+ | DIR_BALIGN dirvals2 {
$$ = gas_parser_align(parser_gas, &$2, 0);
}
| DIR_ORG INTNUM {
}
/* Integer data definition directives */
| DIR_ASCII strvals {
- $$ = gas_define_strings(parser_gas, &$2, 0);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_data(&$2, 1, 0, cur_line);
}
| DIR_ASCIZ strvals {
- $$ = gas_define_strings(parser_gas, &$2, 1);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_data(&$2, 1, 1, cur_line);
}
| DIR_BYTE datavals {
- $$ = gas_define_data(parser_gas, &$2, 1);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_data(&$2, 1, 0, cur_line);
}
| DIR_SHORT datavals {
/* TODO: This should depend on arch */
- $$ = gas_define_data(parser_gas, &$2, 2);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_data(&$2, 2, 0, cur_line);
}
| DIR_WORD datavals {
- $$ = gas_define_data(parser_gas, &$2,
- yasm_arch_wordsize(parser_gas->arch));
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_data(&$2, yasm_arch_wordsize(parser_gas->arch), 0,
+ cur_line);
}
| DIR_INT datavals {
/* TODO: This should depend on arch */
- $$ = gas_define_data(parser_gas, &$2, 4);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_data(&$2, 4, 0, cur_line);
}
| DIR_VALUE datavals {
/* XXX: At least on x86, this is two bytes */
- $$ = gas_define_data(parser_gas, &$2, 2);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_data(&$2, 2, 0, cur_line);
}
| DIR_2BYTE datavals {
- $$ = gas_define_data(parser_gas, &$2, 2);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_data(&$2, 2, 0, cur_line);
}
| DIR_4BYTE datavals {
- $$ = gas_define_data(parser_gas, &$2, 4);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_data(&$2, 4, 0, cur_line);
}
| DIR_QUAD datavals {
- $$ = gas_define_data(parser_gas, &$2, 8);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_data(&$2, 8, 0, cur_line);
}
| DIR_OCTA datavals {
- $$ = gas_define_data(parser_gas, &$2, 16);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_data(&$2, 16, 0, cur_line);
}
| DIR_ZERO expr {
yasm_datavalhead dvs;
yasm_dvs_initialize(&dvs);
yasm_dvs_append(&dvs, yasm_dv_create_expr(
p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0)))));
- $$ = yasm_bc_create_data(&dvs, 1, cur_line);
+ $$ = yasm_bc_create_data(&dvs, 1, 0, cur_line);
yasm_bc_set_multiple($$, $2);
}
| DIR_SLEB128 datavals {
- $$ = gas_define_leb128(parser_gas, &$2, 1);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_leb128(&$2, 1, cur_line);
}
| DIR_ULEB128 datavals {
- $$ = gas_define_leb128(parser_gas, &$2, 0);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_leb128(&$2, 0, cur_line);
}
/* Floating point data definition directives */
| DIR_FLOAT datavals {
- $$ = gas_define_data(parser_gas, &$2, 4);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_data(&$2, 4, 0, cur_line);
}
| DIR_DOUBLE datavals {
- $$ = gas_define_data(parser_gas, &$2, 8);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_data(&$2, 8, 0, cur_line);
}
| DIR_TFLOAT datavals {
- $$ = gas_define_data(parser_gas, &$2, 10);
- yasm_vps_delete(&$2);
+ $$ = yasm_bc_create_data(&$2, 10, 0, cur_line);
}
/* Empty space / fill data definition directives */
| DIR_SKIP expr {
yasm_dvs_initialize(&dvs);
yasm_dvs_append(&dvs, yasm_dv_create_expr($4));
- $$ = yasm_bc_create_data(&dvs, 1, cur_line);
+ $$ = yasm_bc_create_data(&dvs, 1, 0, cur_line);
yasm_bc_set_multiple($$, $2);
}
$$ = NULL;
}
| DIR_SECTION label_id ',' STRING {
- gas_switch_section(parser_gas, $2, $4, NULL, NULL);
+ gas_switch_section(parser_gas, $2, $4.contents, NULL, NULL);
$$ = NULL;
}
| DIR_SECTION label_id ',' STRING ',' '@' label_id {
- gas_switch_section(parser_gas, $2, $4, $7, NULL);
+ gas_switch_section(parser_gas, $2, $4.contents, $7, NULL);
$$ = NULL;
}
- | DIR_SECTION label_id ',' STRING ',' '@' label_id ',' datavals {
- gas_switch_section(parser_gas, $2, $4, $7, &$9);
+ | DIR_SECTION label_id ',' STRING ',' '@' label_id ',' dirvals {
+ gas_switch_section(parser_gas, $2, $4.contents, $7, &$9);
$$ = NULL;
}
/* Other directives */
yasm_dvs_append(&dvs, yasm_dv_create_expr(
p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0)))));
yasm_section_bcs_append(comment,
- yasm_bc_create_data(&dvs, 1, cur_line));
+ yasm_bc_create_data(&dvs, 1, 0, cur_line));
}
yasm_section_bcs_append(comment,
- gas_define_strings(parser_gas, &$2, 1));
- yasm_vps_delete(&$2);
+ yasm_bc_create_data(&$2, 1, 1, cur_line));
$$ = NULL;
}
| DIR_FILE INTNUM STRING {
yasm_vps_delete(&vps);
$$ = NULL;
}
- | DIR_ID datavals {
+ | DIR_ID dirvals {
yasm__warning(YASM_WARN_GENERAL, cur_line,
N_("directive `%s' not recognized"), $1);
$$ = (yasm_bytecode *)NULL;
}
;
-strvals: /* empty */ { yasm_vps_initialize(&$$); }
- | strvals2
+dirvals: /* empty */ { yasm_vps_initialize(&$$); }
+ | dirvals2
;
-strvals2: STRING {
- yasm_valparam *vp = yasm_vp_create($1, NULL);
+dirvals2: expr {
+ yasm_valparam *vp = yasm_vp_create(NULL, $1);
yasm_vps_initialize(&$$);
yasm_vps_append(&$$, vp);
}
- | strvals2 ',' STRING {
- yasm_valparam *vp = yasm_vp_create($3, NULL);
+ | dirvals2 ',' expr {
+ yasm_valparam *vp = yasm_vp_create(NULL, $3);
yasm_vps_append(&$1, vp);
$$ = $1;
}
- | strvals2 ',' ',' STRING {
+ | dirvals2 ',' ',' expr {
yasm_valparam *vp = yasm_vp_create(NULL, NULL);
yasm_vps_append(&$1, vp);
- vp = yasm_vp_create($4, NULL);
+ vp = yasm_vp_create(NULL, $4);
yasm_vps_append(&$1, vp);
$$ = $1;
}
;
-datavals: /* empty */ { yasm_vps_initialize(&$$); }
+strvals: /* empty */ { yasm_dvs_initialize(&$$); }
+ | strvals2
+;
+
+strvals2: STRING {
+ yasm_dataval *dv = yasm_dv_create_string($1.contents, $1.len);
+ yasm_dvs_initialize(&$$);
+ yasm_dvs_append(&$$, dv);
+ }
+ | strvals2 ',' STRING {
+ yasm_dataval *dv = yasm_dv_create_string($3.contents, $3.len);
+ yasm_dvs_append(&$1, dv);
+ $$ = $1;
+ }
+;
+
+datavals: /* empty */ { yasm_dvs_initialize(&$$); }
| datavals2
;
datavals2: expr {
- yasm_valparam *vp = yasm_vp_create(NULL, $1);
- yasm_vps_initialize(&$$);
- yasm_vps_append(&$$, vp);
+ yasm_dataval *dv = yasm_dv_create_expr($1);
+ yasm_dvs_initialize(&$$);
+ yasm_dvs_append(&$$, dv);
}
| datavals2 ',' expr {
- yasm_valparam *vp = yasm_vp_create(NULL, $3);
- yasm_vps_append(&$1, vp);
- $$ = $1;
- }
- | datavals2 ',' ',' expr {
- yasm_valparam *vp = yasm_vp_create(NULL, NULL);
- yasm_vps_append(&$1, vp);
- vp = yasm_vp_create(NULL, $4);
- yasm_vps_append(&$1, vp);
+ yasm_dataval *dv = yasm_dv_create_expr($3);
+ yasm_dvs_append(&$1, dv);
$$ = $1;
}
;
cur_line);
}
-static yasm_bytecode *
-gas_define_strings(yasm_parser_gas *parser_gas, yasm_valparamhead *vps,
- int withzero)
-{
- if (yasm_vps_first(vps)) {
- yasm_datavalhead dvs;
- yasm_valparam *cur;
-
- yasm_dvs_initialize(&dvs);
- yasm_vps_foreach(cur, vps) {
- if (!cur->val)
- yasm__error(cur_line, N_("missing string value"));
- else {
- yasm_dvs_append(&dvs, yasm_dv_create_string(cur->val));
- cur->val = NULL;
- if (withzero)
- yasm_dvs_append(&dvs, yasm_dv_create_expr(
- p_expr_new_ident(yasm_expr_int(
- yasm_intnum_create_uint(0)))));
- }
- }
- return yasm_bc_create_data(&dvs, 1, cur_line);
- } else
- return NULL;
-}
-
-static yasm_bytecode *
-gas_define_data(yasm_parser_gas *parser_gas, yasm_valparamhead *vps,
- unsigned int size)
-{
- if (yasm_vps_first(vps)) {
- yasm_datavalhead dvs;
- yasm_valparam *cur;
-
- yasm_dvs_initialize(&dvs);
- yasm_vps_foreach(cur, vps) {
- if (!cur->param)
- yasm__error(cur_line, N_("missing data value"));
- else
- yasm_dvs_append(&dvs, yasm_dv_create_expr(cur->param));
- cur->param = NULL;
- }
- return yasm_bc_create_data(&dvs, size, cur_line);
- } else
- return NULL;
-}
-
-static yasm_bytecode *
-gas_define_leb128(yasm_parser_gas *parser_gas, yasm_valparamhead *vps,
- int sign)
-{
- if (yasm_vps_first(vps)) {
- yasm_datavalhead dvs;
- yasm_valparam *cur;
-
- yasm_dvs_initialize(&dvs);
- yasm_vps_foreach(cur, vps) {
- if (!cur->param)
- yasm__error(cur_line, N_("missing data value"));
- else
- yasm_dvs_append(&dvs, yasm_dv_create_expr(cur->param));
- cur->param = NULL;
- }
- return yasm_bc_create_leb128(&dvs, sign, cur_line);
- } else
- return NULL;
-}
-
static void
gas_parser_directive(yasm_parser_gas *parser_gas, const char *name,
yasm_valparamhead *valparams,
char *name;
int local;
} label;
+ struct {
+ char *contents;
+ size_t len;
+ } str;
}
%token <intn> INTNUM
%token <flt> FLTNUM
-%token <str_val> DIRECTIVE_NAME STRING FILENAME
+%token <str_val> DIRECTIVE_NAME FILENAME
+%token <str> STRING
%token <int_info> SIZE_OVERRIDE
%token <int_info> DECLARE_DATA
%token <int_info> RESERVE_SPACE
exp: instr
| DECLARE_DATA datavals {
- $$ = yasm_bc_create_data(&$2, $1, cur_line);
+ $$ = yasm_bc_create_data(&$2, $1, 0, cur_line);
}
| RESERVE_SPACE expr {
$$ = yasm_bc_create_reserve($2, $1, cur_line);
}
| INCBIN STRING {
- $$ = yasm_bc_create_incbin($2, NULL, NULL, cur_line);
+ $$ = yasm_bc_create_incbin($2.contents, NULL, NULL, cur_line);
}
| INCBIN STRING ',' {
- $$ = yasm_bc_create_incbin($2, NULL, NULL, cur_line);
+ $$ = yasm_bc_create_incbin($2.contents, NULL, NULL, cur_line);
}
| INCBIN STRING ',' expr {
- $$ = yasm_bc_create_incbin($2, $4, NULL, cur_line);
+ $$ = yasm_bc_create_incbin($2.contents, $4, NULL, cur_line);
}
| INCBIN STRING ',' expr ',' {
- $$ = yasm_bc_create_incbin($2, $4, NULL, cur_line);
+ $$ = yasm_bc_create_incbin($2.contents, $4, NULL, cur_line);
}
| INCBIN STRING ',' expr ',' expr {
- $$ = yasm_bc_create_incbin($2, $4, $6, cur_line);
+ $$ = yasm_bc_create_incbin($2.contents, $4, $6, cur_line);
}
;
;
dataval: dvexpr { $$ = yasm_dv_create_expr($1); }
- | STRING { $$ = yasm_dv_create_string($1); }
+ | STRING {
+ $$ = yasm_dv_create_string($1.contents, $1.len);
+ }
| error {
yasm__error(cur_line, N_("expression syntax error"));
$$ = (yasm_dataval *)NULL;
$$ = yasm_vp_create(NULL, $1);
}
}
- | STRING { $$ = yasm_vp_create($1, NULL); }
+ | STRING { $$ = yasm_vp_create($1.contents, NULL); }
| ID '=' direxpr {
yasm_expr__traverse_leaves_in($3, parser_nasm, fix_directive_symrec);
$$ = yasm_vp_create($1, $3);
| REG { $$ = p_expr_new_ident(yasm_expr_reg($1[0])); }
| STRING {
$$ = p_expr_new_ident(yasm_expr_int(
- yasm_intnum_create_charconst_nasm($1, cur_line)));
- yasm_xfree($1);
+ yasm_intnum_create_charconst_nasm($1.contents, cur_line)));
+ yasm_xfree($1.contents);
}
| explabel { $$ = p_expr_new_ident(yasm_expr_sym($1)); }
/*| expr '||' expr { $$ = p_expr_new_tree($1, YASM_EXPR_LOR, $3); }*/