All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] weak functions not being over-ridden (location dependent)
@ 2008-11-26 12:02 Graeme Russ
  2008-11-26 13:01 ` Remy Bohmer
  0 siblings, 1 reply; 8+ messages in thread
From: Graeme Russ @ 2008-11-26 12:02 UTC (permalink / raw)
  To: u-boot

Hi All,

I have a very strange problem - I am trying to define a weak function, but
whether or not the function is overridden depends on where I put the
overriding function. Case in point:

common.h defines reset_cpu() thusly:

void	reset_cpu     (ulong addr);

in cpu/i386/reset.c I have:

void __reset_cpu(ulong addr)
{
	printf("Resetting using i386 Triple Fault\n");
	set_vector(13, generate_gpf);  /* general protection fault handler */
	set_vector(8, generate_gpf);   /* double fault handler */
	generate_gpf();                /* start the show */
}
void reset_cpu(ulong addr) __attribute__((weak, alias("__reset_cpu")));

Now, if I implement reset_cpu () in cpu/i386/sc520/reset.c

void reset_cpu(ulong addr)
{
	printf("Resetting using SC520 MMCR\n");
	/* Write a '1' to the SYS_RST of the RESCFG MMCR */
	write_mmcr_word(SC520_RESCFG, 0x0001);

	/* NOTREACHED */
}

and issue a reset from the prompt, it uses the Triple Fault

If I move reset_cpu () in board/eNET/eNET.c, it uses the MMCR

Now, if I remove __reset_cpu () (and the weak definition) and leave the
reset_cpu in cpu/i386/sc520/reset.c, it uses the MMCR to reset the CPU. So
/cpu/i386/sc520/reset.c is being compiled and the library is being linked in.

If I go back to __reset_cpu(), weak function and reset_cpu () in
cpu/i386/sc520, u-boot.map reveals:

 .text          0x000000003804ecd4       0x6d cpu/i386/libi386.a(reset.o)
                0x000000003804ecdb                __reset_cpu
                0x000000003804ecd4                generate_gpf
                0x000000003804ed10                do_reset
                0x000000003804ecdb                reset_cpu

and no other references to reset_cpu

Move reset_cpu () to board/eNET/eNET.c and I get

 .text          0x00000000380499a0      0x312 board/eNET/libeNET.a(eNET.o)
                0x00000000380499f8                dram_init
                0x00000000380499e4                last_stage_init
                0x0000000038049a07                init_sc520_enet
                0x0000000038049a46                reset_cpu
                0x0000000038049a69                board_init
                0x00000000380499bb                board_flash_get_legacy
.
.
.
 .text          0x000000003804ecf8       0x6d cpu/i386/libi386.a(reset.o)
                0x000000003804ecff                __reset_cpu
                0x000000003804ecf8                generate_gpf
                0x000000003804ed34                do_reset


If I do not define the weak function and implement reset_cpu () in BOTH
cpu/i386/reset.c and cpu/i386/sc520/reset.c I get no complaints from the
linker, and the reset is performed via triple-fault. u-boot.map reveals:

 .text          0x000000003804ecd4       0x6d cpu/i386/libi386.a(reset.o)
                0x000000003804ecd4                generate_gpf
                0x000000003804ed10                do_reset
                0x000000003804ecdb                reset_cpu

Why is the linker silently discarding an obvious symbol conflict?

Any ideas?

Thanks,

Graeme

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] weak functions not being over-ridden (location dependent)
  2008-11-26 12:02 [U-Boot] weak functions not being over-ridden (location dependent) Graeme Russ
@ 2008-11-26 13:01 ` Remy Bohmer
  2008-11-26 15:12   ` Wolfgang Denk
  0 siblings, 1 reply; 8+ messages in thread
From: Remy Bohmer @ 2008-11-26 13:01 UTC (permalink / raw)
  To: u-boot

Hello Graeme,

> I have a very strange problem - I am trying to define a weak function, but
> whether or not the function is overridden depends on where I put the
> overriding function. Case in point:

You are not the only one, I have seen this also with the LED interface
in U-boot.
My workaround was simple: remove the weak functions... I never took
the time to figure it out exactly, so I am curious if anyone knows the
real answer.

Remy


2008/11/26 Graeme Russ <graeme.russ@gmail.com>:
> Hi All,
>
> I have a very strange problem - I am trying to define a weak function, but
> whether or not the function is overridden depends on where I put the
> overriding function. Case in point:
>
> common.h defines reset_cpu() thusly:
>
> void    reset_cpu     (ulong addr);
>
> in cpu/i386/reset.c I have:
>
> void __reset_cpu(ulong addr)
> {
>        printf("Resetting using i386 Triple Fault\n");
>        set_vector(13, generate_gpf);  /* general protection fault handler */
>        set_vector(8, generate_gpf);   /* double fault handler */
>        generate_gpf();                /* start the show */
> }
> void reset_cpu(ulong addr) __attribute__((weak, alias("__reset_cpu")));
>
> Now, if I implement reset_cpu () in cpu/i386/sc520/reset.c
>
> void reset_cpu(ulong addr)
> {
>        printf("Resetting using SC520 MMCR\n");
>        /* Write a '1' to the SYS_RST of the RESCFG MMCR */
>        write_mmcr_word(SC520_RESCFG, 0x0001);
>
>        /* NOTREACHED */
> }
>
> and issue a reset from the prompt, it uses the Triple Fault
>
> If I move reset_cpu () in board/eNET/eNET.c, it uses the MMCR
>
> Now, if I remove __reset_cpu () (and the weak definition) and leave the
> reset_cpu in cpu/i386/sc520/reset.c, it uses the MMCR to reset the CPU. So
> /cpu/i386/sc520/reset.c is being compiled and the library is being linked in.
>
> If I go back to __reset_cpu(), weak function and reset_cpu () in
> cpu/i386/sc520, u-boot.map reveals:
>
>  .text          0x000000003804ecd4       0x6d cpu/i386/libi386.a(reset.o)
>                0x000000003804ecdb                __reset_cpu
>                0x000000003804ecd4                generate_gpf
>                0x000000003804ed10                do_reset
>                0x000000003804ecdb                reset_cpu
>
> and no other references to reset_cpu
>
> Move reset_cpu () to board/eNET/eNET.c and I get
>
>  .text          0x00000000380499a0      0x312 board/eNET/libeNET.a(eNET.o)
>                0x00000000380499f8                dram_init
>                0x00000000380499e4                last_stage_init
>                0x0000000038049a07                init_sc520_enet
>                0x0000000038049a46                reset_cpu
>                0x0000000038049a69                board_init
>                0x00000000380499bb                board_flash_get_legacy
> .
> .
> .
>  .text          0x000000003804ecf8       0x6d cpu/i386/libi386.a(reset.o)
>                0x000000003804ecff                __reset_cpu
>                0x000000003804ecf8                generate_gpf
>                0x000000003804ed34                do_reset
>
>
> If I do not define the weak function and implement reset_cpu () in BOTH
> cpu/i386/reset.c and cpu/i386/sc520/reset.c I get no complaints from the
> linker, and the reset is performed via triple-fault. u-boot.map reveals:
>
>  .text          0x000000003804ecd4       0x6d cpu/i386/libi386.a(reset.o)
>                0x000000003804ecd4                generate_gpf
>                0x000000003804ed10                do_reset
>                0x000000003804ecdb                reset_cpu
>
> Why is the linker silently discarding an obvious symbol conflict?
>
> Any ideas?
>
> Thanks,
>
> Graeme
>
>
>
>
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] weak functions not being over-ridden (location dependent)
  2008-11-26 13:01 ` Remy Bohmer
@ 2008-11-26 15:12   ` Wolfgang Denk
  2008-11-26 19:32     ` Graeme Russ
  0 siblings, 1 reply; 8+ messages in thread
From: Wolfgang Denk @ 2008-11-26 15:12 UTC (permalink / raw)
  To: u-boot

Dear Remy,

In message <3efb10970811260501h6dcf87b9idf3d80981ceee07b@mail.gmail.com> you wrote:
> 
> > I have a very strange problem - I am trying to define a weak function, but
> > whether or not the function is overridden depends on where I put the
> > overriding function. Case in point:
> 
> You are not the only one, I have seen this also with the LED interface
> in U-boot.
> My workaround was simple: remove the weak functions... I never took
> the time to figure it out exactly, so I am curious if anyone knows the
> real answer.

I think this has been answered before: it doesn't work when the
functions are in libraries. It only works when the respective
functions are in explicitely linked object files.

Jean-Christophe is planning to switch to  linking  objects  like  the
Linux kernel does, but this is a medium/long term task.

For now, check if you can separately link the respective object files.

See the ML archive for the previous discussion.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
It seems intuitively obvious to me, which  means  that  it  might  be
wrong.                                                 -- Chris Torek

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] weak functions not being over-ridden (location dependent)
  2008-11-26 15:12   ` Wolfgang Denk
@ 2008-11-26 19:32     ` Graeme Russ
  2008-11-26 19:42       ` Ben Warren
  2008-11-27 19:50       ` Mike Frysinger
  0 siblings, 2 replies; 8+ messages in thread
From: Graeme Russ @ 2008-11-26 19:32 UTC (permalink / raw)
  To: u-boot

Wolfgang Denk wrote:
> Dear Remy,
> 
> In message <3efb10970811260501h6dcf87b9idf3d80981ceee07b@mail.gmail.com> you wrote:
>>> I have a very strange problem - I am trying to define a weak function, but
>>> whether or not the function is overridden depends on where I put the
>>> overriding function. Case in point:
>> You are not the only one, I have seen this also with the LED interface
>> in U-boot.
>
> I think this has been answered before: it doesn't work when the
> functions are in libraries. It only works when the respective
> functions are in explicitely linked object files.
> 
> 
This doesn't seem right - reset_cpu () will be in a library no matter where
I put it (either libsc520.a or libeNET.a)

Maybe its a binutils issue

Regards,

Graeme

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] weak functions not being over-ridden (location dependent)
  2008-11-26 19:32     ` Graeme Russ
@ 2008-11-26 19:42       ` Ben Warren
  2008-11-26 20:06         ` Graeme Russ
  2008-11-27 19:50       ` Mike Frysinger
  1 sibling, 1 reply; 8+ messages in thread
From: Ben Warren @ 2008-11-26 19:42 UTC (permalink / raw)
  To: u-boot

Graeme,

Graeme Russ wrote:
> Wolfgang Denk wrote:
>   
>> Dear Remy,
>>
>> In message <3efb10970811260501h6dcf87b9idf3d80981ceee07b@mail.gmail.com> you wrote:
>>     
>>>> I have a very strange problem - I am trying to define a weak function, but
>>>> whether or not the function is overridden depends on where I put the
>>>> overriding function. Case in point:
>>>>         
>>> You are not the only one, I have seen this also with the LED interface
>>> in U-boot.
>>>       
>> I think this has been answered before: it doesn't work when the
>> functions are in libraries. It only works when the respective
>> functions are in explicitely linked object files.
>>
>>
>>     
> This doesn't seem right - reset_cpu () will be in a library no matter where
> I put it (either libsc520.a or libeNET.a)
>   
Is the overriding function the only one in the source file (and thus the 
object file)?  I've found that overriding functions will link only if 
there's other code in the source file that is strongly-linked.

regards,
Ben

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] weak functions not being over-ridden (location dependent)
  2008-11-26 19:42       ` Ben Warren
@ 2008-11-26 20:06         ` Graeme Russ
  2008-11-26 20:48           ` Ben Warren
  0 siblings, 1 reply; 8+ messages in thread
From: Graeme Russ @ 2008-11-26 20:06 UTC (permalink / raw)
  To: u-boot

Ben Warren wrote:
> Graeme,
> 
> Graeme Russ wrote:
>> Wolfgang Denk wrote:
>>  
>>> I think this has been answered before: it doesn't work when the
>>> functions are in libraries. It only works when the respective
>>> functions are in explicitely linked object files.
>>>
>>>
>>>     
>> This doesn't seem right - reset_cpu () will be in a library no matter
>> where
>> I put it (either libsc520.a or libeNET.a)
>>   
> Is the overriding function the only one in the source file (and thus the
> object file)?  I've found that overriding functions will link only if
> there's other code in the source file that is strongly-linked.
> 
> regards,
> Ben

That solves the problem - Thanks

I think this is an ld bug IMHO - will submit to binutils mailing list for
comment

In the meantime, I need to dream up a strongly linked function which will
be useful ;)

Regards,

Graeme

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] weak functions not being over-ridden (location dependent)
  2008-11-26 20:06         ` Graeme Russ
