|  | /* | 
|  | *  GRUB  --  GRand Unified Bootloader | 
|  | *  Copyright (C) 2001  Free Software Foundation, Inc. | 
|  | * | 
|  | *  This program is free software; you can redistribute it and/or modify | 
|  | *  it under the terms of the GNU General Public License as published by | 
|  | *  the Free Software Foundation; either version 2 of the License, or | 
|  | *  (at your option) any later version. | 
|  | * | 
|  | *  This program is distributed in the hope that it will be useful, | 
|  | *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | *  GNU General Public License for more details. | 
|  | * | 
|  | *  You should have received a copy of the GNU General Public License | 
|  | *  along with this program; if not, write to the Free Software | 
|  | *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 
|  | */ | 
|  |  | 
|  | /* 32-bit data types */ | 
|  |  | 
|  | typedef unsigned long Elf32_Addr; | 
|  | typedef unsigned short Elf32_Half; | 
|  | typedef unsigned long Elf32_Off; | 
|  | typedef signed long Elf32_Sword; | 
|  | typedef unsigned long Elf32_Word; | 
|  | /* "unsigned char" already exists */ | 
|  |  | 
|  | /* ELF header */ | 
|  | typedef struct | 
|  | { | 
|  |  | 
|  | #define EI_NIDENT 16 | 
|  |  | 
|  | /* first four characters are defined below */ | 
|  | #define EI_MAG0		0 | 
|  | #define ELFMAG0		0x7f | 
|  | #define EI_MAG1		1 | 
|  | #define ELFMAG1		'E' | 
|  | #define EI_MAG2		2 | 
|  | #define ELFMAG2		'L' | 
|  | #define EI_MAG3		3 | 
|  | #define ELFMAG3		'F' | 
|  |  | 
|  | #define EI_CLASS	4	/* data sizes */ | 
|  | #define ELFCLASS32	1	/* i386 -- up to 32-bit data sizes present */ | 
|  |  | 
|  | #define EI_DATA		5	/* data type and ordering */ | 
|  | #define ELFDATA2LSB	1	/* i386 -- LSB 2's complement */ | 
|  |  | 
|  | #define EI_VERSION	6	/* version number.  "e_version" must be the same */ | 
|  | #define EV_CURRENT      1	/* current version number */ | 
|  |  | 
|  | #define EI_PAD		7	/* from here in is just padding */ | 
|  |  | 
|  | #define EI_BRAND	8	/* start of OS branding (This is | 
|  | obviously illegal against the ELF | 
|  | standard.) */ | 
|  |  | 
|  | unsigned char e_ident[EI_NIDENT];	/* basic identification block */ | 
|  |  | 
|  | #define ET_EXEC		2	/* we only care about executable types */ | 
|  | Elf32_Half e_type;		/* file types */ | 
|  |  | 
|  | #define EM_386		3	/* i386 -- obviously use this one */ | 
|  | Elf32_Half e_machine;	/* machine types */ | 
|  | Elf32_Word e_version;	/* use same as "EI_VERSION" above */ | 
|  | Elf32_Addr e_entry;		/* entry point of the program */ | 
|  | Elf32_Off e_phoff;		/* program header table file offset */ | 
|  | Elf32_Off e_shoff;		/* section header table file offset */ | 
|  | Elf32_Word e_flags;		/* flags */ | 
|  | Elf32_Half e_ehsize;		/* elf header size in bytes */ | 
|  | Elf32_Half e_phentsize;	/* program header entry size */ | 
|  | Elf32_Half e_phnum;		/* number of entries in program header */ | 
|  | Elf32_Half e_shentsize;	/* section header entry size */ | 
|  | Elf32_Half e_shnum;		/* number of entries in section header */ | 
|  |  | 
|  | #define SHN_UNDEF       0 | 
|  | #define SHN_LORESERVE   0xff00 | 
|  | #define SHN_LOPROC      0xff00 | 
|  | #define SHN_HIPROC      0xff1f | 
|  | #define SHN_ABS         0xfff1 | 
|  | #define SHN_COMMON      0xfff2 | 
|  | #define SHN_HIRESERVE   0xffff | 
|  | Elf32_Half e_shstrndx;	/* section header table index */ | 
|  | } | 
|  | Elf32_Ehdr; | 
|  |  | 
|  |  | 
|  | #define BOOTABLE_I386_ELF(h) \ | 
|  | ((h.e_ident[EI_MAG0] == ELFMAG0) & (h.e_ident[EI_MAG1] == ELFMAG1) \ | 
|  | & (h.e_ident[EI_MAG2] == ELFMAG2) & (h.e_ident[EI_MAG3] == ELFMAG3) \ | 
|  | & (h.e_ident[EI_CLASS] == ELFCLASS32) & (h.e_ident[EI_DATA] == ELFDATA2LSB) \ | 
|  | & (h.e_ident[EI_VERSION] == EV_CURRENT) & (h.e_type == ET_EXEC) \ | 
|  | & (h.e_machine == EM_386) & (h.e_version == EV_CURRENT)) | 
|  |  | 
|  | /* section table - ? */ | 
|  | typedef struct | 
|  | { | 
|  | Elf32_Word	sh_name;		/* Section name (string tbl index) */ | 
|  | Elf32_Word	sh_type;		/* Section type */ | 
|  | Elf32_Word	sh_flags;		/* Section flags */ | 
|  | Elf32_Addr	sh_addr;		/* Section virtual addr at execution */ | 
|  | Elf32_Off	sh_offset;		/* Section file offset */ | 
|  | Elf32_Word	sh_size;		/* Section size in bytes */ | 
|  | Elf32_Word	sh_link;		/* Link to another section */ | 
|  | Elf32_Word	sh_info;		/* Additional section information */ | 
|  | Elf32_Word	sh_addralign;		/* Section alignment */ | 
|  | Elf32_Word	sh_entsize;		/* Entry size if section holds table */ | 
|  | } | 
|  | Elf32_Shdr; | 
|  |  | 
|  | /* symbol table - page 4-25, figure 4-15 */ | 
|  | typedef struct | 
|  | { | 
|  | Elf32_Word st_name; | 
|  | Elf32_Addr st_value; | 
|  | Elf32_Word st_size; | 
|  | unsigned char st_info; | 
|  | unsigned char st_other; | 
|  | Elf32_Half st_shndx; | 
|  | } | 
|  | Elf32_Sym; | 
|  |  | 
|  | /* symbol type and binding attributes - page 4-26 */ | 
|  |  | 
|  | #define ELF32_ST_BIND(i)    ((i) >> 4) | 
|  | #define ELF32_ST_TYPE(i)    ((i) & 0xf) | 
|  | #define ELF32_ST_INFO(b,t)  (((b)<<4)+((t)&0xf)) | 
|  |  | 
|  | /* symbol binding - page 4-26, figure 4-16 */ | 
|  |  | 
|  | #define STB_LOCAL    0 | 
|  | #define STB_GLOBAL   1 | 
|  | #define STB_WEAK     2 | 
|  | #define STB_LOPROC  13 | 
|  | #define STB_HIPROC  15 | 
|  |  | 
|  | /* symbol types - page 4-28, figure 4-17 */ | 
|  |  | 
|  | #define STT_NOTYPE   0 | 
|  | #define STT_OBJECT   1 | 
|  | #define STT_FUNC     2 | 
|  | #define STT_SECTION  3 | 
|  | #define STT_FILE     4 | 
|  | #define STT_LOPROC  13 | 
|  | #define STT_HIPROC  15 | 
|  |  | 
|  |  | 
|  | /* Macros to split/combine relocation type and symbol page 4-32 */ | 
|  |  | 
|  | #define ELF32_R_SYM(__i)	((__i)>>8) | 
|  | #define ELF32_R_TYPE(__i)	((unsigned char) (__i)) | 
|  | #define ELF32_R_INFO(__s, __t)	(((__s)<<8) + (unsigned char) (__t)) | 
|  |  | 
|  |  | 
|  | /* program header - page 5-2, figure 5-1 */ | 
|  |  | 
|  | typedef struct | 
|  | { | 
|  | Elf32_Word p_type; | 
|  | Elf32_Off p_offset; | 
|  | Elf32_Addr p_vaddr; | 
|  | Elf32_Addr p_paddr; | 
|  | Elf32_Word p_filesz; | 
|  | Elf32_Word p_memsz; | 
|  | Elf32_Word p_flags; | 
|  | Elf32_Word p_align; | 
|  | } | 
|  | Elf32_Phdr; | 
|  |  | 
|  | /* segment types - page 5-3, figure 5-2 */ | 
|  |  | 
|  | #define PT_NULL		0 | 
|  | #define PT_LOAD		1 | 
|  | #define PT_DYNAMIC	2 | 
|  | #define PT_INTERP	3 | 
|  | #define PT_NOTE		4 | 
|  | #define PT_SHLIB	5 | 
|  | #define PT_PHDR		6 | 
|  |  | 
|  | #define PT_LOPROC	0x70000000 | 
|  | #define PT_HIPROC	0x7fffffff | 
|  |  | 
|  | /* segment permissions - page 5-6 */ | 
|  |  | 
|  | #define PF_X		0x1 | 
|  | #define PF_W		0x2 | 
|  | #define PF_R		0x4 | 
|  | #define PF_MASKPROC	0xf0000000 | 
|  |  | 
|  |  | 
|  | /* dynamic structure - page 5-15, figure 5-9 */ | 
|  |  | 
|  | typedef struct | 
|  | { | 
|  | Elf32_Sword d_tag; | 
|  | union | 
|  | { | 
|  | Elf32_Word d_val; | 
|  | Elf32_Addr d_ptr; | 
|  | } | 
|  | d_un; | 
|  | } | 
|  | Elf32_Dyn; | 
|  |  | 
|  | /* Dynamic array tags - page 5-16, figure 5-10.  */ | 
|  |  | 
|  | #define DT_NULL		0 | 
|  | #define DT_NEEDED	1 | 
|  | #define DT_PLTRELSZ	2 | 
|  | #define DT_PLTGOT	3 | 
|  | #define DT_HASH		4 | 
|  | #define DT_STRTAB	5 | 
|  | #define DT_SYMTAB	6 | 
|  | #define DT_RELA		7 | 
|  | #define DT_RELASZ	8 | 
|  | #define DT_RELAENT      9 | 
|  | #define DT_STRSZ	10 | 
|  | #define DT_SYMENT	11 | 
|  | #define DT_INIT		12 | 
|  | #define DT_FINI		13 | 
|  | #define DT_SONAME	14 | 
|  | #define DT_RPATH	15 | 
|  | #define DT_SYMBOLIC	16 | 
|  | #define DT_REL		17 | 
|  | #define DT_RELSZ	18 | 
|  | #define DT_RELENT	19 | 
|  | #define DT_PLTREL	20 | 
|  | #define DT_DEBUG	21 | 
|  | #define DT_TEXTREL	22 | 
|  | #define DT_JMPREL	23 |