| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* This file is derived from the GAS 2.1.4 assembler control file. | 
|  | 2 | The GAS product is under the GNU General Public License, version 2 or later. | 
|  | 3 | As such, this file is also under that license. | 
|  | 4 |  | 
|  | 5 | If the file format changes in the COFF object, this file should be | 
|  | 6 | subsequently updated to reflect the changes. | 
|  | 7 |  | 
|  | 8 | The actual loader module only uses a few of these structures. The full | 
|  | 9 | set is documented here because I received the full set. If you wish | 
|  | 10 | more information about COFF, then O'Reilly has a very excellent book. | 
|  | 11 | */ | 
|  | 12 |  | 
|  | 13 | #define  E_SYMNMLEN  8   /* Number of characters in a symbol name         */ | 
|  | 14 | #define  E_FILNMLEN 14   /* Number of characters in a file name           */ | 
|  | 15 | #define  E_DIMNUM    4   /* Number of array dimensions in auxiliary entry */ | 
|  | 16 |  | 
|  | 17 | /* | 
|  | 18 | * These defines are byte order independent. There is no alignment of fields | 
|  | 19 | * permitted in the structures. Therefore they are declared as characters | 
|  | 20 | * and the values loaded from the character positions. It also makes it | 
|  | 21 | * nice to have it "endian" independent. | 
|  | 22 | */ | 
|  | 23 |  | 
|  | 24 | /* Load a short int from the following tables with little-endian formats */ | 
|  | 25 | #define COFF_SHORT_L(ps) ((short)(((unsigned short)((unsigned char)ps[1])<<8)|\ | 
|  | 26 | ((unsigned short)((unsigned char)ps[0])))) | 
|  | 27 |  | 
|  | 28 | /* Load a long int from the following tables with little-endian formats */ | 
|  | 29 | #define COFF_LONG_L(ps) (((long)(((unsigned long)((unsigned char)ps[3])<<24) |\ | 
|  | 30 | ((unsigned long)((unsigned char)ps[2])<<16) |\ | 
|  | 31 | ((unsigned long)((unsigned char)ps[1])<<8)  |\ | 
|  | 32 | ((unsigned long)((unsigned char)ps[0]))))) | 
|  | 33 |  | 
|  | 34 | /* Load a short int from the following tables with big-endian formats */ | 
|  | 35 | #define COFF_SHORT_H(ps) ((short)(((unsigned short)((unsigned char)ps[0])<<8)|\ | 
|  | 36 | ((unsigned short)((unsigned char)ps[1])))) | 
|  | 37 |  | 
|  | 38 | /* Load a long int from the following tables with big-endian formats */ | 
|  | 39 | #define COFF_LONG_H(ps) (((long)(((unsigned long)((unsigned char)ps[0])<<24) |\ | 
|  | 40 | ((unsigned long)((unsigned char)ps[1])<<16) |\ | 
|  | 41 | ((unsigned long)((unsigned char)ps[2])<<8)  |\ | 
|  | 42 | ((unsigned long)((unsigned char)ps[3]))))) | 
|  | 43 |  | 
|  | 44 | /* These may be overridden later by brain dead implementations which generate | 
|  | 45 | a big-endian header with little-endian data. In that case, generate a | 
|  | 46 | replacement macro which tests a flag and uses either of the two above | 
|  | 47 | as appropriate. */ | 
|  | 48 |  | 
|  | 49 | #define COFF_LONG(v)   COFF_LONG_L(v) | 
|  | 50 | #define COFF_SHORT(v)  COFF_SHORT_L(v) | 
|  | 51 |  | 
|  | 52 | /*** coff information for Intel 386/486.  */ | 
|  | 53 |  | 
|  | 54 | /********************** FILE HEADER **********************/ | 
|  | 55 |  | 
|  | 56 | struct COFF_filehdr { | 
|  | 57 | char f_magic[2];	/* magic number			*/ | 
|  | 58 | char f_nscns[2];	/* number of sections		*/ | 
|  | 59 | char f_timdat[4];	/* time & date stamp		*/ | 
|  | 60 | char f_symptr[4];	/* file pointer to symtab	*/ | 
|  | 61 | char f_nsyms[4];	/* number of symtab entries	*/ | 
|  | 62 | char f_opthdr[2];	/* sizeof(optional hdr)		*/ | 
|  | 63 | char f_flags[2];	/* flags			*/ | 
|  | 64 | }; | 
|  | 65 |  | 
|  | 66 | /* | 
|  | 67 | *   Bits for f_flags: | 
|  | 68 | * | 
|  | 69 | *	F_RELFLG	relocation info stripped from file | 
|  | 70 | *	F_EXEC		file is executable  (i.e. no unresolved external | 
|  | 71 | *			references) | 
|  | 72 | *	F_LNNO		line numbers stripped from file | 
|  | 73 | *	F_LSYMS		local symbols stripped from file | 
|  | 74 | *	F_MINMAL	this is a minimal object file (".m") output of fextract | 
|  | 75 | *	F_UPDATE	this is a fully bound update file, output of ogen | 
|  | 76 | *	F_SWABD		this file has had its bytes swabbed (in names) | 
|  | 77 | *	F_AR16WR	this file has the byte ordering of an AR16WR | 
|  | 78 | *			(e.g. 11/70) machine | 
|  | 79 | *	F_AR32WR	this file has the byte ordering of an AR32WR machine | 
|  | 80 | *			(e.g. vax and iNTEL 386) | 
|  | 81 | *	F_AR32W		this file has the byte ordering of an AR32W machine | 
|  | 82 | *			(e.g. 3b,maxi) | 
|  | 83 | *	F_PATCH		file contains "patch" list in optional header | 
|  | 84 | *	F_NODF		(minimal file only) no decision functions for | 
|  | 85 | *			replaced functions | 
|  | 86 | */ | 
|  | 87 |  | 
|  | 88 | #define  COFF_F_RELFLG		0000001 | 
|  | 89 | #define  COFF_F_EXEC		0000002 | 
|  | 90 | #define  COFF_F_LNNO		0000004 | 
|  | 91 | #define  COFF_F_LSYMS		0000010 | 
|  | 92 | #define  COFF_F_MINMAL		0000020 | 
|  | 93 | #define  COFF_F_UPDATE		0000040 | 
|  | 94 | #define  COFF_F_SWABD		0000100 | 
|  | 95 | #define  COFF_F_AR16WR		0000200 | 
|  | 96 | #define  COFF_F_AR32WR		0000400 | 
|  | 97 | #define  COFF_F_AR32W		0001000 | 
|  | 98 | #define  COFF_F_PATCH		0002000 | 
|  | 99 | #define  COFF_F_NODF		0002000 | 
|  | 100 |  | 
|  | 101 | #define	COFF_I386MAGIC	        0x14c   /* Linux's system    */ | 
|  | 102 |  | 
|  | 103 | #if 0   /* Perhaps, someday, these formats may be used.      */ | 
|  | 104 | #define COFF_I386PTXMAGIC	0x154 | 
|  | 105 | #define COFF_I386AIXMAGIC	0x175   /* IBM's AIX system  */ | 
|  | 106 | #define COFF_I386BADMAG(x) ((COFF_SHORT((x).f_magic) != COFF_I386MAGIC) \ | 
|  | 107 | && COFF_SHORT((x).f_magic) != COFF_I386PTXMAGIC \ | 
|  | 108 | && COFF_SHORT((x).f_magic) != COFF_I386AIXMAGIC) | 
|  | 109 | #else | 
|  | 110 | #define COFF_I386BADMAG(x) (COFF_SHORT((x).f_magic) != COFF_I386MAGIC) | 
|  | 111 | #endif | 
|  | 112 |  | 
|  | 113 | #define	COFF_FILHDR	struct COFF_filehdr | 
|  | 114 | #define	COFF_FILHSZ	sizeof(COFF_FILHDR) | 
|  | 115 |  | 
|  | 116 | /********************** AOUT "OPTIONAL HEADER" **********************/ | 
|  | 117 |  | 
|  | 118 | /* Linux COFF must have this "optional" header. Standard COFF has no entry | 
|  | 119 | location for the "entry" point. They normally would start with the first | 
|  | 120 | location of the .text section. This is not a good idea for linux. So, | 
|  | 121 | the use of this "optional" header is not optional. It is required. | 
|  | 122 |  | 
|  | 123 | Do not be tempted to assume that the size of the optional header is | 
|  | 124 | a constant and simply index the next byte by the size of this structure. | 
|  | 125 | Use the 'f_opthdr' field in the main coff header for the size of the | 
|  | 126 | structure actually written to the file!! | 
|  | 127 | */ | 
|  | 128 |  | 
|  | 129 | typedef struct | 
|  | 130 | { | 
|  | 131 | char 	magic[2];		/* type of file				 */ | 
|  | 132 | char	vstamp[2];		/* version stamp			 */ | 
|  | 133 | char	tsize[4];		/* text size in bytes, padded to FW bdry */ | 
|  | 134 | char	dsize[4];		/* initialized   data "   "		 */ | 
|  | 135 | char	bsize[4];		/* uninitialized data "   "		 */ | 
|  | 136 | char	entry[4];		/* entry pt.				 */ | 
|  | 137 | char 	text_start[4];		/* base of text used for this file       */ | 
|  | 138 | char 	data_start[4];		/* base of data used for this file       */ | 
|  | 139 | } | 
|  | 140 | COFF_AOUTHDR; | 
|  | 141 |  | 
|  | 142 | #define COFF_AOUTSZ (sizeof(COFF_AOUTHDR)) | 
|  | 143 |  | 
|  | 144 | #define COFF_STMAGIC	0401 | 
|  | 145 | #define COFF_OMAGIC     0404 | 
|  | 146 | #define COFF_JMAGIC     0407    /* dirty text and data image, can't share  */ | 
|  | 147 | #define COFF_DMAGIC     0410    /* dirty text segment, data aligned        */ | 
|  | 148 | #define COFF_ZMAGIC     0413    /* The proper magic number for executables  */ | 
|  | 149 | #define COFF_SHMAGIC	0443	/* shared library header                   */ | 
|  | 150 |  | 
|  | 151 | /********************** SECTION HEADER **********************/ | 
|  | 152 |  | 
|  | 153 | struct COFF_scnhdr { | 
|  | 154 | char		s_name[8];	/* section name			    */ | 
|  | 155 | char		s_paddr[4];	/* physical address, aliased s_nlib */ | 
|  | 156 | char		s_vaddr[4];	/* virtual address		    */ | 
|  | 157 | char		s_size[4];	/* section size			    */ | 
|  | 158 | char		s_scnptr[4];	/* file ptr to raw data for section */ | 
|  | 159 | char		s_relptr[4];	/* file ptr to relocation	    */ | 
|  | 160 | char		s_lnnoptr[4];	/* file ptr to line numbers	    */ | 
|  | 161 | char		s_nreloc[2];	/* number of relocation entries	    */ | 
|  | 162 | char		s_nlnno[2];	/* number of line number entries    */ | 
|  | 163 | char		s_flags[4];	/* flags			    */ | 
|  | 164 | }; | 
|  | 165 |  | 
|  | 166 | #define	COFF_SCNHDR	struct COFF_scnhdr | 
|  | 167 | #define	COFF_SCNHSZ	sizeof(COFF_SCNHDR) | 
|  | 168 |  | 
|  | 169 | /* | 
|  | 170 | * names of "special" sections | 
|  | 171 | */ | 
|  | 172 |  | 
|  | 173 | #define COFF_TEXT	".text" | 
|  | 174 | #define COFF_DATA	".data" | 
|  | 175 | #define COFF_BSS	".bss" | 
|  | 176 | #define COFF_COMMENT    ".comment" | 
|  | 177 | #define COFF_LIB        ".lib" | 
|  | 178 |  | 
|  | 179 | #define COFF_SECT_TEXT  0      /* Section for instruction code             */ | 
|  | 180 | #define COFF_SECT_DATA  1      /* Section for initialized globals          */ | 
|  | 181 | #define COFF_SECT_BSS   2      /* Section for un-initialized globals       */ | 
|  | 182 | #define COFF_SECT_REQD  3      /* Minimum number of sections for good file */ | 
|  | 183 |  | 
|  | 184 | #define COFF_STYP_REG     0x00 /* regular segment                          */ | 
|  | 185 | #define COFF_STYP_DSECT   0x01 /* dummy segment                            */ | 
|  | 186 | #define COFF_STYP_NOLOAD  0x02 /* no-load segment                          */ | 
|  | 187 | #define COFF_STYP_GROUP   0x04 /* group segment                            */ | 
|  | 188 | #define COFF_STYP_PAD     0x08 /* .pad segment                             */ | 
|  | 189 | #define COFF_STYP_COPY    0x10 /* copy section                             */ | 
|  | 190 | #define COFF_STYP_TEXT    0x20 /* .text segment                            */ | 
|  | 191 | #define COFF_STYP_DATA    0x40 /* .data segment                            */ | 
|  | 192 | #define COFF_STYP_BSS     0x80 /* .bss segment                             */ | 
|  | 193 | #define COFF_STYP_INFO   0x200 /* .comment section                         */ | 
|  | 194 | #define COFF_STYP_OVER   0x400 /* overlay section                          */ | 
|  | 195 | #define COFF_STYP_LIB    0x800 /* library section                          */ | 
|  | 196 |  | 
|  | 197 | /* | 
|  | 198 | * Shared libraries have the following section header in the data field for | 
|  | 199 | * each library. | 
|  | 200 | */ | 
|  | 201 |  | 
|  | 202 | struct COFF_slib { | 
|  | 203 | char		sl_entsz[4];	/* Size of this entry               */ | 
|  | 204 | char		sl_pathndx[4];	/* size of the header field         */ | 
|  | 205 | }; | 
|  | 206 |  | 
|  | 207 | #define	COFF_SLIBHD	struct COFF_slib | 
|  | 208 | #define	COFF_SLIBSZ	sizeof(COFF_SLIBHD) | 
|  | 209 |  | 
|  | 210 | /********************** LINE NUMBERS **********************/ | 
|  | 211 |  | 
|  | 212 | /* 1 line number entry for every "breakpointable" source line in a section. | 
|  | 213 | * Line numbers are grouped on a per function basis; first entry in a function | 
|  | 214 | * grouping will have l_lnno = 0 and in place of physical address will be the | 
|  | 215 | * symbol table index of the function name. | 
|  | 216 | */ | 
|  | 217 |  | 
|  | 218 | struct COFF_lineno { | 
|  | 219 | union { | 
|  | 220 | char l_symndx[4];	/* function name symbol index, iff l_lnno == 0*/ | 
|  | 221 | char l_paddr[4];	/* (physical) address of line number	*/ | 
|  | 222 | } l_addr; | 
|  | 223 | char l_lnno[2];	/* line number		*/ | 
|  | 224 | }; | 
|  | 225 |  | 
|  | 226 | #define	COFF_LINENO	struct COFF_lineno | 
|  | 227 | #define	COFF_LINESZ	6 | 
|  | 228 |  | 
|  | 229 | /********************** SYMBOLS **********************/ | 
|  | 230 |  | 
|  | 231 | #define COFF_E_SYMNMLEN	 8	/* # characters in a short symbol name	*/ | 
|  | 232 | #define COFF_E_FILNMLEN	14	/* # characters in a file name		*/ | 
|  | 233 | #define COFF_E_DIMNUM	 4	/* # array dimensions in auxiliary entry */ | 
|  | 234 |  | 
|  | 235 | /* | 
|  | 236 | *  All symbols and sections have the following definition | 
|  | 237 | */ | 
|  | 238 |  | 
|  | 239 | struct COFF_syment | 
|  | 240 | { | 
|  | 241 | union { | 
|  | 242 | char e_name[E_SYMNMLEN];    /* Symbol name (first 8 characters) */ | 
|  | 243 | struct { | 
|  | 244 | char e_zeroes[4];         /* Leading zeros */ | 
|  | 245 | char e_offset[4];         /* Offset if this is a header section */ | 
|  | 246 | } e; | 
|  | 247 | } e; | 
|  | 248 |  | 
|  | 249 | char e_value[4];              /* Value (address) of the segment */ | 
|  | 250 | char e_scnum[2];              /* Section number */ | 
|  | 251 | char e_type[2];               /* Type of section */ | 
|  | 252 | char e_sclass[1];             /* Loader class */ | 
|  | 253 | char e_numaux[1];             /* Number of auxiliary entries which follow */ | 
|  | 254 | }; | 
|  | 255 |  | 
|  | 256 | #define COFF_N_BTMASK	(0xf)   /* Mask for important class bits */ | 
|  | 257 | #define COFF_N_TMASK	(0x30)  /* Mask for important type bits  */ | 
|  | 258 | #define COFF_N_BTSHFT	(4)     /* # bits to shift class field   */ | 
|  | 259 | #define COFF_N_TSHIFT	(2)     /* # bits to shift type field    */ | 
|  | 260 |  | 
|  | 261 | /* | 
|  | 262 | *  Auxiliary entries because the main table is too limiting. | 
|  | 263 | */ | 
|  | 264 |  | 
|  | 265 | union COFF_auxent { | 
|  | 266 |  | 
|  | 267 | /* | 
|  | 268 | *  Debugger information | 
|  | 269 | */ | 
|  | 270 |  | 
|  | 271 | struct { | 
|  | 272 | char x_tagndx[4];	        /* str, un, or enum tag indx */ | 
|  | 273 | union { | 
|  | 274 | struct { | 
|  | 275 | char  x_lnno[2];        /* declaration line number */ | 
|  | 276 | char  x_size[2];        /* str/union/array size */ | 
|  | 277 | } x_lnsz; | 
|  | 278 | char x_fsize[4];	        /* size of function */ | 
|  | 279 | } x_misc; | 
|  | 280 |  | 
|  | 281 | union { | 
|  | 282 | struct {		        /* if ISFCN, tag, or .bb */ | 
|  | 283 | char x_lnnoptr[4];	/* ptr to fcn line # */ | 
|  | 284 | char x_endndx[4];	/* entry ndx past block end */ | 
|  | 285 | } x_fcn; | 
|  | 286 |  | 
|  | 287 | struct {		        /* if ISARY, up to 4 dimen. */ | 
|  | 288 | char x_dimen[E_DIMNUM][2]; | 
|  | 289 | } x_ary; | 
|  | 290 | } x_fcnary; | 
|  | 291 |  | 
|  | 292 | char x_tvndx[2];	/* tv index */ | 
|  | 293 | } x_sym; | 
|  | 294 |  | 
|  | 295 | /* | 
|  | 296 | *   Source file names (debugger information) | 
|  | 297 | */ | 
|  | 298 |  | 
|  | 299 | union { | 
|  | 300 | char x_fname[E_FILNMLEN]; | 
|  | 301 | struct { | 
|  | 302 | char x_zeroes[4]; | 
|  | 303 | char x_offset[4]; | 
|  | 304 | } x_n; | 
|  | 305 | } x_file; | 
|  | 306 |  | 
|  | 307 | /* | 
|  | 308 | *   Section information | 
|  | 309 | */ | 
|  | 310 |  | 
|  | 311 | struct { | 
|  | 312 | char x_scnlen[4];	/* section length */ | 
|  | 313 | char x_nreloc[2];	/* # relocation entries */ | 
|  | 314 | char x_nlinno[2];	/* # line numbers */ | 
|  | 315 | } x_scn; | 
|  | 316 |  | 
|  | 317 | /* | 
|  | 318 | *   Transfer vector (branch table) | 
|  | 319 | */ | 
|  | 320 |  | 
|  | 321 | struct { | 
|  | 322 | char x_tvfill[4];	/* tv fill value */ | 
|  | 323 | char x_tvlen[2];	/* length of .tv */ | 
|  | 324 | char x_tvran[2][2];	/* tv range */ | 
|  | 325 | } x_tv;		/* info about .tv section (in auxent of symbol .tv)) */ | 
|  | 326 | }; | 
|  | 327 |  | 
|  | 328 | #define	COFF_SYMENT	struct COFF_syment | 
|  | 329 | #define	COFF_SYMESZ	18 | 
|  | 330 | #define	COFF_AUXENT	union COFF_auxent | 
|  | 331 | #define	COFF_AUXESZ	18 | 
|  | 332 |  | 
|  | 333 | #define COFF_ETEXT	"etext" | 
|  | 334 |  | 
|  | 335 | /********************** RELOCATION DIRECTIVES **********************/ | 
|  | 336 |  | 
|  | 337 | struct COFF_reloc { | 
|  | 338 | char r_vaddr[4];        /* Virtual address of item    */ | 
|  | 339 | char r_symndx[4];       /* Symbol index in the symtab */ | 
|  | 340 | char r_type[2];         /* Relocation type            */ | 
|  | 341 | }; | 
|  | 342 |  | 
|  | 343 | #define COFF_RELOC struct COFF_reloc | 
|  | 344 | #define COFF_RELSZ 10 | 
|  | 345 |  | 
|  | 346 | #define COFF_DEF_DATA_SECTION_ALIGNMENT  4 | 
|  | 347 | #define COFF_DEF_BSS_SECTION_ALIGNMENT   4 | 
|  | 348 | #define COFF_DEF_TEXT_SECTION_ALIGNMENT  4 | 
|  | 349 |  | 
|  | 350 | /* For new sections we haven't heard of before */ | 
|  | 351 | #define COFF_DEF_SECTION_ALIGNMENT       4 |