[PATCH] ppc32: platform-specific functions missing from kallsyms.
authorDavid Woodhouse <dwmw2@infradead.org>
Thu, 5 May 2005 23:15:09 +0000 (16:15 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 5 May 2005 23:36:31 +0000 (16:36 -0700)
The PPC32 kernel puts platform-specific functions into separate sections so
that unneeded parts of it can be freed when we've booted and actually
worked out what we're running on today.

This makes kallsyms ignore those functions, because they're not between
_[se]text or _[se]inittext.  Rather than teaching kallsyms about the
various pmac/chrp/etc sections, this patch adds '_[se]extratext' markers
for kallsyms.

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/ppc/kernel/vmlinux.lds.S
include/asm-generic/sections.h
kernel/kallsyms.c
scripts/kallsyms.c

index 0c0e714b84de74febf1f4dcb59eb1a859902deac..9353584fb7103c77cc866b417eecb12fa729c968 100644 (file)
@@ -145,6 +145,7 @@ SECTIONS
   __init_end = .;
 
   . = ALIGN(4096);
+  _sextratext = .;
   __pmac_begin = .;
   .pmac.text : { *(.pmac.text) }
   .pmac.data : { *(.pmac.data) }
@@ -171,6 +172,7 @@ SECTIONS
   .openfirmware.data : { *(.openfirmware.data) }
   . = ALIGN(4096);
   __openfirmware_end = .;
+  _eextratext = .;
 
   __bss_start = .;
   .bss       :
index 976ac29598b78d0b2c0c90516480e93434d8f506..195ccdc069e6c229dc22024a9d96d0b790f07735 100644 (file)
@@ -8,6 +8,8 @@ extern char _data[], _sdata[], _edata[];
 extern char __bss_start[], __bss_stop[];
 extern char __init_begin[], __init_end[];
 extern char _sinittext[], _einittext[];
+extern char _sextratext[] __attribute__((weak));
+extern char _eextratext[] __attribute__((weak));
 extern char _end[];
 
 #endif /* _ASM_GENERIC_SECTIONS_H_ */
index 1627f8d6e0cdd5f918c30666f4434407df25c293..13bcec151b57f8ebc68f1665a688f200f8c63d89 100644 (file)
@@ -46,6 +46,14 @@ static inline int is_kernel_inittext(unsigned long addr)
        return 0;
 }
 
+static inline int is_kernel_extratext(unsigned long addr)
+{
+       if (addr >= (unsigned long)_sextratext
+           && addr <= (unsigned long)_eextratext)
+               return 1;
+       return 0;
+}
+
 static inline int is_kernel_text(unsigned long addr)
 {
        if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext)
@@ -169,8 +177,9 @@ const char *kallsyms_lookup(unsigned long addr,
        namebuf[0] = 0;
 
        if ((all_var && is_kernel(addr)) ||
-           (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr)))) {
-               unsigned long symbol_end=0;
+           (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr) ||
+                               is_kernel_extratext(addr)))) {
+               unsigned long symbol_end = 0;
 
                /* do a binary search on the sorted kallsyms_addresses array */
                low = 0;
index fe11df83d1fc91b3e6de8a7bdc4a06e25f3d0e2f..d3d2e5341051809b01d13b75b352ed3d41f01d5c 100644 (file)
@@ -67,7 +67,7 @@ struct sym_entry {
 
 static struct sym_entry *table;
 static int size, cnt;
-static unsigned long long _stext, _etext, _sinittext, _einittext;
+static unsigned long long _stext, _etext, _sinittext, _einittext, _sextratext, _eextratext;
 static int all_symbols = 0;
 static char symbol_prefix_char = '\0';
 
@@ -139,6 +139,10 @@ read_symbol(FILE *in, struct sym_entry *s)
                _sinittext = s->addr;
        else if (strcmp(sym, "_einittext") == 0)
                _einittext = s->addr;
+       else if (strcmp(sym, "_sextratext") == 0)
+               _sextratext = s->addr;
+       else if (strcmp(sym, "_eextratext") == 0)
+               _eextratext = s->addr;
        else if (toupper(s->type) == 'A')
        {
                /* Keep these useful absolute symbols */
@@ -194,16 +198,18 @@ symbol_valid(struct sym_entry *s)
         * and inittext sections are discarded */
        if (!all_symbols) {
                if ((s->addr < _stext || s->addr > _etext)
-                   && (s->addr < _sinittext || s->addr > _einittext))
+                   && (s->addr < _sinittext || s->addr > _einittext)
+                   && (s->addr < _sextratext || s->addr > _eextratext))
                        return 0;
                /* Corner case.  Discard any symbols with the same value as
-                * _etext or _einittext, they can move between pass 1 and 2
-                * when the kallsyms data is added.  If these symbols move then
-                * they may get dropped in pass 2, which breaks the kallsyms
-                * rules.
+                * _etext _einittext or _eextratext; they can move between pass
+                * 1 and 2 when the kallsyms data are added.  If these symbols
+                * move then they may get dropped in pass 2, which breaks the
+                * kallsyms rules.
                 */
                if ((s->addr == _etext && strcmp(s->sym + offset, "_etext")) ||
-                   (s->addr == _einittext && strcmp(s->sym + offset, "_einittext")))
+                   (s->addr == _einittext && strcmp(s->sym + offset, "_einittext")) ||
+                   (s->addr == _eextratext && strcmp(s->sym + offset, "_eextratext")))
                        return 0;
        }