Change rs6000_ptrace_ldinfo to return a byte_vector

This changes rs6000_ptrace_ldinfo to return a byte_vector.  I think
this points out an existing double-free in
rs6000_xfer_shared_libraries.

Tested by the buildbot.

gdb/ChangeLog
2018-04-01  Tom Tromey  <tom@tromey.com>

	* rs6000-nat.c (rs6000_ptrace_ldinfo): Return a byte_vector.
	(rs6000_xfer_shared_libraries): Update.
This commit is contained in:
Tom Tromey 2017-11-10 13:52:37 -07:00
parent a9f4c2f56f
commit 09473be85c
2 changed files with 16 additions and 21 deletions

View File

@ -1,3 +1,8 @@
2018-04-01 Tom Tromey <tom@tromey.com>
* rs6000-nat.c (rs6000_ptrace_ldinfo): Return a byte_vector.
(rs6000_xfer_shared_libraries): Update.
2018-04-01 Simon Marchi <simon.marchi@polymtl.ca> 2018-04-01 Simon Marchi <simon.marchi@polymtl.ca>
* common/gdb_vecs.h (char_ptr): Remove. * common/gdb_vecs.h (char_ptr): Remove.

View File

@ -583,25 +583,23 @@ rs6000_create_inferior (struct target_ops * ops, const char *exec_file,
/* Shared Object support. */ /* Shared Object support. */
/* Return the LdInfo data for the given process. Raises an error /* Return the LdInfo data for the given process. Raises an error
if the data could not be obtained. if the data could not be obtained. */
The returned value must be deallocated after use. */ static gdb::byte_vector
static gdb_byte *
rs6000_ptrace_ldinfo (ptid_t ptid) rs6000_ptrace_ldinfo (ptid_t ptid)
{ {
const int pid = ptid_get_pid (ptid); const int pid = ptid_get_pid (ptid);
int ldi_size = 1024; gdb::byte_vector ldi (1024);
void *ldi = xmalloc (ldi_size);
int rc = -1; int rc = -1;
while (1) while (1)
{ {
if (ARCH64 ()) if (ARCH64 ())
rc = rs6000_ptrace64 (PT_LDINFO, pid, (unsigned long) ldi, ldi_size, rc = rs6000_ptrace64 (PT_LDINFO, pid, (unsigned long) ldi.data (),
NULL); ldi.size (), NULL);
else else
rc = rs6000_ptrace32 (PT_LDINFO, pid, (int *) ldi, ldi_size, NULL); rc = rs6000_ptrace32 (PT_LDINFO, pid, (int *) ldi.data (),
ldi.size (), NULL);
if (rc != -1) if (rc != -1)
break; /* Success, we got the entire ld_info data. */ break; /* Success, we got the entire ld_info data. */
@ -610,11 +608,10 @@ rs6000_ptrace_ldinfo (ptid_t ptid)
perror_with_name (_("ptrace ldinfo")); perror_with_name (_("ptrace ldinfo"));
/* ldi is not big enough. Double it and try again. */ /* ldi is not big enough. Double it and try again. */
ldi_size *= 2; ldi.resize (ldi.size () * 2);
ldi = xrealloc (ldi, ldi_size);
} }
return (gdb_byte *) ldi; return ldi;
} }
/* Implement the to_xfer_partial target_ops method for /* Implement the to_xfer_partial target_ops method for
@ -626,9 +623,7 @@ rs6000_xfer_shared_libraries
const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf,
ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
{ {
gdb_byte *ldi_buf;
ULONGEST result; ULONGEST result;
struct cleanup *cleanup;
/* This function assumes that it is being run with a live process. /* This function assumes that it is being run with a live process.
Core files are handled via gdbarch. */ Core files are handled via gdbarch. */
@ -637,14 +632,9 @@ rs6000_xfer_shared_libraries
if (writebuf) if (writebuf)
return TARGET_XFER_E_IO; return TARGET_XFER_E_IO;
ldi_buf = rs6000_ptrace_ldinfo (inferior_ptid); gdb::byte_vector ldi_buf = rs6000_ptrace_ldinfo (inferior_ptid);
gdb_assert (ldi_buf != NULL); result = rs6000_aix_ld_info_to_xml (target_gdbarch (), ldi_buf.data (),
cleanup = make_cleanup (xfree, ldi_buf);
result = rs6000_aix_ld_info_to_xml (target_gdbarch (), ldi_buf,
readbuf, offset, len, 1); readbuf, offset, len, 1);
xfree (ldi_buf);
do_cleanups (cleanup);
if (result == 0) if (result == 0)
return TARGET_XFER_EOF; return TARGET_XFER_EOF;