[PATCH v3 2/8] kexec: generalize and rename get_kernel_stext_sym()
Matthias Brugger
matthias.bgg at gmail.com
Thu Oct 6 06:28:12 PDT 2016
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;
> +}
>
More information about the kexec
mailing list