Maybe some minor changes.
This commit is contained in:
297
util/led/write.c
Normal file
297
util/led/write.c
Normal file
@@ -0,0 +1,297 @@
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Header$";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* You can choose between two strategies:
|
||||
* - Open the output file several times, once for each logical part, and
|
||||
* write to it in multiple places.
|
||||
* - Open the output file once and seek back and forth to each logical
|
||||
* part. In this case #define OUTSEEK.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "out.h"
|
||||
#include "const.h"
|
||||
#include "assert.h"
|
||||
#include "memory.h"
|
||||
#include "orig.h"
|
||||
|
||||
extern long lseek();
|
||||
|
||||
#define WRITE 1 /* Argument to open(). */
|
||||
|
||||
/*
|
||||
* Parts of the output file.
|
||||
*/
|
||||
#define PARTEMIT 0
|
||||
#define PARTRELO 1
|
||||
#define PARTNAME 2
|
||||
#define PARTCHAR 3
|
||||
#ifdef SYMDBUG
|
||||
#define PARTDBUG 4
|
||||
#else SYMDBUG
|
||||
#define PARTDBUG PARTCHAR
|
||||
#endif SYMDBUG
|
||||
#define NPARTS (PARTDBUG + 1)
|
||||
|
||||
/*
|
||||
* Call OUTPART() with the part you want to write on as argument, before
|
||||
* you call OUTWRITE().
|
||||
*/
|
||||
static int outpart = NPARTS;
|
||||
|
||||
#ifdef OUTSEEK
|
||||
|
||||
static int outfile;
|
||||
static long outseek[NPARTS];
|
||||
|
||||
#define OUTPART(p) \
|
||||
{ if (outpart != (p)) {\
|
||||
outpart = (p);\
|
||||
lseek(outfile, outseek[(p)], 0);\
|
||||
}\
|
||||
}
|
||||
#define OUTSECT(i) \
|
||||
{ outpart = NPARTS;\
|
||||
outseek[PARTEMIT] =\
|
||||
outsect[(i)].os_foff + relorig[(i)].org_flen;\
|
||||
}
|
||||
#define OUTWRITE(b, n) \
|
||||
{ if (write(outfile, (b), (n)) != (n))\
|
||||
fatal("write error");\
|
||||
outseek[outpart] += (n);\
|
||||
}
|
||||
#define BEGINSEEK(p, o) \
|
||||
{ outseek[(p)] = (o);\
|
||||
}
|
||||
|
||||
#else OUTSEEK
|
||||
|
||||
static int outfile[NPARTS];
|
||||
|
||||
#define OUTPART(p) \
|
||||
{ outpart = (p);\
|
||||
}
|
||||
#define OUTSECT(i) \
|
||||
{ lseek( outfile[PARTEMIT],\
|
||||
outsect[(i)].os_foff + relorig[(i)].org_flen,\
|
||||
0\
|
||||
);\
|
||||
}
|
||||
#define OUTWRITE(b, n) \
|
||||
{ if (write(outfile[outpart], (b), (n)) != (n))\
|
||||
fatal("write error");\
|
||||
}
|
||||
#define BEGINSEEK(p, o) \
|
||||
{ lseek(outfile[(p)], (o), 0);\
|
||||
}
|
||||
|
||||
#endif OUTSEEK
|
||||
|
||||
extern struct outhead outhead;
|
||||
extern struct outsect outsect[];
|
||||
extern int flagword;
|
||||
extern struct orig relorig[];
|
||||
extern bool bytes_reversed, words_reversed;
|
||||
extern bool incore;
|
||||
|
||||
|
||||
static long offchar;
|
||||
|
||||
/*
|
||||
* Open the output file according to the chosen strategy.
|
||||
* Write away the header and section table: they will not change anymore.
|
||||
*/
|
||||
begin_write()
|
||||
{
|
||||
register long off;
|
||||
|
||||
openoutput();
|
||||
BEGINSEEK(PARTEMIT, (long)0);
|
||||
wrt_head(&outhead);
|
||||
wrt_sect(outsect, outhead.oh_nsect);
|
||||
|
||||
off = SZ_HEAD + (long)outhead.oh_nsect * SZ_SECT + outhead.oh_nemit;
|
||||
|
||||
if (flagword & RFLAG) {
|
||||
/* A relocation table will be produced. */
|
||||
BEGINSEEK(PARTRELO, off);
|
||||
off += (long)outhead.oh_nrelo * SZ_RELO;
|
||||
}
|
||||
|
||||
if (flagword & SFLAG)
|
||||
return;
|
||||
|
||||
/* A name table will be produced. */
|
||||
BEGINSEEK(PARTNAME, off);
|
||||
off += (long)outhead.oh_nname * SZ_NAME;
|
||||
BEGINSEEK(PARTCHAR, off);
|
||||
offchar = off; /* See wrt_name(). */
|
||||
#ifdef SYMDBUG
|
||||
off += outhead.oh_nchar;
|
||||
BEGINSEEK(PARTDBUG, off);
|
||||
#endif SYMDBUG
|
||||
}
|
||||
|
||||
static
|
||||
openoutput()
|
||||
{
|
||||
#ifndef OUTSEEK
|
||||
register int *fdp;
|
||||
#endif OUTSEEK
|
||||
extern char *outputname;
|
||||
|
||||
close(creat(outputname, 0666));
|
||||
#ifdef OUTSEEK
|
||||
if ((outfile = open(outputname, WRITE)) < 0)
|
||||
fatal("can't write %s", outputname);
|
||||
#else OUTSEEK
|
||||
for (fdp = &outfile[PARTEMIT]; fdp < &outfile[NPARTS]; fdp++)
|
||||
if ((*fdp = open(outputname, WRITE)) < 0)
|
||||
fatal("can't write %s", outputname);
|
||||
#endif OUTSEEK
|
||||
}
|
||||
|
||||
static struct outname *
|
||||
sectname(sectindex)
|
||||
int sectindex;
|
||||
{
|
||||
static struct outname namebuf;
|
||||
|
||||
namebuf.on_foff = (long)0; /* No string name. */
|
||||
namebuf.on_type = (S_MIN + sectindex) | S_SCT;
|
||||
namebuf.on_desc = 0;
|
||||
namebuf.on_valu = outsect[sectindex].os_base;
|
||||
|
||||
return &namebuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write out the symbol table and the section names.
|
||||
*/
|
||||
end_write()
|
||||
{
|
||||
register ushort cnt;
|
||||
register struct outname *name;
|
||||
register int sectindex;
|
||||
extern ushort NGlobals;
|
||||
|
||||
assert(!incore);
|
||||
assert(!(flagword & SFLAG));
|
||||
cnt = NGlobals;
|
||||
name = (struct outname *)address(ALLOGLOB, (ind_t)0);
|
||||
while (cnt--) {
|
||||
if (name->on_foff != (long)0) {
|
||||
name->on_mptr = address(ALLOGCHR, (ind_t)name->on_foff);
|
||||
} else {
|
||||
name->on_mptr = (char *)0;
|
||||
}
|
||||
wrt_name(name);
|
||||
name++;
|
||||
}
|
||||
|
||||
for (sectindex = 0; sectindex < outhead.oh_nsect; sectindex++)
|
||||
wrt_name(sectname(sectindex));
|
||||
}
|
||||
|
||||
static
|
||||
wrt_head(head)
|
||||
register struct outhead *head;
|
||||
{
|
||||
assert(!incore);
|
||||
OUTPART(PARTEMIT);
|
||||
if (bytes_reversed || words_reversed)
|
||||
swap((char *)head, SF_HEAD);
|
||||
OUTWRITE((char *)head, SZ_HEAD);
|
||||
/*
|
||||
* Swap back because we will need it again.
|
||||
*/
|
||||
if (bytes_reversed || words_reversed)
|
||||
swap((char *)head, SF_HEAD);
|
||||
}
|
||||
|
||||
static
|
||||
wrt_sect(sect, cnt)
|
||||
register struct outsect *sect;
|
||||
register ushort cnt;
|
||||
{
|
||||
assert(!incore);
|
||||
OUTPART(PARTEMIT);
|
||||
while (cnt--) {
|
||||
if (bytes_reversed || words_reversed)
|
||||
swap((char *)sect, SF_SECT);
|
||||
OUTWRITE((char *)sect, SZ_SECT);
|
||||
/*
|
||||
* Swap back because we will need it again.
|
||||
*/
|
||||
if (bytes_reversed || words_reversed)
|
||||
swap((char *)sect, SF_SECT);
|
||||
sect++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't have to worry about byte order here.
|
||||
*/
|
||||
wrt_emit(emit, sectindex, cnt)
|
||||
register char *emit;
|
||||
int sectindex;
|
||||
register long cnt;
|
||||
{
|
||||
register int n;
|
||||
|
||||
assert(!incore);
|
||||
OUTPART(PARTEMIT);
|
||||
OUTSECT(sectindex);
|
||||
while (cnt) {
|
||||
n = cnt >= BUFSIZ ? BUFSIZ : cnt;
|
||||
OUTWRITE(emit, n);
|
||||
emit += n;
|
||||
cnt -= n;
|
||||
}
|
||||
}
|
||||
|
||||
wrt_relo(relo)
|
||||
register struct outrelo *relo;
|
||||
{
|
||||
assert(!incore);
|
||||
assert(flagword & RFLAG);
|
||||
OUTPART(PARTRELO);
|
||||
if (bytes_reversed || words_reversed)
|
||||
swap((char *)relo, SF_RELO);
|
||||
OUTWRITE((char *)relo, SZ_RELO);
|
||||
}
|
||||
|
||||
wrt_name(name)
|
||||
register struct outname *name;
|
||||
{
|
||||
assert(!incore);
|
||||
assert(!(flagword & SFLAG));
|
||||
if (name->on_mptr != (char *)0) {
|
||||
register int len = strlen(name->on_mptr) + 1;
|
||||
|
||||
OUTPART(PARTCHAR);
|
||||
OUTWRITE(name->on_mptr, len);
|
||||
name->on_foff = offchar;
|
||||
offchar += len;
|
||||
} else {
|
||||
name->on_foff = (long)0;
|
||||
}
|
||||
OUTPART(PARTNAME);
|
||||
if (bytes_reversed || words_reversed)
|
||||
swap((char *)name, SF_NAME);
|
||||
OUTWRITE((char *)name, SZ_NAME);
|
||||
}
|
||||
#ifdef SYMDBUG
|
||||
|
||||
wrt_dbug(buf, size)
|
||||
char *buf;
|
||||
int size;
|
||||
{
|
||||
assert(!incore);
|
||||
assert(!(flagword & SFLAG));
|
||||
OUTPART(PARTDBUG);
|
||||
OUTWRITE((char *)buf, size);
|
||||
}
|
||||
#endif SYMDBUG
|
||||
Reference in New Issue
Block a user