outobj: add obj2 driver

Obj2 is an obj variation for OS/2.

Obj2 has the following differences from obj.

1. Default attributes for a segment are ALIGN=16 and USE32.
2. Add a segment to FLAT group implicitly if 32-bit segment.
3. Recognize Unix sections .text, .rodata, .data and .bss as TEXT32,
   CONST32, DATA32 and BSS32 respectively for compatibility with other
   Unix platforms.
4. Set default classes implicitly for known segments such as TEXT32,
   CONST32, DATA32, BSS32 and so on.

Signed-off-by: KO Myung-Hun <komh78@gmail.com>
This commit is contained in:
KO Myung-Hun 2024-11-22 20:51:47 +09:00 committed by H. Peter Anvin
parent a65be7d59b
commit c7f426f5e5
3 changed files with 127 additions and 8 deletions

View file

@ -15,7 +15,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.
@ -56,7 +56,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... */
@ -73,6 +73,9 @@
#ifndef OF_OBJ
#define OF_OBJ
#endif
#ifndef OF_OBJ2
#define OF_OBJ2
#endif
#ifndef OF_ELF32
#define OF_ELF32
#endif
@ -119,6 +122,9 @@
#ifndef OF_OBJ
#define OF_OBJ
#endif
#ifndef OF_OBJ2
#define OF_OBJ2
#endif
#ifndef OF_BIN
#define OF_BIN
#endif
@ -179,6 +185,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
@ -234,6 +243,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;
@ -278,6 +288,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

View file

@ -22,7 +22,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
@ -602,6 +602,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;
@ -613,10 +618,42 @@ static struct Segment *current_seg;
/* Name for segment to use if no segment directive is defined */
static char DEFAULT_SEG[] = "__NASMDEFSEG";
/* 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));
@ -643,6 +680,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)
@ -1394,9 +1446,16 @@ static int32_t obj_segment(char *name, int *bits)
any_segs = true;
seg->name = nasm_strdup(name);
seg->currentpos = 0;
seg->align = seg->origalign = 1; /* default */
seg->use32 = false; /* default */
seg->combine = CMB_PUBLIC; /* default */
if (ofmt == &of_obj) {
seg->align = 1; /* default for obj */
seg->origalign = 1; /* default for obj */
seg->use32 = false; /* default for obj */
} else {
seg->align = 16; /* default for obj2 */
seg->origalign = 16; /* default for obj2 */
seg->use32 = true; /* default for obj2 */
}
seg->combine = CMB_PUBLIC; /* default */
seg->segclass = seg->overlay = NULL;
seg->pubhead = NULL;
seg->pubtail = &seg->pubhead;
@ -1489,6 +1548,31 @@ static int32_t obj_segment(char *name, int *bits)
if (!seg->use32 && seg->grp && !strcmp(seg->grp->name, "FLAT"))
nasm_panic("wrong combination of USE16(16-bit segment) and FLAT");
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;
@ -2685,4 +2769,26 @@ 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,
obj_out,
obj_deflabel,
obj_segment,
NULL,
obj_sectalign,
obj_segbase,
obj_directive,
obj_cleanup,
obj_pragma_list
};
#endif /* OF_OBJ || OF_OBJ2 */

View file

@ -1,7 +1,7 @@
;; SPDX-License-Identifier: BSD-2-Clause
;; Copyright 1996-2009 The NASM Authors - All Rights Reserved
OUT: obj
OUT: obj obj2
%define __?SECT?__ [section .text]
%imacro group 1+.nolist
[group %1]