indirect.exp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. # Expect script for various indirect symbol tests.
  2. # Copyright (C) 2012-2022 Free Software Foundation, Inc.
  3. #
  4. # This file is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
  17. #
  18. #
  19. # Written by H.J. Lu (hongjiu.lu@intel.com)
  20. #
  21. # Exclude non-ELF targets.
  22. if ![is_elf_format] {
  23. return
  24. }
  25. # Skip target where -shared is not supported
  26. if ![check_shared_lib_support] {
  27. return
  28. }
  29. # Check if compiler works
  30. if { ![check_compiler_available] } {
  31. return
  32. }
  33. # Some bare-metal targets don't support shared libs or PIC.
  34. if { ![run_host_cmd_yesno $CC_FOR_TARGET "-shared -fPIC $srcdir/$subdir/dummy.c -o tmpdir/t.so"] } {
  35. return
  36. }
  37. proc check_link_message { cmd string testname } {
  38. send_log "$cmd\n"
  39. verbose "$cmd"
  40. catch "exec $cmd" exec_output
  41. send_log "$exec_output\n"
  42. verbose "$exec_output"
  43. foreach str $string {
  44. if [string match "*$str*" $exec_output] {
  45. pass "$testname: $str"
  46. } else {
  47. fail "$testname: $str"
  48. }
  49. }
  50. }
  51. # Disable LTO for these tests.
  52. set cc_cmd "$CC_FOR_TARGET"
  53. if {[check_lto_available]} {
  54. append cc_cmd " -fno-lto"
  55. }
  56. # Disable all sanitizers.
  57. append cc_cmd " $NOSANITIZE_CFLAGS"
  58. if { ![ld_compile $cc_cmd $srcdir/$subdir/indirect1a.c tmpdir/indirect1a.o]
  59. || ![ld_compile $cc_cmd $srcdir/$subdir/indirect1b.c tmpdir/indirect1b.o]
  60. || ![ld_compile "$cc_cmd -fPIC" $srcdir/$subdir/indirect2.c tmpdir/indirect2.o]
  61. || ![ld_compile $cc_cmd $srcdir/$subdir/indirect3a.c tmpdir/indirect3a.o]
  62. || ![ld_compile $cc_cmd $srcdir/$subdir/indirect3b.c tmpdir/indirect3b.o]
  63. || ![ld_compile $cc_cmd $srcdir/$subdir/indirect4a.c tmpdir/indirect4a.o]
  64. || ![ld_compile $cc_cmd $srcdir/$subdir/indirect4b.c tmpdir/indirect4b.o]
  65. || ![ld_compile "$cc_cmd -O2 -fPIC -I../bfd" $srcdir/$subdir/pr18720a.c tmpdir/pr18720a.o]
  66. || ![ld_compile $cc_cmd $srcdir/$subdir/pr18720b.c tmpdir/pr18720b.o]
  67. || ![ld_compile "$cc_cmd -fPIC" $srcdir/$subdir/pr19553d.c tmpdir/pr19553d.o]
  68. || ![ld_compile "$cc_cmd -fPIC" $srcdir/$subdir/pr19553c.c tmpdir/pr19553c.o]
  69. || ![ld_compile "$cc_cmd -fPIC" $srcdir/$subdir/pr19553b.c tmpdir/pr19553b.o]
  70. || ![ld_compile $cc_cmd $srcdir/$subdir/pr19553a.c tmpdir/pr19553a.o] } {
  71. unsupported "Indirect symbol tests"
  72. return
  73. }
  74. set build_tests {
  75. {"Build libindirect1c.so"
  76. "-shared" "-fPIC"
  77. {indirect1c.c} {} "libindirect1c.so"}
  78. {"Build libindirect3c.so"
  79. "-shared" "-fPIC"
  80. {indirect3c.c} {} "libindirect3c.so"}
  81. {"Build libindirect4c.so"
  82. "-shared" "-fPIC"
  83. {indirect4c.c} {} "libindirect4c.so"}
  84. {"Build libindirect5.so"
  85. "-shared -Wl,--version-script=indirect5.map" "-fPIC"
  86. {indirect5b.c} {} "libindirect5.so"}
  87. {"Build libpr18720c.so"
  88. "-shared" "-fPIC"
  89. {pr18720c.c} {} "libpr18720c.so"}
  90. {"Build pr18720b1.o"
  91. "-r -nostdlib tmpdir/pr18720b.o" ""
  92. {dummy.c} {} "pr18720b1.o"}
  93. {"Build pr18720a"
  94. "tmpdir/pr18720a.o tmpdir/pr18720b.o tmpdir/libpr18720c.so" ""
  95. {check-ptr-eq.c} {{readelf {--dyn-syms} pr18720.rd}} "pr18720a"}
  96. {"Build libpr19553b.so"
  97. "-shared -Wl,--version-script=pr19553.map" "-fPIC"
  98. {pr19553b.c} {} "libpr19553b.so"}
  99. {"Build libpr19553c.so"
  100. "-shared -Wl,--version-script=pr19553.map" "-fPIC"
  101. {pr19553c.c} {} "libpr19553c.so"}
  102. {"Build libpr19553d.so"
  103. "-shared tmpdir/libpr19553c.so" "-fPIC"
  104. {pr19553d.c} {} "libpr19553d.so"}
  105. }
  106. run_cc_link_tests $build_tests
  107. set string ": final link failed: bad value"
  108. set string1 ": local symbol \`foo\' in tmpdir/indirect1b.o is referenced by DSO"
  109. set testname "Indirect symbol 1a"
  110. set cmd "$ld -e start -o tmpdir/indirect1 tmpdir/indirect1a.o tmpdir/indirect1b.o tmpdir/libindirect1c.so"
  111. check_link_message "$cmd" [list $string1 $string] "$testname"
  112. set testname "Indirect symbol 1b"
  113. set cmd "$ld -e start -o tmpdir/indirect1 tmpdir/indirect1a.o tmpdir/libindirect1c.so tmpdir/indirect1b.o"
  114. check_link_message "$cmd" [list $string1 $string] "$testname"
  115. set string2 ": no symbol version section for versioned symbol \`foo@FOO\'"
  116. set testname "Indirect symbol 2"
  117. set cmd "$ld -shared -o tmpdir/indirect2.so tmpdir/indirect2.o"
  118. check_link_message "$cmd" [list $string2] "$testname"
  119. set run_tests {
  120. {"Run with libindirect3c.so 1"
  121. "-Wl,--no-as-needed tmpdir/indirect3a.o tmpdir/indirect3b.o tmpdir/libindirect3c.so" ""
  122. {dummy.c} "indirect3a" "indirect3.out"}
  123. {"Run with libindirect3c.so 2"
  124. "-Wl,--no-as-needed tmpdir/indirect3a.o tmpdir/libindirect3c.so tmpdir/indirect3b.o" ""
  125. {dummy.c} "indirect3b" "indirect3.out"}
  126. {"Run with libindirect3c.so 3"
  127. "-Wl,--no-as-needed tmpdir/indirect3b.o tmpdir/libindirect3c.so tmpdir/indirect3a.o" ""
  128. {dummy.c} "indirect3c" "indirect3.out"}
  129. {"Run with libindirect3c.so 4"
  130. "-Wl,--no-as-needed tmpdir/libindirect3c.so tmpdir/indirect3b.o tmpdir/indirect3a.o" ""
  131. {dummy.c} "indirect3d" "indirect3.out"}
  132. {"Run with libindirect4c.so 1"
  133. "-Wl,--no-as-needed tmpdir/indirect4a.o tmpdir/indirect4b.o tmpdir/libindirect4c.so" ""
  134. {dummy.c} "indirect4a" "indirect4.out"}
  135. {"Run with libindirect4c.so 2"
  136. "-Wl,--no-as-needed tmpdir/indirect4a.o tmpdir/libindirect4c.so tmpdir/indirect4b.o" ""
  137. {dummy.c} "indirect4b" "indirect4.out"}
  138. {"Run with libindirect4c.so 3"
  139. "-Wl,--no-as-needed tmpdir/indirect4b.o tmpdir/libindirect4c.so tmpdir/indirect4a.o" ""
  140. {dummy.c} "indirect4c" "indirect4.out"}
  141. {"Run with libindirect4c.so 4"
  142. "-Wl,--no-as-needed tmpdir/libindirect4c.so tmpdir/indirect4b.o tmpdir/indirect4a.o" ""
  143. {dummy.c} "indirect4d" "indirect4.out"}
  144. {"Run indirect5 1"
  145. "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libindirect5.so" ""
  146. {indirect5a.c} "indirect5a" "indirect5.out" "$NOPIE_CFLAGS"}
  147. {"Run indirect5 2"
  148. "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/indirect5a.o tmpdir/libindirect5.so" ""
  149. {dummy.c} "indirect5b" "indirect5.out" "$NOPIE_CFLAGS"}
  150. {"Run indirect6 1"
  151. "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libindirect5.so" ""
  152. {indirect6a.c} "indirect6a" "indirect5.out" "$NOPIE_CFLAGS"}
  153. {"Run indirect6 2"
  154. "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/indirect6a.o tmpdir/libindirect5.so" ""
  155. {dummy.c} "indirect6b" "indirect5.out" "$NOPIE_CFLAGS"}
  156. {"Run with libpr18720c.so 1"
  157. "-Wl,--no-as-needed tmpdir/pr18720a.o tmpdir/pr18720b.o tmpdir/libpr18720c.so" ""
  158. {check-ptr-eq.c} "pr18720a" "pr18720.out"}
  159. {"Run with libpr18720c.so 2"
  160. "-Wl,--no-as-needed tmpdir/pr18720a.o tmpdir/libpr18720c.so tmpdir/pr18720b.o" ""
  161. {check-ptr-eq.c} "pr18720b" "pr18720.out"}
  162. {"Run with libpr18720c.so 3"
  163. "-Wl,--no-as-needed tmpdir/pr18720b.o tmpdir/libpr18720c.so tmpdir/pr18720a.o" ""
  164. {check-ptr-eq.c} "pr18720c" "pr18720.out"}
  165. {"Run with libpr18720c.so 4"
  166. "-Wl,--no-as-needed tmpdir/libpr18720c.so tmpdir/pr18720b.o tmpdir/pr18720a.o" ""
  167. {check-ptr-eq.c} "pr18720d" "pr18720.out"}
  168. {"Run with libpr18720c.so 5"
  169. "-Wl,--no-as-needed tmpdir/libpr18720c.so tmpdir/pr18720b1.o tmpdir/pr18720a.o" ""
  170. {check-ptr-eq.c} "pr18720d" "pr18720.out"}
  171. {"Run with libpr19553b.so"
  172. "-Wl,--no-as-needed tmpdir/libpr19553b.so tmpdir/libpr19553d.so -Wl,-rpath-link,." ""
  173. {pr19553a.c} "pr19553b" "pr19553b.out"}
  174. {"Run with libpr19553c.so"
  175. "-Wl,--no-as-needed tmpdir/libpr19553c.so tmpdir/libpr19553b.so tmpdir/libpr19553d.so" ""
  176. {pr19553a.c} "pr19553c" "pr19553c.out"}
  177. {"Run with libpr19553d.so"
  178. "-Wl,--no-as-needed tmpdir/libpr19553d.so tmpdir/libpr19553b.so -Wl,-rpath-link,." ""
  179. {pr19553a.c} "pr19553d" "pr19553d.out"}
  180. }
  181. run_ld_link_exec_tests $run_tests
  182. # Check that "bar" is not dynamic in the executable
  183. proc check_dynamic_syms { test } {
  184. global nm
  185. set cmd "$nm -D $test > dump.out"
  186. send_log "$cmd\n"
  187. catch "exec $cmd" comp_output
  188. if ![string match "" $comp_output] then {
  189. send_log "$comp_output\n"
  190. return 0
  191. }
  192. if { [string match "* bar\n*" [file_contents "dump.out"]] } then {
  193. verbose "output is [file_contents "dump.out"]"
  194. return 0
  195. }
  196. return 1
  197. }
  198. foreach t [list indirect5a indirect5b indirect6a indirect6b] {
  199. set testname [concat $t "dynsym"]
  200. if { [check_dynamic_syms tmpdir/$t] } {
  201. pass $testname
  202. } else {
  203. fail $testname
  204. }
  205. }
  206. send_log "$CC_FOR_TARGET -fPIE -pie $srcdir/$subdir/main.c -o tmpdir/pie"
  207. catch "exec $CC_FOR_TARGET -fPIE -pie $srcdir/$subdir/main.c -o tmpdir/pie" exec_output
  208. send_log "$exec_output"
  209. if { ! [string match "" $exec_output] } {
  210. return
  211. }
  212. set pie_tests {
  213. {"Run indirect5 3"
  214. "-pie -Wl,--no-as-needed tmpdir/libindirect5.so" ""
  215. {indirect5a.c} "indirect5c" "indirect5.out" "-fPIE"}
  216. {"Run indirect5 4"
  217. "-pie -Wl,--no-as-needed tmpdir/indirect5a.o tmpdir/libindirect5.so" ""
  218. {dummy.c} "indirect5d" "indirect5.out" "-fPIE"}
  219. {"Run indirect6 3"
  220. "-pie -Wl,--no-as-needed tmpdir/libindirect5.so" ""
  221. {indirect6a.c} "indirect6c" "indirect5.out" "-fPIE"}
  222. {"Run indirect6 4"
  223. "-pie -Wl,--no-as-needed tmpdir/indirect6a.o tmpdir/libindirect5.so" "-fPIE"
  224. {dummy.c} "indirect6d" "indirect5.out" "-fPIE"}
  225. }
  226. run_ld_link_exec_tests $pie_tests
  227. foreach t [list indirect5c indirect5d indirect6c indirect6d] {
  228. set testname [concat $t "dynsym"]
  229. if { [check_dynamic_syms tmpdir/$t] } {
  230. pass $testname
  231. } else {
  232. fail $testname
  233. }
  234. }