?? xdf-objfmt.c
字號:
/*@null@*/ xdf_objfmt_output_info *info = (xdf_objfmt_output_info *)d; yasm_objfmt_xdf *objfmt_xdf; /*@dependent@*/ /*@null@*/ xdf_section_data *xsd; /*@null@*/ xdf_symrec_data *xsymd; unsigned char *localbuf; /* Don't output absolute sections into the section table */ if (yasm_section_is_absolute(sect)) return 0; assert(info != NULL); objfmt_xdf = info->objfmt_xdf; xsd = yasm_section_get_data(sect, &xdf_section_data_cb); assert(xsd != NULL); localbuf = info->buf; xsymd = yasm_symrec_get_data(xsd->sym, &xdf_symrec_data_cb); assert(xsymd != NULL); YASM_WRITE_32_L(localbuf, xsymd->index); /* section name symbol */ if (xsd->addr) { yasm_intnum_get_sized(xsd->addr, localbuf, 8, 64, 0, 0, 0, 0); localbuf += 8; /* physical address */ } else { YASM_WRITE_32_L(localbuf, 0); YASM_WRITE_32_L(localbuf, 0); } YASM_WRITE_16_L(localbuf, xsd->align); /* alignment */ YASM_WRITE_16_L(localbuf, xsd->flags); /* flags */ YASM_WRITE_32_L(localbuf, xsd->scnptr); /* file ptr to data */ YASM_WRITE_32_L(localbuf, xsd->size); /* section size */ YASM_WRITE_32_L(localbuf, xsd->relptr); /* file ptr to relocs */ YASM_WRITE_32_L(localbuf, xsd->nreloc); /* num of relocation entries */ fwrite(info->buf, 32, 1, info->f); return 0;}static voidxdf_objfmt_output(yasm_objfmt *objfmt, FILE *f, const char *obj_filename, int all_syms, /*@unused@*/ yasm_dbgfmt *df){ yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt; xdf_objfmt_output_info info; unsigned char *localbuf; unsigned long symtab_count = 0; unsigned long strtab_offset; xdf_symtab_entry *entry; info.objfmt_xdf = objfmt_xdf; info.f = f; info.buf = yasm_xmalloc(REGULAR_OUTBUF_SIZE); /* Allocate space for headers by seeking forward */ if (fseek(f, (long)(16+32*(objfmt_xdf->parse_scnum)), SEEK_SET) < 0) { yasm__fatal(N_("could not seek on output file")); /*@notreached@*/ return; } /* Symbol table */ all_syms = 1; /* force all syms into symbol table */ if (all_syms) { /* Need to put all local syms into XDF symbol table */ yasm_symtab_traverse(objfmt_xdf->symtab, objfmt_xdf, xdf_objfmt_append_local_sym); } /* Get number of symbols */ if (STAILQ_EMPTY(&objfmt_xdf->xdf_symtab)) symtab_count = 0; else { /*@null@*/ /*@dependent@*/ xdf_symrec_data *sym_data_prev; entry = STAILQ_LAST(&objfmt_xdf->xdf_symtab, xdf_symtab_entry, link); sym_data_prev = yasm_symrec_get_data(entry->sym, &xdf_symrec_data_cb); assert(sym_data_prev != NULL); symtab_count = sym_data_prev->index + 1; } /* Get file offset of start of string table */ strtab_offset = 16+32*(objfmt_xdf->parse_scnum)+16*symtab_count; STAILQ_FOREACH(entry, &objfmt_xdf->xdf_symtab, link) { const char *name = yasm_symrec_get_name(entry->sym); const yasm_expr *equ_val; const yasm_intnum *intn; size_t len = strlen(name); /*@dependent@*/ /*@null@*/ xdf_symrec_data *xsymd; unsigned long value = 0; long scnum = -3; /* -3 = debugging symbol */ /*@dependent@*/ /*@null@*/ yasm_section *sect; /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc; yasm_sym_vis vis = yasm_symrec_get_visibility(entry->sym); unsigned long flags = 0; /* Get symrec's of_data (needed for storage class) */ xsymd = yasm_symrec_get_data(entry->sym, &xdf_symrec_data_cb); if (!xsymd) yasm_internal_error(N_("xdf: expected sym data to be present")); if (vis & YASM_SYM_GLOBAL) flags = XDF_SYM_GLOBAL; /* Look at symrec for value/scnum/etc. */ if (yasm_symrec_get_label(entry->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 if (yasm_section_is_absolute(sect)) { yasm_expr *abs_start; abs_start = yasm_expr_copy(yasm_section_get_start(sect)); intn = yasm_expr_get_intnum(&abs_start, yasm_common_calc_bc_dist); if (!intn) yasm__error(abs_start->line, N_("absolute section start not an integer expression")); else value = yasm_intnum_get_uint(intn); yasm_expr_destroy(abs_start); flags |= XDF_SYM_EQU; scnum = -2; /* -2 = absolute symbol */ } else yasm_internal_error(N_("didn't understand section")); if (precbc) value += precbc->offset + precbc->len; } } else if ((equ_val = yasm_symrec_get_equ(entry->sym))) { yasm_expr *equ_val_copy = yasm_expr_copy(equ_val); intn = yasm_expr_get_intnum(&equ_val_copy, yasm_common_calc_bc_dist); if (!intn) { if (vis & YASM_SYM_GLOBAL) yasm__error(equ_val->line, N_("global EQU value not an integer expression")); } 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, strtab_offset); /* string table offset */ strtab_offset += len+1; YASM_WRITE_32_L(localbuf, flags); /* flags */ fwrite(info.buf, 16, 1, f); } /* String table */ STAILQ_FOREACH(entry, &objfmt_xdf->xdf_symtab, link) { const char *name = yasm_symrec_get_name(entry->sym); size_t len = strlen(name); fwrite(name, len+1, 1, f); } /* Section data/relocs */ if (yasm_object_sections_traverse(objfmt_xdf->object, &info, xdf_objfmt_output_section)) return; /* Write headers */ if (fseek(f, 0, SEEK_SET) < 0) { yasm__fatal(N_("could not seek on output file")); /*@notreached@*/ return; } localbuf = info.buf; YASM_WRITE_32_L(localbuf, XDF_MAGIC); /* magic number */ YASM_WRITE_32_L(localbuf, objfmt_xdf->parse_scnum); /* number of sects */ YASM_WRITE_32_L(localbuf, symtab_count); /* number of symtabs */ /* size of sect headers + symbol table + strings */ YASM_WRITE_32_L(localbuf, strtab_offset-16); fwrite(info.buf, 16, 1, f); yasm_object_sections_traverse(objfmt_xdf->object, &info, xdf_objfmt_output_secthead); yasm_xfree(info.buf);}static voidxdf_objfmt_destroy(yasm_objfmt *objfmt){ yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt; xdf_symtab_entry *entry1, *entry2; /* Delete local symbol table */ entry1 = STAILQ_FIRST(&objfmt_xdf->xdf_symtab); while (entry1 != NULL) { entry2 = STAILQ_NEXT(entry1, link); yasm_xfree(entry1); entry1 = entry2; } yasm_xfree(objfmt);}static /*@observer@*/ /*@null@*/ yasm_section *xdf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line){ yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt; yasm_valparam *vp = yasm_vps_first(valparams); yasm_section *retval; int isnew; /*@dependent@*/ /*@null@*/ const yasm_intnum *absaddr = NULL; unsigned int addralign = 0; unsigned long flags = 0; int flags_override = 0; char *sectname; int resonly = 0; if (!vp || vp->param || !vp->val) return NULL; sectname = vp->val; while ((vp = yasm_vps_next(vp))) { flags_override = 1; if (yasm__strcasecmp(vp->val, "use16") == 0) { flags &= ~(XDF_SECT_USE_32|XDF_SECT_USE_64); flags |= XDF_SECT_USE_16; yasm_arch_set_var(objfmt_xdf->arch, "mode_bits", 16); } else if (yasm__strcasecmp(vp->val, "use32") == 0) { flags &= ~(XDF_SECT_USE_16|XDF_SECT_USE_64); flags |= XDF_SECT_USE_32; yasm_arch_set_var(objfmt_xdf->arch, "mode_bits", 32); } else if (yasm__strcasecmp(vp->val, "use64") == 0) { flags &= ~(XDF_SECT_USE_16|XDF_SECT_USE_32); flags |= XDF_SECT_USE_64; yasm_arch_set_var(objfmt_xdf->arch, "mode_bits", 64); } else if (yasm__strcasecmp(vp->val, "bss") == 0) { flags |= XDF_SECT_BSS; } else if (yasm__strcasecmp(vp->val, "flat") == 0) { flags |= XDF_SECT_FLAT; } else if (yasm__strcasecmp(vp->val, "absolute") == 0 && vp->param) { flags |= XDF_SECT_ABSOLUTE; absaddr = yasm_expr_get_intnum(&vp->param, NULL); if (!absaddr) { yasm__error(line, N_("argument to `%s' is not an integer"), vp->val); return NULL; } } else if (yasm__strcasecmp(vp->val, "align") == 0 && vp->param) { /*@dependent@*/ /*@null@*/ const yasm_intnum *align; unsigned long bitcnt; 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; } addralign = yasm_intnum_get_uint(align); /* Check to see if alignment is a power of two. * This can be checked by seeing if only one bit is set. */ BitCount(bitcnt, addralign); if (bitcnt > 1) { yasm__error(line, N_("argument to `%s' is not a power of two"), vp->val); return NULL; } /* Check to see if alignment is supported size */ if (addralign > 4096) { yasm__error(line, N_("XDF does not support alignments > 4096")); return NULL; } } else yasm__warning(YASM_WARN_GENERAL, line, N_("Unrecognized qualifier `%s'"), vp->val); } retval = yasm_object_get_general(objfmt_xdf->object, sectname, 0, resonly, &isnew, line); if (isnew) { xdf_section_data *data; yasm_symrec *sym; data = yasm_xmalloc(sizeof(xdf_section_data)); data->scnum = objfmt_xdf->parse_scnum++; data->align = addralign; data->flags = flags; if (absaddr) data->addr = yasm_intnum_copy(absaddr); else data->addr = NULL; data->scnptr = 0; data->size = 0; data->relptr = 0; data->nreloc = 0; STAILQ_INIT(&data->relocs); yasm_section_add_data(retval, &xdf_section_data_cb, data); sym = yasm_symtab_define_label(objfmt_xdf->symtab, sectname, yasm_section_bcs_first(retval), 1, line); xdf_objfmt_symtab_append(objfmt_xdf, sym); data->sym = sym; } else if (flags_override) yasm__warning(YASM_WARN_GENERAL, line, N_("section flags ignored on section redeclaration")); return retval;}static voidxdf_section_data_destroy(void *data){ xdf_section_data *xsd = (xdf_section_data *)data; if (xsd->addr) yasm_intnum_destroy(xsd->addr); yasm_xfree(data);}static voidxdf_section_data_print(void *data, FILE *f, int indent_level){ xdf_section_data *xsd = (xdf_section_data *)data; fprintf(f, "%*ssym=\n", indent_level, ""); yasm_symrec_print(xsd->sym, f, indent_level+1); fprintf(f, "%*sscnum=%ld\n", indent_level, "", xsd->scnum); fprintf(f, "%*sflags=0x%x\n", indent_level, "", xsd->flags); fprintf(f, "%*saddr=", indent_level, ""); yasm_intnum_print(xsd->addr, f); fprintf(f, "%*sscnptr=0x%lx\n", indent_level, "", xsd->scnptr); fprintf(f, "%*ssize=%ld\n", indent_level, "", xsd->size); fprintf(f, "%*srelptr=0x%lx\n", indent_level, "", xsd->relptr); fprintf(f, "%*snreloc=%ld\n", indent_level, "", xsd->nreloc); fprintf(f, "%*srelocs:\n", indent_level, "");}static yasm_symrec *xdf_objfmt_extern_declare(yasm_objfmt *objfmt, const char *name, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line){ yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt; yasm_symrec *sym; sym = yasm_symtab_declare(objfmt_xdf->symtab, name, YASM_SYM_EXTERN, line); xdf_objfmt_symtab_append(objfmt_xdf, sym); return sym;}static yasm_symrec *xdf_objfmt_global_declare(yasm_objfmt *objfmt, const char *name, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line){ yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt; yasm_symrec *sym; sym = yasm_symtab_declare(objfmt_xdf->symtab, name, YASM_SYM_GLOBAL, line); xdf_objfmt_symtab_append(objfmt_xdf, sym); return sym;}static yasm_symrec *xdf_objfmt_common_declare(yasm_objfmt *objfmt, const char *name, /*@only@*/ yasm_expr *size, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, unsigned long line){ yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt; yasm_symrec *sym; yasm_expr_destroy(size); yasm__error(line, N_("XDF object format does not support common variables")); sym = yasm_symtab_declare(objfmt_xdf->symtab, name, YASM_SYM_COMMON, line); return sym;}static voidxdf_symrec_data_destroy(void *data){ yasm_xfree(data);}static voidxdf_symrec_data_print(void *data, FILE *f, int indent_level){ xdf_symrec_data *xsd = (xdf_symrec_data *)data; fprintf(f, "%*ssymtab index=%lu\n", indent_level, "", xsd->index);}static intxdf_objfmt_directive(/*@unused@*/ yasm_objfmt *objfmt, /*@unused@*/ const char *name, /*@unused@*/ yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ yasm_valparamhead *objext_valparams, /*@unused@*/ unsigned long line){ return 1; /* no objfmt directives */}/* Define valid debug formats to use with this object format */static const char *xdf_objfmt_dbgfmt_keywords[] = { "null", NULL};/* Define objfmt structure -- see objfmt.h for details */yasm_objfmt_module yasm_xdf_LTX_objfmt = { YASM_OBJFMT_VERSION, "Extended Dynamic Object", "xdf", "xdf", ".text", 32, xdf_objfmt_dbgfmt_keywords, "null", xdf_objfmt_create, xdf_objfmt_output, xdf_objfmt_destroy, xdf_objfmt_section_switch, xdf_objfmt_extern_declare, xdf_objfmt_global_declare, xdf_objfmt_common_declare, xdf_objfmt_directive};
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -