📄 bin-objfmt.c
字号:
assert(startexpr != NULL); startnum = yasm_expr_get_intnum(&startexpr, NULL); if (!startnum) { yasm__error(startexpr->line, N_("ORG expression too complex")); return; } start = yasm_intnum_get_uint(startnum); yasm_expr_destroy(startexpr); textstart = start; /* Align .data and .bss (if present) by adjusting their starts. */ prevsect = text; prevsectlenptr = &textlen; prevsectpadptr = &textpad; if (data) { start = bin_objfmt_align_section(data, prevsect, start, 4, prevsectlenptr, prevsectpadptr); yasm_section_set_start(data, yasm_expr_create_ident( yasm_expr_int(yasm_intnum_create_uint(start)), 0), 0); datastart = start; prevsect = data; prevsectlenptr = &datalen; prevsectpadptr = &datapad; } if (bss) { start = bin_objfmt_align_section(bss, prevsect, start, 4, prevsectlenptr, prevsectpadptr); yasm_section_set_start(bss, yasm_expr_create_ident( yasm_expr_int(yasm_intnum_create_uint(start)), 0), 0); } /* Output .text first. */ info.sect = text; info.start = textstart; yasm_section_bcs_traverse(text, &info, bin_objfmt_output_bytecode); /* If .data is present, output it */ if (data) { /* Add padding to align .data. Just use a for loop, as this will * seldom be very many bytes. */ for (i=0; i<textpad; i++) fputc(0, f); /* Output .data bytecodes */ info.sect = data; info.start = datastart; yasm_section_bcs_traverse(data, &info, bin_objfmt_output_bytecode); } /* If .bss is present, check it for non-reserve bytecodes */ yasm_xfree(info.buf);}static voidbin_objfmt_destroy(yasm_objfmt *objfmt){ yasm_xfree(objfmt);}static /*@observer@*/ /*@null@*/ yasm_section *bin_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line){ yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt; yasm_valparam *vp; yasm_section *retval; int isnew; unsigned long start; char *sectname; int resonly = 0; unsigned long alignval = 0; int have_alignval = 0; if ((vp = yasm_vps_first(valparams)) && !vp->param && vp->val != NULL) { /* If it's the first section output (.text) start at 0, otherwise * make sure the start is > 128. */ sectname = vp->val; if (strcmp(sectname, ".text") == 0) start = 0; else if (strcmp(sectname, ".data") == 0) start = 200; else if (strcmp(sectname, ".bss") == 0) { start = 200; resonly = 1; } else { /* other section names not recognized. */ yasm__error(line, N_("segment name `%s' not recognized"), sectname); return NULL; } /* Check for ALIGN qualifier */ while ((vp = yasm_vps_next(vp))) { if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) { /*@dependent@*/ /*@null@*/ const yasm_intnum *align; unsigned long bitcnt; if (strcmp(sectname, ".text") == 0) { yasm__error(line, N_("cannot specify an alignment to the `%s' section"), sectname); return NULL; } align = yasm_expr_get_intnum(&vp->param, NULL); if (!align) { yasm__error(line, N_("argument to `%s' is not a power of two"), vp->val); return NULL; } alignval = yasm_intnum_get_uint(align); /* Check to see if alignval is a power of two. * This can be checked by seeing if only one bit is set. */ BitCount(bitcnt, alignval); if (bitcnt > 1) { yasm__error(line, N_("argument to `%s' is not a power of two"), vp->val); return NULL; } have_alignval = 1; } } retval = yasm_object_get_general(objfmt_bin->object, sectname, yasm_expr_create_ident( yasm_expr_int(yasm_intnum_create_uint(start)), line), resonly, &isnew, line); if (isnew) { if (have_alignval) { unsigned long *data = yasm_xmalloc(sizeof(unsigned long)); *data = alignval; yasm_section_add_data(retval, &bin_section_data_callback, data); } yasm_symtab_define_label( yasm_object_get_symtab(objfmt_bin->object), sectname, yasm_section_bcs_first(retval), 1, line); } else if (have_alignval) yasm__warning(YASM_WARN_GENERAL, line, N_("alignment value ignored on section redeclaration")); return retval; } else return NULL;}static voidbin_section_data_destroy(/*@only@*/ void *d){ yasm_xfree(d);}static yasm_symrec *bin_objfmt_extern_declare(yasm_objfmt *objfmt, const char *name, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line){ yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt; yasm_symrec *sym; yasm__warning(YASM_WARN_GENERAL, line, N_("binary object format does not support extern variables")); sym = yasm_symtab_declare(objfmt_bin->symtab, name, YASM_SYM_EXTERN, line); return sym;}static yasm_symrec *bin_objfmt_global_declare(yasm_objfmt *objfmt, const char *name, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line){ yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt; yasm_symrec *sym; yasm__warning(YASM_WARN_GENERAL, line, N_("binary object format does not support global variables")); sym = yasm_symtab_declare(objfmt_bin->symtab, name, YASM_SYM_GLOBAL, line); return sym;}static yasm_symrec *bin_objfmt_common_declare(yasm_objfmt *objfmt, const char *name, /*@only@*/ yasm_expr *size, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line){ yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt; yasm_symrec *sym; yasm_expr_destroy(size); yasm__error(line, N_("binary object format does not support common variables")); sym = yasm_symtab_declare(objfmt_bin->symtab, name, YASM_SYM_COMMON, line); return sym;}static intbin_objfmt_directive(yasm_objfmt *objfmt, const char *name, yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line){ yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt; yasm_section *sect; yasm_valparam *vp; if (yasm__strcasecmp(name, "org") == 0) { /*@null@*/ yasm_expr *start = NULL; /* ORG takes just a simple integer as param */ vp = yasm_vps_first(valparams); if (vp->val) start = yasm_expr_create_ident(yasm_expr_sym(yasm_symtab_use( yasm_object_get_symtab(objfmt_bin->object), vp->val, line)), line); else if (vp->param) { start = vp->param; vp->param = NULL; /* Don't let valparams delete it */ } if (!start) { yasm__error(line, N_("argument to ORG must be expression")); return 0; } /* ORG changes the start of the .text section */ sect = yasm_object_find_general(objfmt_bin->object, ".text"); if (!sect) yasm_internal_error( N_("bin objfmt: .text section does not exist before ORG is called?")); yasm_section_set_start(sect, start, line); return 0; /* directive recognized */ } else return 1; /* directive unrecognized */}static voidbin_section_data_print(void *data, FILE *f, int indent_level){ fprintf(f, "%*salign=%ld\n", indent_level, "", *((unsigned long *)data));}/* Define valid debug formats to use with this object format */static const char *bin_objfmt_dbgfmt_keywords[] = { "null", NULL};/* Define objfmt structure -- see objfmt.h for details */yasm_objfmt_module yasm_bin_LTX_objfmt = { YASM_OBJFMT_VERSION, "Flat format binary", "bin", NULL, ".text", 16, bin_objfmt_dbgfmt_keywords, "null", bin_objfmt_create, bin_objfmt_output, bin_objfmt_destroy, bin_objfmt_section_switch, bin_objfmt_extern_declare, bin_objfmt_global_declare, bin_objfmt_common_declare, bin_objfmt_directive};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -