Thanks Rasmus

On Tue, 2026-10-13 at 11:38 +0200, Rasmus Villemoes wrote:
> On Tue, Oct 13 2026, "Rasmus Villemoes" <[email protected]> wrote:

Yeah, overflow check sounded too easy, but I did try that for a start. Still 
hangs.

Then, I tried which one actually fails and it is strdup.

If I just add size_t len = strlen(s); to the top of the old working strdup() 
function, it also hangs. Strange.

No, wait a minute, it just gets called with null strings, yes.

But the new implementation should catch that as well. Strange.

Somehow it does not like another level of indirection. But I haven't quite 
figured out what exactly it is that
goes wrong. Will keep prodding it...

> > The only other difference I can see is the U-Boot version doing a tail
> > call
> > 
> >     return memcpy(dst, src, len);
> > 
> > which relies on memcpy() being defined to return the dst argument. Now,
> > usually nobody uses memcpy's return value, but it can make code slightly
> > more compact, and any custom memcpy() implementation (e.g. in asm) _must_
> > honour this, as the compiler might transform
> > 
> >   memcpy(a, b, c);
> >   return a;
> > 
> > into
> > 
> >   return memcpy(a, b, c);
> > 
> > [I know this because I played around with this in godbolt a few years
> > ago, and I think found that gcc did this but clang did not, or something
> > like that].
> 
> Just for my own future reference: I misremembered slightly regarding the
> gcc/clang behaviour, but I did file an llvm bug report back then. That
> was just very hard to re-discover because my name was not included when
> llvm migrated their issue tracker to github, but it's this one:
> https://github.com/llvm/llvm-project/issues/46610 .
> 
> > So my best bet is that your platform uses a custom memcpy() which does
> > not have to right return value. Can you try changing that last
> > 
> >     return memcpy(dst, src, len);
> > 
> > into
> > 
> >     memcpy(dst, src, len);
> >     return dst;
> > 
> > and verify in the disassembly that the compiler hasn't changed it back,
> > and then see if your board boots?

Tried that but also did not help. But I will do some more disassembly 
analysis...

> As for this hypothesis, I did quickly look at riscv's asm memcpy(), and
> I don't see anything obviously wrong (it does have a "save for return
> value"). But the arithmetic and comparisons are somewhat risky and
> not-obviously-correct, I think. For example, doing
> 
>       /* Unrolled wordwise copy */
>       addi    t0, t0, -(16*SZREG-1)
>       bgeu    a0, t0, 2f
> 
> to see if the end of the destination buffer is at least 16 words ahead
> of the a0 doesn't work if we happen to work with addresses very close to
> 0, i.e. something like
> 
>   memcpy(32, from_somewhere, 256)
> 
> would certainly fail. But I know nothing about riscv, so I can't really
> read the asm properly, and the "close to 0" thing is unlikely to be the
> real problem.
> 
> Nevertheless, another thing to try is disable CONFIG_SPL_ARCH_MEMPCY
> (and CONFIG_ARCH_MEMCPY for good measure) and see if that makes a
> difference.

Tried that which let to:

/riscv64-glibc-ubuntu-24.04-gcc-2026.08.27-nightly/bin/riscv64-unknown-linux-gnu-ld:
arch/riscv/lib/memmove.o:(.text+0x8): undefined reference to `__memcpy'
/riscv64-glibc-ubuntu-24.04-gcc-2026.08.27-nightly/bin/riscv64-unknown-linux-gnu-ld:
 relocation
R_RISCV_CALL_PLT against `__memcpy' which may bind externally can not be used 
when making a shared object;
recompile with -fPIC
make: *** [Makefile:2113: u-boot] Error 1

So I also had to get rid of CONFIG_USE_ARCH_MEMMOVE.

Outcome is still the same hang.

> Rasmus

Cheers

Marcel

Reply via email to