mirror of
https://github.com/netwide-assembler/nasm.git
synced 2024-11-27 08:10:07 +08:00
206 lines
6.5 KiB
C
206 lines
6.5 KiB
C
/* rdoff.h RDOFF Object File manipulation routines header file
|
|
*
|
|
* The Netwide Assembler is copyright (C) 1996 Simon Tatham and
|
|
* Julian Hall. All rights reserved. The software is
|
|
* redistributable under the licence given in the file "Licence"
|
|
* distributed in the NASM archive.
|
|
*
|
|
* Permission to use this file in your own projects is granted, as long
|
|
* as acknowledgement is given in an appropriate manner to its authors,
|
|
* with instructions of how to obtain a copy via ftp.
|
|
*/
|
|
|
|
#ifndef _RDOFF_H
|
|
#define _RDOFF_H "RDOFF2 support routines v0.3"
|
|
|
|
/* Some systems don't define this automatically */
|
|
extern char *strdup(const char *);
|
|
|
|
typedef unsigned short int16;
|
|
typedef unsigned char byte;
|
|
|
|
#define RDF_MAXSEGS 64
|
|
|
|
/* the records that can be found in the RDOFF header */
|
|
|
|
struct RelocRec {
|
|
byte type; /* must be 1 */
|
|
byte reclen; /* content length */
|
|
byte segment; /* only 0 for code, or 1 for data supported,
|
|
but add 64 for relative refs (ie do not require
|
|
reloc @ loadtime, only linkage) */
|
|
long offset; /* from start of segment in which reference is loc'd */
|
|
byte length; /* 1 2 or 4 bytes */
|
|
int16 refseg; /* segment to which reference refers to */
|
|
};
|
|
|
|
struct ImportRec {
|
|
byte type; /* must be 2 */
|
|
byte reclen; /* content length */
|
|
int16 segment; /* segment number allocated to the label for reloc
|
|
records - label is assumed to be at offset zero
|
|
in this segment, so linker must fix up with offset
|
|
of segment and of offset within segment */
|
|
char label[33]; /* zero terminated... should be written to file until
|
|
the zero, but not after it - max len = 32 chars */
|
|
};
|
|
|
|
struct ExportRec {
|
|
byte type; /* must be 3 */
|
|
byte reclen; /* content length */
|
|
byte flags; /* SYM_* flags (see below) */
|
|
byte segment; /* segment referred to (0/1/2) */
|
|
long offset; /* offset within segment */
|
|
char label[33]; /* zero terminated as above. max len = 32 chars */
|
|
};
|
|
|
|
struct DLLRec {
|
|
byte type; /* must be 4 */
|
|
byte reclen; /* content length */
|
|
char libname[128]; /* name of library to link with at load time */
|
|
};
|
|
|
|
struct BSSRec {
|
|
byte type; /* must be 5 */
|
|
byte reclen; /* content length */
|
|
long amount; /* number of bytes BSS to reserve */
|
|
};
|
|
|
|
struct ModRec {
|
|
byte type; /* must be 8 */
|
|
byte reclen; /* content length */
|
|
char modname[128]; /* module name */
|
|
};
|
|
|
|
/* Flags for ExportRec */
|
|
#define SYM_DATA 0x01
|
|
#define SYM_FUNCTION 0x02
|
|
#define SYM_GLOBAL 0x04
|
|
|
|
#ifdef _MULTBOOT_H
|
|
|
|
#define RDFLDRMOVER_SIZE 22
|
|
|
|
struct MultiBootHdrRec {
|
|
byte type; /* must be 9 */
|
|
byte reclen; /* content length */
|
|
#ifdef __GNUC__
|
|
struct tMultiBootHeader mb __attribute__ ((packed)); /* MultiBoot header */
|
|
#else
|
|
struct tMultiBootHeader mb;
|
|
#endif
|
|
byte mover[RDFLDRMOVER_SIZE]; /* Mover of RDF loader */
|
|
};
|
|
#endif
|
|
|
|
/* GenericRec - contains the type and length field, plus a 128 byte
|
|
char array 'data', which will probably never be used! */
|
|
|
|
struct GenericRec {
|
|
byte type;
|
|
byte reclen;
|
|
char data[128];
|
|
};
|
|
|
|
typedef union RDFHeaderRec {
|
|
char type; /* invariant throughout all below */
|
|
struct GenericRec g;
|
|
struct RelocRec r; /* type == 1 / 6 */
|
|
struct ImportRec i; /* type == 2 / 7 */
|
|
struct ExportRec e; /* type == 3 */
|
|
struct DLLRec d; /* type == 4 */
|
|
struct BSSRec b; /* type == 5 */
|
|
struct ModRec m; /* type == 8 */
|
|
#ifdef _MULTBOOT_H
|
|
struct MultiBootHdrRec mbh; /* type == 9 */
|
|
#endif
|
|
} rdfheaderrec;
|
|
|
|
struct SegmentHeaderRec {
|
|
/* information from file */
|
|
int16 type;
|
|
int16 number;
|
|
int16 reserved;
|
|
long length;
|
|
|
|
/* information built up here */
|
|
long offset;
|
|
byte *data; /* pointer to segment data if it exists in memory */
|
|
};
|
|
|
|
typedef struct RDFFileInfo {
|
|
FILE *fp; /* file descriptor; must be open to use this struct */
|
|
int rdoff_ver; /* should be 1; any higher => not guaranteed to work */
|
|
long header_len;
|
|
long header_ofs;
|
|
|
|
byte *header_loc; /* keep location of header */
|
|
long header_fp; /* current location within header for reading */
|
|
|
|
struct SegmentHeaderRec seg[RDF_MAXSEGS];
|
|
int nsegs;
|
|
|
|
long eof_offset; /* offset of the first byte beyond the end of this
|
|
module */
|
|
|
|
char *name; /* name of module in libraries */
|
|
int *refcount; /* pointer to reference count on file, or NULL */
|
|
} rdffile;
|
|
|
|
#define BUF_BLOCK_LEN 4088 /* selected to match page size (4096)
|
|
* on 80x86 machines for efficiency */
|
|
typedef struct memorybuffer {
|
|
int length;
|
|
byte buffer[BUF_BLOCK_LEN];
|
|
struct memorybuffer *next;
|
|
} memorybuffer;
|
|
|
|
typedef struct {
|
|
memorybuffer * buf; /* buffer containing header records */
|
|
int nsegments; /* number of segments to be written */
|
|
long seglength; /* total length of all the segments */
|
|
} rdf_headerbuf;
|
|
|
|
/* segments used by RDOFF, understood by rdoffloadseg */
|
|
#define RDOFF_CODE 0
|
|
#define RDOFF_DATA 1
|
|
#define RDOFF_HEADER -1
|
|
/* mask for 'segment' in relocation records to find if relative relocation */
|
|
#define RDOFF_RELATIVEMASK 64
|
|
/* mask to find actual segment value in relocation records */
|
|
#define RDOFF_SEGMENTMASK 63
|
|
|
|
extern int rdf_errno;
|
|
|
|
/* utility functions */
|
|
int16 translateshort(int16 in);
|
|
long translatelong(long in);
|
|
|
|
/* RDOFF file manipulation functions */
|
|
int rdfopen(rdffile *f,const char *name);
|
|
int rdfopenhere(rdffile *f, FILE *fp, int *refcount, const char *name);
|
|
int rdfclose(rdffile *f);
|
|
int rdffindsegment(rdffile * f, int segno);
|
|
int rdfloadseg(rdffile *f,int segment,void *buffer);
|
|
rdfheaderrec *rdfgetheaderrec(rdffile *f); /* returns static storage */
|
|
void rdfheaderrewind(rdffile *f); /* back to start of header */
|
|
void rdfperror(const char *app,const char *name);
|
|
|
|
/* functions to write a new RDOFF header to a file -
|
|
use rdfnewheader to allocate a header, rdfaddheader to add records to it,
|
|
rdfaddsegment to notify the header routines that a segment exists, and
|
|
to tell it how long the segment will be.
|
|
rdfwriteheader to write the file id, object length, and header
|
|
to a file, and then rdfdoneheader to dispose of the header */
|
|
|
|
rdf_headerbuf *rdfnewheader(void);
|
|
int rdfaddheader(rdf_headerbuf *h,rdfheaderrec *r);
|
|
int rdfaddsegment(rdf_headerbuf *h, long seglength);
|
|
int rdfwriteheader(FILE *fp,rdf_headerbuf *h);
|
|
void rdfdoneheader(rdf_headerbuf *h);
|
|
|
|
/* This is needed by linker to write multiboot header record */
|
|
int membuflength(memorybuffer *b);
|
|
|
|
#endif /* _RDOFF_H */
|