regularized spelling of license to match name of LICENSE file
[platform/upstream/nasm.git] / rdoff / rdoff.h
1 /*
2  * rdoff.h      RDOFF Object File manipulation routines header file
3  *
4  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
5  * Julian Hall. All rights reserved. The software is
6  * redistributable under the license given in the file "LICENSE"
7  * distributed in the NASM archive.
8  *
9  * Permission to use this file in your own projects is granted, as int32_t
10  * as acknowledgement is given in an appropriate manner to its authors,
11  * with instructions of how to obtain a copy via ftp.
12  */
13
14 #ifndef RDOFF_RDOFF_H
15 #define RDOFF_RDOFF_H 1
16
17 #include <inttypes.h>
18
19 /*
20  * RDOFF definitions. They are used by RDOFF utilities and by NASM's
21  * 'outrdf2.c' output module.
22  */
23
24 /* RDOFF format revision (currently used only when printing the version) */
25 #define RDOFF2_REVISION         "0.6.1"
26
27 /* RDOFF2 file signature */
28 #define RDOFF2_SIGNATURE        "RDOFF2"
29
30 /* Maximum size of an import/export label (including trailing zero) */
31 #define EXIM_LABEL_MAX          64
32
33 /* Maximum size of library or module name (including trailing zero) */
34 #define MODLIB_NAME_MAX         128
35
36 /* Maximum number of segments that we can handle in one file */
37 #define RDF_MAXSEGS             64
38
39 /* Record types that may present the RDOFF header */
40 #define RDFREC_GENERIC          0
41 #define RDFREC_RELOC            1
42 #define RDFREC_IMPORT           2
43 #define RDFREC_GLOBAL           3
44 #define RDFREC_DLL              4
45 #define RDFREC_BSS              5
46 #define RDFREC_SEGRELOC         6
47 #define RDFREC_FARIMPORT        7
48 #define RDFREC_MODNAME          8
49 #define RDFREC_COMMON           10
50
51 /*
52  * Generic record - contains the type and length field, plus a 128 byte
53  * array 'data'
54  */
55 struct GenericRec {
56     uint8_t type;
57     uint8_t reclen;
58     char data[128];
59 };
60
61 /*
62  * Relocation record
63  */
64 struct RelocRec {
65     uint8_t type;                  /* must be 1 */
66     uint8_t reclen;                /* content length */
67     uint8_t segment;               /* only 0 for code, or 1 for data supported,
68                                    but add 64 for relative refs (ie do not require
69                                    reloc @ loadtime, only linkage) */
70     int32_t offset;                /* from start of segment in which reference is loc'd */
71     uint8_t length;                /* 1 2 or 4 bytes */
72     uint16_t refseg;              /* segment to which reference refers to */
73 };
74
75 /*
76  * Extern/import record
77  */
78 struct ImportRec {
79     uint8_t type;                  /* must be 2 */
80     uint8_t reclen;                /* content length */
81     uint8_t flags;                 /* SYM_* flags (see below) */
82     uint16_t segment;             /* segment number allocated to the label for reloc
83                                    records - label is assumed to be at offset zero
84                                    in this segment, so linker must fix up with offset
85                                    of segment and of offset within segment */
86     char label[EXIM_LABEL_MAX]; /* zero terminated, should be written to file
87                                    until the zero, but not after it */
88 };
89
90 /*
91  * Public/export record
92  */
93 struct ExportRec {
94     uint8_t type;                  /* must be 3 */
95     uint8_t reclen;                /* content length */
96     uint8_t flags;                 /* SYM_* flags (see below) */
97     uint8_t segment;               /* segment referred to (0/1/2) */
98     int32_t offset;                /* offset within segment */
99     char label[EXIM_LABEL_MAX]; /* zero terminated as in import */
100 };
101
102 /*
103  * DLL record
104  */
105 struct DLLRec {
106     uint8_t type;                  /* must be 4 */
107     uint8_t reclen;                /* content length */
108     char libname[MODLIB_NAME_MAX];      /* name of library to link with at load time */
109 };
110
111 /*
112  * BSS record
113  */
114 struct BSSRec {
115     uint8_t type;                  /* must be 5 */
116     uint8_t reclen;                /* content length */
117     int32_t amount;                /* number of bytes BSS to reserve */
118 };
119
120 /*
121  * Module name record
122  */
123 struct ModRec {
124     uint8_t type;                  /* must be 8 */
125     uint8_t reclen;                /* content length */
126     char modname[MODLIB_NAME_MAX];      /* module name */
127 };
128
129 /*
130  * Common variable record
131  */
132 struct CommonRec {
133     uint8_t type;                  /* must be 10 */
134     uint8_t reclen;                /* equals 7+label length */
135     uint16_t segment;             /* segment number */
136     int32_t size;                  /* size of common variable */
137     uint16_t align;               /* alignment (power of two) */
138     char label[EXIM_LABEL_MAX]; /* zero terminated as in import */
139 };
140
141 /* Flags for ExportRec */
142 #define SYM_DATA        1
143 #define SYM_FUNCTION    2
144 #define SYM_GLOBAL      4
145 #define SYM_IMPORT      8
146
147 /*** The following part is used only by the utilities *************************/
148
149 #ifdef RDOFF_UTILS
150
151 /* Some systems don't define this automatically */
152 #if !defined(strdup)
153 extern char *strdup(const char *);
154 #endif
155
156 typedef union RDFHeaderRec {
157     char type;                  /* invariant throughout all below */
158     struct GenericRec g;        /* type 0 */
159     struct RelocRec r;          /* type == 1 / 6 */
160     struct ImportRec i;         /* type == 2 / 7 */
161     struct ExportRec e;         /* type == 3 */
162     struct DLLRec d;            /* type == 4 */
163     struct BSSRec b;            /* type == 5 */
164     struct ModRec m;            /* type == 8 */
165     struct CommonRec c;         /* type == 10 */
166 } rdfheaderrec;
167
168 struct SegmentHeaderRec {
169     /* information from file */
170     uint16_t type;
171     uint16_t number;
172     uint16_t reserved;
173     int32_t length;
174
175     /* information built up here */
176     int32_t offset;
177     uint8_t *data;                 /* pointer to segment data if it exists in memory */
178 };
179
180 typedef struct RDFFileInfo {
181     FILE *fp;                   /* file descriptor; must be open to use this struct */
182     int rdoff_ver;              /* should be 1; any higher => not guaranteed to work */
183     int32_t header_len;
184     int32_t header_ofs;
185
186     uint8_t *header_loc;           /* keep location of header */
187     int32_t header_fp;             /* current location within header for reading */
188
189     struct SegmentHeaderRec seg[RDF_MAXSEGS];
190     int nsegs;
191
192     int32_t eof_offset;            /* offset of the first uint8_t beyond the end of this
193                                    module */
194
195     char *name;                 /* name of module in libraries */
196     int *refcount;              /* pointer to reference count on file, or NULL */
197 } rdffile;
198
199 #define BUF_BLOCK_LEN 4088      /* selected to match page size (4096)
200                                  * on 80x86 machines for efficiency */
201 typedef struct memorybuffer {
202     int length;
203     uint8_t buffer[BUF_BLOCK_LEN];
204     struct memorybuffer *next;
205 } memorybuffer;
206
207 typedef struct {
208     memorybuffer *buf;          /* buffer containing header records */
209     int nsegments;              /* number of segments to be written */
210     int32_t seglength;             /* total length of all the segments */
211 } rdf_headerbuf;
212
213 /* segments used by RDOFF, understood by rdoffloadseg */
214 #define RDOFF_CODE      0
215 #define RDOFF_DATA      1
216 #define RDOFF_HEADER    -1
217 /* mask for 'segment' in relocation records to find if relative relocation */
218 #define RDOFF_RELATIVEMASK 64
219 /* mask to find actual segment value in relocation records */
220 #define RDOFF_SEGMENTMASK 63
221
222 extern int rdf_errno;
223
224 /* rdf_errno can hold these error codes */
225 enum {
226     /* 0 */ RDF_OK,
227     /* 1 */ RDF_ERR_OPEN,
228     /* 2 */ RDF_ERR_FORMAT,
229     /* 3 */ RDF_ERR_READ,
230     /* 4 */ RDF_ERR_UNKNOWN,
231     /* 5 */ RDF_ERR_HEADER,
232     /* 6 */ RDF_ERR_NOMEM,
233     /* 7 */ RDF_ERR_VER,
234     /* 8 */ RDF_ERR_RECTYPE,
235     /* 9 */ RDF_ERR_RECLEN,
236     /* 10 */ RDF_ERR_SEGMENT
237 };
238
239 /* utility functions */
240 int32_t translateint32_t(int32_t in);
241 uint16_t translateint16_t(uint16_t in);
242 char *translatesegmenttype(uint16_t type);
243
244 /* RDOFF file manipulation functions */
245 int rdfopen(rdffile * f, const char *name);
246 int rdfopenhere(rdffile * f, FILE * fp, int *refcount, const char *name);
247 int rdfclose(rdffile * f);
248 int rdffindsegment(rdffile * f, int segno);
249 int rdfloadseg(rdffile * f, int segment, void *buffer);
250 rdfheaderrec *rdfgetheaderrec(rdffile * f);     /* returns static storage */
251 void rdfheaderrewind(rdffile * f);      /* back to start of header */
252 void rdfperror(const char *app, const char *name);
253
254 /* functions to write a new RDOFF header to a file -
255    use rdfnewheader to allocate a header, rdfaddheader to add records to it,
256    rdfaddsegment to notify the header routines that a segment exists, and
257    to tell it how int32_t the segment will be.
258    rdfwriteheader to write the file id, object length, and header
259    to a file, and then rdfdoneheader to dispose of the header */
260
261 rdf_headerbuf *rdfnewheader(void);
262 int rdfaddheader(rdf_headerbuf * h, rdfheaderrec * r);
263 int rdfaddsegment(rdf_headerbuf * h, int32_t seglength);
264 int rdfwriteheader(FILE * fp, rdf_headerbuf * h);
265 void rdfdoneheader(rdf_headerbuf * h);
266
267 #endif                          /* RDOFF_UTILS */
268
269 #endif                          /* RDOFF_RDOFF_H */