Support R_SPARC_WDISP10 and R_SPARC_H34.
[external/binutils.git] / gdb / common / agent.c
index 7553835..ecb52dc 100644 (file)
@@ -41,6 +41,9 @@ int debug_agent = 0;
     fprintf_unfiltered (gdb_stdlog, fmt, ##args);
 #endif
 
+/* Global flag to determine using agent or not.  */
+int use_agent = 0;
+
 /* Addresses of in-process agent's symbols both GDB and GDBserver cares
    about.  */
 
@@ -48,6 +51,7 @@ struct ipa_sym_addresses
 {
   CORE_ADDR addr_helper_thread_id;
   CORE_ADDR addr_cmd_buf;
+  CORE_ADDR addr_capability;
 };
 
 /* Cache of the helper thread id.  FIXME: this global should be made
@@ -62,18 +66,29 @@ static struct
 } symbol_list[] = {
   IPA_SYM(helper_thread_id),
   IPA_SYM(cmd_buf),
+  IPA_SYM(capability),
 };
 
 static struct ipa_sym_addresses ipa_sym_addrs;
 
+static int all_agent_symbols_looked_up = 0;
+
+int
+agent_loaded_p (void)
+{
+  return all_agent_symbols_looked_up;
+}
+
 /* Look up all symbols needed by agent.  Return 0 if all the symbols are
    found, return non-zero otherwise.  */
 
 int
-agent_look_up_symbols (void)
+agent_look_up_symbols (void *arg)
 {
   int i;
 
+  all_agent_symbols_looked_up = 0;
+
   for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++)
     {
       CORE_ADDR *addrp =
@@ -82,8 +97,9 @@ agent_look_up_symbols (void)
 
       if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0)
 #else
-      struct minimal_symbol *sym = lookup_minimal_symbol (symbol_list[i].name,
-                                                         NULL, NULL);
+      struct minimal_symbol *sym =
+       lookup_minimal_symbol (symbol_list[i].name, NULL,
+                              (struct objfile *) arg);
 
       if (sym != NULL)
        *addrp = SYMBOL_VALUE_ADDRESS (sym);
@@ -95,6 +111,7 @@ agent_look_up_symbols (void)
        }
     }
 
+  all_agent_symbols_looked_up = 1;
   return 0;
 }
 
@@ -118,7 +135,7 @@ agent_get_helper_thread_id (void)
       else
 #endif
        {
-         warning ("Error reading helper thread's id in lib");
+         warning (_("Error reading helper thread's id in lib"));
        }
     }
 
@@ -154,7 +171,7 @@ gdb_connect_sync_socket (int pid)
   res = fd = socket (PF_UNIX, SOCK_STREAM, 0);
   if (res == -1)
     {
-      warning ("error opening sync socket: %s\n", strerror (errno));
+      warning (_("error opening sync socket: %s"), strerror (errno));
       return -1;
     }
 
@@ -163,7 +180,7 @@ gdb_connect_sync_socket (int pid)
   res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path);
   if (res >= UNIX_PATH_MAX)
     {
-      warning ("string overflow allocating socket name\n");
+      warning (_("string overflow allocating socket name"));
       close (fd);
       return -1;
     }
@@ -171,9 +188,9 @@ gdb_connect_sync_socket (int pid)
   res = connect (fd, (struct sockaddr *) &addr, sizeof (addr));
   if (res == -1)
     {
-      warning ("error connecting sync socket (%s): %s. "
-              "Make sure the directory exists and that it is writable.",
-              path, strerror (errno));
+      warning (_("error connecting sync socket (%s): %s. "
+                "Make sure the directory exists and that it is writable."),
+                path, strerror (errno));
       close (fd);
       return -1;
     }
@@ -207,7 +224,7 @@ agent_run_command (int pid, const char *cmd)
 
   if (ret != 0)
     {
-      warning ("unable to write");
+      warning (_("unable to write"));
       return -1;
     }
 
@@ -293,10 +310,48 @@ agent_run_command (int pid, const char *cmd)
                              IPA_CMD_BUF_SIZE))
 #endif
        {
-         warning ("Error reading command response");
+         warning (_("Error reading command response"));
          return -1;
        }
     }
 
   return 0;
 }
+
+/* Each bit of it stands for a capability of agent.  */
+static unsigned int agent_capability = 0;
+
+/* Return true if agent has capability AGENT_CAP, otherwise return false.  */
+
+int
+agent_capability_check (enum agent_capa agent_capa)
+{
+  if (agent_capability == 0)
+    {
+#ifdef GDBSERVER
+      if (read_inferior_memory (ipa_sym_addrs.addr_capability,
+                               (unsigned char *) &agent_capability,
+                               sizeof agent_capability))
+#else
+      enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+      gdb_byte buf[4];
+
+      if (target_read_memory (ipa_sym_addrs.addr_capability,
+                             buf, sizeof buf) == 0)
+       agent_capability = extract_unsigned_integer (buf, sizeof buf,
+                                                    byte_order);
+      else
+#endif
+       warning (_("Error reading capability of agent"));
+    }
+  return agent_capability & agent_capa;
+}
+
+/* Invalidate the cache of agent capability, so we'll read it from inferior
+   again.  Call it when launches a new program or reconnect to remote stub.  */
+
+void
+agent_capability_invalidate (void)
+{
+  agent_capability = 0;
+}