ll_entry_count returns 0 even though the linker list has 5 entries

Simon Glass sjg at chromium.org
Mon Oct 21 18:32:10 CEST 2024


Hi Osman,

I'm adding Heinrich as he knows about RISC-V. This is a mystery to me.

Regards,
Simon


On Mon, 21 Oct 2024 at 08:56, Osman <aibaykaro at gmail.com> wrote:
>
> Hi Simon,
>
> I have digged on this a bit while debugging and this is the disassembled version of the ll_entry_count:
>
> 1 auipc   s1,0x4
> 2 addi    s1,s1,-436
> 3 sub     s1,s1,s2
> 4 srai    s1,s1,0x3
> 5 auipc   a5,0x2
> 6 ld      a5,-228(a5)
> 7 mulw    s1,s1,a5
>
> For explanation s2 contains the start of the linker list and the s1 contains the end of it so at line 3 it calculates the end-start as 0x258 which is correct in my case (0x80006620 − 0x800063c8). From there it gets a bit interesting cause it shifts that value to right by 3 in line 4, from there it makes a load operation (line 5-6) at 0x80005768 which corresponds to this location in generated .map file:
>
> .rodata.cst8   0x0000000080005768        0x8 drivers/core/lists.o
>
> Since i know the size of the linker list by looking at the .map file i made the calculation myself, 0x258 shifted right 3 times becomes 0x4b and to make the calculation correct size of the struct driver must be shifted as well which is 0x78>>3 = F. Since this is the multiplicative inverse the final value should be something like 0xeeeeeeeeeeeeeeef but the value in that section was just 0x0. From there i was a bit clueless to be honest i am not sure what makes it filled with zeros instead of the actual number, i made a simple c code to test it out myself but it didn't generate the same assembly lines. I know that declaring CONFIG_SPL_OPENSBI just adds the spl_opensbi.c file but I couldn't figure out how it is related to this, that file doesn't even use linker_lists.h. In the end I left it at that since there weren't any more clues. By the way, I looked at the .map file to see what adding opensbi adds to the symbols but those symbols are after the address in question so I couldn't make much sense of it. So that's it, thank you for your time and have a nice day.
>
> Best Regards,
>
> Osman
>
>
> Simon Glass <sjg at chromium.org>, 18 Eki 2024 Cum, 17:55 tarihinde şunu yazdı:
>>
>> Hi Osman,
>>
>> On Fri, 18 Oct 2024 at 01:39, Osman <aibaykaro at gmail.com> wrote:
>> >
>> > Hello Simon,
>> >
>> > I am not sure, the problem is with the rodata as the linker list looks fine and execution finds the start and end of the list correctly. The wrong thing is the size value it uses located at the rodata. This is the region in u-boot-spl.lds that links the rodata:
>> >
>> > . = ALIGN(4);
>> > .rodata : {
>> > *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
>> > } > .spl_mem
>> >
>> > I am not sure where it looks for the alignment of this value. Normally the field which spl looks in rodata should contain the multiplicative inverse of the size of struct driver and from what i can tell from assembly it is shifted as well. Where does the linker look for the alignment of a value like this?
>>
>> This is something of a mystery to me as well. I did dig into it quite
>> a lot at one point and recall some alignment settings on both input
>> and output sections. But the strange thing about your case is that it
>> seems that ll_entry_start() and ll_entry_end() are correct but
>> ll_entry_count() is not. That is the particular situation that I
>> believe you could debug, to understand what is happening.
>>
>>
>> >
>> > Regards,
>> > Osman
>> >
>> > Simon Glass <sjg at chromium.org>, 18 Eki 2024 Cum, 02:18 tarihinde şunu yazdı:
>> >>
>> >> +U-Boot Mailing List
>> >>
>> >> On Thu, 17 Oct 2024 at 03:03, Osman <aibaykaro at gmail.com> wrote:
>> >> >
>> >> > Hello Simon,
>> >> >
>> >> > The problem is solved after enabling SPL_OPENSBI in my case, it would have been better if I knew the reason for it but I can't see how the linker list is related to opensbi configuration. Thank you for your time.
>> >> >
>> >> > By the way I made sure to try the spl by only disabling spl_opensbi configuration to make sure other changes are not affecting it but disabling really causes it to fail again.
>> >>
>> >> I wonder if this has something to do with alignment?
>> >>
>> >> Regards,
>> >> Simon
>> >>
>> >>
>> >> >
>> >> > Regards,
>> >> >
>> >> > Osman
>> >> >
>> >> > Osman <aibaykaro at gmail.com>, 15 Eki 2024 Sal, 14:17 tarihinde şunu yazdı:
>> >> >>
>> >> >> Hi Simon,
>> >> >>
>> >> >> This is a 64 bit RISC-V platform, i don't have LINKER_LIST_ALIGN in my defconfig so it should be 4 by default however it's not a problem with linker list alignment i suppose. After debugging it in assembly I found out that it successfully calculates the length between the start and end of the linker list, it just divides incorrectly because the inverse value of the size of struct driver is wrong. The rodata section which contains that size value is filled with zeros. For reference this is the location it looks for the size value:
>> >> >>
>> >> >> u-boot-spl.map:
>> >> >>  .rodata.cst8   0x0000000080007eb0        0x8 drivers/core/lists.o
>> >> >>
>> >> >>  and this is what i see while debugging:
>> >> >>
>> >> >>  (gdb) x /x 0x0000000080007eb0
>> >> >> 0x80007eb0:     0x00000000
>> >> >>
>> >> >> it should be something like 0xEEEEEEEF for it to work correctly.
>> >> >> Actually there are a lot of spaces that are filled with zeros is this normal?:
>> >> >>
>> >> >> (gdb) x /64w 0x0000000080007e60
>> >> >> 0x80007e60:     0x69797254      0x7420676e      0x6f62206f      0x6620746f
>> >> >> 0x80007e70:     0x206d6f72      0x000a7325      0x3a4c5053      0x736e5520
>> >> >> 0x80007e80:     0x6f707075      0x64657472      0x6f6f4220      0x65442074
>> >> >> 0x80007e90:     0x00000000      0x00000000      0x00000000      0x00000000
>> >> >> 0x80007ea0:     0x00000000      0x00000000      0x00000000      0x00000000
>> >> >> 0x80007eb0:     0x00000000      0x00000000      0x00000000      0x00000000
>> >> >> 0x80007ec0:     0x00000000      0x00000000      0x00000000      0x00000000
>> >> >> 0x80007ed0:     0x00000000      0x00000000      0x00000000      0x00000000
>> >> >> 0x80007ee0:     0x00000000      0x00000000      0x00000000      0x00000000
>> >> >> 0x80007ef0:     0x00000000      0x00000000      0x00000000      0x00000000
>> >> >> 0x80007f00:     0x00000000      0x00000000      0x00000000      0x00000000
>> >> >> 0x80007f10:     0x00000000      0x00000000      0x00000000      0x00000000
>> >> >> 0x80007f20:     0x00000000      0x00000000      0x00000000      0x00000000
>> >> >> 0x80007f30:     0x00000000      0x00000000      0x00000000      0x00000000
>> >> >> 0x80007f40:     0x00000000      0x00000000      0x80007f48      0x00000000
>> >> >> 0x80007f50:     0x80007f48      0x00000000      0x80007f48      0x00000000
>> >> >>
>> >> >> u-boot-spl.map:
>> >> >>  .rodata.boot_from_devices.str1.8
>> >> >>                 0x0000000080007e60       0x39 common/spl/spl.o
>> >> >>  *fill*         0x0000000080007e99        0x7
>> >> >>  .rodata.cst8   0x0000000080007ea0        0x8 common/spl/spl.o
>> >> >>  .rodata.cst8   0x0000000080007ea8        0x8 lib/tiny-printf.o
>> >> >>  .rodata.cst8   0x0000000080007eb0        0x8 drivers/core/lists.o
>> >> >>  .rodata.devfdt_get_addr_index.str1.8
>> >> >>                 0x0000000080007eb8        0x4 drivers/core/fdtaddr.o
>> >> >>  .rodata.dm_extended_scan.str1.8
>> >> >>                 0x0000000080007eb8       0x12 drivers/core/root.o
>> >> >>                                          0x1a (size before relaxing)
>> >> >>  *fill*         0x0000000080007eca        0x6
>> >> >>  .rodata.do_reset.str1.8
>> >> >>                 0x0000000080007ed0       0x29 arch/riscv/lib/reset.o
>> >> >>  *fill*         0x0000000080007ef9        0x7
>> >> >>  .rodata.fdt_address_cells.str1.8
>> >> >>                 0x0000000080007f00        0xf lib/libfdt/fdt_addresses.o
>> >> >>  *fill*         0x0000000080007f0f        0x1
>> >> >>  .rodata.fdt_find_or_add_subnode.str1.8
>> >> >>                 0x0000000080007f10        0xc common/fdt_support.o
>> >> >>  *fill*         0x0000000080007f1c        0x4
>> >> >>  .rodata.fdt_fixup_memory_banks.str1.8
>> >> >>                 0x0000000080007f20       0x9c common/fdt_support.o
>> >> >>  *fill*         0x0000000080007fbc        0x4
>> >> >>  .rodata.fdt_get_alias_namelen.str1.8
>> >> >>                 0x0000000080007fc0        0x9 lib/libfdt/fdt_ro.o
>> >> >>
>> >> >>  I am not sure what is happening here, is there a way to check how a specific rodata region is filled?
>> >> >>
>> >> >>  Regards,
>> >> >>
>> >> >>  Osman


More information about the U-Boot mailing list