From fac5375ea67f728f419e84491b8bd8f65bd64b74 Mon Sep 17 00:00:00 2001 From: Matthew Kilgore Date: Tue, 7 Feb 2023 02:38:10 -0500 Subject: [PATCH] Fix DECLARE LIBRARY against stripped .so file .so files can be stripped such that they contain no "regular" symbol table but do still contain the "dynamic" symbol table, this is pretty typical for .so files. QB64-PE is supposed to check both tables when linking against a .so file, but a bug in ab0c2b18 meant that the second run of nm with the -D flag to check the dynamic symbol table no longer happens. The fix is to introduce a new output file for the dynamic run so that they are handled separately in terms of caching the result. A new test .so file that only contains a dynamic symbol table was added to avoid this in the future. Fixes: #301 --- source/qb64pe.bas | 25 +++++++++++------- source/utilities/build.bas | 6 +++-- .../liblibstripped.so | Bin 0 -> 14040 bytes .../test_stripped.bas | 23 ++++++++++++++++ .../test_stripped.output | 1 + 5 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 tests/compile_tests/declare_library_external/liblibstripped.so create mode 100644 tests/compile_tests/declare_library_external/test_stripped.bas create mode 100644 tests/compile_tests/declare_library_external/test_stripped.output diff --git a/source/qb64pe.bas b/source/qb64pe.bas index 78af3f8a4..ee25cb495 100644 --- a/source/qb64pe.bas +++ b/source/qb64pe.bas @@ -12582,8 +12582,11 @@ END IF 'Clear nm output from previous runs FOR x = 1 TO ResolveStaticFunctions IF LEN(ResolveStaticFunction_File(x)) THEN - s$ = MakeNMOutputFilename$(ResolveStaticFunction_File(x)) - IF _FILEEXISTS(s$) THEN KILL s$ + s$ = MakeNMOutputFilename$(ResolveStaticFunction_File(x), 0) + IF _FILEEXISTS(s$) THEN KILL s$: ClearBuffers s$ + + s$ = MakeNMOutputFilename$(ResolveStaticFunction_File(x), 1) + IF _FILEEXISTS(s$) THEN KILL s$: ClearBuffers s$ END IF NEXT x @@ -12602,7 +12605,8 @@ IF os$ = "WIN" THEN 'resolve static function definitions and add to global.txt FOR x = 1 TO ResolveStaticFunctions - nm_output_file$ = MakeNMOutputFilename$(ResolveStaticFunction_File(x)) + nm_output_file$ = MakeNMOutputFilename$(ResolveStaticFunction_File(x), 0) + nm_output_file_dynamic$ = MakeNMOutputFilename$(ResolveStaticFunction_File(x), 1) IF LEN(ResolveStaticFunction_File(x)) THEN n = 0 @@ -12659,8 +12663,8 @@ IF os$ = "WIN" THEN END IF IF n = 0 THEN 'a C++ dynamic object library? - IF NOT _FILEEXISTS(nm_output_file$) THEN - SHELL _HIDE "cmd /c internal\c\c_compiler\bin\nm.exe " + AddQuotes$(ResolveStaticFunction_File(x)) + " -D --demangle -g >" + AddQuotes$(nm_output_file$) + IF NOT _FILEEXISTS(nm_output_file_dynamic$) THEN + SHELL _HIDE "cmd /c internal\c\c_compiler\bin\nm.exe " + AddQuotes$(ResolveStaticFunction_File(x)) + " -D --demangle -g >" + AddQuotes$(nm_output_file_dynamic$) END IF s$ = " " + ResolveStaticFunction_Name(x) + "(" fh = OpenBuffer%("I", nm_output_file$) @@ -12687,7 +12691,7 @@ IF os$ = "WIN" THEN IF n = 0 THEN 'a C dynamic object library? s$ = " " + ResolveStaticFunction_Name(x) - fh = OpenBuffer%("I", nm_output_file$) + fh = OpenBuffer%("I", nm_output_file_dynamic$) DO UNTIL EndOfBuf%(fh) a$ = ReadBufLine$(fh) IF LEN(a$) THEN @@ -12751,7 +12755,8 @@ IF os$ = "LNX" THEN END IF FOR x = 1 TO ResolveStaticFunctions - nm_output_file$ = MakeNMOutputFilename$(ResolveStaticFunction_File(x)) + nm_output_file$ = MakeNMOutputFilename$(ResolveStaticFunction_File(x), 0) + nm_output_file_dynamic$ = MakeNMOutputFilename$(ResolveStaticFunction_File(x), 1) IF LEN(ResolveStaticFunction_File(x)) THEN n = 0 @@ -12814,8 +12819,8 @@ IF os$ = "LNX" THEN IF n = 0 THEN 'a C++ dynamic object library? IF MacOSX THEN GOTO macosx_libfind_failed - IF NOT _FILEEXISTS(nm_output_file$) THEN - SHELL _HIDE "nm " + AddQuotes$(ResolveStaticFunction_File(x)) + " -D --demangle -g >" + AddQuotes$(nm_output_file$) + " 2>" + AddQuotes$(tmpdir$ + "nm_error.txt") + IF NOT _FILEEXISTS(nm_output_file_dynamic$) THEN + SHELL _HIDE "nm " + AddQuotes$(ResolveStaticFunction_File(x)) + " -D --demangle -g >" + AddQuotes$(nm_output_file_dynamic$) + " 2>" + AddQuotes$(tmpdir$ + "nm_error.txt") END IF s$ = " " + ResolveStaticFunction_Name(x) + "(" fh = OpenBuffer%("I", nm_output_file$) @@ -12842,7 +12847,7 @@ IF os$ = "LNX" THEN IF n = 0 THEN 'a C dynamic object library? s$ = " " + ResolveStaticFunction_Name(x) - fh = OpenBuffer%("I", nm_output_file$) + fh = OpenBuffer%("I", nm_output_file_dynamic$) DO UNTIL EndOfBuf%(fh) a$ = ReadBufLine$(fh) IF LEN(a$) THEN diff --git a/source/utilities/build.bas b/source/utilities/build.bas index b03838c3b..9ef5f17ff 100644 --- a/source/utilities/build.bas +++ b/source/utilities/build.bas @@ -27,6 +27,8 @@ FUNCTION GetMakeExecutable$ () END IF END FUNCTION -FUNCTION MakeNMOutputFilename$ (libfile AS STRING) - MakeNMOutputFilename$ = tmpdir$ + "nm_output_" + StrReplace$(StrReplace$(libfile, pathsep$, "."), ":", ".") + ".txt" +FUNCTION MakeNMOutputFilename$ (libfile AS STRING, dynamic As Long) + If dynamic Then dyn$ = "_dynamic" Else dyn$ = "" + + MakeNMOutputFilename$ = tmpdir$ + "nm_output_" + StrReplace$(StrReplace$(libfile, pathsep$, "."), ":", ".") + dyn$ + ".txt" END FUNCTION diff --git a/tests/compile_tests/declare_library_external/liblibstripped.so b/tests/compile_tests/declare_library_external/liblibstripped.so new file mode 100644 index 0000000000000000000000000000000000000000..831ff9ab4e440a8920087f5517240b97347af65c GIT binary patch literal 14040 zcmeHOU1%It6uz4@?Y2#mC{@=+nyE%;tsN8FqHRgD5R;D9YHgDT(K4NMr^(7@H}1~b zAG9t6B_R~@AcB1=MIm_*ich`>EtTM#tq-CPLQpF$NE#F+mD2H?ne%O@V}gHL7YKgeBnC-j%m zc?m)*smnd;I9u$v-XK$gMx5P2NrS;8MsTj`55aaz{+=J!dRWGxYe)|O%=Mgsg zK%?JFgkxU*so-NiApI8m94f*mw3q>(T!Yulo)`KQ(Q|?4QY#bS@mjGt{>YixpVW_E zevliPJ(#jKjGURuf6b{(E7#za{cQ>Be%HzePhXTd|!N(Wz^PCsT=l%=% z`^bNg?4#MdlgplTm6OTXZ#cQKTT-|muny;>|ER2Y_|Icr>2O-`r^KG=4E@Y4UnAsN z#4k%b2+c+O_$)avAMs<&p_bN~0nLDBKr^5j&Gy|Fe&A`$a__cBUAJ)jvNo&0B z`V&f7?_BU|{L9wJ=gCV!L4W)A)Y7iT-Ii}STsV%oZL+gnQo_DO-HKXbIP zh57)`{VN?Vg;jZTpEc64j)&IRRj=L}@8}`p+RMK0U(3*Gx~_xl#391og};7`f?TMN zaAR-X8Y|C__uU%ro=;pp#8+MAq{;$0wP*%31DXNNfM!55pc&8%Xa+O`ngPv#X5c@} zK%%*JS1Zk*e|t0Ld_PUPjr1Vto1`nGS@^eAmc+>eDsj9i(OkbGIYB@0G4>%kzPaK1 z!B2w?O+5{%=NeZZOIB3px}A@0ZGD(=jHf^2)dl3SlZ3Ia((yX=3V!SCZfJV9rfbde z7pVa!XweL41~dbj0nLDBKr^5j&Gy|G}{{;isXNrBL^|&h8XSzo0wfBUB2gSyI z)n>8rx8gdnv2T_CzGOlCx7&V!?K#{XmhayU3E+V>s`_T@?% zZ;B6OMW|GASvWx7N%5}~4g5_%oKLlm#Q!aYeeCgm*w4GCt81sRv9G_J_sYf&bDP<= zrM(GuyVA?VCcsQf6teEV47)||M8wr!&gL>(vKbX5 z3_7JjWoAy~ODBdx?G=?-baM_nm6^?FJ!KB(JaeEx1J6B9XWGG>Ri-;=A1yjVu05C` z2&@odJH?_yT{#nDs^<)4k5J!&#}%oa<2lOgFO`&eq%bt(=Dj!%OSO5O@LIrL=lFX7 zMyxQ_3Eb;x5XCR{9su%XxxrNYy2kIcw$LBz9h(1d!vb8q|1OI0H2{zM0eXVLB-l$2 zJl1s=#du8vkNXSyFvX%0-7C)iy>#&0fUn+9GGW|L@%f`a@1y6MxS#Pp2Q;1=loAN) z!2Xy9QM@6~BWN*^jTc)& literal 0 HcmV?d00001 diff --git a/tests/compile_tests/declare_library_external/test_stripped.bas b/tests/compile_tests/declare_library_external/test_stripped.bas new file mode 100644 index 000000000..b6264036a --- /dev/null +++ b/tests/compile_tests/declare_library_external/test_stripped.bas @@ -0,0 +1,23 @@ +$CONSOLE:ONLY + +$IF LNX THEN + +' This file is missing the regular symbol table and only contains the dynamic symbol table +DECLARE LIBRARY "./libstripped" + FUNCTION add_values&(BYVAL v1 AS LONG, BYVAL v2 as LONG) +END DECLARE + +result = add_values&(2, 3) +PRINT result + + +$ELSE + +' Windows can't use regular DECLARE LIBRARY to link against a dll, just skip this test +' +' Mac OS dylib files don't have a dynamic symbol table, so also nothing to test +PRINT 5 + +$END IF + +SYSTEM diff --git a/tests/compile_tests/declare_library_external/test_stripped.output b/tests/compile_tests/declare_library_external/test_stripped.output new file mode 100644 index 000000000..922e8a64c --- /dev/null +++ b/tests/compile_tests/declare_library_external/test_stripped.output @@ -0,0 +1 @@ + 5