relocs.c revision 908ec7afacfdc83dc10938ed1d3c38b3526034ec
1968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#include <stdio.h> 2968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#include <stdarg.h> 3968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#include <stdlib.h> 4968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#include <stdint.h> 5968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#include <string.h> 6968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#include <errno.h> 7968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#include <unistd.h> 8968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#include <elf.h> 9968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#include <byteswap.h> 10968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#define USE_BSD 11968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#include <endian.h> 12968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 13ca820181fc187af316a18b2700582663662c4012Robert P. J. Day#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 14968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic Elf32_Ehdr ehdr; 15968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic unsigned long reloc_count, reloc_idx; 16968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic unsigned long *relocs; 17968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 18908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvinstruct section { 19908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin Elf32_Shdr shdr; 20908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin struct section *link; 21908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin Elf32_Sym *symtab; 22908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin Elf32_Rel *reltab; 23908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin char *strtab; 24908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin}; 25908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvinstatic struct section *secs; 26908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin 276a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal/* 286a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * Following symbols have been audited. There values are constant and do 296a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * not change if bzImage is loaded at a different physical address than 306a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * the address for which it has been compiled. Don't warn user about 316a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * absolute relocations present w.r.t these symbols. 326a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal */ 336a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyalstatic const char* safe_abs_relocs[] = { 34600b2fc242992e552e0b4e24c8c1f084b341f39bJeremy Fitzhardinge "xen_irq_disable_direct_reloc", 35600b2fc242992e552e0b4e24c8c1f084b341f39bJeremy Fitzhardinge "xen_save_fl_direct_reloc", 366a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal}; 376a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal 386a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyalstatic int is_safe_abs_reloc(const char* sym_name) 396a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal{ 404d022adab4511892226f1eae00a44502bf685ae5Alejandro Martinez Ruiz int i; 416a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal 42908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (i = 0; i < ARRAY_SIZE(safe_abs_relocs); i++) { 436a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal if (!strcmp(sym_name, safe_abs_relocs[i])) 446a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal /* Match found */ 456a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal return 1; 466a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal } 474707c4717a5a6f375f3300bbccff1d46dcf75b25Roland McGrath if (strncmp(sym_name, "VDSO", 4) == 0) 484707c4717a5a6f375f3300bbccff1d46dcf75b25Roland McGrath return 1; 492a3d4f1f1f839e354ebd7d40b2d5d8ac8481a930Al Viro if (strncmp(sym_name, "__crc_", 6) == 0) 502a3d4f1f1f839e354ebd7d40b2d5d8ac8481a930Al Viro return 1; 516a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal return 0; 526a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal} 536a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal 54968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic void die(char *fmt, ...) 55968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 56968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman va_list ap; 57968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman va_start(ap, fmt); 58968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman vfprintf(stderr, fmt, ap); 59968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman va_end(ap); 60968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman exit(1); 61968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 62968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 63968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic const char *sym_type(unsigned type) 64968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 65968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman static const char *type_name[] = { 66968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#define SYM_TYPE(X) [X] = #X 67968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman SYM_TYPE(STT_NOTYPE), 68968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman SYM_TYPE(STT_OBJECT), 69968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman SYM_TYPE(STT_FUNC), 70968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman SYM_TYPE(STT_SECTION), 71968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman SYM_TYPE(STT_FILE), 72968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman SYM_TYPE(STT_COMMON), 73968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman SYM_TYPE(STT_TLS), 74968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#undef SYM_TYPE 75968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman }; 76968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman const char *name = "unknown sym type name"; 77ca820181fc187af316a18b2700582663662c4012Robert P. J. Day if (type < ARRAY_SIZE(type_name)) { 78968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman name = type_name[type]; 79968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 80968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman return name; 81968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 82968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 83968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic const char *sym_bind(unsigned bind) 84968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 85968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman static const char *bind_name[] = { 86968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#define SYM_BIND(X) [X] = #X 87968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman SYM_BIND(STB_LOCAL), 88968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman SYM_BIND(STB_GLOBAL), 89968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman SYM_BIND(STB_WEAK), 90968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#undef SYM_BIND 91968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman }; 92968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman const char *name = "unknown sym bind name"; 93ca820181fc187af316a18b2700582663662c4012Robert P. J. Day if (bind < ARRAY_SIZE(bind_name)) { 94968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman name = bind_name[bind]; 95968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 96968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman return name; 97968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 98968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 99968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic const char *sym_visibility(unsigned visibility) 100968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 101968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman static const char *visibility_name[] = { 102968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#define SYM_VISIBILITY(X) [X] = #X 103968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman SYM_VISIBILITY(STV_DEFAULT), 104968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman SYM_VISIBILITY(STV_INTERNAL), 105968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman SYM_VISIBILITY(STV_HIDDEN), 106968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman SYM_VISIBILITY(STV_PROTECTED), 107968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#undef SYM_VISIBILITY 108968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman }; 109968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman const char *name = "unknown sym visibility name"; 110ca820181fc187af316a18b2700582663662c4012Robert P. J. Day if (visibility < ARRAY_SIZE(visibility_name)) { 111968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman name = visibility_name[visibility]; 112968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 113968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman return name; 114968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 115968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 116968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic const char *rel_type(unsigned type) 117968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 118968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman static const char *type_name[] = { 119968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#define REL_TYPE(X) [X] = #X 120968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman REL_TYPE(R_386_NONE), 121968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman REL_TYPE(R_386_32), 122968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman REL_TYPE(R_386_PC32), 123968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman REL_TYPE(R_386_GOT32), 124968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman REL_TYPE(R_386_PLT32), 125968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman REL_TYPE(R_386_COPY), 126968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman REL_TYPE(R_386_GLOB_DAT), 127968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman REL_TYPE(R_386_JMP_SLOT), 128968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman REL_TYPE(R_386_RELATIVE), 129968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman REL_TYPE(R_386_GOTOFF), 130968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman REL_TYPE(R_386_GOTPC), 131968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#undef REL_TYPE 132968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman }; 133968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman const char *name = "unknown type rel type name"; 134ca820181fc187af316a18b2700582663662c4012Robert P. J. Day if (type < ARRAY_SIZE(type_name)) { 135968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman name = type_name[type]; 136968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 137968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman return name; 138968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 139968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 140968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic const char *sec_name(unsigned shndx) 141968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 142968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman const char *sec_strtab; 143968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman const char *name; 144908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec_strtab = secs[ehdr.e_shstrndx].strtab; 145968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman name = "<noname>"; 146968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (shndx < ehdr.e_shnum) { 147908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin name = sec_strtab + secs[shndx].shdr.sh_name; 148968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 149968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman else if (shndx == SHN_ABS) { 150968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman name = "ABSOLUTE"; 151968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 152968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman else if (shndx == SHN_COMMON) { 153968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman name = "COMMON"; 154968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 155968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman return name; 156968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 157968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 158968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic const char *sym_name(const char *sym_strtab, Elf32_Sym *sym) 159968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 160968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman const char *name; 161968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman name = "<noname>"; 162968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (sym->st_name) { 163968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman name = sym_strtab + sym->st_name; 164968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 165968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman else { 166908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin name = sec_name(secs[sym->st_shndx].shdr.sh_name); 167968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 168968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman return name; 169968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 170968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 171968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 172968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 173968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#if BYTE_ORDER == LITTLE_ENDIAN 174968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#define le16_to_cpu(val) (val) 175968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#define le32_to_cpu(val) (val) 176968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#endif 177968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#if BYTE_ORDER == BIG_ENDIAN 178968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#define le16_to_cpu(val) bswap_16(val) 179968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#define le32_to_cpu(val) bswap_32(val) 180968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman#endif 181968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 182968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic uint16_t elf16_to_cpu(uint16_t val) 183968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 184968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman return le16_to_cpu(val); 185968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 186968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 187968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic uint32_t elf32_to_cpu(uint32_t val) 188968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 189968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman return le32_to_cpu(val); 190968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 191968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 192968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic void read_ehdr(FILE *fp) 193968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 194968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) { 195968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Cannot read ELF header: %s\n", 196968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman strerror(errno)); 197968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 1988bd1796dedd50abd7553afbe6113bd97cc88390fCyrill Gorcunov if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) { 199968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("No ELF magic\n"); 200968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 201968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) { 202968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Not a 32 bit executable\n"); 203968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 204968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) { 205968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Not a LSB ELF executable\n"); 206968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 207968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) { 208968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Unknown ELF version\n"); 209968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 210968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman /* Convert the fields to native endian */ 211968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman ehdr.e_type = elf16_to_cpu(ehdr.e_type); 212968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman ehdr.e_machine = elf16_to_cpu(ehdr.e_machine); 213968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman ehdr.e_version = elf32_to_cpu(ehdr.e_version); 214968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman ehdr.e_entry = elf32_to_cpu(ehdr.e_entry); 215968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman ehdr.e_phoff = elf32_to_cpu(ehdr.e_phoff); 216968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman ehdr.e_shoff = elf32_to_cpu(ehdr.e_shoff); 217968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman ehdr.e_flags = elf32_to_cpu(ehdr.e_flags); 218968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman ehdr.e_ehsize = elf16_to_cpu(ehdr.e_ehsize); 219968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman ehdr.e_phentsize = elf16_to_cpu(ehdr.e_phentsize); 220968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman ehdr.e_phnum = elf16_to_cpu(ehdr.e_phnum); 221968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman ehdr.e_shentsize = elf16_to_cpu(ehdr.e_shentsize); 222968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman ehdr.e_shnum = elf16_to_cpu(ehdr.e_shnum); 223968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman ehdr.e_shstrndx = elf16_to_cpu(ehdr.e_shstrndx); 224968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 225968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN)) { 226968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Unsupported ELF header type\n"); 227968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 228968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (ehdr.e_machine != EM_386) { 229968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Not for x86\n"); 230968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 231968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (ehdr.e_version != EV_CURRENT) { 232968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Unknown ELF version\n"); 233968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 234968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (ehdr.e_ehsize != sizeof(Elf32_Ehdr)) { 235968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Bad Elf header size\n"); 236968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 237968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (ehdr.e_phentsize != sizeof(Elf32_Phdr)) { 238968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Bad program header entry\n"); 239968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 240968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (ehdr.e_shentsize != sizeof(Elf32_Shdr)) { 241968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Bad section header entry\n"); 242968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 243968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (ehdr.e_shstrndx >= ehdr.e_shnum) { 244968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("String table index out of bounds\n"); 245968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 246968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 247968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 248968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic void read_shdrs(FILE *fp) 249968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 250968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman int i; 251908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin Elf32_Shdr shdr; 252908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin 253908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin secs = calloc(ehdr.e_shnum, sizeof(struct section)); 254908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (!secs) { 255908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin die("Unable to allocate %d section headers\n", 256908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin ehdr.e_shnum); 257968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 258968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) { 259968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Seek to %d failed: %s\n", 260968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman ehdr.e_shoff, strerror(errno)); 261968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 262908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (i = 0; i < ehdr.e_shnum; i++) { 263908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin struct section *sec = &secs[i]; 264908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (fread(&shdr, sizeof shdr, 1, fp) != 1) 265908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin die("Cannot read ELF section headers %d/%d: %s\n", 266908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin i, ehdr.e_shnum, strerror(errno)); 267908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_name = elf32_to_cpu(shdr.sh_name); 268908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_type = elf32_to_cpu(shdr.sh_type); 269908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_flags = elf32_to_cpu(shdr.sh_flags); 270908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_addr = elf32_to_cpu(shdr.sh_addr); 271908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_offset = elf32_to_cpu(shdr.sh_offset); 272908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_size = elf32_to_cpu(shdr.sh_size); 273908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_link = elf32_to_cpu(shdr.sh_link); 274908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_info = elf32_to_cpu(shdr.sh_info); 275908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_addralign = elf32_to_cpu(shdr.sh_addralign); 276908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_entsize = elf32_to_cpu(shdr.sh_entsize); 277908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (sec->shdr.sh_link < ehdr.e_shnum) 278908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->link = &secs[sec->shdr.sh_link]; 279968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 280968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 281968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 282968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 283968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic void read_strtabs(FILE *fp) 284968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 285968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman int i; 286908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (i = 0; i < ehdr.e_shnum; i++) { 287908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin struct section *sec = &secs[i]; 288908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (sec->shdr.sh_type != SHT_STRTAB) { 289968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman continue; 290968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 291908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->strtab = malloc(sec->shdr.sh_size); 292908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (!sec->strtab) { 293968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("malloc of %d bytes for strtab failed\n", 294908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_size); 295968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 296908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) { 297968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Seek to %d failed: %s\n", 298908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_offset, strerror(errno)); 299968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 300908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (fread(sec->strtab, 1, sec->shdr.sh_size, fp) 301908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin != sec->shdr.sh_size) { 302968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Cannot read symbol table: %s\n", 303968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman strerror(errno)); 304968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 305968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 306968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 307968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 308968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic void read_symtabs(FILE *fp) 309968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 310968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman int i,j; 311908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (i = 0; i < ehdr.e_shnum; i++) { 312908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin struct section *sec = &secs[i]; 313908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (sec->shdr.sh_type != SHT_SYMTAB) { 314968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman continue; 315968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 316908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->symtab = malloc(sec->shdr.sh_size); 317908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (!sec->symtab) { 318968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("malloc of %d bytes for symtab failed\n", 319908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_size); 320968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 321908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) { 322968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Seek to %d failed: %s\n", 323908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_offset, strerror(errno)); 324968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 325908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (fread(sec->symtab, 1, sec->shdr.sh_size, fp) 326908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin != sec->shdr.sh_size) { 327968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Cannot read symbol table: %s\n", 328968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman strerror(errno)); 329968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 330908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) { 331908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin Elf32_Sym *sym = &sec->symtab[j]; 332908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sym->st_name = elf32_to_cpu(sym->st_name); 333908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sym->st_value = elf32_to_cpu(sym->st_value); 334908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sym->st_size = elf32_to_cpu(sym->st_size); 335908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sym->st_shndx = elf16_to_cpu(sym->st_shndx); 336968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 337968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 338968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 339968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 340968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 341968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic void read_relocs(FILE *fp) 342968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 343968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman int i,j; 344908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (i = 0; i < ehdr.e_shnum; i++) { 345908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin struct section *sec = &secs[i]; 346908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (sec->shdr.sh_type != SHT_REL) { 347968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman continue; 348968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 349908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->reltab = malloc(sec->shdr.sh_size); 350908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (!sec->reltab) { 351968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("malloc of %d bytes for relocs failed\n", 352908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_size); 353968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 354908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) { 355968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Seek to %d failed: %s\n", 356908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec->shdr.sh_offset, strerror(errno)); 357968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 358908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (fread(sec->reltab, 1, sec->shdr.sh_size, fp) 359908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin != sec->shdr.sh_size) { 360968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Cannot read symbol table: %s\n", 361968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman strerror(errno)); 362968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 363908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) { 364908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin Elf32_Rel *rel = &sec->reltab[j]; 365908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin rel->r_offset = elf32_to_cpu(rel->r_offset); 366908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin rel->r_info = elf32_to_cpu(rel->r_info); 367968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 368968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 369968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 370968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 371968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 372968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic void print_absolute_symbols(void) 373968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 374968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman int i; 375968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman printf("Absolute symbols\n"); 376968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman printf(" Num: Value Size Type Bind Visibility Name\n"); 377908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (i = 0; i < ehdr.e_shnum; i++) { 378908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin struct section *sec = &secs[i]; 379968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman char *sym_strtab; 380968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman Elf32_Sym *sh_symtab; 381968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman int j; 382908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin 383908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (sec->shdr.sh_type != SHT_SYMTAB) { 384968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman continue; 385968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 386908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sh_symtab = sec->symtab; 387908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sym_strtab = sec->link->strtab; 388908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) { 389968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman Elf32_Sym *sym; 390968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman const char *name; 391908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sym = &sec->symtab[j]; 392968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman name = sym_name(sym_strtab, sym); 393968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (sym->st_shndx != SHN_ABS) { 394968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman continue; 395968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 396968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman printf("%5d %08x %5d %10s %10s %12s %s\n", 397968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman j, sym->st_value, sym->st_size, 398968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman sym_type(ELF32_ST_TYPE(sym->st_info)), 399968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman sym_bind(ELF32_ST_BIND(sym->st_info)), 400968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman sym_visibility(ELF32_ST_VISIBILITY(sym->st_other)), 401968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman name); 402968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 403968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 404968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman printf("\n"); 405968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 406968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 407968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic void print_absolute_relocs(void) 408968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 4096a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal int i, printed = 0; 4106a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal 411908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (i = 0; i < ehdr.e_shnum; i++) { 412908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin struct section *sec = &secs[i]; 413908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin struct section *sec_applies, *sec_symtab; 414968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman char *sym_strtab; 415968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman Elf32_Sym *sh_symtab; 416968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman int j; 417908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (sec->shdr.sh_type != SHT_REL) { 418968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman continue; 419968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 420908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec_symtab = sec->link; 421908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec_applies = &secs[sec->shdr.sh_info]; 422908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) { 423968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman continue; 424968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 425908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sh_symtab = sec_symtab->symtab; 426908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sym_strtab = sec_symtab->link->strtab; 427908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) { 428968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman Elf32_Rel *rel; 429968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman Elf32_Sym *sym; 430968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman const char *name; 431908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin rel = &sec->reltab[j]; 432968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; 433968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman name = sym_name(sym_strtab, sym); 434968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (sym->st_shndx != SHN_ABS) { 435968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman continue; 436968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 4376a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal 4386a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal /* Absolute symbols are not relocated if bzImage is 4396a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * loaded at a non-compiled address. Display a warning 4406a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * to user at compile time about the absolute 4416a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * relocations present. 4426a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * 4436a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * User need to audit the code to make sure 4446a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * some symbols which should have been section 4456a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * relative have not become absolute because of some 4466a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * linker optimization or wrong programming usage. 4476a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * 4486a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * Before warning check if this absolute symbol 4496a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal * relocation is harmless. 4506a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal */ 4516a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal if (is_safe_abs_reloc(name)) 4526a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal continue; 4536a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal 4546a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal if (!printed) { 4556a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal printf("WARNING: Absolute relocations" 4566a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal " present\n"); 4576a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal printf("Offset Info Type Sym.Value " 4586a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal "Sym.Name\n"); 4596a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal printed = 1; 4606a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal } 4616a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal 462968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman printf("%08x %08x %10s %08x %s\n", 463968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman rel->r_offset, 464968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman rel->r_info, 465968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman rel_type(ELF32_R_TYPE(rel->r_info)), 466968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman sym->st_value, 467968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman name); 468968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 469968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 4706a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal 4716a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal if (printed) 4726a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal printf("\n"); 473968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 474968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 475968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) 476968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 477968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman int i; 478968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman /* Walk through the relocations */ 479908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (i = 0; i < ehdr.e_shnum; i++) { 480968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman char *sym_strtab; 481968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman Elf32_Sym *sh_symtab; 482908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin struct section *sec_applies, *sec_symtab; 483968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman int j; 484908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin struct section *sec = &secs[i]; 485908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin 486908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (sec->shdr.sh_type != SHT_REL) { 487968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman continue; 488968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 489908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec_symtab = sec->link; 490908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sec_applies = &secs[sec->shdr.sh_info]; 491908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) { 492968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman continue; 493968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 494908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sh_symtab = sec_symtab->symtab; 495908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin sym_strtab = sec->link->strtab; 496908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) { 497968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman Elf32_Rel *rel; 498968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman Elf32_Sym *sym; 499968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman unsigned r_type; 500908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin rel = &sec->reltab[j]; 501968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; 502968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman r_type = ELF32_R_TYPE(rel->r_info); 503968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman /* Don't visit relocations to absolute symbols */ 504968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (sym->st_shndx == SHN_ABS) { 505968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman continue; 506968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 507968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (r_type == R_386_PC32) { 508968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman /* PC relative relocations don't need to be adjusted */ 509968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 510968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman else if (r_type == R_386_32) { 511968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman /* Visit relocations that need to be adjusted */ 512968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman visit(rel, sym); 513968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 514968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman else { 515968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Unsupported relocation type: %d\n", r_type); 516968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 517968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 518968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 519968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 520968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 521968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic void count_reloc(Elf32_Rel *rel, Elf32_Sym *sym) 522968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 523968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman reloc_count += 1; 524968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 525968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 526968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic void collect_reloc(Elf32_Rel *rel, Elf32_Sym *sym) 527968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 528968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman /* Remember the address that needs to be adjusted. */ 529968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman relocs[reloc_idx++] = rel->r_offset; 530968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 531968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 532968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic int cmp_relocs(const void *va, const void *vb) 533968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 534968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman const unsigned long *a, *b; 535968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman a = va; b = vb; 536968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman return (*a == *b)? 0 : (*a > *b)? 1 : -1; 537968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 538968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 539968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic void emit_relocs(int as_text) 540968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 541968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman int i; 542968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman /* Count how many relocations I have and allocate space for them. */ 543968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman reloc_count = 0; 544968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman walk_relocs(count_reloc); 545968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman relocs = malloc(reloc_count * sizeof(relocs[0])); 546968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (!relocs) { 547968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("malloc of %d entries for relocs failed\n", 548968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman reloc_count); 549968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 550968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman /* Collect up the relocations */ 551968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman reloc_idx = 0; 552968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman walk_relocs(collect_reloc); 553968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 554968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman /* Order the relocations for more efficient processing */ 555968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs); 556968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 557968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman /* Print the relocations */ 558968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (as_text) { 559968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman /* Print the relocations in a form suitable that 560968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman * gas will like. 561968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman */ 562968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman printf(".section \".data.reloc\",\"a\"\n"); 563968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman printf(".balign 4\n"); 564908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (i = 0; i < reloc_count; i++) { 565968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman printf("\t .long 0x%08lx\n", relocs[i]); 566968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 567968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman printf("\n"); 568968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 569968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman else { 570968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman unsigned char buf[4]; 571968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman buf[0] = buf[1] = buf[2] = buf[3] = 0; 572968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman /* Print a stop */ 573968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); 574968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman /* Now print each relocation */ 575908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (i = 0; i < reloc_count; i++) { 576968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman buf[0] = (relocs[i] >> 0) & 0xff; 577968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman buf[1] = (relocs[i] >> 8) & 0xff; 578968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman buf[2] = (relocs[i] >> 16) & 0xff; 579968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman buf[3] = (relocs[i] >> 24) & 0xff; 580968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); 581968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 582968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 583968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 584968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 585968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanstatic void usage(void) 586968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 5876a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal die("relocs [--abs-syms |--abs-relocs | --text] vmlinux\n"); 588968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 589968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 590968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biedermanint main(int argc, char **argv) 591968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman{ 5926a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal int show_absolute_syms, show_absolute_relocs; 593968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman int as_text; 594968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman const char *fname; 595968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman FILE *fp; 596968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman int i; 597968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman 5986a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal show_absolute_syms = 0; 5996a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal show_absolute_relocs = 0; 600968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman as_text = 0; 601968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman fname = NULL; 602908ec7afacfdc83dc10938ed1d3c38b3526034ecH. Peter Anvin for (i = 1; i < argc; i++) { 603968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman char *arg = argv[i]; 604968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (*arg == '-') { 6056a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal if (strcmp(argv[1], "--abs-syms") == 0) { 6066a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal show_absolute_syms = 1; 6076a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal continue; 6086a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal } 6096a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal 6106a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal if (strcmp(argv[1], "--abs-relocs") == 0) { 6116a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal show_absolute_relocs = 1; 612968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman continue; 613968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 614968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman else if (strcmp(argv[1], "--text") == 0) { 615968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman as_text = 1; 616968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman continue; 617968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 618968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 619968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman else if (!fname) { 620968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman fname = arg; 621968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman continue; 622968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 623968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman usage(); 624968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 625968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (!fname) { 626968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman usage(); 627968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 628968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman fp = fopen(fname, "r"); 629968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman if (!fp) { 630968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman die("Cannot open %s: %s\n", 631968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman fname, strerror(errno)); 632968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 633968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman read_ehdr(fp); 634968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman read_shdrs(fp); 635968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman read_strtabs(fp); 636968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman read_symtabs(fp); 637968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman read_relocs(fp); 6386a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal if (show_absolute_syms) { 639968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman print_absolute_symbols(); 6406a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal return 0; 6416a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal } 6426a044b3a0a1829ef19bb29548ffe553f48e8d80cVivek Goyal if (show_absolute_relocs) { 643968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman print_absolute_relocs(); 644968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman return 0; 645968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman } 646968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman emit_relocs(as_text); 647968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman return 0; 648968de4f02621db35b8ae5239c8cfc6664fb872d8Eric W. Biederman} 649