[Crash-utility] [PATCH 1/3] arm64: relax symbol filters

Dave Anderson anderson at redhat.com
Thu Nov 19 19:35:59 UTC 2015



----- Original Message -----
> 
> Below is a (hardly tested, pretty messy, incomplete - needs to address
> other architectures verify_symbol() prototypes) patch that illustrates
> this idea. I'm OK with special casing _kernel_flags_le, but generally
> prefer to look for general solutions. Let me know if you like anything
> in the patch below, if so, then I can clean it up and send it properly.
> The patch takes care of the two cases pointed above, i.e. 'sym -l' and
> 'rd -S'.
> 
> Thanks,
> drew

I appreciate the effort, but I really don't want to make this into a
project that seeps into the other architectures, or into the general symbol
handling code.  And although it probably wouldn't be an issue in this
case, I don't like to change interfaces defined in defs.h because they
can-be/are used by extension modules, and something like this could
conceivably break one.

All of the architectures have their own xxxx_verify_symbol() function
to perform whatever machine-specific hacks that they require.  And since
it's a simple STREQ("_kernel_flags_le") check, please let's just keep it
in-house so to speak.

Thanks,
   Dave


> 
> Author: Andrew Jones <drjones at redhat.com>
> Date:   Thu Nov 19 19:31:28 2015 +0100
> 
>     symbols: keep absolutes, but handle specially
> 
> diff --git a/arm64.c b/arm64.c
> index 91b35787e6942..534d301c39afd 100644
> --- a/arm64.c
> +++ b/arm64.c
> @@ -24,7 +24,7 @@
>  #define NOT_IMPLEMENTED(X) error((X), "%s: function not implemented\n",
>  __func__)
>  
>  static struct machine_specific arm64_machine_specific = { 0 };
> -static int arm64_verify_symbol(const char *, ulong, char);
> +static int arm64_verify_symbol(const char *, ulong, char, unsigned char *);
>  static void arm64_parse_cmdline_args(void);
>  static void arm64_calc_phys_offset(void);
>  static void arm64_calc_virtual_memory_ranges(void);
> @@ -330,7 +330,7 @@ arm64_init(int when)
>   * Accept or reject a symbol from the kernel namelist.
>   */
>  static int
> -arm64_verify_symbol(const char *name, ulong value, char type)
> +arm64_verify_symbol(const char *name, ulong value, char type, unsigned char
> *flags)
>  {
>  	if (!name || !strlen(name))
>  		return FALSE;
> @@ -345,9 +345,13 @@ arm64_verify_symbol(const char *name, ulong value, char
> type)
>  	if (STREQ(name, "$d") || STREQ(name, "$x"))
>  		return FALSE;
>  	
> -	if ((type == 'A') && (STRNEQ(name, "__crc_") || STRNEQ(name,
> "__reg_num_")))
> +	if ((type == 'A' || type == 'a') &&
> +            (STRNEQ(name, "__crc_") || STRNEQ(name, "__reg_num_")))
>  		return FALSE;
>  
> +	if ((type == 'A' || type == 'a') && flags)
> +		*flags |= SYMBOL_NO_OFFSET;
> +
>  	if (!(machdep->flags & KSYMS_START) && STREQ(name, "idmap_pg_dir"))
>  		machdep->flags |= KSYMS_START;
>  
> diff --git a/defs.h b/defs.h
> index 981b030cc6688..3b6fd15496063 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -969,7 +969,7 @@ struct machdep_table {
>  	uint64_t (*memory_size)(void);
>  	ulong (*vmalloc_start)(void);
>          int (*is_task_addr)(ulong);
> -	int (*verify_symbol)(const char *, ulong, char);
> +	int (*verify_symbol)(const char *, ulong, char, unsigned char *);
>  	int (*dis_filter)(ulong, char *, unsigned int);
>  	int (*get_smp_cpus)(void);
>          int (*is_kvaddr)(ulong);
> @@ -2412,6 +2412,7 @@ struct rb_root
>  
>  #define SYMBOL_NAME_USED (0x1)
>  #define MODULE_SYMBOL    (0x2)
> +#define SYMBOL_NO_OFFSET (0x4)
>  #define IS_MODULE_SYMBOL(SYM)  ((SYM)->flags & MODULE_SYMBOL)
>  
>  struct syment {
> diff --git a/symbols.c b/symbols.c
> index 5a2aa7ccb5713..bcd2e4e1947fb 100644
> --- a/symbols.c
> +++ b/symbols.c
> @@ -716,6 +716,8 @@ store_symbols(bfd *abfd, int dynamic, void *minisyms,
> long symcount,
>  
>    	for (; from < fromend; from += size)
>      	{
> +		unsigned char flags = 0;
> +
>        		if ((sym = bfd_minisymbol_to_symbol(abfd, dynamic, from, store))
>        		    == NULL)
>  			error(FATAL, "bfd_minisymbol_to_symbol() failed\n");
> @@ -724,13 +726,14 @@ store_symbols(bfd *abfd, int dynamic, void *minisyms,
> long symcount,
>  		name = strip_symbol_end(syminfo.name, buf);
>  
>  		if (machdep->verify_symbol(name, syminfo.value,
> -		    syminfo.type)) {
> +		    syminfo.type, &flags)) {
>  			if (kt->flags & (RELOC_SET|RELOC_FORCE))
>  				sp->value = relocate(syminfo.value,
>  					(char *)syminfo.name, !(first++));
>  			else
>  				sp->value = syminfo.value;
>  			sp->type = syminfo.type;
> +			sp->flags = flags;
>  			namespace_ctl(NAMESPACE_INSTALL, &st->kernel_namespace,
>  				sp, name);
>  			sp++;
> @@ -789,6 +792,9 @@ store_sysmap_symbols(void)
>  	rewind(map);
>  
>  	while (fgets(buf, BUFSIZE, map)) {
> +
> +		unsigned char flags = 0;
> +
>  		if ((c = parse_line(buf, mapitems)) != 3)
>  			continue;
>  
> @@ -800,13 +806,14 @@ store_sysmap_symbols(void)
>  		strip_symbol_end(name, NULL);
>  
>                  if (machdep->verify_symbol(name, syment.value,
> -		    syment.type)) {
> +		    syment.type, &flags)) {
>  			if (kt->flags & RELOC_SET)
>  				sp->value = relocate(syment.value,
>  					syment.name, !(first++));
>  			else
>  				sp->value = syment.value;
>                          sp->type = syment.type;
> +			sp->flags = flags;
>                          namespace_ctl(NAMESPACE_INSTALL,
>                          &st->kernel_namespace,
>                                  sp, name);
>                          sp++;
> @@ -2243,7 +2250,7 @@ store_module_kallsyms_v2(struct load_module *lm, int
> start, int curr,
>  		 * Make sure that these don't end up into our symbol list.
>  		 */
>  		if (machine_type("ARM") &&
> -		    !machdep->verify_symbol(nameptr, ec->st_value, ec->st_info))
> +		    !machdep->verify_symbol(nameptr, ec->st_value, ec->st_info, NULL))
>  			continue;
>  
>  		if (CRASHDEBUG(7))
> @@ -3908,7 +3915,12 @@ show_symbol(struct syment *sp, ulong offset, ulong
> show_flags)
>                  fprintf(fp, (radix == 16) ?
>  			"%lx (%c) %s+0x%lx" : "%lx (%c) %s+%ld",
>  			sp->value+offset, sp->type, sp->name, offset);
> -        else
> +        else if (highest_bit_long(sp->value) != highest_bit_long(ULONG_MAX))
> +		if (highest_bit_long(ULONG_MAX) > 31)
> +                	fprintf(fp, "%016lx (%c) %s", sp->value, sp->type,
> sp->name);
> +		else
> +                	fprintf(fp, "%08lx (%c) %s", sp->value, sp->type,
> sp->name);
> +	else
>                  fprintf(fp, "%lx (%c) %s", sp->value, sp->type, sp->name);
>  
>  	if (lm)
> @@ -4692,7 +4704,7 @@ value_to_symstr(ulong value, char *buf, ulong radix)
>  	if ((radix != 10) && (radix != 16))
>  		radix = 16;
>  
> -        if ((sp = value_search(value, &offset))) {
> +        if ((sp = value_search(value, &offset)) && !(sp->flags &
> SYMBOL_NO_OFFSET)) {
>                  if (offset)
>                          sprintf(buf, radix == 16 ? "%s+0x%lx" : "%s+%ld",
>  				sp->name, offset);
> @@ -11446,14 +11458,15 @@ store_load_module_symbols(bfd *bfd, int dynamic,
> void *minisyms,
>                  }
>  
>                  if (found) {
> +			unsigned char flags = 0;
>                          strcpy(name, syminfo.name);
>                          strip_module_symbol_end(name);
>  			strip_symbol_end(name, NULL);
>                          if (machdep->verify_symbol(name, syminfo.value,
> -                            syminfo.type)) {
> +                            syminfo.type, &flags)) {
>                                  sp->value = syminfo.value;
>                                  sp->type = syminfo.type;
> -				sp->flags |= MODULE_SYMBOL;
> +				sp->flags |= (MODULE_SYMBOL | flags);
>                                  namespace_ctl(NAMESPACE_INSTALL,
>                                          &lm->mod_load_namespace, sp, name);
>  
> 




More information about the Crash-utility mailing list