/* Low level interface to ptrace, for the remote server for GDB.
- Copyright (C) 1995-2022 Free Software Foundation, Inc.
+ Copyright (C) 1995-2023 Free Software Foundation, Inc.
This file is part of GDB.
return proc;
}
+void
+linux_process_target::remove_linux_process (process_info *proc)
+{
+ if (proc->priv->mem_fd >= 0)
+ close (proc->priv->mem_fd);
+
+ this->low_delete_process (proc->priv->arch_private);
+
+ xfree (proc->priv);
+ proc->priv = nullptr;
+
+ remove_process (proc);
+}
+
arch_process_info *
linux_process_target::low_new_process ()
{
return 0;
}
- internal_error (__FILE__, __LINE__, _("unknown ptrace event %d"), event);
+ internal_error (_("unknown ptrace event %d"), event);
}
CORE_ADDR
linux_process_target::get_pc (lwp_info *lwp)
{
- struct regcache *regcache;
- CORE_ADDR pc;
+ process_info *proc = get_thread_process (get_lwp_thread (lwp));
+ gdb_assert (!proc->starting_up);
if (!low_supports_breakpoints ())
return 0;
scoped_restore_current_thread restore_thread;
switch_to_thread (get_lwp_thread (lwp));
- regcache = get_thread_regcache (current_thread, 1);
- pc = low_get_pc (regcache);
+ struct regcache *regcache = get_thread_regcache (current_thread, 1);
+ CORE_ADDR pc = low_get_pc (regcache);
threads_debug_printf ("pc is 0x%lx", (long) pc);
if (!low_supports_breakpoints ())
return false;
+ process_info *proc = get_thread_process (get_lwp_thread (lwp));
+ if (proc->starting_up)
+ {
+ /* Claim we have the stop PC so that the caller doesn't try to
+ fetch it itself. */
+ return true;
+ }
+
pc = get_pc (lwp);
sw_breakpoint_pc = pc - low_decr_pc_after_break ();
err = attach_lwp (ptid);
if (err != 0)
{
- remove_process (proc);
+ this->remove_linux_process (proc);
std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err);
error ("Cannot attach to process %ld: %s", pid, reason.c_str ());
void
linux_process_target::mourn (process_info *process)
{
- struct process_info_private *priv;
-
#ifdef USE_THREAD_DB
thread_db_mourn (process);
#endif
delete_lwp (get_thread_lwp (thread));
});
- /* Freeing all private data. */
- priv = process->priv;
- close (priv->mem_fd);
- low_delete_process (priv->arch_private);
- free (priv);
- process->priv = NULL;
-
- remove_process (process);
+ this->remove_linux_process (process);
}
void
struct lwp_info *
find_lwp_pid (ptid_t ptid)
{
- thread_info *thread = find_thread ([&] (thread_info *thr_arg)
+ long lwp = ptid.lwp () != 0 ? ptid.lwp () : ptid.pid ();
+ thread_info *thread = find_thread ([lwp] (thread_info *thr_arg)
{
- int lwp = ptid.lwp () != 0 ? ptid.lwp () : ptid.pid ();
return thr_arg->id.lwp () == lwp;
});
{
struct thread_info *thread = get_lwp_thread (lwp);
- internal_error (__FILE__, __LINE__,
- "unsuspend LWP %ld, suspended=%d\n", lwpid_of (thread),
+ internal_error ("unsuspend LWP %ld, suspended=%d\n", lwpid_of (thread),
lwp->suspended);
}
}
if (requested_child->suspended
&& requested_child->status_pending_p)
{
- internal_error (__FILE__, __LINE__,
- "requesting an event out of a"
+ internal_error ("requesting an event out of a"
" suspended child?");
}
else
{
/* The LWP stopped due to a plain signal or a syscall signal. Either way,
- event_chid->waitstatus wasn't filled in with the details, so look at
+ event_chid->waitstatus wasn't filled in with the details, so look at
the wait status W. */
if (WSTOPSIG (w) == SYSCALL_SIGTRAP)
{
if (lwp->suspended != 0)
{
- internal_error (__FILE__, __LINE__,
- "LWP %ld is suspended, suspended=%d\n",
+ internal_error ("LWP %ld is suspended, suspended=%d\n",
lwpid_of (thread), lwp->suspended);
}
gdb_assert (lwp->stopped);
if (lwp->suspended != 0)
{
- internal_error (__FILE__, __LINE__,
- "LWP %ld is suspended, suspended=%d\n",
+ internal_error ("LWP %ld is suspended, suspended=%d\n",
lwpid_of (thread), lwp->suspended);
}
gdb_assert (lwp->stopped);
step = 1;
else
{
- internal_error (__FILE__, __LINE__,
- "moving out of jump pad single-stepping"
+ internal_error ("moving out of jump pad single-stepping"
" not implemented on this target");
}
}
if (lwp->suspended != 0)
{
- internal_error (__FILE__, __LINE__,
- "LWP %ld suspended=%d\n", lwpid_of (thread),
+ internal_error ("LWP %ld suspended=%d\n", lwpid_of (thread),
lwp->suspended);
}
if (lseek (fd, memaddr, SEEK_SET) != -1)
bytes = (readbuf != nullptr
? read (fd, readbuf, len)
- ? write (fd, writebuf, len));
+ : write (fd, writebuf, len));
#endif
if (bytes < 0)
{
/* Send a SIGINT to the process group. This acts just like the user
typed a ^C on the controlling terminal. */
- ::kill (-signal_pid, SIGINT);
+ int res = ::kill (-signal_pid, SIGINT);
+ if (res == -1)
+ warning (_("Sending SIGINT to process group of pid %ld failed: %s"),
+ signal_pid, safe_strerror (errno));
}
bool
to debugger memory starting at MYADDR. */
int
-linux_process_target::read_auxv (CORE_ADDR offset, unsigned char *myaddr,
- unsigned int len)
+linux_process_target::read_auxv (int pid, CORE_ADDR offset,
+ unsigned char *myaddr, unsigned int len)
{
char filename[PATH_MAX];
int fd, n;
- int pid = lwpid_of (current_thread);
xsnprintf (filename, sizeof filename, "/proc/%d/auxv", pid);
/* Offset and size of r_debug.r_map. */
int r_map_offset;
+ /* Offset of r_debug_extended.r_next. */
+ int r_next_offset;
+
/* Offset to l_addr field in struct link_map. */
int l_addr_offset;
int l_prev_offset;
};
+static const link_map_offsets lmo_32bit_offsets =
+ {
+ 0, /* r_version offset. */
+ 4, /* r_debug.r_map offset. */
+ 20, /* r_debug_extended.r_next. */
+ 0, /* l_addr offset in link_map. */
+ 4, /* l_name offset in link_map. */
+ 8, /* l_ld offset in link_map. */
+ 12, /* l_next offset in link_map. */
+ 16 /* l_prev offset in link_map. */
+ };
+
+static const link_map_offsets lmo_64bit_offsets =
+ {
+ 0, /* r_version offset. */
+ 8, /* r_debug.r_map offset. */
+ 40, /* r_debug_extended.r_next. */
+ 0, /* l_addr offset in link_map. */
+ 8, /* l_name offset in link_map. */
+ 16, /* l_ld offset in link_map. */
+ 24, /* l_next offset in link_map. */
+ 32 /* l_prev offset in link_map. */
+ };
+
+/* Get the loaded shared libraries from one namespace. */
+
+static void
+read_link_map (std::string &document, CORE_ADDR lmid, CORE_ADDR lm_addr,
+ CORE_ADDR lm_prev, int ptr_size, const link_map_offsets *lmo)
+{
+ CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
+
+ while (lm_addr
+ && read_one_ptr (lm_addr + lmo->l_name_offset,
+ &l_name, ptr_size) == 0
+ && read_one_ptr (lm_addr + lmo->l_addr_offset,
+ &l_addr, ptr_size) == 0
+ && read_one_ptr (lm_addr + lmo->l_ld_offset,
+ &l_ld, ptr_size) == 0
+ && read_one_ptr (lm_addr + lmo->l_prev_offset,
+ &l_prev, ptr_size) == 0
+ && read_one_ptr (lm_addr + lmo->l_next_offset,
+ &l_next, ptr_size) == 0)
+ {
+ unsigned char libname[PATH_MAX];
+
+ if (lm_prev != l_prev)
+ {
+ warning ("Corrupted shared library list: 0x%s != 0x%s",
+ paddress (lm_prev), paddress (l_prev));
+ break;
+ }
+
+ /* Not checking for error because reading may stop before we've got
+ PATH_MAX worth of characters. */
+ libname[0] = '\0';
+ linux_read_memory (l_name, libname, sizeof (libname) - 1);
+ libname[sizeof (libname) - 1] = '\0';
+ if (libname[0] != '\0')
+ {
+ string_appendf (document, "<library name=\"");
+ xml_escape_text_append (document, (char *) libname);
+ string_appendf (document, "\" lm=\"0x%s\" l_addr=\"0x%s\" "
+ "l_ld=\"0x%s\" lmid=\"0x%s\"/>",
+ paddress (lm_addr), paddress (l_addr),
+ paddress (l_ld), paddress (lmid));
+ }
+
+ lm_prev = lm_addr;
+ lm_addr = l_next;
+ }
+}
+
/* Construct qXfer:libraries-svr4:read reply. */
int
struct process_info_private *const priv = current_process ()->priv;
char filename[PATH_MAX];
int pid, is_elf64;
-
- static const struct link_map_offsets lmo_32bit_offsets =
- {
- 0, /* r_version offset. */
- 4, /* r_debug.r_map offset. */
- 0, /* l_addr offset in link_map. */
- 4, /* l_name offset in link_map. */
- 8, /* l_ld offset in link_map. */
- 12, /* l_next offset in link_map. */
- 16 /* l_prev offset in link_map. */
- };
-
- static const struct link_map_offsets lmo_64bit_offsets =
- {
- 0, /* r_version offset. */
- 8, /* r_debug.r_map offset. */
- 0, /* l_addr offset in link_map. */
- 8, /* l_name offset in link_map. */
- 16, /* l_ld offset in link_map. */
- 24, /* l_next offset in link_map. */
- 32 /* l_prev offset in link_map. */
- };
- const struct link_map_offsets *lmo;
unsigned int machine;
- int ptr_size;
- CORE_ADDR lm_addr = 0, lm_prev = 0;
- CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
- int header_done = 0;
+ CORE_ADDR lmid = 0, lm_addr = 0, lm_prev = 0;
if (writebuf != NULL)
return -2;
pid = lwpid_of (current_thread);
xsnprintf (filename, sizeof filename, "/proc/%d/exe", pid);
is_elf64 = elf_64_file_p (filename, &machine);
- lmo = is_elf64 ? &lmo_64bit_offsets : &lmo_32bit_offsets;
- ptr_size = is_elf64 ? 8 : 4;
+ const link_map_offsets *lmo;
+ int ptr_size;
+ if (is_elf64)
+ {
+ lmo = &lmo_64bit_offsets;
+ ptr_size = 8;
+ }
+ else
+ {
+ lmo = &lmo_32bit_offsets;
+ ptr_size = 4;
+ }
while (annex[0] != '\0')
{
break;
name_len = sep - annex;
- if (name_len == 5 && startswith (annex, "start"))
+ if (name_len == 4 && startswith (annex, "lmid"))
+ addrp = &lmid;
+ else if (name_len == 5 && startswith (annex, "start"))
addrp = &lm_addr;
else if (name_len == 4 && startswith (annex, "prev"))
addrp = &lm_prev;
annex = decode_address_to_semicolon (addrp, sep + 1);
}
- if (lm_addr == 0)
+ std::string document = "<library-list-svr4 version=\"1.0\"";
+
+ /* When the starting LM_ADDR is passed in the annex, only traverse that
+ namespace, which is assumed to be identified by LMID.
+
+ Otherwise, start with R_DEBUG and traverse all namespaces we find. */
+ if (lm_addr != 0)
+ {
+ document += ">";
+ read_link_map (document, lmid, lm_addr, lm_prev, ptr_size, lmo);
+ }
+ else
{
- int r_version = 0;
+ if (lm_prev != 0)
+ warning ("ignoring prev=0x%s without start", paddress (lm_prev));
- if (priv->r_debug == 0)
- priv->r_debug = get_r_debug (pid, is_elf64);
+ /* We could interpret LMID as 'provide only the libraries for this
+ namespace' but GDB is currently only providing lmid, start, and
+ prev, or nothing. */
+ if (lmid != 0)
+ warning ("ignoring lmid=0x%s without start", paddress (lmid));
+
+ CORE_ADDR r_debug = priv->r_debug;
+ if (r_debug == 0)
+ r_debug = priv->r_debug = get_r_debug (pid, is_elf64);
/* We failed to find DT_DEBUG. Such situation will not change
for this inferior - do not retry it. Report it to GDB as
E01, see for the reasons at the GDB solib-svr4.c side. */
- if (priv->r_debug == (CORE_ADDR) -1)
+ if (r_debug == (CORE_ADDR) -1)
return -1;
- if (priv->r_debug != 0)
+ /* Terminate the header if we end up with an empty list. */
+ if (r_debug == 0)
+ document += ">";
+
+ while (r_debug != 0)
{
- if (linux_read_memory (priv->r_debug + lmo->r_version_offset,
+ int r_version = 0;
+ if (linux_read_memory (r_debug + lmo->r_version_offset,
(unsigned char *) &r_version,
- sizeof (r_version)) != 0
- || r_version < 1)
+ sizeof (r_version)) != 0)
{
- warning ("unexpected r_debug version %d", r_version);
+ warning ("unable to read r_version from 0x%s",
+ paddress (r_debug + lmo->r_version_offset));
+ break;
}
- else if (read_one_ptr (priv->r_debug + lmo->r_map_offset,
- &lm_addr, ptr_size) != 0)
+
+ if (r_version < 1)
{
- warning ("unable to read r_map from 0x%lx",
- (long) priv->r_debug + lmo->r_map_offset);
+ warning ("unexpected r_debug version %d", r_version);
+ break;
}
- }
- }
-
- std::string document = "<library-list-svr4 version=\"1.0\"";
- while (lm_addr
- && read_one_ptr (lm_addr + lmo->l_name_offset,
- &l_name, ptr_size) == 0
- && read_one_ptr (lm_addr + lmo->l_addr_offset,
- &l_addr, ptr_size) == 0
- && read_one_ptr (lm_addr + lmo->l_ld_offset,
- &l_ld, ptr_size) == 0
- && read_one_ptr (lm_addr + lmo->l_prev_offset,
- &l_prev, ptr_size) == 0
- && read_one_ptr (lm_addr + lmo->l_next_offset,
- &l_next, ptr_size) == 0)
- {
- unsigned char libname[PATH_MAX];
+ if (read_one_ptr (r_debug + lmo->r_map_offset, &lm_addr,
+ ptr_size) != 0)
+ {
+ warning ("unable to read r_map from 0x%s",
+ paddress (r_debug + lmo->r_map_offset));
+ break;
+ }
- if (lm_prev != l_prev)
- {
- warning ("Corrupted shared library list: 0x%lx != 0x%lx",
- (long) lm_prev, (long) l_prev);
- break;
- }
+ /* We read the entire namespace. */
+ lm_prev = 0;
- /* Ignore the first entry even if it has valid name as the first entry
- corresponds to the main executable. The first entry should not be
- skipped if the dynamic loader was loaded late by a static executable
- (see solib-svr4.c parameter ignore_first). But in such case the main
- executable does not have PT_DYNAMIC present and this function already
- exited above due to failed get_r_debug. */
- if (lm_prev == 0)
- string_appendf (document, " main-lm=\"0x%lx\"", (unsigned long) lm_addr);
- else
- {
- /* Not checking for error because reading may stop before
- we've got PATH_MAX worth of characters. */
- libname[0] = '\0';
- linux_read_memory (l_name, libname, sizeof (libname) - 1);
- libname[sizeof (libname) - 1] = '\0';
- if (libname[0] != '\0')
+ /* The first entry corresponds to the main executable unless the
+ dynamic loader was loaded late by a static executable. But
+ in such case the main executable does not have PT_DYNAMIC
+ present and we would not have gotten here. */
+ if (r_debug == priv->r_debug)
{
- if (!header_done)
+ if (lm_addr != 0)
+ string_appendf (document, " main-lm=\"0x%s\">",
+ paddress (lm_addr));
+ else
+ document += ">";
+
+ lm_prev = lm_addr;
+ if (read_one_ptr (lm_addr + lmo->l_next_offset,
+ &lm_addr, ptr_size) != 0)
{
- /* Terminate `<library-list-svr4'. */
- document += '>';
- header_done = 1;
+ warning ("unable to read l_next from 0x%s",
+ paddress (lm_addr + lmo->l_next_offset));
+ break;
}
+ }
- string_appendf (document, "<library name=\"");
- xml_escape_text_append (&document, (char *) libname);
- string_appendf (document, "\" lm=\"0x%lx\" "
- "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
- (unsigned long) lm_addr, (unsigned long) l_addr,
- (unsigned long) l_ld);
+ read_link_map (document, r_debug, lm_addr, lm_prev, ptr_size, lmo);
+
+ if (r_version < 2)
+ break;
+
+ if (read_one_ptr (r_debug + lmo->r_next_offset, &r_debug,
+ ptr_size) != 0)
+ {
+ warning ("unable to read r_next from 0x%s",
+ paddress (r_debug + lmo->r_next_offset));
+ break;
}
}
-
- lm_prev = lm_addr;
- lm_addr = l_next;
}
- if (!header_done)
- {
- /* Empty list; terminate `<library-list-svr4'. */
- document += "/>";
- }
- else
- document += "</library-list-svr4>";
+ document += "</library-list-svr4>";
int document_len = document.length ();
if (offset < document_len)
#ifdef HAVE_LINUX_BTRACE
+bool
+linux_process_target::supports_btrace ()
+{
+ return true;
+}
+
btrace_target_info *
linux_process_target::enable_btrace (thread_info *tp,
const btrace_config *conf)
/* Encode an Intel Processor Trace configuration. */
static void
-linux_low_encode_pt_config (struct buffer *buffer,
+linux_low_encode_pt_config (std::string *buffer,
const struct btrace_data_pt_config *config)
{
- buffer_grow_str (buffer, "<pt-config>\n");
+ *buffer += "<pt-config>\n";
switch (config->cpu.vendor)
{
case CV_INTEL:
- buffer_xml_printf (buffer, "<cpu vendor=\"GenuineIntel\" family=\"%u\" "
- "model=\"%u\" stepping=\"%u\"/>\n",
- config->cpu.family, config->cpu.model,
- config->cpu.stepping);
+ string_xml_appendf (*buffer, "<cpu vendor=\"GenuineIntel\" family=\"%u\" "
+ "model=\"%u\" stepping=\"%u\"/>\n",
+ config->cpu.family, config->cpu.model,
+ config->cpu.stepping);
break;
default:
break;
}
- buffer_grow_str (buffer, "</pt-config>\n");
+ *buffer += "</pt-config>\n";
}
/* Encode a raw buffer. */
static void
-linux_low_encode_raw (struct buffer *buffer, const gdb_byte *data,
+linux_low_encode_raw (std::string *buffer, const gdb_byte *data,
unsigned int size)
{
if (size == 0)
return;
/* We use hex encoding - see gdbsupport/rsp-low.h. */
- buffer_grow_str (buffer, "<raw>\n");
+ *buffer += "<raw>\n";
while (size-- > 0)
{
elem[0] = tohex ((*data >> 4) & 0xf);
elem[1] = tohex (*data++ & 0xf);
- buffer_grow (buffer, elem, 2);
+ buffer->append (elem, 2);
}
- buffer_grow_str (buffer, "</raw>\n");
+ *buffer += "</raw>\n";
}
/* See to_read_btrace target method. */
int
linux_process_target::read_btrace (btrace_target_info *tinfo,
- buffer *buffer,
+ std::string *buffer,
enum btrace_read_type type)
{
struct btrace_data btrace;
if (err != BTRACE_ERR_NONE)
{
if (err == BTRACE_ERR_OVERFLOW)
- buffer_grow_str0 (buffer, "E.Overflow.");
+ *buffer += "E.Overflow.";
else
- buffer_grow_str0 (buffer, "E.Generic Error.");
+ *buffer += "E.Generic Error.";
return -1;
}
switch (btrace.format)
{
case BTRACE_FORMAT_NONE:
- buffer_grow_str0 (buffer, "E.No Trace.");
+ *buffer += "E.No Trace.";
return -1;
case BTRACE_FORMAT_BTS:
- buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");
- buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");
+ *buffer += "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n";
+ *buffer += "<btrace version=\"1.0\">\n";
for (const btrace_block &block : *btrace.variant.bts.blocks)
- buffer_xml_printf (buffer, "<block begin=\"0x%s\" end=\"0x%s\"/>\n",
- paddress (block.begin), paddress (block.end));
+ string_xml_appendf (*buffer, "<block begin=\"0x%s\" end=\"0x%s\"/>\n",
+ paddress (block.begin), paddress (block.end));
- buffer_grow_str0 (buffer, "</btrace>\n");
+ *buffer += "</btrace>\n";
break;
case BTRACE_FORMAT_PT:
- buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");
- buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");
- buffer_grow_str (buffer, "<pt>\n");
+ *buffer += "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n";
+ *buffer += "<btrace version=\"1.0\">\n";
+ *buffer += "<pt>\n";
linux_low_encode_pt_config (buffer, &btrace.variant.pt.config);
linux_low_encode_raw (buffer, btrace.variant.pt.data,
btrace.variant.pt.size);
- buffer_grow_str (buffer, "</pt>\n");
- buffer_grow_str0 (buffer, "</btrace>\n");
+ *buffer += "</pt>\n";
+ *buffer += "</btrace>\n";
break;
default:
- buffer_grow_str0 (buffer, "E.Unsupported Trace Format.");
+ *buffer += "E.Unsupported Trace Format.";
return -1;
}
int
linux_process_target::read_btrace_conf (const btrace_target_info *tinfo,
- buffer *buffer)
+ std::string *buffer)
{
const struct btrace_config *conf;
- buffer_grow_str (buffer, "<!DOCTYPE btrace-conf SYSTEM \"btrace-conf.dtd\">\n");
- buffer_grow_str (buffer, "<btrace-conf version=\"1.0\">\n");
+ *buffer += "<!DOCTYPE btrace-conf SYSTEM \"btrace-conf.dtd\">\n";
+ *buffer += "<btrace-conf version=\"1.0\">\n";
conf = linux_btrace_conf (tinfo);
if (conf != NULL)
break;
case BTRACE_FORMAT_BTS:
- buffer_xml_printf (buffer, "<bts");
- buffer_xml_printf (buffer, " size=\"0x%x\"", conf->bts.size);
- buffer_xml_printf (buffer, " />\n");
+ string_xml_appendf (*buffer, "<bts");
+ string_xml_appendf (*buffer, " size=\"0x%x\"", conf->bts.size);
+ string_xml_appendf (*buffer, " />\n");
break;
case BTRACE_FORMAT_PT:
- buffer_xml_printf (buffer, "<pt");
- buffer_xml_printf (buffer, " size=\"0x%x\"", conf->pt.size);
- buffer_xml_printf (buffer, "/>\n");
+ string_xml_appendf (*buffer, "<pt");
+ string_xml_appendf (*buffer, " size=\"0x%x\"", conf->pt.size);
+ string_xml_appendf (*buffer, "/>\n");
break;
}
}
- buffer_grow_str0 (buffer, "</btrace-conf>\n");
+ *buffer += "</btrace-conf>\n";
return 0;
}
#endif /* HAVE_LINUX_BTRACE */
/* See linux-low.h. */
int
-linux_get_auxv (int wordsize, CORE_ADDR match, CORE_ADDR *valp)
+linux_get_auxv (int pid, int wordsize, CORE_ADDR match, CORE_ADDR *valp)
{
gdb_byte *data = (gdb_byte *) alloca (2 * wordsize);
int offset = 0;
gdb_assert (wordsize == 4 || wordsize == 8);
- while (the_target->read_auxv (offset, data, 2 * wordsize) == 2 * wordsize)
+ while (the_target->read_auxv (pid, offset, data, 2 * wordsize)
+ == 2 * wordsize)
{
if (wordsize == 4)
{
/* See linux-low.h. */
CORE_ADDR
-linux_get_hwcap (int wordsize)
+linux_get_hwcap (int pid, int wordsize)
{
CORE_ADDR hwcap = 0;
- linux_get_auxv (wordsize, AT_HWCAP, &hwcap);
+ linux_get_auxv (pid, wordsize, AT_HWCAP, &hwcap);
return hwcap;
}
/* See linux-low.h. */
CORE_ADDR
-linux_get_hwcap2 (int wordsize)
+linux_get_hwcap2 (int pid, int wordsize)
{
CORE_ADDR hwcap2 = 0;
- linux_get_auxv (wordsize, AT_HWCAP2, &hwcap2);
+ linux_get_auxv (pid, wordsize, AT_HWCAP2, &hwcap2);
return hwcap2;
}