static int xdf_objfmt_count_sym(yasm_symrec *sym, /*@null@*/ void *d) { /*@null@*/ xdf_objfmt_output_info *info = (xdf_objfmt_output_info *)d; yasm_sym_vis vis = yasm_symrec_get_visibility(sym); assert(info != NULL); if (vis & YASM_SYM_COMMON) { yasm_error_set(YASM_ERROR_GENERAL, N_("XDF object format does not support common variables")); yasm_errwarn_propagate(info->errwarns, yasm_symrec_get_decl_line(sym)); return 0; } if (info->all_syms || (vis != YASM_SYM_LOCAL && !(vis & YASM_SYM_DLOCAL))) { /* Save index in symrec data */ xdf_symrec_data *sym_data = yasm_xmalloc(sizeof(xdf_symrec_data)); sym_data->index = info->indx; yasm_symrec_add_data(sym, &xdf_symrec_data_cb, sym_data); info->indx++; } return 0; }
int yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *drex, unsigned char *low3, uintptr_t reg, unsigned int bits, x86_rex_bit_pos rexbit) { *low3 = (unsigned char)(reg&7); if (bits == 64) { x86_expritem_reg_size size = (x86_expritem_reg_size)(reg & ~0xFUL); if (size == X86_REG8X || (reg & 0xF) >= 8) { if (drex) { *drex |= ((reg & 8) >> 3) << rexbit; } else { /* Check to make sure we can set it */ if (*rex == 0xff) { yasm_error_set(YASM_ERROR_TYPE, N_("cannot use A/B/C/DH with instruction needing REX")); return 1; } *rex |= 0x40 | (((reg & 8) >> 3) << rexbit); } } else if (size == X86_REG8 && (reg & 7) >= 4) {
int yasm_dir_helper_intn(void *obj, yasm_valparam *vp, unsigned long line, void *data, uintptr_t arg) { yasm_object *object = (yasm_object *)obj; /*@only@*/ /*@null@*/ yasm_expr *e; /*@dependent@*/ /*@null@*/ yasm_intnum *local; yasm_intnum **intn = (yasm_intnum **)data; if (*intn) yasm_intnum_destroy(*intn); if (!(e = yasm_vp_expr(vp, object->symtab, line)) || !(local = yasm_expr_get_intnum(&e, 0))) { yasm_error_set(YASM_ERROR_NOT_CONSTANT, N_("argument to `%s' is not an integer"), vp->val); if (e) yasm_expr_destroy(e); return -1; } *intn = yasm_intnum_copy(local); yasm_expr_destroy(e); return 0; }
static uintptr_t x86_reggroup_get_reg(yasm_arch *arch, uintptr_t reggroup, unsigned long regindex) { yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch; switch ((x86_expritem_reg_size)(reggroup & ~0xFUL)) { case X86_XMMREG: case X86_YMMREG: if (arch_x86->mode_bits == 64) { if (regindex > 15) return 0; return reggroup | (regindex & 15); } /*@fallthrough@*/ case X86_MMXREG: case X86_FPUREG: if (regindex > 7) return 0; return reggroup | (regindex & 7); default: yasm_error_set(YASM_ERROR_VALUE, N_("bad register group")); } return 0; }
static int bc_incbin_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, void *add_span_data) { bytecode_incbin *incbin = (bytecode_incbin *)bc->contents; FILE *f; /*@dependent@*/ /*@null@*/ const yasm_intnum *num; unsigned long start = 0, maxlen = 0xFFFFFFFFUL, flen; /* Try to convert start to integer value */ if (incbin->start) { num = yasm_expr_get_intnum(&incbin->start, 0); if (num) start = yasm_intnum_get_uint(num); if (!num) { /* FIXME */ yasm_error_set(YASM_ERROR_NOT_IMPLEMENTED, N_("incbin does not yet understand non-constant")); return -1; } } /* Try to convert maxlen to integer value */ if (incbin->maxlen) { num = yasm_expr_get_intnum(&incbin->maxlen, 0); if (num) maxlen = yasm_intnum_get_uint(num); if (!num) { /* FIXME */ yasm_error_set(YASM_ERROR_NOT_IMPLEMENTED, N_("incbin does not yet understand non-constant")); return -1; } } /* Open file and determine its length */ f = yasm_fopen_include(incbin->filename, incbin->from, "rb", NULL); if (!f) { yasm_error_set(YASM_ERROR_IO, N_("`incbin': unable to open file `%s'"), incbin->filename); return -1; } if (fseek(f, 0L, SEEK_END) < 0) { yasm_error_set(YASM_ERROR_IO, N_("`incbin': unable to seek on file `%s'"), incbin->filename); return -1; } flen = (unsigned long)ftell(f); fclose(f); /* Compute length of incbin from start, maxlen, and len */ if (start > flen) { yasm_warn_set(YASM_WARN_GENERAL, N_("`incbin': start past end of file `%s'"), incbin->filename); start = flen; } flen -= start; if (incbin->maxlen) if (maxlen < flen) flen = maxlen; bc->len += flen; return 0; }
int gas_parser_lex(YYSTYPE *lvalp, yasm_parser_gas *parser_gas) { yasm_scanner *s = &parser_gas->s; YYCTYPE *cursor = s->cur; size_t count; YYCTYPE savech; /* Handle one token of lookahead */ if (parser_gas->peek_token != NONE) { int tok = parser_gas->peek_token; *lvalp = parser_gas->peek_tokval; /* structure copy */ parser_gas->tokch = parser_gas->peek_tokch; parser_gas->peek_token = NONE; return tok; } /* Catch EOF */ if (s->eof && cursor == s->eof) return 0; /* Jump to proper "exclusive" states */ switch (parser_gas->state) { case COMMENT: goto comment; case SECTION_DIRECTIVE: goto section_directive; case NASM_FILENAME: goto nasm_filename; default: break; } scan: SCANINIT(); { static unsigned char yybm[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 254, 254, 126, 126, 126, 126, 126, 126, 94, 94, 0, 0, 0, 0, 0, 0, 8, 78, 78, 78, 78, 78, 78, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 12, 0, 78, 78, 78, 78, 78, 78, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; #line 258 "gas-token.c" { YYCTYPE yych; unsigned int yyaccept; goto yy0; ++YYCURSOR; yy0: if((YYLIMIT - YYCURSOR) < 5) YYFILL(5); yych = *YYCURSOR; if(yych <= '/'){ if(yych <= '#'){ if(yych <= '\r'){ if(yych <= '\t'){ if(yych <= '\b') goto yy30; goto yy26; } else { if(yych <= '\n') goto yy28; if(yych <= '\f') goto yy30; goto yy26; } } else { if(yych <= ' '){ if(yych <= '\037') goto yy30; goto yy26; } else { if(yych <= '!') goto yy17; if(yych <= '"') goto yy11; goto yy24; } } } else { if(yych <= '*'){ if(yych <= '%'){ if(yych <= '$') goto yy17; goto yy22; } else { if(yych == '\'') goto yy9; goto yy17; } } else { if(yych <= ','){ if(yych <= '+') goto yy5; goto yy17; } else { if(yych <= '-') goto yy5; if(yych <= '.') goto yy7; goto yy18; } } } } else { if(yych <= 'Z'){ if(yych <= '<'){ if(yych <= '9'){ if(yych >= '1') goto yy4; goto yy2; } else { if(yych <= ':') goto yy17; if(yych <= ';') goto yy19; goto yy13; } } else { if(yych <= '>'){ if(yych <= '=') goto yy17; goto yy15; } else { if(yych <= '?') goto yy30; if(yych <= '@') goto yy17; goto yy21; } } } else { if(yych <= 'z'){ if(yych <= '^'){ if(yych <= ']') goto yy30; goto yy17; } else { if(yych == '`') goto yy30; goto yy21; } } else { if(yych <= '|'){ if(yych <= '{') goto yy30; goto yy17; } else { if(yych == '~') goto yy17; goto yy30; } } } } yy2: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if(yych <= 'T'){ if(yych <= 'A'){ if(yych <= '/'){ if(yych == '.') goto yy90; goto yy3; } else { if(yych <= '9') goto yy90; if(yych <= ':') goto yy81; goto yy3; } } else { if(yych <= 'E'){ if(yych <= 'B') goto yy85; if(yych >= 'D') goto yy88; goto yy3; } else { if(yych <= 'F') goto yy86; if(yych >= 'T') goto yy88; goto yy3; } } } else { if(yych <= 'e'){ if(yych <= 'a'){ if(yych == 'X') goto yy92; goto yy3; } else { if(yych <= 'b') goto yy85; if(yych >= 'd') goto yy88; goto yy3; } } else { if(yych <= 't'){ if(yych <= 'f') goto yy86; if(yych >= 't') goto yy88; goto yy3; } else { if(yych == 'x') goto yy92; goto yy3; } } } yy3: #line 229 "./modules/parsers/gas/gas-token.re" { savech = s->tok[TOKLEN]; s->tok[TOKLEN] = '\0'; lvalp->intn = yasm_intnum_create_dec(TOK); s->tok[TOKLEN] = savech; RETURN(INTNUM); } #line 402 "gas-token.c" yy4: yych = *++YYCURSOR; if(yych <= 'E'){ if(yych <= ':'){ if(yych <= '9') goto yy84; goto yy81; } else { if(yych == 'B') goto yy77; goto yy84; } } else { if(yych <= 'b'){ if(yych <= 'F') goto yy79; if(yych <= 'a') goto yy84; goto yy77; } else { if(yych == 'f') goto yy79; goto yy84; } } yy5: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); if(yych == '.') goto yy61; if(yych <= '/') goto yy6; if(yych <= '9') goto yy59; goto yy6; yy6: #line 303 "./modules/parsers/gas/gas-token.re" { RETURN(s->tok[0]); } #line 431 "gas-token.c" yy7: yych = *++YYCURSOR; if(yybm[0+yych] & 16) { goto yy49; } goto yy37; yy8: #line 310 "./modules/parsers/gas/gas-token.re" { lvalp->str.contents = yasm__xstrndup(TOK, TOKLEN); lvalp->str.len = TOKLEN; RETURN(ID); } #line 444 "gas-token.c" yy9: yych = *++YYCURSOR; goto yy10; yy10: #line 289 "./modules/parsers/gas/gas-token.re" { goto charconst; } #line 452 "gas-token.c" yy11: yych = *++YYCURSOR; goto yy12; yy12: #line 294 "./modules/parsers/gas/gas-token.re" { goto stringconst; } #line 460 "gas-token.c" yy13: yych = *++YYCURSOR; if(yych == '<') goto yy47; goto yy14; yy14: #line 301 "./modules/parsers/gas/gas-token.re" { RETURN(LEFT_OP); } #line 467 "gas-token.c" yy15: yych = *++YYCURSOR; if(yych == '>') goto yy45; goto yy16; yy16: #line 302 "./modules/parsers/gas/gas-token.re" { RETURN(RIGHT_OP); } #line 474 "gas-token.c" yy17: yych = *++YYCURSOR; goto yy6; yy18: yych = *++YYCURSOR; if(yych == '*') goto yy43; if(yych == '/') goto yy41; goto yy6; yy19: yych = *++YYCURSOR; goto yy20; yy20: #line 304 "./modules/parsers/gas/gas-token.re" { parser_gas->state = INITIAL; RETURN(s->tok[0]); } #line 489 "gas-token.c" yy21: yych = *++YYCURSOR; goto yy37; yy22: yych = *++YYCURSOR; if(yybm[0+yych] & 2) { goto yy33; } goto yy23; yy23: #line 407 "./modules/parsers/gas/gas-token.re" { yasm_warn_set(YASM_WARN_UNREC_CHAR, N_("ignoring unrecognized character `%s'"), yasm__conv_unprint(s->tok[0])); goto scan; } #line 505 "gas-token.c" yy24: yych = *++YYCURSOR; goto yy25; yy25: #line 389 "./modules/parsers/gas/gas-token.re" { if (parser_gas->is_cpp_preproc) { RETURN(CPP_LINE_MARKER); } else goto line_comment; } #line 517 "gas-token.c" yy26: yych = *++YYCURSOR; goto yy32; yy27: #line 398 "./modules/parsers/gas/gas-token.re" { goto scan; } #line 523 "gas-token.c" yy28: yych = *++YYCURSOR; goto yy29; yy29: #line 400 "./modules/parsers/gas/gas-token.re" { if (parser_gas->save_input) cursor = save_line(parser_gas, cursor); parser_gas->state = INITIAL; RETURN(s->tok[0]); } #line 534 "gas-token.c" yy30: yych = *++YYCURSOR; goto yy23; yy31: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy32; yy32: if(yybm[0+yych] & 1) { goto yy31; } goto yy27; yy33: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy34; yy34: if(yybm[0+yych] & 2) { goto yy33; } goto yy35; yy35: #line 327 "./modules/parsers/gas/gas-token.re" { savech = s->tok[TOKLEN]; s->tok[TOKLEN] = '\0'; if (parser_gas->is_nasm_preproc && strcmp(TOK+1, "line") == 0) { s->tok[TOKLEN] = savech; RETURN(NASM_LINE_MARKER); } switch (yasm_arch_parse_check_regtmod (p_object->arch, TOK+1, TOKLEN-1, &lvalp->arch_data)) { case YASM_ARCH_REG: s->tok[TOKLEN] = savech; RETURN(REG); case YASM_ARCH_REGGROUP: s->tok[TOKLEN] = savech; RETURN(REGGROUP); case YASM_ARCH_SEGREG: s->tok[TOKLEN] = savech; RETURN(SEGREG); default: break; } yasm_error_set(YASM_ERROR_GENERAL, N_("Unrecognized register name `%s'"), s->tok); s->tok[TOKLEN] = savech; lvalp->arch_data = 0; RETURN(REG); } #line 583 "gas-token.c" yy36: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy37; yy37: if(yybm[0+yych] & 4) { goto yy36; } if(yych != '@') goto yy8; goto yy38; yy38: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy39; yy39: if(yybm[0+yych] & 8) { goto yy38; } goto yy40; yy40: #line 317 "./modules/parsers/gas/gas-token.re" { /* if @ not part of ID, move the scanner cursor to the first @ */ if (!((yasm_objfmt_base *)p_object->objfmt)->module->id_at_ok) cursor = (unsigned char *)strchr(TOK, '@'); lvalp->str.contents = yasm__xstrndup(TOK, TOKLEN); lvalp->str.len = TOKLEN; RETURN(ID); } #line 611 "gas-token.c" yy41: yych = *++YYCURSOR; goto yy42; yy42: #line 396 "./modules/parsers/gas/gas-token.re" { goto line_comment; } #line 617 "gas-token.c" yy43: yych = *++YYCURSOR; goto yy44; yy44: #line 388 "./modules/parsers/gas/gas-token.re" { parser_gas->state = COMMENT; goto comment; } #line 623 "gas-token.c" yy45: yych = *++YYCURSOR; goto yy46; yy46: #line 300 "./modules/parsers/gas/gas-token.re" { RETURN(RIGHT_OP); } #line 629 "gas-token.c" yy47: yych = *++YYCURSOR; goto yy48; yy48: #line 299 "./modules/parsers/gas/gas-token.re" { RETURN(LEFT_OP); } #line 635 "gas-token.c" yy49: ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); yych = *YYCURSOR; goto yy50; yy50: if(yybm[0+yych] & 16) { goto yy49; } if(yych <= 'E'){ if(yych <= '.'){ if(yych == '$') goto yy36; if(yych >= '.') goto yy36; goto yy51; } else { if(yych <= '?') goto yy51; if(yych <= '@') goto yy38; if(yych <= 'D') goto yy36; goto yy52; } } else { if(yych <= '`'){ if(yych <= 'Z') goto yy36; if(yych == '_') goto yy36; goto yy51; } else { if(yych == 'e') goto yy52; if(yych <= 'z') goto yy36; goto yy51; } } yy51: #line 266 "./modules/parsers/gas/gas-token.re" { savech = s->tok[TOKLEN]; s->tok[TOKLEN] = '\0'; lvalp->flt = yasm_floatnum_create(TOK); s->tok[TOKLEN] = savech; RETURN(FLTNUM); } #line 674 "gas-token.c" yy52: yyaccept = 2; yych = *(YYMARKER = ++YYCURSOR); if(yych <= ','){ if(yych == '+') goto yy55; goto yy37; } else { if(yych <= '-') goto yy55; if(yych <= '/') goto yy37; if(yych >= ':') goto yy37; goto yy53; } yy53: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy54; yy54: if(yych <= '?'){ if(yych <= '-'){ if(yych == '$') goto yy36; goto yy51; } else { if(yych <= '.') goto yy36; if(yych <= '/') goto yy51; if(yych <= '9') goto yy53; goto yy51; } } else { if(yych <= '^'){ if(yych <= '@') goto yy38; if(yych <= 'Z') goto yy36; goto yy51; } else { if(yych == '`') goto yy51; if(yych <= 'z') goto yy36; goto yy51; } } yy55: yych = *++YYCURSOR; if(yych <= '/') goto yy56; if(yych <= '9') goto yy57; goto yy56; yy56: YYCURSOR = YYMARKER; switch(yyaccept){ case 0: goto yy3; case 6: goto yy91; case 3: goto yy51; case 4: goto yy66; case 5: goto yy87; case 1: goto yy6; case 2: goto yy8; } yy57: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy58; yy58: if(yych <= '/') goto yy51; if(yych <= '9') goto yy57; goto yy51; yy59: ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; goto yy60; yy60: if(yych == '.') goto yy65; if(yych <= '/') goto yy56; if(yych <= '9') goto yy59; goto yy56; yy61: yych = *++YYCURSOR; if(yych <= '/') goto yy56; if(yych >= ':') goto yy56; goto yy62; yy62: yyaccept = 3; YYMARKER = ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); yych = *YYCURSOR; goto yy63; yy63: if(yych <= 'D'){ if(yych <= '/') goto yy51; if(yych <= '9') goto yy62; goto yy51; } else { if(yych <= 'E') goto yy64; if(yych != 'e') goto yy51; goto yy64; } yy64: yych = *++YYCURSOR; if(yych <= ','){ if(yych == '+') goto yy55; goto yy56; } else { if(yych <= '-') goto yy55; if(yych <= '/') goto yy56; if(yych <= '9') goto yy57; goto yy56; } yy65: yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if(yych <= 'D'){ if(yych <= '/') goto yy66; if(yych <= '9') goto yy67; goto yy66; } else { if(yych <= 'E') goto yy69; if(yych == 'e') goto yy69; goto yy66; } yy66: #line 273 "./modules/parsers/gas/gas-token.re" { savech = s->tok[TOKLEN]; s->tok[TOKLEN] = '\0'; lvalp->flt = yasm_floatnum_create(TOK); s->tok[TOKLEN] = savech; RETURN(FLTNUM); } #line 788 "gas-token.c" yy67: yyaccept = 3; YYMARKER = ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); yych = *YYCURSOR; goto yy68; yy68: if(yych <= 'D'){ if(yych <= '/') goto yy51; if(yych <= '9') goto yy67; goto yy51; } else { if(yych <= 'E') goto yy73; if(yych == 'e') goto yy73; goto yy51; } yy69: yych = *++YYCURSOR; if(yych <= ','){ if(yych != '+') goto yy56; goto yy70; } else { if(yych <= '-') goto yy70; if(yych <= '/') goto yy56; if(yych <= '9') goto yy71; goto yy56; } yy70: yych = *++YYCURSOR; if(yych <= '/') goto yy56; if(yych >= ':') goto yy56; goto yy71; yy71: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy72; yy72: if(yych <= '/') goto yy66; if(yych <= '9') goto yy71; goto yy66; yy73: yych = *++YYCURSOR; if(yych <= ','){ if(yych != '+') goto yy56; goto yy74; } else { if(yych <= '-') goto yy74; if(yych <= '/') goto yy56; if(yych <= '9') goto yy75; goto yy56; } yy74: yych = *++YYCURSOR; if(yych <= '/') goto yy56; if(yych >= ':') goto yy56; goto yy75; yy75: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy76; yy76: if(yych <= '/') goto yy51; if(yych <= '9') goto yy75; goto yy51; yy77: yych = *++YYCURSOR; goto yy78; yy78: #line 379 "./modules/parsers/gas/gas-token.re" { /* build local label name */ lvalp->str.contents = yasm_xmalloc(30); lvalp->str.len = sprintf(lvalp->str.contents, "L%c\001%lu", s->tok[0], parser_gas->local[s->tok[0]-'0']); RETURN(ID); } #line 857 "gas-token.c" yy79: yych = *++YYCURSOR; goto yy80; yy80: #line 369 "./modules/parsers/gas/gas-token.re" { /* build local label name */ lvalp->str.contents = yasm_xmalloc(30); lvalp->str.len = sprintf(lvalp->str.contents, "L%c\001%lu", s->tok[0], parser_gas->local[s->tok[0]-'0']+1); RETURN(ID); } #line 870 "gas-token.c" yy81: yych = *++YYCURSOR; goto yy82; yy82: #line 357 "./modules/parsers/gas/gas-token.re" { /* increment label index */ parser_gas->local[s->tok[0]-'0']++; /* build local label name */ lvalp->str.contents = yasm_xmalloc(30); lvalp->str.len = sprintf(lvalp->str.contents, "L%c\001%lu", s->tok[0], parser_gas->local[s->tok[0]-'0']); RETURN(LABEL); } #line 885 "gas-token.c" yy83: ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; goto yy84; yy84: if(yych == '.') goto yy65; if(yych <= '/') goto yy3; if(yych <= '9') goto yy83; goto yy3; yy85: yych = *++YYCURSOR; if(yybm[0+yych] & 128) { goto yy104; } goto yy78; yy86: yyaccept = 5; yych = *(YYMARKER = ++YYCURSOR); if(yych == '+') goto yy96; if(yych == '-') goto yy96; goto yy97; yy87: #line 280 "./modules/parsers/gas/gas-token.re" { savech = s->tok[TOKLEN]; s->tok[TOKLEN] = '\0'; lvalp->flt = yasm_floatnum_create(TOK+2); s->tok[TOKLEN] = savech; RETURN(FLTNUM); } #line 913 "gas-token.c" yy88: yyaccept = 5; yych = *(YYMARKER = ++YYCURSOR); if(yych == '+') goto yy96; if(yych == '-') goto yy96; goto yy97; yy89: yyaccept = 6; YYMARKER = ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; goto yy90; yy90: if(yybm[0+yych] & 32) { goto yy89; } if(yych == '.') goto yy65; if(yych <= '/') goto yy91; if(yych <= '9') goto yy59; goto yy91; yy91: #line 247 "./modules/parsers/gas/gas-token.re" { savech = s->tok[TOKLEN]; s->tok[TOKLEN] = '\0'; lvalp->intn = yasm_intnum_create_oct(TOK); s->tok[TOKLEN] = savech; RETURN(INTNUM); } #line 940 "gas-token.c" yy92: yych = *++YYCURSOR; if(yybm[0+yych] & 64) { goto yy93; } goto yy56; yy93: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy94; yy94: if(yybm[0+yych] & 64) { goto yy93; } goto yy95; yy95: #line 256 "./modules/parsers/gas/gas-token.re" { savech = s->tok[TOKLEN]; s->tok[TOKLEN] = '\0'; /* skip 0 and x */ lvalp->intn = yasm_intnum_create_hex(TOK+2); s->tok[TOKLEN] = savech; RETURN(INTNUM); } #line 964 "gas-token.c" yy96: yyaccept = 5; YYMARKER = ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); yych = *YYCURSOR; goto yy97; yy97: if(yych <= '9'){ if(yych == '.') goto yy98; if(yych <= '/') goto yy87; goto yy96; } else { if(yych <= 'E'){ if(yych <= 'D') goto yy87; goto yy100; } else { if(yych == 'e') goto yy100; goto yy87; } } yy98: yyaccept = 5; YYMARKER = ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); yych = *YYCURSOR; goto yy99; yy99: if(yych <= 'D'){ if(yych <= '/') goto yy87; if(yych <= '9') goto yy98; goto yy87; } else { if(yych <= 'E') goto yy100; if(yych != 'e') goto yy87; goto yy100; } yy100: yych = *++YYCURSOR; if(yych <= ','){ if(yych != '+') goto yy56; goto yy101; } else { if(yych <= '-') goto yy101; if(yych <= '/') goto yy56; if(yych <= '9') goto yy102; goto yy56; } yy101: yych = *++YYCURSOR; if(yych <= '/') goto yy56; if(yych >= ':') goto yy56; goto yy102; yy102: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy103; yy103: if(yych <= '/') goto yy87; if(yych <= '9') goto yy102; goto yy87; yy104: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy105; yy105: if(yybm[0+yych] & 128) { goto yy104; } goto yy106; yy106: #line 238 "./modules/parsers/gas/gas-token.re" { savech = s->tok[TOKLEN]; s->tok[TOKLEN] = '\0'; lvalp->intn = yasm_intnum_create_bin(TOK+2); s->tok[TOKLEN] = savech; RETURN(INTNUM); } #line 1035 "gas-token.c" } } #line 413 "./modules/parsers/gas/gas-token.re" /* C-style comment; nesting not supported */ comment: SCANINIT(); { #line 1047 "gas-token.c" { YYCTYPE yych; goto yy107; ++YYCURSOR; yy107: if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if(yych == '\n') goto yy111; if(yych != '*') goto yy113; goto yy109; yy109: yych = *++YYCURSOR; if(yych == '/') goto yy114; goto yy110; yy110: #line 429 "./modules/parsers/gas/gas-token.re" { if (cursor == s->eof) return 0; goto comment; } #line 1068 "gas-token.c" yy111: yych = *++YYCURSOR; goto yy112; yy112: #line 423 "./modules/parsers/gas/gas-token.re" { if (parser_gas->save_input) cursor = save_line(parser_gas, cursor); RETURN(s->tok[0]); } #line 1078 "gas-token.c" yy113: yych = *++YYCURSOR; goto yy110; yy114: yych = *++YYCURSOR; goto yy115; yy115: #line 421 "./modules/parsers/gas/gas-token.re" { parser_gas->state = INITIAL; goto scan; } #line 1086 "gas-token.c" } } #line 434 "./modules/parsers/gas/gas-token.re" /* Single line comment. */ line_comment: { static unsigned char yybm[] = { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, }; #line 1130 "gas-token.c" { YYCTYPE yych; goto yy116; yy117: ++YYCURSOR; yy116: if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy118; yy118: if(yybm[0+yych] & 128) { goto yy117; } goto yy119; yy119: #line 439 "./modules/parsers/gas/gas-token.re" { goto scan; } #line 1146 "gas-token.c" } } #line 440 "./modules/parsers/gas/gas-token.re" /* .section directive (the section name portion thereof) */ section_directive: SCANINIT(); { static unsigned char yybm[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 128, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; #line 1192 "gas-token.c" { YYCTYPE yych; goto yy120; ++YYCURSOR; yy120: if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if(yych <= '$'){ if(yych <= '\r'){ if(yych <= '\t'){ if(yych <= '\b') goto yy132; goto yy126; } else { if(yych <= '\n') goto yy130; if(yych <= '\f') goto yy132; goto yy126; } } else { if(yych <= '!'){ if(yych == ' ') goto yy126; goto yy132; } else { if(yych <= '"') goto yy124; if(yych <= '#') goto yy132; goto yy122; } } } else { if(yych <= '@'){ if(yych <= '.'){ if(yych <= '+') goto yy132; if(yych <= ',') goto yy128; goto yy122; } else { if(yych <= '/') goto yy132; if(yych >= ':') goto yy132; goto yy122; } } else { if(yych <= '_'){ if(yych <= 'Z') goto yy122; if(yych <= '^') goto yy132; goto yy122; } else { if(yych <= '`') goto yy132; if(yych >= '{') goto yy132; goto yy122; } } } yy122: yych = *++YYCURSOR; goto yy137; yy123: #line 447 "./modules/parsers/gas/gas-token.re" { lvalp->str.contents = yasm__xstrndup(TOK, TOKLEN); lvalp->str.len = TOKLEN; parser_gas->state = INITIAL; RETURN(ID); } #line 1253 "gas-token.c" yy124: yych = *++YYCURSOR; goto yy125; yy125: #line 454 "./modules/parsers/gas/gas-token.re" { goto stringconst; } #line 1259 "gas-token.c" yy126: yych = *++YYCURSOR; goto yy135; yy127: #line 456 "./modules/parsers/gas/gas-token.re" { goto section_directive; } #line 1265 "gas-token.c" yy128: yych = *++YYCURSOR; goto yy129; yy129: #line 458 "./modules/parsers/gas/gas-token.re" { parser_gas->state = INITIAL; RETURN(s->tok[0]); } #line 1274 "gas-token.c" yy130: yych = *++YYCURSOR; goto yy131; yy131: #line 463 "./modules/parsers/gas/gas-token.re" { if (parser_gas->save_input) cursor = save_line(parser_gas, cursor); parser_gas->state = INITIAL; RETURN(s->tok[0]); } #line 1285 "gas-token.c" yy132: yych = *++YYCURSOR; goto yy133; yy133: #line 470 "./modules/parsers/gas/gas-token.re" { yasm_warn_set(YASM_WARN_UNREC_CHAR, N_("ignoring unrecognized character `%s'"), yasm__conv_unprint(s->tok[0])); goto section_directive; } #line 1296 "gas-token.c" yy134: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy135; yy135: if(yybm[0+yych] & 64) { goto yy134; } goto yy127; yy136: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy137; yy137: if(yybm[0+yych] & 128) { goto yy136; } goto yy123; } } #line 476 "./modules/parsers/gas/gas-token.re" /* filename portion of nasm preproc %line */ nasm_filename: strbuf = yasm_xmalloc(STRBUF_ALLOC_SIZE); strbuf_size = STRBUF_ALLOC_SIZE; count = 0; nasm_filename_scan: SCANINIT(); { static unsigned char yybm[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; #line 1363 "gas-token.c" { YYCTYPE yych; goto yy138; ++YYCURSOR; yy138: if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if(yych <= '\f'){ if(yych <= '\b') goto yy144; if(yych <= '\t') goto yy142; if(yych >= '\v') goto yy144; goto yy140; } else { if(yych <= '\r') goto yy142; if(yych == ' ') goto yy142; goto yy144; } yy140: yych = *++YYCURSOR; goto yy141; yy141: #line 488 "./modules/parsers/gas/gas-token.re" { strbuf_append(count++, cursor, s, '\0'); lvalp->str.contents = (char *)strbuf; lvalp->str.len = count; parser_gas->state = INITIAL; RETURN(STRING); } #line 1392 "gas-token.c" yy142: yych = *++YYCURSOR; goto yy147; yy143: #line 496 "./modules/parsers/gas/gas-token.re" { goto nasm_filename_scan; } #line 1398 "gas-token.c" yy144: yych = *++YYCURSOR; goto yy145; yy145: #line 498 "./modules/parsers/gas/gas-token.re" { if (cursor == s->eof) { strbuf_append(count++, cursor, s, '\0'); lvalp->str.contents = (char *)strbuf; lvalp->str.len = count; parser_gas->state = INITIAL; RETURN(STRING); } strbuf_append(count++, cursor, s, s->tok[0]); goto nasm_filename_scan; } #line 1414 "gas-token.c" yy146: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; goto yy147; yy147: if(yybm[0+yych] & 128) { goto yy146; } goto yy143; } } #line 509 "./modules/parsers/gas/gas-token.re" /* character constant values */ charconst: /*TODO*/ /* string constant values */ stringconst: strbuf = yasm_xmalloc(STRBUF_ALLOC_SIZE); strbuf_size = STRBUF_ALLOC_SIZE; count = 0; stringconst_scan: SCANINIT(); { #line 1443 "gas-token.c" { YYCTYPE yych; goto yy148; ++YYCURSOR; yy148: if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if(yych == '"') goto yy152; if(yych != '\\') goto yy154; goto yy150; yy150: yych = *++YYCURSOR; if(yych != '\n') goto yy155; goto yy151; yy151: #line 547 "./modules/parsers/gas/gas-token.re" { if (cursor == s->eof) { yasm_error_set(YASM_ERROR_SYNTAX, N_("unexpected end of file in string")); lvalp->str.contents = (char *)strbuf; lvalp->str.len = count; RETURN(STRING); } strbuf_append(count++, cursor, s, s->tok[0]); goto stringconst_scan; } #line 1470 "gas-token.c" yy152: yych = *++YYCURSOR; goto yy153; yy153: #line 539 "./modules/parsers/gas/gas-token.re" { strbuf_append(count, cursor, s, '\0'); yasm_unescape_cstring(strbuf, &count); lvalp->str.contents = (char *)strbuf; lvalp->str.len = count; RETURN(STRING); } #line 1482 "gas-token.c" yy154: yych = *++YYCURSOR; goto yy151; yy155: yych = *++YYCURSOR; goto yy156; yy156: #line 526 "./modules/parsers/gas/gas-token.re" { if (cursor == s->eof) { yasm_error_set(YASM_ERROR_SYNTAX, N_("unexpected end of file in string")); lvalp->str.contents = (char *)strbuf; lvalp->str.len = count; RETURN(STRING); } strbuf_append(count++, cursor, s, '\\'); strbuf_append(count++, cursor, s, s->tok[1]); goto stringconst_scan; } #line 1501 "gas-token.c" } } #line 558 "./modules/parsers/gas/gas-token.re" }
int yasm_value_output_basic(yasm_value *value, /*@out@*/ unsigned char *buf, size_t destsize, yasm_bytecode *bc, int warn, yasm_arch *arch) { /*@dependent@*/ /*@null@*/ yasm_intnum *intn = NULL; /*@only@*/ yasm_intnum *outval; int sym_local; int retval = 1; unsigned int valsize = value->size; if (value->no_warn) warn = 0; if (value->abs) { /* Handle floating point expressions */ if (!value->rel && value->abs->op == YASM_EXPR_IDENT && value->abs->terms[0].type == YASM_EXPR_FLOAT) { if (yasm_arch_floatnum_tobytes(arch, value->abs->terms[0].data.flt, buf, destsize, valsize, 0, warn)) return -1; else return 1; } /* Check for complex float expressions */ if (yasm_expr__contains(value->abs, YASM_EXPR_FLOAT)) { yasm_error_set(YASM_ERROR_FLOATING_POINT, N_("floating point expression too complex")); return -1; } /* Handle normal integer expressions */ intn = yasm_expr_get_intnum(&value->abs, 1); if (!intn) { /* Second try before erroring: yasm_expr_get_intnum doesn't handle * SEG:OFF, so try simplifying out any to just the OFF portion, * then getting the intnum again. */ yasm_expr *seg = yasm_expr_extract_deep_segoff(&value->abs); if (seg) yasm_expr_destroy(seg); intn = yasm_expr_get_intnum(&value->abs, 1); } if (!intn) { /* Still don't have an integer! */ yasm_error_set(YASM_ERROR_TOO_COMPLEX, N_("expression too complex")); return -1; } } /* Adjust warn for signed/unsigned integer warnings */ if (warn != 0) warn = value->sign ? -1 : 1; if (value->rel) { /* If relative portion is not in bc section, don't try to handle it * here. Otherwise get the relative portion's offset. */ /*@dependent@*/ yasm_bytecode *rel_prevbc; unsigned long dist; sym_local = yasm_symrec_get_label(value->rel, &rel_prevbc); if (value->wrt || value->seg_of || value->section_rel || !sym_local) return 0; /* we can't handle SEG, WRT, or external symbols */ if (rel_prevbc->section != bc->section) return 0; /* not in this section */ if (!value->curpos_rel) return 0; /* not PC-relative */ /* Calculate value relative to current assembly position */ dist = yasm_bc_next_offset(rel_prevbc); if (dist < bc->offset) { outval = yasm_intnum_create_uint(bc->offset - dist); yasm_intnum_calc(outval, YASM_EXPR_NEG, NULL); } else { dist -= bc->offset; outval = yasm_intnum_create_uint(dist); } if (value->rshift > 0) { /*@only@*/ yasm_intnum *shamt = yasm_intnum_create_uint((unsigned long)value->rshift); yasm_intnum_calc(outval, YASM_EXPR_SHR, shamt); yasm_intnum_destroy(shamt); } /* Add in absolute portion */ if (intn) yasm_intnum_calc(outval, YASM_EXPR_ADD, intn); /* Output! */ if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize, 0, bc, warn)) retval = -1; yasm_intnum_destroy(outval); return retval; } if (value->seg_of || value->rshift || value->curpos_rel || value->ip_rel || value->section_rel) return 0; /* We can't handle this with just an absolute */ if (intn) { /* Output just absolute portion */ if (yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize, 0, bc, warn)) retval = -1; } else { /* No absolute or relative portions: output 0 */ outval = yasm_intnum_create_uint(0); if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize, 0, bc, warn)) retval = -1; yasm_intnum_destroy(outval); } return retval; }
static int xdf_objfmt_output_sym(yasm_symrec *sym, /*@null@*/ void *d) { /*@null@*/ xdf_objfmt_output_info *info = (xdf_objfmt_output_info *)d; yasm_sym_vis vis = yasm_symrec_get_visibility(sym); assert(info != NULL); if (info->all_syms || vis != YASM_SYM_LOCAL) { /*@only@*/ char *name = yasm_symrec_get_global_name(sym, info->object); const yasm_expr *equ_val; const yasm_intnum *intn; size_t len = strlen(name); unsigned long value = 0; long scnum = -3; /* -3 = debugging symbol */ /*@dependent@*/ /*@null@*/ yasm_section *sect; /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc; unsigned long flags = 0; unsigned char *localbuf; if (vis & YASM_SYM_GLOBAL) flags = XDF_SYM_GLOBAL; /* Look at symrec for value/scnum/etc. */ if (yasm_symrec_get_label(sym, &precbc)) { if (precbc) sect = yasm_bc_get_section(precbc); else sect = NULL; /* it's a label: get value and offset. * If there is not a section, leave as debugging symbol. */ if (sect) { /*@dependent@*/ /*@null@*/ xdf_section_data *csectd; csectd = yasm_section_get_data(sect, &xdf_section_data_cb); if (csectd) scnum = csectd->scnum; else yasm_internal_error(N_("didn't understand section")); if (precbc) value += yasm_bc_next_offset(precbc); } } else if ((equ_val = yasm_symrec_get_equ(sym))) { yasm_expr *equ_val_copy = yasm_expr_copy(equ_val); intn = yasm_expr_get_intnum(&equ_val_copy, 1); if (!intn) { if (vis & YASM_SYM_GLOBAL) { yasm_error_set(YASM_ERROR_NOT_CONSTANT, N_("global EQU value not an integer expression")); yasm_errwarn_propagate(info->errwarns, equ_val->line); } } else value = yasm_intnum_get_uint(intn); yasm_expr_destroy(equ_val_copy); flags |= XDF_SYM_EQU; scnum = -2; /* -2 = absolute symbol */ } else { if (vis & YASM_SYM_EXTERN) { flags = XDF_SYM_EXTERN; scnum = -1; } } localbuf = info->buf; YASM_WRITE_32_L(localbuf, scnum); /* section number */ YASM_WRITE_32_L(localbuf, value); /* value */ YASM_WRITE_32_L(localbuf, info->strtab_offset); info->strtab_offset += (unsigned long)(len+1); YASM_WRITE_32_L(localbuf, flags); /* flags */ fwrite(info->buf, 16, 1, info->f); yasm_xfree(name); } return 0; }
static int xdf_objfmt_output_value(yasm_value *value, unsigned char *buf, unsigned int destsize, unsigned long offset, yasm_bytecode *bc, int warn, /*@null@*/ void *d) { /*@null@*/ xdf_objfmt_output_info *info = (xdf_objfmt_output_info *)d; yasm_objfmt_xdf *objfmt_xdf; /*@dependent@*/ /*@null@*/ yasm_intnum *intn; unsigned long intn_minus; int retval; unsigned int valsize = value->size; assert(info != NULL); objfmt_xdf = info->objfmt_xdf; if (value->abs) value->abs = yasm_expr_simplify(value->abs, 1); /* Try to output constant and PC-relative section-local first. * Note this does NOT output any value with a SEG, WRT, external, * cross-section, or non-PC-relative reference (those are handled below). */ switch (yasm_value_output_basic(value, buf, destsize, bc, warn, info->object->arch)) { case -1: return 1; case 0: break; default: return 0; } if (value->section_rel) { yasm_error_set(YASM_ERROR_TOO_COMPLEX, N_("xdf: relocation too complex")); return 1; } intn_minus = 0; if (value->rel) { xdf_reloc *reloc; reloc = yasm_xmalloc(sizeof(xdf_reloc)); reloc->reloc.addr = yasm_intnum_create_uint(bc->offset + offset); reloc->reloc.sym = value->rel; reloc->base = NULL; reloc->size = valsize/8; reloc->shift = value->rshift; if (value->seg_of) reloc->type = XDF_RELOC_SEG; else if (value->wrt) { reloc->base = value->wrt; reloc->type = XDF_RELOC_WRT; } else if (value->curpos_rel) { reloc->type = XDF_RELOC_RIP; /* Adjust to start of section, so subtract out the bytecode * offset. */ intn_minus = bc->offset; } else reloc->type = XDF_RELOC_REL; info->xsd->nreloc++; yasm_section_add_reloc(info->sect, (yasm_reloc *)reloc, yasm_xfree); } if (intn_minus > 0) { intn = yasm_intnum_create_uint(intn_minus); yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL); } else intn = yasm_intnum_create_uint(0); if (value->abs) { yasm_intnum *intn2 = yasm_expr_get_intnum(&value->abs, 0); if (!intn2) { yasm_error_set(YASM_ERROR_TOO_COMPLEX, N_("xdf: relocation too complex")); yasm_intnum_destroy(intn); return 1; } yasm_intnum_calc(intn, YASM_EXPR_ADD, intn2); } retval = yasm_arch_intnum_tobytes(info->object->arch, intn, buf, destsize, valsize, 0, bc, warn); yasm_intnum_destroy(intn); return retval; }
static void x86_reg_print(yasm_arch *arch, uintptr_t reg, FILE *f) { static const char *name8[] = {"al","cl","dl","bl","ah","ch","dh","bh"}; static const char *name8x[] = { "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" }; static const char *name16[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" }; static const char *name32[] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" }; static const char *name64[] = { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" }; switch ((x86_expritem_reg_size)(reg & ~0xFUL)) { case X86_REG8: fprintf(f, "%s", name8[reg&0xF]); break; case X86_REG8X: fprintf(f, "%s", name8x[reg&0xF]); break; case X86_REG16: fprintf(f, "%s", name16[reg&0xF]); break; case X86_REG32: fprintf(f, "%s", name32[reg&0xF]); break; case X86_REG64: fprintf(f, "%s", name64[reg&0xF]); break; case X86_MMXREG: fprintf(f, "mm%d", (int)(reg&0xF)); break; case X86_XMMREG: fprintf(f, "xmm%d", (int)(reg&0xF)); break; case X86_YMMREG: fprintf(f, "ymm%d", (int)(reg&0xF)); break; case X86_CRREG: fprintf(f, "cr%d", (int)(reg&0xF)); break; case X86_DRREG: fprintf(f, "dr%d", (int)(reg&0xF)); break; case X86_TRREG: fprintf(f, "tr%d", (int)(reg&0xF)); break; case X86_FPUREG: fprintf(f, "st%d", (int)(reg&0xF)); break; default: yasm_error_set(YASM_ERROR_VALUE, N_("unknown register size")); } }
static int bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d, yasm_output_value_func output_value, /*@unused@*/ yasm_output_reloc_func output_reloc) { bytecode_align *align = (bytecode_align *)bc->contents; unsigned long len; unsigned long boundary = yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, 0)); if (boundary == 0) return 0; else { unsigned long end = bc->offset; if (bc->offset & (boundary-1)) end = (bc->offset & ~(boundary-1)) + boundary; len = end - bc->offset; if (len == 0) return 0; if (align->maxskip) { unsigned long maxskip = yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip, 0)); if (len > maxskip) return 0; } } if (align->fill) { unsigned long v; v = yasm_intnum_get_uint(yasm_expr_get_intnum(&align->fill, 0)); memset(*bufp, (int)v, len); *bufp += len; } else if (align->code_fill) { unsigned long maxlen = 15; while (!align->code_fill[maxlen] && maxlen>0) maxlen--; if (maxlen == 0) { yasm_error_set(YASM_ERROR_GENERAL, N_("could not find any code alignment size")); return 1; } /* Fill with maximum code fill as much as possible */ while (len > maxlen) { memcpy(*bufp, align->code_fill[maxlen], maxlen); *bufp += maxlen; len -= maxlen; } if (!align->code_fill[len]) { yasm_error_set(YASM_ERROR_VALUE, N_("invalid alignment size %d"), len); return 1; } /* Handle rest of code fill */ memcpy(*bufp, align->code_fill[len], len); *bufp += len; } else { /* Just fill with 0 */ memset(*bufp, 0, len); *bufp += len; } return 0; }
/*@-nullderef -nullpass -branchstate@*/ int yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand) { boolean carry = 0; wordptr op1, op2 = NULL; N_int count; /* Always do computations with in full bit vector. * Bit vector results must be calculated through intermediate storage. */ op1 = intnum_tobv(op1static, acc); if (operand) op2 = intnum_tobv(op2static, operand); if (!operand && op != YASM_EXPR_NEG && op != YASM_EXPR_NOT && op != YASM_EXPR_LNOT) { yasm_error_set(YASM_ERROR_ARITHMETIC, N_("operation needs an operand")); BitVector_Empty(result); return 1; } /* A operation does a bitvector computation if result is allocated. */ switch (op) { case YASM_EXPR_ADD: BitVector_add(result, op1, op2, &carry); break; case YASM_EXPR_SUB: BitVector_sub(result, op1, op2, &carry); break; case YASM_EXPR_MUL: BitVector_Multiply(result, op1, op2); break; case YASM_EXPR_DIV: /* TODO: make sure op1 and op2 are unsigned */ if (BitVector_is_empty(op2)) { yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero")); BitVector_Empty(result); return 1; } else BitVector_Divide(result, op1, op2, spare); break; case YASM_EXPR_SIGNDIV: if (BitVector_is_empty(op2)) { yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero")); BitVector_Empty(result); return 1; } else BitVector_Divide(result, op1, op2, spare); break; case YASM_EXPR_MOD: /* TODO: make sure op1 and op2 are unsigned */ if (BitVector_is_empty(op2)) { yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero")); BitVector_Empty(result); return 1; } else BitVector_Divide(spare, op1, op2, result); break; case YASM_EXPR_SIGNMOD: if (BitVector_is_empty(op2)) { yasm_error_set(YASM_ERROR_ZERO_DIVISION, N_("divide by zero")); BitVector_Empty(result); return 1; } else BitVector_Divide(spare, op1, op2, result); break; case YASM_EXPR_NEG: BitVector_Negate(result, op1); break; case YASM_EXPR_NOT: Set_Complement(result, op1); break; case YASM_EXPR_OR: Set_Union(result, op1, op2); break; case YASM_EXPR_AND: Set_Intersection(result, op1, op2); break; case YASM_EXPR_XOR: Set_ExclusiveOr(result, op1, op2); break; case YASM_EXPR_XNOR: Set_ExclusiveOr(result, op1, op2); Set_Complement(result, result); break; case YASM_EXPR_NOR: Set_Union(result, op1, op2); Set_Complement(result, result); break; case YASM_EXPR_SHL: if (operand->type == INTNUM_L && operand->val.l >= 0) { BitVector_Copy(result, op1); BitVector_Move_Left(result, (N_int)operand->val.l); } else /* don't even bother, just zero result */ BitVector_Empty(result); break; case YASM_EXPR_SHR: if (operand->type == INTNUM_L && operand->val.l >= 0) { BitVector_Copy(result, op1); carry = BitVector_msb_(op1); count = (N_int)operand->val.l; while (count-- > 0) BitVector_shift_right(result, carry); } else /* don't even bother, just zero result */ BitVector_Empty(result); break; case YASM_EXPR_LOR: BitVector_Empty(result); BitVector_LSB(result, !BitVector_is_empty(op1) || !BitVector_is_empty(op2)); break; case YASM_EXPR_LAND: BitVector_Empty(result); BitVector_LSB(result, !BitVector_is_empty(op1) && !BitVector_is_empty(op2)); break; case YASM_EXPR_LNOT: BitVector_Empty(result); BitVector_LSB(result, BitVector_is_empty(op1)); break; case YASM_EXPR_LXOR: BitVector_Empty(result); BitVector_LSB(result, !BitVector_is_empty(op1) ^ !BitVector_is_empty(op2)); break; case YASM_EXPR_LXNOR: BitVector_Empty(result); BitVector_LSB(result, !(!BitVector_is_empty(op1) ^ !BitVector_is_empty(op2))); break; case YASM_EXPR_LNOR: BitVector_Empty(result); BitVector_LSB(result, !(!BitVector_is_empty(op1) || !BitVector_is_empty(op2))); break; case YASM_EXPR_EQ: BitVector_Empty(result); BitVector_LSB(result, BitVector_equal(op1, op2)); break; case YASM_EXPR_LT: BitVector_Empty(result); BitVector_LSB(result, BitVector_Compare(op1, op2) < 0); break; case YASM_EXPR_GT: BitVector_Empty(result); BitVector_LSB(result, BitVector_Compare(op1, op2) > 0); break; case YASM_EXPR_LE: BitVector_Empty(result); BitVector_LSB(result, BitVector_Compare(op1, op2) <= 0); break; case YASM_EXPR_GE: BitVector_Empty(result); BitVector_LSB(result, BitVector_Compare(op1, op2) >= 0); break; case YASM_EXPR_NE: BitVector_Empty(result); BitVector_LSB(result, !BitVector_equal(op1, op2)); break; case YASM_EXPR_SEG: yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"), "SEG"); break; case YASM_EXPR_WRT: yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"), "WRT"); break; case YASM_EXPR_SEGOFF: yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid use of '%s'"), ":"); break; case YASM_EXPR_IDENT: if (result) BitVector_Copy(result, op1); break; default: yasm_error_set(YASM_ERROR_ARITHMETIC, N_("invalid operation in intnum calculation")); BitVector_Empty(result); return 1; } /* Try to fit the result into 32 bits if possible */ if (acc->type == INTNUM_BV) BitVector_Destroy(acc->val.bv); intnum_frombv(acc, result); return 0; }