bfd: Fix warning when compiling with clang, fix buglet

Message ID 1517353359-6550-1-git-send-email-simon.marchi@ericsson.com
State New
Headers show
Series
  • bfd: Fix warning when compiling with clang, fix buglet
Related show

Commit Message

Simon Marchi Jan. 30, 2018, 11:02 p.m.
I would like to fix instances of the following warning, when building
with clang with no special CFLAGS other than -g3 -O0.

/home/emaisin/src/binutils-gdb/bfd/elflink.c:5425:45: error: performing pointer arithmetic on a null pointer has undefined behavior [-Werror,-Wnull-pointer-arithmetic]
    return (struct elf_link_hash_entry *) 0 - 1;
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^

Replacing those with "(struct elf_link_hash_entry *) -1" gets rid of the
warning.  I wanted to check that it didn't change the resulting code, so
I tried to build this:

  $ cat test.c
  int *before()
  {
          return (int *) 0 - 1;
  }

  int *after()
  {
          return (int *) - 1;
  }

  $ gcc -c test.c -g
  $ objdump -d test.o

  test.o:     file format elf64-x86-64

  Disassembly of section .text:

  0000000000000000 <before>:
     0:   55                      push   %rbp
     1:   48 89 e5                mov    %rsp,%rbp
     4:   48 c7 c0 fc ff ff ff    mov    $0xfffffffffffffffc,%rax
     b:   5d                      pop    %rbp
     c:   c3                      retq

  000000000000000d <after>:
     d:   55                      push   %rbp
     e:   48 89 e5                mov    %rsp,%rbp
    11:   48 c7 c0 ff ff ff ff    mov    $0xffffffffffffffff,%rax
    18:   5d                      pop    %rbp
    19:   c3                      retq

This shows that the previous code doesn't actually return -1 as the
function documentation says, but the new one does, so it's kind of a
bugfix.

bfd/ChangeLog:

	* elf64-ppc.c (ppc64_elf_archive_symbol_lookup): Remove pointer
	arithmetic on NULL pointer.
	* elflink.c (_bfd_elf_archive_symbol_lookup,
	elf_link_add_archive_symbols): Likewise.
---
 bfd/elf64-ppc.c | 2 +-
 bfd/elflink.c   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

-- 
2.7.4

Comments

Alan Modra Jan. 31, 2018, 8:13 a.m. | #1
On Tue, Jan 30, 2018 at 06:02:39PM -0500, Simon Marchi wrote:
> 	* elf64-ppc.c (ppc64_elf_archive_symbol_lookup): Remove pointer

> 	arithmetic on NULL pointer.

> 	* elflink.c (_bfd_elf_archive_symbol_lookup,

> 	elf_link_add_archive_symbols): Likewise.


OK.

-- 
Alan Modra
Australia Development Lab, IBM
Simon Marchi Jan. 31, 2018, 1:44 p.m. | #2
On 2018-01-31 03:13 AM, Alan Modra wrote:
> On Tue, Jan 30, 2018 at 06:02:39PM -0500, Simon Marchi wrote:

>> 	* elf64-ppc.c (ppc64_elf_archive_symbol_lookup): Remove pointer

>> 	arithmetic on NULL pointer.

>> 	* elflink.c (_bfd_elf_archive_symbol_lookup,

>> 	elf_link_add_archive_symbols): Likewise.

> 

> OK.


I spotted another instance of it in ld (I am not building ld usually
in my development cycle).  Here's an updated patch.


From e2a35510043ba09129f59c05c6d9597531c0abbe Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@ericsson.com>

Date: Wed, 31 Jan 2018 08:23:32 -0500
Subject: [PATCH] bfd/ld: Fix warning when compiling with clang, fix buglet

I would like to fix instances of the following warning, when building
with clang with no special CFLAGS other than -g3 -O0.

/home/emaisin/src/binutils-gdb/bfd/elflink.c:5425:45: error: performing pointer arithmetic on a null pointer has undefined behavior [-Werror,-Wnull-pointer-arithmetic]
    return (struct elf_link_hash_entry *) 0 - 1;
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^

Replacing those with "(struct elf_link_hash_entry *) -1" gets rid of the
warning.  I wanted to check that it didn't change the resulting code, so
I tried to build this:

  $ cat test.c
  int *before()
  {
          return (int *) 0 - 1;
  }

  int *after()
  {
          return (int *) - 1;
  }

  $ gcc -c test.c -g
  $ objdump -d test.o

  test.o:     file format elf64-x86-64

  Disassembly of section .text:

  0000000000000000 <before>:
     0:   55                      push   %rbp
     1:   48 89 e5                mov    %rsp,%rbp
     4:   48 c7 c0 fc ff ff ff    mov    $0xfffffffffffffffc,%rax
     b:   5d                      pop    %rbp
     c:   c3                      retq

  000000000000000d <after>:
     d:   55                      push   %rbp
     e:   48 89 e5                mov    %rsp,%rbp
    11:   48 c7 c0 ff ff ff ff    mov    $0xffffffffffffffff,%rax
    18:   5d                      pop    %rbp
    19:   c3                      retq

This shows that the previous code doesn't actually return -1 as the
function documentation says, but the new one does, so it's kind of a
bugfix.

bfd/ChangeLog:

	* elf64-ppc.c (ppc64_elf_archive_symbol_lookup): Avoid pointer
	arithmetic on NULL pointer.
	* elflink.c (_bfd_elf_archive_symbol_lookup,
	elf_link_add_archive_symbols): Likewise.

