commit 005b0768c37e2ab7f456eb0423db8375953f33a9
parent 0ac243be7e8c6aa564736bc7935bd018076b6113
Author: Kyle Milz <kyle@0x30.net>
Date: Wed, 15 Jun 2016 20:48:28 -0600
src: make instrumented application depend on runtime lib
Diffstat:
13 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/lib/Jamfile b/lib/Jamfile
@@ -1,8 +1,6 @@
SubDir TOP lib ;
-SubDirCcFlags -pthread -fpic -DPIC ;
+SubDirCcFlags -pthread ;
-Main libcitrun.$(SHLIB_SUF) : runtime.c ;
-InstallLib $(PREFIX)/lib : libcitrun.$(SHLIB_SUF) ;
-
-LINKFLAGS on libcitrun.$(SHLIB_SUF) += -shared -fpic -pthread ;
+Library libcitrun : runtime.c ;
+InstallLib $(PREFIX)/lib : libcitrun ;
diff --git a/lib/runtime.c b/lib/runtime.c
@@ -20,6 +20,8 @@ extern uint64_t citrun_nodes_total;
void send_metadata(int);
void send_execution_data(int);
+/* Make sure instrumented programs rely on this library in some way. */
+int needs_to_link_against_libcitrun;
int xread(int d, const void *buf, size_t bytes_total);
int xwrite(int d, const void *buf, size_t bytes_total);
diff --git a/src/inst_action.cc b/src/inst_action.cc
@@ -88,6 +88,8 @@ InstrumentAction::EndSourceFileAction()
// Embed the header directly in the primary source file.
ss << runtime_h << std::endl;
+ ss << "extern int needs_to_link_against_libcitrun;" << std::endl;
+
// Define storage for coverage data
ss << "static uint64_t _citrun_lines[" << num_lines << "];" << std::endl;
diff --git a/src/inst_ast_visitor.cc b/src/inst_ast_visitor.cc
@@ -66,6 +66,16 @@ RewriteASTVisitor::VisitFunctionDecl(clang::FunctionDecl *f)
if (f->hasBody() == 0)
return true;
+ // We need to depend directly on a symbol provided by libcitrun,
+ // otherwise the library will get discarded at link time.
+ std::stringstream ss;
+ ss << "needs_to_link_against_libcitrun = 0;";
+
+ clang::Stmt *FuncBody = f->getBody();
+ clang::SourceLocation curly_brace(FuncBody->getLocStart().getLocWithOffset(1));
+
+ TheRewriter.InsertTextBefore(curly_brace, ss.str());
+
return true;
}
diff --git a/src/inst_main.cc b/src/inst_main.cc
@@ -202,6 +202,7 @@ patch_link_command(std::vector<char *> &args)
// Add the runtime library and the symbol define hack
// automatically to the command line
+ args.push_back("-pthread");
args.push_back(lib_str);
}
diff --git a/t/fibonacci.t b/t/fibonacci.t
@@ -50,7 +50,7 @@ my $inst_src_good = <<EOF;
long long
fibonacci(long long n)
-{
+{needs_to_link_against_libcitrun = 0;
if ((++_citrun_lines[7], n == 0))
return (++_citrun_lines[8], 0);
else if ((++_citrun_lines[9], n == 1))
@@ -61,7 +61,7 @@ fibonacci(long long n)
int
main(int argc, char *argv[])
-{
+{needs_to_link_against_libcitrun = 0;
long long n;
if ((++_citrun_lines[20], argc != 2)) {
diff --git a/t/for.t b/t/for.t
@@ -28,7 +28,7 @@ $project->compile();
my $inst_src_good = <<EOF;
int
main(void)
-{
+{needs_to_link_against_libcitrun = 0;
int i;
for (i = 0; (++_citrun_lines[6], i < 19); i++) {
diff --git a/t/hello_world.t b/t/hello_world.t
@@ -27,7 +27,7 @@ my $inst_src_good = <<EOF;
int
main(void)
-{
+{needs_to_link_against_libcitrun = 0;
(++_citrun_lines[6], printf("hello, world!"));
return (++_citrun_lines[7], 0);
}
diff --git a/t/if.t b/t/if.t
@@ -38,7 +38,7 @@ my $inst_src_good = <<EOF;
int
main(int argc, char *argv[])
-{
+{needs_to_link_against_libcitrun = 0;
if ((++_citrun_lines[6], argc == 1))
return (++_citrun_lines[7], 1);
else
diff --git a/t/inst_preamble.t b/t/inst_preamble.t
@@ -34,6 +34,7 @@ struct citrun_node {
const char *file_name;
};
+extern int needs_to_link_against_libcitrun;
static uint64_t _citrun_lines[6];
struct citrun_node citrun_node_source_0 = {
.lines_ptr = _citrun_lines,
diff --git a/t/return.t b/t/return.t
@@ -27,11 +27,11 @@ EOF
$project->compile();
my $inst_src_good = <<EOF;
-int foo() {
+int foo() {needs_to_link_against_libcitrun = 0;
return (++_citrun_lines[2], 0);
}
-int main(void) {
+int main(void) {needs_to_link_against_libcitrun = 0;
return (++_citrun_lines[6], 10);
return (++_citrun_lines[8], 10 + 10);
diff --git a/t/switch.t b/t/switch.t
@@ -32,7 +32,7 @@ $project->compile();
my $inst_src_good = <<EOF;
int
main(void)
-{
+{needs_to_link_against_libcitrun = 0;
int i;
switch ((++_citrun_lines[6], i)) {
diff --git a/t/while.t b/t/while.t
@@ -30,7 +30,7 @@ $project->compile();
my $inst_src_good = <<EOF;
int
main(void)
-{
+{needs_to_link_against_libcitrun = 0;
int i;
i = 0;