1e2be04c7SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2607ca46eSDavid Howells /* This file is derived from the GAS 2.1.4 assembler control file. 3607ca46eSDavid Howells The GAS product is under the GNU General Public License, version 2 or later. 4607ca46eSDavid Howells As such, this file is also under that license. 5607ca46eSDavid Howells 6607ca46eSDavid Howells If the file format changes in the COFF object, this file should be 7607ca46eSDavid Howells subsequently updated to reflect the changes. 8607ca46eSDavid Howells 9607ca46eSDavid Howells The actual loader module only uses a few of these structures. The full 10607ca46eSDavid Howells set is documented here because I received the full set. If you wish 11607ca46eSDavid Howells more information about COFF, then O'Reilly has a very excellent book. 12607ca46eSDavid Howells */ 13607ca46eSDavid Howells 14*541be050SMasahiro Yamada #ifndef _UAPI_LINUX_COFF_H 15*541be050SMasahiro Yamada #define _UAPI_LINUX_COFF_H 16*541be050SMasahiro Yamada 17607ca46eSDavid Howells #define E_SYMNMLEN 8 /* Number of characters in a symbol name */ 18607ca46eSDavid Howells #define E_FILNMLEN 14 /* Number of characters in a file name */ 19607ca46eSDavid Howells #define E_DIMNUM 4 /* Number of array dimensions in auxiliary entry */ 20607ca46eSDavid Howells 21607ca46eSDavid Howells /* 22607ca46eSDavid Howells * These defines are byte order independent. There is no alignment of fields 23607ca46eSDavid Howells * permitted in the structures. Therefore they are declared as characters 24607ca46eSDavid Howells * and the values loaded from the character positions. It also makes it 25607ca46eSDavid Howells * nice to have it "endian" independent. 26607ca46eSDavid Howells */ 27607ca46eSDavid Howells 28607ca46eSDavid Howells /* Load a short int from the following tables with little-endian formats */ 29607ca46eSDavid Howells #define COFF_SHORT_L(ps) ((short)(((unsigned short)((unsigned char)ps[1])<<8)|\ 30607ca46eSDavid Howells ((unsigned short)((unsigned char)ps[0])))) 31607ca46eSDavid Howells 32607ca46eSDavid Howells /* Load a long int from the following tables with little-endian formats */ 33607ca46eSDavid Howells #define COFF_LONG_L(ps) (((long)(((unsigned long)((unsigned char)ps[3])<<24) |\ 34607ca46eSDavid Howells ((unsigned long)((unsigned char)ps[2])<<16) |\ 35607ca46eSDavid Howells ((unsigned long)((unsigned char)ps[1])<<8) |\ 36607ca46eSDavid Howells ((unsigned long)((unsigned char)ps[0]))))) 37607ca46eSDavid Howells 38607ca46eSDavid Howells /* Load a short int from the following tables with big-endian formats */ 39607ca46eSDavid Howells #define COFF_SHORT_H(ps) ((short)(((unsigned short)((unsigned char)ps[0])<<8)|\ 40607ca46eSDavid Howells ((unsigned short)((unsigned char)ps[1])))) 41607ca46eSDavid Howells 42607ca46eSDavid Howells /* Load a long int from the following tables with big-endian formats */ 43607ca46eSDavid Howells #define COFF_LONG_H(ps) (((long)(((unsigned long)((unsigned char)ps[0])<<24) |\ 44607ca46eSDavid Howells ((unsigned long)((unsigned char)ps[1])<<16) |\ 45607ca46eSDavid Howells ((unsigned long)((unsigned char)ps[2])<<8) |\ 46607ca46eSDavid Howells ((unsigned long)((unsigned char)ps[3]))))) 47607ca46eSDavid Howells 48607ca46eSDavid Howells /* These may be overridden later by brain dead implementations which generate 49607ca46eSDavid Howells a big-endian header with little-endian data. In that case, generate a 50607ca46eSDavid Howells replacement macro which tests a flag and uses either of the two above 51607ca46eSDavid Howells as appropriate. */ 52607ca46eSDavid Howells 53607ca46eSDavid Howells #define COFF_LONG(v) COFF_LONG_L(v) 54607ca46eSDavid Howells #define COFF_SHORT(v) COFF_SHORT_L(v) 55607ca46eSDavid Howells 56607ca46eSDavid Howells /*** coff information for Intel 386/486. */ 57607ca46eSDavid Howells 58607ca46eSDavid Howells /********************** FILE HEADER **********************/ 59607ca46eSDavid Howells 60607ca46eSDavid Howells struct COFF_filehdr { 61607ca46eSDavid Howells char f_magic[2]; /* magic number */ 62607ca46eSDavid Howells char f_nscns[2]; /* number of sections */ 63607ca46eSDavid Howells char f_timdat[4]; /* time & date stamp */ 64607ca46eSDavid Howells char f_symptr[4]; /* file pointer to symtab */ 65607ca46eSDavid Howells char f_nsyms[4]; /* number of symtab entries */ 66607ca46eSDavid Howells char f_opthdr[2]; /* sizeof(optional hdr) */ 67607ca46eSDavid Howells char f_flags[2]; /* flags */ 68607ca46eSDavid Howells }; 69607ca46eSDavid Howells 70607ca46eSDavid Howells /* 71607ca46eSDavid Howells * Bits for f_flags: 72607ca46eSDavid Howells * 73607ca46eSDavid Howells * F_RELFLG relocation info stripped from file 74607ca46eSDavid Howells * F_EXEC file is executable (i.e. no unresolved external 75607ca46eSDavid Howells * references) 76607ca46eSDavid Howells * F_LNNO line numbers stripped from file 77607ca46eSDavid Howells * F_LSYMS local symbols stripped from file 78607ca46eSDavid Howells * F_MINMAL this is a minimal object file (".m") output of fextract 79607ca46eSDavid Howells * F_UPDATE this is a fully bound update file, output of ogen 80607ca46eSDavid Howells * F_SWABD this file has had its bytes swabbed (in names) 81607ca46eSDavid Howells * F_AR16WR this file has the byte ordering of an AR16WR 82607ca46eSDavid Howells * (e.g. 11/70) machine 83607ca46eSDavid Howells * F_AR32WR this file has the byte ordering of an AR32WR machine 84607ca46eSDavid Howells * (e.g. vax and iNTEL 386) 85607ca46eSDavid Howells * F_AR32W this file has the byte ordering of an AR32W machine 86607ca46eSDavid Howells * (e.g. 3b,maxi) 87607ca46eSDavid Howells * F_PATCH file contains "patch" list in optional header 88607ca46eSDavid Howells * F_NODF (minimal file only) no decision functions for 89607ca46eSDavid Howells * replaced functions 90607ca46eSDavid Howells */ 91607ca46eSDavid Howells 92607ca46eSDavid Howells #define COFF_F_RELFLG 0000001 93607ca46eSDavid Howells #define COFF_F_EXEC 0000002 94607ca46eSDavid Howells #define COFF_F_LNNO 0000004 95607ca46eSDavid Howells #define COFF_F_LSYMS 0000010 96607ca46eSDavid Howells #define COFF_F_MINMAL 0000020 97607ca46eSDavid Howells #define COFF_F_UPDATE 0000040 98607ca46eSDavid Howells #define COFF_F_SWABD 0000100 99607ca46eSDavid Howells #define COFF_F_AR16WR 0000200 100607ca46eSDavid Howells #define COFF_F_AR32WR 0000400 101607ca46eSDavid Howells #define COFF_F_AR32W 0001000 102607ca46eSDavid Howells #define COFF_F_PATCH 0002000 103607ca46eSDavid Howells #define COFF_F_NODF 0002000 104607ca46eSDavid Howells 105607ca46eSDavid Howells #define COFF_I386MAGIC 0x14c /* Linux's system */ 106607ca46eSDavid Howells 107607ca46eSDavid Howells #if 0 /* Perhaps, someday, these formats may be used. */ 108607ca46eSDavid Howells #define COFF_I386PTXMAGIC 0x154 109607ca46eSDavid Howells #define COFF_I386AIXMAGIC 0x175 /* IBM's AIX system */ 110607ca46eSDavid Howells #define COFF_I386BADMAG(x) ((COFF_SHORT((x).f_magic) != COFF_I386MAGIC) \ 111607ca46eSDavid Howells && COFF_SHORT((x).f_magic) != COFF_I386PTXMAGIC \ 112607ca46eSDavid Howells && COFF_SHORT((x).f_magic) != COFF_I386AIXMAGIC) 113607ca46eSDavid Howells #else 114607ca46eSDavid Howells #define COFF_I386BADMAG(x) (COFF_SHORT((x).f_magic) != COFF_I386MAGIC) 115607ca46eSDavid Howells #endif 116607ca46eSDavid Howells 117607ca46eSDavid Howells #define COFF_FILHDR struct COFF_filehdr 118607ca46eSDavid Howells #define COFF_FILHSZ sizeof(COFF_FILHDR) 119607ca46eSDavid Howells 120607ca46eSDavid Howells /********************** AOUT "OPTIONAL HEADER" **********************/ 121607ca46eSDavid Howells 122607ca46eSDavid Howells /* Linux COFF must have this "optional" header. Standard COFF has no entry 123607ca46eSDavid Howells location for the "entry" point. They normally would start with the first 124607ca46eSDavid Howells location of the .text section. This is not a good idea for linux. So, 125607ca46eSDavid Howells the use of this "optional" header is not optional. It is required. 126607ca46eSDavid Howells 127607ca46eSDavid Howells Do not be tempted to assume that the size of the optional header is 128607ca46eSDavid Howells a constant and simply index the next byte by the size of this structure. 129607ca46eSDavid Howells Use the 'f_opthdr' field in the main coff header for the size of the 130607ca46eSDavid Howells structure actually written to the file!! 131607ca46eSDavid Howells */ 132607ca46eSDavid Howells 133607ca46eSDavid Howells typedef struct 134607ca46eSDavid Howells { 135607ca46eSDavid Howells char magic[2]; /* type of file */ 136607ca46eSDavid Howells char vstamp[2]; /* version stamp */ 137607ca46eSDavid Howells char tsize[4]; /* text size in bytes, padded to FW bdry */ 138607ca46eSDavid Howells char dsize[4]; /* initialized data " " */ 139607ca46eSDavid Howells char bsize[4]; /* uninitialized data " " */ 140607ca46eSDavid Howells char entry[4]; /* entry pt. */ 141607ca46eSDavid Howells char text_start[4]; /* base of text used for this file */ 142607ca46eSDavid Howells char data_start[4]; /* base of data used for this file */ 143607ca46eSDavid Howells } 144607ca46eSDavid Howells COFF_AOUTHDR; 145607ca46eSDavid Howells 146607ca46eSDavid Howells #define COFF_AOUTSZ (sizeof(COFF_AOUTHDR)) 147607ca46eSDavid Howells 148607ca46eSDavid Howells #define COFF_STMAGIC 0401 149607ca46eSDavid Howells #define COFF_OMAGIC 0404 150607ca46eSDavid Howells #define COFF_JMAGIC 0407 /* dirty text and data image, can't share */ 151607ca46eSDavid Howells #define COFF_DMAGIC 0410 /* dirty text segment, data aligned */ 152607ca46eSDavid Howells #define COFF_ZMAGIC 0413 /* The proper magic number for executables */ 153607ca46eSDavid Howells #define COFF_SHMAGIC 0443 /* shared library header */ 154607ca46eSDavid Howells 155607ca46eSDavid Howells /********************** SECTION HEADER **********************/ 156607ca46eSDavid Howells 157607ca46eSDavid Howells struct COFF_scnhdr { 158607ca46eSDavid Howells char s_name[8]; /* section name */ 159607ca46eSDavid Howells char s_paddr[4]; /* physical address, aliased s_nlib */ 160607ca46eSDavid Howells char s_vaddr[4]; /* virtual address */ 161607ca46eSDavid Howells char s_size[4]; /* section size */ 162607ca46eSDavid Howells char s_scnptr[4]; /* file ptr to raw data for section */ 163607ca46eSDavid Howells char s_relptr[4]; /* file ptr to relocation */ 164607ca46eSDavid Howells char s_lnnoptr[4]; /* file ptr to line numbers */ 165607ca46eSDavid Howells char s_nreloc[2]; /* number of relocation entries */ 166607ca46eSDavid Howells char s_nlnno[2]; /* number of line number entries */ 167607ca46eSDavid Howells char s_flags[4]; /* flags */ 168607ca46eSDavid Howells }; 169607ca46eSDavid Howells 170607ca46eSDavid Howells #define COFF_SCNHDR struct COFF_scnhdr 171607ca46eSDavid Howells #define COFF_SCNHSZ sizeof(COFF_SCNHDR) 172607ca46eSDavid Howells 173607ca46eSDavid Howells /* 174607ca46eSDavid Howells * names of "special" sections 175607ca46eSDavid Howells */ 176607ca46eSDavid Howells 177607ca46eSDavid Howells #define COFF_TEXT ".text" 178607ca46eSDavid Howells #define COFF_DATA ".data" 179607ca46eSDavid Howells #define COFF_BSS ".bss" 180607ca46eSDavid Howells #define COFF_COMMENT ".comment" 181607ca46eSDavid Howells #define COFF_LIB ".lib" 182607ca46eSDavid Howells 183607ca46eSDavid Howells #define COFF_SECT_TEXT 0 /* Section for instruction code */ 184607ca46eSDavid Howells #define COFF_SECT_DATA 1 /* Section for initialized globals */ 185607ca46eSDavid Howells #define COFF_SECT_BSS 2 /* Section for un-initialized globals */ 186607ca46eSDavid Howells #define COFF_SECT_REQD 3 /* Minimum number of sections for good file */ 187607ca46eSDavid Howells 188607ca46eSDavid Howells #define COFF_STYP_REG 0x00 /* regular segment */ 189607ca46eSDavid Howells #define COFF_STYP_DSECT 0x01 /* dummy segment */ 190607ca46eSDavid Howells #define COFF_STYP_NOLOAD 0x02 /* no-load segment */ 191607ca46eSDavid Howells #define COFF_STYP_GROUP 0x04 /* group segment */ 192607ca46eSDavid Howells #define COFF_STYP_PAD 0x08 /* .pad segment */ 193607ca46eSDavid Howells #define COFF_STYP_COPY 0x10 /* copy section */ 194607ca46eSDavid Howells #define COFF_STYP_TEXT 0x20 /* .text segment */ 195607ca46eSDavid Howells #define COFF_STYP_DATA 0x40 /* .data segment */ 196607ca46eSDavid Howells #define COFF_STYP_BSS 0x80 /* .bss segment */ 197607ca46eSDavid Howells #define COFF_STYP_INFO 0x200 /* .comment section */ 198607ca46eSDavid Howells #define COFF_STYP_OVER 0x400 /* overlay section */ 199607ca46eSDavid Howells #define COFF_STYP_LIB 0x800 /* library section */ 200607ca46eSDavid Howells 201607ca46eSDavid Howells /* 202607ca46eSDavid Howells * Shared libraries have the following section header in the data field for 203607ca46eSDavid Howells * each library. 204607ca46eSDavid Howells */ 205607ca46eSDavid Howells 206607ca46eSDavid Howells struct COFF_slib { 207607ca46eSDavid Howells char sl_entsz[4]; /* Size of this entry */ 208607ca46eSDavid Howells char sl_pathndx[4]; /* size of the header field */ 209607ca46eSDavid Howells }; 210607ca46eSDavid Howells 211607ca46eSDavid Howells #define COFF_SLIBHD struct COFF_slib 212607ca46eSDavid Howells #define COFF_SLIBSZ sizeof(COFF_SLIBHD) 213607ca46eSDavid Howells 214607ca46eSDavid Howells /********************** LINE NUMBERS **********************/ 215607ca46eSDavid Howells 216607ca46eSDavid Howells /* 1 line number entry for every "breakpointable" source line in a section. 217607ca46eSDavid Howells * Line numbers are grouped on a per function basis; first entry in a function 218607ca46eSDavid Howells * grouping will have l_lnno = 0 and in place of physical address will be the 219607ca46eSDavid Howells * symbol table index of the function name. 220607ca46eSDavid Howells */ 221607ca46eSDavid Howells 222607ca46eSDavid Howells struct COFF_lineno { 223607ca46eSDavid Howells union { 224607ca46eSDavid Howells char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ 225607ca46eSDavid Howells char l_paddr[4]; /* (physical) address of line number */ 226607ca46eSDavid Howells } l_addr; 227607ca46eSDavid Howells char l_lnno[2]; /* line number */ 228607ca46eSDavid Howells }; 229607ca46eSDavid Howells 230607ca46eSDavid Howells #define COFF_LINENO struct COFF_lineno 231607ca46eSDavid Howells #define COFF_LINESZ 6 232607ca46eSDavid Howells 233607ca46eSDavid Howells /********************** SYMBOLS **********************/ 234607ca46eSDavid Howells 235607ca46eSDavid Howells #define COFF_E_SYMNMLEN 8 /* # characters in a short symbol name */ 236607ca46eSDavid Howells #define COFF_E_FILNMLEN 14 /* # characters in a file name */ 237607ca46eSDavid Howells #define COFF_E_DIMNUM 4 /* # array dimensions in auxiliary entry */ 238607ca46eSDavid Howells 239607ca46eSDavid Howells /* 240607ca46eSDavid Howells * All symbols and sections have the following definition 241607ca46eSDavid Howells */ 242607ca46eSDavid Howells 243607ca46eSDavid Howells struct COFF_syment 244607ca46eSDavid Howells { 245607ca46eSDavid Howells union { 246607ca46eSDavid Howells char e_name[E_SYMNMLEN]; /* Symbol name (first 8 characters) */ 247607ca46eSDavid Howells struct { 248607ca46eSDavid Howells char e_zeroes[4]; /* Leading zeros */ 249607ca46eSDavid Howells char e_offset[4]; /* Offset if this is a header section */ 250607ca46eSDavid Howells } e; 251607ca46eSDavid Howells } e; 252607ca46eSDavid Howells 253607ca46eSDavid Howells char e_value[4]; /* Value (address) of the segment */ 254607ca46eSDavid Howells char e_scnum[2]; /* Section number */ 255607ca46eSDavid Howells char e_type[2]; /* Type of section */ 256607ca46eSDavid Howells char e_sclass[1]; /* Loader class */ 257607ca46eSDavid Howells char e_numaux[1]; /* Number of auxiliary entries which follow */ 258607ca46eSDavid Howells }; 259607ca46eSDavid Howells 260607ca46eSDavid Howells #define COFF_N_BTMASK (0xf) /* Mask for important class bits */ 261607ca46eSDavid Howells #define COFF_N_TMASK (0x30) /* Mask for important type bits */ 262607ca46eSDavid Howells #define COFF_N_BTSHFT (4) /* # bits to shift class field */ 263607ca46eSDavid Howells #define COFF_N_TSHIFT (2) /* # bits to shift type field */ 264607ca46eSDavid Howells 265607ca46eSDavid Howells /* 266607ca46eSDavid Howells * Auxiliary entries because the main table is too limiting. 267607ca46eSDavid Howells */ 268607ca46eSDavid Howells 269607ca46eSDavid Howells union COFF_auxent { 270607ca46eSDavid Howells 271607ca46eSDavid Howells /* 272607ca46eSDavid Howells * Debugger information 273607ca46eSDavid Howells */ 274607ca46eSDavid Howells 275607ca46eSDavid Howells struct { 276607ca46eSDavid Howells char x_tagndx[4]; /* str, un, or enum tag indx */ 277607ca46eSDavid Howells union { 278607ca46eSDavid Howells struct { 279607ca46eSDavid Howells char x_lnno[2]; /* declaration line number */ 280607ca46eSDavid Howells char x_size[2]; /* str/union/array size */ 281607ca46eSDavid Howells } x_lnsz; 282607ca46eSDavid Howells char x_fsize[4]; /* size of function */ 283607ca46eSDavid Howells } x_misc; 284607ca46eSDavid Howells 285607ca46eSDavid Howells union { 286607ca46eSDavid Howells struct { /* if ISFCN, tag, or .bb */ 287607ca46eSDavid Howells char x_lnnoptr[4]; /* ptr to fcn line # */ 288607ca46eSDavid Howells char x_endndx[4]; /* entry ndx past block end */ 289607ca46eSDavid Howells } x_fcn; 290607ca46eSDavid Howells 291607ca46eSDavid Howells struct { /* if ISARY, up to 4 dimen. */ 292607ca46eSDavid Howells char x_dimen[E_DIMNUM][2]; 293607ca46eSDavid Howells } x_ary; 294607ca46eSDavid Howells } x_fcnary; 295607ca46eSDavid Howells 296607ca46eSDavid Howells char x_tvndx[2]; /* tv index */ 297607ca46eSDavid Howells } x_sym; 298607ca46eSDavid Howells 299607ca46eSDavid Howells /* 300607ca46eSDavid Howells * Source file names (debugger information) 301607ca46eSDavid Howells */ 302607ca46eSDavid Howells 303607ca46eSDavid Howells union { 304607ca46eSDavid Howells char x_fname[E_FILNMLEN]; 305607ca46eSDavid Howells struct { 306607ca46eSDavid Howells char x_zeroes[4]; 307607ca46eSDavid Howells char x_offset[4]; 308607ca46eSDavid Howells } x_n; 309607ca46eSDavid Howells } x_file; 310607ca46eSDavid Howells 311607ca46eSDavid Howells /* 312607ca46eSDavid Howells * Section information 313607ca46eSDavid Howells */ 314607ca46eSDavid Howells 315607ca46eSDavid Howells struct { 316607ca46eSDavid Howells char x_scnlen[4]; /* section length */ 317607ca46eSDavid Howells char x_nreloc[2]; /* # relocation entries */ 318607ca46eSDavid Howells char x_nlinno[2]; /* # line numbers */ 319607ca46eSDavid Howells } x_scn; 320607ca46eSDavid Howells 321607ca46eSDavid Howells /* 322607ca46eSDavid Howells * Transfer vector (branch table) 323607ca46eSDavid Howells */ 324607ca46eSDavid Howells 325607ca46eSDavid Howells struct { 326607ca46eSDavid Howells char x_tvfill[4]; /* tv fill value */ 327607ca46eSDavid Howells char x_tvlen[2]; /* length of .tv */ 328607ca46eSDavid Howells char x_tvran[2][2]; /* tv range */ 329607ca46eSDavid Howells } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ 330607ca46eSDavid Howells }; 331607ca46eSDavid Howells 332607ca46eSDavid Howells #define COFF_SYMENT struct COFF_syment 333607ca46eSDavid Howells #define COFF_SYMESZ 18 334607ca46eSDavid Howells #define COFF_AUXENT union COFF_auxent 335607ca46eSDavid Howells #define COFF_AUXESZ 18 336607ca46eSDavid Howells 337607ca46eSDavid Howells #define COFF_ETEXT "etext" 338607ca46eSDavid Howells 339607ca46eSDavid Howells /********************** RELOCATION DIRECTIVES **********************/ 340607ca46eSDavid Howells 341607ca46eSDavid Howells struct COFF_reloc { 342607ca46eSDavid Howells char r_vaddr[4]; /* Virtual address of item */ 343607ca46eSDavid Howells char r_symndx[4]; /* Symbol index in the symtab */ 344607ca46eSDavid Howells char r_type[2]; /* Relocation type */ 345607ca46eSDavid Howells }; 346607ca46eSDavid Howells 347607ca46eSDavid Howells #define COFF_RELOC struct COFF_reloc 348607ca46eSDavid Howells #define COFF_RELSZ 10 349607ca46eSDavid Howells 350607ca46eSDavid Howells #define COFF_DEF_DATA_SECTION_ALIGNMENT 4 351607ca46eSDavid Howells #define COFF_DEF_BSS_SECTION_ALIGNMENT 4 352607ca46eSDavid Howells #define COFF_DEF_TEXT_SECTION_ALIGNMENT 4 353607ca46eSDavid Howells 354607ca46eSDavid Howells /* For new sections we haven't heard of before */ 355607ca46eSDavid Howells #define COFF_DEF_SECTION_ALIGNMENT 4 356*541be050SMasahiro Yamada 357*541be050SMasahiro Yamada #endif /* _UAPI_LINUX_COFF_H */ 358