00001 /* ndk - [ rdoff.h ] 00002 * 00003 * Routines for reading/manipulating RDOFF2 object 00004 * files. 00005 * 00006 * (c)2004 dcipher / neuraldk 00007 * www.neuraldk.org 00008 */ 00009 00020 /* rdoff.h RDOFF Object File manipulation routines header file 00021 * 00022 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and 00023 * Julian Hall. All rights reserved. The software is 00024 * redistributable under the licence given in the file "Licence" 00025 * distributed in the NASM archive. 00026 * 00027 * Permission to use this file in your own projects is granted, as long 00028 * as acknowledgement is given in an appropriate manner to its authors, 00029 * with instructions of how to obtain a copy via ftp. 00030 */ 00031 00032 #ifndef _RDOFF_H 00033 #define _RDOFF_H "RDOFF2 support routines v0.3" 00034 00035 #include <types.h> 00036 00037 /* Some systems don't define this automatically */ 00038 extern char *strdup(const char *); 00039 00040 //typedef unsigned short int16; // <-- all instances replaced with uint16 00041 typedef unsigned char byte; 00042 00043 #define RDF_MAXSEGS 64 00044 00045 /* the records that can be found in the RDOFF header */ 00046 00047 struct RelocRec 00048 { 00049 byte type; /* must be 1 */ 00050 byte reclen; /* content length */ 00051 byte segment; /* only 0 for code, or 1 for data supported, 00052 but add 64 for relative refs (ie do not require 00053 reloc @ loadtime, only linkage) */ 00054 long offset; /* from start of segment in which reference is loc'd */ 00055 byte length; /* 1 2 or 4 bytes */ 00056 uint16 refseg; /* segment to which reference refers to */ 00057 }; 00058 00059 struct ImportRec 00060 { 00061 byte type; /* must be 2 */ 00062 byte reclen; /* content length */ 00063 uint16 segment; /* segment number allocated to the label for reloc 00064 records - label is assumed to be at offset zero 00065 in this segment, so linker must fix up with offset 00066 of segment and of offset within segment */ 00067 char label[33]; /* zero terminated... should be written to file until 00068 the zero, but not after it - max len = 32 chars */ 00069 }; 00070 00071 struct ExportRec 00072 { 00073 byte type; /* must be 3 */ 00074 byte reclen; /* content length */ 00075 byte flags; /* SYM_* flags (see below) */ 00076 byte segment; /* segment referred to (0/1/2) */ 00077 long offset; /* offset within segment */ 00078 char label[33]; /* zero terminated as above. max len = 32 chars */ 00079 }; 00080 00081 struct DLLRec 00082 { 00083 byte type; /* must be 4 */ 00084 byte reclen; /* content length */ 00085 char libname[128]; /* name of library to link with at load time */ 00086 }; 00087 00088 struct BSSRec 00089 { 00090 byte type; /* must be 5 */ 00091 byte reclen; /* content length */ 00092 long amount; /* number of bytes BSS to reserve */ 00093 }; 00094 00095 struct ModRec 00096 { 00097 byte type; /* must be 8 */ 00098 byte reclen; /* content length */ 00099 char modname[128]; /* module name */ 00100 }; 00101 00102 /* Flags for ExportRec */ 00103 #define SYM_DATA 0x01 00104 #define SYM_FUNCTION 0x02 00105 #define SYM_GLOBAL 0x04 00106 00107 /* Multiboot record */ 00108 00109 #ifdef _MULTBOOT_H 00110 00111 #define TRAMPOLINESIZE 22 00112 00113 struct MultiBootHdrRec 00114 { 00115 byte type; /* must be 9 */ 00116 byte reclen; /* content length */ 00117 #ifdef __GNUC__ 00118 struct tMultiBootHeader mb __attribute__ ((packed)); /* MultiBoot header */ 00119 #else 00120 struct tMultiBootHeader mb; 00121 #endif 00122 byte trampoline[TRAMPOLINESIZE]; 00123 }; 00124 00125 #endif 00126 00127 /* GenericRec - contains the type and length field, plus a 128 byte 00128 char array 'data', which will probably never be used! */ 00129 00130 struct GenericRec 00131 { 00132 byte type; 00133 byte reclen; 00134 char data[128]; 00135 }; 00136 00137 typedef union RDFHeaderRec 00138 { 00139 char type; /* invariant throughout all below */ 00140 struct GenericRec g; 00141 struct RelocRec r; /* type == 1 / 6 */ 00142 struct ImportRec i; /* type == 2 / 7 */ 00143 struct ExportRec e; /* type == 3 */ 00144 struct DLLRec d; /* type == 4 */ 00145 struct BSSRec b; /* type == 5 */ 00146 struct ModRec m; /* type == 8 */ 00147 #ifdef _MULTBOOT_H 00148 struct MultiBootHdrRec mbh; /* type == 9 */ 00149 #endif 00150 } rdfheaderrec; 00151 00152 struct SegmentHeaderRec 00153 { 00154 /* information from file */ 00155 uint16 type; 00156 uint16 number; 00157 uint16 reserved; 00158 long length; 00159 00160 /* information built up here */ 00161 long offset; 00162 byte *data; /* pointer to segment data if it exists in memory */ 00163 }; 00164 00165 typedef struct RDFFileInfo 00166 { 00167 //FILE *fp; /* file descriptor; must be open to use this struct */ 00168 int rdoff_ver; /* should be 1; any higher => not guaranteed to work */ 00169 long header_len; 00170 long header_ofs; 00171 00172 byte *header_loc; /* keep location of header */ 00173 long header_fp; /* current location within header for reading */ 00174 00175 struct SegmentHeaderRec seg[RDF_MAXSEGS]; 00176 int nsegs; 00177 00178 long eof_offset; /* offset of the first byte beyond the end of this 00179 module */ 00180 00181 char *name; /* name of module in libraries */ 00182 int *refcount; /* pointer to reference count on file, or NULL */ 00183 } rdffile; 00184 00185 #define BUF_BLOCK_LEN 4088 /* selected to match page size (4096) 00186 * on 80x86 machines for efficiency */ 00187 typedef struct memorybuffer 00188 { 00189 int length; 00190 byte buffer[BUF_BLOCK_LEN]; 00191 struct memorybuffer *next; 00192 } memorybuffer; 00193 00194 typedef struct 00195 { 00196 memorybuffer *buf; /* buffer containing header records */ 00197 int nsegments; /* number of segments to be written */ 00198 long seglength; /* total length of all the segments */ 00199 } rdf_headerbuf; 00200 00201 /* segments used by RDOFF, understood by rdoffloadseg */ 00202 #define RDOFF_CODE 0 00203 #define RDOFF_DATA 1 00204 #define RDOFF_HEADER -1 00205 /* mask for 'segment' in relocation records to find if relative relocation */ 00206 #define RDOFF_RELATIVEMASK 64 00207 /* mask to find actual segment value in relocation records */ 00208 #define RDOFF_SEGMENTMASK 63 00209 00210 extern int rdf_errno; 00211 00212 /* utility functions */ 00213 uint16 translateshort(uint16 in); 00214 long translatelong(long in); 00215 00216 /* RDOFF file manipulation functions */ 00217 int rdfopen(rdffile * f, const char *name); 00218 00219 //int rdfopenhere(rdffile *f, FILE *fp, int *refcount, const char *name); 00220 int rdfclose(rdffile * f); 00221 int rdffindsegment(rdffile * f, int segno); 00222 int rdfloadseg(rdffile * f, int segment, void *buffer); 00223 rdfheaderrec *rdfgetheaderrec(rdffile * f); /* returns static storage */ 00224 void rdfheaderrewind(rdffile * f); /* back to start of header */ 00225 void rdfperror(const char *app, const char *name); 00226 00227 /* functions to write a new RDOFF header to a file - 00228 use rdfnewheader to allocate a header, rdfaddheader to add records to it, 00229 rdfaddsegment to notify the header routines that a segment exists, and 00230 to tell it how long the segment will be. 00231 rdfwriteheader to write the file id, object length, and header 00232 to a file, and then rdfdoneheader to dispose of the header */ 00233 00234 rdf_headerbuf *rdfnewheader(void); 00235 int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r); 00236 int rdfaddsegment(rdf_headerbuf * h, long seglength); 00237 00238 //int rdfwriteheader(FILE *fp,rdf_headerbuf *h); 00239 void rdfdoneheader(rdf_headerbuf * h); 00240 00241 /* This is needed by linker to write multiboot header record */ 00242 int membuflength(memorybuffer * b); 00243 00244 #endif /* _RDOFF_H */ 00245