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
