----- 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(a)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);