On 09/07/2016 06:33 AM, AKASHI Takahiro wrote: > From: Pratyush Anand <panand at redhat.com> > > get_kernel_stext_sym() has been defined for both arm and i386. Other > architecture might need some other kernel symbol address. Therefore rewrite > this function as generic function to get any kernel symbol address. > > More over, kallsyms is not arch specific representation, therefore have > common function for all arches. > > Signed-off-by: Pratyush Anand <panand at redhat.com> > [created symbols.c] > Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org> > --- > kexec/Makefile | 1 + > kexec/arch/arm/crashdump-arm.c | 40 +--------------------------------------- > kexec/arch/i386/crashdump-x86.c | 32 +------------------------------- > kexec/kexec.h | 2 ++ > kexec/symbols.c | 41 +++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 46 insertions(+), 70 deletions(-) > create mode 100644 kexec/symbols.c > > diff --git a/kexec/Makefile b/kexec/Makefile > index 39f365f..2b4fb3d 100644 > --- a/kexec/Makefile > +++ b/kexec/Makefile > @@ -26,6 +26,7 @@ KEXEC_SRCS_base += kexec/kernel_version.c > KEXEC_SRCS_base += kexec/lzma.c > KEXEC_SRCS_base += kexec/zlib.c > KEXEC_SRCS_base += kexec/kexec-xen.c > +KEXEC_SRCS_base += kexec/symbols.c > > KEXEC_GENERATED_SRCS += $(PURGATORY_HEX_C) > > diff --git a/kexec/arch/arm/crashdump-arm.c b/kexec/arch/arm/crashdump-arm.c > index 4a89b5e..2bc898b 100644 > --- a/kexec/arch/arm/crashdump-arm.c > +++ b/kexec/arch/arm/crashdump-arm.c > @@ -73,48 +73,10 @@ static struct crash_elf_info elf_info = { > > extern unsigned long long user_page_offset; > > -/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */ > -static unsigned long long get_kernel_stext_sym(void) > -{ > - const char *kallsyms = "/proc/kallsyms"; > - const char *stext = "_stext"; > - char sym[128]; > - char line[128]; > - FILE *fp; > - unsigned long long vaddr = 0; > - char type; > - > - fp = fopen(kallsyms, "r"); > - if (!fp) { > - fprintf(stderr, "Cannot open %s\n", kallsyms); > - return 0; > - } > - > - while(fgets(line, sizeof(line), fp) != NULL) { > - unsigned long long addr; > - > - if (sscanf(line, "%Lx %c %s", &addr, &type, sym) != 3) > - continue; > - > - if (strcmp(sym, stext) == 0) { > - dbgprintf("kernel symbol %s vaddr = %#llx\n", stext, addr); > - vaddr = addr; > - break; > - } > - } > - > - fclose(fp); > - > - if (vaddr == 0) > - fprintf(stderr, "Cannot get kernel %s symbol address\n", stext); > - > - return vaddr; > -} > - > static int get_kernel_page_offset(struct kexec_info *info, > struct crash_elf_info *elf_info) > { > - unsigned long long stext_sym_addr = get_kernel_stext_sym(); > + unsigned long long stext_sym_addr = get_kernel_sym("stext"); > if (stext_sym_addr == 0) { > if (user_page_offset != (-1ULL)) { > elf_info->page_offset = user_page_offset; > diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c > index bbc0f35..664eb3b 100644 > --- a/kexec/arch/i386/crashdump-x86.c > +++ b/kexec/arch/i386/crashdump-x86.c > @@ -102,36 +102,6 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info), > return -1; > } > > -/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */ > -static unsigned long long get_kernel_stext_sym(void) > -{ > - const char *kallsyms = "/proc/kallsyms"; > - const char *stext = "_stext"; > - char sym[128]; > - char line[128]; > - FILE *fp; > - unsigned long long vaddr; > - char type; > - > - fp = fopen(kallsyms, "r"); > - if (!fp) { > - fprintf(stderr, "Cannot open %s\n", kallsyms); > - return 0; > - } > - > - while(fgets(line, sizeof(line), fp) != NULL) { > - if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3) > - continue; > - if (strcmp(sym, stext) == 0) { > - dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr); > - return vaddr; > - } > - } > - > - fprintf(stderr, "Cannot get kernel %s symbol address\n", stext); > - return 0; > -} > - > /* Retrieve info regarding virtual address kernel has been compiled for and > * size of the kernel from /proc/kcore. Current /proc/kcore parsing from > * from kexec-tools fails because of malformed elf notes. A kernel patch has > @@ -182,7 +152,7 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info), > > /* Traverse through the Elf headers and find the region where > * _stext symbol is located in. That's where kernel is mapped */ > - stext_sym = get_kernel_stext_sym(); > + stext_sym = get_kernel_sym("stext"); I think this should be get_kernel_sym("_stext"); Apart from that as Simon already mentioned, due to commit 9f62cbd ("kexec/arch/i386: Add support for KASLR memory randomization") this patch does not apply cleanly. Regards, Matthias > for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) { > if (phdr->p_type == PT_LOAD) { > unsigned long long saddr = phdr->p_vaddr; > diff --git a/kexec/kexec.h b/kexec/kexec.h > index 9194f1c..b4fafad 100644 > --- a/kexec/kexec.h > +++ b/kexec/kexec.h > @@ -312,4 +312,6 @@ int xen_kexec_load(struct kexec_info *info); > int xen_kexec_unload(uint64_t kexec_flags); > void xen_kexec_exec(void); > > +extern unsigned long long get_kernel_sym(const char *text); > + > #endif /* KEXEC_H */ > diff --git a/kexec/symbols.c b/kexec/symbols.c > new file mode 100644 > index 0000000..ea6e327 > --- /dev/null > +++ b/kexec/symbols.c > @@ -0,0 +1,41 @@ > +#include <stdio.h> > +#include <string.h> > +#include "kexec.h" > + > +/* Retrieve kernel symbol virtual address from /proc/kallsyms */ > +unsigned long long get_kernel_sym(const char *text) > +{ > + const char *kallsyms = "/proc/kallsyms"; > + char sym[128]; > + char line[128]; > + FILE *fp; > + unsigned long long vaddr = 0; > + char type; > + > + fp = fopen(kallsyms, "r"); > + if (!fp) { > + fprintf(stderr, "Cannot open %s\n", kallsyms); > + return 0; > + } > + > + while (fgets(line, sizeof(line), fp) != NULL) { > + unsigned long long addr; > + > + if (sscanf(line, "%Lx %c %s", &addr, &type, sym) != 3) > + continue; > + > + if (strcmp(sym, text) == 0) { > + dbgprintf("kernel symbol %s vaddr = %#llx\n", > + text, addr); > + vaddr = addr; > + break; > + } > + } > + > + fclose(fp); > + > + if (vaddr == 0) > + fprintf(stderr, "Cannot get kernel %s symbol address\n", text); > + > + return vaddr; > +} >