<div dir="ltr">Hi All,<div><br></div><div>There was no update last week -- I'm still trying to get back into a regular schedule.</div><div><br></div><div>Open-source changes since the last update were:</div><div><br></div><div>(1) Some bug fixes for JITLink MachO / arm64 support (PAGE21/PAGEOFF12 now handle addends correctly).</div><div>(2) llvm-jitlink now supports loading archives as well as relocatable objects.</div><div>(3) llvm-jitlink now supports basic object-file level mocking and testing.</div><div><br></div><div>That last one is unusual so I want to expand on it. The llvm-jitlink tool acquired a couple of new options to support this feature: "--phony-externals" which resolves all otherwise unresolved symbols to null instead of erroring, and "-harness" which allows a set of objects to be designated as a test harness, with the regular object files implicitly treated as objects to be tested. If the -harness option is passed llvm-jitlink installs a JITLink plugin to make some modifications to the usual linker rules:</div><div><br></div><div>-- All symbols referenced by the harness object(s) are promoted to default visibility so that the harness can directly access static symbols inside the test object(s)</div><div>-- All symbols defined by the harness object(s) override (rather than clashing with) symbols defined in the test object(s).</div><div><br></div><div>With these modifications in place we can selectively test functions in an object file by mocking their callees. For example, suppose we have an object file, test_code.o, compiled from the following C source (which we do not have access to):</div><div><br></div><div><font face="monospace">void irrelevant_function() { irrelevant_external(); }</font></div><div><font face="monospace"><br></font></div><div><font face="monospace">int function_to_mock(int X) {</font></div><div><font face="monospace">  return /* some function of X */;</font></div><div><font face="monospace">}<br></font></div><div><font face="monospace"><br></font></div><div><font face="monospace">static void function_to_test() {</font></div><div><font face="monospace">  ...</font></div><div><font face="monospace">  int Y = function_to_mock();</font></div><div><font face="monospace">  printf("Y is %i\n", Y);</font></div><div><font face="monospace">}</font></div><div><br></div><div>We would like to know how function_to_test behaves when we change the behavior of function_to_mock. We can do this by writing a test harness:</div><div><br></div><div><font face="monospace">void function_to_test();</font></div><div><font face="monospace"><br></font></div><div><font face="monospace">int function_to_mock(int X) {</font></div><div><font face="monospace">  printf("used mock utility function\n");</font></div><div><font face="monospace">  return 42;</font></div><div><font face="monospace">}</font></div><div><font face="monospace"><br></font></div><div><font face="monospace">int main(int argc, char *argv[]) {</font></div><div><font face="monospace">  function_to_test():</font></div><div><font face="monospace">  return 0; </font></div><div><font face="monospace">}</font></div><div><br></div><div>This harness code could not be linked against test_code.o under normal circumstances: function_to_test is static and will fail to resolve from the harness code, function_to_mock is a duplicate definition, and irrelevant_external is undefined. Our new llvm-jitlink options take care of these issues however, and running the test looks like:</div><div><br></div><div><span style="font-family:monospace">% clang -c -o test_code_harness.o test_code_harness.c</span><br></div><div><font face="monospace">% llvm-jitlink -phony-externals test_code.o -harness test_code_harness.o</font></div><div><font face="monospace">used mock utility function</font></div><div><font face="monospace">Y is 42</font></div><div><br></div><div>This utility may be of interest to people who want to perform some very late testing on build products to verify that compiled code behaves as expected. On basic C test cases it works reasonably well. C++ test cases are another matter: Any code involving classes tends to have a lot of non-trivial surface area (e.g. vtables) that would require great care to mock. Perhaps we need a new tool to tackle that problem.</div><div><br></div><div>In the meantime, if nothing else this provides a neat example of how JITLink plugins can be used to modify the default linker behavior.</div><div><br></div><div>Regards,</div><div>Lang. </div></div>