generate_BUFSIZ.sh 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #!/bin/sh
  2. # Called from top-level directory a-la
  3. #
  4. # scripts/generate_BUFSIZ.sh include/common_bufsiz.h
  5. . ./.config || exit 1
  6. debug=false
  7. #debug=true
  8. postcompile=false
  9. test x"$1" = x"--post" && { postcompile=true; shift; }
  10. common_bufsiz_h=$1
  11. test x"$NM" = x"" && NM="${CONFIG_CROSS_COMPILER_PREFIX}nm"
  12. test x"$CC" = x"" && CC="${CONFIG_CROSS_COMPILER_PREFIX}gcc"
  13. exitcmd="exit 0"
  14. regenerate() {
  15. cat >"$1.$$"
  16. test -f "$1" && diff "$1.$$" "$1" >/dev/null && rm "$1.$$" && return
  17. mv "$1.$$" "$1"
  18. }
  19. generate_std_and_exit() {
  20. $debug && echo "Configuring: bb_common_bufsiz1[] in bss"
  21. {
  22. echo "enum { COMMON_BUFSIZE = 1024 };"
  23. echo "extern char bb_common_bufsiz1[];"
  24. echo "#define setup_common_bufsiz() ((void)0)"
  25. } | regenerate "$common_bufsiz_h"
  26. echo "std" >"$common_bufsiz_h.method"
  27. $exitcmd
  28. }
  29. generate_big_and_exit() {
  30. $debug && echo "Configuring: bb_common_bufsiz1[] in _end[], COMMON_BUFSIZE = $1"
  31. {
  32. echo "enum { COMMON_BUFSIZE = $1 };"
  33. echo "extern char _end[]; /* linker-provided label */"
  34. echo "#define bb_common_bufsiz1 _end"
  35. echo "#define setup_common_bufsiz() ((void)0)"
  36. } | regenerate "$common_bufsiz_h"
  37. echo "$2" >"$common_bufsiz_h.method"
  38. $exitcmd
  39. }
  40. generate_1k_and_exit() {
  41. generate_big_and_exit 1024 "1k"
  42. }
  43. generate_malloc_and_exit() {
  44. $debug && echo "Configuring: bb_common_bufsiz1[] is malloced"
  45. {
  46. echo "enum { COMMON_BUFSIZE = 1024 };"
  47. echo "extern char *const bb_common_bufsiz1;"
  48. echo "void setup_common_bufsiz(void);"
  49. } | regenerate "$common_bufsiz_h"
  50. echo "malloc" >"$common_bufsiz_h.method"
  51. $exitcmd
  52. }
  53. round_down_COMMON_BUFSIZE() {
  54. COMMON_BUFSIZE=$(( ($1-32) & 0xfffffe0 ))
  55. COMMON_BUFSIZE=$(( COMMON_BUFSIZE < 1024 ? 1024 : COMMON_BUFSIZE ))
  56. }
  57. # User does not want any funky stuff?
  58. test x"$CONFIG_FEATURE_USE_BSS_TAIL" = x"y" || generate_std_and_exit
  59. # The script is run two times: before compilation, when it needs to
  60. # (re)generate $common_bufsiz_h, and directly after successful build,
  61. # when it needs to assess whether the build is ok to use at all (not buggy),
  62. # and (re)generate $common_bufsiz_h for a future build.
  63. if $postcompile; then
  64. # Postcompile needs to create/delete OK/FAIL files
  65. test -f busybox_unstripped || exit 1
  66. test -f "$common_bufsiz_h.method" || exit 1
  67. # How the build was done?
  68. method=`cat -- "$common_bufsiz_h.method"`
  69. # Get _end address
  70. END=`$NM busybox_unstripped | grep ' . _end$'| cut -d' ' -f1`
  71. test x"$END" = x"" && generate_std_and_exit
  72. $debug && echo "END:0x$END $((0x$END))"
  73. END=$((0x$END))
  74. # Get PAGE_SIZE
  75. {
  76. echo "#include <sys/user.h>"
  77. echo "#if defined(PAGE_SIZE) && PAGE_SIZE > 0"
  78. echo "char page_size[PAGE_SIZE];"
  79. echo "#endif"
  80. } >page_size_$$.c
  81. $CC -c "page_size_$$.c" || exit 1
  82. PAGE_SIZE=`$NM --size-sort "page_size_$$.o" | cut -d' ' -f1`
  83. rm "page_size_$$.c" "page_size_$$.o"
  84. test x"$PAGE_SIZE" = x"" && exit 1
  85. $debug && echo "PAGE_SIZE:0x$PAGE_SIZE $((0x$PAGE_SIZE))"
  86. PAGE_SIZE=$((0x$PAGE_SIZE))
  87. test $PAGE_SIZE -lt 512 && exit 1
  88. # How much space between _end[] and next page?
  89. PAGE_MASK=$((PAGE_SIZE-1))
  90. TAIL_SIZE=$(( (-END) & PAGE_MASK ))
  91. $debug && echo "TAIL_SIZE:$TAIL_SIZE bytes"
  92. if test x"$method" = x"1k" || test x"$method" = x"big"; then
  93. if test $TAIL_SIZE -lt 1024; then
  94. # _end[] has no enough space for bb_common_bufsiz1[]
  95. echo "Warning! Space in _end[] is too small ($TAIL_SIZE bytes)!"
  96. echo "Rerun make to build a binary which doesn't use it!"
  97. rm -- "$common_bufsiz_h.1k.OK" 2>/dev/null
  98. { md5sum <.config | cut -d' ' -f1; stat -c "%Y" .config; } >"$common_bufsiz_h.1k.FAIL"
  99. rm busybox_unstripped busybox 2>/dev/null
  100. # Note: here we can do either a "malloc" or "std" build.
  101. # "malloc" gives a bit bigger code:
  102. # text bss filename
  103. # 804355 5385 busybox.std
  104. # 804618 4361 busybox.malloc
  105. # but may have a smaller .bss (not guaranteed!). Use "pmap -x" to verify.
  106. exitcmd="exit 1"
  107. generate_malloc_and_exit
  108. else
  109. PREV_SIZE=1024
  110. test x"$method" = x"big" && PREV_SIZE=`cat -- "$common_bufsiz_h.1k.OK"`
  111. round_down_COMMON_BUFSIZE $PREV_SIZE
  112. PREV_BUFSIZE=$COMMON_BUFSIZE
  113. rm -- "$common_bufsiz_h.1k.FAIL" 2>/dev/null
  114. echo $TAIL_SIZE >"$common_bufsiz_h.1k.OK"
  115. round_down_COMMON_BUFSIZE $TAIL_SIZE
  116. # emit message only if COMMON_BUFSIZE is indeed larger
  117. test $COMMON_BUFSIZE -gt $PREV_BUFSIZE \
  118. && echo "Rerun make to use larger COMMON_BUFSIZE ($COMMON_BUFSIZE)"
  119. #TODO: test $PREV_BUFSIZE -lt $TAIL_SIZE && PANIC!!!
  120. #Code size with COMMON_BUFSIZE > 1024 may be bigger than code with COMMON_BUFSIZE = 1024!
  121. #(currently we just hope "-32 and round down to 32" saves us)
  122. test $COMMON_BUFSIZE = 1024 && generate_1k_and_exit
  123. generate_big_and_exit $COMMON_BUFSIZE "big"
  124. fi
  125. fi
  126. fi
  127. # Based on past success/fail of 1k build, decide next build type
  128. if test -f "$common_bufsiz_h.1k.OK"; then
  129. # Previous build succeeded fitting 1k into _end[].
  130. # Try bigger COMMON_BUFSIZE if possible.
  131. TAIL_SIZE=`cat -- "$common_bufsiz_h.1k.OK"`
  132. round_down_COMMON_BUFSIZE $TAIL_SIZE
  133. test $COMMON_BUFSIZE = 1024 && generate_1k_and_exit
  134. generate_big_and_exit $COMMON_BUFSIZE "big"
  135. fi
  136. if test -f "$common_bufsiz_h.1k.FAIL"; then
  137. # Previous build FAILED to fit 1k into _end[].
  138. # Was it with same .config?
  139. oldcfg=`cat -- "$common_bufsiz_h.1k.FAIL"`
  140. curcfg=`md5sum <.config | cut -d' ' -f1; stat -c "%Y" .config`
  141. # If yes, then build a "malloced" version
  142. if test x"$oldcfg" = x"$curcfg"; then
  143. echo "Will not try 1k build, it failed before. Touch .config to override"
  144. # Note: here we can do either a "malloc" or "std" build.
  145. generate_malloc_and_exit
  146. fi
  147. # else: try 1k version
  148. echo "New .config, will try 1k build"
  149. rm -- "$common_bufsiz_h.1k.FAIL"
  150. generate_1k_and_exit
  151. fi
  152. # There was no 1k build yet. Try it.
  153. generate_1k_and_exit