GDB (API)
/home/stan/gdb/src/gdb/common/agent.c
Go to the documentation of this file.
00001 /* Shared utility routines for GDB to interact with agent.
00002 
00003    Copyright (C) 2009-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #ifdef GDBSERVER
00021 #include "server.h"
00022 #else
00023 #include "defs.h"
00024 #include "target.h"
00025 #include "inferior.h" /* for non_stop */
00026 #endif
00027 
00028 #include <string.h>
00029 #include <unistd.h>
00030 #include "agent.h"
00031 #include "filestuff.h"
00032 
00033 int debug_agent = 0;
00034 
00035 #ifdef GDBSERVER
00036 #define DEBUG_AGENT(fmt, args...)       \
00037   if (debug_agent)                      \
00038     fprintf (stderr, fmt, ##args);
00039 #else
00040 #define DEBUG_AGENT(fmt, args...)       \
00041   if (debug_agent)                      \
00042     fprintf_unfiltered (gdb_stdlog, fmt, ##args);
00043 #endif
00044 
00045 /* Global flag to determine using agent or not.  */
00046 int use_agent = 0;
00047 
00048 /* Addresses of in-process agent's symbols both GDB and GDBserver cares
00049    about.  */
00050 
00051 struct ipa_sym_addresses
00052 {
00053   CORE_ADDR addr_helper_thread_id;
00054   CORE_ADDR addr_cmd_buf;
00055   CORE_ADDR addr_capability;
00056 };
00057 
00058 /* Cache of the helper thread id.  FIXME: this global should be made
00059    per-process.  */
00060 static unsigned int helper_thread_id = 0;
00061 
00062 static struct
00063 {
00064   const char *name;
00065   int offset;
00066   int required;
00067 } symbol_list[] = {
00068   IPA_SYM(helper_thread_id),
00069   IPA_SYM(cmd_buf),
00070   IPA_SYM(capability),
00071 };
00072 
00073 static struct ipa_sym_addresses ipa_sym_addrs;
00074 
00075 static int all_agent_symbols_looked_up = 0;
00076 
00077 int
00078 agent_loaded_p (void)
00079 {
00080   return all_agent_symbols_looked_up;
00081 }
00082 
00083 /* Look up all symbols needed by agent.  Return 0 if all the symbols are
00084    found, return non-zero otherwise.  */
00085 
00086 int
00087 agent_look_up_symbols (void *arg)
00088 {
00089   int i;
00090 
00091   all_agent_symbols_looked_up = 0;
00092 
00093   for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
00094     {
00095       CORE_ADDR *addrp =
00096         (CORE_ADDR *) ((char *) &ipa_sym_addrs + symbol_list[i].offset);
00097 #ifdef GDBSERVER
00098 
00099       if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
00100 #else
00101       struct minimal_symbol *sym =
00102         lookup_minimal_symbol (symbol_list[i].name, NULL,
00103                                (struct objfile *) arg);
00104 
00105       if (sym != NULL)
00106         *addrp = SYMBOL_VALUE_ADDRESS (sym);
00107       else
00108 #endif
00109         {
00110           DEBUG_AGENT ("symbol `%s' not found\n", symbol_list[i].name);
00111           return -1;
00112         }
00113     }
00114 
00115   all_agent_symbols_looked_up = 1;
00116   return 0;
00117 }
00118 
00119 static unsigned int
00120 agent_get_helper_thread_id (void)
00121 {
00122   if  (helper_thread_id == 0)
00123     {
00124 #ifdef GDBSERVER
00125       if (read_inferior_memory (ipa_sym_addrs.addr_helper_thread_id,
00126                                 (unsigned char *) &helper_thread_id,
00127                                 sizeof helper_thread_id))
00128 #else
00129       enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
00130       gdb_byte buf[4];
00131 
00132       if (target_read_memory (ipa_sym_addrs.addr_helper_thread_id,
00133                               buf, sizeof buf) == 0)
00134         helper_thread_id = extract_unsigned_integer (buf, sizeof buf,
00135                                                      byte_order);
00136       else
00137 #endif
00138         {
00139           warning (_("Error reading helper thread's id in lib"));
00140         }
00141     }
00142 
00143   return helper_thread_id;
00144 }
00145 
00146 #ifdef HAVE_SYS_UN_H
00147 #include <sys/socket.h>
00148 #include <sys/un.h>
00149 #define SOCK_DIR P_tmpdir
00150 
00151 #ifndef UNIX_PATH_MAX
00152 #define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path)
00153 #endif
00154 
00155 #endif
00156 
00157 /* Connects to synchronization socket.  PID is the pid of inferior, which is
00158    used to set up the connection socket.  */
00159 
00160 static int
00161 gdb_connect_sync_socket (int pid)
00162 {
00163 #ifdef HAVE_SYS_UN_H
00164   struct sockaddr_un addr;
00165   int res, fd;
00166   char path[UNIX_PATH_MAX];
00167 
00168   res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", P_tmpdir, pid);
00169   if (res >= UNIX_PATH_MAX)
00170     return -1;
00171 
00172   res = fd = gdb_socket_cloexec (PF_UNIX, SOCK_STREAM, 0);
00173   if (res == -1)
00174     {
00175       warning (_("error opening sync socket: %s"), strerror (errno));
00176       return -1;
00177     }
00178 
00179   addr.sun_family = AF_UNIX;
00180 
00181   res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
00182   if (res >= UNIX_PATH_MAX)
00183     {
00184       warning (_("string overflow allocating socket name"));
00185       close (fd);
00186       return -1;
00187     }
00188 
00189   res = connect (fd, (struct sockaddr *) &addr, sizeof (addr));
00190   if (res == -1)
00191     {
00192       warning (_("error connecting sync socket (%s): %s. "
00193                  "Make sure the directory exists and that it is writable."),
00194                  path, strerror (errno));
00195       close (fd);
00196       return -1;
00197     }
00198 
00199   return fd;
00200 #else
00201   return -1;
00202 #endif
00203 }
00204 
00205 /* Execute an agent command in the inferior.  PID is the value of pid of the
00206    inferior.  CMD is the buffer for command.  GDB or GDBserver will store the
00207    command into it and fetch the return result from CMD.  The interaction
00208    between GDB/GDBserver and the agent is synchronized by a synchronization
00209    socket.  Return zero if success, otherwise return non-zero.  */
00210 
00211 int
00212 agent_run_command (int pid, const char *cmd, int len)
00213 {
00214   int fd;
00215   int tid = agent_get_helper_thread_id ();
00216   ptid_t ptid = ptid_build (pid, tid, 0);
00217 
00218 #ifdef GDBSERVER
00219   int ret = write_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
00220                                    (const unsigned char *) cmd, len);
00221 #else
00222   int ret = target_write_memory (ipa_sym_addrs.addr_cmd_buf,
00223                                  (gdb_byte *) cmd, len);
00224 #endif
00225 
00226   if (ret != 0)
00227     {
00228       warning (_("unable to write"));
00229       return -1;
00230     }
00231 
00232   DEBUG_AGENT ("agent: resumed helper thread\n");
00233 
00234   /* Resume helper thread.  */
00235 #ifdef GDBSERVER
00236 {
00237   struct thread_resume resume_info;
00238 
00239   resume_info.thread = ptid;
00240   resume_info.kind = resume_continue;
00241   resume_info.sig = GDB_SIGNAL_0;
00242   (*the_target->resume) (&resume_info, 1);
00243 }
00244 #else
00245  target_resume (ptid, 0, GDB_SIGNAL_0);
00246 #endif
00247 
00248   fd = gdb_connect_sync_socket (pid);
00249   if (fd >= 0)
00250     {
00251       char buf[1] = "";
00252       int ret;
00253 
00254       DEBUG_AGENT ("agent: signalling helper thread\n");
00255 
00256       do
00257         {
00258           ret = write (fd, buf, 1);
00259         } while (ret == -1 && errno == EINTR);
00260 
00261         DEBUG_AGENT ("agent: waiting for helper thread's response\n");
00262 
00263       do
00264         {
00265           ret = read (fd, buf, 1);
00266         } while (ret == -1 && errno == EINTR);
00267 
00268       close (fd);
00269 
00270       DEBUG_AGENT ("agent: helper thread's response received\n");
00271     }
00272   else
00273     return -1;
00274 
00275   /* Need to read response with the inferior stopped.  */
00276   if (!ptid_equal (ptid, null_ptid))
00277     {
00278       struct target_waitstatus status;
00279       int was_non_stop = non_stop;
00280       /* Stop thread PTID.  */
00281       DEBUG_AGENT ("agent: stop helper thread\n");
00282 #ifdef GDBSERVER
00283       {
00284         struct thread_resume resume_info;
00285 
00286         resume_info.thread = ptid;
00287         resume_info.kind = resume_stop;
00288         resume_info.sig = GDB_SIGNAL_0;
00289         (*the_target->resume) (&resume_info, 1);
00290       }
00291 
00292       non_stop = 1;
00293       mywait (ptid, &status, 0, 0);
00294 #else
00295       non_stop = 1;
00296       target_stop (ptid);
00297 
00298       memset (&status, 0, sizeof (status));
00299       target_wait (ptid, &status, 0);
00300 #endif
00301       non_stop = was_non_stop;
00302     }
00303 
00304   if (fd >= 0)
00305     {
00306 #ifdef GDBSERVER
00307       if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf,
00308                                 (unsigned char *) cmd, IPA_CMD_BUF_SIZE))
00309 #else
00310       if (target_read_memory (ipa_sym_addrs.addr_cmd_buf, (gdb_byte *) cmd,
00311                               IPA_CMD_BUF_SIZE))
00312 #endif
00313         {
00314           warning (_("Error reading command response"));
00315           return -1;
00316         }
00317     }
00318 
00319   return 0;
00320 }
00321 
00322 /* Each bit of it stands for a capability of agent.  */
00323 static unsigned int agent_capability = 0;
00324 
00325 /* Return true if agent has capability AGENT_CAP, otherwise return false.  */
00326 
00327 int
00328 agent_capability_check (enum agent_capa agent_capa)
00329 {
00330   if (agent_capability == 0)
00331     {
00332 #ifdef GDBSERVER
00333       if (read_inferior_memory (ipa_sym_addrs.addr_capability,
00334                                 (unsigned char *) &agent_capability,
00335                                 sizeof agent_capability))
00336 #else
00337       enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
00338       gdb_byte buf[4];
00339 
00340       if (target_read_memory (ipa_sym_addrs.addr_capability,
00341                               buf, sizeof buf) == 0)
00342         agent_capability = extract_unsigned_integer (buf, sizeof buf,
00343                                                      byte_order);
00344       else
00345 #endif
00346         warning (_("Error reading capability of agent"));
00347     }
00348   return agent_capability & agent_capa;
00349 }
00350 
00351 /* Invalidate the cache of agent capability, so we'll read it from inferior
00352    again.  Call it when launches a new program or reconnect to remote stub.  */
00353 
00354 void
00355 agent_capability_invalidate (void)
00356 {
00357   agent_capability = 0;
00358 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines