[PATCH] ARM: decompressor: fix BSS size calculation
Russell King
rmk+kernel at armlinux.org.uk
Mon Sep 25 11:11:46 PDT 2017
Assuming size(1) gives the size of the BSS is a mistake - it reports
the size of the .bss section in the ELF image, which may not be the
same as the region we mark with the __bss_start..__bss_stop symbols.
We use the size of the BSS in the decompressor to know whether the
kernel will overwrite the appended dtb, by adding the BSS size to the
size of the Image (stored at the end of the compressed data) and adding
the desired address of the decompressed image.
If the BSS size is smaller than it really is, the decompressor can
incorrectly assume that the BSS clearance will not overwrite the DTB.
Here is an illustration:
$ arm-linux-size vmlinux
text data bss dec hex filename
8136972 3098076 10240348 21475396 147b044 vmlinux
$ arm-linux-nm vmlinux | grep __bss_
c0ac0e34 B __bss_start
c1484f9c B __bss_stop
$ stat -c %s arch/arm/boot/Image
11243060
In the above case, we are 12 bytes short. This is caused by the BSS
section being aligned by one of its input sections:
Idx Name Size VMA LMA File off Algn
23 __bug_table 00005d3c c0abb0f8 c0abb0f8 00acb0f8 2**2
CONTENTS, ALLOC, LOAD, DATA
24 .bss 009c415c c0ac0e40 c0ac0e40 00ad0e34 2**6
ALLOC
Note that there's an additional 12 bytes difference between the file
offset and LMA compared with the bug table - this occurs because one
of the input sections for the .bss section requires a 64 byte
alignment.
Fix this by using 'nm' and awk to access the __bss_start and __bss_stop
symbols, using their difference for the size of the BSS.
Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
---
arch/arm/boot/compressed/Makefile | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index d50430c40045..d26e250a56b0 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -116,8 +116,10 @@ ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
asflags-y := -DZIMAGE
# Supply kernel BSS size to the decompressor via a linker symbol.
-KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \
- awk 'END{print $$3}')
+KBSS_SZ = $(shell $(CROSS_COMPILE)nm $(obj)/../../../../vmlinux | \
+ awk '/B __bss_start$$/ {bss_start=strtonum("0x"$$1)}; \
+ /B __bss_stop$$/ {bss_stop=strtonum("0x"$$1)}; \
+ END {print bss_stop-bss_start}')
LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ)
# Supply ZRELADDR to the decompressor via a linker symbol.
ifneq ($(CONFIG_AUTO_ZRELADDR),y)
--
2.7.4
More information about the linux-arm-kernel
mailing list