public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [review] Only make a nullterminated string if we need to
@ 2019-10-22 22:30 Christian Biesinger (Code Review)
  2019-10-25 17:59 ` Tom Tromey (Code Review)
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Christian Biesinger (Code Review) @ 2019-10-22 22:30 UTC (permalink / raw)
  To: gdb-patches; +Cc: Christian Biesinger

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/222
......................................................................

Only make a nullterminated string if we need to

As of 7bb43059820c5febb4509b15202a93efde442bc6, we no longer need
a nullterminated linkage_name to look up the entry in the hash table.

So this patch makes it so we only make the copy if the entry was
not found.

gdb/ChangeLog:

2019-10-22  Christian Biesinger  <cbiesinger@google.com>

	* symtab.c (symbol_set_names): Only make a nullterminated copy of
	linkage_name if the entry was not found and we need to demangle.

Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
---
M gdb/symtab.c
1 file changed, 16 insertions(+), 16 deletions(-)



diff --git a/gdb/symtab.c b/gdb/symtab.c
index 0a87fec..787c4b6 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -829,8 +829,6 @@
 		  struct objfile_per_bfd_storage *per_bfd)
 {
   struct demangled_name_entry **slot;
-  /* A 0-terminated copy of the linkage name.  */
-  const char *linkage_name_copy;
 
   if (gsymbol->language == language_ada)
     {
@@ -855,20 +853,7 @@
   if (per_bfd->demangled_names_hash == NULL)
     create_demangled_names_hash (per_bfd);
 
-  if (linkage_name[len] != '\0')
-    {
-      char *alloc_name;
-
-      alloc_name = (char *) alloca (len + 1);
-      memcpy (alloc_name, linkage_name, len);
-      alloc_name[len] = '\0';
-
-      linkage_name_copy = alloc_name;
-    }
-  else
-    linkage_name_copy = linkage_name;
-
-  struct demangled_name_entry entry (gdb::string_view (linkage_name_copy, len));
+  struct demangled_name_entry entry (gdb::string_view (linkage_name, len));
   slot = ((struct demangled_name_entry **)
 	  htab_find_slot (per_bfd->demangled_names_hash.get (),
 			  &entry, INSERT));
@@ -880,6 +865,21 @@
       || (gsymbol->language == language_go
 	  && (*slot)->demangled[0] == '\0'))
     {
+      /* A 0-terminated copy of the linkage name.  */
+      const char *linkage_name_copy;
+      if (linkage_name[len] != '\0')
+	{
+	  char *alloc_name;
+
+	  alloc_name = (char *) alloca (len + 1);
+	  memcpy (alloc_name, linkage_name, len);
+	  alloc_name[len] = '\0';
+
+	  linkage_name_copy = alloc_name;
+	}
+      else
+	linkage_name_copy = linkage_name;
+
       char *demangled_name_ptr
 	= symbol_find_demangled_name (gsymbol, linkage_name_copy);
       gdb::unique_xmalloc_ptr<char> demangled_name (demangled_name_ptr);

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [review] Only make a nullterminated string if we need to
  2019-10-22 22:30 [review] Only make a nullterminated string if we need to Christian Biesinger (Code Review)
@ 2019-10-25 17:59 ` Tom Tromey (Code Review)
  2019-10-25 18:04 ` Christian Biesinger (Code Review)
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Tom Tromey (Code Review) @ 2019-10-25 17:59 UTC (permalink / raw)
  To: Christian Biesinger, gdb-patches; +Cc: Luis Machado

Tom Tromey has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/222
......................................................................


Patch Set 1:

Thanks for the patch.

The patch moves the `linkage_name_copy` code a bit lower.
But, I think this copy is actually no longer needed at all, and
so the code can be removed.  The only real (non-flag) use of
linkage_name_copy is to again copy:

	  strcpy (mangled_ptr, linkage_name_copy);

... but this could be replaced by a memcpy and then a store of
the trailing \0.

Wouldn't this change also re-enable the string_view change?
It seems that way to me, but I wonder if I am missing something here.


-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
Gerrit-Change-Number: 222
Gerrit-PatchSet: 1
Gerrit-Owner: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Luis Machado <luis.machado@linaro.org>
Gerrit-CC: Tom Tromey <tromey@sourceware.org>
Gerrit-Comment-Date: Fri, 25 Oct 2019 17:59:13 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
Gerrit-MessageType: comment

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [review] Only make a nullterminated string if we need to
  2019-10-22 22:30 [review] Only make a nullterminated string if we need to Christian Biesinger (Code Review)
  2019-10-25 17:59 ` Tom Tromey (Code Review)
@ 2019-10-25 18:04 ` Christian Biesinger (Code Review)
  2019-10-25 20:02 ` [review v2] " Christian Biesinger (Code Review)
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Christian Biesinger (Code Review) @ 2019-10-25 18:04 UTC (permalink / raw)
  To: Christian Biesinger, gdb-patches; +Cc: Tom Tromey, Luis Machado

