-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
busybox free printing stray characters #372
Comments
small test case
|
Started pouring into glibc printf() call stack - gdb (2021.03-eng1) is useless as it can't seem to unravel the heavily macro'ized vfprintf_internal() code so wading through assembly muck ! Deep inside the state machine for parsing format specifier, there's a little function read_int() which needs to be called 6 times for the 6 format specifiers, however it is called only 4 times, with it bailing early in the 4th round - which explains why only 3 specifiers are parsed and 3 numbers printed in output above, |
4th read_int() call is tripping because format specifier seems corrupted. (gdb) p/s (char *)0x51228 Expected The control characters in the 4th format specifier is the ones causing the issue. objump of the binary shows the format specifier string is OK in the binary Disassembly of section .rodata: |
At the time of main() entry the string is already clobbered. Breakpoint 4, 0x00010300 in ?? () <-- main Next was to check the page contents when it first wired up into user-space. Address 0x5_123f is in .rodata, but shares the physical page with .text too.
This is wired up at the time libc startup due to a jump to .text in that page |
Observed the ITLB Misses for the process, until one pertaining to 0x5_0000 hits (page size on ARC is 8k so 0x5_0000 to 0x5_1FFF). After update_mmu_cache() looked at the physical page containing the .rodata
The address of interest is 0x5123f => 0xbe78_a000 + 0x123f = 0xbe78_b23f Used nsim trace output to see where this address is being populated. Sure enough during initramfs unpacking / populating it is being memcpy() - with incorrect byte.
|
The memcpy src in turn is being setup in kernel initramfs gzip inflate code - since initramfs is GZIP compressed per build.
and rebuild the kernel, the problem goes away with everything else being same
|
The memcpy source in turn is populated from a different copy loop in inflaste_fast() => initramfs gzip inflate code
In the first 8-byte copy, src and dst overlap which is NOK since these are short pointers, so only need to copy 2 bytes and not 8.
So the issue is why is gcc generating 8-byte LDD when only 2 bytes are intended (given the short/uint16 pointer). So summarize: the issue is gcc generating an 8 byte at a time access (LDD/STD) for a short pointer access which requires 2 bytes at a time. Not sure of related, but arc64 gcc has a similar problem with unaligned access where it fetches more data than warranted (and the reason I disable unaligned access for arc64). |
Weied that building the specific kernel file with -mno-ll64 changes the access to LDH/STH, however the issue remains (so happening elsewhere too) |
testcase for gcc is attached: look for zol generated at .L52 FWIW the problem is seen with upstream gcc 10.2, as well as gcc from 2020.09 release |
FWIW the issue remains (gcc generating LDD/STD for uint16 * access) even with -mno-unaligned-access With -mno-ll64 (for just this file), gcc still does 8 byte access in loop (vs. 2) albeit with two LD/ST instead of single LDD/STD
And to prove that this and only this is the issue I replaced the "C" code with inline asm (and switched back -ll64 for whole file)
And the problem goes away
Over to you Claudiu. Phew ! |
This seems a mainline issue as I can reproduce it with aarch64 gcc 10.2 as well. |
For the record that's a work-around for the Linux kernel with use of more conservative diff --git a/lib/zlib_inflate/Makefile b/lib/zlib_inflate/Makefile
index 27327d3e9f54..6f97070d08a3 100644
--- a/lib/zlib_inflate/Makefile
+++ b/lib/zlib_inflate/Makefile
@@ -18,3 +18,5 @@ obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o
zlib_inflate-objs := inffast.o inflate.o infutil.o \
inftrees.o inflate_syms.o
+
+CFLAGS_inffast.o += -O2 With that contents of initramfs get decompressed correctly, in particularly that fixes #373. |
The |
Per Richard, this is not a bug see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100363#c17 I propose to close this issue. |
And I'm Mahatma Gandhi !
Seriously I'm surprised you say that. Did you even read through the whole bug report. There's clearly something the compiler is doing "more" than it is expected and the only way to make it NOT do that is either lower the optimization level or even worse align a uint16 to byte. Is that the solution you propose we adopt in the Linux kernel. |
Can you please explain a bit more for mere mortals what is trying to do - we already have unaligned access disabled by default - is this disabling something more when we have -munaligned-access. Is this yet more of sweeping the problem under the rug. |
|
Got this issue one more time (actually Cuper had it when debugging QEMU), now just Do we plan to fix it somehow? As I can understand the issue is in kernel zlib inflate implementation with -O3 optimization level. So we can at least apply this patch #372 (comment) to our buildroot, because we need stable environment for testing. |
@vineetgarc what's your take on this one? I.e. which would be the best solution to tis med- and long-term? |
Can someone please fix this. I want to have a Linux Image for HS that is not crippled with this issues. |
@cupertinomiranda please use https://github.com/foss-for-synopsys-dwc-arc-processors/buildroot/tree/arc-2021.05.x-kernel-02 branch with snps_archs38_qemu_defconfig . This configuration uses custom kernel config with kernel optimization level set to O2. |
The workaround is already mentioned several times in the issue - the simplest way is to do this w/o any source changes is in your buildroot folder, make linux-menuconfig -> General Setup -> Compiler optimization level -> O2 The actual fix is still pending (neither party wants to fix it) and will take lot more time to resolve correctly. |
foss-for-synopsys-dwc-arc-processors/toolchain#372 Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
foss-for-synopsys-dwc-arc-processors/toolchain#372 Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
foss-for-synopsys-dwc-arc-processors/toolchain#372 Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
I think we agree that the issue is related to kernel code and there is nothing to fix in toolchain. So I opened kernel bug for it here: foss-for-synopsys-dwc-arc-processors/linux#68 . @claziss since we have workaround in the kernel sources (see https://github.com/foss-for-synopsys-dwc-arc-processors/linux/blob/bc5fec251f1087dc999fa744aa64799fc02a5476/lib/zlib_inflate/Makefile#L22) I think you can enable unaligned access back for arc64 linux toolchain. And then please close this, because I don't see what can be done here in toolchain. |
foss-for-synopsys-dwc-arc-processors/toolchain#372 Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
foss-for-synopsys-dwc-arc-processors/toolchain#372 Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
foss-for-synopsys-dwc-arc-processors/toolchain#372 Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
foss-for-synopsys-dwc-arc-processors/toolchain#372 Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
foss-for-synopsys-dwc-arc-processors/toolchain#372 Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
foss-for-synopsys-dwc-arc-processors/toolchain#372 Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
foss-for-synopsys-dwc-arc-processors/toolchain#372 Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
foss-for-synopsys-dwc-arc-processors/toolchain#372 Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Busybox free prints stray characters
This is off of Buildroot 2021.02, upstream gcc 10.2 + (foss-for-synopsys-dwc-arc-processors/gcc@5aeabae "arc: Refurbish adc/sbc patterns"
Linux kernel is built with -O3 (CC_OPTIMIZE_FOR_PERFORMANCE_O3)
The text was updated successfully, but these errors were encountered: