1*3d8817e4Smiod /* `a.out.adobe' differences from standard a.out files 2*3d8817e4Smiod 3*3d8817e4Smiod Copyright 2001 Free Software Foundation, Inc. 4*3d8817e4Smiod 5*3d8817e4Smiod This program is free software; you can redistribute it and/or modify 6*3d8817e4Smiod it under the terms of the GNU General Public License as published by 7*3d8817e4Smiod the Free Software Foundation; either version 2 of the License, or 8*3d8817e4Smiod (at your option) any later version. 9*3d8817e4Smiod 10*3d8817e4Smiod This program is distributed in the hope that it will be useful, 11*3d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of 12*3d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13*3d8817e4Smiod GNU General Public License for more details. 14*3d8817e4Smiod 15*3d8817e4Smiod You should have received a copy of the GNU General Public License 16*3d8817e4Smiod along with this program; if not, write to the Free Software 17*3d8817e4Smiod Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 18*3d8817e4Smiod 19*3d8817e4Smiod #ifndef __A_OUT_ADOBE_H__ 20*3d8817e4Smiod #define __A_OUT_ADOBE_H__ 21*3d8817e4Smiod 22*3d8817e4Smiod #define BYTES_IN_WORD 4 23*3d8817e4Smiod 24*3d8817e4Smiod /* Struct external_exec is the same. */ 25*3d8817e4Smiod 26*3d8817e4Smiod /* This is the layout on disk of the 32-bit or 64-bit exec header. */ 27*3d8817e4Smiod 28*3d8817e4Smiod struct external_exec 29*3d8817e4Smiod { 30*3d8817e4Smiod bfd_byte e_info[4]; /* magic number and stuff */ 31*3d8817e4Smiod bfd_byte e_text[BYTES_IN_WORD]; /* length of text section in bytes */ 32*3d8817e4Smiod bfd_byte e_data[BYTES_IN_WORD]; /* length of data section in bytes */ 33*3d8817e4Smiod bfd_byte e_bss[BYTES_IN_WORD]; /* length of bss area in bytes */ 34*3d8817e4Smiod bfd_byte e_syms[BYTES_IN_WORD]; /* length of symbol table in bytes */ 35*3d8817e4Smiod bfd_byte e_entry[BYTES_IN_WORD]; /* start address */ 36*3d8817e4Smiod bfd_byte e_trsize[BYTES_IN_WORD]; /* length of text relocation info */ 37*3d8817e4Smiod bfd_byte e_drsize[BYTES_IN_WORD]; /* length of data relocation info */ 38*3d8817e4Smiod }; 39*3d8817e4Smiod 40*3d8817e4Smiod #define EXEC_BYTES_SIZE (4 + BYTES_IN_WORD * 7) 41*3d8817e4Smiod 42*3d8817e4Smiod /* Magic numbers for a.out files */ 43*3d8817e4Smiod 44*3d8817e4Smiod #undef ZMAGIC 45*3d8817e4Smiod #define ZMAGIC 0xAD0BE /* Cute, eh? */ 46*3d8817e4Smiod #undef OMAGIC 47*3d8817e4Smiod #undef NMAGIC 48*3d8817e4Smiod 49*3d8817e4Smiod #define N_BADMAG(x) ((x).a_info != ZMAGIC) 50*3d8817e4Smiod 51*3d8817e4Smiod /* By default, segment size is constant. But some machines override this 52*3d8817e4Smiod to be a function of the a.out header (e.g. machine type). */ 53*3d8817e4Smiod #ifndef N_SEGSIZE 54*3d8817e4Smiod #define N_SEGSIZE(x) SEGMENT_SIZE 55*3d8817e4Smiod #endif 56*3d8817e4Smiod #undef N_SEGSIZE /* FIXMEXXXX */ 57*3d8817e4Smiod 58*3d8817e4Smiod /* Segment information for the a.out.Adobe format is specified after the 59*3d8817e4Smiod file header. It contains N segment descriptors, followed by one with 60*3d8817e4Smiod a type of zero. 61*3d8817e4Smiod 62*3d8817e4Smiod The actual text of the segments starts at N_TXTOFF in the file, 63*3d8817e4Smiod regardless of how many or how few segment headers there are. */ 64*3d8817e4Smiod 65*3d8817e4Smiod struct external_segdesc { 66*3d8817e4Smiod unsigned char e_type[1]; 67*3d8817e4Smiod unsigned char e_size[3]; 68*3d8817e4Smiod unsigned char e_virtbase[4]; 69*3d8817e4Smiod unsigned char e_filebase[4]; 70*3d8817e4Smiod }; 71*3d8817e4Smiod 72*3d8817e4Smiod struct internal_segdesc { 73*3d8817e4Smiod unsigned int a_type:8; /* Segment type N_TEXT, N_DATA, 0 */ 74*3d8817e4Smiod unsigned int a_size:24; /* Segment size */ 75*3d8817e4Smiod bfd_vma a_virtbase; /* Virtual address */ 76*3d8817e4Smiod unsigned int a_filebase; /* Base address in object file */ 77*3d8817e4Smiod }; 78*3d8817e4Smiod 79*3d8817e4Smiod #define N_TXTADDR(x) \ 80*3d8817e4Smiod 81*3d8817e4Smiod /* This is documented to be at 1024, but appears to really be at 2048. 82*3d8817e4Smiod FIXME?! */ 83*3d8817e4Smiod #define N_TXTOFF(x) 2048 84*3d8817e4Smiod 85*3d8817e4Smiod #define N_TXTSIZE(x) ((x).a_text) 86*3d8817e4Smiod 87*3d8817e4Smiod #define N_DATADDR(x) 88*3d8817e4Smiod 89*3d8817e4Smiod #define N_BSSADDR(x) 90*3d8817e4Smiod 91*3d8817e4Smiod /* Offsets of the various portions of the file after the text segment. */ 92*3d8817e4Smiod 93*3d8817e4Smiod #define N_DATOFF(x) ( N_TXTOFF(x) + N_TXTSIZE(x) ) 94*3d8817e4Smiod #define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data ) 95*3d8817e4Smiod #define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize ) 96*3d8817e4Smiod #define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize ) 97*3d8817e4Smiod #define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms ) 98*3d8817e4Smiod 99*3d8817e4Smiod /* Symbols */ 100*3d8817e4Smiod struct external_nlist { 101*3d8817e4Smiod bfd_byte e_strx[BYTES_IN_WORD]; /* index into string table of name */ 102*3d8817e4Smiod bfd_byte e_type[1]; /* type of symbol */ 103*3d8817e4Smiod bfd_byte e_other[1]; /* misc info (usually empty) */ 104*3d8817e4Smiod bfd_byte e_desc[2]; /* description field */ 105*3d8817e4Smiod bfd_byte e_value[BYTES_IN_WORD]; /* value of symbol */ 106*3d8817e4Smiod }; 107*3d8817e4Smiod 108*3d8817e4Smiod #define EXTERNAL_NLIST_SIZE (BYTES_IN_WORD+4+BYTES_IN_WORD) 109*3d8817e4Smiod 110*3d8817e4Smiod struct internal_nlist { 111*3d8817e4Smiod unsigned long n_strx; /* index into string table of name */ 112*3d8817e4Smiod unsigned char n_type; /* type of symbol */ 113*3d8817e4Smiod unsigned char n_other; /* misc info (usually empty) */ 114*3d8817e4Smiod unsigned short n_desc; /* description field */ 115*3d8817e4Smiod bfd_vma n_value; /* value of symbol */ 116*3d8817e4Smiod }; 117*3d8817e4Smiod 118*3d8817e4Smiod /* The n_type field is the symbol type, containing: */ 119*3d8817e4Smiod 120*3d8817e4Smiod #define N_UNDF 0 /* Undefined symbol */ 121*3d8817e4Smiod #define N_ABS 2 /* Absolute symbol -- defined at particular addr */ 122*3d8817e4Smiod #define N_TEXT 4 /* Text sym -- defined at offset in text seg */ 123*3d8817e4Smiod #define N_DATA 6 /* Data sym -- defined at offset in data seg */ 124*3d8817e4Smiod #define N_BSS 8 /* BSS sym -- defined at offset in zero'd seg */ 125*3d8817e4Smiod #define N_COMM 0x12 /* Common symbol (visible after shared lib dynlink) */ 126*3d8817e4Smiod #define N_FN 0x1f /* File name of .o file */ 127*3d8817e4Smiod #define N_FN_SEQ 0x0C /* N_FN from Sequent compilers (sigh) */ 128*3d8817e4Smiod /* Note: N_EXT can only be usefully OR-ed with N_UNDF, N_ABS, N_TEXT, 129*3d8817e4Smiod N_DATA, or N_BSS. When the low-order bit of other types is set, 130*3d8817e4Smiod (e.g. N_WARNING versus N_FN), they are two different types. */ 131*3d8817e4Smiod #define N_EXT 1 /* External symbol (as opposed to local-to-this-file) */ 132*3d8817e4Smiod #define N_TYPE 0x1e 133*3d8817e4Smiod #define N_STAB 0xe0 /* If any of these bits are on, it's a debug symbol */ 134*3d8817e4Smiod 135*3d8817e4Smiod #define N_INDR 0x0a 136*3d8817e4Smiod 137*3d8817e4Smiod /* The following symbols refer to set elements. 138*3d8817e4Smiod All the N_SET[ATDB] symbols with the same name form one set. 139*3d8817e4Smiod Space is allocated for the set in the text section, and each set 140*3d8817e4Smiod elements value is stored into one word of the space. 141*3d8817e4Smiod The first word of the space is the length of the set (number of elements). 142*3d8817e4Smiod 143*3d8817e4Smiod The address of the set is made into an N_SETV symbol 144*3d8817e4Smiod whose name is the same as the name of the set. 145*3d8817e4Smiod This symbol acts like a N_DATA global symbol 146*3d8817e4Smiod in that it can satisfy undefined external references. */ 147*3d8817e4Smiod 148*3d8817e4Smiod /* These appear as input to LD, in a .o file. */ 149*3d8817e4Smiod #define N_SETA 0x14 /* Absolute set element symbol */ 150*3d8817e4Smiod #define N_SETT 0x16 /* Text set element symbol */ 151*3d8817e4Smiod #define N_SETD 0x18 /* Data set element symbol */ 152*3d8817e4Smiod #define N_SETB 0x1A /* Bss set element symbol */ 153*3d8817e4Smiod 154*3d8817e4Smiod /* This is output from LD. */ 155*3d8817e4Smiod #define N_SETV 0x1C /* Pointer to set vector in data area. */ 156*3d8817e4Smiod 157*3d8817e4Smiod /* Warning symbol. The text gives a warning message, the next symbol 158*3d8817e4Smiod in the table will be undefined. When the symbol is referenced, the 159*3d8817e4Smiod message is printed. */ 160*3d8817e4Smiod 161*3d8817e4Smiod #define N_WARNING 0x1e 162*3d8817e4Smiod 163*3d8817e4Smiod /* Relocations 164*3d8817e4Smiod 165*3d8817e4Smiod There are two types of relocation flavours for a.out systems, 166*3d8817e4Smiod standard and extended. The standard form is used on systems where the 167*3d8817e4Smiod instruction has room for all the bits of an offset to the operand, whilst 168*3d8817e4Smiod the extended form is used when an address operand has to be split over n 169*3d8817e4Smiod instructions. Eg, on the 68k, each move instruction can reference 170*3d8817e4Smiod the target with a displacement of 16 or 32 bits. On the sparc, move 171*3d8817e4Smiod instructions use an offset of 14 bits, so the offset is stored in 172*3d8817e4Smiod the reloc field, and the data in the section is ignored. 173*3d8817e4Smiod */ 174*3d8817e4Smiod 175*3d8817e4Smiod /* This structure describes a single relocation to be performed. 176*3d8817e4Smiod The text-relocation section of the file is a vector of these structures, 177*3d8817e4Smiod all of which apply to the text section. 178*3d8817e4Smiod Likewise, the data-relocation section applies to the data section. */ 179*3d8817e4Smiod 180*3d8817e4Smiod struct reloc_std_external { 181*3d8817e4Smiod bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */ 182*3d8817e4Smiod bfd_byte r_index[3]; /* symbol table index of symbol */ 183*3d8817e4Smiod bfd_byte r_type[1]; /* relocation type */ 184*3d8817e4Smiod }; 185*3d8817e4Smiod 186*3d8817e4Smiod #define RELOC_STD_BITS_PCREL_BIG 0x80 187*3d8817e4Smiod #define RELOC_STD_BITS_PCREL_LITTLE 0x01 188*3d8817e4Smiod 189*3d8817e4Smiod #define RELOC_STD_BITS_LENGTH_BIG 0x60 190*3d8817e4Smiod #define RELOC_STD_BITS_LENGTH_SH_BIG 5 /* To shift to units place */ 191*3d8817e4Smiod #define RELOC_STD_BITS_LENGTH_LITTLE 0x06 192*3d8817e4Smiod #define RELOC_STD_BITS_LENGTH_SH_LITTLE 1 193*3d8817e4Smiod 194*3d8817e4Smiod #define RELOC_STD_BITS_EXTERN_BIG 0x10 195*3d8817e4Smiod #define RELOC_STD_BITS_EXTERN_LITTLE 0x08 196*3d8817e4Smiod 197*3d8817e4Smiod #define RELOC_STD_BITS_BASEREL_BIG 0x08 198*3d8817e4Smiod #define RELOC_STD_BITS_BASEREL_LITTLE 0x08 199*3d8817e4Smiod 200*3d8817e4Smiod #define RELOC_STD_BITS_JMPTABLE_BIG 0x04 201*3d8817e4Smiod #define RELOC_STD_BITS_JMPTABLE_LITTLE 0x04 202*3d8817e4Smiod 203*3d8817e4Smiod #define RELOC_STD_BITS_RELATIVE_BIG 0x02 204*3d8817e4Smiod #define RELOC_STD_BITS_RELATIVE_LITTLE 0x02 205*3d8817e4Smiod 206*3d8817e4Smiod #define RELOC_STD_SIZE (BYTES_IN_WORD + 3 + 1) /* Bytes per relocation entry */ 207*3d8817e4Smiod 208*3d8817e4Smiod struct reloc_std_internal 209*3d8817e4Smiod { 210*3d8817e4Smiod bfd_vma r_address; /* Address (within segment) to be relocated. */ 211*3d8817e4Smiod /* The meaning of r_symbolnum depends on r_extern. */ 212*3d8817e4Smiod unsigned int r_symbolnum:24; 213*3d8817e4Smiod /* Nonzero means value is a pc-relative offset 214*3d8817e4Smiod and it should be relocated for changes in its own address 215*3d8817e4Smiod as well as for changes in the symbol or section specified. */ 216*3d8817e4Smiod unsigned int r_pcrel:1; 217*3d8817e4Smiod /* Length (as exponent of 2) of the field to be relocated. 218*3d8817e4Smiod Thus, a value of 2 indicates 1<<2 bytes. */ 219*3d8817e4Smiod unsigned int r_length:2; 220*3d8817e4Smiod /* 1 => relocate with value of symbol. 221*3d8817e4Smiod r_symbolnum is the index of the symbol 222*3d8817e4Smiod in files the symbol table. 223*3d8817e4Smiod 0 => relocate with the address of a segment. 224*3d8817e4Smiod r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS 225*3d8817e4Smiod (the N_EXT bit may be set also, but signifies nothing). */ 226*3d8817e4Smiod unsigned int r_extern:1; 227*3d8817e4Smiod /* The next three bits are for SunOS shared libraries, and seem to 228*3d8817e4Smiod be undocumented. */ 229*3d8817e4Smiod unsigned int r_baserel:1; /* Linkage table relative */ 230*3d8817e4Smiod unsigned int r_jmptable:1; /* pc-relative to jump table */ 231*3d8817e4Smiod unsigned int r_relative:1; /* "relative relocation" */ 232*3d8817e4Smiod /* unused */ 233*3d8817e4Smiod unsigned int r_pad:1; /* Padding -- set to zero */ 234*3d8817e4Smiod }; 235*3d8817e4Smiod 236*3d8817e4Smiod 237*3d8817e4Smiod /* EXTENDED RELOCS */ 238*3d8817e4Smiod 239*3d8817e4Smiod struct reloc_ext_external { 240*3d8817e4Smiod bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */ 241*3d8817e4Smiod bfd_byte r_index[3]; /* symbol table index of symbol */ 242*3d8817e4Smiod bfd_byte r_type[1]; /* relocation type */ 243*3d8817e4Smiod bfd_byte r_addend[BYTES_IN_WORD]; /* datum addend */ 244*3d8817e4Smiod }; 245*3d8817e4Smiod 246*3d8817e4Smiod #define RELOC_EXT_BITS_EXTERN_BIG 0x80 247*3d8817e4Smiod #define RELOC_EXT_BITS_EXTERN_LITTLE 0x01 248*3d8817e4Smiod 249*3d8817e4Smiod #define RELOC_EXT_BITS_TYPE_BIG 0x1F 250*3d8817e4Smiod #define RELOC_EXT_BITS_TYPE_SH_BIG 0 251*3d8817e4Smiod #define RELOC_EXT_BITS_TYPE_LITTLE 0xF8 252*3d8817e4Smiod #define RELOC_EXT_BITS_TYPE_SH_LITTLE 3 253*3d8817e4Smiod 254*3d8817e4Smiod /* Bytes per relocation entry */ 255*3d8817e4Smiod #define RELOC_EXT_SIZE (BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD) 256*3d8817e4Smiod 257*3d8817e4Smiod enum reloc_type 258*3d8817e4Smiod { 259*3d8817e4Smiod /* simple relocations */ 260*3d8817e4Smiod RELOC_8, /* data[0:7] = addend + sv */ 261*3d8817e4Smiod RELOC_16, /* data[0:15] = addend + sv */ 262*3d8817e4Smiod RELOC_32, /* data[0:31] = addend + sv */ 263*3d8817e4Smiod /* pc-rel displacement */ 264*3d8817e4Smiod RELOC_DISP8, /* data[0:7] = addend - pc + sv */ 265*3d8817e4Smiod RELOC_DISP16, /* data[0:15] = addend - pc + sv */ 266*3d8817e4Smiod RELOC_DISP32, /* data[0:31] = addend - pc + sv */ 267*3d8817e4Smiod /* Special */ 268*3d8817e4Smiod RELOC_WDISP30, /* data[0:29] = (addend + sv - pc)>>2 */ 269*3d8817e4Smiod RELOC_WDISP22, /* data[0:21] = (addend + sv - pc)>>2 */ 270*3d8817e4Smiod RELOC_HI22, /* data[0:21] = (addend + sv)>>10 */ 271*3d8817e4Smiod RELOC_22, /* data[0:21] = (addend + sv) */ 272*3d8817e4Smiod RELOC_13, /* data[0:12] = (addend + sv) */ 273*3d8817e4Smiod RELOC_LO10, /* data[0:9] = (addend + sv) */ 274*3d8817e4Smiod RELOC_SFA_BASE, 275*3d8817e4Smiod RELOC_SFA_OFF13, 276*3d8817e4Smiod /* P.I.C. (base-relative) */ 277*3d8817e4Smiod RELOC_BASE10, /* Not sure - maybe we can do this the */ 278*3d8817e4Smiod RELOC_BASE13, /* right way now */ 279*3d8817e4Smiod RELOC_BASE22, 280*3d8817e4Smiod /* for some sort of pc-rel P.I.C. (?) */ 281*3d8817e4Smiod RELOC_PC10, 282*3d8817e4Smiod RELOC_PC22, 283*3d8817e4Smiod /* P.I.C. jump table */ 284*3d8817e4Smiod RELOC_JMP_TBL, 285*3d8817e4Smiod /* reputedly for shared libraries somehow */ 286*3d8817e4Smiod RELOC_SEGOFF16, 287*3d8817e4Smiod RELOC_GLOB_DAT, 288*3d8817e4Smiod RELOC_JMP_SLOT, 289*3d8817e4Smiod RELOC_RELATIVE, 290*3d8817e4Smiod 291*3d8817e4Smiod RELOC_11, 292*3d8817e4Smiod RELOC_WDISP2_14, 293*3d8817e4Smiod RELOC_WDISP19, 294*3d8817e4Smiod RELOC_HHI22, /* data[0:21] = (addend + sv) >> 42 */ 295*3d8817e4Smiod RELOC_HLO10, /* data[0:9] = (addend + sv) >> 32 */ 296*3d8817e4Smiod 297*3d8817e4Smiod /* 29K relocation types */ 298*3d8817e4Smiod RELOC_JUMPTARG, 299*3d8817e4Smiod RELOC_CONST, 300*3d8817e4Smiod RELOC_CONSTH, 301*3d8817e4Smiod 302*3d8817e4Smiod NO_RELOC 303*3d8817e4Smiod }; 304*3d8817e4Smiod 305*3d8817e4Smiod 306*3d8817e4Smiod struct reloc_internal { 307*3d8817e4Smiod bfd_vma r_address; /* offset of of data to relocate */ 308*3d8817e4Smiod long r_index; /* symbol table index of symbol */ 309*3d8817e4Smiod enum reloc_type r_type; /* relocation type */ 310*3d8817e4Smiod bfd_vma r_addend; /* datum addend */ 311*3d8817e4Smiod }; 312*3d8817e4Smiod 313*3d8817e4Smiod #endif /* __A_OUT_ADOBE_H__ */ 314