[U-Boot] weak functions not being over-ridden (location dependent)

Remy Bohmer linux at bohmer.net
Wed Nov 26 14:01:50 CET 2008


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 at 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
>


More information about the U-Boot mailing list