Christian Biesinger has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/222
......................................................................


Patch Set 1:

> Patch Set 1:
> 
> Thanks for the patch.
> 
> The patch moves the `linkage_name_copy` code a bit lower.
> But, I think this copy is actually no longer needed at all, and
> so the code can be removed.  The only real (non-flag) use of
> linkage_name_copy is to again copy:
> 
> 	  strcpy (mangled_ptr, linkage_name_copy);
> 
> ... but this could be replaced by a memcpy and then a store of
> the trailing \0.
> 
> Wouldn't this change also re-enable the string_view change?
> It seems that way to me, but I wonder if I am missing something here.

Unfortunately it is also used in the call to symbol_find_demangled_name, and that can't be changed without changing bfd API; I haven't investigated that but I suspect it may be difficult.

You are correct as far as that strcpy goes, of course.


-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
Gerrit-Change-Number: 222
Gerrit-PatchSet: 1
Gerrit-Owner: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Luis Machado <luis.machado@linaro.org>
Gerrit-CC: Tom Tromey <tromey@sourceware.org>
Gerrit-Comment-Date: Fri, 25 Oct 2019 18:03:57 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
Gerrit-MessageType: comment

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [review v2] Only make a nullterminated string if we need to
  2019-10-22 22:30 [review] Only make a nullterminated string if we need to Christian Biesinger (Code Review)
  2019-10-25 17:59 ` Tom Tromey (Code Review)
  2019-10-25 18:04 ` Christian Biesinger (Code Review)
@ 2019-10-25 20:02 ` Christian Biesinger (Code Review)
  2019-10-25 20:08 ` Christian Biesinger (Code Review)
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Christian Biesinger (Code Review) @ 2019-10-25 20:02 UTC (permalink / raw)
  To: Christian Biesinger, Luis Machado, gdb-patches; +Cc: Tom Tromey

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/222
......................................................................

Only make a nullterminated string if we need to

As of 7bb43059820c5febb4509b15202a93efde442bc6, we no longer need
a nullterminated linkage_name to look up the entry in the hash table.

So this patch makes it so we only make the copy if the entry was
not found.

gdb/ChangeLog:

2019-10-22  Christian Biesinger  <cbiesinger@google.com>

	* symtab.c (symbol_set_names): Only make a nullterminated copy of
	linkage_name if the entry was not found and we need to demangle.

Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
---
M gdb/symtab.c
1 file changed, 18 insertions(+), 17 deletions(-)



diff --git a/gdb/symtab.c b/gdb/symtab.c
index 79c5fde..65d6311 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -832,8 +832,6 @@
 		  struct objfile_per_bfd_storage *per_bfd)
 {
   struct demangled_name_entry **slot;
-  /* A 0-terminated copy of the linkage name.  */
-  const char *linkage_name_copy;
 
   if (gsymbol->language == language_ada)
     {
@@ -858,20 +856,7 @@
   if (per_bfd->demangled_names_hash == NULL)
     create_demangled_names_hash (per_bfd);
 
-  if (linkage_name[len] != '\0')
-    {
-      char *alloc_name;
-
-      alloc_name = (char *) alloca (len + 1);
-      memcpy (alloc_name, linkage_name, len);
-      alloc_name[len] = '\0';
-
-      linkage_name_copy = alloc_name;
-    }
-  else
-    linkage_name_copy = linkage_name;
-
-  struct demangled_name_entry entry (gdb::string_view (linkage_name_copy, len));
+  struct demangled_name_entry entry (gdb::string_view (linkage_name, len));
   slot = ((struct demangled_name_entry **)
 	  htab_find_slot (per_bfd->demangled_names_hash.get (),
 			  &entry, INSERT));
@@ -882,6 +867,21 @@
 	 This happens to, e.g., main.init (__go_init_main).  Cope.  */
       || (gsymbol->language == language_go && (*slot)->demangled == nullptr))
     {
+      /* A 0-terminated copy of the linkage name.  */
+      const char *linkage_name_copy;
+      if (linkage_name[len] != '\0')
+	{
+	  char *alloc_name;
+
+	  alloc_name = (char *) alloca (len + 1);
+	  memcpy (alloc_name, linkage_name, len);
+	  alloc_name[len] = '\0';
+
+	  linkage_name_copy = alloc_name;
+	}
+      else
+	linkage_name_copy = linkage_name;
+
       gdb::unique_xmalloc_ptr<char> demangled_name_ptr
 	(symbol_find_demangled_name (gsymbol, linkage_name_copy));
 
@@ -912,7 +912,8 @@
 	       obstack_alloc (&per_bfd->storage_obstack,
 			      sizeof (demangled_name_entry) + len + 1));
 	  char *mangled_ptr = reinterpret_cast<char *> (*slot + 1);
-	  strcpy (mangled_ptr, linkage_name_copy);
+	  memcpy (mangled_ptr, linkage_name, len);
+	  mangled_ptr [len] = '\0';
 	  new (*slot) demangled_name_entry
 	    (gdb::string_view (mangled_ptr, len));
 	}

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
Gerrit-Change-Number: 222
Gerrit-PatchSet: 2
Gerrit-Owner: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Luis Machado <luis.machado@linaro.org>
Gerrit-CC: Tom Tromey <tromey@sourceware.org>
Gerrit-MessageType: newpatchset

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [review v2] Only make a nullterminated string if we need to
  2019-10-22 22:30 [review] Only make a nullterminated string if we need to Christian Biesinger (Code Review)
                   ` (2 preceding siblings ...)
  2019-10-25 20:02 ` [review v2] " Christian Biesinger (Code Review)
