1 /* The library used by gdb.
2    Copyright (C) 2014-2018 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 #include <cc1plugin-config.h>
21 #include <vector>
22 #include <string>
23 #include <sys/socket.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 #include <sys/wait.h>
27 #include <stdio.h>
28 #include <errno.h>
29 #include <sys/stat.h>
30 #include <stdlib.h>
31 #include <sstream>
32 #include "marshall-c.hh"
33 #include "rpc.hh"
34 #include "connection.hh"
35 #include "names.hh"
36 #include "callbacks.hh"
37 #include "libiberty.h"
38 #include "xregex.h"
39 #include "findcomp.hh"
40 #include "compiler-name.hh"
41 #include "intl.h"
42 
43 struct libcc1;
44 
45 class libcc1_connection;
46 
47 // The C compiler context that we hand back to our caller.
48 struct libcc1 : public gcc_c_context
49 {
50   libcc1 (const gcc_base_vtable *, const gcc_c_fe_vtable *);
51   ~libcc1 ();
52 
53   // A convenience function to print something.
printlibcc154   void print (const char *str)
55   {
56     this->print_function (this->print_datum, str);
57   }
58 
59   libcc1_connection *connection;
60 
61   gcc_c_oracle_function *binding_oracle;
62   gcc_c_symbol_address_function *address_oracle;
63   void *oracle_datum;
64 
65   void (*print_function) (void *datum, const char *message);
66   void *print_datum;
67 
68   std::vector<std::string> args;
69   std::string source_file;
70 
71   /* Non-zero as an equivalent to gcc driver option "-v".  */
72   bool verbose;
73 
74   /* Compiler to set by set_triplet_regexp or set_driver_filename.  */
75   class compiler
76   {
77   protected:
78     libcc1 *self_;
79   public:
compiler(libcc1 * self)80     compiler (libcc1 *self) : self_ (self)
81     {
82     }
83     virtual char *find (std::string &compiler) const;
~compiler()84     virtual ~compiler ()
85     {
86     }
87   } *compilerp;
88 
89   /* Compiler to set by set_triplet_regexp.  */
90   class compiler_triplet_regexp : public compiler
91   {
92   private:
93     std::string triplet_regexp_;
94   public:
95     virtual char *find (std::string &compiler) const;
compiler_triplet_regexp(libcc1 * self,std::string triplet_regexp)96     compiler_triplet_regexp (libcc1 *self, std::string triplet_regexp)
97       : compiler (self), triplet_regexp_ (triplet_regexp)
98     {
99     }
~compiler_triplet_regexp()100     virtual ~compiler_triplet_regexp ()
101     {
102     }
103   };
104 
105   /* Compiler to set by set_driver_filename.  */
106   class compiler_driver_filename : public compiler
107   {
108   private:
109     std::string driver_filename_;
110   public:
111     virtual char *find (std::string &compiler) const;
compiler_driver_filename(libcc1 * self,std::string driver_filename)112     compiler_driver_filename (libcc1 *self, std::string driver_filename)
113       : compiler (self), driver_filename_ (driver_filename)
114     {
115     }
~compiler_driver_filename()116     virtual ~compiler_driver_filename ()
117     {
118     }
119   };
120 };
121 
122 // A local subclass of connection that holds a back-pointer to the
123 // gcc_c_context object that we provide to our caller.
124 class libcc1_connection : public cc1_plugin::connection
125 {
126 public:
127 
libcc1_connection(int fd,int aux_fd,libcc1 * b)128   libcc1_connection (int fd, int aux_fd, libcc1 *b)
129     : connection (fd, aux_fd),
130       back_ptr (b)
131   {
132   }
133 
print(const char * buf)134   virtual void print (const char *buf)
135   {
136     back_ptr->print (buf);
137   }
138 
139   libcc1 *back_ptr;
140 };
141 
libcc1(const gcc_base_vtable * v,const gcc_c_fe_vtable * cv)142 libcc1::libcc1 (const gcc_base_vtable *v,
143 		const gcc_c_fe_vtable *cv)
144   : connection (NULL),
145     binding_oracle (NULL),
146     address_oracle (NULL),
147     oracle_datum (NULL),
148     print_function (NULL),
149     print_datum (NULL),
150     args (),
151     source_file (),
152     verbose (false),
153     compilerp (new libcc1::compiler (this))
154 {
155   base.ops = v;
156   c_ops = cv;
157 }
158 
~libcc1()159 libcc1::~libcc1 ()
160 {
161   delete connection;
162   delete compilerp;
163 }
164 
165 
166 
167 // Enclose these functions in an anonymous namespace because they
168 // shouldn't be exported, but they can't be static because they're
169 // used as template arguments.
170 namespace {
171   // This is a wrapper function that is called by the RPC system and
172   // that then forwards the call to the library user.  Note that the
173   // return value is not used; the type cannot be 'void' due to
174   // limitations in our simple RPC.
175   int
c_call_binding_oracle(cc1_plugin::connection * conn,enum gcc_c_oracle_request request,const char * identifier)176   c_call_binding_oracle (cc1_plugin::connection *conn,
177 			 enum gcc_c_oracle_request request,
178 			 const char *identifier)
179   {
180     libcc1 *self = ((libcc1_connection *) conn)->back_ptr;
181 
182     self->binding_oracle (self->oracle_datum, self, request, identifier);
183     return 1;
184   }
185 
186   // This is a wrapper function that is called by the RPC system and
187   // that then forwards the call to the library user.
188   gcc_address
c_call_symbol_address(cc1_plugin::connection * conn,const char * identifier)189   c_call_symbol_address (cc1_plugin::connection *conn, const char *identifier)
190   {
191     libcc1 *self = ((libcc1_connection *) conn)->back_ptr;
192 
193     return self->address_oracle (self->oracle_datum, self, identifier);
194   }
195 } /* anonymous namespace */
196 
197 
198 
199 static void
set_callbacks(struct gcc_c_context * s,gcc_c_oracle_function * binding_oracle,gcc_c_symbol_address_function * address_oracle,void * datum)200 set_callbacks (struct gcc_c_context *s,
201 	       gcc_c_oracle_function *binding_oracle,
202 	       gcc_c_symbol_address_function *address_oracle,
203 	       void *datum)
204 {
205   libcc1 *self = (libcc1 *) s;
206 
207   self->binding_oracle = binding_oracle;
208   self->address_oracle = address_oracle;
209   self->oracle_datum = datum;
210 }
211 
212 // Instances of these rpc<> template functions are installed into the
213 // "c_vtable".  These functions are parameterized by type and method
214 // name and forward the call via the connection.
215 
216 template<typename R, const char *&NAME>
217 R rpc (struct gcc_c_context *s)
218 {
219   libcc1 *self = (libcc1 *) s;
220   R result;
221 
222   if (!cc1_plugin::call (self->connection, NAME, &result))
223     return 0;
224   return result;
225 }
226 
227 template<typename R, const char *&NAME, typename A>
228 R rpc (struct gcc_c_context *s, A arg)
229 {
230   libcc1 *self = (libcc1 *) s;
231   R result;
232 
233   if (!cc1_plugin::call (self->connection, NAME, &result, arg))
234     return 0;
235   return result;
236 }
237 
238 template<typename R, const char *&NAME, typename A1, typename A2>
239 R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2)
240 {
241   libcc1 *self = (libcc1 *) s;
242   R result;
243 
244   if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2))
245     return 0;
246   return result;
247 }
248 
249 template<typename R, const char *&NAME, typename A1, typename A2, typename A3>
250 R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3)
251 {
252   libcc1 *self = (libcc1 *) s;
253   R result;
254 
255   if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3))
256     return 0;
257   return result;
258 }
259 
260 template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
261 	 typename A4>
262 R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4)
263 {
264   libcc1 *self = (libcc1 *) s;
265   R result;
266 
267   if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
268 			 arg4))
269     return 0;
270   return result;
271 }
272 
273 template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
274 	 typename A4, typename A5>
275 R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
276 {
277   libcc1 *self = (libcc1 *) s;
278   R result;
279 
280   if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
281 			 arg4, arg5))
282     return 0;
283   return result;
284 }
285 
286 template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
287 	 typename A4, typename A5, typename A6, typename A7>
288 R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5,
289        A6 arg6, A7 arg7)
290 {
291   libcc1 *self = (libcc1 *) s;
292   R result;
293 
294   if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
295 			 arg4, arg5, arg6, arg7))
296     return 0;
297   return result;
298 }
299 
300 static const struct gcc_c_fe_vtable c_vtable =
301 {
302   GCC_C_FE_VERSION_0,
303   set_callbacks,
304 
305 #define GCC_METHOD0(R, N) \
306   rpc<R, cc1_plugin::c::N>,
307 #define GCC_METHOD1(R, N, A) \
308   rpc<R, cc1_plugin::c::N, A>,
309 #define GCC_METHOD2(R, N, A, B) \
310   rpc<R, cc1_plugin::c::N, A, B>,
311 #define GCC_METHOD3(R, N, A, B, C) \
312   rpc<R, cc1_plugin::c::N, A, B, C>,
313 #define GCC_METHOD4(R, N, A, B, C, D) \
314   rpc<R, cc1_plugin::c::N, A, B, C, D>,
315 #define GCC_METHOD5(R, N, A, B, C, D, E) \
316   rpc<R, cc1_plugin::c::N, A, B, C, D, E>,
317 #define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
318   rpc<R, cc1_plugin::c::N, A, B, C, D, E, F, G>,
319 
320 #include "gcc-c-fe.def"
321 
322 #undef GCC_METHOD0
323 #undef GCC_METHOD1
324 #undef GCC_METHOD2
325 #undef GCC_METHOD3
326 #undef GCC_METHOD4
327 #undef GCC_METHOD5
328 #undef GCC_METHOD7
329 };
330 
331 
332 
333 // Construct an appropriate regexp to match the compiler name.
334 static std::string
make_regexp(const char * triplet_regexp,const char * compiler)335 make_regexp (const char *triplet_regexp, const char *compiler)
336 {
337   std::stringstream buf;
338 
339   buf << "^" << triplet_regexp << "-";
340 
341   // Quote the compiler name in case it has something funny in it.
342   for (const char *p = compiler; *p; ++p)
343     {
344       switch (*p)
345 	{
346 	case '.':
347 	case '^':
348 	case '$':
349 	case '*':
350 	case '+':
351 	case '?':
352 	case '(':
353 	case ')':
354 	case '[':
355 	case '{':
356 	case '\\':
357 	case '|':
358 	  buf << '\\';
359 	  break;
360 	}
361       buf << *p;
362     }
363   buf << "$";
364 
365   return buf.str ();
366 }
367 
368 static void
libcc1_set_verbose(struct gcc_base_context * s,int verbose)369 libcc1_set_verbose (struct gcc_base_context *s, int /* bool */ verbose)
370 {
371   libcc1 *self = (libcc1 *) s;
372 
373   self->verbose = verbose != 0;
374 }
375 
376 char *
find(std::string & compiler ATTRIBUTE_UNUSED) const377 libcc1::compiler::find (std::string &compiler ATTRIBUTE_UNUSED) const
378 {
379   return xstrdup (_("Compiler has not been specified"));
380 }
381 
382 char *
find(std::string & compiler) const383 libcc1::compiler_triplet_regexp::find (std::string &compiler) const
384 {
385   std::string rx = make_regexp (triplet_regexp_.c_str (), C_COMPILER_NAME);
386   if (self_->verbose)
387     fprintf (stderr, _("searching for compiler matching regex %s\n"),
388 	     rx.c_str());
389   regex_t triplet;
390   int code = regcomp (&triplet, rx.c_str (), REG_EXTENDED | REG_NOSUB);
391   if (code != 0)
392     {
393       size_t len = regerror (code, &triplet, NULL, 0);
394       char err[len];
395 
396       regerror (code, &triplet, err, len);
397 
398       return concat ("Could not compile regexp \"",
399 		     rx.c_str (),
400 		     "\": ",
401 		     err,
402 		     (char *) NULL);
403     }
404 
405   if (!find_compiler (triplet, &compiler))
406     {
407       regfree (&triplet);
408       return concat ("Could not find a compiler matching \"",
409 		     rx.c_str (),
410 		     "\"",
411 		     (char *) NULL);
412     }
413   regfree (&triplet);
414   if (self_->verbose)
415     fprintf (stderr, _("found compiler %s\n"), compiler.c_str());
416   return NULL;
417 }
418 
419 char *
find(std::string & compiler) const420 libcc1::compiler_driver_filename::find (std::string &compiler) const
421 {
422   // Simulate fnotice by fprintf.
423   if (self_->verbose)
424     fprintf (stderr, _("using explicit compiler filename %s\n"),
425 	     driver_filename_.c_str());
426   compiler = driver_filename_;
427   return NULL;
428 }
429 
430 static char *
libcc1_set_arguments(struct gcc_base_context * s,int argc,char ** argv)431 libcc1_set_arguments (struct gcc_base_context *s,
432 		      int argc, char **argv)
433 {
434   libcc1 *self = (libcc1 *) s;
435 
436   std::string compiler;
437   char *errmsg = self->compilerp->find (compiler);
438   if (errmsg != NULL)
439     return errmsg;
440 
441   self->args.push_back (compiler);
442 
443   for (int i = 0; i < argc; ++i)
444     self->args.push_back (argv[i]);
445 
446   return NULL;
447 }
448 
449 static char *
libcc1_set_triplet_regexp(struct gcc_base_context * s,const char * triplet_regexp)450 libcc1_set_triplet_regexp (struct gcc_base_context *s,
451 			   const char *triplet_regexp)
452 {
453   libcc1 *self = (libcc1 *) s;
454 
455   delete self->compilerp;
456   self->compilerp = new libcc1::compiler_triplet_regexp (self, triplet_regexp);
457   return NULL;
458 }
459 
460 static char *
libcc1_set_driver_filename(struct gcc_base_context * s,const char * driver_filename)461 libcc1_set_driver_filename (struct gcc_base_context *s,
462 			    const char *driver_filename)
463 {
464   libcc1 *self = (libcc1 *) s;
465 
466   delete self->compilerp;
467   self->compilerp = new libcc1::compiler_driver_filename (self,
468 							  driver_filename);
469   return NULL;
470 }
471 
472 static char *
libcc1_set_arguments_v0(struct gcc_base_context * s,const char * triplet_regexp,int argc,char ** argv)473 libcc1_set_arguments_v0 (struct gcc_base_context *s,
474 			 const char *triplet_regexp,
475 			 int argc, char **argv)
476 {
477   char *errmsg = libcc1_set_triplet_regexp (s, triplet_regexp);
478   if (errmsg != NULL)
479     return errmsg;
480 
481   return libcc1_set_arguments (s, argc, argv);
482 }
483 
484 static void
libcc1_set_source_file(struct gcc_base_context * s,const char * file)485 libcc1_set_source_file (struct gcc_base_context *s,
486 			const char *file)
487 {
488   libcc1 *self = (libcc1 *) s;
489 
490   self->source_file = file;
491 }
492 
493 static void
libcc1_set_print_callback(struct gcc_base_context * s,void (* print_function)(void * datum,const char * message),void * datum)494 libcc1_set_print_callback (struct gcc_base_context *s,
495 			   void (*print_function) (void *datum,
496 						   const char *message),
497 			   void *datum)
498 {
499   libcc1 *self = (libcc1 *) s;
500 
501   self->print_function = print_function;
502   self->print_datum = datum;
503 }
504 
505 static int
fork_exec(libcc1 * self,char ** argv,int spair_fds[2],int stderr_fds[2])506 fork_exec (libcc1 *self, char **argv, int spair_fds[2], int stderr_fds[2])
507 {
508   pid_t child_pid = fork ();
509 
510   if (child_pid == -1)
511     {
512       close (spair_fds[0]);
513       close (spair_fds[1]);
514       close (stderr_fds[0]);
515       close (stderr_fds[1]);
516       return 0;
517     }
518 
519   if (child_pid == 0)
520     {
521       // Child.
522       dup2 (stderr_fds[1], 1);
523       dup2 (stderr_fds[1], 2);
524       close (stderr_fds[0]);
525       close (stderr_fds[1]);
526       close (spair_fds[0]);
527 
528       execvp (argv[0], argv);
529       _exit (127);
530     }
531   else
532     {
533       // Parent.
534       close (spair_fds[1]);
535       close (stderr_fds[1]);
536 
537       cc1_plugin::status result = cc1_plugin::FAIL;
538       if (self->connection->send ('H')
539 	  && ::cc1_plugin::marshall (self->connection, GCC_C_FE_VERSION_1))
540 	result = self->connection->wait_for_query ();
541 
542       close (spair_fds[0]);
543       close (stderr_fds[0]);
544 
545       while (true)
546 	{
547 	  int status;
548 
549 	  if (waitpid (child_pid, &status, 0) == -1)
550 	    {
551 	      if (errno != EINTR)
552 		return 0;
553 	    }
554 
555 	  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0)
556 	    return 0;
557 	  break;
558 	}
559 
560       if (!result)
561 	return 0;
562       return 1;
563     }
564 }
565 
566 static int
libcc1_compile(struct gcc_base_context * s,const char * filename)567 libcc1_compile (struct gcc_base_context *s,
568 		const char *filename)
569 {
570   libcc1 *self = (libcc1 *) s;
571 
572   int fds[2];
573   if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) != 0)
574     {
575       self->print ("could not create socketpair\n");
576       return 0;
577     }
578 
579   int stderr_fds[2];
580   if (pipe (stderr_fds) != 0)
581     {
582       self->print ("could not create pipe\n");
583       close (fds[0]);
584       close (fds[1]);
585       return 0;
586     }
587 
588   self->args.push_back ("-fplugin=libcc1plugin");
589   char buf[100];
590   if (snprintf (buf, sizeof (buf), "-fplugin-arg-libcc1plugin-fd=%d", fds[1])
591       >= (long) sizeof (buf))
592     abort ();
593   self->args.push_back (buf);
594 
595   self->args.push_back (self->source_file);
596   self->args.push_back ("-c");
597   self->args.push_back ("-o");
598   self->args.push_back (filename);
599   if (self->verbose)
600     self->args.push_back ("-v");
601 
602   self->connection = new libcc1_connection (fds[0], stderr_fds[0], self);
603 
604   cc1_plugin::callback_ftype *fun
605     = cc1_plugin::callback<int,
606 			   enum gcc_c_oracle_request,
607 			   const char *,
608 			   c_call_binding_oracle>;
609   self->connection->add_callback ("binding_oracle", fun);
610 
611   fun = cc1_plugin::callback<gcc_address,
612 			     const char *,
613 			     c_call_symbol_address>;
614   self->connection->add_callback ("address_oracle", fun);
615 
616   char **argv = new (std::nothrow) char *[self->args.size () + 1];
617   if (argv == NULL)
618     return 0;
619 
620   for (unsigned int i = 0; i < self->args.size (); ++i)
621     argv[i] = const_cast<char *> (self->args[i].c_str ());
622   argv[self->args.size ()] = NULL;
623 
624   return fork_exec (self, argv, fds, stderr_fds);
625 }
626 
627 static int
libcc1_compile_v0(struct gcc_base_context * s,const char * filename,int verbose)628 libcc1_compile_v0 (struct gcc_base_context *s, const char *filename,
629 		   int verbose)
630 {
631   libcc1_set_verbose (s, verbose);
632   return libcc1_compile (s, filename);
633 }
634 
635 static void
libcc1_destroy(struct gcc_base_context * s)636 libcc1_destroy (struct gcc_base_context *s)
637 {
638   libcc1 *self = (libcc1 *) s;
639 
640   delete self;
641 }
642 
643 static const struct gcc_base_vtable vtable =
644 {
645   GCC_FE_VERSION_1,
646   libcc1_set_arguments_v0,
647   libcc1_set_source_file,
648   libcc1_set_print_callback,
649   libcc1_compile_v0,
650   libcc1_destroy,
651   libcc1_set_verbose,
652   libcc1_compile,
653   libcc1_set_arguments,
654   libcc1_set_triplet_regexp,
655   libcc1_set_driver_filename,
656 };
657 
658 extern "C" gcc_c_fe_context_function gcc_c_fe_context;
659 
660 #ifdef __GNUC__
661 #pragma GCC visibility push(default)
662 #endif
663 
664 extern "C"
665 struct gcc_c_context *
gcc_c_fe_context(enum gcc_base_api_version base_version,enum gcc_c_api_version c_version)666 gcc_c_fe_context (enum gcc_base_api_version base_version,
667 		  enum gcc_c_api_version c_version)
668 {
669   if ((base_version != GCC_FE_VERSION_0 && base_version != GCC_FE_VERSION_1)
670       || (c_version != GCC_C_FE_VERSION_0 && c_version != GCC_C_FE_VERSION_1))
671     return NULL;
672 
673   return new libcc1 (&vtable, &c_vtable);
674 }
675