-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <elf.h>
-#include <byteswap.h>
-#define USE_BSD
-#include <endian.h>
-#include <regex.h>
-#include <tools/le_byteshift.h>
+/* This is included from relocs_32/64.c */
#define ElfW(type) _ElfW(ELF_BITS, type)
#define _ElfW(bits, type) __ElfW(bits, type)
#define __ElfW(bits, type) Elf##bits##_##type
-#ifndef ELF_BITS
-#define ELF_BITS 32
-#endif
-
-#if (ELF_BITS == 64)
-#define ELF_MACHINE EM_X86_64
-#define ELF_MACHINE_NAME "x86_64"
-#define SHT_REL_TYPE SHT_RELA
-#define Elf_Rel Elf64_Rela
-#else
-#define ELF_MACHINE EM_386
-#define ELF_MACHINE_NAME "i386"
-#define SHT_REL_TYPE SHT_REL
-#define Elf_Rel ElfW(Rel)
-#endif
-
-#if (ELF_BITS == 64)
-#define ELF_CLASS ELFCLASS64
-#define ELF_R_SYM(val) ELF64_R_SYM(val)
-#define ELF_R_TYPE(val) ELF64_R_TYPE(val)
-#define ELF_ST_TYPE(o) ELF64_ST_TYPE(o)
-#define ELF_ST_BIND(o) ELF64_ST_BIND(o)
-#define ELF_ST_VISIBILITY(o) ELF64_ST_VISIBILITY(o)
-#else
-#define ELF_CLASS ELFCLASS32
-#define ELF_R_SYM(val) ELF32_R_SYM(val)
-#define ELF_R_TYPE(val) ELF32_R_TYPE(val)
-#define ELF_ST_TYPE(o) ELF32_ST_TYPE(o)
-#define ELF_ST_BIND(o) ELF32_ST_BIND(o)
-#define ELF_ST_VISIBILITY(o) ELF32_ST_VISIBILITY(o)
-#endif
-
#define Elf_Addr ElfW(Addr)
#define Elf_Ehdr ElfW(Ehdr)
#define Elf_Phdr ElfW(Phdr)
#define Elf_Shdr ElfW(Shdr)
#define Elf_Sym ElfW(Sym)
-static void die(char *fmt, ...);
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
static Elf_Ehdr ehdr;
struct relocs {
};
static struct section *secs;
-enum symtype {
- S_ABS,
- S_REL,
- S_SEG,
- S_LIN,
- S_NSYMTYPES
-};
-
static const char * const sym_regex_kernel[S_NSYMTYPES] = {
/*
* Following symbols have been audited. There values are constant and do
"^(xen_irq_disable_direct_reloc$|"
"xen_save_fl_direct_reloc$|"
"VDSO|"
-#if (ELF_BITS == 64)
+#if ELF_BITS == 64
"__vvar_page|"
#endif
"__crc_)",
"__end_rodata|"
"__initramfs_start|"
"(jiffies|jiffies_64)|"
-#if (ELF_BITS == 64)
+#if ELF_BITS == 64
"__per_cpu_load|"
"init_per_cpu__.*|"
"__end_rodata_hpage_align|"
}
}
-static void die(char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- exit(1);
-}
-
static const char *sym_type(unsigned type)
{
static const char *type_name[] = {
{
static const char *type_name[] = {
#define REL_TYPE(X) [X] = #X
-#if (ELF_BITS == 64)
+#if ELF_BITS == 64
REL_TYPE(R_X86_64_NONE),
REL_TYPE(R_X86_64_64),
REL_TYPE(R_X86_64_PC32),
#define elf_half_to_cpu(x) elf16_to_cpu(x)
#define elf_word_to_cpu(x) elf32_to_cpu(x)
-#if (ELF_BITS == 64)
+#if ELF_BITS == 64
static uint64_t elf64_to_cpu(uint64_t val)
{
return le64_to_cpu(val);
int i;
const char *format;
- if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
+ if (ELF_BITS == 64)
format = "%5d %016"PRIx64" %5"PRId64" %10s %10s %12s %s\n";
else
format = "%5d %08"PRIx32" %5"PRId32" %10s %10s %12s %s\n";
int i, printed = 0;
const char *format;
- if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
+ if (ELF_BITS == 64)
format = "%016"PRIx64" %016"PRIx64" %10s %016"PRIx64" %s\n";
else
format = "%08"PRIx32" %08"PRIx32" %10s %08"PRIx32" %s\n";
}
}
+#if ELF_BITS == 64
+
/*
* Check to see if a symbol lies in the .data..percpu section.
* For some as yet not understood reason the "__init_begin"
strcmp(symname, "__init_begin");
}
+
static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
const char *symname)
{
return 0;
}
+#else
static int do_reloc32(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
const char *symname)
return 0;
}
+#endif
+
static int cmp_relocs(const void *va, const void *vb)
{
const uint32_t *a, *b;
int (*do_reloc)(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
const char *symname);
- if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
+#if ELF_BITS == 64
+ if (!use_real_mode)
do_reloc = do_reloc64;
- else if (!use_real_mode)
+ else
+ die("--realmode not valid for a 64-bit ELF file");
+#else
+ if (!use_real_mode)
do_reloc = do_reloc32;
else
do_reloc = do_reloc_real;
+#endif
/* Collect up the relocations */
walk_relocs(do_reloc);
for (i = 0; i < relocs32.count; i++)
write_reloc(relocs32.offset[i], stdout);
} else {
- if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
+ if (ELF_BITS == 64) {
/* Print a stop */
write_reloc(0, stdout);
}
}
-static void usage(void)
-{
- die("relocs [--abs-syms|--abs-relocs|--text|--realmode] vmlinux\n");
-}
+#if ELF_BITS == 64
+# define process process_64
+#else
+# define process process_32
+#endif
-int main(int argc, char **argv)
+void process(FILE *fp, int use_real_mode, int as_text,
+ int show_absolute_syms, int show_absolute_relocs)
{
- int show_absolute_syms, show_absolute_relocs;
- int as_text, use_real_mode;
- const char *fname;
- FILE *fp;
- int i;
-
- show_absolute_syms = 0;
- show_absolute_relocs = 0;
- as_text = 0;
- use_real_mode = 0;
- fname = NULL;
- for (i = 1; i < argc; i++) {
- char *arg = argv[i];
- if (*arg == '-') {
- if (strcmp(arg, "--abs-syms") == 0) {
- show_absolute_syms = 1;
- continue;
- }
- if (strcmp(arg, "--abs-relocs") == 0) {
- show_absolute_relocs = 1;
- continue;
- }
- if (strcmp(arg, "--text") == 0) {
- as_text = 1;
- continue;
- }
- if (strcmp(arg, "--realmode") == 0) {
- use_real_mode = 1;
- continue;
- }
- }
- else if (!fname) {
- fname = arg;
- continue;
- }
- usage();
- }
- if (!fname) {
- usage();
- }
regex_init(use_real_mode);
- fp = fopen(fname, "r");
- if (!fp) {
- die("Cannot open %s: %s\n",
- fname, strerror(errno));
- }
read_ehdr(fp);
read_shdrs(fp);
read_strtabs(fp);
read_symtabs(fp);
read_relocs(fp);
- if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
+ if (ELF_BITS == 64)
percpu_init();
if (show_absolute_syms) {
print_absolute_symbols();
- goto out;
+ return;
}
if (show_absolute_relocs) {
print_absolute_relocs();
- goto out;
+ return;
}
emit_relocs(as_text, use_real_mode);
-out:
- fclose(fp);
- return 0;
}
--- /dev/null
+#include "relocs.h"
+
+void die(char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ exit(1);
+}
+
+static void usage(void)
+{
+ die("relocs [--abs-syms|--abs-relocs|--text|--realmode] vmlinux\n");
+}
+
+int main(int argc, char **argv)
+{
+ int show_absolute_syms, show_absolute_relocs;
+ int as_text, use_real_mode;
+ const char *fname;
+ FILE *fp;
+ int i;
+ unsigned char e_ident[EI_NIDENT];
+
+ show_absolute_syms = 0;
+ show_absolute_relocs = 0;
+ as_text = 0;
+ use_real_mode = 0;
+ fname = NULL;
+ for (i = 1; i < argc; i++) {
+ char *arg = argv[i];
+ if (*arg == '-') {
+ if (strcmp(arg, "--abs-syms") == 0) {
+ show_absolute_syms = 1;
+ continue;
+ }
+ if (strcmp(arg, "--abs-relocs") == 0) {
+ show_absolute_relocs = 1;
+ continue;
+ }
+ if (strcmp(arg, "--text") == 0) {
+ as_text = 1;
+ continue;
+ }
+ if (strcmp(arg, "--realmode") == 0) {
+ use_real_mode = 1;
+ continue;
+ }
+ }
+ else if (!fname) {
+ fname = arg;
+ continue;
+ }
+ usage();
+ }
+ if (!fname) {
+ usage();
+ }
+ fp = fopen(fname, "r");
+ if (!fp) {
+ die("Cannot open %s: %s\n", fname, strerror(errno));
+ }
+ if (fread(&e_ident, 1, EI_NIDENT, fp) != EI_NIDENT) {
+ die("Cannot read %s: %s", fname, strerror(errno));
+ }
+ rewind(fp);
+ if (e_ident[EI_CLASS] == ELFCLASS64)
+ process_64(fp, use_real_mode, as_text,
+ show_absolute_syms, show_absolute_relocs);
+ else
+ process_32(fp, use_real_mode, as_text,
+ show_absolute_syms, show_absolute_relocs);
+ fclose(fp);
+ return 0;
+}