@ 2019-10-25 20:08 ` Christian Biesinger (Code Review)
  2019-10-28 18:51 ` [review v3] " Christian Biesinger (Code Review)
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Christian Biesinger (Code Review) @ 2019-10-25 20:08 UTC (permalink / raw)
  To: Christian Biesinger, gdb-patches; +Cc: Tom Tromey, Luis Machado

Christian Biesinger has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/222
......................................................................


Patch Set 2:

> Patch Set 1:
> 
> Thanks for the patch.
> 
> The patch moves the `linkage_name_copy` code a bit lower.
> But, I think this copy is actually no longer needed at all, and
> so the code can be removed.  The only real (non-flag) use of
> linkage_name_copy is to again copy:
> 
> 	  strcpy (mangled_ptr, linkage_name_copy);
> 
> ... but this could be replaced by a memcpy and then a store of
> the trailing \0.
> 
> Wouldn't this change also re-enable the string_view change?
> It seems that way to me, but I wonder if I am missing something here.

I did update the patch to use the memcpy.

There are still two issues blocking the string_view change:
- The demangle call mentioned in my previous comment. This could be addressed by just always doing alloca + memcpy, which should be relatively cheap compared to the actual demangling, I'd think
- Even if copy_name==false, this function will still copy the name if it is not nullterminated (it has to, because general_symbol_info expects a nullterminated string). This could be fixed by adding a size to general_symbol_info. That should be doable, and I'll look into it

However, I think this patch is good even before solving those two issues.


-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
Gerrit-Change-Number: 222
Gerrit-PatchSet: 2
Gerrit-Owner: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Luis Machado <luis.machado@linaro.org>
Gerrit-CC: Tom Tromey <tromey@sourceware.org>
Gerrit-Comment-Date: Fri, 25 Oct 2019 20:07:59 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
Gerrit-MessageType: comment

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [review v3] Only make a nullterminated string if we need to
  2019-10-22 22:30 [review] Only make a nullterminated string if we need to Christian Biesinger (Code Review)
                   ` (3 preceding siblings ...)
  2019-10-25 20:08 ` Christian Biesinger (Code Review)
@ 2019-10-28 18:51 ` Christian Biesinger (Code Review)
  2019-10-28 19:01 ` [review v4] " Christian Biesinger (Code Review)
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Christian Biesinger (Code Review) @ 2019-10-28 18:51 UTC (permalink / raw)
  To: Christian Biesinger, Luis Machado, gdb-patches; +Cc: Tom Tromey

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/222
......................................................................

Only make a nullterminated string if we need to

As of 7bb43059820c5febb4509b15202a93efde442bc6, we no longer need
a nullterminated linkage_name to look up the entry in the hash table.

So this patch makes it so we only make the copy if the entry was
not found.

By auditing all callers of symbol_set_names, I found out that all cases
where the string may not be nullterminated already pass true for COPY_NAME.
So here, I am documenting that as a requirement and am removing the code
that relies on undefined behavior in symbol_set_names (it accessed the string
past the provided length to check for nulltermination). Note that the Ada
case at the beginning of symbol_set_names was already relying on this.

gdb/ChangeLog:

2019-10-28  Christian Biesinger  <cbiesinger@google.com>

	* symtab.h (symbol_set_names): Document that copy_name must be
	set to true for non-nullterminated strings.
	* symtab.c (symbol_set_names): Only make a nullterminated copy of
	linkage_name if the entry was not found and we need to demangle.

Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
---
M gdb/symtab.c
M gdb/symtab.h
2 files changed, 22 insertions(+), 19 deletions(-)



diff --git a/gdb/symtab.c b/gdb/symtab.c
index 79c5fde..674ab2e 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -832,8 +832,6 @@
 		  struct objfile_per_bfd_storage *per_bfd)
 {
   struct demangled_name_entry **slot;
-  /* A 0-terminated copy of the linkage name.  */
-  const char *linkage_name_copy;
 
   if (gsymbol->language == language_ada)
     {
@@ -858,20 +856,7 @@
   if (per_bfd->demangled_names_hash == NULL)
     create_demangled_names_hash (per_bfd);
 
-  if (linkage_name[len] != '\0')
-    {
-      char *alloc_name;
-
-      alloc_name = (char *) alloca (len + 1);
-      memcpy (alloc_name, linkage_name, len);
-      alloc_name[len] = '\0';
-
-      linkage_name_copy = alloc_name;
-    }
-  else
-    linkage_name_copy = linkage_name;
-
-  struct demangled_name_entry entry (gdb::string_view (linkage_name_copy, len));
+  struct demangled_name_entry entry (gdb::string_view (linkage_name, len));
   slot = ((struct demangled_name_entry **)
 	  htab_find_slot (per_bfd->demangled_names_hash.get (),
 			  &entry, INSERT));
@@ -882,6 +867,22 @@
 	 This happens to, e.g., main.init (__go_init_main).  Cope.  */
       || (gsymbol->language == language_go && (*slot)->demangled == nullptr))
     {
+      /* A 0-terminated copy of the linkage name.  Callers must set COPY_NAME
+         to true if the string might not be nullterminated.  */
+      const char *linkage_name_copy;
+      if (copy_name)
+	{
+	  char *alloc_name;
+
+	  alloc_name = (char *) alloca (len + 1);
+	  memcpy (alloc_name, linkage_name, len);
+	  alloc_name[len] = '\0';
+
+	  linkage_name_copy = alloc_name;
+	}
+      else
+	linkage_name_copy = linkage_name;
+
       gdb::unique_xmalloc_ptr<char> demangled_name_ptr
 	(symbol_find_demangled_name (gsymbol, linkage_name_copy));
 
@@ -894,7 +895,7 @@
 	 It turns out that it is actually important to still save such
 	 an entry in the hash table, because storing this name gives
 	 us better bcache hit rates for partial symbols.  */
-      if (!copy_name && linkage_name_copy == linkage_name)
+      if (!copy_name)
 	{
 	  *slot
 	    = ((struct demangled_name_entry *)
@@ -912,7 +913,8 @@
 	       obstack_alloc (&per_bfd->storage_obstack,
 			      sizeof (demangled_name_entry) + len + 1));
 	  char *mangled_ptr = reinterpret_cast<char *> (*slot + 1);
-	  strcpy (mangled_ptr, linkage_name_copy);
+	  memcpy (mangled_ptr, linkage_name, len);
+	  mangled_ptr [len] = '\0';
 	  new (*slot) demangled_name_entry
 	    (gdb::string_view (mangled_ptr, len));
 	}
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 5300383..131a74d 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -504,7 +504,8 @@
   (symbol)->ginfo.name = (linkage_name)
 
 /* Set the linkage and natural names of a symbol, by demangling
-   the linkage name.  */
+   the linkage name.  If linkage_name may not be nullterminated,
+   copy_name must be set to true.  */
 #define SYMBOL_SET_NAMES(symbol,linkage_name,len,copy_name,objfile)	\
   symbol_set_names (&(symbol)->ginfo, linkage_name, len, copy_name, \
 		    (objfile)->per_bfd)

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
Gerrit-Change-Number: 222
Gerrit-PatchSet: 3
Gerrit-Owner: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Luis Machado <luis.machado@linaro.org>
Gerrit-CC: Tom Tromey <tromey@sourceware.org>
Gerrit-MessageType: newpatchset

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [review v4] Only make a nullterminated string if we need to
  2019-10-22 22:30 [review] Only make a nullterminated string if we need to Christian Biesinger (Code Review)
                   ` (4 preceding siblings ...)
  2019-10-28 18:51 ` [review v3] " Christian Biesinger (Code Review)
@ 2019-10-28 19:01 ` Christian Biesinger (Code Review)
  2019-10-29 19:10 ` Tom Tromey (Code Review)
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Christian Biesinger (Code Review) @ 2019-10-28 19:01 UTC (permalink / raw)
  To: Christian Biesinger, Luis Machado, gdb-patches; +Cc: Tom Tromey

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/222
......................................................................

Only make a nullterminated string if we need to

As of 7bb43059820c5febb4509b15202a93efde442bc6, we no longer need
a nullterminated linkage_name to look up the entry in the hash table.

So this patch makes it so we only make the copy if the entry was
not found.

By auditing all callers of symbol_set_names, I found out that all cases
where the string may not be nullterminated already pass true for COPY_NAME.
So here, I am documenting that as a requirement and am removing the code
that relies on undefined behavior in symbol_set_names (it accessed the string
past the provided length to check for nulltermination). Note that the Ada
case at the beginning of symbol_set_names was already relying on this.

gdb/ChangeLog:

2019-10-28  Christian Biesinger  <cbiesinger@google.com>

	* symtab.h (symbol_set_names): Document that copy_name must be
	set to true for non-nullterminated strings.
	* symtab.c (symbol_set_names): Only make a nullterminated copy of
	linkage_name if the entry was not found and we need to demangle.

Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
---
M gdb/symtab.c
M gdb/symtab.h
2 files changed, 21 insertions(+), 19 deletions(-)



diff --git a/gdb/symtab.c b/gdb/symtab.c
index 79c5fde..a6a9dc9 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -832,8 +832,6 @@
 		  struct objfile_per_bfd_storage *per_bfd)
 {
   struct demangled_name_entry **slot;
-  /* A 0-terminated copy of the linkage name.  */
-  const char *linkage_name_copy;
 
   if (gsymbol->language == language_ada)
     {
@@ -858,20 +856,7 @@
   if (per_bfd->demangled_names_hash == NULL)
     create_demangled_names_hash (per_bfd);
 
-  if (linkage_name[len] != '\0')
-    {
-      char *alloc_name;
-
-      alloc_name = (char *) alloca (len + 1);
-      memcpy (alloc_name, linkage_name, len);
-      alloc_name[len] = '\0';
-
-      linkage_name_copy = alloc_name;
-    }
-  else
-    linkage_name_copy = linkage_name;
-
-  struct demangled_name_entry entry (gdb::string_view (linkage_name_copy, len));
+  struct demangled_name_entry entry (gdb::string_view (linkage_name, len));
   slot = ((struct demangled_name_entry **)
 	  htab_find_slot (per_bfd->demangled_names_hash.get (),
 			  &entry, INSERT));
@@ -882,6 +867,21 @@
 	 This happens to, e.g., main.init (__go_init_main).  Cope.  */
       || (gsymbol->language == language_go && (*slot)->demangled == nullptr))
     {
+      /* A 0-terminated copy of the linkage name.  Callers must set COPY_NAME
+         to true if the string might not be nullterminated.  We have to make
+         this copy because demangling needs a nullterminated string.  */
+      const char *linkage_name_copy;
+      if (copy_name)
+	{
+	  char *alloc_name = (char *) alloca (len + 1);
+	  memcpy (alloc_name, linkage_name, len);
+	  alloc_name[len] = '\0';
+
+	  linkage_name_copy = alloc_name;
+	}
+      else
+	linkage_name_copy = linkage_name;
+
       gdb::unique_xmalloc_ptr<char> demangled_name_ptr
 	(symbol_find_demangled_name (gsymbol, linkage_name_copy));
 
@@ -894,7 +894,7 @@
 	 It turns out that it is actually important to still save such
 	 an entry in the hash table, because storing this name gives
 	 us better bcache hit rates for partial symbols.  */
-      if (!copy_name && linkage_name_copy == linkage_name)
+      if (!copy_name)
 	{
 	  *slot
 	    = ((struct demangled_name_entry *)
@@ -912,7 +912,8 @@
 	       obstack_alloc (&per_bfd->storage_obstack,
 			      sizeof (demangled_name_entry) + len + 1));
 	  char *mangled_ptr = reinterpret_cast<char *> (*slot + 1);
-	  strcpy (mangled_ptr, linkage_name_copy);
+	  memcpy (mangled_ptr, linkage_name, len);
+	  mangled_ptr [len] = '\0';
 	  new (*slot) demangled_name_entry
 	    (gdb::string_view (mangled_ptr, len));
 	}
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 5300383..131a74d 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -504,7 +504,8 @@
   (symbol)->ginfo.name = (linkage_name)
 
 /* Set the linkage and natural names of a symbol, by demangling
-   the linkage name.  */
+   the linkage name.  If linkage_name may not be nullterminated,
+   copy_name must be set to true.  */
 #define SYMBOL_SET_NAMES(symbol,linkage_name,len,copy_name,objfile)	\
   symbol_set_names (&(symbol)->ginfo, linkage_name, len, copy_name, \
 		    (objfile)->per_bfd)

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
Gerrit-Change-Number: 222
Gerrit-PatchSet: 4
Gerrit-Owner: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Luis Machado <luis.machado@linaro.org>
Gerrit-CC: Tom Tromey <tromey@sourceware.org>
Gerrit-MessageType: newpatchset

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [review v4] Only make a nullterminated string if we need to
  2019-10-22 22:30 [review] Only make a nullterminated string if we need to Christian Biesinger (Code Review)
                   ` (5 preceding siblings ...)
  2019-10-28 19:01 ` [review v4] " Christian Biesinger (Code Review)
@ 2019-10-29 19:10 ` Tom Tromey (Code Review)
  2019-10-29 19:28 ` [pushed] " Sourceware to Gerrit sync (Code Review)
  2019-10-29 19:28 ` Sourceware to Gerrit sync (Code Review)
  8 siblings, 0 replies; 10+ messages in thread
From: Tom Tromey (Code Review) @ 2019-10-29 19:10 UTC (permalink / raw)
  To: Christian Biesinger, gdb-patches; +Cc: Luis Machado

Tom Tromey has posted comments on this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/222
......................................................................


Patch Set 4: Code-Review+2

Thank you.  This is ok.

I suddenly realized that maybe storing a string_view is confusing
because, in reality, the stored strings must always be \0-terminated,
because that's how they are used in the rest of the code (via the
symbol names).  But it seems like if there was a problem, this patch
must fix it.


-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
Gerrit-Change-Number: 222
Gerrit-PatchSet: 4
Gerrit-Owner: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Luis Machado <luis.machado@linaro.org>
Gerrit-Reviewer: Tom Tromey <tromey@sourceware.org>
Gerrit-Comment-Date: Tue, 29 Oct 2019 19:09:56 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [pushed] Only make a nullterminated string if we need to
  2019-10-22 22:30 [review] Only make a nullterminated string if we need to Christian Biesinger (Code Review)
                   ` (6 preceding siblings ...)
  2019-10-29 19:10 ` Tom Tromey (Code Review)
@ 2019-10-29 19:28 ` Sourceware to Gerrit sync (Code Review)
  2019-10-29 19:28 ` Sourceware to Gerrit sync (Code Review)
  8 siblings, 0 replies; 10+ messages in thread
From: Sourceware to Gerrit sync (Code Review) @ 2019-10-29 19:28 UTC (permalink / raw)
  To: Christian Biesinger, Luis Machado, Tom Tromey, gdb-patches

The original change was created by Christian Biesinger.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/222
......................................................................

Only make a nullterminated string if we need to

As of 7bb43059820c5febb4509b15202a93efde442bc6, we no longer need
a nullterminated linkage_name to look up the entry in the hash table.

So this patch makes it so we only make the copy if the entry was
not found.

By auditing all callers of symbol_set_names, I found out that all cases
where the string may not be nullterminated already pass true for COPY_NAME.
So here, I am documenting that as a requirement and am removing the code
that relies on undefined behavior in symbol_set_names (it accessed the string
past the provided length to check for nulltermination). Note that the Ada
case at the beginning of symbol_set_names was already relying on this.

gdb/ChangeLog:

2019-10-29  Christian Biesinger  <cbiesinger@google.com>

	* symtab.h (symbol_set_names): Document that copy_name must be
	set to true for non-nullterminated strings.
	* symtab.c (symbol_set_names): Only make a nullterminated copy of
	linkage_name if the entry was not found and we need to demangle.

Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
---
M gdb/ChangeLog
M gdb/symtab.c
M gdb/symtab.h
3 files changed, 28 insertions(+), 19 deletions(-)



diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c96b61a..1c4e47c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
 2019-10-29  Christian Biesinger  <cbiesinger@google.com>
 
+	* symtab.h (symbol_set_names): Document that copy_name must be
+	set to true for non-nullterminated strings.
+	* symtab.c (symbol_set_names): Only make a nullterminated copy of
+	linkage_name if the entry was not found and we need to demangle.
+
+2019-10-29  Christian Biesinger  <cbiesinger@google.com>
+
 	* Makefile.in (HFILES_NO_SRCDIR): Add gdb_binary_search.h.
 	* dwarf2-frame.c (bsearch_fde_cmp): Update.
 	(dwarf2_frame_find_fde): Replace bsearch with gdb::binary_search.
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 79c5fde..a6a9dc9 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -832,8 +832,6 @@
 		  struct objfile_per_bfd_storage *per_bfd)
 {
   struct demangled_name_entry **slot;
-  /* A 0-terminated copy of the linkage name.  */
-  const char *linkage_name_copy;
 
   if (gsymbol->language == language_ada)
     {
@@ -858,20 +856,7 @@
   if (per_bfd->demangled_names_hash == NULL)
     create_demangled_names_hash (per_bfd);
 
-  if (linkage_name[len] != '\0')
-    {
-      char *alloc_name;
-
-      alloc_name = (char *) alloca (len + 1);
-      memcpy (alloc_name, linkage_name, len);
-      alloc_name[len] = '\0';
-
-      linkage_name_copy = alloc_name;
-    }
-  else
-    linkage_name_copy = linkage_name;
-
-  struct demangled_name_entry entry (gdb::string_view (linkage_name_copy, len));
+  struct demangled_name_entry entry (gdb::string_view (linkage_name, len));
   slot = ((struct demangled_name_entry **)
 	  htab_find_slot (per_bfd->demangled_names_hash.get (),
 			  &entry, INSERT));
@@ -882,6 +867,21 @@
 	 This happens to, e.g., main.init (__go_init_main).  Cope.  */
       || (gsymbol->language == language_go && (*slot)->demangled == nullptr))
     {
+      /* A 0-terminated copy of the linkage name.  Callers must set COPY_NAME
+         to true if the string might not be nullterminated.  We have to make
+         this copy because demangling needs a nullterminated string.  */
+      const char *linkage_name_copy;
+      if (copy_name)
+	{
+	  char *alloc_name = (char *) alloca (len + 1);
+	  memcpy (alloc_name, linkage_name, len);
+	  alloc_name[len] = '\0';
+
+	  linkage_name_copy = alloc_name;
+	}
+      else
+	linkage_name_copy = linkage_name;
+
       gdb::unique_xmalloc_ptr<char> demangled_name_ptr
 	(symbol_find_demangled_name (gsymbol, linkage_name_copy));
 
@@ -894,7 +894,7 @@
 	 It turns out that it is actually important to still save such
 	 an entry in the hash table, because storing this name gives
 	 us better bcache hit rates for partial symbols.  */
-      if (!copy_name && linkage_name_copy == linkage_name)
+      if (!copy_name)
 	{
 	  *slot
 	    = ((struct demangled_name_entry *)
@@ -912,7 +912,8 @@
 	       obstack_alloc (&per_bfd->storage_obstack,
 			      sizeof (demangled_name_entry) + len + 1));
 	  char *mangled_ptr = reinterpret_cast<char *> (*slot + 1);
-	  strcpy (mangled_ptr, linkage_name_copy);
+	  memcpy (mangled_ptr, linkage_name, len);
+	  mangled_ptr [len] = '\0';
 	  new (*slot) demangled_name_entry
 	    (gdb::string_view (mangled_ptr, len));
 	}
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 5300383..131a74d 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -504,7 +504,8 @@
   (symbol)->ginfo.name = (linkage_name)
 
 /* Set the linkage and natural names of a symbol, by demangling
-   the linkage name.  */
+   the linkage name.  If linkage_name may not be nullterminated,
+   copy_name must be set to true.  */
 #define SYMBOL_SET_NAMES(symbol,linkage_name,len,copy_name,objfile)	\
   symbol_set_names (&(symbol)->ginfo, linkage_name, len, copy_name, \
 		    (objfile)->per_bfd)

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
Gerrit-Change-Number: 222
Gerrit-PatchSet: 5
Gerrit-Owner: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Luis Machado <luis.machado@linaro.org>
Gerrit-Reviewer: Tom Tromey <tromey@sourceware.org>
Gerrit-MessageType: newpatchset

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [pushed] Only make a nullterminated string if we need to
  2019-10-22 22:30 [review] Only make a nullterminated string if we need to Christian Biesinger (Code Review)
                   ` (7 preceding siblings ...)
  2019-10-29 19:28 ` [pushed] " Sourceware to Gerrit sync (Code Review)
@ 2019-10-29 19:28 ` Sourceware to Gerrit sync (Code Review)
  8 siblings, 0 replies; 10+ messages in thread
From: Sourceware to Gerrit sync (Code Review) @ 2019-10-29 19:28 UTC (permalink / raw)
  To: Christian Biesinger, gdb-patches; +Cc: Tom Tromey, Luis Machado

Sourceware to Gerrit sync has submitted this change.

Change URL: https://gnutoolchain-gerrit.osci.io/r/c/binutils-gdb/+/222
......................................................................

Only make a nullterminated string if we need to

As of 7bb43059820c5febb4509b15202a93efde442bc6, we no longer need
a nullterminated linkage_name to look up the entry in the hash table.

So this patch makes it so we only make the copy if the entry was
not found.

By auditing all callers of symbol_set_names, I found out that all cases
where the string may not be nullterminated already pass true for COPY_NAME.
So here, I am documenting that as a requirement and am removing the code
that relies on undefined behavior in symbol_set_names (it accessed the string
past the provided length to check for nulltermination). Note that the Ada
case at the beginning of symbol_set_names was already relying on this.

gdb/ChangeLog:

2019-10-29  Christian Biesinger  <cbiesinger@google.com>

	* symtab.h (symbol_set_names): Document that copy_name must be
	set to true for non-nullterminated strings.
	* symtab.c (symbol_set_names): Only make a nullterminated copy of
	linkage_name if the entry was not found and we need to demangle.

Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
---
M gdb/ChangeLog
M gdb/symtab.c
M gdb/symtab.h
3 files changed, 28 insertions(+), 19 deletions(-)


diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c96b61a..1c4e47c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
 2019-10-29  Christian Biesinger  <cbiesinger@google.com>
 
+	* symtab.h (symbol_set_names): Document that copy_name must be
+	set to true for non-nullterminated strings.
+	* symtab.c (symbol_set_names): Only make a nullterminated copy of
+	linkage_name if the entry was not found and we need to demangle.
+
+2019-10-29  Christian Biesinger  <cbiesinger@google.com>
+
 	* Makefile.in (HFILES_NO_SRCDIR): Add gdb_binary_search.h.
 	* dwarf2-frame.c (bsearch_fde_cmp): Update.
 	(dwarf2_frame_find_fde): Replace bsearch with gdb::binary_search.
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 79c5fde..a6a9dc9 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -832,8 +832,6 @@
 		  struct objfile_per_bfd_storage *per_bfd)
 {
   struct demangled_name_entry **slot;
-  /* A 0-terminated copy of the linkage name.  */
-  const char *linkage_name_copy;
 
   if (gsymbol->language == language_ada)
     {
@@ -858,20 +856,7 @@
   if (per_bfd->demangled_names_hash == NULL)
     create_demangled_names_hash (per_bfd);
 
-  if (linkage_name[len] != '\0')
-    {
-      char *alloc_name;
-
-      alloc_name = (char *) alloca (len + 1);
-      memcpy (alloc_name, linkage_name, len);
-      alloc_name[len] = '\0';
-
-      linkage_name_copy = alloc_name;
-    }
-  else
-    linkage_name_copy = linkage_name;
-
-  struct demangled_name_entry entry (gdb::string_view (linkage_name_copy, len));
+  struct demangled_name_entry entry (gdb::string_view (linkage_name, len));
   slot = ((struct demangled_name_entry **)
 	  htab_find_slot (per_bfd->demangled_names_hash.get (),
 			  &entry, INSERT));
@@ -882,6 +867,21 @@
 	 This happens to, e.g., main.init (__go_init_main).  Cope.  */
       || (gsymbol->language == language_go && (*slot)->demangled == nullptr))
     {
+      /* A 0-terminated copy of the linkage name.  Callers must set COPY_NAME
+         to true if the string might not be nullterminated.  We have to make
+         this copy because demangling needs a nullterminated string.  */
+      const char *linkage_name_copy;
+      if (copy_name)
+	{
+	  char *alloc_name = (char *) alloca (len + 1);
+	  memcpy (alloc_name, linkage_name, len);
+	  alloc_name[len] = '\0';
+
+	  linkage_name_copy = alloc_name;
+	}
+      else
+	linkage_name_copy = linkage_name;
+
       gdb::unique_xmalloc_ptr<char> demangled_name_ptr
 	(symbol_find_demangled_name (gsymbol, linkage_name_copy));
 
@@ -894,7 +894,7 @@
 	 It turns out that it is actually important to still save such
 	 an entry in the hash table, because storing this name gives
 	 us better bcache hit rates for partial symbols.  */
-      if (!copy_name && linkage_name_copy == linkage_name)
+      if (!copy_name)
 	{
 	  *slot
 	    = ((struct demangled_name_entry *)
@@ -912,7 +912,8 @@
 	       obstack_alloc (&per_bfd->storage_obstack,
 			      sizeof (demangled_name_entry) + len + 1));
 	  char *mangled_ptr = reinterpret_cast<char *> (*slot + 1);
-	  strcpy (mangled_ptr, linkage_name_copy);
+	  memcpy (mangled_ptr, linkage_name, len);
+	  mangled_ptr [len] = '\0';
 	  new (*slot) demangled_name_entry
 	    (gdb::string_view (mangled_ptr, len));
 	}
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 5300383..131a74d 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -504,7 +504,8 @@
   (symbol)->ginfo.name = (linkage_name)
 
 /* Set the linkage and natural names of a symbol, by demangling
-   the linkage name.  */
+   the linkage name.  If linkage_name may not be nullterminated,
+   copy_name must be set to true.  */
 #define SYMBOL_SET_NAMES(symbol,linkage_name,len,copy_name,objfile)	\
   symbol_set_names (&(symbol)->ginfo, linkage_name, len, copy_name, \
 		    (objfile)->per_bfd)

-- 
Gerrit-Project: binutils-gdb
Gerrit-Branch: master
Gerrit-Change-Id: I183302e1f51483ff6dff0fd5c3b0f32f0f04a5d2
Gerrit-Change-Number: 222
Gerrit-PatchSet: 5
Gerrit-Owner: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Christian Biesinger <cbiesinger@google.com>
Gerrit-Reviewer: Luis Machado <luis.machado@linaro.org>
Gerrit-Reviewer: Tom Tromey <tromey@sourceware.org>
Gerrit-MessageType: merged

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-10-29 19:28 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-22 22:30 [review] Only make a nullterminated string if we need to Christian Biesinger (Code Review)
2019-10-25 17:59 ` Tom Tromey (Code Review)
2019-10-25 18:04 ` Christian Biesinger (Code Review)
2019-10-25 20:02 ` [review v2] " Christian Biesinger (Code Review)
2019-10-25 20:08 ` Christian Biesinger (Code Review)
2019-10-28 18:51 ` [review v3] " Christian Biesinger (Code Review)
2019-10-28 19:01 ` [review v4] " Christian Biesinger (Code Review)
2019-10-29 19:10 ` Tom Tromey (Code Review)
2019-10-29 19:28 ` [pushed] " Sourceware to Gerrit sync (Code Review)
2019-10-29 19:28 ` Sourceware to Gerrit sync (Code Review)

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).