📄 outobj.c
字号:
/*
* Initializer for a PUBDEF record.
* parm[0] = group index
* parm[1] = segment index
* parm[2] = frame (only used when both indexes are zero)
*/
static void ori_pubdef(ObjRecord * orp)
{
obj_index(orp, orp->parm[0]);
obj_index(orp, orp->parm[1]);
if (!(orp->parm[0] | orp->parm[1]))
obj_word(orp, orp->parm[2]);
}
/*
* Initializer for a LINNUM record.
* parm[0] = group index
* parm[1] = segment index
*/
static void ori_linnum(ObjRecord * orp)
{
obj_index(orp, orp->parm[0]);
obj_index(orp, orp->parm[1]);
}
/*
* Initializer for a local vars record.
*/
static void ori_local(ObjRecord * orp)
{
obj_byte(orp, 0x40);
obj_byte(orp, dSYM);
}
/*
* Null initializer for records that continue without any header info
*/
static void ori_null(ObjRecord * orp)
{
(void)orp; /* Do nothing */
}
/*
* This concludes the low level section of outobj.c
*/
static char obj_infile[FILENAME_MAX];
static efunc error;
static evalfunc evaluate;
static ldfunc deflabel;
static FILE *ofp;
static long first_seg;
static int any_segs;
static int passtwo;
static int arrindex;
#define GROUP_MAX 256 /* we won't _realistically_ have more
* than this many segs in a group */
#define EXT_BLKSIZ 256 /* block size for externals list */
struct Segment; /* need to know these structs exist */
struct Group;
struct LineNumber {
struct LineNumber *next;
struct Segment *segment;
long offset;
long lineno;
};
static struct FileName {
struct FileName *next;
char *name;
struct LineNumber *lnhead, **lntail;
int index;
} *fnhead, **fntail;
static struct Array {
struct Array *next;
unsigned size;
int basetype;
} *arrhead, **arrtail;
#define ARRAYBOT 31 /* magic number for first array index */
static struct Public {
struct Public *next;
char *name;
long offset;
long segment; /* only if it's far-absolute */
int type; /* only for local debug syms */
} *fpubhead, **fpubtail, *last_defined;
static struct External {
struct External *next;
char *name;
long commonsize;
long commonelem; /* element size if FAR, else zero */
int index; /* OBJ-file external index */
enum {
DEFWRT_NONE, /* no unusual default-WRT */
DEFWRT_STRING, /* a string we don't yet understand */
DEFWRT_SEGMENT, /* a segment */
DEFWRT_GROUP /* a group */
} defwrt_type;
union {
char *string;
struct Segment *seg;
struct Group *grp;
} defwrt_ptr;
struct External *next_dws; /* next with DEFWRT_STRING */
} *exthead, **exttail, *dws;
static int externals;
static struct ExtBack {
struct ExtBack *next;
struct External *exts[EXT_BLKSIZ];
} *ebhead, **ebtail;
static struct Segment {
struct Segment *next;
long index; /* the NASM segment id */
long obj_index; /* the OBJ-file segment index */
struct Group *grp; /* the group it belongs to */
unsigned long currentpos;
long align; /* can be SEG_ABS + absolute addr */
enum {
CMB_PRIVATE = 0,
CMB_PUBLIC = 2,
CMB_STACK = 5,
CMB_COMMON = 6
} combine;
long use32; /* is this segment 32-bit? */
struct Public *pubhead, **pubtail, *lochead, **loctail;
char *name;
char *segclass, *overlay; /* `class' is a C++ keyword :-) */
ObjRecord *orp;
} *seghead, **segtail, *obj_seg_needs_update;
static struct Group {
struct Group *next;
char *name;
long index; /* NASM segment id */
long obj_index; /* OBJ-file group index */
long nentries; /* number of elements... */
long nindices; /* ...and number of index elts... */
union {
long index;
char *name;
} segs[GROUP_MAX]; /* ...in this */
} *grphead, **grptail, *obj_grp_needs_update;
static struct ImpDef {
struct ImpDef *next;
char *extname;
char *libname;
unsigned int impindex;
char *impname;
} *imphead, **imptail;
static struct ExpDef {
struct ExpDef *next;
char *intname;
char *extname;
unsigned int ordinal;
int flags;
} *exphead, **exptail;
#define EXPDEF_FLAG_ORDINAL 0x80
#define EXPDEF_FLAG_RESIDENT 0x40
#define EXPDEF_FLAG_NODATA 0x20
#define EXPDEF_MASK_PARMCNT 0x1F
static long obj_entry_seg, obj_entry_ofs;
struct ofmt of_obj;
/* The current segment */
static struct Segment *current_seg;
static long obj_segment(char *, int, int *);
static void obj_write_file(int debuginfo);
static int obj_directive(char *, char *, int);
static void obj_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval)
{
ofp = fp;
error = errfunc;
evaluate = eval;
deflabel = ldef;
first_seg = seg_alloc();
any_segs = FALSE;
fpubhead = NULL;
fpubtail = &fpubhead;
exthead = NULL;
exttail = &exthead;
imphead = NULL;
imptail = &imphead;
exphead = NULL;
exptail = &exphead;
dws = NULL;
externals = 0;
ebhead = NULL;
ebtail = &ebhead;
seghead = obj_seg_needs_update = NULL;
segtail = &seghead;
grphead = obj_grp_needs_update = NULL;
grptail = &grphead;
obj_entry_seg = NO_SEG;
obj_uppercase = FALSE;
obj_use32 = FALSE;
passtwo = 0;
current_seg = NULL;
of_obj.current_dfmt->init(&of_obj, NULL, fp, errfunc);
}
static int obj_set_info(enum geninfo type, char **val)
{
(void)type;
(void)val;
return 0;
}
static void obj_cleanup(int debuginfo)
{
obj_write_file(debuginfo);
of_obj.current_dfmt->cleanup();
fclose(ofp);
while (seghead) {
struct Segment *segtmp = seghead;
seghead = seghead->next;
while (segtmp->pubhead) {
struct Public *pubtmp = segtmp->pubhead;
segtmp->pubhead = pubtmp->next;
nasm_free(pubtmp->name);
nasm_free(pubtmp);
}
nasm_free(segtmp->segclass);
nasm_free(segtmp->overlay);
nasm_free(segtmp);
}
while (fpubhead) {
struct Public *pubtmp = fpubhead;
fpubhead = fpubhead->next;
nasm_free(pubtmp->name);
nasm_free(pubtmp);
}
while (exthead) {
struct External *exttmp = exthead;
exthead = exthead->next;
nasm_free(exttmp);
}
while (imphead) {
struct ImpDef *imptmp = imphead;
imphead = imphead->next;
nasm_free(imptmp->extname);
nasm_free(imptmp->libname);
nasm_free(imptmp->impname); /* nasm_free won't mind if it's NULL */
nasm_free(imptmp);
}
while (exphead) {
struct ExpDef *exptmp = exphead;
exphead = exphead->next;
nasm_free(exptmp->extname);
nasm_free(exptmp->intname);
nasm_free(exptmp);
}
while (ebhead) {
struct ExtBack *ebtmp = ebhead;
ebhead = ebhead->next;
nasm_free(ebtmp);
}
while (grphead) {
struct Group *grptmp = grphead;
grphead = grphead->next;
nasm_free(grptmp);
}
}
static void obj_ext_set_defwrt(struct External *ext, char *id)
{
struct Segment *seg;
struct Group *grp;
for (seg = seghead; seg; seg = seg->next)
if (!strcmp(seg->name, id)) {
ext->defwrt_type = DEFWRT_SEGMENT;
ext->defwrt_ptr.seg = seg;
nasm_free(id);
return;
}
for (grp = grphead; grp; grp = grp->next)
if (!strcmp(grp->name, id)) {
ext->defwrt_type = DEFWRT_GROUP;
ext->defwrt_ptr.grp = grp;
nasm_free(id);
return;
}
ext->defwrt_type = DEFWRT_STRING;
ext->defwrt_ptr.string = id;
ext->next_dws = dws;
dws = ext;
}
static void obj_deflabel(char *name, long segment,
long offset, int is_global, char *special)
{
/*
* We have three cases:
*
* (i) `segment' is a segment-base. If so, set the name field
* for the segment or group structure it refers to, and then
* return.
*
* (ii) `segment' is one of our segments, or a SEG_ABS segment.
* Save the label position for later output of a PUBDEF record.
* (Or a MODPUB, if we work out how.)
*
* (iii) `segment' is not one of our segments. Save the label
* position for later output of an EXTDEF, and also store a
* back-reference so that we can map later references to this
* segment number to the external index.
*/
struct External *ext;
struct ExtBack *eb;
struct Segment *seg;
int i;
int used_special = FALSE; /* have we used the special text? */
#if defined(DEBUG) && DEBUG>2
fprintf(stderr,
" obj_deflabel: %s, seg=%ld, off=%ld, is_global=%d, %s\n",
name, segment, offset, is_global, special);
#endif
/*
* If it's a special-retry from pass two, discard it.
*/
if (is_global == 3)
return;
/*
* First check for the double-period, signifying something
* unusual.
*/
if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
if (!strcmp(name, "..start")) {
obj_entry_seg = segment;
obj_entry_ofs = offset;
return;
}
error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
}
/*
* Case (i):
*/
if (obj_seg_needs_update) {
obj_seg_needs_update->name = name;
return;
} else if (obj_grp_needs_update) {
obj_grp_needs_update->name = name;
return;
}
if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
return;
if (segment >= SEG_ABS || segment == NO_SEG) {
/*
* SEG_ABS subcase of (ii).
*/
if (is_global) {
struct Public *pub;
pub = *fpubtail = nasm_malloc(sizeof(*pub));
fpubtail = &pub->next;
pub->next = NULL;
pub->name = nasm_strdup(name);
pub->offset = offset;
pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS);
}
if (special)
error(ERR_NONFATAL, "OBJ supports no special symbol features"
" for this symbol type");
return;
}
/*
* If `any_segs' is still FALSE, we might need to define a
* default segment, if they're trying to declare a label in
* `first_seg'.
*/
if (!any_segs && segment == first_seg) {
int tempint; /* ignored */
if (segment != obj_segment("__NASMDEFSEG", 2, &tempint))
error(ERR_PANIC, "strange segment conditions in OBJ driver");
}
for (seg = seghead; seg && is_global; seg = seg->next)
if (seg->index == segment) {
struct Public *loc = nasm_malloc(sizeof(*loc));
/*
* Case (ii). Maybe MODPUB someday?
*/
*seg->pubtail = loc;
seg->pubtail = &loc->next;
loc->next = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -