public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Tom Tromey <tom@tromey.com>
To: Mark Harmstone <mark@harmstone.com>
Cc: binutils@sourceware.org
Subject: Re: [PATCH 2/2] gdb: Allow reading of enum definitions in PDB files
Date: Thu, 11 May 2023 07:41:05 -0600	[thread overview]
Message-ID: <87y1lv3s0e.fsf@tromey.com> (raw)
In-Reply-To: <20230509003247.24156-2-mark@harmstone.com> (Mark Harmstone's message of "Tue, 9 May 2023 01:32:47 +0100")

>>>>> "Mark" == Mark Harmstone <mark@harmstone.com> writes:

Mark> Adds a new file pdbread.c, which parses LF_ENUM records in PDB files.

Hi.  Thank you for the patch.  I'm happy to see this happening.

Normally, gdb patches should be sent to the gdb-patches list.  It's fine
IMO to just CC one like this, in the middle of a series, to gdb-patches.

I don't know anything about pdb, so I won't comment much on that.

Mark> --- a/gdb/configure.tgt
Mark> +++ b/gdb/configure.tgt
Mark> @@ -335,7 +335,7 @@ i[34567]86-*-cygwin*)
Mark>  	;;
Mark>  i[34567]86-*-mingw32*)
Mark>  	# Target: Intel 386 running win32
Mark> -	gdb_target_obs="i386-windows-tdep.o windows-tdep.o"
Mark> +	gdb_target_obs="i386-windows-tdep.o windows-tdep.o pdbread.o"

I don't think this should be handled here.

Object and debuginfo readers can either be compiled in unconditionally,
or by seeing whether any necessary support is present in BFD.  For the
latter, see how elfread.o is handled in gdb/configure.ac.

Mark> +/* Return the size in bytes of a PDB builtin type.  */
Mark> +static ULONGEST
Mark> +pdb_builtin_type_length (uint32_t t)
Mark> +{

Probably this can be removed in favor.  It's only used here:

+  t->set_target_type (pdb_builtin_type (builtin_type (objfile),
+					bfd_getl32 (&en.underlying_type)));
+  t->set_length (pdb_builtin_type_length (bfd_getl32 (&en.underlying_type)));

but this will do something weird if the builtin type and
pdb_builtin_type_length disagree about the size.  Instead you can do
something like:

   struct type *targ_type = pdb_builtin_type (...);
   t->set_target_type (targ_type);
   t->set_length (targ_type->length ());

Mark> +/* Some integers, such as enum values, get stored as an extended value if
Mark> +   they're too large to fit into two bytes.  The two bytes that would normally
Mark> +   be the value are instead a type indicator, and the actual value follows.  */
Mark> +static bool
Mark> +pdb_read_extended_value (uint16_t kind, char **ptr, uint16_t *length,
Mark> +			 LONGEST *ret)

gdb normally puts 'const' where it makes sense, so for instance 'const char **ptr'.
This requires a change in the caller but I was going to request that anyway.

Mark> +  buf = (char *) xmalloc (length);
Mark> +
Mark> +  if (bfd_bread (buf, length, tpi) != length)
Mark> +    goto end;

gdb generally uses RAII now for cleanups.  'buf' could either be a
unique_xmalloc_ptr<char>, or a gdb::char_vector (or even byte_vector
depending on if you want to use gdb_byte).  This will ensure proper
cleanup even in the face of future refactorings, and instead of 'goto end',
the code can just 'return'.

Mark> +	  /* Round to 4-byte boundary.  */
Mark> +	  if ((ptr - buf + 2) % 4)
Mark> +	    {
Mark> +	      if (length < 4)
Mark> +		goto end;
Mark> +
Mark> +	      length -= 4 - ((ptr - buf + 2) % 4);
Mark> +	      ptr += 4 - ((ptr - buf + 2) % 4);

I thought gdb had some macro for this but I can't find it now.

Mark> +	case LF_INDEX: {
Mark> +	  struct lf_index *ind;
Mark> +	  uint32_t fl_type;
Mark> +
Mark> +	  if (length < sizeof (*ind))
Mark> +	    goto end;
Mark> +
Mark> +	  ind = (struct lf_index *) ptr;

Not sure if this is really guaranteed to have correct alignment; if not
it could just be memcpy'd out.

Mark> +  name_len = length - sizeof (en);
Mark> +  name = (char * ) xmalloc (name_len + 1);

Either unique_xmalloc_ptr<char> or std::string here.

Mark> +  t = type_allocator (objfile).new_type ();
Mark> +  t->set_code (TYPE_CODE_ENUM);
Mark> +  t->set_name (name);

This will leak 'name'.

In gdb, types are allocated on an obstack; in this case, the objfile
obstack.  When the objfile is destroyed, the obstack is also freed --
but this does not run any destructors or free any data associated with
objects on the obstack.

Instead, if a string must be preserved, it should be copied to the
objfile obstack.  If the string is likely to be duplicated in the
objfile (if it might be needed multiple times), then objfile::intern can
be used.

Mark> +  num_types = last_type - first_type + 1;
Mark> +  types = (struct pdb_type *) xmalloc (sizeof (*types) * num_types);

Use std::vector here.

Mark> +
Mark> +  for (unsigned int i = 0; i < num_types; i++)

You can use C++ "foreach".

Mark> +	  bfd_close (tpi);

gdb has a complicated BFD reference-counting setup, but that might be
overkill for this use.  However, it's not difficult to make a deleter
type that wraps bfd_close, so that explicit closes on error paths aren't
needed.  This would be more idiomatic in gdb.  If you look for typedefs
of unique_ptr, you'll find some of these.

Mark> +static void
Mark> +pdb_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
Mark> +{
Mark> +  buildsym_compunit builder(objfile, "", nullptr, language_c, 0);

Assuming this is the first of several PDB-reading patches, it may be
worth considering the overall approach.

Other debug info readers in gdb work in two passes.  First they make
some kind of "quick" index.  Then, when a symbol lookup finds a match,
the full debug info for a given compilation unit is read in.

The code here only does the second step.  I don't know PDB, so maybe
that's the only way it can be done?

In gdb, the symbols are normally associated with a given compilation
unit.  This isn't done in this patch... I'm wondering if that's possible
to do?

Mark> +if {![istarget i*86-*-mingw*]
Mark> +  && ![istarget x86_64-*-mingw*]} {
Mark> +    return 0

Probably can use 'require {is_any_target ...}'

Mark> +gdb_test "ptype enum enum1" "type = enum enum1 \{red, green, blue = -1, yellow = 32768, purple = 4294967296\}.*" "ptype enum enum1"

Normally we'd split the lines so they fit in 80 columns.

Tom

  reply	other threads:[~2023-05-11 13:41 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-09  0:32 [PATCH 1/2] pdb: Allow loading by gdb Mark Harmstone
2023-05-09  0:32 ` [PATCH 2/2] gdb: Allow reading of enum definitions in PDB files Mark Harmstone
2023-05-11 13:41   ` Tom Tromey [this message]
2023-05-10  0:56 ` [PATCH 1/2] pdb: Allow loading by gdb Alan Modra
2023-05-15  1:04   ` Mark Harmstone
2023-05-15  1:26     ` Alan Modra
2023-05-16 15:03     ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87y1lv3s0e.fsf@tromey.com \
    --to=tom@tromey.com \
    --cc=binutils@sourceware.org \
    --cc=mark@harmstone.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).