Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototypes that preempt built-in functions are wrongly discarded #15

Open
stephenrkell opened this issue Sep 2, 2014 · 0 comments
Open

Comments

@stephenrkell
Copy link
Contributor

Using cilly to compile eglibc 2.19 fails at configure time, complaining:

configure:6792: error: support for the symbol redirection needed

The failing test program (conftest.c) looks like this:

extern char *strstr (const char *, const char *) __asm ("my_strstr");
char *foo (const char *a, const char *b)
{
  return __builtin_strstr (a, b);
}

The configure script expects to see a reference to my_strstr in the output assembly. This holds for gcc, but not for cilly wrapping gcc.

After fixing a trivial earlier bug (that __builtin_strstr was not included in the builtins list; patch sent!), we get

/* Generated by CIL v. 1.7.3 */
/* print_CIL_Input is true */

/* compiler builtin: 
   char *__builtin_strstr(char const   * , char const   * ) ;  */
#line 2 "conftest.c"
char *foo(char const   *a , char const   *b ) 
{ 
  char *tmp ;

  {
#line 4
  tmp = __builtin_strstr(a, b);
#line 4
  return (tmp);
}
}

where we note that our prototype for strstr has gone away! That's because it appears to be unused. My proposed fix is a gross hack to rmtmps, something like as follows, but I'd be amenable to cleaner suggestions.

diff --git a/src/rmtmps.ml b/src/rmtmps.ml
index 2034623..09b5bde 100644
--- a/src/rmtmps.ml
+++ b/src/rmtmps.ml
@@ -422,6 +422,21 @@ class markReachableVisitor
     | GVarDecl (varinfo, _)
     | GFun ({svar = varinfo}, _) ->
        varinfo.vreferenced <- true;
+       (* If we're a builtin, but we've seen a prototype for the
+        * corresponding non-builtin function, then mark that one
+        * used too. *)
+       let isBuiltin = H.mem builtinFunctions varinfo.vname in
+       if isBuiltin then begin
+         let nonBuiltinName = Str.replace_first (Str.regexp "^__builtin_") "" varinfo.
+         try 
+           let gv = H.find globalMap nonBuiltinName in
+            match gv with 
+             GFun({svar = nbvarinfo}, _) -> nbvarinfo.vreferenced <- true; ()
+           | GVarDecl(nbvarinfo, _) -> nbvarinfo.vreferenced <- true; ()
+           | _ -> ()
+         with Not_found -> ()
+       end
+       ;
        DoChildren
     | _ ->
        SkipChildren
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant