[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