ld/ChangeLog:

	* ldexp.c (fold_name, exp_fold_tree_1): Avoid pointer arithmetic
	on NULL pointer.
---
 bfd/elf64-ppc.c | 2 +-
 bfd/elflink.c   | 4 ++--
 ld/ldexp.c      | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 5cbb035..9e4a4b5 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -5051,7 +5051,7 @@ ppc64_elf_archive_symbol_lookup (bfd *abfd,
   len = strlen (name);
   dot_name = bfd_alloc (abfd, len + 2);
   if (dot_name == NULL)
-    return (struct elf_link_hash_entry *) 0 - 1;
+    return (struct elf_link_hash_entry *) -1;
   dot_name[0] = '.';
   memcpy (dot_name + 1, name, len + 1);
   h = _bfd_elf_archive_symbol_lookup (abfd, info, dot_name);
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 3787c85..e891424 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -5422,7 +5422,7 @@ _bfd_elf_archive_symbol_lookup (bfd *abfd,
   len = strlen (name);
   copy = (char *) bfd_alloc (abfd, len);
   if (copy == NULL)
-    return (struct elf_link_hash_entry *) 0 - 1;
+    return (struct elf_link_hash_entry *) -1;

   first = p - name + 1;
   memcpy (copy, name, first);
@@ -5520,7 +5520,7 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
 	    }

 	  h = archive_symbol_lookup (abfd, info, symdef->name);
-	  if (h == (struct elf_link_hash_entry *) 0 - 1)
+	  if (h == (struct elf_link_hash_entry *) -1)
 	    goto error_return;

 	  if (h == NULL)
diff --git a/ld/ldexp.c b/ld/ldexp.c
index a097205..8cb3df9 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -782,7 +782,7 @@ fold_name (etree_type *tree)
 	  if (expld.assign_src == NULL)
 	    expld.assign_src = h;
 	  else
-	    expld.assign_src = (struct bfd_link_hash_entry *) 0 - 1;
+	    expld.assign_src = (struct bfd_link_hash_entry *) -1;
 	}
       break;

@@ -1207,7 +1207,7 @@ exp_fold_tree_1 (etree_type *tree)
 		     false branches.)  */
 		  if (expld.assign_src != NULL
 		      && (expld.assign_src
-			  != (struct bfd_link_hash_entry *) 0 - 1))
+			  != (struct bfd_link_hash_entry *) -1))
 		    bfd_copy_link_hash_symbol_type (link_info.output_bfd, h,
 						    expld.assign_src);
 		}
-- 
2.7.4
Nick Clifton Feb. 1, 2018, 1:24 p.m. | #3
Hi Simon,

> bfd/ChangeLog:

> 

> 	* elf64-ppc.c (ppc64_elf_archive_symbol_lookup): Avoid pointer

> 	arithmetic on NULL pointer.

> 	* elflink.c (_bfd_elf_archive_symbol_lookup,

> 	elf_link_add_archive_symbols): Likewise.

> 

> ld/ChangeLog:

> 

> 	* ldexp.c (fold_name, exp_fold_tree_1): Avoid pointer arithmetic

> 	on NULL pointer.


I have applied your revised patch.

Cheers
  Nick
Simon Marchi Feb. 1, 2018, 8:56 p.m. | #4
On 2018-02-01 08:24 AM, Nick Clifton wrote:
> Hi Simon,

> 

>> bfd/ChangeLog:

>>

>> 	* elf64-ppc.c (ppc64_elf_archive_symbol_lookup): Avoid pointer

>> 	arithmetic on NULL pointer.

>> 	* elflink.c (_bfd_elf_archive_symbol_lookup,

>> 	elf_link_add_archive_symbols): Likewise.

>>

>> ld/ChangeLog:

>>

>> 	* ldexp.c (fold_name, exp_fold_tree_1): Avoid pointer arithmetic

>> 	on NULL pointer.

> 

> I have applied your revised patch.

> 

> Cheers

>   Nick

> 


Thanks!

Patch

diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 5cbb035..9e4a4b5 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -5051,7 +5051,7 @@  ppc64_elf_archive_symbol_lookup (bfd *abfd,
   len = strlen (name);
   dot_name = bfd_alloc (abfd, len + 2);
   if (dot_name == NULL)
-    return (struct elf_link_hash_entry *) 0 - 1;
+    return (struct elf_link_hash_entry *) -1;
   dot_name[0] = '.';
   memcpy (dot_name + 1, name, len + 1);
   h = _bfd_elf_archive_symbol_lookup (abfd, info, dot_name);
diff --git a/bfd/elflink.c b/bfd/elflink.c
index f1ec880..1de8e78 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -5422,7 +5422,7 @@  _bfd_elf_archive_symbol_lookup (bfd *abfd,
   len = strlen (name);
   copy = (char *) bfd_alloc (abfd, len);
   if (copy == NULL)
-    return (struct elf_link_hash_entry *) 0 - 1;
+    return (struct elf_link_hash_entry *) -1;
 
   first = p - name + 1;
   memcpy (copy, name, first);
@@ -5520,7 +5520,7 @@  elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
 	    }
 
 	  h = archive_symbol_lookup (abfd, info, symdef->name);
-	  if (h == (struct elf_link_hash_entry *) 0 - 1)
+	  if (h == (struct elf_link_hash_entry *) -1)
 	    goto error_return;
 
 	  if (h == NULL)