diff options
-rw-r--r-- | Makefile | 2 | ||||
-rwxr-xr-x | scripts/generate_BUFSIZ.sh | 180 |
2 files changed, 109 insertions, 73 deletions
@@ -611,7 +611,7 @@ quiet_cmd_busybox__ ?= LINK $@ "$(core-y)" \ "$(libs-y)" \ "$(LDLIBS)" \ - && $(srctree)/scripts/generate_BUFSIZ.sh include/common_bufsiz.h + && $(srctree)/scripts/generate_BUFSIZ.sh --post include/common_bufsiz.h # Generate System.map quiet_cmd_sysmap = SYSMAP diff --git a/scripts/generate_BUFSIZ.sh b/scripts/generate_BUFSIZ.sh index 1914fa0f5..8aa0174a6 100755 --- a/scripts/generate_BUFSIZ.sh +++ b/scripts/generate_BUFSIZ.sh @@ -7,11 +7,16 @@ debug=false +postcompile=false +test x"$1" = x"--post" && { postcompile=true; shift; } + common_bufsiz_h=$1 test x"$NM" = x"" && NM="${CONFIG_CROSS_COMPILER_PREFIX}nm" test x"$CC" = x"" && CC="${CONFIG_CROSS_COMPILER_PREFIX}gcc" +exitcmd="exit 0" + regenerate() { cat >"$1.$$" test -f "$1" && diff "$1.$$" "$1" >/dev/null && rm "$1.$$" && return @@ -19,99 +24,130 @@ regenerate() { } generate_std_and_exit() { - $debug && echo "Default: bb_common_bufsiz1[] in bss" + $debug && echo "Configuring: bb_common_bufsiz1[] in bss" { echo "enum { COMMON_BUFSIZE = 1024 };" echo "extern char bb_common_bufsiz1[];" echo "#define setup_common_bufsiz() ((void)0)" } | regenerate "$common_bufsiz_h" - exit 0 + echo "std" >"$common_bufsiz_h.method" + $exitcmd } -# User does not want any funky stuff? -test x"$CONFIG_FEATURE_USE_BSS_TAIL" = x"y" || generate_std_and_exit - -test -f busybox_unstripped || { - # We did not try anything yet - $debug && echo "Will try to fit bb_common_bufsiz1[] into _end[]" +generate_big_and_exit() { + $debug && echo "Configuring: bb_common_bufsiz1[] in _end[], COMMON_BUFSIZE = $1" { - echo "enum { COMMON_BUFSIZE = 1024 };" + echo "enum { COMMON_BUFSIZE = $1 };" echo "extern char _end[]; /* linker-provided label */" echo "#define bb_common_bufsiz1 _end" echo "#define setup_common_bufsiz() ((void)0)" } | regenerate "$common_bufsiz_h" - echo 1024 >"$common_bufsiz_h.BUFSIZE" - exit 0 + echo "$2" >"$common_bufsiz_h.method" + $exitcmd } -# Get _end address -END=`$NM busybox_unstripped | grep ' . _end$'| cut -d' ' -f1` -test x"$END" = x"" && generate_std_and_exit -$debug && echo "END:0x$END $((0x$END))" -END=$((0x$END)) - -# Get PAGE_SIZE -echo "\ -#include <sys/user.h> -#if defined(PAGE_SIZE) && PAGE_SIZE > 0 -char page_size[PAGE_SIZE]; -#else -char page_size[1]; -#endif -" >page_size_$$.c -$CC -c "page_size_$$.c" || generate_std_and_exit -PAGE_SIZE=`$NM --size-sort "page_size_$$.o" | cut -d' ' -f1` -rm "page_size_$$.c" "page_size_$$.o" -test x"$PAGE_SIZE" = x"" && generate_std_and_exit -$debug && echo "PAGE_SIZE:0x$PAGE_SIZE $((0x$PAGE_SIZE))" -PAGE_SIZE=$((0x$PAGE_SIZE)) -test $PAGE_SIZE -lt 1024 && generate_std_and_exit - -# How much space between _end[] and next page? -PAGE_MASK=$((PAGE_SIZE-1)) -REM=$(( (-END) & PAGE_MASK )) -$debug && echo "REM:$REM" - -if test $REM -lt 1024; then - # _end[] has no enough space for bb_common_bufsiz1[], - # users will need to malloc it. +generate_1k_and_exit() { + generate_big_and_exit 1024 "1k" +} + + +generate_malloc_and_exit() { + $debug && echo "Configuring: bb_common_bufsiz1[] is malloced" { echo "enum { COMMON_BUFSIZE = 1024 };" echo "extern char *const bb_common_bufsiz1;" echo "void setup_common_bufsiz(void);" } | regenerate "$common_bufsiz_h" - # Check that we aren't left with a buggy binary: - if test -f "$common_bufsiz_h.BUFSIZE"; then - rm "$common_bufsiz_h.BUFSIZE" - echo "Warning! Space in _end[] is too small ($REM bytes)!" - echo "Rerun make to build a binary which doesn't use it!" - exit 1 + echo "malloc" >"$common_bufsiz_h.method" + $exitcmd +} + +# User does not want any funky stuff? +test x"$CONFIG_FEATURE_USE_BSS_TAIL" = x"y" || generate_std_and_exit + +# The script is run two times: before compilation, when it needs to +# (re)generate $common_bufsiz_h, and directly after successful build, +# when it needs to assess whether the build is ok to use at all (not buggy), +# and (re)generate $common_bufsiz_h for a future build. + +if $postcompile; then + # Postcompile needs to create/delete OK/FAIL files + + test -f busybox_unstripped || exit 1 + test -f "$common_bufsiz_h.method" || exit 1 + + # How the build was done? + method=`cat -- "$common_bufsiz_h.method"` + + # Get _end address + END=`$NM busybox_unstripped | grep ' . _end$'| cut -d' ' -f1` + test x"$END" = x"" && generate_std_and_exit + $debug && echo "END:0x$END $((0x$END))" + END=$((0x$END)) + + # Get PAGE_SIZE + { + echo "#include <sys/user.h>" + echo "#if defined(PAGE_SIZE) && PAGE_SIZE > 0" + echo "char page_size[PAGE_SIZE];" + echo "#endif" + } >page_size_$$.c + $CC -c "page_size_$$.c" || exit 1 + PAGE_SIZE=`$NM --size-sort "page_size_$$.o" | cut -d' ' -f1` + rm "page_size_$$.c" "page_size_$$.o" + test x"$PAGE_SIZE" = x"" && exit 1 + $debug && echo "PAGE_SIZE:0x$PAGE_SIZE $((0x$PAGE_SIZE))" + PAGE_SIZE=$((0x$PAGE_SIZE)) + test $PAGE_SIZE -lt 512 && exit 1 + + # How much space between _end[] and next page? + PAGE_MASK=$((PAGE_SIZE-1)) + COMMON_BUFSIZE=$(( (-END) & PAGE_MASK )) + echo "COMMON_BUFSIZE = $COMMON_BUFSIZE bytes" + + if test x"$method" = x"1k"; then + if test $COMMON_BUFSIZE -lt 1024; then + # _end[] has no enough space for bb_common_bufsiz1[] + rm -- "$common_bufsiz_h.1k.OK" 2>/dev/null + { md5sum <.config | cut -d' ' -f1; stat -c "%Y" .config; } >"$common_bufsiz_h.1k.FAIL" + echo "Warning! Space in _end[] is too small ($COMMON_BUFSIZE bytes)!" + echo "Rerun make to build a binary which doesn't use it!" + rm busybox_unstripped + exitcmd="exit 1" + else + rm -- "$common_bufsiz_h.1k.FAIL" 2>/dev/null + echo $COMMON_BUFSIZE >"$common_bufsiz_h.1k.OK" + test $COMMON_BUFSIZE -gt $((1024+32)) && echo "Rerun make to use larger COMMON_BUFSIZE" + fi fi - echo "COMMON_BUFSIZE = 1024 bytes, the buffer will be malloced" - exit 0 fi -# _end[] has REM bytes for bb_common_bufsiz1[] -OLD=1024 -test -f "$common_bufsiz_h.BUFSIZE" && OLD=`cat "$common_bufsiz_h.BUFSIZE"` -$debug && echo "OLD:$OLD" -{ -echo "enum { COMMON_BUFSIZE = $REM };" -echo "extern char _end[]; /* linker-provided label */" -echo "#define bb_common_bufsiz1 _end" -echo "#define setup_common_bufsiz() ((void)0)" -} | regenerate "$common_bufsiz_h" -echo $REM >"$common_bufsiz_h.BUFSIZE" - -# Check that code did not grow too much and thus _end[] did not shrink: -if test $OLD -gt $REM; then - echo "Warning! Space in _end[] has decreased from $OLD to $REM bytes!" - echo "Rerun make!" - exit 1 -fi +# Based on past success/fail of 1k build, decide next build type -if test $OLD != $REM; then - echo "Space in _end[] is $REM bytes. Rerun make to use larger COMMON_BUFSIZE." -else - echo "COMMON_BUFSIZE = $REM bytes" +if test -f "$common_bufsiz_h.1k.OK"; then + # Previous build succeeded fitting 1k into _end[]. + # Try bigger COMMON_BUFSIZE if possible. + COMMON_BUFSIZE=`cat -- "$common_bufsiz_h.1k.OK"` + # Round down a bit + COMMON_BUFSIZE=$(( (COMMON_BUFSIZE-32) & 0xfffffe0 )) + COMMON_BUFSIZE=$(( COMMON_BUFSIZE < 1024 ? 1024 : COMMON_BUFSIZE )) + test $COMMON_BUFSIZE = 1024 && generate_1k_and_exit + generate_big_and_exit $COMMON_BUFSIZE "big" +fi +if test -f "$common_bufsiz_h.1k.FAIL"; then + # Previous build FAILED to fit 1k into _end[]. + # Was it with same .config? + oldcfg=`cat -- "$common_bufsiz_h.1k.FAIL"` + curcfg=`md5sum <.config | cut -d' ' -f1; stat -c "%Y" .config` + # If yes, then build a "malloced" version + if test x"$oldcfg" = x"$curcfg"; then + echo "Will not try 1k build, it failed before. Touch .config to override" + generate_malloc_and_exit + fi + # else: try 1k version + echo "New .config, will try 1k build" + rm -- "$common_bufsiz_h.1k.FAIL" + generate_1k_and_exit fi +# There was no 1k build yet. Try it. +generate_1k_and_exit |