1 /* coff.h - Common Object File Format (COFF) support
2  *
3  * This file was developed for the AVRA assembler in order to produce COFF output files
4  * for use with the Atmel AVR Studio.  The Lean C Compiler (LCC) debugging stabs
5  * output was used as input to the assembler.
6  *
7  * This software has absolutely no warrantee!  The money you paid for this will be
8  * promptly refunded if not fully satisfied.
9  *
10  * Beta release 1/20/2000 by Bob Harris
11  *
12  * This software has not been fully tested and probably has a few software deficiencies.
13  * Some software support may be possible by sending a problem description report to
14  * rth@mclean.sparta.com */
15 
16 #define MAGIC_NUMBER_AVR   0xa12
17 
18 #define	N_GSYM	0x20		/* global symbol: name,,0,type,0 */
19 #define	N_FNAME	0x22		/* procedure name (f77 kludge): name,,0 */
20 #define	N_FUN	0x24		/* procedure: name,,0,linenumber,address */
21 #define	N_STSYM	0x26		/* static symbol: name,,0,type,address */
22 #define	N_LCSYM	0x28		/* .lcomm symbol: name,,0,type,address */
23 #define N_MAIN  0x2a            /* name of main routine : name,,0,0,0 */
24 #define N_ROSYM 0x2c		/* ro_data objects */
25 #define N_OBJ	0x38		/* object file path or name */
26 #define N_OPT	0x3c		/* compiler options */
27 #define	N_RSYM	0x40		/* register sym: name,,0,type,register */
28 #define	N_SLINE	0x44		/* src line: 0,,0,linenumber,address */
29 #define	N_FLINE	0x4c		/* function start.end */
30 #define	N_SSYM	0x60		/* structure elt: name,,0,type,struct_offset */
31 #define N_ENDM	0x62		/* last stab emitted for module */
32 #define	N_SO	0x64		/* source file name: name,,0,0,address */
33 #define	N_LSYM	0x80		/* local sym: name,,0,type,offset */
34 #define	N_BINCL 0x82		/* header file: name,,0,0,0 */
35 #define	N_SOL	0x84		/* #included file name: name,,0,0,address */
36 #define	N_PSYM	0xa0		/* parameter: name,,0,type,offset */
37 #define N_EINCL 0xa2		/* end of include file */
38 #define	N_ENTRY	0xa4		/* alternate entry: name,linenumber,address */
39 #define	N_LBRAC	0xc0		/* left bracket: 0,,0,nesting level,address */
40 #define	N_EXCL	0xc2		/* excluded include file */
41 #define	N_RBRAC	0xe0		/* right bracket: 0,,0,nesting level,address */
42 #define	N_BCOMM	0xe2		/* begin common: name,, */
43 #define	N_ECOMM	0xe4		/* end common: name,, */
44 #define	N_ECOML	0xe8		/* end common (local name): ,,address */
45 #define	N_LENG	0xfe		/* second stab entry with length information */
46 
47 
48 /* Type of a symbol, in low N bits of the word */
49 #define T_NULL		0
50 #define T_VOID		1	/* function argument (only used by compiler) */
51 #define T_CHAR		2	/* character		*/
52 #define T_SHORT		3	/* short integer	*/
53 #define T_INT		4	/* integer		*/
54 #define T_LONG		5	/* long integer		*/
55 #define T_FLOAT		6	/* floating point	*/
56 #define T_DOUBLE	7	/* double word		*/
57 #define T_STRUCT	8	/* structure 		*/
58 #define T_UNION		9	/* union 		*/
59 #define T_ENUM		10	/* enumeration 		*/
60 #define T_MOE		11	/* member of enumeration*/
61 #define T_UCHAR		12	/* unsigned character	*/
62 #define T_USHORT	13	/* unsigned short	*/
63 #define T_UINT		14	/* unsigned integer	*/
64 #define T_ULONG		15	/* unsigned long	*/
65 #define T_LNGDBL	16	/* long double		*/
66 
67 /* derived types, in n_type */
68 #define DT_NON		(0)	/* no derived type */
69 #define DT_PTR		(1)	/* pointer */
70 #define DT_FCN		(2)	/* function */
71 #define DT_ARY		(3)	/* array */
72 
73 struct external_filehdr {
74 	unsigned short f_magic;		/* magic number			*/
75 	unsigned short f_nscns;		/* number of sections		*/
76 	unsigned long f_timdat;	/* time & date stamp		*/
77 	unsigned long f_symptr;	/* file pointer to symtab	*/
78 	unsigned long f_nsyms;		/* number of symtab entries	*/
79 	unsigned short f_opthdr;	/* sizeof(optional hdr)		*/
80 	unsigned short f_flags;		/* flags			*/
81 };
82 
83 /* Bits for f_flags:
84  *	F_RELFLG	relocation info stripped from file
85  *	F_EXEC		file is executable (no unresolved external references)
86  *	F_LNNO		line numbers stripped from file
87  *	F_LSYMS		local symbols stripped from file
88  *	F_AR32WR	file has byte ordering of an AR32WR machine (e.g. vax) */
89 
90 #define F_RELFLG	(0x0001)
91 #define F_EXEC		(0x0002)
92 #define F_LNNO		(0x0004)
93 #define F_LSYMS		(0x0008)
94 
95 struct external_scnhdr {
96 	char		s_name[8];	/* section name			*/
97 	unsigned long		s_paddr;	/* physical address, aliased s_nlib */
98 	unsigned long		s_vaddr;	/* virtual address		*/
99 	unsigned long		s_size;		/* section size			*/
100 	unsigned long		s_scnptr;	/* file ptr to raw data for section */
101 	unsigned long		s_relptr;	/* file ptr to relocation	*/
102 	unsigned long		s_lnnoptr;	/* file ptr to line numbers	*/
103 	unsigned short		s_nreloc;	/* number of relocation entries	*/
104 	unsigned short		s_nlnno;	/* number of line number entries*/
105 	unsigned long		s_flags;	/* flags			*/
106 };
107 
108 #define	SCNHDR	struct external_scnhdr
109 #define	SCNHSZ	sizeof(SCNHDR)
110 
111 /* names of "special" sections */
112 #define _TEXT	".text"
113 #define _DATA	".data"
114 #define _BSS	".bss"
115 #define _COMMENT ".comment"
116 #define _LIB ".lib"
117 
118 /* s_flags "type" */
119 #define STYP_TEXT	 (0x0020)	/* section contains text only */
120 #define STYP_DATA	 (0x0040)	/* section contains data only */
121 #define STYP_BSS	 (0x0080)	/* section contains bss only */
122 
123 
124 struct lineno {
125 	union {
126 		long  l_symndx;  /* symtbl index of func name */
127 		long  l_paddr;   /* paddr of line number */
128 	} l_addr;
129 	unsigned short  l_lnno;    /* line number */
130 };
131 
132 #define LINENO      struct lineno
133 #define LINESZ      6
134 
135 
136 
137 #define N_UNDEF	((short)0)	/* undefined symbol */
138 #define N_ABS	((short)-1)	/* value of symbol is absolute */
139 #define N_DEBUG	((short)-2)	/* debugging symbol -- value is meaningless */
140 
141 /* STORAGE CLASSES */
142 
143 /* This used to be defined as -1, but now n_sclass is unsigned.  */
144 #define C_EFCN		0xff	/* physical end of function	*/
145 #define C_NULL		0
146 #define C_AUTO		1	/* automatic variable		*/
147 #define C_EXT		2	/* external symbol		*/
148 #define C_STAT		3	/* static			*/
149 #define C_REG		4	/* register variable		*/
150 #define C_EXTDEF	5	/* external definition		*/
151 #define C_LABEL		6	/* label			*/
152 #define C_ULABEL	7	/* undefined label		*/
153 #define C_MOS		8	/* member of structure		*/
154 #define C_ARG		9	/* function argument		*/
155 #define C_STRTAG	10	/* structure tag		*/
156 #define C_MOU		11	/* member of union		*/
157 #define C_UNTAG		12	/* union tag			*/
158 #define C_TPDEF		13	/* type definition		*/
159 #define C_USTATIC	14	/* undefined static		*/
160 #define C_ENTAG		15	/* enumeration tag		*/
161 #define C_MOE		16	/* member of enumeration	*/
162 #define C_REGPARM	17	/* register parameter		*/
163 #define C_FIELD		18	/* bit field			*/
164 #define C_AUTOARG	19	/* auto argument		*/
165 #define C_LASTENT	20	/* dummy entry (end of block)	*/
166 #define C_BLOCK		100	/* ".bb" or ".eb"		*/
167 #define C_FCN		101	/* ".bf" or ".ef"		*/
168 #define C_EOS		102	/* end of structure		*/
169 #define C_FILE		103	/* file name			*/
170 #define C_LINE		104	/* line # reformatted as symbol table entry */
171 #define C_ALIAS	 	105	/* duplicate tag		*/
172 #define C_HIDDEN	106	/* ext symbol in dmert public lib */
173 
174 #define E_SYMNMLEN	8	/* # characters in a symbol name	*/
175 #define E_FILNMLEN	14	/* # characters in a file name		*/
176 #define E_DIMNUM	4	/* # array dimensions in auxiliary entry */
177 
178 struct syment {
179 	union {
180 		char          _n_name[E_SYMNMLEN];  /* symbol name*/
181 		struct {
182 			long    _n_zeroes;          /* symbol name */
183 
184 			long    _n_offset;          /* location in string table */
185 		} _n_n;
186 		char          *_n_nptr[2];        /* allows overlaying */
187 	} _n;
188 	unsigned long     n_value;            /* value of symbol */
189 
190 	short             n_scnum;            /* section number */
191 
192 	unsigned short    n_type;             /* type and derived */
193 
194 	char              n_sclass;           /* storage class */
195 
196 	char              n_numaux;           /* number of aux entries */
197 };
198 
199 #define  n_name          _n._n_name
200 #define  n_zeroes        _n._n_n._n_zeroes
201 #define  n_offset        _n._n_n._n_offset
202 #define  n_nptr          _n._n_nptr[1]
203 
204 #define  SYMNMLEN  8
205 #define  SYMESZ    18                    /* size of a symbol table entry */
206 
207 union auxent {
208 	struct {
209 		long   x_tagndx;
210 		union {
211 			struct {
212 				unsigned short   x_lnno;
213 				unsigned short   x_size;
214 			} x_lnsz;
215 			long    x_fsize;
216 		} x_misc;
217 		union {
218 			struct {
219 				long    x_lnnoptr;
220 				long    x_endndx;
221 			} x_fcn;
222 			struct {
223 				unsigned short   x_dimen[E_DIMNUM];
224 			} x_ary;
225 		} x_fcnary;
226 		unsigned short   x_tvndx;
227 	} x_sym;
228 	union {
229 		char   x_fname[E_FILNMLEN];
230 		struct {
231 			unsigned long x_zeroes;
232 			unsigned long x_offset;
233 		} x_n;
234 	} x_file;
235 	struct {
236 		long   x_scnlen;
237 		unsigned short   x_nreloc;
238 		unsigned short   x_nlinno;
239 	} x_scn;
240 	struct {
241 		long   x_tvfill;
242 		unsigned short   x_tvlen;
243 		unsigned short   x_tvran[2];
244 	} x_tv;
245 };
246 
247 #define FILNMLEN  14
248 #define DIMNUM    4
249 #define AUXENT    union auxent
250 #define AUXESZ    18
251 
252 
253 /* Coff additions */
254 typedef struct ListNodeTag {
255 	struct ListNodeTag *Next;	/* Double Linked List */
256 	struct ListNodeTag *Last;	/* Double Linked List */
257 	void *pObject;	/* points to list object */
258 	unsigned long Size;
259 	int FileNumber;		/* corresponds to individual file(s) */
260 } LISTNODE;
261 
262 typedef struct ListNodeHeadTag {
263 	LISTNODE Node;
264 	int TotalBytes;	/* size of allocated object(s) */
265 	int TotalItems; /* number of allocated objects */
266 	LISTNODE *current;	/* pointer for FindFirst/FindNext */
267 } LISTNODEHEAD ;
268 
269 
270 typedef struct  {
271 	unsigned short StabType;
272 	unsigned short CoffType;
273 	unsigned short ByteSize;
274 	unsigned short Line;	/* used by arrays */
275 	unsigned short Dimensions[6]; /* used by arrays */
276 } STABCOFFMAP;
277 
278 struct coff_info {
279 
280 	int CurrentFileNumber;
281 	int FunctionStartLine;	/* used in Line number table */
282 	int CurrentSourceLine;
283 
284 	/* Internal */
285 	unsigned char *pRomMemory;	/* 16 bit wide words/addresses */
286 	unsigned char *pEEPRomMemory;	/* 8 bit wide words/addresses */
287 	int MaxRomAddress;
288 	int MaxEepromAddress;
289 	int NeedLineNumberFixup;
290 	int GlobalStartAddress;
291 	int GlobalEndAddress;
292 	LISTNODEHEAD ListOfSplitLines;
293 
294 	/* External */
295 	struct external_filehdr FileHeader;		/* Only one of these per output file */
296 	LISTNODEHEAD ListOfSectionHeaders;	/* .text, .bss */
297 	LISTNODEHEAD ListOfRawData;			/* Program, EEPROM */
298 	LISTNODEHEAD ListOfRelocations;		/* Not used now */
299 	LISTNODEHEAD ListOfLineNumbers;
300 	LISTNODEHEAD ListOfSymbols;
301 	LISTNODEHEAD ListOfGlobals;
302 	LISTNODEHEAD ListOfSpecials;
303 	LISTNODEHEAD ListOfUndefined;
304 	LISTNODEHEAD ListOfStrings;
305 	LISTNODEHEAD ListOfTypes;
306 };
307 
308 /* Internal routines */
309 int stab_add_lineno(struct prog_info *pi, int LineNumber, char *pLabel, char *pFunction);
310 int stab_add_lbracket(struct prog_info *pi, int Level, char *pLabel, char *pFunction);
311 int stab_add_rbracket(struct prog_info *pi, int Level, char *pLabel, char *pFunction);
312 int stab_add_filename(char *pName, char *pLabel);
313 int stab_add_function(struct prog_info *pi, char *pName, char *pLabel);
314 int stab_add_global(struct prog_info *pi, char *pName, char *pType);
315 int stab_add_local(struct prog_info *pi, char *pName, char *pType, char *pOffset);
316 int stab_add_parameter_symbol(struct prog_info *pi, char *pName, char *pType, char *pOffset);
317 int stab_add_static_symbol(struct prog_info *pi, char *pName, char *pType, char *pLabel);
318 int stab_add_local_register(struct prog_info *pi, char *pName, char *pType, char *pRegister);
319 int stab_add_local_type(char *pString, char *pType);
320 int stab_add_tag_type(char *pName, char *pDesciptor);
321 
322 int GetStabType(char *p, unsigned short *pType, char **pEnd);
323 int AddNameToEntry(char *pName, struct syment *pEntry);
324 int GetArrayType(char *p, char **pEnd, STABCOFFMAP *pMap, unsigned short *DerivedBits, int ExtraLevels);
325 int GetEnumTagItem(char *p, char **pEnd, char **pEnumName, int *pEnumValue);
326 int GetStructUnionTagItem(char *p, char **pEnd, char **pName, unsigned short *pType, unsigned short *pBitOffset, unsigned short *pBitSize);
327 int GetStringDelimiters(char *pString, char **pTokens, int MaxTokens);
328 int SetupDefinedType(unsigned short Type, STABCOFFMAP *pMap, unsigned short *DerivedBits, int ExtraLevels);
329 int GetArrayDefinitions(STABCOFFMAP *pMap, char *pMinIndex, char *pMaxIndex, char *pType, unsigned short *DerivedBits, int ExtraLevels);
330 int GetInternalType(char *pName, STABCOFFMAP *pMap);
331 unsigned short GetCoffType(unsigned short StabType);
332 unsigned short GetCoffTypeSize(unsigned short StabType);
333 int CopyStabCoffMap(unsigned short StabType, STABCOFFMAP *pMap);
334 int IsTypeArray(unsigned short CoffType);
335 void AddArrayAuxInfo(union auxent *pAux, unsigned short SymbolIndex, STABCOFFMAP *pMap);
336 int GetSubRangeType(unsigned short Type, STABCOFFMAP *pMap, char *pLow, char *pHigh);
337 char *SkipPastDigits(char *p);
338 int GetDigitLength(char *p);
339 
340 /* List management routines */
341 
342 void InitializeList(LISTNODEHEAD *pNode);
343 void *AllocateTwoListObjects(LISTNODEHEAD *pHead, int size);
344 void *AllocateListObject(LISTNODEHEAD *pHead, int size);
345 LISTNODE *AllocateListNode(void *pObject, int size);
346 void AddNodeToList(LISTNODEHEAD *pHead, LISTNODE *pNode);
347 void *FindFirstListObject(LISTNODEHEAD *pHead);
348 void *FindNextListObject(LISTNODEHEAD *pHead);
349 LISTNODE *GetCurrentNode(LISTNODEHEAD *pHead);
350 void *GetCurrentListObject(LISTNODEHEAD *pHead);
351 void *FindLastListObject(LISTNODEHEAD *pHead);
352 void *FindNextLastListObject(LISTNODEHEAD *pHead);
353 void FreeList(LISTNODEHEAD *pHead);
354 LISTNODE  *AddListObject(LISTNODEHEAD *pHead, void *pObject, int size);
355 
356