diff --git a/output/outform.h b/output/outform.h index 3b846749..c3a8e487 100644 --- a/output/outform.h +++ b/output/outform.h @@ -45,7 +45,7 @@ * OF_ONLY -- only include specified object formats * OF_name -- ensure that output format 'name' is included * OF_NO_name -- remove output format 'name' - * OF_DOS -- ensure that 'obj', 'bin', 'win32' & 'win64' are included. + * OF_DOS -- ensure that 'obj', 'obj2', 'bin', 'win32' & 'win64' are included. * OF_UNIX -- ensure that 'aout', 'aoutb', 'coff', 'elf32' & 'elf64' are in. * OF_OTHERS -- ensure that 'bin', 'as86', 'rdf' 'macho32' & 'macho64' are in. * OF_ALL -- ensure that all formats are included. @@ -86,7 +86,7 @@ /* ====configurable info begins here==== */ /* formats configurable: - * bin,obj,elf32,elf64,aout,aoutb,coff,win32,as86,rdf2,macho32,macho64 */ + * bin,obj,obj2,elf32,elf64,aout,aoutb,coff,win32,as86,rdf2,macho32,macho64 */ /* process options... */ @@ -103,6 +103,9 @@ #ifndef OF_OBJ #define OF_OBJ #endif +#ifndef OF_OBJ2 +#define OF_OBJ2 +#endif #ifndef OF_ELF32 #define OF_ELF32 #endif @@ -149,6 +152,9 @@ #ifndef OF_OBJ #define OF_OBJ #endif +#ifndef OF_OBJ2 +#define OF_OBJ2 +#endif #ifndef OF_BIN #define OF_BIN #endif @@ -209,6 +215,9 @@ #ifdef OF_NO_OBJ #undef OF_OBJ #endif +#ifdef OF_NO_OBJ2 +#undef OF_OBJ2 +#endif #ifdef OF_NO_ELF32 #undef OF_ELF32 #endif @@ -264,6 +273,7 @@ extern const struct ofmt of_elfx32; extern const struct ofmt of_elf64; extern const struct ofmt of_as86; extern const struct ofmt of_obj; +extern const struct ofmt of_obj2; extern const struct ofmt of_win32; extern const struct ofmt of_win64; extern const struct ofmt of_ieee; @@ -308,6 +318,9 @@ static const struct ofmt * const drivers[] = { #ifdef OF_OBJ &of_obj, #endif +#ifdef OF_OBJ2 + &of_obj2, +#endif #ifdef OF_WIN32 &of_win32, #endif diff --git a/output/outobj.c b/output/outobj.c index 281839d0..c29e7e9f 100644 --- a/output/outobj.c +++ b/output/outobj.c @@ -51,7 +51,7 @@ #include "outform.h" #include "outlib.h" -#ifdef OF_OBJ +#if defined(OF_OBJ) || defined(OF_OBJ2) /* * outobj.c is divided into two sections. The first section is low level @@ -630,6 +630,11 @@ static struct ExpDef { #define EXPDEF_FLAG_NODATA 0x20 #define EXPDEF_MASK_PARMCNT 0x1F +struct SegmentToClass { + const char *segment; /* segment */ + const char *segclass; /* class */ +}; + static int32_t obj_entry_seg, obj_entry_ofs; const struct ofmt of_obj; @@ -638,10 +643,42 @@ static const struct dfmt borland_debug_form; /* The current segment */ static struct Segment *current_seg; +/* Conversion table from known segments to default classes */ +static const struct SegmentToClass conv_table[] = { + /* known segments, default class */ + { "CODE", "CODE" }, + { "TEXT", "CODE" }, + { "CONST", "CONST" }, + { "DATA", "DATA" }, + { "BSS", "BSS" }, + { "STACK", "STACK" }, + { "CODE32", "CODE" }, + { "TEXT32", "CODE" }, + { "CONST32", "CONST" }, + { "DATA32", "DATA" }, + { "BSS32", "BSS" }, + { "STACK32", "STACK" }, + { NULL, NULL }, +}; + static int32_t obj_segment(char *, int *); static void obj_write_file(void); static enum directive_result obj_directive(enum directive, char *); +static const char *get_default_class(const char *segment) +{ + const struct SegmentToClass *conv; + + if (segment && segment[0]) { + for (conv = conv_table; conv->segment; conv++) { + if (!strcmp(segment, conv->segment)) + return conv->segclass; + } + } + + return NULL; +} + static void obj_init(void) { strlcpy(obj_infile, inname, sizeof(obj_infile)); @@ -668,6 +705,21 @@ static void obj_init(void) obj_use32 = false; passtwo = 0; current_seg = NULL; + + /* + * Convert known Unix sections to OMF segments via macros. + */ + if (ofmt == &of_obj2) { + char section_text[] = ".text=TEXT32"; + char section_rodata[] = ".rodata=CONST32"; + char section_data[] = ".data=DATA32"; + char section_bss[] = ".bss=BSS32"; + + pp_pre_define(section_text); + pp_pre_define(section_rodata); + pp_pre_define(section_data); + pp_pre_define(section_bss); + } } static void obj_cleanup(void) @@ -1403,8 +1455,13 @@ static int32_t obj_segment(char *name, int *bits) any_segs = true; seg->name = nasm_strdup(name); seg->currentpos = 0; - seg->align = 1; /* default */ - seg->use32 = false; /* default */ + if (ofmt == &of_obj) { + seg->align = 1; /* default for obj */ + seg->use32 = false; /* default for obj */ + } else { + seg->align = 16; /* default for obj2 */ + seg->use32 = true; /* default for obj2 */ + } seg->combine = CMB_PUBLIC; /* default */ seg->segclass = seg->overlay = NULL; seg->pubhead = NULL; @@ -1517,6 +1574,31 @@ static int32_t obj_segment(char *name, int *bits) } } + if (ofmt == &of_obj2) { + if (seg->use32 && !seg->grp) { + struct Group *grp; + for (grp = grphead; grp; grp = grp->next) + if (!strcmp(grp->name, "FLAT")) + break; + if (!grp) { + obj_directive(D_GROUP, "FLAT"); + for (grp = grphead; grp; grp = grp->next) + if (!strcmp(grp->name, "FLAT")) + break; + if (!grp) + nasm_panic("failure to define FLAT?!"); + } + seg->grp = grp; + } + + if (!seg->segclass) { + const char *segclass = get_default_class(seg->name); + + if (segclass) + seg->segclass = nasm_strdup(segclass); + } + } + /* We need to know whenever we have at least one 32-bit segment */ obj_use32 |= seg->use32; @@ -2698,4 +2780,27 @@ const struct ofmt of_obj = { obj_cleanup, obj_pragma_list }; -#endif /* OF_OBJ */ + +const struct ofmt of_obj2 = { + "Intel/Microsoft OMF (i386) (OS/2)", + "obj2", + ".obj", + 0, + 32, + borland_debug_arr, + &borland_debug_form, + obj_stdmac, + obj_init, + null_reset, + nasm_do_legacy_output, + obj_out, + obj_deflabel, + obj_segment, + NULL, + obj_sectalign, + obj_segbase, + obj_directive, + obj_cleanup, + obj_pragma_list +}; +#endif /* OF_OBJ || OF_OBJ2 */ diff --git a/output/outobj.mac b/output/outobj.mac index 09158f23..75e758c6 100644 --- a/output/outobj.mac +++ b/output/outobj.mac @@ -31,7 +31,7 @@ ;; ;; -------------------------------------------------------------------------- -OUT: obj +OUT: obj obj2 %define __?SECT?__ [section .text] %imacro group 1+.nolist [group %1]