0001
0002
0003
0004 #define ElfW(type) _ElfW(ELF_BITS, type)
0005 #define _ElfW(bits, type) __ElfW(bits, type)
0006 #define __ElfW(bits, type) Elf##bits##_##type
0007
0008 #define Elf_Addr ElfW(Addr)
0009 #define Elf_Ehdr ElfW(Ehdr)
0010 #define Elf_Phdr ElfW(Phdr)
0011 #define Elf_Shdr ElfW(Shdr)
0012 #define Elf_Sym ElfW(Sym)
0013
0014 static Elf_Ehdr ehdr;
0015 static unsigned long shnum;
0016 static unsigned int shstrndx;
0017 static unsigned int shsymtabndx;
0018 static unsigned int shxsymtabndx;
0019
0020 static int sym_index(Elf_Sym *sym);
0021
0022 struct relocs {
0023 uint32_t *offset;
0024 unsigned long count;
0025 unsigned long size;
0026 };
0027
0028 static struct relocs relocs16;
0029 static struct relocs relocs32;
0030 #if ELF_BITS == 64
0031 static struct relocs relocs32neg;
0032 static struct relocs relocs64;
0033 #define FMT PRIu64
0034 #else
0035 #define FMT PRIu32
0036 #endif
0037
0038 struct section {
0039 Elf_Shdr shdr;
0040 struct section *link;
0041 Elf_Sym *symtab;
0042 Elf32_Word *xsymtab;
0043 Elf_Rel *reltab;
0044 char *strtab;
0045 };
0046 static struct section *secs;
0047
0048 static const char * const sym_regex_kernel[S_NSYMTYPES] = {
0049
0050
0051
0052
0053
0054
0055 [S_ABS] =
0056 "^(xen_irq_disable_direct_reloc$|"
0057 "xen_save_fl_direct_reloc$|"
0058 "VDSO|"
0059 "__crc_)",
0060
0061
0062
0063
0064
0065 [S_REL] =
0066 "^(__init_(begin|end)|"
0067 "__x86_cpu_dev_(start|end)|"
0068 "(__parainstructions|__alt_instructions)(_end)?|"
0069 "(__iommu_table|__apicdrivers|__smp_locks)(_end)?|"
0070 "__(start|end)_pci_.*|"
0071 #if CONFIG_FW_LOADER
0072 "__(start|end)_builtin_fw|"
0073 #endif
0074 "__(start|stop)___ksymtab(_gpl)?|"
0075 "__(start|stop)___kcrctab(_gpl)?|"
0076 "__(start|stop)___param|"
0077 "__(start|stop)___modver|"
0078 "__(start|stop)___bug_table|"
0079 "__tracedata_(start|end)|"
0080 "__(start|stop)_notes|"
0081 "__end_rodata|"
0082 "__end_rodata_aligned|"
0083 "__initramfs_start|"
0084 "(jiffies|jiffies_64)|"
0085 #if ELF_BITS == 64
0086 "__per_cpu_load|"
0087 "init_per_cpu__.*|"
0088 "__end_rodata_hpage_align|"
0089 #endif
0090 "__vvar_page|"
0091 "_end)$"
0092 };
0093
0094
0095 static const char * const sym_regex_realmode[S_NSYMTYPES] = {
0096
0097
0098
0099
0100 [S_REL] =
0101 "^pa_",
0102
0103
0104
0105
0106 [S_SEG] =
0107 "^real_mode_seg$",
0108
0109
0110
0111
0112
0113 [S_LIN] =
0114 "^pa_",
0115 };
0116
0117 static const char * const *sym_regex;
0118
0119 static regex_t sym_regex_c[S_NSYMTYPES];
0120 static int is_reloc(enum symtype type, const char *sym_name)
0121 {
0122 return sym_regex[type] &&
0123 !regexec(&sym_regex_c[type], sym_name, 0, NULL, 0);
0124 }
0125
0126 static void regex_init(int use_real_mode)
0127 {
0128 char errbuf[128];
0129 int err;
0130 int i;
0131
0132 if (use_real_mode)
0133 sym_regex = sym_regex_realmode;
0134 else
0135 sym_regex = sym_regex_kernel;
0136
0137 for (i = 0; i < S_NSYMTYPES; i++) {
0138 if (!sym_regex[i])
0139 continue;
0140
0141 err = regcomp(&sym_regex_c[i], sym_regex[i],
0142 REG_EXTENDED|REG_NOSUB);
0143
0144 if (err) {
0145 regerror(err, &sym_regex_c[i], errbuf, sizeof(errbuf));
0146 die("%s", errbuf);
0147 }
0148 }
0149 }
0150
0151 static const char *sym_type(unsigned type)
0152 {
0153 static const char *type_name[] = {
0154 #define SYM_TYPE(X) [X] = #X
0155 SYM_TYPE(STT_NOTYPE),
0156 SYM_TYPE(STT_OBJECT),
0157 SYM_TYPE(STT_FUNC),
0158 SYM_TYPE(STT_SECTION),
0159 SYM_TYPE(STT_FILE),
0160 SYM_TYPE(STT_COMMON),
0161 SYM_TYPE(STT_TLS),
0162 #undef SYM_TYPE
0163 };
0164 const char *name = "unknown sym type name";
0165 if (type < ARRAY_SIZE(type_name)) {
0166 name = type_name[type];
0167 }
0168 return name;
0169 }
0170
0171 static const char *sym_bind(unsigned bind)
0172 {
0173 static const char *bind_name[] = {
0174 #define SYM_BIND(X) [X] = #X
0175 SYM_BIND(STB_LOCAL),
0176 SYM_BIND(STB_GLOBAL),
0177 SYM_BIND(STB_WEAK),
0178 #undef SYM_BIND
0179 };
0180 const char *name = "unknown sym bind name";
0181 if (bind < ARRAY_SIZE(bind_name)) {
0182 name = bind_name[bind];
0183 }
0184 return name;
0185 }
0186
0187 static const char *sym_visibility(unsigned visibility)
0188 {
0189 static const char *visibility_name[] = {
0190 #define SYM_VISIBILITY(X) [X] = #X
0191 SYM_VISIBILITY(STV_DEFAULT),
0192 SYM_VISIBILITY(STV_INTERNAL),
0193 SYM_VISIBILITY(STV_HIDDEN),
0194 SYM_VISIBILITY(STV_PROTECTED),
0195 #undef SYM_VISIBILITY
0196 };
0197 const char *name = "unknown sym visibility name";
0198 if (visibility < ARRAY_SIZE(visibility_name)) {
0199 name = visibility_name[visibility];
0200 }
0201 return name;
0202 }
0203
0204 static const char *rel_type(unsigned type)
0205 {
0206 static const char *type_name[] = {
0207 #define REL_TYPE(X) [X] = #X
0208 #if ELF_BITS == 64
0209 REL_TYPE(R_X86_64_NONE),
0210 REL_TYPE(R_X86_64_64),
0211 REL_TYPE(R_X86_64_PC64),
0212 REL_TYPE(R_X86_64_PC32),
0213 REL_TYPE(R_X86_64_GOT32),
0214 REL_TYPE(R_X86_64_PLT32),
0215 REL_TYPE(R_X86_64_COPY),
0216 REL_TYPE(R_X86_64_GLOB_DAT),
0217 REL_TYPE(R_X86_64_JUMP_SLOT),
0218 REL_TYPE(R_X86_64_RELATIVE),
0219 REL_TYPE(R_X86_64_GOTPCREL),
0220 REL_TYPE(R_X86_64_32),
0221 REL_TYPE(R_X86_64_32S),
0222 REL_TYPE(R_X86_64_16),
0223 REL_TYPE(R_X86_64_PC16),
0224 REL_TYPE(R_X86_64_8),
0225 REL_TYPE(R_X86_64_PC8),
0226 #else
0227 REL_TYPE(R_386_NONE),
0228 REL_TYPE(R_386_32),
0229 REL_TYPE(R_386_PC32),
0230 REL_TYPE(R_386_GOT32),
0231 REL_TYPE(R_386_PLT32),
0232 REL_TYPE(R_386_COPY),
0233 REL_TYPE(R_386_GLOB_DAT),
0234 REL_TYPE(R_386_JMP_SLOT),
0235 REL_TYPE(R_386_RELATIVE),
0236 REL_TYPE(R_386_GOTOFF),
0237 REL_TYPE(R_386_GOTPC),
0238 REL_TYPE(R_386_8),
0239 REL_TYPE(R_386_PC8),
0240 REL_TYPE(R_386_16),
0241 REL_TYPE(R_386_PC16),
0242 #endif
0243 #undef REL_TYPE
0244 };
0245 const char *name = "unknown type rel type name";
0246 if (type < ARRAY_SIZE(type_name) && type_name[type]) {
0247 name = type_name[type];
0248 }
0249 return name;
0250 }
0251
0252 static const char *sec_name(unsigned shndx)
0253 {
0254 const char *sec_strtab;
0255 const char *name;
0256 sec_strtab = secs[shstrndx].strtab;
0257 name = "<noname>";
0258 if (shndx < shnum) {
0259 name = sec_strtab + secs[shndx].shdr.sh_name;
0260 }
0261 else if (shndx == SHN_ABS) {
0262 name = "ABSOLUTE";
0263 }
0264 else if (shndx == SHN_COMMON) {
0265 name = "COMMON";
0266 }
0267 return name;
0268 }
0269
0270 static const char *sym_name(const char *sym_strtab, Elf_Sym *sym)
0271 {
0272 const char *name;
0273 name = "<noname>";
0274 if (sym->st_name) {
0275 name = sym_strtab + sym->st_name;
0276 }
0277 else {
0278 name = sec_name(sym_index(sym));
0279 }
0280 return name;
0281 }
0282
0283 static Elf_Sym *sym_lookup(const char *symname)
0284 {
0285 int i;
0286 for (i = 0; i < shnum; i++) {
0287 struct section *sec = &secs[i];
0288 long nsyms;
0289 char *strtab;
0290 Elf_Sym *symtab;
0291 Elf_Sym *sym;
0292
0293 if (sec->shdr.sh_type != SHT_SYMTAB)
0294 continue;
0295
0296 nsyms = sec->shdr.sh_size/sizeof(Elf_Sym);
0297 symtab = sec->symtab;
0298 strtab = sec->link->strtab;
0299
0300 for (sym = symtab; --nsyms >= 0; sym++) {
0301 if (!sym->st_name)
0302 continue;
0303 if (strcmp(symname, strtab + sym->st_name) == 0)
0304 return sym;
0305 }
0306 }
0307 return 0;
0308 }
0309
0310 #if BYTE_ORDER == LITTLE_ENDIAN
0311 #define le16_to_cpu(val) (val)
0312 #define le32_to_cpu(val) (val)
0313 #define le64_to_cpu(val) (val)
0314 #endif
0315 #if BYTE_ORDER == BIG_ENDIAN
0316 #define le16_to_cpu(val) bswap_16(val)
0317 #define le32_to_cpu(val) bswap_32(val)
0318 #define le64_to_cpu(val) bswap_64(val)
0319 #endif
0320
0321 static uint16_t elf16_to_cpu(uint16_t val)
0322 {
0323 return le16_to_cpu(val);
0324 }
0325
0326 static uint32_t elf32_to_cpu(uint32_t val)
0327 {
0328 return le32_to_cpu(val);
0329 }
0330
0331 #define elf_half_to_cpu(x) elf16_to_cpu(x)
0332 #define elf_word_to_cpu(x) elf32_to_cpu(x)
0333
0334 #if ELF_BITS == 64
0335 static uint64_t elf64_to_cpu(uint64_t val)
0336 {
0337 return le64_to_cpu(val);
0338 }
0339 #define elf_addr_to_cpu(x) elf64_to_cpu(x)
0340 #define elf_off_to_cpu(x) elf64_to_cpu(x)
0341 #define elf_xword_to_cpu(x) elf64_to_cpu(x)
0342 #else
0343 #define elf_addr_to_cpu(x) elf32_to_cpu(x)
0344 #define elf_off_to_cpu(x) elf32_to_cpu(x)
0345 #define elf_xword_to_cpu(x) elf32_to_cpu(x)
0346 #endif
0347
0348 static int sym_index(Elf_Sym *sym)
0349 {
0350 Elf_Sym *symtab = secs[shsymtabndx].symtab;
0351 Elf32_Word *xsymtab = secs[shxsymtabndx].xsymtab;
0352 unsigned long offset;
0353 int index;
0354
0355 if (sym->st_shndx != SHN_XINDEX)
0356 return sym->st_shndx;
0357
0358
0359 offset = (unsigned long)sym - (unsigned long)symtab;
0360 index = offset / sizeof(*sym);
0361
0362 return elf32_to_cpu(xsymtab[index]);
0363 }
0364
0365 static void read_ehdr(FILE *fp)
0366 {
0367 if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) {
0368 die("Cannot read ELF header: %s\n",
0369 strerror(errno));
0370 }
0371 if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) {
0372 die("No ELF magic\n");
0373 }
0374 if (ehdr.e_ident[EI_CLASS] != ELF_CLASS) {
0375 die("Not a %d bit executable\n", ELF_BITS);
0376 }
0377 if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) {
0378 die("Not a LSB ELF executable\n");
0379 }
0380 if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
0381 die("Unknown ELF version\n");
0382 }
0383
0384 ehdr.e_type = elf_half_to_cpu(ehdr.e_type);
0385 ehdr.e_machine = elf_half_to_cpu(ehdr.e_machine);
0386 ehdr.e_version = elf_word_to_cpu(ehdr.e_version);
0387 ehdr.e_entry = elf_addr_to_cpu(ehdr.e_entry);
0388 ehdr.e_phoff = elf_off_to_cpu(ehdr.e_phoff);
0389 ehdr.e_shoff = elf_off_to_cpu(ehdr.e_shoff);
0390 ehdr.e_flags = elf_word_to_cpu(ehdr.e_flags);
0391 ehdr.e_ehsize = elf_half_to_cpu(ehdr.e_ehsize);
0392 ehdr.e_phentsize = elf_half_to_cpu(ehdr.e_phentsize);
0393 ehdr.e_phnum = elf_half_to_cpu(ehdr.e_phnum);
0394 ehdr.e_shentsize = elf_half_to_cpu(ehdr.e_shentsize);
0395 ehdr.e_shnum = elf_half_to_cpu(ehdr.e_shnum);
0396 ehdr.e_shstrndx = elf_half_to_cpu(ehdr.e_shstrndx);
0397
0398 shnum = ehdr.e_shnum;
0399 shstrndx = ehdr.e_shstrndx;
0400
0401 if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN))
0402 die("Unsupported ELF header type\n");
0403 if (ehdr.e_machine != ELF_MACHINE)
0404 die("Not for %s\n", ELF_MACHINE_NAME);
0405 if (ehdr.e_version != EV_CURRENT)
0406 die("Unknown ELF version\n");
0407 if (ehdr.e_ehsize != sizeof(Elf_Ehdr))
0408 die("Bad Elf header size\n");
0409 if (ehdr.e_phentsize != sizeof(Elf_Phdr))
0410 die("Bad program header entry\n");
0411 if (ehdr.e_shentsize != sizeof(Elf_Shdr))
0412 die("Bad section header entry\n");
0413
0414
0415 if (shnum == SHN_UNDEF || shstrndx == SHN_XINDEX) {
0416 Elf_Shdr shdr;
0417
0418 if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0)
0419 die("Seek to %" FMT " failed: %s\n", ehdr.e_shoff, strerror(errno));
0420
0421 if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
0422 die("Cannot read initial ELF section header: %s\n", strerror(errno));
0423
0424 if (shnum == SHN_UNDEF)
0425 shnum = elf_xword_to_cpu(shdr.sh_size);
0426
0427 if (shstrndx == SHN_XINDEX)
0428 shstrndx = elf_word_to_cpu(shdr.sh_link);
0429 }
0430
0431 if (shstrndx >= shnum)
0432 die("String table index out of bounds\n");
0433 }
0434
0435 static void read_shdrs(FILE *fp)
0436 {
0437 int i;
0438 Elf_Shdr shdr;
0439
0440 secs = calloc(shnum, sizeof(struct section));
0441 if (!secs) {
0442 die("Unable to allocate %ld section headers\n",
0443 shnum);
0444 }
0445 if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) {
0446 die("Seek to %" FMT " failed: %s\n",
0447 ehdr.e_shoff, strerror(errno));
0448 }
0449 for (i = 0; i < shnum; i++) {
0450 struct section *sec = &secs[i];
0451 if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
0452 die("Cannot read ELF section headers %d/%ld: %s\n",
0453 i, shnum, strerror(errno));
0454 sec->shdr.sh_name = elf_word_to_cpu(shdr.sh_name);
0455 sec->shdr.sh_type = elf_word_to_cpu(shdr.sh_type);
0456 sec->shdr.sh_flags = elf_xword_to_cpu(shdr.sh_flags);
0457 sec->shdr.sh_addr = elf_addr_to_cpu(shdr.sh_addr);
0458 sec->shdr.sh_offset = elf_off_to_cpu(shdr.sh_offset);
0459 sec->shdr.sh_size = elf_xword_to_cpu(shdr.sh_size);
0460 sec->shdr.sh_link = elf_word_to_cpu(shdr.sh_link);
0461 sec->shdr.sh_info = elf_word_to_cpu(shdr.sh_info);
0462 sec->shdr.sh_addralign = elf_xword_to_cpu(shdr.sh_addralign);
0463 sec->shdr.sh_entsize = elf_xword_to_cpu(shdr.sh_entsize);
0464 if (sec->shdr.sh_link < shnum)
0465 sec->link = &secs[sec->shdr.sh_link];
0466 }
0467
0468 }
0469
0470 static void read_strtabs(FILE *fp)
0471 {
0472 int i;
0473 for (i = 0; i < shnum; i++) {
0474 struct section *sec = &secs[i];
0475 if (sec->shdr.sh_type != SHT_STRTAB) {
0476 continue;
0477 }
0478 sec->strtab = malloc(sec->shdr.sh_size);
0479 if (!sec->strtab) {
0480 die("malloc of %" FMT " bytes for strtab failed\n",
0481 sec->shdr.sh_size);
0482 }
0483 if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
0484 die("Seek to %" FMT " failed: %s\n",
0485 sec->shdr.sh_offset, strerror(errno));
0486 }
0487 if (fread(sec->strtab, 1, sec->shdr.sh_size, fp)
0488 != sec->shdr.sh_size) {
0489 die("Cannot read symbol table: %s\n",
0490 strerror(errno));
0491 }
0492 }
0493 }
0494
0495 static void read_symtabs(FILE *fp)
0496 {
0497 int i,j;
0498
0499 for (i = 0; i < shnum; i++) {
0500 struct section *sec = &secs[i];
0501 int num_syms;
0502
0503 switch (sec->shdr.sh_type) {
0504 case SHT_SYMTAB_SHNDX:
0505 sec->xsymtab = malloc(sec->shdr.sh_size);
0506 if (!sec->xsymtab) {
0507 die("malloc of %" FMT " bytes for xsymtab failed\n",
0508 sec->shdr.sh_size);
0509 }
0510 if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
0511 die("Seek to %" FMT " failed: %s\n",
0512 sec->shdr.sh_offset, strerror(errno));
0513 }
0514 if (fread(sec->xsymtab, 1, sec->shdr.sh_size, fp)
0515 != sec->shdr.sh_size) {
0516 die("Cannot read extended symbol table: %s\n",
0517 strerror(errno));
0518 }
0519 shxsymtabndx = i;
0520 continue;
0521
0522 case SHT_SYMTAB:
0523 num_syms = sec->shdr.sh_size / sizeof(Elf_Sym);
0524
0525 sec->symtab = malloc(sec->shdr.sh_size);
0526 if (!sec->symtab) {
0527 die("malloc of %" FMT " bytes for symtab failed\n",
0528 sec->shdr.sh_size);
0529 }
0530 if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
0531 die("Seek to %" FMT " failed: %s\n",
0532 sec->shdr.sh_offset, strerror(errno));
0533 }
0534 if (fread(sec->symtab, 1, sec->shdr.sh_size, fp)
0535 != sec->shdr.sh_size) {
0536 die("Cannot read symbol table: %s\n",
0537 strerror(errno));
0538 }
0539 for (j = 0; j < num_syms; j++) {
0540 Elf_Sym *sym = &sec->symtab[j];
0541
0542 sym->st_name = elf_word_to_cpu(sym->st_name);
0543 sym->st_value = elf_addr_to_cpu(sym->st_value);
0544 sym->st_size = elf_xword_to_cpu(sym->st_size);
0545 sym->st_shndx = elf_half_to_cpu(sym->st_shndx);
0546 }
0547 shsymtabndx = i;
0548 continue;
0549
0550 default:
0551 continue;
0552 }
0553 }
0554 }
0555
0556
0557 static void read_relocs(FILE *fp)
0558 {
0559 int i,j;
0560 for (i = 0; i < shnum; i++) {
0561 struct section *sec = &secs[i];
0562 if (sec->shdr.sh_type != SHT_REL_TYPE) {
0563 continue;
0564 }
0565 sec->reltab = malloc(sec->shdr.sh_size);
0566 if (!sec->reltab) {
0567 die("malloc of %" FMT " bytes for relocs failed\n",
0568 sec->shdr.sh_size);
0569 }
0570 if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {
0571 die("Seek to %" FMT " failed: %s\n",
0572 sec->shdr.sh_offset, strerror(errno));
0573 }
0574 if (fread(sec->reltab, 1, sec->shdr.sh_size, fp)
0575 != sec->shdr.sh_size) {
0576 die("Cannot read symbol table: %s\n",
0577 strerror(errno));
0578 }
0579 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
0580 Elf_Rel *rel = &sec->reltab[j];
0581 rel->r_offset = elf_addr_to_cpu(rel->r_offset);
0582 rel->r_info = elf_xword_to_cpu(rel->r_info);
0583 #if (SHT_REL_TYPE == SHT_RELA)
0584 rel->r_addend = elf_xword_to_cpu(rel->r_addend);
0585 #endif
0586 }
0587 }
0588 }
0589
0590
0591 static void print_absolute_symbols(void)
0592 {
0593 int i;
0594 const char *format;
0595
0596 if (ELF_BITS == 64)
0597 format = "%5d %016"PRIx64" %5"PRId64" %10s %10s %12s %s\n";
0598 else
0599 format = "%5d %08"PRIx32" %5"PRId32" %10s %10s %12s %s\n";
0600
0601 printf("Absolute symbols\n");
0602 printf(" Num: Value Size Type Bind Visibility Name\n");
0603 for (i = 0; i < shnum; i++) {
0604 struct section *sec = &secs[i];
0605 char *sym_strtab;
0606 int j;
0607
0608 if (sec->shdr.sh_type != SHT_SYMTAB) {
0609 continue;
0610 }
0611 sym_strtab = sec->link->strtab;
0612 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Sym); j++) {
0613 Elf_Sym *sym;
0614 const char *name;
0615 sym = &sec->symtab[j];
0616 name = sym_name(sym_strtab, sym);
0617 if (sym->st_shndx != SHN_ABS) {
0618 continue;
0619 }
0620 printf(format,
0621 j, sym->st_value, sym->st_size,
0622 sym_type(ELF_ST_TYPE(sym->st_info)),
0623 sym_bind(ELF_ST_BIND(sym->st_info)),
0624 sym_visibility(ELF_ST_VISIBILITY(sym->st_other)),
0625 name);
0626 }
0627 }
0628 printf("\n");
0629 }
0630
0631 static void print_absolute_relocs(void)
0632 {
0633 int i, printed = 0;
0634 const char *format;
0635
0636 if (ELF_BITS == 64)
0637 format = "%016"PRIx64" %016"PRIx64" %10s %016"PRIx64" %s\n";
0638 else
0639 format = "%08"PRIx32" %08"PRIx32" %10s %08"PRIx32" %s\n";
0640
0641 for (i = 0; i < shnum; i++) {
0642 struct section *sec = &secs[i];
0643 struct section *sec_applies, *sec_symtab;
0644 char *sym_strtab;
0645 Elf_Sym *sh_symtab;
0646 int j;
0647 if (sec->shdr.sh_type != SHT_REL_TYPE) {
0648 continue;
0649 }
0650 sec_symtab = sec->link;
0651 sec_applies = &secs[sec->shdr.sh_info];
0652 if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
0653 continue;
0654 }
0655 sh_symtab = sec_symtab->symtab;
0656 sym_strtab = sec_symtab->link->strtab;
0657 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
0658 Elf_Rel *rel;
0659 Elf_Sym *sym;
0660 const char *name;
0661 rel = &sec->reltab[j];
0662 sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
0663 name = sym_name(sym_strtab, sym);
0664 if (sym->st_shndx != SHN_ABS) {
0665 continue;
0666 }
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681 if (is_reloc(S_ABS, name) || is_reloc(S_REL, name))
0682 continue;
0683
0684 if (!printed) {
0685 printf("WARNING: Absolute relocations"
0686 " present\n");
0687 printf("Offset Info Type Sym.Value "
0688 "Sym.Name\n");
0689 printed = 1;
0690 }
0691
0692 printf(format,
0693 rel->r_offset,
0694 rel->r_info,
0695 rel_type(ELF_R_TYPE(rel->r_info)),
0696 sym->st_value,
0697 name);
0698 }
0699 }
0700
0701 if (printed)
0702 printf("\n");
0703 }
0704
0705 static void add_reloc(struct relocs *r, uint32_t offset)
0706 {
0707 if (r->count == r->size) {
0708 unsigned long newsize = r->size + 50000;
0709 void *mem = realloc(r->offset, newsize * sizeof(r->offset[0]));
0710
0711 if (!mem)
0712 die("realloc of %ld entries for relocs failed\n",
0713 newsize);
0714 r->offset = mem;
0715 r->size = newsize;
0716 }
0717 r->offset[r->count++] = offset;
0718 }
0719
0720 static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel,
0721 Elf_Sym *sym, const char *symname))
0722 {
0723 int i;
0724
0725 for (i = 0; i < shnum; i++) {
0726 char *sym_strtab;
0727 Elf_Sym *sh_symtab;
0728 struct section *sec_applies, *sec_symtab;
0729 int j;
0730 struct section *sec = &secs[i];
0731
0732 if (sec->shdr.sh_type != SHT_REL_TYPE) {
0733 continue;
0734 }
0735 sec_symtab = sec->link;
0736 sec_applies = &secs[sec->shdr.sh_info];
0737 if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
0738 continue;
0739 }
0740 sh_symtab = sec_symtab->symtab;
0741 sym_strtab = sec_symtab->link->strtab;
0742 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
0743 Elf_Rel *rel = &sec->reltab[j];
0744 Elf_Sym *sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
0745 const char *symname = sym_name(sym_strtab, sym);
0746
0747 process(sec, rel, sym, symname);
0748 }
0749 }
0750 }
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774
0775 static int per_cpu_shndx = -1;
0776 static Elf_Addr per_cpu_load_addr;
0777
0778 static void percpu_init(void)
0779 {
0780 int i;
0781 for (i = 0; i < shnum; i++) {
0782 ElfW(Sym) *sym;
0783 if (strcmp(sec_name(i), ".data..percpu"))
0784 continue;
0785
0786 if (secs[i].shdr.sh_addr != 0)
0787 return;
0788
0789 sym = sym_lookup("__per_cpu_load");
0790 if (!sym)
0791 die("can't find __per_cpu_load\n");
0792
0793 per_cpu_shndx = i;
0794 per_cpu_load_addr = sym->st_value;
0795 return;
0796 }
0797 }
0798
0799 #if ELF_BITS == 64
0800
0801
0802
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812
0813
0814
0815
0816 static int is_percpu_sym(ElfW(Sym) *sym, const char *symname)
0817 {
0818 int shndx = sym_index(sym);
0819
0820 return (shndx == per_cpu_shndx) &&
0821 strcmp(symname, "__init_begin") &&
0822 strcmp(symname, "__per_cpu_load") &&
0823 strncmp(symname, "init_per_cpu_", 13);
0824 }
0825
0826
0827 static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
0828 const char *symname)
0829 {
0830 unsigned r_type = ELF64_R_TYPE(rel->r_info);
0831 ElfW(Addr) offset = rel->r_offset;
0832 int shn_abs = (sym->st_shndx == SHN_ABS) && !is_reloc(S_REL, symname);
0833
0834 if (sym->st_shndx == SHN_UNDEF)
0835 return 0;
0836
0837
0838
0839
0840 if (sec->shdr.sh_info == per_cpu_shndx)
0841 offset += per_cpu_load_addr;
0842
0843 switch (r_type) {
0844 case R_X86_64_NONE:
0845
0846 break;
0847
0848 case R_X86_64_PC32:
0849 case R_X86_64_PLT32:
0850
0851
0852
0853
0854
0855
0856 if (is_percpu_sym(sym, symname))
0857 add_reloc(&relocs32neg, offset);
0858 break;
0859
0860 case R_X86_64_PC64:
0861
0862
0863
0864 if (is_percpu_sym(sym, symname))
0865 die("Invalid R_X86_64_PC64 relocation against per-CPU symbol %s\n",
0866 symname);
0867 break;
0868
0869 case R_X86_64_32:
0870 case R_X86_64_32S:
0871 case R_X86_64_64:
0872
0873
0874
0875 if (is_percpu_sym(sym, symname))
0876 break;
0877
0878 if (shn_abs) {
0879
0880
0881
0882
0883 if (is_reloc(S_ABS, symname))
0884 break;
0885
0886 die("Invalid absolute %s relocation: %s\n",
0887 rel_type(r_type), symname);
0888 break;
0889 }
0890
0891
0892
0893
0894
0895
0896
0897 if ((int32_t)offset != (int64_t)offset)
0898 die("Relocation offset doesn't fit in 32 bits\n");
0899
0900 if (r_type == R_X86_64_64)
0901 add_reloc(&relocs64, offset);
0902 else
0903 add_reloc(&relocs32, offset);
0904 break;
0905
0906 default:
0907 die("Unsupported relocation type: %s (%d)\n",
0908 rel_type(r_type), r_type);
0909 break;
0910 }
0911
0912 return 0;
0913 }
0914
0915 #else
0916
0917 static int do_reloc32(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
0918 const char *symname)
0919 {
0920 unsigned r_type = ELF32_R_TYPE(rel->r_info);
0921 int shn_abs = (sym->st_shndx == SHN_ABS) && !is_reloc(S_REL, symname);
0922
0923 switch (r_type) {
0924 case R_386_NONE:
0925 case R_386_PC32:
0926 case R_386_PC16:
0927 case R_386_PC8:
0928 case R_386_PLT32:
0929
0930
0931
0932
0933
0934 break;
0935
0936 case R_386_32:
0937 if (shn_abs) {
0938
0939
0940
0941
0942 if (is_reloc(S_ABS, symname))
0943 break;
0944
0945 die("Invalid absolute %s relocation: %s\n",
0946 rel_type(r_type), symname);
0947 break;
0948 }
0949
0950 add_reloc(&relocs32, rel->r_offset);
0951 break;
0952
0953 default:
0954 die("Unsupported relocation type: %s (%d)\n",
0955 rel_type(r_type), r_type);
0956 break;
0957 }
0958
0959 return 0;
0960 }
0961
0962 static int do_reloc_real(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
0963 const char *symname)
0964 {
0965 unsigned r_type = ELF32_R_TYPE(rel->r_info);
0966 int shn_abs = (sym->st_shndx == SHN_ABS) && !is_reloc(S_REL, symname);
0967
0968 switch (r_type) {
0969 case R_386_NONE:
0970 case R_386_PC32:
0971 case R_386_PC16:
0972 case R_386_PC8:
0973 case R_386_PLT32:
0974
0975
0976
0977
0978
0979 break;
0980
0981 case R_386_16:
0982 if (shn_abs) {
0983
0984
0985
0986
0987 if (is_reloc(S_ABS, symname))
0988 break;
0989
0990 if (is_reloc(S_SEG, symname)) {
0991 add_reloc(&relocs16, rel->r_offset);
0992 break;
0993 }
0994 } else {
0995 if (!is_reloc(S_LIN, symname))
0996 break;
0997 }
0998 die("Invalid %s %s relocation: %s\n",
0999 shn_abs ? "absolute" : "relative",
1000 rel_type(r_type), symname);
1001 break;
1002
1003 case R_386_32:
1004 if (shn_abs) {
1005
1006
1007
1008
1009 if (is_reloc(S_ABS, symname))
1010 break;
1011
1012 if (is_reloc(S_REL, symname)) {
1013 add_reloc(&relocs32, rel->r_offset);
1014 break;
1015 }
1016 } else {
1017 if (is_reloc(S_LIN, symname))
1018 add_reloc(&relocs32, rel->r_offset);
1019 break;
1020 }
1021 die("Invalid %s %s relocation: %s\n",
1022 shn_abs ? "absolute" : "relative",
1023 rel_type(r_type), symname);
1024 break;
1025
1026 default:
1027 die("Unsupported relocation type: %s (%d)\n",
1028 rel_type(r_type), r_type);
1029 break;
1030 }
1031
1032 return 0;
1033 }
1034
1035 #endif
1036
1037 static int cmp_relocs(const void *va, const void *vb)
1038 {
1039 const uint32_t *a, *b;
1040 a = va; b = vb;
1041 return (*a == *b)? 0 : (*a > *b)? 1 : -1;
1042 }
1043
1044 static void sort_relocs(struct relocs *r)
1045 {
1046 qsort(r->offset, r->count, sizeof(r->offset[0]), cmp_relocs);
1047 }
1048
1049 static int write32(uint32_t v, FILE *f)
1050 {
1051 unsigned char buf[4];
1052
1053 put_unaligned_le32(v, buf);
1054 return fwrite(buf, 1, 4, f) == 4 ? 0 : -1;
1055 }
1056
1057 static int write32_as_text(uint32_t v, FILE *f)
1058 {
1059 return fprintf(f, "\t.long 0x%08"PRIx32"\n", v) > 0 ? 0 : -1;
1060 }
1061
1062 static void emit_relocs(int as_text, int use_real_mode)
1063 {
1064 int i;
1065 int (*write_reloc)(uint32_t, FILE *) = write32;
1066 int (*do_reloc)(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
1067 const char *symname);
1068
1069 #if ELF_BITS == 64
1070 if (!use_real_mode)
1071 do_reloc = do_reloc64;
1072 else
1073 die("--realmode not valid for a 64-bit ELF file");
1074 #else
1075 if (!use_real_mode)
1076 do_reloc = do_reloc32;
1077 else
1078 do_reloc = do_reloc_real;
1079 #endif
1080
1081
1082 walk_relocs(do_reloc);
1083
1084 if (relocs16.count && !use_real_mode)
1085 die("Segment relocations found but --realmode not specified\n");
1086
1087
1088 sort_relocs(&relocs32);
1089 #if ELF_BITS == 64
1090 sort_relocs(&relocs32neg);
1091 sort_relocs(&relocs64);
1092 #else
1093 sort_relocs(&relocs16);
1094 #endif
1095
1096
1097 if (as_text) {
1098
1099
1100
1101 printf(".section \".data.reloc\",\"a\"\n");
1102 printf(".balign 4\n");
1103 write_reloc = write32_as_text;
1104 }
1105
1106 if (use_real_mode) {
1107 write_reloc(relocs16.count, stdout);
1108 for (i = 0; i < relocs16.count; i++)
1109 write_reloc(relocs16.offset[i], stdout);
1110
1111 write_reloc(relocs32.count, stdout);
1112 for (i = 0; i < relocs32.count; i++)
1113 write_reloc(relocs32.offset[i], stdout);
1114 } else {
1115 #if ELF_BITS == 64
1116
1117 write_reloc(0, stdout);
1118
1119
1120 for (i = 0; i < relocs64.count; i++)
1121 write_reloc(relocs64.offset[i], stdout);
1122
1123
1124 write_reloc(0, stdout);
1125
1126
1127 for (i = 0; i < relocs32neg.count; i++)
1128 write_reloc(relocs32neg.offset[i], stdout);
1129 #endif
1130
1131
1132 write_reloc(0, stdout);
1133
1134
1135 for (i = 0; i < relocs32.count; i++)
1136 write_reloc(relocs32.offset[i], stdout);
1137 }
1138 }
1139
1140
1141
1142
1143
1144
1145
1146 static int do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
1147 const char *symname)
1148 {
1149 printf("%s\t%s\t%s\t%s\n",
1150 sec_name(sec->shdr.sh_info),
1151 rel_type(ELF_R_TYPE(rel->r_info)),
1152 symname,
1153 sec_name(sym_index(sym)));
1154 return 0;
1155 }
1156
1157 static void print_reloc_info(void)
1158 {
1159 printf("reloc section\treloc type\tsymbol\tsymbol section\n");
1160 walk_relocs(do_reloc_info);
1161 }
1162
1163 #if ELF_BITS == 64
1164 # define process process_64
1165 #else
1166 # define process process_32
1167 #endif
1168
1169 void process(FILE *fp, int use_real_mode, int as_text,
1170 int show_absolute_syms, int show_absolute_relocs,
1171 int show_reloc_info)
1172 {
1173 regex_init(use_real_mode);
1174 read_ehdr(fp);
1175 read_shdrs(fp);
1176 read_strtabs(fp);
1177 read_symtabs(fp);
1178 read_relocs(fp);
1179 if (ELF_BITS == 64)
1180 percpu_init();
1181 if (show_absolute_syms) {
1182 print_absolute_symbols();
1183 return;
1184 }
1185 if (show_absolute_relocs) {
1186 print_absolute_relocs();
1187 return;
1188 }
1189 if (show_reloc_info) {
1190 print_reloc_info();
1191 return;
1192 }
1193 emit_relocs(as_text, use_real_mode);
1194 }