2.4.6-pre3 unresolved symbol do_softirq
PATCH 1/1 2.4.6-pre3 unresolved symbol do_softirq
do_softirq is called from asm code which does not get preprocessed. It needs to be exported with no version.
Against 2.4.6-pre3. Note to users: you must run make mrproper after applying this patch.
Index: 6-pre3.1/kernel/ksyms.c
kernel/ksyms.c Wed, 13 Jun 2001 22:04:07 +1000 kaos (linux-2.4/j/46_ksyms.c 1.1.2.2.1.1.2.1.1.8.2.1.2.1 644) renamed from kernel/ksyms.c Sat, 09 Jun 2001 11:25:53 +1000 kaos (linux-2.4/j/46_ksyms.c 1.1.2.2.1.1.2.1.1.8.2.1.2.1 644) +1 -1
@@ -536,7 +536,7 @@ EXPORT_SYMBOL(remove_bh); EXPORT_SYMBOL(tasklet_init); EXPORT_SYMBOL(tasklet_kill); EXPORT_SYMBOL(__run_task_queue); -EXPORT_SYMBOL(do_softirq); +EXPORT_SYMBOL_NOVERS(do_softirq); EXPORT_SYMBOL(tasklet_schedule); EXPORT_SYMBOL(tasklet_hi_schedule);
Quoted 2 lines · Keith Owens
do_softirqis called from asm code which does not get preprocessed. It needs to be exported with no version.
It can get preprocessed if you know how. Simply use the "i" asm constraint for an extra argument, and use the symbol there. For example:
__asm__("%0" : : "i" (my_versioned_symbol));It works and we've been doing it on sparc for ages.
Later,
David S. Miller
[email protected]
Quoted 11 lines · David S. Miller
Quoted 2 lines · Keith Owens
do_softirqis called from asm code which does not get preprocessed. It needs to be exported with no version.It can get preprocessed if you know how. Simply use the "i" asm constraint for an extra argument, and use the symbol there. For example:
__asm__("%0" : : "i" (my_versioned_symbol));It works and we've been doing it on sparc for ages.
It works for integers but call do_softirq is more of a problem. I could not find an asm constraint that generated correct code in a single instruction. The closest I could get was
__asm__("call *%%eax" : : "a" (do_softirq));
The 'obvious'
__asm__("call %0" : : "m" (do_softirq));
calls to a location that contains the address of do_softirq, oops.
Any other architectures that call do_softirq inside asm would need similar hard coding of indirect branches. It is simpler to export do_softirq with no version, and have cleaner asm.
Quoted 11 lines · Keith Owens
It works for integers but call
do_softirqis more of a problem. I could not find an asm constraint that generated correct code in a single instruction. The closest I could get was
__asm__("call *%%eax" : : "a" (do_softirq));
The 'obvious'
__asm__("call %0" : : "m" (do_softirq));
calls to a location that contains the address ofdo_softirq, oops.Any other architectures that call
do_softirqinside asm would need similar hard coding of indirect branches. It is simpler to exportdo_softirqwith no version, and have cleaner asm.
Why doesn't this work on x86?
#define my_symbol my_symbol_versioned
extern void my_symbol(void);
__asm__("call %0" : : "i" (my_symbol));
Later,
David S. Miller
[email protected]
Quoted 6 lines · David S. Miller
Why doesn't this work on x86?
#define
my_symbolmy_symbol_versioned
extern voidmy_symbol(void);
__asm__("call %0" : : "i" (my_symbol));
#define my_symbol my_symbol_versioned
extern void my_symbol(void);
void foo(void) { __asm__("call %0" : : "i" (my_symbol)); }
# gcc -o x x.c /tmp/cclWXduj.s: Assembler messages: /tmp/cclWXduj.s:12: Error: suffix or operands invalid for `call'
Quoted 8 lines · Keith Owens
#define
my_symbolmy_symbol_versioned
extern voidmy_symbol(void);void foo(void) {
__asm__("call %0" : : "i" (my_symbol)); }# gcc -o x x.c /tmp/cclWXduj.s: Assembler messages: /tmp/cclWXduj.s:12: Error: suffix or operands invalid for `call'
I can't believe there is no reliable way to get rid of that pesky "$" gcc is adding to the symbol. Oh well...
Later,
David S. Miller
[email protected]
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Keith" == Keith Owens <[email protected]> writes:
Keith> #define my_symbol my_symbol_versioned extern void Keith> my_symbol(void);
Keith> void foo(void) { __asm__("call %0" : : "i" (my_symbol)); }
Keith> # gcc -o x x.c /tmp/cclWXduj.s: Assembler messages:
Keith> /tmp/cclWXduj.s:12: Error: suffix or operands invalid for Keith> `call'
Try ye' olde STRINGIFY and string concatenation? Well, at least I try...
#define my_symbol my_symbol_versioned
#define STRINGIFY(a) STRINGIFY1(a)
#define STRINGIFY1(a) #a
extern void my_symbol(void);
void foo(void)
{
__asm__("call " STRINGIFY(my_symbol) "\n");
}
[bpringle@localhost bpringle]$ gcc -o x x.c
/usr/lib/crt1.o(.text+0x18): undefined reference to `main'
/tmp/ccIj9Cit.o: In function `foo':
/tmp/ccIj9Cit.o(.text+0x4): undefined reference to `my_symbol_versioned'
collect2: ld returned 1 exit statusregards,
Bill Pringlemeir.
Quoted 16 lines · Bill Pringlemeir
Try ye' olde STRINGIFY and string concatenation? Well, at least I try...
#define my_symbol my_symbol_versioned #define STRINGIFY(a) STRINGIFY1(a) #define STRINGIFY1(a) #a extern void my_symbol(void); void foo(void) { __asm__("call " STRINGIFY(my_symbol) "\n"); } [bpringle@localhost bpringle]$ gcc -o x x.c /usr/lib/crt1.o(.text+0x18): undefined reference to `main' /tmp/ccIj9Cit.o: In function `foo': /tmp/ccIj9Cit.o(.text+0x4): undefined reference to `my_symbol_versioned'
Only at the cost of polluting every .h file that calls a symbol from __asm__. The whole pre-processor kludge for symbol versions goes away in 2.5 so live with _novers for now.
Quoted 5 lines · David S. Miller
Quoted 3 lines · Keith Owens
#define
my_symbolmy_symbol_versioned
extern voidmy_symbol(void);
Quoted 8 lines
Quoted 5 lines
void foo(void) {
__asm__("call %0" : : "i" (my_symbol)); }# gcc -o x x.c /tmp/cclWXduj.s: Assembler messages: /tmp/cclWXduj.s:12: Error: suffix or operands invalid for `call'I can't believe there is no reliable way to get rid of that pesky "$" gcc is adding to the symbol. Oh well...
void foo(void) { __asm__("call %c0" : : "i" (my_symbol)); }
^^^
-
"David S. Miller" <[email protected]> writes:
|> Keith Owens writes:
|> > #define my_symbol my_symbol_versioned
|> > extern void my_symbol(void);
|> >
|> > void foo(void) { __asm__("call %0" : : "i" (my_symbol)); }
|> >
|> > # gcc -o x x.c
|> > /tmp/cclWXduj.s: Assembler messages:
|> > /tmp/cclWXduj.s:12: Error: suffix or operands invalid for `call'
|>
|> I can't believe there is no reliable way to get rid of that
|> pesky "$" gcc is adding to the symbol. Oh well...Use %c0. *Note Output Templates and Operand Substitution: (gcc)Output Template.
Andreas.
Signature · 5 lines
Andreas Schwab "And now for something SuSE Labs completely different." [email protected] SuSE GmbH, Schanzäckerstr. 10, D-90443 Nürnberg Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
Quoted 7 lines · Andreas Schwab
"David S. Miller" <[email protected]> writes:
|> I can't believe there is no reliable way to get rid of that |> pesky "$" gcc is adding to the symbol. Oh well...
Use %c0. *Note Output Templates and Operand Substitution: (gcc)Output Template.
Nice, see Keith? There are no excuses :-)
Later,
David S. Miller
[email protected]
Quoted 11 lines · David S. Miller
Quoted 7 lines · Andreas Schwab
"David S. Miller" <[email protected]> writes:
|> I can't believe there is no reliable way to get rid of that |> pesky "$" gcc is adding to the symbol. Oh well...
Use %c0. *Note Output Templates and Operand Substitution: (gcc)Output Template.
Nice, see Keith? There are no excuses :-)
Oh, there are always excuses ;). But in this case ...
Index: 6-pre3.1/include/asm-i386/softirq.h
include/asm-i386/softirq.h Thu, 14 Jun 2001 02:26:16 +1000 kaos (linux-2.4/T/51_softirq.h 1.3 644) renamed from include/asm-i386/softirq.h Sat, 09 Jun 2001 11:25:53 +1000 kaos (linux-2.4/T/51_softirq.h 1.3 644) +2 -2
@@ -36,13 +36,13 @@ do { \ \ ".section .text.lock,\"ax\";" \ "2: pushl %%eax; pushl %%ecx; pushl %%edx;" \ - "call do_softirq;" \ + "call %c1;" \ "popl %%edx; popl %%ecx; popl %%eax;" \ "jmp 1b;" \ ".previous;" \ \ : /* no output */ \ - : "r" (ptr) \ + : "r" (ptr), "i" (do_softirq) \ /* no registers clobbered */ ); \ } while (0)
No changes to kernel/ksyms, it still says EXPORT_SYMBOL(do_softirq); I like it.
Quoted 2 lines · David S. Miller
I can't believe there is no reliable way to get rid of that pesky "$" gcc is adding to the symbol. Oh well...
GCC on ARM does a similar thing - all constants in the assembler are prefixed with '#' or '@'. Using the 'i' constraint adds this. This behaviour is actually useful when you want to pass a constant or a register - it allows GCC to make the decision for you, and do the right thing in the assembler fragment. Eg, the following code used to be in the kernel until 2.3:
extern __inline__ void __outb (unsigned int value, unsigned int port)
{
unsigned long temp;
__asm__ __volatile__(
"tst %2, #0x80000000\n\t"
"mov %0, %4\n\t"
"addeq %0, %0, %3\n\t"
"strb %1, [%0, %2, lsl #2] @ outb"
: "=&r" (temp)
: "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
: "cc");
}%3 and %4 might be a constant:
mov r5, #0x03000000
or a real register if the constant can't be loaded in one instruction:
mov r5, r1
'I' in this case means "a constant suitable for use with the arithmetic instructions".
--
Russell King ([email protected]) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html
Quoted 2 lines · Andreas Schwab
Use %c0. *Note Output Templates and Operand Substitution: (gcc)Output Template.
Oh great! I can get rid of some more crap from the ARM tree!
Thanks.
--
Russell King ([email protected]) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html
Quoted 5 lines · David S. Miller
Quoted 2 lines · Keith Owens
do_softirqis called from asm code which does not get preprocessed. It needs to be exported with no version.
Quoted 7 lines
It can get preprocessed if you know how. Simply use the "i" asm constraint for an extra argument, and use the symbol there. For example:
__asm__("%0" : : "i" (my_versioned_symbol));It works and we've been doing it on sparc for ages.
how to do this in foo.S code?
Signature · 3 lines
Jeff Garzik | Andre the Giant has a posse. Building 1024 | MandrakeSoft |
Quoted 1 line · Jeff Garzik
how to do this in
foo.Scode?
foo.S goes through the preprocessor already.
Later,
David S. Miller
[email protected]
Quoted 5 lines · Jeff Garzik
Quoted 2 lines · David S. Miller
It can get preprocessed if you know how. Simply use the "i" asm constraint for an extra argument, and use the symbol there.
how to do this in
foo.Scode?
Fortunately it is not a problem for foo.S code - yet. External symbol references only need module version pre-processing when the code is in a module. AFAIK no *.S code is compiled into a module, all *.S code is built into vmlinux, this is why I did not use this argument myself. OTOH if any *.S code is compiled into a module then all symbols it refers to must be EXPORT_SYMBOL_NOVERS().
Quoted 2 lines · Keith Owens
OTOH if any *.S code is compiled into a module then all symbols it refers to must be
EXPORT_SYMBOL_NOVERS().
Why not just add --include modversions.h to the gcc command line to build it, why wouldn't this work?
Later,
David S. Miller
[email protected]
Quoted 7 lines · David S. Miller
Quoted 2 lines · Keith Owens
OTOH if any *.S code is compiled into a module then all symbols it refers to must be
EXPORT_SYMBOL_NOVERS().Why not just add --include
modversions.hto the gcc command line to build it, why wouldn't this work?
Assembler code is not hooked into the generic module symbol version handling. Every .S rule is unique and I'm not going to change every one.
Quoted 7 lines · Keith Owens
Quoted 5 lines · David S. Miller
Quoted 2 lines · Keith Owens
OTOH if any *.S code is compiled into a module then all symbols it refers to must be
EXPORT_SYMBOL_NOVERS().
Quoted 6 lines
Quoted 2 lines
Why not just add --include
modversions.hto the gcc command line to build it, why wouldn't this work?Assembler code is not hooked into the generic module symbol version handling. Every .S rule is unique and I'm not going to change every one.
Why not make a ASM_CPP_DEFINES that all those rules use?
Surely this is a smaller hammer than making them all NOVERS(), I think all of these workarounds with novers for assembly are silly and are merely looking for a solution which nobody (perhaps except me :-) is bothering to look for.
Later,
David S. Miller
[email protected]
Quoted 4 lines · David S. Miller
Surely this is a smaller hammer than making them all
NOVERS(), I think all of these workarounds with novers for assembly are silly and are merely looking for a solution which nobody (perhaps except me :-) is bothering to look for.
modversions.h will disappear in 2.5 anyway, and be replaced with a cleaner system of symbol versions which does not rely on pre-processor fudging of symbol names. It should be able to handle assembler as well as C.