@ 2008-11-26 20:48           ` Ben Warren
  0 siblings, 0 replies; 8+ messages in thread
From: Ben Warren @ 2008-11-26 20:48 UTC (permalink / raw)
  To: u-boot

Graeme Russ wrote:
> Ben Warren wrote:
>   
>> Graeme,
>>
>> Graeme Russ wrote:
>>     
>>> Wolfgang Denk wrote:
>>>  
>>>       
>>>> I think this has been answered before: it doesn't work when the
>>>> functions are in libraries. It only works when the respective
>>>> functions are in explicitely linked object files.
>>>>
>>>>
>>>>     
>>>>         
>>> This doesn't seem right - reset_cpu () will be in a library no matter
>>> where
>>> I put it (either libsc520.a or libeNET.a)
>>>   
>>>       
>> Is the overriding function the only one in the source file (and thus the
>> object file)?  I've found that overriding functions will link only if
>> there's other code in the source file that is strongly-linked.
>>
>> regards,
>> Ben
>>     
>
> That solves the problem - Thanks
>
> I think this is an ld bug IMHO - will submit to binutils mailing list for
> comment
>
>   
I found discussions through Google where this was talked about, and for 
whatever reason it's intended behavior.  There are ways to force linking 
with ld switches, but they're only supported in newer versions of 
gcc/binutils and we're constrained here to supporting older tools.

 From a software architecture standpoint, it seems wrong, but the easy 
fix is to add your overriding functions to existing files.  For example, 
you'll see that all implementations of cpu_eth_init() are in 
cpu/<cpu>/cpu.c, although I would have preferred to create a new file 
called something like cpu/<cpu>/enet.c

Fun stuff...

cheers,
Ben

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [U-Boot] weak functions not being over-ridden (location dependent)
  2008-11-26 19:32     ` Graeme Russ
  2008-11-26 19:42       ` Ben Warren
@ 2008-11-27 19:50       ` Mike Frysinger
  1 sibling, 0 replies; 8+ messages in thread
From: Mike Frysinger @ 2008-11-27 19:50 UTC (permalink / raw)
  To: u-boot

On Wednesday 26 November 2008 14:32:48 Graeme Russ wrote:
> Wolfgang Denk wrote:
> > In message ... you wrote:
> >>> I have a very strange problem - I am trying to define a weak function,
> >>> but whether or not the function is overridden depends on where I put
> >>> the overriding function. Case in point:
> >>
> >> You are not the only one, I have seen this also with the LED interface
> >> in U-boot.
> >
> > I think this has been answered before: it doesn't work when the
> > functions are in libraries. It only works when the respective
> > functions are in explicitely linked object files.
>
> This doesn't seem right - reset_cpu () will be in a library no matter where
> I put it (either libsc520.a or libeNET.a)

the linker treates archives differently from shared libraries by design.  
"linked objects" refers to .o object files, not .a archives.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 835 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20081127/0a34bae5/attachment.pgp 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2008-11-27 19:50 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-26 12:02 [U-Boot] weak functions not being over-ridden (location dependent) Graeme Russ
2008-11-26 13:01 ` Remy Bohmer
2008-11-26 15:12   ` Wolfgang Denk
2008-11-26 19:32     ` Graeme Russ
2008-11-26 19:42       ` Ben Warren
2008-11-26 20:06         ` Graeme Russ
2008-11-26 20:48           ` Ben Warren
2008-11-27 19:50       ` Mike Frysinger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.