libcc1.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. /* The library used by gdb.
  2. Copyright (C) 2014 Free Software Foundation, Inc.
  3. This file is part of GCC.
  4. GCC is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU General Public License as published by the Free
  6. Software Foundation; either version 3, or (at your option) any later
  7. version.
  8. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  9. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  11. for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GCC; see the file COPYING3. If not see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <cc1plugin-config.h>
  16. #include <vector>
  17. #include <string>
  18. #include <sys/socket.h>
  19. #include <sys/types.h>
  20. #include <unistd.h>
  21. #include <sys/wait.h>
  22. #include <stdio.h>
  23. #include <errno.h>
  24. #include <sys/stat.h>
  25. #include <stdlib.h>
  26. #include <sstream>
  27. #include "rpc.hh"
  28. #include "connection.hh"
  29. #include "names.hh"
  30. #include "callbacks.hh"
  31. #include "gcc-interface.h"
  32. #include "libiberty.h"
  33. #include "xregex.h"
  34. #include "findcomp.hh"
  35. #include "compiler-name.h"
  36. struct libcc1;
  37. class libcc1_connection;
  38. // The C compiler context that we hand back to our caller.
  39. struct libcc1 : public gcc_c_context
  40. {
  41. libcc1 (const gcc_base_vtable *, const gcc_c_fe_vtable *);
  42. ~libcc1 ();
  43. // A convenience function to print something.
  44. void print (const char *str)
  45. {
  46. this->print_function (this->print_datum, str);
  47. }
  48. libcc1_connection *connection;
  49. gcc_c_oracle_function *binding_oracle;
  50. gcc_c_symbol_address_function *address_oracle;
  51. void *oracle_datum;
  52. void (*print_function) (void *datum, const char *message);
  53. void *print_datum;
  54. std::vector<std::string> args;
  55. std::string source_file;
  56. };
  57. // A local subclass of connection that holds a back-pointer to the
  58. // gcc_c_context object that we provide to our caller.
  59. class libcc1_connection : public cc1_plugin::connection
  60. {
  61. public:
  62. libcc1_connection (int fd, int aux_fd, libcc1 *b)
  63. : connection (fd, aux_fd),
  64. back_ptr (b)
  65. {
  66. }
  67. virtual void print (const char *buf)
  68. {
  69. back_ptr->print (buf);
  70. }
  71. libcc1 *back_ptr;
  72. };
  73. libcc1::libcc1 (const gcc_base_vtable *v,
  74. const gcc_c_fe_vtable *cv)
  75. : connection (NULL),
  76. binding_oracle (NULL),
  77. address_oracle (NULL),
  78. oracle_datum (NULL),
  79. print_function (NULL),
  80. print_datum (NULL),
  81. args (),
  82. source_file ()
  83. {
  84. base.ops = v;
  85. c_ops = cv;
  86. }
  87. libcc1::~libcc1 ()
  88. {
  89. delete connection;
  90. }
  91. // This is a wrapper function that is called by the RPC system and
  92. // that then forwards the call to the library user. Note that the
  93. // return value is not used; the type cannot be 'void' due to
  94. // limitations in our simple RPC.
  95. int
  96. call_binding_oracle (cc1_plugin::connection *conn,
  97. enum gcc_c_oracle_request request,
  98. const char *identifier)
  99. {
  100. libcc1 *self = ((libcc1_connection *) conn)->back_ptr;
  101. self->binding_oracle (self->oracle_datum, self, request, identifier);
  102. return 1;
  103. }
  104. // This is a wrapper function that is called by the RPC system and
  105. // that then forwards the call to the library user.
  106. gcc_address
  107. call_symbol_address (cc1_plugin::connection *conn, const char *identifier)
  108. {
  109. libcc1 *self = ((libcc1_connection *) conn)->back_ptr;
  110. return self->address_oracle (self->oracle_datum, self, identifier);
  111. }
  112. static void
  113. set_callbacks (struct gcc_c_context *s,
  114. gcc_c_oracle_function *binding_oracle,
  115. gcc_c_symbol_address_function *address_oracle,
  116. void *datum)
  117. {
  118. libcc1 *self = (libcc1 *) s;
  119. self->binding_oracle = binding_oracle;
  120. self->address_oracle = address_oracle;
  121. self->oracle_datum = datum;
  122. }
  123. // Instances of these rpc<> template functions are installed into the
  124. // "c_vtable". These functions are parameterized by type and method
  125. // name and forward the call via the connection.
  126. template<typename R, const char *&NAME>
  127. R rpc (struct gcc_c_context *s)
  128. {
  129. libcc1 *self = (libcc1 *) s;
  130. R result;
  131. if (!cc1_plugin::call (self->connection, NAME, &result))
  132. return 0;
  133. return result;
  134. }
  135. template<typename R, const char *&NAME, typename A>
  136. R rpc (struct gcc_c_context *s, A arg)
  137. {
  138. libcc1 *self = (libcc1 *) s;
  139. R result;
  140. if (!cc1_plugin::call (self->connection, NAME, &result, arg))
  141. return 0;
  142. return result;
  143. }
  144. template<typename R, const char *&NAME, typename A1, typename A2>
  145. R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2)
  146. {
  147. libcc1 *self = (libcc1 *) s;
  148. R result;
  149. if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2))
  150. return 0;
  151. return result;
  152. }
  153. template<typename R, const char *&NAME, typename A1, typename A2, typename A3>
  154. R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3)
  155. {
  156. libcc1 *self = (libcc1 *) s;
  157. R result;
  158. if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3))
  159. return 0;
  160. return result;
  161. }
  162. template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
  163. typename A4>
  164. R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4)
  165. {
  166. libcc1 *self = (libcc1 *) s;
  167. R result;
  168. if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
  169. arg4))
  170. return 0;
  171. return result;
  172. }
  173. template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
  174. typename A4, typename A5>
  175. R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
  176. {
  177. libcc1 *self = (libcc1 *) s;
  178. R result;
  179. if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
  180. arg4, arg5))
  181. return 0;
  182. return result;
  183. }
  184. template<typename R, const char *&NAME, typename A1, typename A2, typename A3,
  185. typename A4, typename A5, typename A6, typename A7>
  186. R rpc (struct gcc_c_context *s, A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5,
  187. A6 arg6, A7 arg7)
  188. {
  189. libcc1 *self = (libcc1 *) s;
  190. R result;
  191. if (!cc1_plugin::call (self->connection, NAME, &result, arg1, arg2, arg3,
  192. arg4, arg5, arg6, arg7))
  193. return 0;
  194. return result;
  195. }
  196. static const struct gcc_c_fe_vtable c_vtable =
  197. {
  198. GCC_C_FE_VERSION_0,
  199. set_callbacks,
  200. #define GCC_METHOD0(R, N) \
  201. rpc<R, cc1_plugin::N>,
  202. #define GCC_METHOD1(R, N, A) \
  203. rpc<R, cc1_plugin::N, A>,
  204. #define GCC_METHOD2(R, N, A, B) \
  205. rpc<R, cc1_plugin::N, A, B>,
  206. #define GCC_METHOD3(R, N, A, B, C) \
  207. rpc<R, cc1_plugin::N, A, B, C>,
  208. #define GCC_METHOD4(R, N, A, B, C, D) \
  209. rpc<R, cc1_plugin::N, A, B, C, D>,
  210. #define GCC_METHOD5(R, N, A, B, C, D, E) \
  211. rpc<R, cc1_plugin::N, A, B, C, D, E>,
  212. #define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
  213. rpc<R, cc1_plugin::N, A, B, C, D, E, F, G>,
  214. #include "gcc-c-fe.def"
  215. #undef GCC_METHOD0
  216. #undef GCC_METHOD1
  217. #undef GCC_METHOD2
  218. #undef GCC_METHOD3
  219. #undef GCC_METHOD4
  220. #undef GCC_METHOD5
  221. #undef GCC_METHOD7
  222. };
  223. // Construct an appropriate regexp to match the compiler name.
  224. static std::string
  225. make_regexp (const char *triplet_regexp, const char *compiler)
  226. {
  227. std::stringstream buf;
  228. buf << "^" << triplet_regexp << "-";
  229. // Quote the compiler name in case it has something funny in it.
  230. for (const char *p = compiler; *p; ++p)
  231. {
  232. switch (*p)
  233. {
  234. case '.':
  235. case '^':
  236. case '$':
  237. case '*':
  238. case '+':
  239. case '?':
  240. case '(':
  241. case ')':
  242. case '[':
  243. case '{':
  244. case '\\':
  245. case '|':
  246. buf << '\\';
  247. break;
  248. }
  249. buf << *p;
  250. }
  251. buf << "$";
  252. return buf.str ();
  253. }
  254. static char *
  255. libcc1_set_arguments (struct gcc_base_context *s,
  256. const char *triplet_regexp,
  257. int argc, char **argv)
  258. {
  259. libcc1 *self = (libcc1 *) s;
  260. regex_t triplet;
  261. int code;
  262. std::string rx = make_regexp (triplet_regexp, COMPILER_NAME);
  263. code = regcomp (&triplet, rx.c_str (), REG_EXTENDED | REG_NOSUB);
  264. if (code != 0)
  265. {
  266. size_t len = regerror (code, &triplet, NULL, 0);
  267. char err[len];
  268. regerror (code, &triplet, err, len);
  269. return concat ("Could not compile regexp \"",
  270. rx.c_str (),
  271. "\": ",
  272. err,
  273. (char *) NULL);
  274. }
  275. std::string compiler;
  276. if (!find_compiler (triplet, &compiler))
  277. {
  278. regfree (&triplet);
  279. return concat ("Could not find a compiler matching \"",
  280. rx.c_str (),
  281. "\"",
  282. (char *) NULL);
  283. }
  284. regfree (&triplet);
  285. self->args.push_back (compiler);
  286. for (int i = 0; i < argc; ++i)
  287. self->args.push_back (argv[i]);
  288. return NULL;
  289. }
  290. static void
  291. libcc1_set_source_file (struct gcc_base_context *s,
  292. const char *file)
  293. {
  294. libcc1 *self = (libcc1 *) s;
  295. self->source_file = file;
  296. }
  297. static void
  298. libcc1_set_print_callback (struct gcc_base_context *s,
  299. void (*print_function) (void *datum,
  300. const char *message),
  301. void *datum)
  302. {
  303. libcc1 *self = (libcc1 *) s;
  304. self->print_function = print_function;
  305. self->print_datum = datum;
  306. }
  307. static int
  308. fork_exec (libcc1 *self, char **argv, int spair_fds[2], int stderr_fds[2])
  309. {
  310. pid_t child_pid = fork ();
  311. if (child_pid == -1)
  312. {
  313. close (spair_fds[0]);
  314. close (spair_fds[1]);
  315. close (stderr_fds[0]);
  316. close (stderr_fds[1]);
  317. return 0;
  318. }
  319. if (child_pid == 0)
  320. {
  321. // Child.
  322. dup2 (stderr_fds[1], 1);
  323. dup2 (stderr_fds[1], 2);
  324. close (stderr_fds[0]);
  325. close (stderr_fds[1]);
  326. close (spair_fds[0]);
  327. execvp (argv[0], argv);
  328. _exit (127);
  329. }
  330. else
  331. {
  332. // Parent.
  333. close (spair_fds[1]);
  334. close (stderr_fds[1]);
  335. cc1_plugin::status result = cc1_plugin::FAIL;
  336. if (self->connection->send ('H')
  337. && ::cc1_plugin::marshall (self->connection, GCC_C_FE_VERSION_0))
  338. result = self->connection->wait_for_query ();
  339. close (spair_fds[0]);
  340. close (stderr_fds[0]);
  341. while (true)
  342. {
  343. int status;
  344. if (waitpid (child_pid, &status, 0) == -1)
  345. {
  346. if (errno != EINTR)
  347. return 0;
  348. }
  349. if (!WIFEXITED (status) || WEXITSTATUS (status) != 0)
  350. return 0;
  351. break;
  352. }
  353. if (!result)
  354. return 0;
  355. return 1;
  356. }
  357. }
  358. static int
  359. libcc1_compile (struct gcc_base_context *s,
  360. const char *filename,
  361. int verbose)
  362. {
  363. libcc1 *self = (libcc1 *) s;
  364. int fds[2];
  365. if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) != 0)
  366. {
  367. self->print ("could not create socketpair\n");
  368. return 0;
  369. }
  370. int stderr_fds[2];
  371. if (pipe (stderr_fds) != 0)
  372. {
  373. self->print ("could not create pipe\n");
  374. close (fds[0]);
  375. close (fds[1]);
  376. return 0;
  377. }
  378. self->args.push_back ("-fplugin=libcc1plugin");
  379. char buf[100];
  380. if (snprintf (buf, sizeof (buf), "-fplugin-arg-libcc1plugin-fd=%d", fds[1])
  381. >= (long) sizeof (buf))
  382. abort ();
  383. self->args.push_back (buf);
  384. self->args.push_back (self->source_file);
  385. self->args.push_back ("-c");
  386. self->args.push_back ("-o");
  387. self->args.push_back (filename);
  388. if (verbose)
  389. self->args.push_back ("-v");
  390. self->connection = new libcc1_connection (fds[0], stderr_fds[0], self);
  391. cc1_plugin::callback_ftype *fun
  392. = cc1_plugin::callback<int,
  393. enum gcc_c_oracle_request,
  394. const char *,
  395. call_binding_oracle>;
  396. self->connection->add_callback ("binding_oracle", fun);
  397. fun = cc1_plugin::callback<gcc_address,
  398. const char *,
  399. call_symbol_address>;
  400. self->connection->add_callback ("address_oracle", fun);
  401. char **argv = new (std::nothrow) char *[self->args.size () + 1];
  402. if (argv == NULL)
  403. return 0;
  404. for (unsigned int i = 0; i < self->args.size (); ++i)
  405. argv[i] = const_cast<char *> (self->args[i].c_str ());
  406. argv[self->args.size ()] = NULL;
  407. return fork_exec (self, argv, fds, stderr_fds);
  408. }
  409. static void
  410. libcc1_destroy (struct gcc_base_context *s)
  411. {
  412. libcc1 *self = (libcc1 *) s;
  413. delete self;
  414. }
  415. static const struct gcc_base_vtable vtable =
  416. {
  417. GCC_FE_VERSION_0,
  418. libcc1_set_arguments,
  419. libcc1_set_source_file,
  420. libcc1_set_print_callback,
  421. libcc1_compile,
  422. libcc1_destroy
  423. };
  424. extern "C" gcc_c_fe_context_function gcc_c_fe_context;
  425. #ifdef __GNUC__
  426. #pragma GCC visibility push(default)
  427. #endif
  428. extern "C"
  429. struct gcc_c_context *
  430. gcc_c_fe_context (enum gcc_base_api_version base_version,
  431. enum gcc_c_api_version c_version)
  432. {
  433. if (base_version != GCC_FE_VERSION_0 || c_version != GCC_C_FE_VERSION_0)
  434. return NULL;
  435. return new libcc1 (&vtable, &c_vtable);
  436. }