mirror of
				https://github.com/netwide-assembler/nasm.git
				synced 2025-10-10 00:25:06 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			270 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			270 lines
		
	
	
		
			8.7 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 license given in the file "LICENSE"
 | |
|  * distributed in the NASM archive.
 | |
|  *
 | |
|  * Permission to use this file in your own projects is granted, as int32_t
 | |
|  * as acknowledgement is given in an appropriate manner to its authors,
 | |
|  * with instructions of how to obtain a copy via ftp.
 | |
|  */
 | |
| 
 | |
| #ifndef RDOFF_RDOFF_H
 | |
| #define RDOFF_RDOFF_H 1
 | |
| 
 | |
| #include <inttypes.h>
 | |
| 
 | |
| /*
 | |
|  * RDOFF definitions. They are used by RDOFF utilities and by NASM's
 | |
|  * 'outrdf2.c' output module.
 | |
|  */
 | |
| 
 | |
| /* RDOFF format revision (currently used only when printing the version) */
 | |
| #define RDOFF2_REVISION		"0.6.1"
 | |
| 
 | |
| /* RDOFF2 file signature */
 | |
| #define RDOFF2_SIGNATURE	"RDOFF2"
 | |
| 
 | |
| /* Maximum size of an import/export label (including trailing zero) */
 | |
| #define EXIM_LABEL_MAX		64
 | |
| 
 | |
| /* Maximum size of library or module name (including trailing zero) */
 | |
| #define MODLIB_NAME_MAX		128
 | |
| 
 | |
| /* Maximum number of segments that we can handle in one file */
 | |
| #define RDF_MAXSEGS		64
 | |
| 
 | |
| /* Record types that may present the RDOFF header */
 | |
| #define RDFREC_GENERIC		0
 | |
| #define RDFREC_RELOC		1
 | |
| #define RDFREC_IMPORT		2
 | |
| #define RDFREC_GLOBAL		3
 | |
| #define RDFREC_DLL		4
 | |
| #define RDFREC_BSS		5
 | |
| #define RDFREC_SEGRELOC		6
 | |
| #define RDFREC_FARIMPORT	7
 | |
| #define RDFREC_MODNAME		8
 | |
| #define RDFREC_COMMON		10
 | |
| 
 | |
| /*
 | |
|  * Generic record - contains the type and length field, plus a 128 byte
 | |
|  * array 'data'
 | |
|  */
 | |
| struct GenericRec {
 | |
|     uint8_t type;
 | |
|     uint8_t reclen;
 | |
|     char data[128];
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * Relocation record
 | |
|  */
 | |
| struct RelocRec {
 | |
|     uint8_t type;                  /* must be 1 */
 | |
|     uint8_t reclen;                /* content length */
 | |
|     uint8_t segment;               /* only 0 for code, or 1 for data supported,
 | |
|                                    but add 64 for relative refs (ie do not require
 | |
|                                    reloc @ loadtime, only linkage) */
 | |
|     int32_t offset;                /* from start of segment in which reference is loc'd */
 | |
|     uint8_t length;                /* 1 2 or 4 bytes */
 | |
|     uint16_t refseg;              /* segment to which reference refers to */
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * Extern/import record
 | |
|  */
 | |
| struct ImportRec {
 | |
|     uint8_t type;                  /* must be 2 */
 | |
|     uint8_t reclen;                /* content length */
 | |
|     uint8_t flags;                 /* SYM_* flags (see below) */
 | |
|     uint16_t 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[EXIM_LABEL_MAX]; /* zero terminated, should be written to file
 | |
|                                    until the zero, but not after it */
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * Public/export record
 | |
|  */
 | |
| struct ExportRec {
 | |
|     uint8_t type;                  /* must be 3 */
 | |
|     uint8_t reclen;                /* content length */
 | |
|     uint8_t flags;                 /* SYM_* flags (see below) */
 | |
|     uint8_t segment;               /* segment referred to (0/1/2) */
 | |
|     int32_t offset;                /* offset within segment */
 | |
|     char label[EXIM_LABEL_MAX]; /* zero terminated as in import */
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * DLL record
 | |
|  */
 | |
| struct DLLRec {
 | |
|     uint8_t type;                  /* must be 4 */
 | |
|     uint8_t reclen;                /* content length */
 | |
|     char libname[MODLIB_NAME_MAX];      /* name of library to link with at load time */
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * BSS record
 | |
|  */
 | |
| struct BSSRec {
 | |
|     uint8_t type;                  /* must be 5 */
 | |
|     uint8_t reclen;                /* content length */
 | |
|     int32_t amount;                /* number of bytes BSS to reserve */
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * Module name record
 | |
|  */
 | |
| struct ModRec {
 | |
|     uint8_t type;                  /* must be 8 */
 | |
|     uint8_t reclen;                /* content length */
 | |
|     char modname[MODLIB_NAME_MAX];      /* module name */
 | |
| };
 | |
| 
 | |
| /*
 | |
|  * Common variable record
 | |
|  */
 | |
| struct CommonRec {
 | |
|     uint8_t type;                  /* must be 10 */
 | |
|     uint8_t reclen;                /* equals 7+label length */
 | |
|     uint16_t segment;             /* segment number */
 | |
|     int32_t size;                  /* size of common variable */
 | |
|     uint16_t align;               /* alignment (power of two) */
 | |
|     char label[EXIM_LABEL_MAX]; /* zero terminated as in import */
 | |
| };
 | |
| 
 | |
| /* Flags for ExportRec */
 | |
| #define SYM_DATA	1
 | |
| #define SYM_FUNCTION	2
 | |
| #define SYM_GLOBAL	4
 | |
| #define SYM_IMPORT	8
 | |
| 
 | |
| /*** The following part is used only by the utilities *************************/
 | |
| 
 | |
| #ifdef RDOFF_UTILS
 | |
| 
 | |
| /* Some systems don't define this automatically */
 | |
| #if !defined(strdup)
 | |
| extern char *strdup(const char *);
 | |
| #endif
 | |
| 
 | |
| typedef union RDFHeaderRec {
 | |
|     char type;                  /* invariant throughout all below */
 | |
|     struct GenericRec g;        /* type 0 */
 | |
|     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 */
 | |
|     struct CommonRec c;         /* type == 10 */
 | |
| } rdfheaderrec;
 | |
| 
 | |
| struct SegmentHeaderRec {
 | |
|     /* information from file */
 | |
|     uint16_t type;
 | |
|     uint16_t number;
 | |
|     uint16_t reserved;
 | |
|     int32_t length;
 | |
| 
 | |
|     /* information built up here */
 | |
|     int32_t offset;
 | |
|     uint8_t *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 */
 | |
|     int32_t header_len;
 | |
|     int32_t header_ofs;
 | |
| 
 | |
|     uint8_t *header_loc;           /* keep location of header */
 | |
|     int32_t header_fp;             /* current location within header for reading */
 | |
| 
 | |
|     struct SegmentHeaderRec seg[RDF_MAXSEGS];
 | |
|     int nsegs;
 | |
| 
 | |
|     int32_t eof_offset;            /* offset of the first uint8_t 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;
 | |
|     uint8_t buffer[BUF_BLOCK_LEN];
 | |
|     struct memorybuffer *next;
 | |
| } memorybuffer;
 | |
| 
 | |
| typedef struct {
 | |
|     memorybuffer *buf;          /* buffer containing header records */
 | |
|     int nsegments;              /* number of segments to be written */
 | |
|     int32_t 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;
 | |
| 
 | |
| /* rdf_errno can hold these error codes */
 | |
| enum {
 | |
|     /* 0 */ RDF_OK,
 | |
|     /* 1 */ RDF_ERR_OPEN,
 | |
|     /* 2 */ RDF_ERR_FORMAT,
 | |
|     /* 3 */ RDF_ERR_READ,
 | |
|     /* 4 */ RDF_ERR_UNKNOWN,
 | |
|     /* 5 */ RDF_ERR_HEADER,
 | |
|     /* 6 */ RDF_ERR_NOMEM,
 | |
|     /* 7 */ RDF_ERR_VER,
 | |
|     /* 8 */ RDF_ERR_RECTYPE,
 | |
|     /* 9 */ RDF_ERR_RECLEN,
 | |
|     /* 10 */ RDF_ERR_SEGMENT
 | |
| };
 | |
| 
 | |
| /* utility functions */
 | |
| int32_t translateint32_t(int32_t in);
 | |
| uint16_t translateint16_t(uint16_t in);
 | |
| char *translatesegmenttype(uint16_t type);
 | |
| 
 | |
| /* 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 int32_t 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, int32_t seglength);
 | |
| int rdfwriteheader(FILE * fp, rdf_headerbuf * h);
 | |
| void rdfdoneheader(rdf_headerbuf * h);
 | |
| 
 | |
| #endif                          /* RDOFF_UTILS */
 | |
| 
 | |
| #endif                          /* RDOFF_RDOFF_H */
 |