[Crash-utility] [PATCH] Fix for 4.19-rc1 and later "relative __ksymtab entries"

Dave Anderson anderson at redhat.com
Wed Aug 29 14:46:47 UTC 2018



----- Original Message -----
> kernels which have CONFIG_HAVE_ARCH_PREL32_RELOCATIONS will now store
> module symbol values relative to themselves since linux kernel's commit
> 7290d580957 ("module: use relative references for __ksymtab entries")
> 
> Do the lookup one way or another depending on the kernel's kernel_symbol
> struct, the case without the ARCH_PREL32_RELOCATIONS is the same as the
> old behaviour

Hi Dominique,

Thanks for both the bug report and fix -- your patch is queued for crash-7.2.4:
  
  https://github.com/crash-utility/crash/commit/001f77a05585c15ebd14bb72d5fde314a63c06fe

My task_struct.pids patch has also been applied:

  https://github.com/crash-utility/crash/commit/d7eec45d4c2cdd836ce48a81b0ae688a7d2879ba

Thanks,
  Dave


> 
> ---
> Hi! This is a follow-up on the bz I opened yesterday[1]
> 
> I'll let you commit your part of the tasks_struct pids, with both patches
> I can start crash normally and could check that address of symbols within
> a module look correct when compared to /proc/kallsyms, so I guess this
> isn't too bad.
> I also tried with an older kernel without problem.
> 
> [1] https://bugzilla.redhat.com/show_bug.cgi?id=1623127
> 
>  defs.h    |  1 +
>  symbols.c | 98 +++++++++++++++++++++++++++++++++++++------------------
>  2 files changed, 68 insertions(+), 31 deletions(-)
> 
> diff --git a/defs.h b/defs.h
> index 8687ff1..166ee48 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -2036,6 +2036,7 @@ struct offset_table {                    /* stash of
> commonly-used offsets */
>  	long memcg_cache_params___root_caches_node;
>  	long memcg_cache_params_children;
>  	long memcg_cache_params_children_node;
> +	long kernel_symbol_value;
>  };
>  
>  struct size_table {         /* stash of commonly-used sizes */
> diff --git a/symbols.c b/symbols.c
> index 2e6713a..7e73bad 100644
> --- a/symbols.c
> +++ b/symbols.c
> @@ -1595,12 +1595,40 @@ store_module_symbols_v1(ulong total, int
> mods_installed)
>                  st->flags |= INSMOD_BUILTIN;
>  }
>  
> -struct kernel_symbol
> -{
> -        unsigned long value;
> -        const char *name;
> +union kernel_symbol {
> +	struct kernel_symbol_v1 {
> +		unsigned long value;
> +		const char *name;
> +	} v1;
> +	/* kernel 4.19 introduced relative symbol positionning */
> +	struct kernel_symbol_v2 {
> +		int value_offset;
> +		int name_offset;
> +	} v2;
>  };
>  
> +static ulong
> +modsym_name(ulong syms, union kernel_symbol *modsym, int i)
> +{
> +	if (VALID_MEMBER(kernel_symbol_value))
> +		return (ulong)modsym->v1.name;
> +
> +	return syms + i * sizeof(struct kernel_symbol_v2) +
> +		offsetof(struct kernel_symbol_v2, name_offset) +
> +		modsym->v2.name_offset;
> +}
> +
> +static ulong
> +modsym_value(ulong syms, union kernel_symbol *modsym, int i)
> +{
> +	if (VALID_MEMBER(kernel_symbol_value))
> +		return (ulong)modsym->v1.value;
> +
> +	return syms + i * sizeof(struct kernel_symbol_v2) +
> +		offsetof(struct kernel_symbol_v2, value_offset) +
> +		modsym->v2.value_offset;
> +}
> +
>  void
>  store_module_symbols_v2(ulong total, int mods_installed)
>  {
> @@ -1614,7 +1642,8 @@ store_module_symbols_v2(ulong total, int
> mods_installed)
>  	long strbuflen;
>  	ulong size;
>  	int mcnt, lm_mcnt;
> -	struct kernel_symbol *modsym;
> +	union kernel_symbol *modsym;
> +	size_t kernel_symbol_size;
>  	struct load_module *lm;
>  	char buf1[BUFSIZE];
>  	char buf2[BUFSIZE];
> @@ -1639,6 +1668,13 @@ store_module_symbols_v2(ulong total, int
> mods_installed)
>  		  "re-initialization of module symbols not implemented yet!\n");
>  	}
>  
> +	MEMBER_OFFSET_INIT(kernel_symbol_value, "kernel_symbol", "value");
> +	if (VALID_MEMBER(kernel_symbol_value)) {
> +		kernel_symbol_size = sizeof(struct kernel_symbol_v1);
> +	} else {
> +		kernel_symbol_size = sizeof(struct kernel_symbol_v2);
> +	}
> +
>          if ((st->ext_module_symtable = (struct syment *)
>               calloc(total, sizeof(struct syment))) == NULL)
>                  error(FATAL, "v2 module syment space malloc (%ld symbols):
>                  %s\n",
> @@ -1750,20 +1786,20 @@ store_module_symbols_v2(ulong total, int
> mods_installed)
>  		}
>  
>  		if (nsyms) {
> -			modsymbuf = GETBUF(sizeof(struct kernel_symbol)*nsyms);
> +			modsymbuf = GETBUF(kernel_symbol_size*nsyms);
>  			readmem((ulong)syms, KVADDR, modsymbuf,
> -				nsyms * sizeof(struct kernel_symbol),
> +				nsyms * kernel_symbol_size,
>  				"module symbols", FAULT_ON_ERROR);
>  		}
>  
>  		for (i = first = last = 0; i < nsyms; i++) {
> -			modsym = (struct kernel_symbol *)
> -			    (modsymbuf + (i * sizeof(struct kernel_symbol)));
> +			modsym = (union kernel_symbol *)
> +			    (modsymbuf + (i * kernel_symbol_size));
>  			if (!first
> -			    || first > (ulong)modsym->name)
> -				first = (ulong)modsym->name;
> -			if ((ulong)modsym->name > last)
> -				last = (ulong)modsym->name;
> +			    || first > modsym_name(syms, modsym, i))
> +				first = modsym_name(syms, modsym, i);
> +			if (modsym_name(syms, modsym, i) > last)
> +				last = modsym_name(syms, modsym, i);
>  		}
>  
>  		if (last > first) {
> @@ -1787,21 +1823,21 @@ store_module_symbols_v2(ulong total, int
> mods_installed)
>  
>  		for (i = 0; i < nsyms; i++) {
>  
> -			modsym = (struct kernel_symbol *)
> -			    (modsymbuf + (i * sizeof(struct kernel_symbol)));
> +			modsym = (union kernel_symbol *)
> +			    (modsymbuf + (i * kernel_symbol_size));
>  
>  			BZERO(buf1, BUFSIZE);
>  
>  			if (strbuf)
>  				strcpy(buf1,
> -					&strbuf[(ulong)modsym->name - first]);
> +					&strbuf[modsym_name(syms, modsym, i) - first]);
>  			else
> -				read_string((ulong)modsym->name, buf1,
> +				read_string(modsym_name(syms, modsym, i), buf1,
>                              		BUFSIZE-1);
>  
>                  	if (strlen(buf1)) {
>  				st->ext_module_symtable[mcnt].value =
> -					modsym->value;
> +					modsym_value(syms, modsym, i);
>  				st->ext_module_symtable[mcnt].type = '?';
>  				st->ext_module_symtable[mcnt].flags |= MODULE_SYMBOL;
>  				strip_module_symbol_end(buf1);
> @@ -1823,21 +1859,21 @@ store_module_symbols_v2(ulong total, int
> mods_installed)
>  			FREEBUF(strbuf);
>  
>  		if (ngplsyms) {
> -			modsymbuf = GETBUF(sizeof(struct kernel_symbol) *
> +			modsymbuf = GETBUF(kernel_symbol_size *
>  				ngplsyms);
>  			readmem((ulong)gpl_syms, KVADDR, modsymbuf,
> -				ngplsyms * sizeof(struct kernel_symbol),
> +				ngplsyms * kernel_symbol_size,
>  				"module gpl symbols", FAULT_ON_ERROR);
>  		}
>  
>  		for (i = first = last = 0; i < ngplsyms; i++) {
> -			modsym = (struct kernel_symbol *)
> -			    (modsymbuf + (i * sizeof(struct kernel_symbol)));
> +			modsym = (union kernel_symbol *)
> +			    (modsymbuf + (i * kernel_symbol_size));
>  			if (!first
> -			    || first > (ulong)modsym->name)
> -				first = (ulong)modsym->name;
> -			if ((ulong)modsym->name > last)
> -				last = (ulong)modsym->name;
> +			    || first > modsym_name(gpl_syms, modsym, i))
> +				first = modsym_name(gpl_syms, modsym, i);
> +			if (modsym_name(gpl_syms, modsym, i) > last)
> +				last = modsym_name(gpl_syms, modsym, i);
>  		}
>  
>  		if (last > first) {
> @@ -1860,21 +1896,21 @@ store_module_symbols_v2(ulong total, int
> mods_installed)
>  
>  		for (i = 0; i < ngplsyms; i++) {
>  
> -			modsym = (struct kernel_symbol *)
> -			    (modsymbuf + (i * sizeof(struct kernel_symbol)));
> +			modsym = (union kernel_symbol *)
> +			    (modsymbuf + (i * kernel_symbol_size));
>  
>  			BZERO(buf1, BUFSIZE);
>  
>  			if (strbuf)
>  				strcpy(buf1,
> -					&strbuf[(ulong)modsym->name - first]);
> +					&strbuf[modsym_name(gpl_syms, modsym, i) - first]);
>  			else
> -				read_string((ulong)modsym->name, buf1,
> +				read_string(modsym_name(gpl_syms, modsym, i), buf1,
>                              		BUFSIZE-1);
>  
>                  	if (strlen(buf1)) {
>  				st->ext_module_symtable[mcnt].value =
> -					modsym->value;
> +					modsym_value(gpl_syms, modsym, i);
>  				st->ext_module_symtable[mcnt].type = '?';
>  				st->ext_module_symtable[mcnt].flags |= MODULE_SYMBOL;
>  				strip_module_symbol_end(buf1);
> --
> 2.17.1
> 
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
> 




More information about the Crash-utility mailing list