[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