Cross compiling qbittorrent to run on Xiaomi router results in peculiar QT bug
I tried to run qBittorrent on a Xiaomi R3G. It broke. I traced the corruption through qBittorrent into Qt, found a MIPS-specific bug in QString::fromLatin1(), supplied a one-line fix, and apparently the bug is still there.
The cross-compilation tool chain is a part of OpenWrt and is fairly well documented so I’ll skip it here. There also are tutorials and scripts that perform qbittorrent cross-compilation on github.
The fun part started after I’ve successfully compiled qbittorrent to run under mipsel architecture. It did run, but I could not add any downloads.
Using the tried and tested “just insert prints and bisect” approach, I’ve managed to trace the bug to QString::fromLatin1(). Except it wasn’t compiled from cpp, but had it’s own mipsel optimized assembly code.
The interesting part is that the bug is self-evident, and the fix is also self-evident. That’s how I found it btw. I do understand assembler and low-level logic, but I don’t know this exact architecture. So I’ve pasted the qtbase/src/corelib/text/qstring_mips_dsp_asm.S in reasonably sized chunks to ChatGPT, explained that I’m looking for a bug and asked to explain line by line what’s the cpu doing. First, if the string’s address is aligned to 2, a good branch is executed and no errors occurs.
If not, we come to this piece at line 326:
#if defined(__mips_dspr2)
prepend t1, t2, 8
#else
sll t4, t4, 24
srl t1, t1, 8
or t1, t1, t4
#endif
This is a conditional compilation. Xiaomi R3G and it’s mipsel 24k will use the lower part of the code, while 74k that’s got dspr extension would use a single upper instruction.
The crux: both paths must produce the same result — and they do not, they don’t even use the same input registers!
sll t4, t2, 24
With this fix both paths will produce identical result. Everything needed to see the bug and to fix it is clearly visible in the code, no need run it. But instead of applying the fix, QT developers decided to disable the optimized code.
Refs: qBittorrent issue #18654, QT bug #111740, QT devs discussion