Fix elf_gnu_ifunc_resolve_by_got buglet
authorPedro Alves <palves@redhat.com>
Thu, 26 Apr 2018 12:01:26 +0000 (13:01 +0100)
committerPedro Alves <palves@redhat.com>
Thu, 26 Apr 2018 12:05:58 +0000 (13:05 +0100)
The next patch will add a call to elf_gnu_ifunc_resolve_by_got that
trips on a latent buglet -- the function is writing to its output
parameter even if the address wasn't found, confusing the caller.  The
function's intro comment says:

  /* Try to find the target resolved function entry address of a STT_GNU_IFUNC
     function NAME.  If the address is found it is stored to *ADDR_P (if ADDR_P
     is not NULL) and the function returns 1.  It returns 0 otherwise.

So fix the function accordingly.

gdb/ChangeLog:
2018-04-26  Pedro Alves  <palves@redhat.com>

* elfread.c (elf_gnu_ifunc_resolve_by_got): Don't write to *ADDR_P
unless we actually resolved the ifunc.

gdb/ChangeLog
gdb/elfread.c

index 67e1bab..9de1b10 100644 (file)
@@ -1,5 +1,10 @@
 2018-04-26  Pedro Alves  <palves@redhat.com>
 
+       * elfread.c (elf_gnu_ifunc_resolve_by_got): Don't write to *ADDR_P
+       unless we actually resolved the ifunc.
+
+2018-04-26  Pedro Alves  <palves@redhat.com>
+
        * c-exp.y (variable production): Prefer ifunc minsyms over
        regular function symbols.
        * symtab.c (find_gnu_ifunc): New function.
index 16a692d..42a2c92 100644 (file)
@@ -833,10 +833,12 @@ elf_gnu_ifunc_resolve_by_got (const char *name, CORE_ADDR *addr_p)
                                                 &current_target);
       addr = gdbarch_addr_bits_remove (gdbarch, addr);
 
-      if (addr_p)
-       *addr_p = addr;
       if (elf_gnu_ifunc_record_cache (name, addr))
-       return 1;
+       {
+         if (addr_p != NULL)
+           *addr_p = addr;
+         return 1;
+       }
     }
 
   return 0;