From: Peter Johnson Date: Sat, 25 Feb 2006 19:39:57 +0000 (-0000) Subject: Fix #70 by allowing overrides on the default (usually ".text") section. X-Git-Tag: v0.5.0rc2~5^2~48 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b5c76541cb88717b50a9442b4587eadb3f5f8247;p=yasm Fix #70 by allowing overrides on the default (usually ".text") section. The fix for this rippled into a lot of places, and I'm starting to see some opportunities for cleaning up some of the object and objfmt structures. * objfmt.h (yasm_objfmt_add_default_section): Move from standalone function into objfmt-specific function. (yasm_objfmt_module): Remove default_section_name string, and add objfmt specific add_default_section function. * yasm.c (main): Use slightly updated parameters when calling. * section.h (yasm_section_is_default, yasm_section_set_default): New. * section.c (yasm_section): Add def member (for default section flag). (yasm_section_is_default, yasm_section_set_default): Implement. * xdf-objfmt.c, bin-objfmt.c, dbg-objfmt.c, coff-objfmt.c: Implement. Usually this required refactoring the objfmt-specific section data creation into a separate function that could be used by both section_switch() and the new add_default_section() functions, and changing section_switch() to update changes to the section data if section was new or previously just a default section, instead of the previous behavior of warning if the section was not new. * objfmt.c: Delete (no longer needed). * Makefile.inc, Makefile.flat, libyasm.vcproj Makefile.dj: Update to reflect removal. * xdf-overdef.asm, win32-overdef.asm, elf-overdef.asm: Test. svn path=/trunk/yasm/; revision=1390 --- diff --git a/Mkfiles/Makefile.dj b/Mkfiles/Makefile.dj index 78fb39a5..4ddcb664 100644 --- a/Mkfiles/Makefile.dj +++ b/Mkfiles/Makefile.dj @@ -28,7 +28,6 @@ LIBYASM_OBJS= \ libyasm/intnum.o \ libyasm/linemgr.o \ libyasm/mergesort.o \ - libyasm/objfmt.o \ libyasm/section.o \ libyasm/splitpath.o \ libyasm/strcasecmp.o \ diff --git a/Mkfiles/Makefile.flat b/Mkfiles/Makefile.flat index 5dc40971..b72e09fb 100644 --- a/Mkfiles/Makefile.flat +++ b/Mkfiles/Makefile.flat @@ -31,7 +31,6 @@ LIBYASM_OBJS= \ libyasm/intnum.o \ libyasm/linemgr.o \ libyasm/mergesort.o \ - libyasm/objfmt.o \ libyasm/section.o \ libyasm/splitpath.o \ libyasm/strcasecmp.o \ diff --git a/Mkfiles/vc/libyasm/libyasm.vcproj b/Mkfiles/vc/libyasm/libyasm.vcproj index 3fce785b..8fb3329b 100644 --- a/Mkfiles/vc/libyasm/libyasm.vcproj +++ b/Mkfiles/vc/libyasm/libyasm.vcproj @@ -346,9 +346,6 @@ - - - - diff --git a/frontends/yasm/yasm.c b/frontends/yasm/yasm.c index 2544c290..b8c035a6 100644 --- a/frontends/yasm/yasm.c +++ b/frontends/yasm/yasm.c @@ -553,7 +553,7 @@ main(int argc, char *argv[]) cur_objfmt_module = ((yasm_objfmt_base *)cur_objfmt)->module; /* Add an initial "default" section to object */ - def_sect = yasm_objfmt_add_default_section(cur_objfmt, object); + def_sect = yasm_objfmt_add_default_section(cur_objfmt); /* Initialize the debug format */ cur_dbgfmt = yasm_dbgfmt_create(cur_dbgfmt_module, object, cur_objfmt, diff --git a/libyasm/Makefile.inc b/libyasm/Makefile.inc index 78d59a0d..b220a2a8 100644 --- a/libyasm/Makefile.inc +++ b/libyasm/Makefile.inc @@ -6,7 +6,6 @@ libyasm_a_SOURCES += libyasm/symrec.c libyasm_a_SOURCES += libyasm/file.c libyasm_a_SOURCES += libyasm/section.c libyasm_a_SOURCES += libyasm/arch.c -libyasm_a_SOURCES += libyasm/objfmt.c libyasm_a_SOURCES += libyasm/intnum.c libyasm_a_SOURCES += libyasm/floatnum.c libyasm_a_SOURCES += libyasm/hamt.c diff --git a/libyasm/objfmt.c b/libyasm/objfmt.c deleted file mode 100644 index 798c1136..00000000 --- a/libyasm/objfmt.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Object format interface - * - * Copyright (C) 2003 Peter Johnson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#define YASM_LIB_INTERNAL -#define YASM_ARCH_INTERNAL -#include "util.h" -/*@unused@*/ RCSID("$Id$"); - -#include "coretype.h" -#include "valparam.h" - -#include "objfmt.h" - - -yasm_section * -yasm_objfmt_add_default_section(yasm_objfmt *objfmt, yasm_object *object) -{ - yasm_objfmt_base *of_base = (yasm_objfmt_base *)objfmt; - yasm_section *retval; - yasm_valparamhead vps; - yasm_valparam *vp; - - vp = yasm_vp_create(yasm__xstrdup(of_base->module->default_section_name), - NULL); - yasm_vps_initialize(&vps); - yasm_vps_append(&vps, vp); - retval = yasm_objfmt_section_switch(objfmt, &vps, NULL, 0); - yasm_vps_delete(&vps); - - return retval; -} diff --git a/libyasm/objfmt.h b/libyasm/objfmt.h index 33ccb6a7..e498e185 100644 --- a/libyasm/objfmt.h +++ b/libyasm/objfmt.h @@ -57,9 +57,6 @@ typedef struct yasm_objfmt_module { */ /*@null@*/ const char *extension; - /** Default (starting) section name. */ - const char *default_section_name; - /** Default (starting) x86 BITS setting. This only appies to the x86 * architecture; other architectures ignore this setting. */ @@ -97,6 +94,11 @@ typedef struct yasm_objfmt_module { */ void (*destroy) (/*@only@*/ yasm_objfmt *objfmt); + /** Module-level implementation of yasm_objfmt_add_default_section(). + * Call yasm_objfmt_add_default_section() instead of calling this function. + */ + yasm_section * (*add_default_section) (yasm_objfmt *objfmt); + /** Module-level implementation of yasm_objfmt_section_switch(). * Call yasm_objfmt_section_switch() instead of calling this function. */ @@ -161,6 +163,13 @@ void yasm_objfmt_output(yasm_objfmt *objfmt, FILE *f, int all_syms, */ void yasm_objfmt_destroy(/*@only@*/ yasm_objfmt *objfmt); +/** Add a default section to an object. + * \param objfmt object format + * \param object object + * \return Default section. + */ +yasm_section *yasm_objfmt_add_default_section(yasm_objfmt *objfmt); + /** Switch object file sections. The first val of the valparams should * be the section name. Calls yasm_object_get_general() to actually get * the section. @@ -251,14 +260,9 @@ int yasm_objfmt_directive(yasm_objfmt *objfmt, const char *name, #define yasm_objfmt_directive(objfmt, name, vpms, oe_vpms, line) \ ((yasm_objfmt_base *)objfmt)->module->directive(objfmt, name, vpms, \ oe_vpms, line) +#define yasm_objfmt_add_default_section(objfmt) \ + ((yasm_objfmt_base *)objfmt)->module->add_default_section(objfmt) #endif -/** Add a default section to an object. - * \param objfmt object format - * \param object object - * \return Default section. - */ -yasm_section *yasm_objfmt_add_default_section(yasm_objfmt *objfmt, - yasm_object *object); #endif diff --git a/libyasm/section.c b/libyasm/section.c index 4a7283af..54d49b5f 100644 --- a/libyasm/section.c +++ b/libyasm/section.c @@ -80,6 +80,8 @@ struct yasm_section { int code; /* section contains code (instructions) */ int res_only; /* allow only resb family of bytecodes? */ + int def; /* "default" section, e.g. not specified by + using section directive */ /* the bytecodes for the section's contents */ /*@reldef@*/ STAILQ_HEAD(yasm_bytecodehead, yasm_bytecode) bcs; @@ -165,6 +167,7 @@ yasm_object_get_general(yasm_object *object, const char *name, s->code = code; s->res_only = res_only; + s->def = 0; *isnew = 1; return s; @@ -198,7 +201,9 @@ yasm_object_create_absolute(yasm_object *object, yasm_expr *start, STAILQ_INIT(&s->relocs); s->destroy_reloc = NULL; + s->code = 0; s->res_only = 1; + s->def = 0; return s; } @@ -259,6 +264,18 @@ yasm_section_set_opt_flags(yasm_section *sect, unsigned long opt_flags) sect->opt_flags = opt_flags; } +int +yasm_section_is_default(const yasm_section *sect) +{ + return sect->def; +} + +void +yasm_section_set_default(yasm_section *sect, int def) +{ + sect->def = def; +} + yasm_object * yasm_section_get_object(const yasm_section *sect) { diff --git a/libyasm/section.h b/libyasm/section.h index c48fae40..531a5195 100644 --- a/libyasm/section.h +++ b/libyasm/section.h @@ -180,6 +180,19 @@ unsigned long yasm_section_get_opt_flags(const yasm_section *sect); */ void yasm_section_set_opt_flags(yasm_section *sect, unsigned long opt_flags); +/** Determine if a section was declared as the "default" section (e.g. not + * created through a section directive). + * \param sect section + * \return Nonzero if section was declared as default. + */ +int yasm_section_is_default(const yasm_section *sect); + +/** Set section "default" flag to a new value. + * \param sect section + * \param def new value of default flag + */ +void yasm_section_set_default(yasm_section *sect, int def); + /** Get object owner of a section. * \param sect section * \return Object this section is a part of. diff --git a/modules/objfmts/bin/bin-objfmt.c b/modules/objfmts/bin/bin-objfmt.c index 645ff8f7..9dfca3fd 100644 --- a/modules/objfmts/bin/bin-objfmt.c +++ b/modules/objfmts/bin/bin-objfmt.c @@ -334,6 +334,31 @@ bin_objfmt_destroy(yasm_objfmt *objfmt) yasm_xfree(objfmt); } +static void +bin_objfmt_init_new_section(yasm_objfmt_bin *objfmt_bin, yasm_section *sect, + const char *sectname, unsigned long line) +{ + yasm_symtab_define_label( + yasm_object_get_symtab(objfmt_bin->object), sectname, + yasm_section_bcs_first(sect), 1, line); +} + +static yasm_section * +bin_objfmt_add_default_section(yasm_objfmt *objfmt) +{ + yasm_objfmt_bin *objfmt_bin = (yasm_objfmt_bin *)objfmt; + yasm_section *retval; + int isnew; + + retval = yasm_object_get_general(objfmt_bin->object, ".text", 0, 16, 1, 0, + &isnew, 0); + if (isnew) { + bin_objfmt_init_new_section(objfmt_bin, retval, ".text", 0); + yasm_section_set_default(retval, 1); + } + return retval; +} + static /*@observer@*/ /*@null@*/ yasm_section * bin_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ @@ -413,10 +438,12 @@ bin_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, yasm_expr_int(yasm_intnum_create_uint(start)), line), align, strcmp(sectname, ".text") == 0, resonly, &isnew, line); - if (isnew) { - yasm_symtab_define_label( - yasm_object_get_symtab(objfmt_bin->object), sectname, - yasm_section_bcs_first(retval), 1, line); + if (isnew) + bin_objfmt_init_new_section(objfmt_bin, retval, sectname, line); + + if (isnew || yasm_section_is_default(retval)) { + yasm_section_set_default(retval, 0); + yasm_section_set_align(retval, align, line); } else if (have_align) yasm__warning(YASM_WARN_GENERAL, line, N_("alignment value ignored on section redeclaration")); @@ -528,13 +555,13 @@ yasm_objfmt_module yasm_bin_LTX_objfmt = { "Flat format binary", "bin", NULL, - ".text", 16, bin_objfmt_dbgfmt_keywords, "null", bin_objfmt_create, bin_objfmt_output, bin_objfmt_destroy, + bin_objfmt_add_default_section, bin_objfmt_section_switch, bin_objfmt_extern_declare, bin_objfmt_global_declare, diff --git a/modules/objfmts/coff/coff-objfmt.c b/modules/objfmts/coff/coff-objfmt.c index d0ed68c3..6961a403 100644 --- a/modules/objfmts/coff/coff-objfmt.c +++ b/modules/objfmts/coff/coff-objfmt.c @@ -1054,24 +1054,22 @@ coff_objfmt_destroy(yasm_objfmt *objfmt) yasm_xfree(objfmt); } -static void -coff_objfmt_init_new_section(yasm_objfmt_coff *objfmt_coff, - yasm_section *sect, const char *sectname, - unsigned long flags, unsigned long flags2, - unsigned long line) +static coff_section_data * +coff_objfmt_init_new_section(yasm_objfmt_coff *objfmt_coff, yasm_section *sect, + const char *sectname, unsigned long line) { coff_section_data *data; yasm_symrec *sym; data = yasm_xmalloc(sizeof(coff_section_data)); data->scnum = objfmt_coff->parse_scnum++; - data->flags = flags; + data->flags = 0; data->addr = 0; data->scnptr = 0; data->size = 0; data->relptr = 0; data->nreloc = 0; - data->flags2 = flags2; + data->flags2 = 0; data->strtab_name = 0; yasm_section_add_data(sect, &coff_section_data_cb, data); @@ -1081,6 +1079,27 @@ coff_objfmt_init_new_section(yasm_objfmt_coff *objfmt_coff, coff_objfmt_sym_set_data(sym, COFF_SCL_STAT, NULL, 1, COFF_SYMTAB_AUX_SECT); data->sym = sym; + return data; +} + +static yasm_section * +coff_objfmt_add_default_section(yasm_objfmt *objfmt) +{ + yasm_objfmt_coff *objfmt_coff = (yasm_objfmt_coff *)objfmt; + yasm_section *retval; + coff_section_data *csd; + int isnew; + + retval = yasm_object_get_general(objfmt_coff->object, ".text", 0, 16, 1, 0, + &isnew, 0); + if (isnew) { + csd = coff_objfmt_init_new_section(objfmt_coff, retval, ".text", 0); + csd->flags = COFF_STYP_TEXT; + if (objfmt_coff->win32) + csd->flags |= COFF_STYP_EXECUTE | COFF_STYP_READ; + yasm_section_set_default(retval, 1); + } + return retval; } static /*@observer@*/ /*@null@*/ yasm_section * @@ -1093,12 +1112,14 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, yasm_valparam *vp = yasm_vps_first(valparams); yasm_section *retval; int isnew; + int iscode = 0; unsigned long flags; unsigned long flags2 = 0; int flags_override = 0; char *sectname; int resonly = 0; unsigned long align = 0; + coff_section_data *csd; static const struct { const char *name; @@ -1173,6 +1194,7 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, flags |= COFF_STYP_EXECUTE | COFF_STYP_READ; align = 16; } + iscode = 1; } else if (strcmp(sectname, ".rdata") == 0) { flags = COFF_STYP_DATA; if (objfmt_coff->win32) { @@ -1201,6 +1223,7 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, flags = COFF_STYP_TEXT; if (objfmt_coff->win32) flags |= COFF_STYP_EXECUTE | COFF_STYP_READ; + iscode = 1; } while ((vp = yasm_vps_next(vp))) { @@ -1226,12 +1249,16 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, flags2 &= ~flagquals[i].flags2; if (objfmt_coff->win32) flags &= ~flagquals[i].win32flags; + if (flagquals[i].win32flags & COFF_STYP_EXECUTE) + iscode = 0; break; case 1: flags |= flagquals[i].stdflags; flags2 |= flagquals[i].flags2; if (objfmt_coff->win32) flags |= flagquals[i].win32flags; + if (flagquals[i].win32flags & COFF_STYP_EXECUTE) + iscode = 1; break; case 2: flags &= ~COFF_STYP_STD_MASK; @@ -1241,6 +1268,8 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, flags &= ~COFF_STYP_WIN32_MASK; flags |= flagquals[i].win32flags; } + if (flagquals[i].win32flags & COFF_STYP_EXECUTE) + iscode = 1; break; } flags_override = 1; @@ -1347,13 +1376,19 @@ coff_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, } retval = yasm_object_get_general(objfmt_coff->object, sectname, 0, align, - (flags & COFF_STYP_EXECUTE) != 0, - resonly, &isnew, line); + iscode, resonly, &isnew, line); if (isnew) - coff_objfmt_init_new_section(objfmt_coff, retval, sectname, flags, - flags2, line); - else if (flags_override) + csd = coff_objfmt_init_new_section(objfmt_coff, retval, sectname, line); + else + csd = yasm_section_get_data(retval, &coff_section_data_cb); + + if (isnew || yasm_section_is_default(retval)) { + yasm_section_set_default(retval, 0); + csd->flags = flags; + csd->flags2 = flags2; + yasm_section_set_align(retval, align, line); + } else if (flags_override) yasm__warning(YASM_WARN_GENERAL, line, N_("section flags ignored on section redeclaration")); return retval; @@ -1508,11 +1543,13 @@ win32_objfmt_directive(yasm_objfmt *objfmt, const char *name, 0, 0, &isnew, line); /* Initialize directive section if needed */ - if (isnew) - coff_objfmt_init_new_section(objfmt_coff, sect, - yasm_section_get_name(sect), - COFF_STYP_INFO | COFF_STYP_DISCARD - | COFF_STYP_READ, 0, line); + if (isnew) { + coff_section_data *csd; + csd = coff_objfmt_init_new_section(objfmt_coff, sect, + yasm_section_get_name(sect), + line); + csd->flags = COFF_STYP_INFO | COFF_STYP_DISCARD | COFF_STYP_READ; + } /* Add text as data bytecode */ yasm_dvs_initialize(&dvs); @@ -1542,13 +1579,13 @@ yasm_objfmt_module yasm_coff_LTX_objfmt = { "COFF (DJGPP)", "coff", "o", - ".text", 32, coff_objfmt_dbgfmt_keywords, "null", coff_objfmt_create, coff_objfmt_output, coff_objfmt_destroy, + coff_objfmt_add_default_section, coff_objfmt_section_switch, coff_objfmt_extern_declare, coff_objfmt_global_declare, @@ -1561,13 +1598,13 @@ yasm_objfmt_module yasm_win32_LTX_objfmt = { "Win32", "win32", "obj", - ".text", 32, coff_objfmt_dbgfmt_keywords, "null", win32_objfmt_create, coff_objfmt_output, coff_objfmt_destroy, + coff_objfmt_add_default_section, coff_objfmt_section_switch, coff_objfmt_extern_declare, coff_objfmt_global_declare, @@ -1580,13 +1617,13 @@ yasm_objfmt_module yasm_win64_LTX_objfmt = { "Win64", "win64", "obj", - ".text", 64, coff_objfmt_dbgfmt_keywords, "null", win64_objfmt_create, coff_objfmt_output, coff_objfmt_destroy, + coff_objfmt_add_default_section, coff_objfmt_section_switch, coff_objfmt_extern_declare, coff_objfmt_global_declare, @@ -1597,13 +1634,13 @@ yasm_objfmt_module yasm_x64_LTX_objfmt = { "Win64", "x64", "obj", - ".text", 64, coff_objfmt_dbgfmt_keywords, "null", win64_objfmt_create, coff_objfmt_output, coff_objfmt_destroy, + coff_objfmt_add_default_section, coff_objfmt_section_switch, coff_objfmt_extern_declare, coff_objfmt_global_declare, diff --git a/modules/objfmts/dbg/dbg-objfmt.c b/modules/objfmts/dbg/dbg-objfmt.c index 84d60c2b..525d9eb2 100644 --- a/modules/objfmts/dbg/dbg-objfmt.c +++ b/modules/objfmts/dbg/dbg-objfmt.c @@ -95,6 +95,26 @@ dbg_objfmt_destroy(yasm_objfmt *objfmt) yasm_xfree(objfmt); } +static yasm_section * +dbg_objfmt_add_default_section(yasm_objfmt *objfmt) +{ + yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)objfmt; + yasm_section *retval; + int isnew; + + retval = yasm_object_get_general(objfmt_dbg->object, ".text", + yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(200)), 0), + 0, 0, 0, &isnew, 0); + if (isnew) { + fprintf(objfmt_dbg->dbgfile, "(new) "); + yasm_symtab_define_label( + yasm_object_get_symtab(objfmt_dbg->object), ".text", + yasm_section_bcs_first(retval), 1, 0); + yasm_section_set_default(retval, 1); + } + return retval; +} + static /*@observer@*/ /*@null@*/ yasm_section * dbg_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ @@ -122,6 +142,7 @@ dbg_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, yasm_object_get_symtab(objfmt_dbg->object), vp->val, yasm_section_bcs_first(retval), 1, line); } + yasm_section_set_default(retval, 0); fprintf(objfmt_dbg->dbgfile, "\"%s\" section\n", vp->val); return retval; } else { @@ -214,13 +235,13 @@ yasm_objfmt_module yasm_dbg_LTX_objfmt = { "Trace of all info passed to object format module", "dbg", "dbg", - ".text", 32, dbg_objfmt_dbgfmt_keywords, "null", dbg_objfmt_create, dbg_objfmt_output, dbg_objfmt_destroy, + dbg_objfmt_add_default_section, dbg_objfmt_section_switch, dbg_objfmt_extern_declare, dbg_objfmt_global_declare, diff --git a/modules/objfmts/elf/elf-objfmt.c b/modules/objfmts/elf/elf-objfmt.c index e622f6e3..c895fc46 100644 --- a/modules/objfmts/elf/elf-objfmt.c +++ b/modules/objfmts/elf/elf-objfmt.c @@ -748,6 +748,43 @@ elf_objfmt_destroy(yasm_objfmt *objfmt) yasm_xfree(objfmt); } +static elf_secthead * +elf_objfmt_init_new_section(yasm_objfmt_elf *objfmt_elf, yasm_section *sect, + const char *sectname, unsigned long type, + unsigned long flags, unsigned long line) +{ + elf_secthead *esd; + yasm_symrec *sym; + elf_strtab_entry *name = elf_strtab_append_str(objfmt_elf->shstrtab, + sectname); + + esd = elf_secthead_create(name, type, flags, 0, 0); + yasm_section_add_data(sect, &elf_section_data, esd); + sym = yasm_symtab_define_label( + yasm_object_get_symtab(objfmt_elf->object), sectname, + yasm_section_bcs_first(sect), 1, line); + + elf_secthead_set_sym(esd, sym); + + return esd; +} + +static yasm_section * +elf_objfmt_add_default_section(yasm_objfmt *objfmt) +{ + yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)objfmt; + yasm_section *retval; + int isnew; + elf_secthead *esd; + + retval = yasm_object_get_general(objfmt_elf->object, ".text", 0, 16, 1, 0, + &isnew, 0); + esd = elf_objfmt_init_new_section(objfmt_elf, retval, ".text", SHT_PROGBITS, + SHF_ALLOC + SHF_EXECINSTR, 0); + yasm_section_set_default(retval, 1); + return retval; +} + static /*@observer@*/ /*@null@*/ yasm_section * elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, /*@null@*/ yasm_valparamhead *objext_valparams, @@ -773,6 +810,8 @@ elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, /*{ "progbits", SHT_PROGBITS },*/ /*{ "align", 0 } */ }; + /*@dependent@*/ /*@null@*/ const yasm_intnum *merge_intn = NULL; + elf_secthead *esd; if (!vp || vp->param || !vp->val) return NULL; @@ -892,36 +931,13 @@ elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, yasm__warning(YASM_WARN_GENERAL, line, N_("Unrecognized qualifier `%s'"), vp->val); } - - retval = yasm_object_get_general(objfmt_elf->object, sectname, 0, align, - (flags & SHF_EXECINSTR) != 0, resonly, - &isnew, line); - - if (isnew) { - elf_secthead *esd; - yasm_symrec *sym; - elf_strtab_entry *name = elf_strtab_append_str(objfmt_elf->shstrtab, - sectname); - - esd = elf_secthead_create(name, type, flags, 0, 0); - yasm_section_add_data(retval, &elf_section_data, esd); - sym = yasm_symtab_define_label( - yasm_object_get_symtab(objfmt_elf->object), sectname, - yasm_section_bcs_first(retval), 1, line); - - elf_secthead_set_sym(esd, sym); - /* Handle merge entity size */ if (flags & SHF_MERGE) { if (objext_valparams && (vp = yasm_vps_first(objext_valparams)) && vp->param) { - /*@dependent@*/ /*@null@*/ const yasm_intnum *merge_intn; merge_intn = yasm_expr_get_intnum(&vp->param, NULL); - if (merge_intn) - elf_secthead_set_entsize(esd, - yasm_intnum_get_uint(merge_intn)); - else + if (!merge_intn) yasm__warning(YASM_WARN_GENERAL, line, N_("invalid merge entity size")); } else { @@ -930,6 +946,23 @@ elf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, flags &= ~SHF_MERGE; } } + + retval = yasm_object_get_general(objfmt_elf->object, sectname, 0, align, + (flags & SHF_EXECINSTR) != 0, resonly, + &isnew, line); + + if (isnew) + esd = elf_objfmt_init_new_section(objfmt_elf, retval, sectname, type, + flags, line); + else + esd = yasm_section_get_data(retval, &elf_section_data); + + if (isnew || yasm_section_is_default(retval)) { + yasm_section_set_default(retval, 0); + elf_secthead_set_typeflags(esd, type, flags); + if (merge_intn) + elf_secthead_set_entsize(esd, yasm_intnum_get_uint(merge_intn)); + yasm_section_set_align(retval, align, line); } else if (flags_override) yasm__warning(YASM_WARN_GENERAL, line, N_("section flags ignored on section redeclaration")); @@ -1149,13 +1182,13 @@ yasm_objfmt_module yasm_elf_LTX_objfmt = { "ELF", "elf", "o", - ".text", 32, elf_objfmt_dbgfmt_keywords, "null", elf_objfmt_create, elf_objfmt_output, elf_objfmt_destroy, + elf_objfmt_add_default_section, elf_objfmt_section_switch, elf_objfmt_extern_declare, elf_objfmt_global_declare, @@ -1167,13 +1200,13 @@ yasm_objfmt_module yasm_elf32_LTX_objfmt = { "ELF (32-bit)", "elf32", "o", - ".text", 32, elf_objfmt_dbgfmt_keywords, "null", elf32_objfmt_create, elf_objfmt_output, elf_objfmt_destroy, + elf_objfmt_add_default_section, elf_objfmt_section_switch, elf_objfmt_extern_declare, elf_objfmt_global_declare, @@ -1185,13 +1218,13 @@ yasm_objfmt_module yasm_elf64_LTX_objfmt = { "ELF (64-bit)", "elf64", "o", - ".text", 64, elf_objfmt_dbgfmt_keywords, "null", elf64_objfmt_create, elf_objfmt_output, elf_objfmt_destroy, + elf_objfmt_add_default_section, elf_objfmt_section_switch, elf_objfmt_extern_declare, elf_objfmt_global_declare, diff --git a/modules/objfmts/elf/elf.c b/modules/objfmts/elf/elf.c index 6e4aad2b..84d50739 100644 --- a/modules/objfmts/elf/elf.c +++ b/modules/objfmts/elf/elf.c @@ -747,6 +747,14 @@ elf_secthead_get_type(elf_secthead *shead) return shead->type; } +void +elf_secthead_set_typeflags(elf_secthead *shead, elf_section_type type, + elf_section_flags flags) +{ + shead->type = type; + shead->flags = flags; +} + int elf_secthead_is_empty(elf_secthead *shead) { diff --git a/modules/objfmts/elf/elf.h b/modules/objfmts/elf/elf.h index e7e37339..e9af8848 100644 --- a/modules/objfmts/elf/elf.h +++ b/modules/objfmts/elf/elf.h @@ -462,6 +462,8 @@ unsigned long elf_secthead_write_to_file(FILE *f, elf_secthead *esd, void elf_secthead_append_reloc(yasm_section *sect, elf_secthead *shead, elf_reloc_entry *reloc); elf_section_type elf_secthead_get_type(elf_secthead *shead); +void elf_secthead_set_typeflags(elf_secthead *shead, elf_section_type type, + elf_section_flags flags); int elf_secthead_is_empty(elf_secthead *shead); struct yasm_symrec *elf_secthead_get_sym(elf_secthead *shead); unsigned long elf_secthead_get_align(const elf_secthead *shead); diff --git a/modules/objfmts/elf/tests/Makefile.inc b/modules/objfmts/elf/tests/Makefile.inc index 15f35652..873485b1 100644 --- a/modules/objfmts/elf/tests/Makefile.inc +++ b/modules/objfmts/elf/tests/Makefile.inc @@ -19,6 +19,9 @@ EXTRA_DIST += modules/objfmts/elf/tests/elftest.errwarn EXTRA_DIST += modules/objfmts/elf/tests/elftimes.asm EXTRA_DIST += modules/objfmts/elf/tests/elftimes.hex EXTRA_DIST += modules/objfmts/elf/tests/elftimes.errwarn +EXTRA_DIST += modules/objfmts/elf/tests/elf-overdef.asm +EXTRA_DIST += modules/objfmts/elf/tests/elf-overdef.hex +EXTRA_DIST += modules/objfmts/elf/tests/elf-overdef.errwarn EXTRA_DIST += modules/objfmts/elf/tests/elf-x86id.asm EXTRA_DIST += modules/objfmts/elf/tests/elf-x86id.hex EXTRA_DIST += modules/objfmts/elf/tests/elf-x86id.errwarn diff --git a/modules/objfmts/elf/tests/elf-overdef.asm b/modules/objfmts/elf/tests/elf-overdef.asm new file mode 100644 index 00000000..e42d1f48 --- /dev/null +++ b/modules/objfmts/elf/tests/elf-overdef.asm @@ -0,0 +1,2 @@ +section .text align=64 + diff --git a/modules/objfmts/elf/tests/elf-overdef.errwarn b/modules/objfmts/elf/tests/elf-overdef.errwarn new file mode 100644 index 00000000..e69de29b diff --git a/modules/objfmts/elf/tests/elf-overdef.hex b/modules/objfmts/elf/tests/elf-overdef.hex new file mode 100644 index 00000000..30b8ed4e --- /dev/null +++ b/modules/objfmts/elf/tests/elf-overdef.hex @@ -0,0 +1,360 @@ +7f +45 +4c +46 +01 +01 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +03 +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +a0 +00 +00 +00 +00 +00 +00 +00 +34 +00 +00 +00 +00 +00 +28 +00 +05 +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +2e +74 +65 +78 +74 +00 +2e +73 +74 +72 +74 +61 +62 +00 +2e +73 +79 +6d +74 +61 +62 +00 +2e +73 +68 +73 +74 +72 +74 +61 +62 +00 +00 +00 +00 +00 +2d +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +00 +f1 +ff +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +17 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +21 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +64 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +0f +00 +00 +00 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +68 +00 +00 +00 +30 +00 +00 +00 +02 +00 +00 +00 +03 +00 +00 +00 +04 +00 +00 +00 +10 +00 +00 +00 +01 +00 +00 +00 +01 +00 +00 +00 +06 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +00 +00 +00 +00 diff --git a/modules/objfmts/win32/tests/Makefile.inc b/modules/objfmts/win32/tests/Makefile.inc index 0fdd0353..ea6c9e49 100644 --- a/modules/objfmts/win32/tests/Makefile.inc +++ b/modules/objfmts/win32/tests/Makefile.inc @@ -6,6 +6,9 @@ EXTRA_DIST += modules/objfmts/win32/tests/export.asm EXTRA_DIST += modules/objfmts/win32/tests/export.hex EXTRA_DIST += modules/objfmts/win32/tests/export.errwarn EXTRA_DIST += modules/objfmts/win32/tests/win32_test.sh +EXTRA_DIST += modules/objfmts/win32/tests/win32-overdef.asm +EXTRA_DIST += modules/objfmts/win32/tests/win32-overdef.hex +EXTRA_DIST += modules/objfmts/win32/tests/win32-overdef.errwarn EXTRA_DIST += modules/objfmts/win32/tests/win32test.c EXTRA_DIST += modules/objfmts/win32/tests/win32test.asm EXTRA_DIST += modules/objfmts/win32/tests/win32test.hex diff --git a/modules/objfmts/win32/tests/win32-overdef.asm b/modules/objfmts/win32/tests/win32-overdef.asm new file mode 100644 index 00000000..e42d1f48 --- /dev/null +++ b/modules/objfmts/win32/tests/win32-overdef.asm @@ -0,0 +1,2 @@ +section .text align=64 + diff --git a/modules/objfmts/win32/tests/win32-overdef.errwarn b/modules/objfmts/win32/tests/win32-overdef.errwarn new file mode 100644 index 00000000..e69de29b diff --git a/modules/objfmts/win32/tests/win32-overdef.hex b/modules/objfmts/win32/tests/win32-overdef.hex new file mode 100644 index 00000000..00d97cd6 --- /dev/null +++ b/modules/objfmts/win32/tests/win32-overdef.hex @@ -0,0 +1,136 @@ +4c +01 +01 +00 +00 +00 +00 +00 +3c +00 +00 +00 +04 +00 +00 +00 +00 +00 +0c +01 +2e +74 +65 +78 +74 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +00 +70 +60 +2e +66 +69 +6c +65 +00 +00 +00 +00 +00 +00 +00 +fe +ff +00 +00 +67 +01 +2d +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +2e +74 +65 +78 +74 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +03 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +00 +00 +00 diff --git a/modules/objfmts/xdf/tests/Makefile.inc b/modules/objfmts/xdf/tests/Makefile.inc index bec2fb38..babc0566 100644 --- a/modules/objfmts/xdf/tests/Makefile.inc +++ b/modules/objfmts/xdf/tests/Makefile.inc @@ -12,6 +12,9 @@ EXTRA_DIST += modules/objfmts/xdf/tests/xdfprotect.errwarn EXTRA_DIST += modules/objfmts/xdf/tests/xdfother.asm EXTRA_DIST += modules/objfmts/xdf/tests/xdfother.hex EXTRA_DIST += modules/objfmts/xdf/tests/xdfother.errwarn +EXTRA_DIST += modules/objfmts/xdf/tests/xdf-overdef.asm +EXTRA_DIST += modules/objfmts/xdf/tests/xdf-overdef.hex +EXTRA_DIST += modules/objfmts/xdf/tests/xdf-overdef.errwarn EXTRA_DIST += modules/objfmts/xdf/tests/xdfvirtual.asm EXTRA_DIST += modules/objfmts/xdf/tests/xdfvirtual.hex EXTRA_DIST += modules/objfmts/xdf/tests/xdfvirtual.errwarn diff --git a/modules/objfmts/xdf/tests/xdf-overdef.asm b/modules/objfmts/xdf/tests/xdf-overdef.asm new file mode 100644 index 00000000..e42d1f48 --- /dev/null +++ b/modules/objfmts/xdf/tests/xdf-overdef.asm @@ -0,0 +1,2 @@ +section .text align=64 + diff --git a/modules/objfmts/xdf/tests/xdf-overdef.errwarn b/modules/objfmts/xdf/tests/xdf-overdef.errwarn new file mode 100644 index 00000000..e69de29b diff --git a/modules/objfmts/xdf/tests/xdf-overdef.hex b/modules/objfmts/xdf/tests/xdf-overdef.hex new file mode 100644 index 00000000..d98026d2 --- /dev/null +++ b/modules/objfmts/xdf/tests/xdf-overdef.hex @@ -0,0 +1,78 @@ +22 +43 +65 +87 +01 +00 +00 +00 +01 +00 +00 +00 +3e +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +48 +00 +00 +00 +00 +00 +00 +00 +2e +74 +65 +78 +74 +00 diff --git a/modules/objfmts/xdf/xdf-objfmt.c b/modules/objfmts/xdf/xdf-objfmt.c index 703de1a6..24b7a0a1 100644 --- a/modules/objfmts/xdf/xdf-objfmt.c +++ b/modules/objfmts/xdf/xdf-objfmt.c @@ -651,6 +651,48 @@ xdf_objfmt_destroy(yasm_objfmt *objfmt) yasm_xfree(objfmt); } +static xdf_section_data * +xdf_objfmt_init_new_section(yasm_objfmt_xdf *objfmt_xdf, yasm_section *sect, + const char *sectname, unsigned long line) +{ + xdf_section_data *data; + yasm_symrec *sym; + + data = yasm_xmalloc(sizeof(xdf_section_data)); + data->scnum = objfmt_xdf->parse_scnum++; + data->flags = 0; + data->addr = NULL; + data->vaddr = NULL; + data->scnptr = 0; + data->size = 0; + data->relptr = 0; + data->nreloc = 0; + STAILQ_INIT(&data->relocs); + yasm_section_add_data(sect, &xdf_section_data_cb, data); + + sym = yasm_symtab_define_label(objfmt_xdf->symtab, sectname, + yasm_section_bcs_first(sect), 1, line); + data->sym = sym; + return data; +} + +static yasm_section * +xdf_objfmt_add_default_section(yasm_objfmt *objfmt) +{ + yasm_objfmt_xdf *objfmt_xdf = (yasm_objfmt_xdf *)objfmt; + yasm_section *retval; + xdf_section_data *xsd; + int isnew; + + retval = yasm_object_get_general(objfmt_xdf->object, ".text", 0, 0, 1, 0, + &isnew, 0); + if (isnew) { + xsd = xdf_objfmt_init_new_section(objfmt_xdf, retval, ".text", 0); + yasm_section_set_default(retval, 1); + } + return retval; +} + static /*@observer@*/ /*@null@*/ yasm_section * xdf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, /*@unused@*/ /*@null@*/ @@ -668,6 +710,7 @@ xdf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, int flags_override = 0; char *sectname; int resonly = 0; + xdf_section_data *xsd; if (!vp || vp->param || !vp->val) return NULL; @@ -745,32 +788,25 @@ xdf_objfmt_section_switch(yasm_objfmt *objfmt, yasm_valparamhead *valparams, retval = yasm_object_get_general(objfmt_xdf->object, sectname, 0, align, 1, 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->flags = flags; - if (absaddr) - data->addr = yasm_intnum_copy(absaddr); - else - data->addr = NULL; - if (vaddr) - data->vaddr = yasm_intnum_copy(vaddr); - else - data->vaddr = 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); - data->sym = sym; + if (isnew) + xsd = xdf_objfmt_init_new_section(objfmt_xdf, retval, sectname, line); + else + xsd = yasm_section_get_data(retval, &xdf_section_data_cb); + + if (isnew || yasm_section_is_default(retval)) { + yasm_section_set_default(retval, 0); + xsd->flags = flags; + if (absaddr) { + if (xsd->addr) + yasm_intnum_destroy(xsd->addr); + xsd->addr = yasm_intnum_copy(absaddr); + } + if (vaddr) { + if (xsd->vaddr) + yasm_intnum_destroy(xsd->vaddr); + xsd->vaddr = yasm_intnum_copy(vaddr); + } + yasm_section_set_align(retval, align, line); } else if (flags_override) yasm__warning(YASM_WARN_GENERAL, line, N_("section flags ignored on section redeclaration")); @@ -883,13 +919,13 @@ yasm_objfmt_module yasm_xdf_LTX_objfmt = { "Extended Dynamic Object", "xdf", "xdf", - ".text", 32, xdf_objfmt_dbgfmt_keywords, "null", xdf_objfmt_create, xdf_objfmt_output, xdf_objfmt_destroy, + xdf_objfmt_add_default_section, xdf_objfmt_section_switch, xdf_objfmt_extern_declare, xdf_objfmt_global_declare,