libbacktrace patch committed: Use __has_attribute for fallthrough

2024-07-18 Thread Ian Lance Taylor
This libbacktrace patch uses __has_attribute for fallthrough.  It also
fixes some FALLTHROUGH comments to use ATTRIBUTE_FALLTHROUGH.
Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

Ian

* internal.h: Use __has_attribute to check for fallthrough
attribute.
* elf.c (elf_zstd_decompress): Use ATTRIBUTE_FALLTHROUGH rather
than a FALLTHROUGH comment.
58b219d3cf69a0464d3c74d43e4cc24117e64647
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index e8d67feab6d..0040479143d 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -4848,25 +4848,25 @@ elf_zstd_decompress (const unsigned char *pin, size_t 
sin,
  {
  case 8:
*pout++ = *plit++;
-   /* FALLTHROUGH */
+   ATTRIBUTE_FALLTHROUGH;
  case 7:
*pout++ = *plit++;
-   /* FALLTHROUGH */
+   ATTRIBUTE_FALLTHROUGH;
  case 6:
*pout++ = *plit++;
-   /* FALLTHROUGH */
+   ATTRIBUTE_FALLTHROUGH;
  case 5:
*pout++ = *plit++;
-   /* FALLTHROUGH */
+   ATTRIBUTE_FALLTHROUGH;
  case 4:
*pout++ = *plit++;
-   /* FALLTHROUGH */
+   ATTRIBUTE_FALLTHROUGH;
  case 3:
*pout++ = *plit++;
-   /* FALLTHROUGH */
+   ATTRIBUTE_FALLTHROUGH;
  case 2:
*pout++ = *plit++;
-   /* FALLTHROUGH */
+   ATTRIBUTE_FALLTHROUGH;
  case 1:
*pout++ = *plit++;
break;
diff --git a/libbacktrace/internal.h b/libbacktrace/internal.h
index a119cda692f..fe2abe50b0f 100644
--- a/libbacktrace/internal.h
+++ b/libbacktrace/internal.h
@@ -56,6 +56,11 @@ POSSIBILITY OF SUCH DAMAGE.  */
 # endif
 #endif
 
+#ifdef __has_attribute
+# if __has_attribute(fallthrough)
+#  define ATTRIBUTE_FALLTHROUGH __attribute__ ((fallthrough))
+# endif
+#endif
 #ifndef ATTRIBUTE_FALLTHROUGH
 # if (GCC_VERSION >= 7000)
 #  define ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__))


Re: libbacktrace patch committed: Better backtrace_print if no debug info

2024-07-17 Thread Ian Lance Taylor
On Wed, Jul 17, 2024 at 5:40 PM Ian Lance Taylor  wrote:
>
> This libbacktrace patch improves backtrace_print when there is no
> debug info.  It falls back to calling backtrace_syminfo, and uses that
> to print an offset from a symbol if it can.  This is a partial fix for
> https://github.com/ianlancetaylor/libbacktrace/issues/59.
> Bootstrapped and ran libbacktrace testsuite on x86_64-pc-linux-gnu.
> Committed to mainline.

And this patch corrects a bug in that patch.

Ian
c7c8bcdbb412c71c9522f7874d43a3bd9319b940
diff --git a/libbacktrace/print.c b/libbacktrace/print.c
index 70f5a93c49d..d4637af9a4f 100644
--- a/libbacktrace/print.c
+++ b/libbacktrace/print.c
@@ -77,7 +77,7 @@ static void print_syminfo_callback (void *data, uintptr_t pc,
 fprintf (pdata->f, "0x%lx ???\n\t%s+0x%lx:0\n",
 (unsigned long) pc,
 symname,
-pc - symval);
+(unsigned long) (pc - symval));
 }
 
 /* Print one level of a backtrace.  */


libbacktrace patch committed: Better backtrace_print if no debug info

2024-07-17 Thread Ian Lance Taylor
This libbacktrace patch improves backtrace_print when there is no
debug info.  It falls back to calling backtrace_syminfo, and uses that
to print an offset from a symbol if it can.  This is a partial fix for
https://github.com/ianlancetaylor/libbacktrace/issues/59.
Bootstrapped and ran libbacktrace testsuite on x86_64-pc-linux-gnu.
Committed to mainline.

Ian

* print.c (print_syminfo_callback): New static function.
(print_callback): Call backtrace_syminfo if there is no function
or file name.
4dbb53eb10767d111228224ae3113aee0d4d6213
diff --git a/libbacktrace/print.c b/libbacktrace/print.c
index 3e61f02ebbc..70f5a93c49d 100644
--- a/libbacktrace/print.c
+++ b/libbacktrace/print.c
@@ -47,6 +47,39 @@ struct print_data
   FILE *f;
 };
 
+/* Print errors to stderr.  */
+
+static void
+error_callback (void *data, const char *msg, int errnum)
+{
+  struct print_data *pdata = (struct print_data *) data;
+
+  if (pdata->state->filename != NULL)
+fprintf (stderr, "%s: ", pdata->state->filename);
+  fprintf (stderr, "libbacktrace: %s", msg);
+  if (errnum > 0)
+fprintf (stderr, ": %s", strerror (errnum));
+  fputc ('\n', stderr);
+}
+
+/* Print one level of a backtrace if we couldn't get a file or function name.
+   Use syminfo to try to get a symbol name.  */
+
+static void print_syminfo_callback (void *data, uintptr_t pc,
+   const char *symname, uintptr_t symval,
+   uintptr_t symsize ATTRIBUTE_UNUSED)
+{
+  struct print_data *pdata = (struct print_data *) data;
+
+  if (symname == NULL)
+fprintf (pdata->f, "0x%lx ???\n\t???:0\n", (unsigned long) pc);
+  else
+fprintf (pdata->f, "0x%lx ???\n\t%s+0x%lx:0\n",
+(unsigned long) pc,
+symname,
+pc - symval);
+}
+
 /* Print one level of a backtrace.  */
 
 static int
@@ -55,6 +88,13 @@ print_callback (void *data, uintptr_t pc, const char 
*filename, int lineno,
 {
   struct print_data *pdata = (struct print_data *) data;
 
+  if (function == NULL && filename == NULL)
+{
+  backtrace_syminfo (pdata->state, pc, print_syminfo_callback,
+error_callback, data);
+  return 0;
+}
+
   fprintf (pdata->f, "0x%lx %s\n\t%s:%d\n",
   (unsigned long) pc,
   function == NULL ? "???" : function,
@@ -63,21 +103,6 @@ print_callback (void *data, uintptr_t pc, const char 
*filename, int lineno,
   return 0;
 }
 
-/* Print errors to stderr.  */
-
-static void
-error_callback (void *data, const char *msg, int errnum)
-{
-  struct print_data *pdata = (struct print_data *) data;
-
-  if (pdata->state->filename != NULL)
-fprintf (stderr, "%s: ", pdata->state->filename);
-  fprintf (stderr, "libbacktrace: %s", msg);
-  if (errnum > 0)
-fprintf (stderr, ": %s", strerror (errnum));
-  fputc ('\n', stderr);
-}
-
 /* Print a backtrace.  */
 
 void __attribute__((noinline))


libbacktrace patch committed: Mention dl_iterate_phdr in README

2024-07-17 Thread Ian Lance Taylor
This patch adds some notes about dl_iterate_phdr to the libbacktrace
README file.  In general dl_iterate_phdr is not async-signal-safe and
does call malloc, so programs that want to use libbacktrace functions
from a signal handler or within malloc must make an initiali
libbacktrace call in order to call dl_iterate_phdr.  Committed to
mainline.

Ian

* README: Add notes about dl_iterate_phdr.
14667f4cc51b6c59cf9e6c05f3bcac17df94ef10
diff --git a/libbacktrace/README b/libbacktrace/README
index 6225f92b855..6e6ec332fe2 100644
--- a/libbacktrace/README
+++ b/libbacktrace/README
@@ -5,8 +5,18 @@ The libbacktrace library may be linked into a program or 
library and
 used to produce symbolic backtraces.
 Sample uses would be to print a detailed backtrace when an error
 occurs or to gather detailed profiling information.
+
 In general the functions provided by this library are async-signal-safe,
 meaning that they may be safely called from a signal handler.
+That said, on systems that use dl_iterate_phdr, such as GNU/Linux,
+the first call to a libbacktrace function will call dl_iterate_phdr,
+which is not in general async-signal-safe.  Therefore, programs
+that call libbacktrace from a signal handler should ensure that they
+make an initial call from outside of a signal handler.
+Similar considerations apply when arranging to call libbacktrace
+from within malloc; dl_iterate_phdr can also call malloc,
+so make an initial call to a libbacktrace function outside of
+malloc before trying to call libbacktrace functions within malloc.
 
 The libbacktrace library is provided under a BSD license.
 See the source files for the exact license text.
@@ -20,7 +30,7 @@ will work.
 See the source file backtrace-supported.h.in for the macros that it
 defines.
 
-As of October 2020, libbacktrace supports ELF, PE/COFF, Mach-O, and
+As of July 2024, libbacktrace supports ELF, PE/COFF, Mach-O, and
 XCOFF executables with DWARF debugging information.
 In other words, it supports GNU/Linux, *BSD, macOS, Windows, and AIX.
 The library is written to make it straightforward to add support for


libbacktrace patch committed: Avoid infinite recursion

2024-07-11 Thread Ian Lance Taylor
libbacktrace could get an infinite recursion in an odd case in which a
.gnu_debugdata section was added to a debug file, and mini_debuginfo
was put into the debug file, and the debug file was put into a
/usr/lib/debug directory to be found by build ID.  This combination
doesn't really make sense but we shouldn't get an infinite recursion.
This patch fixes the problem.  Bootstrapped and ran libbacktrace tests
on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* elf.c (elf_add): Don't use .gnu_debugdata if we are already
reading a debuginfo file.
* Makefile.am (m2test_*): New test targets.
(CHECK_PROGRAMS): Add m2test.
(MAKETESTS): Add m2test_minidebug2.
(%_minidebug2): New pattern.
(CLEANFILES): Remove minidebug2 files.
* Makefile.in: Regenerate.
8a3a34665210105a89b14f380c3bec780c209046
diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am
index bed42c29329..8215cfd9bd5 100644
--- a/libbacktrace/Makefile.am
+++ b/libbacktrace/Makefile.am
@@ -594,6 +594,39 @@ MAKETESTS += mtest_minidebug
$(OBJCOPY) --add-section .gnu_debugdata=$<.mdbg.xz $<.strip
mv $<.strip $@
 
+if HAVE_ELF
+if HAVE_BUILDID
+if HAVE_OBJCOPY_DEBUGLINK
+
+m2test_SOURCES = $(mtest_SOURCES)
+m2test_CFLAGS = $(libbacktrace_TEST_CFLAGS) -O
+m2test_LDFLAGS = -Wl,--build-id $(libbacktrace_testing_ldflags)
+m2test_LDADD = libbacktrace_elf_for_test.la
+
+check_PROGRAMS += m2test
+MAKETESTS += m2test_minidebug2
+
+# minidebug2 is like minidebug but also adds the gnu_debugdata section
+# to the debug file, and uses a build ID file.  There is no reason to do
+# this but it was causing an infinite recursion.
+%_minidebug2: %
+   $(NM) -D $< -P --defined-only | $(AWK) '{ print $$1 }' | sort > 
$<.dsyms2
+   $(NM) $< -P --defined-only | $(AWK) '{ if ($$2 == "T" || $$2 == "t" || 
$$2 == "D") print $$1 }' | sort > $<.fsyms2
+   $(COMM) -13 $<.dsyms2 $<.fsyms2 > $<.keepsyms2
+   $(OBJCOPY) --only-keep-debug $< $<.dbg2
+   $(OBJCOPY) -S --remove-section .gdb_index --remove-section .comment 
--keep-symbols=$<.keepsyms2 $<.dbg2 $<.mdbg2
+   $(OBJCOPY) --strip-all --remove-section ..comment $< $<.strip2
+   rm -f $<.mdbg2.xz
+   $(XZ) $<.mdbg2
+   $(OBJCOPY) --add-section .gnu_debugdata=$<.mdbg2.xz $<.dbg2
+   $(OBJCOPY) --add-section .gnu_debugdata=$<.mdbg2.xz $<.strip2
+   $(SHELL) ./install-debuginfo-for-buildid.sh $(TEST_BUILD_ID_DIR) $<.dbg2
+   mv $<.strip2 $@
+
+endif HAVE_OBJCOPY_DEBUGLINK
+endif HAVE_BUILDID
+endif HAVE_ELF
+
 endif HAVE_MINIDEBUG
 
 endif NATIVE
@@ -629,7 +662,8 @@ TESTS += $(MAKETESTS) $(BUILDTESTS)
 CLEANFILES = \
$(MAKETESTS) $(BUILDTESTS) *.debug elf_for_test.c edtest2_build.c \
gen_edtest2_build \
-   *.dsyms *.fsyms *.keepsyms *.dbg *.mdbg *.mdbg.xz *.strip
+   *.dsyms *.fsyms *.keepsyms *.dbg *.mdbg *.mdbg.xz *.strip \
+   *.dsyms2 *.fsyms2 *.keepsyms2 *.dbg2 *.mdbg2 *.mdbg2.xz *.strip2
 
 clean-local:
-rm -rf usr
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index e6a66c0db90..107c96892a0 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -6841,7 +6841,8 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
}
}
 
-  if (!gnu_debugdata_view_valid
+  if (!debuginfo
+ && !gnu_debugdata_view_valid
  && strcmp (name, ".gnu_debugdata") == 0)
{
  if (!elf_get_view (state, descriptor, memory, memory_size,


libbacktrace patch committed: Don't fail if symbol size is unknown

2024-07-11 Thread Ian Lance Taylor
Mach-O and PE/COFF don't record symbol sizes in the symbol table.
Adjust the libbacktrace testsuite so that it doesn't fail if the
symbol size is unknown, only if it is incorrect.  Ran libbacktrace
tests on macOS on the compile farm and on x86_64-pc-linux-gnu.
Committed to mainline.

Ian

* btest.c (test5): Don't fail if symbol size is 0.
* mtest.c (test5): Likewise.
d7318f4cf89c2a934fcd1f87d711081285fad242
diff --git a/libbacktrace/btest.c b/libbacktrace/btest.c
index c4b2db2cce2..3b603f643fa 100644
--- a/libbacktrace/btest.c
+++ b/libbacktrace/btest.c
@@ -440,7 +440,7 @@ test5 (void)
   (unsigned long) (uintptr_t) );
  symdata.failed = 1;
}
-  else if (symdata.size != sizeof (global))
+  else if (symdata.size != sizeof (global) && symdata.size != 0)
{
  fprintf (stderr,
   "test5: unexpected syminfo size got %lx expected %lx\n",
diff --git a/libbacktrace/mtest.c b/libbacktrace/mtest.c
index f793391653d..5ec43c7bbce 100644
--- a/libbacktrace/mtest.c
+++ b/libbacktrace/mtest.c
@@ -373,7 +373,7 @@ test5 (void)
   (unsigned long) (uintptr_t) );
  symdata.failed = 1;
}
-  else if (symdata.size != sizeof (global))
+  else if (symdata.size != sizeof (global) && symdata.size != 0)
{
  fprintf (stderr,
   "test5: unexpected syminfo size got %lx expected %lx\n",


libbacktrace patch committed: Correctly gather Mach-O symbols

2024-07-11 Thread Ian Lance Taylor
The libbacktrace symbol table code was incorrectly discarding global
Mach-O symbols.  This patch fixes the problem.  Tested on macOS on the
compile farm, and also on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

For PR libbacktrace/97082
* macho.c (MACH_O_N_EXT): Don't define.
(MACH_O_N_UNDF): Define.
(macho_defined_symbol): Don't discard N_EXT symbols.  Do
discard N_UNDF symbols.
af827b2ab90b9d726c7182c41fa2409005909db8
diff --git a/libbacktrace/macho.c b/libbacktrace/macho.c
index 5ceff05b29a..8f768f14a57 100644
--- a/libbacktrace/macho.c
+++ b/libbacktrace/macho.c
@@ -271,12 +271,14 @@ struct macho_nlist_64
 
 /* Value found in nlist n_type field.  */
 
-#define MACH_O_N_EXT   0x01/* Extern symbol */
+#define MACH_O_N_STAB  0xe0/* Stabs debugging symbol */
+#define MACH_O_N_TYPE  0x0e/* Mask for type bits */
+
+/* Values found after masking with MACH_O_N_TYPE.  */
+#define MACH_O_N_UNDF  0x00/* Undefined symbol */
 #define MACH_O_N_ABS   0x02/* Absolute symbol */
-#define MACH_O_N_SECT  0x0e/* Defined in section */
+#define MACH_O_N_SECT  0x0e/* Defined in section from n_sect field */
 
-#define MACH_O_N_TYPE  0x0e/* Mask for type bits */
-#define MACH_O_N_STAB  0xe0/* Stabs debugging symbol */
 
 /* Information we keep for a Mach-O symbol.  */
 
@@ -492,10 +494,10 @@ macho_defined_symbol (uint8_t type)
 {
   if ((type & MACH_O_N_STAB) != 0)
 return 0;
-  if ((type & MACH_O_N_EXT) != 0)
-return 0;
   switch (type & MACH_O_N_TYPE)
 {
+case MACH_O_N_UNDF:
+  return 0;
 case MACH_O_N_ABS:
   return 1;
 case MACH_O_N_SECT:


Re: libbacktrace patch committed: Add clang optnone attribute

2024-07-11 Thread Eric Gallager
On Thu, Jul 11, 2024 at 7:19 PM Andrew Pinski  wrote:
>
> On Thu, Jul 11, 2024 at 4:14 PM Ian Lance Taylor  wrote:
> >
> > The libbacktrace testsuite was not passing when run with current
> > versions of clang.  Add the optnone attribute to make it pass.  Add
> > -Wno-attributes and -Wno-unknown-attributes to disable warnings about
> > unrecognized function attributes.  Bootstrapped and ran libbacktrace
> > testsuite on x86_64-pc-linux-gnu.  Committed to mainline.
>
> NoteI see they have `noclone` and `noinline`, maybe it should have
> `noipa` on them too. noipa disables a few more things than
> noclone/noinline that might make a difference too.
>

Yeah, I was thinking of that, too, perhaps wrapped in a macro like:

#if __has_attribute(optnone)
# define ATTR_NOOPTS __attribute__ ((noinline, noclone, optnone, unused))
#else
# if __has_attribute(noipa)
#  define ATTR_NOOPTS __attribute__ ((noipa, unused))
# else
#  define ATTR_NOOPTS __attribute__ ((noinline, noclone, unused))
# endif /* noipa */
#endif /* optnone */

...and then use that macro in the relevant places. That way it
wouldn't be necessary to turn off the warnings from -Wno-attributes
and -Wno-unknown-attributes.

> Thanks,
> Andrew Pinski
>
> >
> > Ian
> >
> > * btest.c (test1, test3): Add optnone attribute.
> > * edtest.c (test1): Likewise.
> > * mtest.c (test1, test3): Likewise.
> > * configure.ac: Use -Wno-attributes and -Wno-unknown-attributes.
> > * configure: Regenerate.


Re: libbacktrace patch committed: Add clang optnone attribute

2024-07-11 Thread Ian Lance Taylor
On Thu, Jul 11, 2024 at 4:18 PM Andrew Pinski  wrote:
>
> On Thu, Jul 11, 2024 at 4:14 PM Ian Lance Taylor  wrote:
> >
> > The libbacktrace testsuite was not passing when run with current
> > versions of clang.  Add the optnone attribute to make it pass.  Add
> > -Wno-attributes and -Wno-unknown-attributes to disable warnings about
> > unrecognized function attributes.  Bootstrapped and ran libbacktrace
> > testsuite on x86_64-pc-linux-gnu.  Committed to mainline.
>
> NoteI see they have `noclone` and `noinline`, maybe it should have
> `noipa` on them too. noipa disables a few more things than
> noclone/noinline that might make a difference too.

Thanks, I looked into that, and as far as I can tell for purposes of
the libbacktrace testsuite it doesn't matter.  All that matters here
is that the function isn't inlined, so that it shows up in the call
stack.  It's OK if the compiler makes other deductions about what the
function does.  And indeed the tests are passing.  Of course we can
change the testsuite again if I'm mistaken.

Ian


Re: libbacktrace patch committed: Add clang optnone attribute

2024-07-11 Thread Andrew Pinski
On Thu, Jul 11, 2024 at 4:14 PM Ian Lance Taylor  wrote:
>
> The libbacktrace testsuite was not passing when run with current
> versions of clang.  Add the optnone attribute to make it pass.  Add
> -Wno-attributes and -Wno-unknown-attributes to disable warnings about
> unrecognized function attributes.  Bootstrapped and ran libbacktrace
> testsuite on x86_64-pc-linux-gnu.  Committed to mainline.

NoteI see they have `noclone` and `noinline`, maybe it should have
`noipa` on them too. noipa disables a few more things than
noclone/noinline that might make a difference too.

Thanks,
Andrew Pinski

>
> Ian
>
> * btest.c (test1, test3): Add optnone attribute.
> * edtest.c (test1): Likewise.
> * mtest.c (test1, test3): Likewise.
> * configure.ac: Use -Wno-attributes and -Wno-unknown-attributes.
> * configure: Regenerate.


libbacktrace patch committed: Add clang optnone attribute

2024-07-11 Thread Ian Lance Taylor
The libbacktrace testsuite was not passing when run with current
versions of clang.  Add the optnone attribute to make it pass.  Add
-Wno-attributes and -Wno-unknown-attributes to disable warnings about
unrecognized function attributes.  Bootstrapped and ran libbacktrace
testsuite on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* btest.c (test1, test3): Add optnone attribute.
* edtest.c (test1): Likewise.
* mtest.c (test1, test3): Likewise.
* configure.ac: Use -Wno-attributes and -Wno-unknown-attributes.
* configure: Regenerate.
67130485e51fb4391908dc8beb7259623a94fbd6
diff --git a/libbacktrace/btest.c b/libbacktrace/btest.c
index d9fc372d33d..c4b2db2cce2 100644
--- a/libbacktrace/btest.c
+++ b/libbacktrace/btest.c
@@ -49,7 +49,7 @@ POSSIBILITY OF SUCH DAMAGE.  */
 
 /* Test the backtrace function with non-inlined functions.  */
 
-static int test1 (void) __attribute__ ((noinline, noclone, unused));
+static int test1 (void) __attribute__ ((noinline, noclone, optnone, unused));
 static int f2 (int) __attribute__ ((noinline, noclone));
 static int f3 (int, int) __attribute__ ((noinline, noclone));
 
@@ -163,7 +163,7 @@ f13 (int f1line, int f2line)
 
 /* Test the backtrace_simple function with non-inlined functions.  */
 
-static int test3 (void) __attribute__ ((noinline, noclone, unused));
+static int test3 (void) __attribute__ ((noinline, noclone, optnone, unused));
 static int f22 (int) __attribute__ ((noinline, noclone));
 static int f23 (int, int) __attribute__ ((noinline, noclone));
 
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 59e9c415db8..bfd7f35d2d2 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -144,7 +144,8 @@ AC_SUBST(EXTRA_FLAGS)
 
 ACX_PROG_CC_WARNING_OPTS([-W -Wall -Wwrite-strings -Wstrict-prototypes \
  -Wmissing-prototypes -Wold-style-definition \
- -Wmissing-format-attribute -Wcast-qual],
+ -Wmissing-format-attribute -Wcast-qual \
+ -Wno-attributes -Wno-unknown-attributes],
  [WARN_FLAGS])
 
 AC_ARG_ENABLE([werror],
diff --git a/libbacktrace/edtest.c b/libbacktrace/edtest.c
index d99b8a60295..b644d93788c 100644
--- a/libbacktrace/edtest.c
+++ b/libbacktrace/edtest.c
@@ -43,7 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.  */
 
 #include "testlib.h"
 
-static int test1 (void) __attribute__ ((noinline, noclone, unused));
+static int test1 (void) __attribute__ ((noinline, noclone, optnone, unused));
 extern int f2 (int);
 extern int f3 (int, int);
 
diff --git a/libbacktrace/mtest.c b/libbacktrace/mtest.c
index 9afe7089514..f793391653d 100644
--- a/libbacktrace/mtest.c
+++ b/libbacktrace/mtest.c
@@ -47,7 +47,7 @@ POSSIBILITY OF SUCH DAMAGE.  */
 
 #include "testlib.h"
 
-static int test1 (void) __attribute__ ((noinline, noclone, unused));
+static int test1 (void) __attribute__ ((noinline, noclone, optnone, unused));
 static int f2 (int) __attribute__ ((noinline, noclone));
 static int f3 (int, int) __attribute__ ((noinline, noclone));
 
@@ -211,7 +211,7 @@ f3 (int f1line __attribute__ ((unused)), int f2line 
__attribute__ ((unused)))
 
 /* Test the backtrace_simple function with non-inlined functions.  */
 
-static int test3 (void) __attribute__ ((noinline, noclone, unused));
+static int test3 (void) __attribute__ ((noinline, noclone, optnone, unused));
 static int f22 (int) __attribute__ ((noinline, noclone));
 static int f23 (int, int) __attribute__ ((noinline, noclone));
 


libbacktrace patch committed: Suggest -g if no debug info

2024-07-11 Thread Ian Lance Taylor
This small libbacktrace patch suggests compiling with -g (and, on
macOS, running dsymutil), if there is no debug info.  Ran libbacktrace
testsuite.  Committed to mainline.

Ian

* elf.c (elf_nodebug): Suggest -g.
* macho.c (macho_nodebug): Suggest -g and dsymutil.
* pecoff.c (coff_nodebug): Suggest -g.
b96789abf8a51e8f70309799b5dfee36d4fb3da6
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 735f8752500..e6a66c0db90 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -589,7 +589,7 @@ elf_nodebug (struct backtrace_state *state, uintptr_t pc,
   return bdata.ret;
 }
 
-  error_callback (data, "no debug info in ELF executable", -1);
+  error_callback (data, "no debug info in ELF executable (make sure to compile 
with -g)", -1);
   return 0;
 }
 
diff --git a/libbacktrace/macho.c b/libbacktrace/macho.c
index 42f24721e6a..5ceff05b29a 100644
--- a/libbacktrace/macho.c
+++ b/libbacktrace/macho.c
@@ -324,7 +324,7 @@ macho_nodebug (struct backtrace_state *state 
ATTRIBUTE_UNUSED,
   backtrace_full_callback callback ATTRIBUTE_UNUSED,
   backtrace_error_callback error_callback, void *data)
 {
-  error_callback (data, "no debug info in Mach-O executable", -1);
+  error_callback (data, "no debug info in Mach-O executable (make sure to 
compile with -g; may need to run dsymutil)", -1);
   return 0;
 }
 
diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c
index bbb59e26d7a..e88e4d2b038 100644
--- a/libbacktrace/pecoff.c
+++ b/libbacktrace/pecoff.c
@@ -240,7 +240,7 @@ coff_nodebug (struct backtrace_state *state 
ATTRIBUTE_UNUSED,
  backtrace_full_callback callback ATTRIBUTE_UNUSED,
  backtrace_error_callback error_callback, void *data)
 {
-  error_callback (data, "no debug info in PE/COFF executable", -1);
+  error_callback (data, "no debug info in PE/COFF executable (make sure to 
compile with -g)", -1);
   return 0;
 }
 


libbacktrace patch committed: Remove trailing whitespace

2024-07-11 Thread Ian Lance Taylor
This minor libbacktrace patch removes trailing whitespace.  Ran
libbacktrace tests.  Committed to mainline.

Ian

* dwarf.c: Remove trailing whitespace.
* macho.c: Likewise.
3f660179d6a0ebcd83d6a546f48a163d1a685f72
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index ed0672964c2..cc36a0a2990 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -1705,7 +1705,7 @@ add_ranges_from_ranges (
base = (uintptr_t) high;
   else
{
- if (!add_range (state, rdata, 
+ if (!add_range (state, rdata,
  (uintptr_t) low + base + base_address,
  (uintptr_t) high + base + base_address,
  error_callback, data, vec))
@@ -1904,7 +1904,7 @@ add_ranges (struct backtrace_state *state,
const struct dwarf_sections *dwarf_sections,
uintptr_t base_address, int is_bigendian,
struct unit *u, uintptr_t base, const struct pcrange *pcrange,
-   int (*add_range) (struct backtrace_state *state, void *rdata, 
+   int (*add_range) (struct backtrace_state *state, void *rdata,
  uintptr_t lowpc, uintptr_t highpc,
  backtrace_error_callback error_callback,
  void *data, void *vec),
diff --git a/libbacktrace/macho.c b/libbacktrace/macho.c
index b4856346ccc..42f24721e6a 100644
--- a/libbacktrace/macho.c
+++ b/libbacktrace/macho.c
@@ -674,7 +674,6 @@ macho_add_symtab (struct backtrace_state *state, int 
descriptor,
  struct macho_syminfo_data *p;
 
  p = backtrace_atomic_load_pointer (pp);
- 
  if (p == NULL)
break;
 


libbacktrace patch committed: OK if zero backward bits

2024-06-16 Thread Ian Lance Taylor
I've committed this libbacktrace patch to not fail on the case where
there are no bits available when looking backward.  This can happen at
the very end of the frame if no bits are actually required.  The test
case is long and may be proprietary, so not including it.
Bootstrapped and ran libbacktrace and Go testsuite.  Committed to
mainline.

Ian

* elf.c (elf_fetch_bits_backward) Don't fail if no bits are
available.
dda0996e11dbc07f63d3456e36dc5eaec7361004
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 3cd87020b03..735f8752500 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -1182,14 +1182,7 @@ elf_fetch_bits_backward (const unsigned char **ppin,
   val = *pval;
 
   if (unlikely (pin <= pinend))
-{
-  if (bits == 0)
-   {
- elf_uncompress_failed ();
- return 0;
-   }
-  return 1;
-}
+return 1;
 
   pin -= 4;
 


Re: libbacktrace patch committed: Don't assume compressed section aligned

2024-03-08 Thread H.J. Lu
On Fri, Mar 8, 2024 at 2:48 PM Fangrui Song  wrote:
>
> On ELF64, it looks like BFD uses 8-byte alignment for compressed
> `.debug_*` sections while gold/lld/mold use 1-byte alignment. I do not
> know how the Solaris linker sets the alignment.
>
> The specification's wording makes me confused whether it really
> requires 8-byte alignment, even if a non-packed `Elf64_Chdr` surely
> requires 8.

Since compressed sections begin with a compression header
structure that identifies the compression algorithm, compressed
sections must be aligned to the alignment of the compression
header.  I don't think there is any ambiguity here.

> > The sh_size and sh_addralign fields of the section header for a compressed 
> > section reflect the requirements of the compressed section.
>
> There are many `.debug_*` sections. So avoiding some alignment padding
> seems a very natural extension (a DWARF v5 -gsplit-dwarf relocatable
> file has ~10 `.debug_*` sections), even if the specification doesn't
> allow it with a very strict interpretation...
>
> (Off-topic: I wonder whether ELF control structures should use
> unaligned LEB128 more. REL/RELA can naturally be replaced with a
> LEB128 one similar to wasm.)
>
> On Fri, Mar 8, 2024 at 1:57 PM Ian Lance Taylor  wrote:
> >
> > Reportedly when lld compresses debug sections, it fails to set the
> > alignment of the compressed section such that the compressed header
> > can be read directly.  To me this seems like a bug in lld.  However,
> > libbacktrace needs to work around it.  This patch, originally by the
> > GitHub user ubyte, does that.  Bootstrapped and tested on
> > x86_64-pc-linux-gnu.  Committed to mainline.
> >
> > Ian
> >
> > * elf.c (elf_uncompress_chdr): Don't assume compressed section is
> > aligned.
>
>
>
> --
> 宋方睿



-- 
H.J.


Re: libbacktrace patch committed: Don't assume compressed section aligned

2024-03-08 Thread Fangrui Song
On ELF64, it looks like BFD uses 8-byte alignment for compressed
`.debug_*` sections while gold/lld/mold use 1-byte alignment. I do not
know how the Solaris linker sets the alignment.

The specification's wording makes me confused whether it really
requires 8-byte alignment, even if a non-packed `Elf64_Chdr` surely
requires 8.

> The sh_size and sh_addralign fields of the section header for a compressed 
> section reflect the requirements of the compressed section.

There are many `.debug_*` sections. So avoiding some alignment padding
seems a very natural extension (a DWARF v5 -gsplit-dwarf relocatable
file has ~10 `.debug_*` sections), even if the specification doesn't
allow it with a very strict interpretation...

(Off-topic: I wonder whether ELF control structures should use
unaligned LEB128 more. REL/RELA can naturally be replaced with a
LEB128 one similar to wasm.)

On Fri, Mar 8, 2024 at 1:57 PM Ian Lance Taylor  wrote:
>
> Reportedly when lld compresses debug sections, it fails to set the
> alignment of the compressed section such that the compressed header
> can be read directly.  To me this seems like a bug in lld.  However,
> libbacktrace needs to work around it.  This patch, originally by the
> GitHub user ubyte, does that.  Bootstrapped and tested on
> x86_64-pc-linux-gnu.  Committed to mainline.
>
> Ian
>
> * elf.c (elf_uncompress_chdr): Don't assume compressed section is
> aligned.



-- 
宋方睿


libbacktrace patch committed: Don't assume compressed section aligned

2024-03-08 Thread Ian Lance Taylor
Reportedly when lld compresses debug sections, it fails to set the
alignment of the compressed section such that the compressed header
can be read directly.  To me this seems like a bug in lld.  However,
libbacktrace needs to work around it.  This patch, originally by the
GitHub user ubyte, does that.  Bootstrapped and tested on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* elf.c (elf_uncompress_chdr): Don't assume compressed section is
aligned.
5825bd0e0d0040126e78269e56c9b9f533e2a520
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 7841c86cd9c..3cd87020b03 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -5076,7 +5076,7 @@ elf_uncompress_chdr (struct backtrace_state *state,
 backtrace_error_callback error_callback, void *data,
 unsigned char **uncompressed, size_t *uncompressed_size)
 {
-  const b_elf_chdr *chdr;
+  b_elf_chdr chdr;
   char *alc;
   size_t alc_len;
   unsigned char *po;
@@ -5088,27 +5088,30 @@ elf_uncompress_chdr (struct backtrace_state *state,
   if (compressed_size < sizeof (b_elf_chdr))
 return 1;
 
-  chdr = (const b_elf_chdr *) compressed;
+  /* The lld linker can misalign a compressed section, so we can't safely read
+ the fields directly as we can for other ELF sections.  See
+ https://github.com/ianlancetaylor/libbacktrace/pull/120.  */
+  memcpy (, compressed, sizeof (b_elf_chdr));
 
   alc = NULL;
   alc_len = 0;
-  if (*uncompressed != NULL && *uncompressed_size >= chdr->ch_size)
+  if (*uncompressed != NULL && *uncompressed_size >= chdr.ch_size)
 po = *uncompressed;
   else
 {
-  alc_len = chdr->ch_size;
+  alc_len = chdr.ch_size;
   alc = backtrace_alloc (state, alc_len, error_callback, data);
   if (alc == NULL)
return 0;
   po = (unsigned char *) alc;
 }
 
-  switch (chdr->ch_type)
+  switch (chdr.ch_type)
 {
 case ELFCOMPRESS_ZLIB:
   if (!elf_zlib_inflate_and_verify (compressed + sizeof (b_elf_chdr),
compressed_size - sizeof (b_elf_chdr),
-   zdebug_table, po, chdr->ch_size))
+   zdebug_table, po, chdr.ch_size))
goto skip;
   break;
 
@@ -5116,7 +5119,7 @@ elf_uncompress_chdr (struct backtrace_state *state,
   if (!elf_zstd_decompress (compressed + sizeof (b_elf_chdr),
compressed_size - sizeof (b_elf_chdr),
(unsigned char *)zdebug_table, po,
-   chdr->ch_size))
+   chdr.ch_size))
goto skip;
   break;
 
@@ -5126,7 +5129,7 @@ elf_uncompress_chdr (struct backtrace_state *state,
 }
 
   *uncompressed = po;
-  *uncompressed_size = chdr->ch_size;
+  *uncompressed_size = chdr.ch_size;
 
   return 1;
 
@@ -6876,8 +6879,8 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
}
 }
 
-  // A debuginfo file may not have a useful .opd section, but we can use the
-  // one from the original executable.
+  /* A debuginfo file may not have a useful .opd section, but we can use the
+ one from the original executable.  */
   if (opd == NULL)
 opd = caller_opd;
 


libbacktrace patch committed: Link test programs with -no-install

2024-03-02 Thread Ian Lance Taylor
Some of the libbacktrace tests link a program and then modify the
debug info in some way.  When configured with --enable-shared the
linking, using libtool, generates a shell script.  That causes the
tests to fail because they can't modify the debug info of a shell
script.  This patch, originally by Jan Tojnar, pass the -no-install
flag to libtool to avoid generating a shell script.  Bootstrapped and
ran libbacktrace tests on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* Makefile.am (libbacktrace_testing_ldflags): Define.
(*_LDFLAGS): Add $(libbacktrace_testing_ldflags) for test
programs.
* Makefile.in: Regenerate
9b0d218544cd1b12bf63792c70052d2970acc69b
diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am
index 750ed80ed05..5677ecd8865 100644
--- a/libbacktrace/Makefile.am
+++ b/libbacktrace/Makefile.am
@@ -106,6 +106,10 @@ check_DATA =
 # Flags to use when compiling test programs.
 libbacktrace_TEST_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) -g
 
+# Flags to use when linking test programs.
+# This avoids generating a shell script when configured with --enable-shared.
+libbacktrace_testing_ldflags = -no-install
+
 if USE_DSYMUTIL
 
 %.dSYM: %
@@ -170,54 +174,63 @@ xcoff_%.c: xcoff.c
 
 test_elf_32_SOURCES = test_format.c testlib.c
 test_elf_32_CFLAGS = $(libbacktrace_TEST_CFLAGS)
+test_elf_32_LDFLAGS = $(libbacktrace_testing_ldflags)
 test_elf_32_LDADD = libbacktrace_noformat.la elf_32.lo
 
 BUILDTESTS += test_elf_32
 
 test_elf_64_SOURCES = test_format.c testlib.c
 test_elf_64_CFLAGS = $(libbacktrace_TEST_CFLAGS)
+test_elf_64_LDFLAGS = $(libbacktrace_testing_ldflags)
 test_elf_64_LDADD = libbacktrace_noformat.la elf_64.lo
 
 BUILDTESTS += test_elf_64
 
 test_macho_SOURCES = test_format.c testlib.c
 test_macho_CFLAGS = $(libbacktrace_TEST_CFLAGS)
+test_macho_LDFLAGS = $(libbacktrace_testing_ldflags)
 test_macho_LDADD = libbacktrace_noformat.la macho.lo
 
 BUILDTESTS += test_macho
 
 test_xcoff_32_SOURCES = test_format.c testlib.c
 test_xcoff_32_CFLAGS = $(libbacktrace_TEST_CFLAGS)
+test_xcoff_32_LDFLAGS = $(libbacktrace_testing_ldflags)
 test_xcoff_32_LDADD = libbacktrace_noformat.la xcoff_32.lo
 
 BUILDTESTS += test_xcoff_32
 
 test_xcoff_64_SOURCES = test_format.c testlib.c
 test_xcoff_64_CFLAGS = $(libbacktrace_TEST_CFLAGS)
+test_xcoff_64_LDFLAGS = $(libbacktrace_testing_ldflags)
 test_xcoff_64_LDADD = libbacktrace_noformat.la xcoff_64.lo
 
 BUILDTESTS += test_xcoff_64
 
 test_pecoff_SOURCES = test_format.c testlib.c
 test_pecoff_CFLAGS = $(libbacktrace_TEST_CFLAGS)
+test_pecoff_LDFLAGS = $(libbacktrace_testing_ldflags)
 test_pecoff_LDADD = libbacktrace_noformat.la pecoff.lo
 
 BUILDTESTS += test_pecoff
 
 test_unknown_SOURCES = test_format.c testlib.c
 test_unknown_CFLAGS = $(libbacktrace_TEST_CFLAGS)
+test_unknown_LDFLAGS = $(libbacktrace_testing_ldflags)
 test_unknown_LDADD = libbacktrace_noformat.la unknown.lo
 
 BUILDTESTS += test_unknown
 
 unittest_SOURCES = unittest.c testlib.c
 unittest_CFLAGS = $(libbacktrace_TEST_CFLAGS)
+unittest_LDFLAGS = $(libbacktrace_testing_ldflags)
 unittest_LDADD = libbacktrace.la
 
 BUILDTESTS += unittest
 
 unittest_alloc_SOURCES = $(unittest_SOURCES)
 unittest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS)
+unittest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags)
 unittest_alloc_LDADD = libbacktrace_alloc.la
 
 BUILDTESTS += unittest_alloc
@@ -253,7 +266,7 @@ if HAVE_OBJCOPY_DEBUGLINK
 
 b2test_SOURCES = $(btest_SOURCES)
 b2test_CFLAGS = $(libbacktrace_TEST_CFLAGS)
-b2test_LDFLAGS = -Wl,--build-id
+b2test_LDFLAGS = -Wl,--build-id $(libbacktrace_testing_ldflags)
 b2test_LDADD = libbacktrace_elf_for_test.la
 
 check_PROGRAMS += b2test
@@ -263,7 +276,7 @@ if HAVE_DWZ
 
 b3test_SOURCES = $(btest_SOURCES)
 b3test_CFLAGS = $(libbacktrace_TEST_CFLAGS)
-b3test_LDFLAGS = -Wl,--build-id
+b3test_LDFLAGS = -Wl,--build-id $(libbacktrace_testing_ldflags)
 b3test_LDADD = libbacktrace_elf_for_test.la
 
 check_PROGRAMS += b3test
@@ -277,6 +290,7 @@ endif HAVE_ELF
 
 btest_SOURCES = btest.c testlib.c
 btest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -O
+btest_LDFLAGS = $(libbacktrace_testing_ldflags)
 btest_LDADD = libbacktrace.la
 
 BUILDTESTS += btest
@@ -289,6 +303,7 @@ if HAVE_ELF
 
 btest_lto_SOURCES = btest.c testlib.c
 btest_lto_CFLAGS = $(libbacktrace_TEST_CFLAGS) -O -flto
+btest_lto_LDFLAGS = $(libbacktrace_testing_ldflags)
 btest_lto_LDADD = libbacktrace.la
 
 BUILDTESTS += btest_lto
@@ -297,6 +312,7 @@ endif HAVE_ELF
 
 btest_alloc_SOURCES = $(btest_SOURCES)
 btest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS)
+btest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags)
 btest_alloc_LDADD = libbacktrace_alloc.la
 
 BUILDTESTS += btest_alloc
@@ -331,6 +347,7 @@ endif HAVE_DWZ
 
 stest_SOURCES = stest.c
 stest_CFLAGS = $(libbacktrace_TEST_CFLAGS)
+stest_LDFLAGS = $(libbacktrace_testing_ldflags)
 stest_LDADD = libbacktrace.la
 
 BUILDTESTS += stest
@@ -341,6 +358,7 @@ endif USE_DSYMUTIL
 
 stest_alloc_SOURCES = $(stest_SOURCES)
 stest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS)

libbacktrace patch committed: Skip all LZMA block header padding bytes

2024-03-02 Thread Ian Lance Taylor
This patch to libbacktrace corrects the LZMA block header parsing to
skip all the padding bytes, verifying that they are zero.  This fixes
https://github.com/ianlancetaylor/libbacktrace/issues/118.
Bootstrapped and ran libbacktrace tests on x86_64-pc-linux-gnu.  I was
able to verify that the problem occurred when setting the environment
variable XZ_OPT="--threads=2", and that this patch fixes the bug.
Committed to mainline.

Ian

* elf.c (elf_uncompress_lzma_block): Skip all header padding bytes
and verify that they are zero.
23f9fbed3c97ed70d2615d7d3fa7c249cc862553
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index f4527e2477d..7841c86cd9c 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -5568,6 +5568,7 @@ elf_uncompress_lzma_block (const unsigned char 
*compressed,
   uint64_t header_compressed_size;
   uint64_t header_uncompressed_size;
   unsigned char lzma2_properties;
+  size_t crc_offset;
   uint32_t computed_crc;
   uint32_t stream_crc;
   size_t uncompressed_offset;
@@ -5671,19 +5672,20 @@ elf_uncompress_lzma_block (const unsigned char 
*compressed,
   /* The properties describe the dictionary size, but we don't care
  what that is.  */
 
-  /* Block header padding.  */
-  if (unlikely (off + 4 > compressed_size))
+  /* Skip to just before CRC, verifying zero bytes in between.  */
+  crc_offset = block_header_offset + block_header_size - 4;
+  if (unlikely (crc_offset + 4 > compressed_size))
 {
   elf_uncompress_failed ();
   return 0;
 }
-
-  off = (off + 3) &~ (size_t) 3;
-
-  if (unlikely (off + 4 > compressed_size))
+  for (; off < crc_offset; off++)
 {
-  elf_uncompress_failed ();
-  return 0;
+  if (compressed[off] != 0)
+   {
+ elf_uncompress_failed ();
+ return 0;
+   }
 }
 
   /* Block header CRC.  */


Re: libbacktrace patch committed: Read symbol table of debuginfo file

2024-03-01 Thread Ian Lance Taylor
On Thu, Feb 29, 2024 at 7:47 PM Ian Lance Taylor  wrote:
>
> This patch to libbacktrace reads symbol tables from debuginfo files.
> These become another symbol table to search.  This is needed if people
> use --strip-all rather than --strip-debug when adding a debuglink
> section.  This fixes
> https://github.com/ianlancetaylor/libbacktrace/issues/113.
> Bootstrapped and ran libbacktrace and libgo tests on
> x86_64-pc-linux-gnu.  Committed to mainline.

This introduced a bug on the PPC v1 ABI, where libbacktrace uses the
.opd section to convert from a function descriptor address to a code
address.  The .opd section is missing from a debuginfo file.  This
patch changes the code to use the original .opd section if it is
missing.  Checked on powerpc64-linux-gnu and x86_64-pc-linux-gnu.
Committed to mainline.

Ian

PR libbacktrace/114201
* elf.c (elf_add): Add caller_opd parameter.  Change all callers.
Release opd data after all recursive calls.
f692b338cd27a4e0d38fcb5af3d416cd66fbf814
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 664937e1438..f4527e2477d 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -6501,8 +6501,9 @@ backtrace_uncompress_lzma (struct backtrace_state *state,
 static int
 elf_add (struct backtrace_state *state, const char *filename, int descriptor,
 const unsigned char *memory, size_t memory_size,
-uintptr_t base_address, backtrace_error_callback error_callback,
-void *data, fileline *fileline_fn, int *found_sym, int *found_dwarf,
+uintptr_t base_address, struct elf_ppc64_opd_data *caller_opd,
+backtrace_error_callback error_callback, void *data,
+fileline *fileline_fn, int *found_sym, int *found_dwarf,
 struct dwarf_data **fileline_entry, int exe, int debuginfo,
 const char *with_buildid_data, uint32_t with_buildid_size)
 {
@@ -6557,6 +6558,7 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
   struct elf_view split_debug_view[DEBUG_MAX];
   unsigned char split_debug_view_valid[DEBUG_MAX];
   struct elf_ppc64_opd_data opd_data, *opd;
+  int opd_view_valid;
   struct dwarf_sections dwarf_sections;
 
   if (!debuginfo)
@@ -6584,6 +6586,7 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
   debug_view_valid = 0;
   memset (_debug_view_valid[0], 0, sizeof split_debug_view_valid);
   opd = NULL;
+  opd_view_valid = 0;
 
   if (!elf_get_view (state, descriptor, memory, memory_size, 0, sizeof ehdr,
 error_callback, data, _view))
@@ -6867,9 +6870,15 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
  opd->addr = shdr->sh_addr;
  opd->data = (const char *) opd_data.view.view.data;
  opd->size = shdr->sh_size;
+ opd_view_valid = 1;
}
 }
 
+  // A debuginfo file may not have a useful .opd section, but we can use the
+  // one from the original executable.
+  if (opd == NULL)
+opd = caller_opd;
+
   if (symtab_shndx == 0)
 symtab_shndx = dynsym_shndx;
   if (symtab_shndx != 0)
@@ -6948,9 +6957,9 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
elf_release_view (state, _view, error_callback, data);
  if (debugaltlink_view_valid)
elf_release_view (state, _view, error_callback, data);
- ret = elf_add (state, "", d, NULL, 0, base_address, error_callback,
-data, fileline_fn, found_sym, found_dwarf, NULL, 0,
-1, NULL, 0);
+ ret = elf_add (state, "", d, NULL, 0, base_address, opd,
+error_callback, data, fileline_fn, found_sym,
+found_dwarf, NULL, 0, 1, NULL, 0);
  if (ret < 0)
backtrace_close (d, error_callback, data);
  else if (descriptor >= 0)
@@ -6965,12 +6974,6 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
   buildid_view_valid = 0;
 }
 
-  if (opd)
-{
-  elf_release_view (state, >view, error_callback, data);
-  opd = NULL;
-}
-
   if (debuglink_name != NULL)
 {
   int d;
@@ -6985,9 +6988,9 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
  elf_release_view (state, _view, error_callback, data);
  if (debugaltlink_view_valid)
elf_release_view (state, _view, error_callback, data);
- ret = elf_add (state, "", d, NULL, 0, base_address, error_callback,
-data, fileline_fn, found_sym, found_dwarf, NULL, 0,
-1, NULL, 0);
+ ret = elf_add (state, "", d, NULL, 0, base_address, opd,
+error_callback, data, fileline_fn, found_sym,
+found_dwarf, NULL, 0, 1, NULL, 0);
  if (ret < 0)
backtrace_close (d, error_callback, data);
  else if (descriptor >= 0)
@@ -7013,7 +7016,7 @@ elf_add (struct 

libbacktrace patch committed: Read symbol table of debuginfo file

2024-02-29 Thread Ian Lance Taylor
This patch to libbacktrace reads symbol tables from debuginfo files.
These become another symbol table to search.  This is needed if people
use --strip-all rather than --strip-debug when adding a debuglink
section.  This fixes
https://github.com/ianlancetaylor/libbacktrace/issues/113.
Bootstrapped and ran libbacktrace and libgo tests on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* elf.c (elf_add): Add the symbol table from a debuginfo file.
* Makefile.am (MAKETESTS): Add buildidfull and gnudebuglinkfull
variants of buildid and gnudebuglink tests.
(%_gnudebuglinkfull, %_buildidfull): New patterns.
* Makefile.in: Regenerate.
24810fbf7b0ce274dfa46cc362305ac77ee5a72c
diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am
index 16a72d2abf7..750ed80ed05 100644
--- a/libbacktrace/Makefile.am
+++ b/libbacktrace/Makefile.am
@@ -257,7 +257,7 @@ b2test_LDFLAGS = -Wl,--build-id
 b2test_LDADD = libbacktrace_elf_for_test.la
 
 check_PROGRAMS += b2test
-MAKETESTS += b2test_buildid
+MAKETESTS += b2test_buildid b2test_buildidfull
 
 if HAVE_DWZ
 
@@ -267,7 +267,7 @@ b3test_LDFLAGS = -Wl,--build-id
 b3test_LDADD = libbacktrace_elf_for_test.la
 
 check_PROGRAMS += b3test
-MAKETESTS += b3test_dwz_buildid
+MAKETESTS += b3test_dwz_buildid b3test_dwz_buildidfull
 
 endif HAVE_DWZ
 
@@ -443,12 +443,16 @@ endif HAVE_PTHREAD
 
 if HAVE_OBJCOPY_DEBUGLINK
 
-MAKETESTS += btest_gnudebuglink
+MAKETESTS += btest_gnudebuglink btest_gnudebuglinkfull
 
 %_gnudebuglink: %
$(OBJCOPY) --only-keep-debug $< $@.debug
$(OBJCOPY) --strip-debug --add-gnu-debuglink=$@.debug $< $@
 
+%_gnudebuglinkfull: %
+   $(OBJCOPY) --only-keep-debug $< $@.debug
+   $(OBJCOPY) --strip-all --add-gnu-debuglink=$@.debug $< $@
+
 endif HAVE_OBJCOPY_DEBUGLINK
 
 %_buildid: %
@@ -457,6 +461,12 @@ endif HAVE_OBJCOPY_DEBUGLINK
  $<
$(OBJCOPY) --strip-debug $< $@
 
+%_buildidfull: %
+   ./install-debuginfo-for-buildid.sh \
+ "$(TEST_BUILD_ID_DIR)" \
+ $<
+   $(OBJCOPY) --strip-all $< $@
+
 if HAVE_COMPRESSED_DEBUG
 
 ctestg_SOURCES = btest.c testlib.c
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index c506cc29fe1..664937e1438 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -6872,7 +6872,7 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
 
   if (symtab_shndx == 0)
 symtab_shndx = dynsym_shndx;
-  if (symtab_shndx != 0 && !debuginfo)
+  if (symtab_shndx != 0)
 {
   const b_elf_shdr *symtab_shdr;
   unsigned int strtab_shndx;


libbacktrace patch committed

2023-07-31 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch, based on one by Andres Freund, uses the
_pgmptr variable declared on Windows to find the executable file name
if none is specified.  Bootstrapped and ran libbacktrace testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

Patch from Andres Freund:
* configure.ac: Check for _pgmptr declaration.
* fileline.c (fileline_initialize): Check for _pgmfptr before
/proc/self/exec.
* configure, config.h.in: Regenerate.
a349ba16f18b66b70c7a1bdb1ab5c5b6247676da
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 39e6bf41e35..72ff2b30053 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -407,6 +407,9 @@ if test "$have_getexecname" = "yes"; then
   AC_DEFINE(HAVE_GETEXECNAME, 1, [Define if getexecname is available.])
 fi
 
+# Check for _pgmptr variable, contains the executable filename on windows
+AC_CHECK_DECLS([_pgmptr])
+
 # Check for sysctl definitions.
 
 AC_CACHE_CHECK([for KERN_PROC],
diff --git a/libbacktrace/fileline.c b/libbacktrace/fileline.c
index 674bf33cdcf..0e560b44e7a 100644
--- a/libbacktrace/fileline.c
+++ b/libbacktrace/fileline.c
@@ -155,6 +155,16 @@ macho_get_executable_path (struct backtrace_state *state,
 
 #endif /* !defined (HAVE_MACH_O_DYLD_H) */
 
+#if HAVE_DECL__PGMPTR
+
+#define windows_executable_filename() _pgmptr
+
+#else /* !HAVE_DECL__PGMPTR */
+
+#define windows_executable_filename() NULL
+
+#endif /* !HAVE_DECL__PGMPTR */
+
 /* Initialize the fileline information from the executable.  Returns 1
on success, 0 on failure.  */
 
@@ -192,7 +202,7 @@ fileline_initialize (struct backtrace_state *state,
 
   descriptor = -1;
   called_error_callback = 0;
-  for (pass = 0; pass < 8; ++pass)
+  for (pass = 0; pass < 9; ++pass)
 {
   int does_not_exist;
 
@@ -205,23 +215,28 @@ fileline_initialize (struct backtrace_state *state,
  filename = getexecname ();
  break;
case 2:
- filename = "/proc/self/exe";
+ /* Test this before /proc/self/exe, as the latter exists but points
+to the wine binary (and thus doesn't work).  */
+ filename = windows_executable_filename ();
  break;
case 3:
- filename = "/proc/curproc/file";
+ filename = "/proc/self/exe";
  break;
case 4:
+ filename = "/proc/curproc/file";
+ break;
+   case 5:
  snprintf (buf, sizeof (buf), "/proc/%ld/object/a.out",
(long) getpid ());
  filename = buf;
  break;
-   case 5:
+   case 6:
  filename = sysctl_exec_name1 (state, error_callback, data);
  break;
-   case 6:
+   case 7:
  filename = sysctl_exec_name2 (state, error_callback, data);
  break;
-   case 7:
+   case 8:
  filename = macho_get_executable_path (state, error_callback, data);
  break;
default:


libbacktrace patch committed: Tweaks to zstd decompression

2023-03-28 Thread Ian Lance Taylor via Gcc-patches
In looking over the recently committed support for zstd decompression
in libbacktrace, I found a few minor cases that needed fixing.
Bootstrapped and tested on x86_64-pc-linux-gnu.  Committed to
mainline.

Ian


* elf.c (elf_zstd_read_fse): Call elf_fetch_bits after reading
bits, not before.  Add unlikely for error case.
(elf_zstd_offset_table): Regenerate.
(elf_zstd_read_huff): Clear 13 entries in weight_mark, not 12.
(elf_zstd_read_literals): For a single stream adjust by
total_streams_size, not compressed_size.
2e71f05403c36d25216107a7ae43c7055a282d73
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index efd509bba6b..665b3dd1a53 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -2806,18 +2806,18 @@ elf_zstd_read_fse (const unsigned char **ppin, const 
unsigned char *pinend,
  while ((val & 0xfff) == 0xfff)
{
  zidx += 3 * 6;
- if  (!elf_fetch_bits (, pinend, , ))
-   return 0;
  val >>= 12;
  bits -= 12;
+ if  (!elf_fetch_bits (, pinend, , ))
+   return 0;
}
  while ((val & 3) == 3)
{
  zidx += 3;
- if (!elf_fetch_bits (, pinend, , ))
-   return 0;
  val >>= 2;
  bits -= 2;
+ if (!elf_fetch_bits (, pinend, , ))
+   return 0;
}
  /* We have at least 13 bits here, don't need to fetch.  */
  zidx += val & 3;
@@ -2947,7 +2947,7 @@ elf_zstd_build_fse (const int16_t *norm, int idx, 
uint16_t *next,
pos = (pos + step) & mask;
}
 }
-  if (pos != 0)
+  if (unlikely (pos != 0))
 {
   elf_uncompress_failed ();
   return 0;
@@ -3423,17 +3423,17 @@ static const struct elf_zstd_fse_baseline_entry 
elf_zstd_match_table[64] =
 
 static const struct elf_zstd_fse_baseline_entry elf_zstd_offset_table[32] =
 {
-  { 1, 0, 5, 0 }, { 64, 6, 4, 0 }, { 512, 9, 5, 0 },
-  { 32768, 15, 5, 0 }, { 2097152, 21, 5, 0 }, { 8, 3, 5, 0 },
-  { 128, 7, 4, 0 }, { 4096, 12, 5, 0 }, { 262144, 18, 5, 0 },
-  { 8388608, 23, 5, 0 }, { 32, 5, 5, 0 }, { 256, 8, 4, 0 },
-  { 16384, 14, 5, 0 }, { 1048576, 20, 5, 0 }, { 4, 2, 5, 0 },
-  { 128, 7, 4, 16 }, { 2048, 11, 5, 0 }, { 131072, 17, 5, 0 },
-  { 4194304, 22, 5, 0 }, { 16, 4, 5, 0 }, { 256, 8, 4, 16 },
-  { 8192, 13, 5, 0 }, { 524288, 19, 5, 0 }, { 2, 1, 5, 0 },
-  { 64, 6, 4, 16 }, { 1024, 10, 5, 0 }, { 65536, 16, 5, 0 },
-  { 268435456, 28, 5, 0 }, { 134217728, 27, 5, 0 }, { 67108864, 26, 5, 0 },
-  { 33554432, 25, 5, 0 }, { 16777216, 24, 5, 0 },
+  { 1, 0, 5, 0 }, { 61, 6, 4, 0 }, { 509, 9, 5, 0 },
+  { 32765, 15, 5, 0 }, { 2097149, 21, 5, 0 }, { 5, 3, 5, 0 },
+  { 125, 7, 4, 0 }, { 4093, 12, 5, 0 }, { 262141, 18, 5, 0 },
+  { 8388605, 23, 5, 0 }, { 29, 5, 5, 0 }, { 253, 8, 4, 0 },
+  { 16381, 14, 5, 0 }, { 1048573, 20, 5, 0 }, { 1, 2, 5, 0 },
+  { 125, 7, 4, 16 }, { 2045, 11, 5, 0 }, { 131069, 17, 5, 0 },
+  { 4194301, 22, 5, 0 }, { 13, 4, 5, 0 }, { 253, 8, 4, 16 },
+  { 8189, 13, 5, 0 }, { 524285, 19, 5, 0 }, { 2, 1, 5, 0 },
+  { 61, 6, 4, 16 }, { 1021, 10, 5, 0 }, { 65533, 16, 5, 0 },
+  { 268435453, 28, 5, 0 }, { 134217725, 27, 5, 0 }, { 67108861, 26, 5, 0 },
+  { 33554429, 25, 5, 0 }, { 16777213, 24, 5, 0 },
 };
 
 /* Read a zstd Huffman table and build the decoding table in *TABLE, reading
@@ -3618,7 +3618,7 @@ elf_zstd_read_huff (const unsigned char **ppin, const 
unsigned char *pinend,
 }
 
   weight_mark = (uint32_t *) (weights + 256);
-  memset (weight_mark, 0, 12 * sizeof (uint32_t));
+  memset (weight_mark, 0, 13 * sizeof (uint32_t));
   weight_mask = 0;
   for (i = 0; i < count; ++i)
 {
@@ -3685,7 +3685,7 @@ elf_zstd_read_huff (const unsigned char **ppin, const 
unsigned char *pinend,
 
   /* Change WEIGHT_MARK from a count of weights to the index of the first
  symbol for that weight.  We shift the indexes to also store how many we
- hae seen so far, below.  */
+ have seen so far, below.  */
   {
 uint32_t next;
 
@@ -3766,7 +3766,7 @@ elf_zstd_read_literals (const unsigned char **ppin,
 {
   int raw;
 
-  /* Raw_literals_Block or RLE_Literals_Block */
+  /* Raw_Literals_Block or RLE_Literals_Block */
 
   raw = (hdr & 3) == 0;
 
@@ -3948,7 +3948,7 @@ elf_zstd_read_literals (const unsigned char **ppin,
   unsigned int bits;
   uint32_t i;
 
-  pback = pin + compressed_size - 1;
+  pback = pin + total_streams_size - 1;
   pbackend = pin;
   if (!elf_fetch_backward_init (, pbackend, , ))
return 0;


libbacktrace patch committed: Only test --build-id if supported

2023-01-06 Thread Ian Lance Taylor via Gcc-patches
PR 108297 points out that there are systems that use ELF but for which
the linker does not support the --build-id option.  This libbacktrace
patch skips --build-id tests when it doesn't work.  Bootstrapped and
ran libbacktrace tests on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

PR libbacktrace/108297
* configure.ac: Test whether linker supports --build-id.
* Makefile.am: Only run --build-id tests if supported.
* configure, Makefile.in: Regenerate.
diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am
index 047b573c29a..1c4ac2baeb6 100644
--- a/libbacktrace/Makefile.am
+++ b/libbacktrace/Makefile.am
@@ -248,6 +248,7 @@ check_DATA += allocfail.dSYM
 endif USE_DSYMUTIL
 
 if HAVE_ELF
+if HAVE_BUILDID
 if HAVE_OBJCOPY_DEBUGLINK
 
 b2test_SOURCES = $(btest_SOURCES)
@@ -271,6 +272,7 @@ MAKETESTS += b3test_dwz_buildid
 endif HAVE_DWZ
 
 endif HAVE_OBJCOPY_DEBUGLINK
+endif HAVE_BUILDID
 endif HAVE_ELF
 
 btest_SOURCES = btest.c testlib.c
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index d0a0475cfa8..28e3a688c24 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -484,7 +484,18 @@ AC_CHECK_LIB([z], [compress],
 [AC_DEFINE(HAVE_ZLIB, 1, [Define if -lz is available.])])
 AM_CONDITIONAL(HAVE_ZLIB, test "$ac_cv_lib_z_compress" = yes)
 
-dnl Test whether the linker supports the --compress_debug_sections option.
+dnl Test whether the linker supports the --build-id option.
+AC_CACHE_CHECK([whether --build-id is supported],
+[libbacktrace_cv_ld_buildid],
+[LDFLAGS_hold=$LDFLAGS
+LDFLAGS="$LDFLAGS -Wl,--build-id"
+AC_LINK_IFELSE([AC_LANG_PROGRAM(,)],
+[libbacktrace_cv_ld_buildid=yes],
+[libbacktrace_cv_ld_buildid=no])
+LDFLAGS=$LDFLAGS_hold])
+AM_CONDITIONAL(HAVE_BUILDID, test "$libbacktrace_cv_ld_buildid" = yes)
+
+dnl Test whether the linker supports the --compress-debug-sections option.
 AC_CACHE_CHECK([whether --compress-debug-sections is supported],
 [libgo_cv_ld_compress],
 [LDFLAGS_hold=$LDFLAGS


libbacktrace patch committed: Check for sys/link.h

2022-07-08 Thread Ian Lance Taylor via Gcc-patches
Apparently QNX declares dl_iterate_phdr and friends in sys/link.h
rather than link.h.  This patch updates libbacktrace to check there.
This fixes https://github.com/ianlancetaylor/libbacktrace/issues/86.
Bootstrapped and ran libbacktrace testsuite on x86_64-pc-linux-gnu.
Committed to mainline.

Ian

* configure.ac: Check for sys/link.h.  Use either link.h or
sys/link.h when checking for dl_iterate_phdr.
* elf.c: Include sys/link.h if available.
* configure, config.h.in: Regenerate.
bab8b6e52fb0b48b5d9d1af5f93e5c8fb20d6240
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 857987a2859..1daaa2f62d2 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -335,13 +335,17 @@ fi
 AC_SUBST(BACKTRACE_USES_MALLOC)
 
 # Check for dl_iterate_phdr.
-AC_CHECK_HEADERS(link.h)
-if test "$ac_cv_header_link_h" = "no"; then
+AC_CHECK_HEADERS(link.h sys/link.h)
+if test "$ac_cv_header_link_h" = "no" -a "$ac_cv_header_sys_link_h" = "no"; 
then
   have_dl_iterate_phdr=no
 else
   if test -n "${with_target_subdir}"; then
+link_h=link.h
+if test "$ac_cv_header_link_h" = "no"; then
+   link_h=sys/link.h
+fi
 # When built as a GCC target library, we can't do a link test.
-AC_EGREP_HEADER([dl_iterate_phdr], [link.h], [have_dl_iterate_phdr=yes],
+AC_EGREP_HEADER([dl_iterate_phdr], [$link_h], [have_dl_iterate_phdr=yes],
[have_dl_iterate_phdr=no])
   else
 AC_CHECK_FUNC([dl_iterate_phdr], [have_dl_iterate_phdr=yes],
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 8b82dd45875..181d195fe35 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -40,7 +40,12 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include 
 
 #ifdef HAVE_DL_ITERATE_PHDR
-#include 
+ #ifdef HAVE_LINK_H
+  #include 
+ #endif
+ #ifdef HAVE_SYS_LINK_H
+  #include 
+ #endif
 #endif
 
 #include "backtrace.h"


libbacktrace patch committed: Don't exit Mach-O dyld loop on failure

2022-07-07 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch changes the loop over dynamic libraries on
Mach-O to keep going if we fail to find the debug info for a
particular library.  We can still pick up debug info for other
libraries even if one fails.  Tested on x86_64-pc-linux-gnu which
admittedly does little, but others have tested it on Mach-o.
Committed to mainline.

Ian

* macho.c (backtrace_initialize) [HAVE_MACH_O_DYLD_H]: Don't exit
loop if we can't find debug info for one shared library.
d8ddf1fa098fa50929ea0a1569a8e38d80fadbaf
diff --git a/libbacktrace/macho.c b/libbacktrace/macho.c
index 3f40811719e..16f406507d2 100644
--- a/libbacktrace/macho.c
+++ b/libbacktrace/macho.c
@@ -1268,7 +1268,7 @@ backtrace_initialize (struct backtrace_state *state, 
const char *filename,
   mff = macho_nodebug;
   if (!macho_add (state, name, d, 0, NULL, base_address, 0,
  error_callback, data, , ))
-   return 0;
+   continue;
 
   if (mff != macho_nodebug)
macho_fileline_fn = mff;


libbacktrace patch committed: Don't let "make clean" remove allocfail.sh

2022-07-07 Thread Ian Lance Taylor via Gcc-patches
The script allocfail.sh was being incorrectly removed by "make clean".
This patch fixes the problem.  This fixes
https://github.com/ianlancetaylor/libbacktrace/issues/81.  Ran
libbacktrace "make check" and "make clean" on x86_64-pc-linux-gnu.
Committed to mainline.

Ian

For https://github.com/ianlancetaylor/libbacktrace/issues/81
* Makefile.am (MAKETESTS): New variable split out of TESTS.
(CLEANFILES): Replace TESTS with BUILDTESTS and MAKETESTS.
* Makefile.in: Regenerate.
9ed57796235abcd24e06b1ce10fe72c3d0d07cc5
diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am
index bf507b73918..9f8516d00e2 100644
--- a/libbacktrace/Makefile.am
+++ b/libbacktrace/Makefile.am
@@ -85,13 +85,19 @@ libbacktrace_la_DEPENDENCIES = $(libbacktrace_la_LIBADD)
 
 # Testsuite.
 
-# Add a test to this variable if you want it to be built.
+# Add a test to this variable if you want it to be built as a program,
+# with SOURCES, etc.
 check_PROGRAMS =
 
 # Add a test to this variable if you want it to be run.
 TESTS =
 
-# Add a test to this variable if you want it to be built and run.
+# Add a test to this variable if you want it to be built as a Makefile
+# target and run.
+MAKETESTS =
+
+# Add a test to this variable if you want it to be built as a program,
+# with SOURCES, etc., and run.
 BUILDTESTS =
 
 # Add a file to this variable if you want it to be built for testing.
@@ -250,7 +256,7 @@ b2test_LDFLAGS = -Wl,--build-id
 b2test_LDADD = libbacktrace_elf_for_test.la
 
 check_PROGRAMS += b2test
-TESTS += b2test_buildid
+MAKETESTS += b2test_buildid
 
 if HAVE_DWZ
 
@@ -260,7 +266,7 @@ b3test_LDFLAGS = -Wl,--build-id
 b3test_LDADD = libbacktrace_elf_for_test.la
 
 check_PROGRAMS += b3test
-TESTS += b3test_dwz_buildid
+MAKETESTS += b3test_dwz_buildid
 
 endif HAVE_DWZ
 
@@ -311,11 +317,11 @@ if HAVE_DWZ
  cp $< $@; \
fi
 
-TESTS += btest_dwz
+MAKETESTS += btest_dwz
 
 if HAVE_OBJCOPY_DEBUGLINK
 
-TESTS += btest_dwz_gnudebuglink
+MAKETESTS += btest_dwz_gnudebuglink
 
 endif HAVE_OBJCOPY_DEBUGLINK
 
@@ -416,7 +422,7 @@ endif HAVE_PTHREAD
 
 if HAVE_OBJCOPY_DEBUGLINK
 
-TESTS += btest_gnudebuglink
+MAKETESTS += btest_gnudebuglink
 
 %_gnudebuglink: %
$(OBJCOPY) --only-keep-debug $< $@.debug
@@ -494,7 +500,7 @@ endif USE_DSYMUTIL
 
 if HAVE_MINIDEBUG
 
-TESTS += mtest_minidebug
+MAKETESTS += mtest_minidebug
 
 %_minidebug: %
$(NM) -D $< -P --defined-only | $(AWK) '{ print $$1 }' | sort > $<.dsyms
@@ -536,10 +542,11 @@ endif HAVE_ELF
 
 check_PROGRAMS += $(BUILDTESTS)
 
-TESTS += $(BUILDTESTS)
+TESTS += $(MAKETESTS) $(BUILDTESTS)
 
 CLEANFILES = \
-   $(TESTS) *.debug elf_for_test.c edtest2_build.c gen_edtest2_build \
+   $(MAKETESTS) $(BUILDTESTS) *.debug elf_for_test.c edtest2_build.c \
+   gen_edtest2_build \
*.dsyms *.fsyms *.keepsyms *.dbg *.mdbg *.mdbg.xz *.strip
 
 clean-local:


libbacktrace patch committed: Update README

2022-05-28 Thread Ian Lance Taylor via Gcc-patches
This patch updates the libbacktrace README to a near copy of the one
from github.com/ianlancetaylor/libbacktrace.  Committed to mainline.
This fixes GCC PR 105721.

Ian

* README: Update.
6cf19361732bd7f8b41716ef9f4b5c205a3193b8
diff --git a/libbacktrace/README b/libbacktrace/README
index e8b225745c9..6225f92b855 100644
--- a/libbacktrace/README
+++ b/libbacktrace/README
@@ -1,23 +1,31 @@
 The libbacktrace library
-Initially written by Ian Lance Taylor 
+Initially written by Ian Lance Taylor 
 
 The libbacktrace library may be linked into a program or library and
-used to produce symbolic backtraces.  Sample uses would be to print a
-detailed backtrace when an error occurs or to gather detailed
-profiling information.
+used to produce symbolic backtraces.
+Sample uses would be to print a detailed backtrace when an error
+occurs or to gather detailed profiling information.
+In general the functions provided by this library are async-signal-safe,
+meaning that they may be safely called from a signal handler.
 
-The libbacktrace library is provided under a BSD license.  See the
-source files for the exact license text.
+The libbacktrace library is provided under a BSD license.
+See the source files for the exact license text.
 
 The public functions are declared and documented in the header file
 backtrace.h, which should be #include'd by a user of the library.
 
 Building libbacktrace will generate a file backtrace-supported.h,
 which a user of the library may use to determine whether backtraces
-will work.  See the source file backtrace-supported.h.in for the
-macros that it defines.
+will work.
+See the source file backtrace-supported.h.in for the macros that it
+defines.
 
-As of September 2012, libbacktrace only supports ELF executables with
-DWARF debugging information.  The library is written to make it
-straightforward to add support for other object file and debugging
-formats.
+As of October 2020, libbacktrace supports ELF, PE/COFF, Mach-O, and
+XCOFF executables with DWARF debugging information.
+In other words, it supports GNU/Linux, *BSD, macOS, Windows, and AIX.
+The library is written to make it straightforward to add support for
+other object file and debugging formats.
+
+The library relies on the C++ unwind API defined at
+https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html
+This API is provided by GCC and clang.


libbacktrace patch committed: don't skip aligned byte

2022-04-05 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch by Rui Ueyama fixes handling an uncompressed
block that starts at an aligned byte.  If the bits before the
uncompressed block ended at a byte boundary, libbacktrace accidentally
skipped the next byte, which is the first byte of the length of the
block.  Bootstrapped and ran libbacktrace tests on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* elf.c (elf_zlib_inflate): Don't skip initial aligned byte in
uncompressed block.
584ae0f0eea2a162dc02984c5976d5cbab5cd1e7
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 5c7c21a8da7..8b82dd45875 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -1796,7 +1796,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, 
uint16_t *zdebug_table,
  /* An uncompressed block.  */
 
  /* If we've read ahead more than a byte, back up.  */
- while (bits > 8)
+ while (bits >= 8)
{
  --pin;
  bits -= 8;


libbacktrace patch committed: Handle skeleton units

2022-02-16 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch handles DWARF 5 skeleton units, which are used
when part of the DWARF information is stored in a separate file.  This
doesn't actually look in the separate file, as the line number
information, which is all that we care about, is normally kept in the
main executable because it needs relocations.  For this patch
bootstrapped and ran libbacktrace and Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* dwarf.c (find_address_ranges): Handle skeleton units.
(read_function_entry): Likewise.
3c16999f983331301384f51fc1cdc04f7d51ef6c
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 2158bc14065..45cc9e77e40 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -1989,14 +1989,16 @@ find_address_ranges (struct backtrace_state *state, 
uintptr_t base_address,
  break;
 
case DW_AT_stmt_list:
- if (abbrev->tag == DW_TAG_compile_unit
+ if ((abbrev->tag == DW_TAG_compile_unit
+  || abbrev->tag == DW_TAG_skeleton_unit)
  && (val.encoding == ATTR_VAL_UINT
  || val.encoding == ATTR_VAL_REF_SECTION))
u->lineoff = val.u.uint;
  break;
 
case DW_AT_name:
- if (abbrev->tag == DW_TAG_compile_unit)
+ if (abbrev->tag == DW_TAG_compile_unit
+ || abbrev->tag == DW_TAG_skeleton_unit)
{
  name_val = val;
  have_name_val = 1;
@@ -2004,7 +2006,8 @@ find_address_ranges (struct backtrace_state *state, 
uintptr_t base_address,
  break;
 
case DW_AT_comp_dir:
- if (abbrev->tag == DW_TAG_compile_unit)
+ if (abbrev->tag == DW_TAG_compile_unit
+ || abbrev->tag == DW_TAG_skeleton_unit)
{
  comp_dir_val = val;
  have_comp_dir_val = 1;
@@ -2012,19 +2015,22 @@ find_address_ranges (struct backtrace_state *state, 
uintptr_t base_address,
  break;
 
case DW_AT_str_offsets_base:
- if (abbrev->tag == DW_TAG_compile_unit
+ if ((abbrev->tag == DW_TAG_compile_unit
+  || abbrev->tag == DW_TAG_skeleton_unit)
  && val.encoding == ATTR_VAL_REF_SECTION)
u->str_offsets_base = val.u.uint;
  break;
 
case DW_AT_addr_base:
- if (abbrev->tag == DW_TAG_compile_unit
+ if ((abbrev->tag == DW_TAG_compile_unit
+  || abbrev->tag == DW_TAG_skeleton_unit)
  && val.encoding == ATTR_VAL_REF_SECTION)
u->addr_base = val.u.uint;
  break;
 
case DW_AT_rnglists_base:
- if (abbrev->tag == DW_TAG_compile_unit
+ if ((abbrev->tag == DW_TAG_compile_unit
+  || abbrev->tag == DW_TAG_skeleton_unit)
  && val.encoding == ATTR_VAL_REF_SECTION)
u->rnglists_base = val.u.uint;
  break;
@@ -2052,7 +2058,8 @@ find_address_ranges (struct backtrace_state *state, 
uintptr_t base_address,
}
 
   if (abbrev->tag == DW_TAG_compile_unit
- || abbrev->tag == DW_TAG_subprogram)
+ || abbrev->tag == DW_TAG_subprogram
+ || abbrev->tag == DW_TAG_skeleton_unit)
{
  if (!add_ranges (state, dwarf_sections, base_address,
   is_bigendian, u, pcrange.lowpc, ,
@@ -2060,9 +2067,10 @@ find_address_ranges (struct backtrace_state *state, 
uintptr_t base_address,
   (void *) addrs))
return 0;
 
- /* If we found the PC range in the DW_TAG_compile_unit, we
-can stop now.  */
- if (abbrev->tag == DW_TAG_compile_unit
+ /* If we found the PC range in the DW_TAG_compile_unit or
+DW_TAG_skeleton_unit, we can stop now.  */
+ if ((abbrev->tag == DW_TAG_compile_unit
+  || abbrev->tag == DW_TAG_skeleton_unit)
  && (pcrange.have_ranges
  || (pcrange.have_lowpc && pcrange.have_highpc)))
return 1;
@@ -3274,7 +3282,8 @@ read_function_entry (struct backtrace_state *state, 
struct dwarf_data *ddata,
 
  /* The compile unit sets the base address for any address
 ranges in the function entries.  */
- if (abbrev->tag == DW_TAG_compile_unit
+ if ((abbrev->tag == DW_TAG_compile_unit
+  || abbrev->tag == DW_TAG_skeleton_unit)
  && abbrev->attrs[i].name == DW_AT_low_pc)
{
  if (val.encoding == ATTR_VAL_ADDRESS)


libbacktrace patch committed: Initialize DWARF 5 fields of unit

2022-02-16 Thread Ian Lance Taylor via Gcc-patches
When I added the DWARF 5 support to libbacktrace in 2019-12-13 I
forgot to initialize the new fields of the unit data structure.
Whoops.  Fixed with this patch.  Bootstrapped and ran libbacktrace and
Go testsuite on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* dwarf.c (build_address_map): Initialize DWARF 5 fields of unit.
ab59cb2055658a72fdccba0be76eeadd222ffef6
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index c0bae0e501e..2158bc14065 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -2221,6 +2221,9 @@ build_address_map (struct backtrace_state *state, 
uintptr_t base_address,
   u->comp_dir = NULL;
   u->abs_filename = NULL;
   u->lineoff = 0;
+  u->str_offsets_base = 0;
+  u->addr_base = 0;
+  u->rnglists_base = 0;
 
   /* The actual line number mappings will be read as needed.  */
   u->lines = NULL;


libbacktrace patch committed: Don't special case file 0

2021-03-02 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch stops special casing file 0.  It's no longer
necessary as for DWARF 5 support we now set up filename 0 in all
cases.  Bootstrapped and ran libbacktrace and Go tests on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* dwarf.c (read_line_program): Don't special case file 0.
(read_function_entry): Likewise.
b3176ab8787a7f988a931e26bce9227edd2e6d1a
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 546b4b26a32..e6b1f238cd3 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -2857,20 +2857,15 @@ read_line_program (struct backtrace_state *state, 
struct dwarf_data *ddata,
uint64_t fileno;
 
fileno = read_uleb128 (line_buf);
-   if (fileno == 0)
- filename = "";
-   else
+   if (fileno >= hdr->filenames_count)
  {
-   if (fileno >= hdr->filenames_count)
- {
-   dwarf_buf_error (line_buf,
-("invalid file number in "
- "line number program"),
-0);
-   return 0;
- }
-   filename = hdr->filenames[fileno];
+   dwarf_buf_error (line_buf,
+("invalid file number in "
+ "line number program"),
+0);
+   return 0;
  }
+   filename = hdr->filenames[fileno];
  }
  break;
case DW_LNS_set_column:
@@ -3298,21 +3293,15 @@ read_function_entry (struct backtrace_state *state, 
struct dwarf_data *ddata,
case DW_AT_call_file:
  if (val.encoding == ATTR_VAL_UINT)
{
- if (val.u.uint == 0)
-   function->caller_filename = "";
- else
+ if (val.u.uint >= lhdr->filenames_count)
{
- if (val.u.uint >= lhdr->filenames_count)
-   {
- dwarf_buf_error (unit_buf,
-  ("invalid file number in "
-   "DW_AT_call_file attribute"),
-  0);
- return 0;
-   }
- function->caller_filename =
-   lhdr->filenames[val.u.uint];
+ dwarf_buf_error (unit_buf,
+  ("invalid file number in "
+   "DW_AT_call_file attribute"),
+  0);
+ return 0;
}
+ function->caller_filename = lhdr->filenames[val.u.uint];
}
  break;
 


libbacktrace patch committed: Pass -1 to error callback for unknown DWARF

2021-03-02 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch passes -1 to the error callback function for
unknown DWARF versions.  This makes users of libbacktrace treat DWARF
versions that libbacktrace does not support as though no debug
information were available.  This fixes PR 98818.  Bootstrapped and
ran libbacktrace tests on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* dwarf.c (dwarf_buf_error): Add errnum parameter.  Change all
callers.
* backtrace.h: Update backtrace_error_callback comment.
df003d1e0bf2d0a8e2ed45a323d4e974b15dc95f
diff --git a/libbacktrace/backtrace.h b/libbacktrace/backtrace.h
index 2814763f417..caaa66d3686 100644
--- a/libbacktrace/backtrace.h
+++ b/libbacktrace/backtrace.h
@@ -71,13 +71,14 @@ struct backtrace_state;
invalid after this function returns.
 
As a special case, the ERRNUM argument will be passed as -1 if no
-   debug info can be found for the executable, but the function
-   requires debug info (e.g., backtrace_full, backtrace_pcinfo).  The
-   MSG in this case will be something along the lines of "no debug
-   info".  Similarly, ERRNUM will be passed as -1 if there is no
-   symbol table, but the function requires a symbol table (e.g.,
-   backtrace_syminfo).  This may be used as a signal that some other
-   approach should be tried.  */
+   debug info can be found for the executable, or if the debug info
+   exists but has an unsupported version, but the function requires
+   debug info (e.g., backtrace_full, backtrace_pcinfo).  The MSG in
+   this case will be something along the lines of "no debug info".
+   Similarly, ERRNUM will be passed as -1 if there is no symbol table,
+   but the function requires a symbol table (e.g., backtrace_syminfo).
+   This may be used as a signal that some other approach should be
+   tried.  */
 
 typedef void (*backtrace_error_callback) (void *data, const char *msg,
  int errnum);
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 9097df6cc76..546b4b26a32 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -410,13 +410,13 @@ struct dwarf_data
 /* Report an error for a DWARF buffer.  */
 
 static void
-dwarf_buf_error (struct dwarf_buf *buf, const char *msg)
+dwarf_buf_error (struct dwarf_buf *buf, const char *msg, int errnum)
 {
   char b[200];
 
   snprintf (b, sizeof b, "%s in %s at %d",
msg, buf->name, (int) (buf->buf - buf->start));
-  buf->error_callback (buf->data, b, 0);
+  buf->error_callback (buf->data, b, errnum);
 }
 
 /* Require at least COUNT bytes in BUF.  Return 1 if all is well, 0 on
@@ -430,7 +430,7 @@ require (struct dwarf_buf *buf, size_t count)
 
   if (!buf->reported_underflow)
 {
-  dwarf_buf_error (buf, "DWARF underflow");
+  dwarf_buf_error (buf, "DWARF underflow", 0);
   buf->reported_underflow = 1;
 }
 
@@ -592,7 +592,7 @@ read_address (struct dwarf_buf *buf, int addrsize)
 case 8:
   return read_uint64 (buf);
 default:
-  dwarf_buf_error (buf, "unrecognized address size");
+  dwarf_buf_error (buf, "unrecognized address size", 0);
   return 0;
 }
 }
@@ -643,7 +643,7 @@ read_uleb128 (struct dwarf_buf *buf)
ret |= ((uint64_t) (b & 0x7f)) << shift;
   else if (!overflow)
{
- dwarf_buf_error (buf, "LEB128 overflows uint64_t");
+ dwarf_buf_error (buf, "LEB128 overflows uint64_t", 0);
  overflow = 1;
}
   shift += 7;
@@ -678,7 +678,7 @@ read_sleb128 (struct dwarf_buf *buf)
val |= ((uint64_t) (b & 0x7f)) << shift;
   else if (!overflow)
{
- dwarf_buf_error (buf, "signed LEB128 overflows uint64_t");
+ dwarf_buf_error (buf, "signed LEB128 overflows uint64_t", 0);
  overflow = 1;
}
   shift += 7;
@@ -818,7 +818,7 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
offset = read_offset (buf, is_dwarf64);
if (offset >= dwarf_sections->size[DEBUG_STR])
  {
-   dwarf_buf_error (buf, "DW_FORM_strp out of range");
+   dwarf_buf_error (buf, "DW_FORM_strp out of range", 0);
return 0;
  }
val->encoding = ATTR_VAL_STRING;
@@ -833,7 +833,7 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
offset = read_offset (buf, is_dwarf64);
if (offset >= dwarf_sections->size[DEBUG_LINE_STR])
  {
-   dwarf_buf_error (buf, "DW_FORM_line_strp out of range");
+   dwarf_buf_error (buf, "DW_FORM_line_strp out of range", 0);
return 0;
  }
val->encoding = ATTR_VAL_STRING;
@@ -880,7 +880,8 @@ read_attribute (enum dwarf_form form, uint64_t implicit_val,
if (form == DW_FORM_implicit_const)
  {
dwarf_buf_error (buf,
-"DW_FORM_indirect to DW_FORM_implicit_const");
+"DW_FORM_indirect to DW_FORM_implicit_const",
+0);
return 0;
  }
return 

libbacktrace patch committed: Use objcopy --help to check for option

2021-02-11 Thread Ian Lance Taylor via Gcc-patches
This patch changes the libbacktrace configure script to check for
whether objcopy supports --add-gnu-debuglink (a test that only affects
the libbacktrace testsuite) to look at the objcopy --help option
rather than trying to apply --add-gnu-debuglink to /bin/ls.  The
latter can trigger a warning if /bin/ls already has a separate debug
file.  Bootstrapped and ran libbacktrace testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* configure.ac: Check for objcopy --add-gnu-debuglink by using
objcopy --help.
* configure: Regenerate
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 83d4733509a..43a33a66b82 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -500,8 +500,7 @@ AC_CACHE_CHECK([whether objcopy supports debuglink],
   libbacktrace_cv_objcopy_debuglink=no
 elif ! test -n "${OBJCOPY}"; then
   libbacktrace_cv_objcopy_debuglink=no
-elif ${OBJCOPY} --add-gnu-debuglink=x /bin/ls /tmp/ls$$; then
-  rm -f /tmp/ls$$
+elif ${OBJCOPY} --help | fgrep add-gnu-debuglink >/dev/null 2>&1; then
   libbacktrace_cv_objcopy_debuglink=yes
 else
   libbacktrace_cv_objcopy_debuglink=no


libbacktrace patch committed: Don't fail tests if dwz fails

2021-01-18 Thread Ian Lance Taylor via Gcc-patches
On my system the current version of dwz fails on some DWARF 5 input.
This is reportedly fixed by
https://sourceware.org/pipermail/dwz/2021q1/000775.html, but in the
meantime there is no reason for the libbacktrace testsuite to fail
just because dwz fails.  This patch changes the Makefile so that if
dwz fails, we just use the uncompressed debug info.  The test becomes
meaningless, but at least it passes.  And it will continue to test dwz
information for cases where dwz works.  Bootstrapped and ran
libbacktrace tests on x86_64-pc-linux-gnu.  Committed to mainline.

(This commit also regenerates configure, which was not correct
regenerated by an earlier commit.  The only difference is some #line
directives.)

Ian

* Makefile.am (%_dwz): If dwz fails, use uncompressed debug info.
* Makefile.in: Regenerate.
* configure: Regenerate.
bfde774667fbce6d7d326c8a36a098138e224a95
diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am
index e1e55009f09..8874f41338a 100644
--- a/libbacktrace/Makefile.am
+++ b/libbacktrace/Makefile.am
@@ -303,9 +303,13 @@ if HAVE_DWZ
rm -f $@ $@_common.debug
cp $< $@_1
cp $< $@_2
-   $(DWZ) -m $@_common.debug $@_1 $@_2
-   rm -f $@_2
-   mv $@_1 $@
+   if $(DWZ) -m $@_common.debug $@_1 $@_2; then \
+ rm -f $@_2; \
+ mv $@_1 $@; \
+   else \
+ echo "Ignoring dwz errors, assuming that test passes"; \
+ cp $< $@; \
+   fi
 
 TESTS += btest_dwz
 


libbacktrace patch committed: Use correct DWARF-5 filename index

2021-01-18 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch uses the correct directory and filename index
for DWARF 5.  For DWARF 4 and before, the zero entry for the directory
and filename information stored in the line program came from the
compilation unit.  Because of that, the old code used to handle zero
specially, and otherwise subtract one from the index.  For DWARF 5,
the zero entry is actually present in the tables, so it is no longer
appropriate to subtract one.  To make this work in the simplest
manner, just always store the zero entry in the tables, and stop
treating zero specially, and stop subtracting one.  For DWARF 4 and
before, fetch the zero entry from the compilation unit.  Bootstrapped
on x86_64-pc-linux-gnu.  The libbacktrace tests all pass.  The libgo
test all pass except for the ones that fail due to PR 98708.
Committed to mainline.

Ian

* dwarf.c (read_v2_paths): Allocate zero entry for dirs and
filenames.
(read_line_program): Remove parameter u, change caller.  Don't
subtract one from dirs and filenames index.
(read_function_entry): Don't subtract one from filenames index.
4817984f0f79656698e8b380e524f56a53881f15
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 3d0cbedf770..9097df6cc76 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -2344,19 +2344,20 @@ read_v2_paths (struct backtrace_state *state, struct 
unit *u,
   ++hdr->dirs_count;
 }
 
-  hdr->dirs = NULL;
-  if (hdr->dirs_count != 0)
-{
-  hdr->dirs = ((const char **)
-  backtrace_alloc (state,
-   hdr->dirs_count * sizeof (const char *),
-   hdr_buf->error_callback,
-   hdr_buf->data));
-  if (hdr->dirs == NULL)
-   return 0;
-}
+  /* The index of the first entry in the list of directories is 1.  Index 0 is
+ used for the current directory of the compilation.  To simplify index
+ handling, we set entry 0 to the compilation unit directory.  */
+  ++hdr->dirs_count;
+  hdr->dirs = ((const char **)
+  backtrace_alloc (state,
+   hdr->dirs_count * sizeof (const char *),
+   hdr_buf->error_callback,
+   hdr_buf->data));
+  if (hdr->dirs == NULL)
+return 0;
 
-  i = 0;
+  hdr->dirs[0] = u->comp_dir;
+  i = 1;
   while (*hdr_buf->buf != '\0')
 {
   if (hdr_buf->reported_underflow)
@@ -2383,6 +2384,10 @@ read_v2_paths (struct backtrace_state *state, struct 
unit *u,
   ++hdr->filenames_count;
 }
 
+  /* The index of the first entry in the list of file names is 1.  Index 0 is
+ used for the DW_AT_name of the compilation unit.  To simplify index
+ handling, we set entry 0 to the compilation unit file name.  */
+  ++hdr->filenames_count;
   hdr->filenames = ((const char **)
backtrace_alloc (state,
 hdr->filenames_count * sizeof (char *),
@@ -2390,7 +2395,8 @@ read_v2_paths (struct backtrace_state *state, struct unit 
*u,
 hdr_buf->data));
   if (hdr->filenames == NULL)
 return 0;
-  i = 0;
+  hdr->filenames[0] = u->filename;
+  i = 1;
   while (*hdr_buf->buf != '\0')
 {
   const char *filename;
@@ -2404,7 +2410,7 @@ read_v2_paths (struct backtrace_state *state, struct unit 
*u,
return 0;
   dir_index = read_uleb128 (hdr_buf);
   if (IS_ABSOLUTE_PATH (filename)
- || (dir_index == 0 && u->comp_dir == NULL))
+ || (dir_index < hdr->dirs_count && hdr->dirs[dir_index] == NULL))
hdr->filenames[i] = filename;
   else
{
@@ -2413,10 +2419,8 @@ read_v2_paths (struct backtrace_state *state, struct 
unit *u,
  size_t filename_len;
  char *s;
 
- if (dir_index == 0)
-   dir = u->comp_dir;
- else if (dir_index - 1 < hdr->dirs_count)
-   dir = hdr->dirs[dir_index - 1];
+ if (dir_index < hdr->dirs_count)
+   dir = hdr->dirs[dir_index];
  else
{
  dwarf_buf_error (hdr_buf,
@@ -2704,8 +2708,8 @@ read_line_header (struct backtrace_state *state, struct 
dwarf_data *ddata,
 
 static int
 read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
-  struct unit *u, const struct line_header *hdr,
-  struct dwarf_buf *line_buf, struct line_vector *vec)
+  const struct line_header *hdr, struct dwarf_buf *line_buf,
+  struct line_vector *vec)
 {
   uint64_t address;
   unsigned int op_index;
@@ -2715,8 +2719,8 @@ read_line_program (struct backtrace_state *state, struct 
dwarf_data *ddata,
 
   address = 0;
   op_index = 0;
-  if (hdr->filenames_count > 0)
-reset_filename = hdr->filenames[0];
+  if (hdr->filenames_count > 1)
+reset_filename = hdr->filenames[1];
   else
 reset_filename = "";
   filename = reset_filename;
@@ -2781,10 +2785,8 @@ read_line_program 

libbacktrace patch committed: permit values at end of buffer

2020-12-02 Thread Ian Lance Taylor via Gcc-patches
A couple of buffer overflow checks in libbacktrace incorrectly used >=
when comparing the end of the value with the end of the buffer.  It is
of course OK if the value ends at the very end of the buffer.  This
patch corrects those cases to use > instead.  Bootstrapped and ran
libbacktrace and Go tests on x86_64-pc-linux-gnu.  Committed to
mainline.

Ian

* dwarf.c (resolve_string): Use > rather than >= to check whether
string index extends past buffer.
(resolve_addr_index): Similarly for address index.
2e7ce16d5156bab9c217d21e7ff17a6a6eaf6fd3
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 582f34bc816..0c913c95983 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -1053,7 +1053,7 @@ resolve_string (const struct dwarf_sections 
*dwarf_sections, int is_dwarf64,
 
offset = val->u.uint * (is_dwarf64 ? 8 : 4) + str_offsets_base;
if (offset + (is_dwarf64 ? 8 : 4)
-   >= dwarf_sections->size[DEBUG_STR_OFFSETS])
+   > dwarf_sections->size[DEBUG_STR_OFFSETS])
  {
error_callback (data, "DW_FORM_strx value out of range", 0);
return 0;
@@ -1097,7 +1097,7 @@ resolve_addr_index (const struct dwarf_sections 
*dwarf_sections,
   struct dwarf_buf addr_buf;
 
   offset = addr_index * addrsize + addr_base;
-  if (offset + addrsize >= dwarf_sections->size[DEBUG_ADDR])
+  if (offset + addrsize > dwarf_sections->size[DEBUG_ADDR])
 {
   error_callback (data, "DW_FORM_addrx value out of range", 0);
   return 0;


libbacktrace patch committed: Use __attribute__((__fallthrough__))

2020-10-20 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch uses __attribute__((__fallthrough__)) rather
than relying on a /*fallthrough*/ comment.  Bootstrapped and ran
libbacktrace tests on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* internal.h (ATTRIBUTE_FALLTHROUGH): Define.
* elf.c (elf_zlib_inflate): Use ATTRIBUTE_FALLTHROUGH.
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 941f820d944..d52b86cdeb5 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -2081,10 +2081,10 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, 
uint16_t *zdebug_table,
{
case 6:
  *plen++ = prev;
- /* fallthrough */
+ ATTRIBUTE_FALLTHROUGH;
case 5:
  *plen++ = prev;
- /* fallthrough */
+ ATTRIBUTE_FALLTHROUGH;
case 4:
  *plen++ = prev;
}
@@ -2115,22 +2115,22 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, 
uint16_t *zdebug_table,
{
case 10:
  *plen++ = 0;
- /* fallthrough */
+ ATTRIBUTE_FALLTHROUGH;
case 9:
  *plen++ = 0;
- /* fallthrough */
+ ATTRIBUTE_FALLTHROUGH;
case 8:
  *plen++ = 0;
- /* fallthrough */
+ ATTRIBUTE_FALLTHROUGH;
case 7:
  *plen++ = 0;
- /* fallthrough */
+ ATTRIBUTE_FALLTHROUGH;
case 6:
  *plen++ = 0;
- /* fallthrough */
+ ATTRIBUTE_FALLTHROUGH;
case 5:
  *plen++ = 0;
- /* fallthrough */
+ ATTRIBUTE_FALLTHROUGH;
case 4:
  *plen++ = 0;
}
diff --git a/libbacktrace/internal.h b/libbacktrace/internal.h
index 047a700c0ce..659db9e21e2 100644
--- a/libbacktrace/internal.h
+++ b/libbacktrace/internal.h
@@ -56,6 +56,14 @@ POSSIBILITY OF SUCH DAMAGE.  */
 # endif
 #endif
 
+#ifndef ATTRIBUTE_FALLTHROUGH
+# if (GCC_VERSION >= 7000)
+#  define ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__))
+# else
+#  define ATTRIBUTE_FALLTHROUGH
+# endif
+#endif
+
 #ifndef HAVE_SYNC_FUNCTIONS
 
 /* Define out the sync functions.  These should never be called if


libbacktrace patch committed: Create mtest.dsym

2020-09-28 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch creates mtest.dsym when using dsymutil.  This
is for PR 97082, but it probably doesn't fix the PR.  Bootstrapped and
ran libbacktrace tests on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

PR libbacktrace/97082
* Makefile.am (check_DATA): Add mtest.dSYM if USE_DSYMUTIL.
* Makefile.in: Regenerate.
diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am
index f7e8ca2cf5c..5899a2157f4 100644
--- a/libbacktrace/Makefile.am
+++ b/libbacktrace/Makefile.am
@@ -484,6 +484,10 @@ mtest_LDADD = libbacktrace.la
 
 BUILDTESTS += mtest
 
+if USE_DSYMUTIL
+check_DATA += mtest.dSYM
+endif USE_DSYMUTIL
+
 if HAVE_MINIDEBUG
 
 TESTS += mtest_minidebug


libbacktrace patch committed: Only use dsymutil with Mach-O

2020-09-28 Thread Ian Lance Taylor via Gcc-patches
This patch changes the libbacktrace tests to only run dsymutil when
building for Mach-O.  This should fix GCC PR 97227.  Bootstrapped and
ran libbacktrace tests on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

PR libbacktrace/97227
* configure.ac (USE_DSYMUTIL): Define instead of HAVE_DSYMUTIL.
* Makefile.am: Change all uses of HAVE_DSYMUTIL to USE_DSYMUTIL.
* configure: Regenerate.
* Makefile.in: Regenerate.
diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am
index 4d349386c9b..f7e8ca2cf5c 100644
--- a/libbacktrace/Makefile.am
+++ b/libbacktrace/Makefile.am
@@ -100,12 +100,12 @@ check_DATA =
 # Flags to use when compiling test programs.
 libbacktrace_TEST_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) -g
 
-if HAVE_DSYMUTIL
+if USE_DSYMUTIL
 
 %.dSYM: %
$(DSYMUTIL) $<
 
-endif HAVE_DSYMUTIL
+endif USE_DSYMUTIL
 
 if NATIVE
 check_LTLIBRARIES = libbacktrace_alloc.la
@@ -237,9 +237,9 @@ allocfail.sh: allocfail
 
 TESTS += allocfail.sh
 
-if HAVE_DSYMUTIL
+if USE_DSYMUTIL
 check_DATA += allocfail.dSYM
-endif HAVE_DSYMUTIL
+endif USE_DSYMUTIL
 
 if HAVE_ELF
 if HAVE_OBJCOPY_DEBUGLINK
@@ -273,9 +273,9 @@ btest_LDADD = libbacktrace.la
 
 BUILDTESTS += btest
 
-if HAVE_DSYMUTIL
+if USE_DSYMUTIL
 check_DATA += btest.dSYM
-endif HAVE_DSYMUTIL
+endif USE_DSYMUTIL
 
 if HAVE_ELF
 
@@ -293,9 +293,9 @@ btest_alloc_LDADD = libbacktrace_alloc.la
 
 BUILDTESTS += btest_alloc
 
-if HAVE_DSYMUTIL
+if USE_DSYMUTIL
 check_DATA += btest_alloc.dSYM
-endif HAVE_DSYMUTIL
+endif USE_DSYMUTIL
 
 if HAVE_DWZ
 
@@ -323,9 +323,9 @@ stest_LDADD = libbacktrace.la
 
 BUILDTESTS += stest
 
-if HAVE_DSYMUTIL
+if USE_DSYMUTIL
 check_DATA += stest.dSYM
-endif HAVE_DSYMUTIL
+endif USE_DSYMUTIL
 
 stest_alloc_SOURCES = $(stest_SOURCES)
 stest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS)
@@ -333,9 +333,9 @@ stest_alloc_LDADD = libbacktrace_alloc.la
 
 BUILDTESTS += stest_alloc
 
-if HAVE_DSYMUTIL
+if USE_DSYMUTIL
 check_DATA += stest_alloc.dSYM
-endif HAVE_DSYMUTIL
+endif USE_DSYMUTIL
 
 if HAVE_ELF
 
@@ -366,17 +366,17 @@ edtest_LDADD = libbacktrace.la
 
 BUILDTESTS += edtest
 
-if HAVE_DSYMUTIL
+if USE_DSYMUTIL
 check_DATA += edtest.dSYM
-endif HAVE_DSYMUTIL
+endif USE_DSYMUTIL
 
 edtest_alloc_SOURCES = $(edtest_SOURCES)
 edtest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 edtest_alloc_LDADD = libbacktrace_alloc.la
 
-if HAVE_DSYMUTIL
+if USE_DSYMUTIL
 check_DATA += edtest_alloc.dSYM
-endif HAVE_DSYMUTIL
+endif USE_DSYMUTIL
 
 BUILDTESTS += edtest_alloc
 
@@ -394,9 +394,9 @@ ttest_SOURCES = ttest.c testlib.c
 ttest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -pthread
 ttest_LDADD = libbacktrace.la
 
-if HAVE_DSYMUTIL
+if USE_DSYMUTIL
 check_DATA += ttest.dSYM
-endif HAVE_DSYMUTIL
+endif USE_DSYMUTIL
 
 BUILDTESTS += ttest_alloc
 
@@ -404,9 +404,9 @@ ttest_alloc_SOURCES = $(ttest_SOURCES)
 ttest_alloc_CFLAGS = $(ttest_CFLAGS)
 ttest_alloc_LDADD = libbacktrace_alloc.la
 
-if HAVE_DSYMUTIL
+if USE_DSYMUTIL
 check_DATA += ttest_alloc.dSYM
-endif HAVE_DSYMUTIL
+endif USE_DSYMUTIL
 
 endif HAVE_PTHREAD
 
@@ -462,9 +462,9 @@ dwarf5_LDADD = libbacktrace.la
 
 BUILDTESTS += dwarf5
 
-if HAVE_DSYMUTIL
+if USE_DSYMUTIL
 check_DATA += dwarf5.dSYM
-endif HAVE_DSYMUTIL
+endif USE_DSYMUTIL
 
 dwarf5_alloc_SOURCES = $(dwarf5_SOURCES)
 dwarf5_alloc_CFLAGS = $(dwarf5_CFLAGS)
@@ -472,9 +472,9 @@ dwarf5_alloc_LDADD = libbacktrace_alloc.la
 
 BUILDTESTS += dwarf5_alloc
 
-if HAVE_DSYMUTIL
+if USE_DSYMUTIL
 check_DATA += dwarf5_alloc.dSYM
-endif HAVE_DSYMUTIL
+endif USE_DSYMUTIL
 
 endif
 
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 0659ea60484..ec456bf4a1f 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -510,7 +510,7 @@ AM_CONDITIONAL(HAVE_OBJCOPY_DEBUGLINK, test 
"$libbacktrace_cv_objcopy_debuglink"
 
 AC_ARG_VAR(DSYMUTIL, [location of dsymutil])
 AC_CHECK_PROG(DSYMUTIL, dsymutil, dsymutil)
-AM_CONDITIONAL(HAVE_DSYMUTIL, test -n "${DSYMUTIL}")
+AM_CONDITIONAL(USE_DSYMUTIL, test -n "${DSYMUTIL}" -a "$FORMAT_FILE" = 
"macho.lo")
 
 AC_ARG_VAR(NM, [location of nm])
 AC_CHECK_PROG(NM, nm, nm)


Re: libbacktrace patch committed: Avoid ambiguous binary search

2020-09-22 Thread Ian Lance Taylor via Gcc-patches
On Tue, Sep 8, 2020 at 6:22 PM Ian Lance Taylor  wrote:
>
> This patch to libbacktrace avoids ambiguous binary searches.
> Searching for a range match can cause the search order to not match
> the sort order, which can cause libbacktrace to miss matching entries.
> This patch allocates an extra entry at the end of function_addrs and
> unit_addrs vectors, so that we can safely compare to the next entry
> when searching.  It adjusts the matching code accordingly.  This fixes
> https://github.com/ianlancetaylor/libbacktrace/issues/44.
> Bootstrapped and ran libbacktrace and libgo tests on
> x86_64-pc-linux-gnu.  Committed to mainline.

I realized that this isn't quite right for the case where the PC value
we are looking up is equal to the low value in the array we are
searching.  In that case to ensure consistent results we have to step
forward to the end of the sequence of identical low values, and only
then step backward.  This patch implements that.  It also ensures that
the right thing happens if someone decides to look up the PC value -1.
Bootstrapped and ran libbacktrace and Go tests on x86_64-pc-linux-gnu.
Committed to mainline.

Ian

* dwarf.c (report_inlined_functions): Handle PC == -1 and PC ==
p->low.
(dwarf_lookup_pc): Likewise.
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 386701bffea..582f34bc816 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -3558,6 +3558,11 @@ report_inlined_functions (uintptr_t pc, struct function 
*function,
   if (function->function_addrs_count == 0)
 return 0;
 
+  /* Our search isn't safe if pc == -1, as that is the sentinel
+ value.  */
+  if (pc + 1 == 0)
+return 0;
+
   p = ((struct function_addrs *)
bsearch (, function->function_addrs,
function->function_addrs_count,
@@ -3567,9 +3572,12 @@ report_inlined_functions (uintptr_t pc, struct function 
*function,
 return 0;
 
   /* Here pc >= p->low && pc < (p + 1)->low.  The function_addrs are
- sorted by low, so we are at the end of a range of function_addrs
- with the same low alue.  Walk backward and use the first range
- that includes pc.  */
+ sorted by low, so if pc > p->low we are at the end of a range of
+ function_addrs with the same low value.  If pc == p->low walk
+ forward to the end of the range with that low value.  Then walk
+ backward and use the first range that includes pc.  */
+  while (pc == (p + 1)->low)
+++p;
   match = NULL;
   while (1)
 {
@@ -3636,8 +3644,10 @@ dwarf_lookup_pc (struct backtrace_state *state, struct 
dwarf_data *ddata,
 
   *found = 1;
 
-  /* Find an address range that includes PC.  */
-  entry = (ddata->addrs_count == 0
+  /* Find an address range that includes PC.  Our search isn't safe if
+ PC == -1, as we use that as a sentinel value, so skip the search
+ in that case.  */
+  entry = (ddata->addrs_count == 0 || pc + 1 == 0
   ? NULL
   : bsearch (, ddata->addrs, ddata->addrs_count,
  sizeof (struct unit_addrs), unit_addrs_search));
@@ -3649,9 +3659,12 @@ dwarf_lookup_pc (struct backtrace_state *state, struct 
dwarf_data *ddata,
 }
 
   /* Here pc >= entry->low && pc < (entry + 1)->low.  The unit_addrs
- are sorted by low, so we are at the end of a range of unit_addrs
- with the same low value.  Walk backward and use the first range
- that includes pc.  */
+ are sorted by low, so if pc > p->low we are at the end of a range
+ of unit_addrs with the same low value.  If pc == p->low walk
+ forward to the end of the range with that low value.  Then walk
+ backward and use the first range that includes pc.  */
+  while (pc == (entry + 1)->low)
+++entry;
   found_entry = 0;
   while (1)
 {
@@ -3832,9 +3845,12 @@ dwarf_lookup_pc (struct backtrace_state *state, struct 
dwarf_data *ddata,
 return callback (data, pc, ln->filename, ln->lineno, NULL);
 
   /* Here pc >= p->low && pc < (p + 1)->low.  The function_addrs are
- sorted by low, so we are at the end of a range of function_addrs
- with the same low alue.  Walk backward and use the first range
- that includes pc.  */
+ sorted by low, so if pc > p->low we are at the end of a range of
+ function_addrs with the same low value.  If pc == p->low walk
+ forward to the end of the range with that low value.  Then walk
+ backward and use the first range that includes pc.  */
+  while (pc == (p + 1)->low)
+++p;
   fmatch = NULL;
   while (1)
 {


libbacktrace patch committed: Don't strip underscore on 64-bit PE

2020-09-08 Thread Ian Lance Taylor via Gcc-patches
This patch to libbacktrace avoids stripping a leading underscore from
symbol names on 64-bit PE COFF.  Bootstrapped and ran Go tests on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* pecoff.c (coff_initialize_syminfo): Add is_64 parameter.
(coff_add): Determine and pass is_64.
diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c
index 221571c862e..49e5c3d868c 100644
--- a/libbacktrace/pecoff.c
+++ b/libbacktrace/pecoff.c
@@ -330,7 +330,7 @@ coff_is_function_symbol (const b_coff_internal_symbol *isym)
 
 static int
 coff_initialize_syminfo (struct backtrace_state *state,
-uintptr_t base_address,
+uintptr_t base_address, int is_64,
 const b_coff_section_header *sects, size_t sects_num,
 const b_coff_external_symbol *syms, size_t syms_size,
 const unsigned char *strtab, size_t strtab_size,
@@ -426,9 +426,12 @@ coff_initialize_syminfo (struct backtrace_state *state,
  else
name = isym.name;
 
- /* Strip leading '_'.  */
- if (name[0] == '_')
-   name++;
+ if (!is_64)
+   {
+ /* Strip leading '_'.  */
+ if (name[0] == '_')
+   name++;
+   }
 
  /* Symbol value is section relative, so we need to read the address
 of its section.  */
@@ -605,6 +608,7 @@ coff_add (struct backtrace_state *state, int descriptor,
   off_t max_offset;
   struct backtrace_view debug_view;
   int debug_view_valid;
+  int is_64;
   uintptr_t image_base;
   struct dwarf_sections dwarf_sections;
 
@@ -680,12 +684,16 @@ coff_add (struct backtrace_state *state, int descriptor,
   sects = (const b_coff_section_header *)
 (sects_view.data + fhdr.size_of_optional_header);
 
+  is_64 = 0;
   if (fhdr.size_of_optional_header > sizeof (*opt_hdr))
 {
   if (opt_hdr->magic == PE_MAGIC)
image_base = opt_hdr->u.pe.image_base;
   else if (opt_hdr->magic == PEP_MAGIC)
-   image_base = opt_hdr->u.pep.image_base;
+   {
+ image_base = opt_hdr->u.pep.image_base;
+ is_64 = 1;
+   }
   else
{
  error_callback (data, "bad magic in PE optional header", 0);
@@ -778,7 +786,7 @@ coff_add (struct backtrace_state *state, int descriptor,
   if (sdata == NULL)
goto fail;
 
-  if (!coff_initialize_syminfo (state, image_base,
+  if (!coff_initialize_syminfo (state, image_base, is_64,
sects, sects_num,
syms_view.data, syms_size,
str_view.data, str_size,


libbacktrace patch committed: Get executable name on macOS

2020-09-08 Thread Ian Lance Taylor via Gcc-patches
This patch to libbacktrace gets the executable name on macOS using
_NSGetExecutablePath.  This is another aspect of PR 96973.  Tested
basic functionality on macOS.  Bootstrapped and ran libbacktrace tests
on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

 * fileline.c (macho_get_executable_path): New static function.
(fileline_initialize): Call macho_get_executable_path.
diff --git a/libbacktrace/fileline.c b/libbacktrace/fileline.c
index cc1011e8b5d..be62b9899c5 100644
--- a/libbacktrace/fileline.c
+++ b/libbacktrace/fileline.c
@@ -43,6 +43,10 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include 
 #endif
 
+#ifdef HAVE_MACH_O_DYLD_H
+#include 
+#endif
+
 #include "backtrace.h"
 #include "internal.h"
 
@@ -122,6 +126,35 @@ sysctl_exec_name2 (struct backtrace_state *state,
 
 #endif /* defined (HAVE_KERN_PROC_ARGS) || |defined (HAVE_KERN_PROC) */
 
+#ifdef HAVE_MACH_O_DYLD_H
+
+static char *
+macho_get_executable_path (struct backtrace_state *state,
+  backtrace_error_callback error_callback, void *data)
+{
+  uint32_t len;
+  char *name;
+
+  len = 0;
+  if (_NSGetExecutablePath (NULL, ) == 0)
+return NULL;
+  name = (char *) backtrace_alloc (state, len, error_callback, data);
+  if (name == NULL)
+return NULL;
+  if (_NSGetExecutablePath (name, ) != 0)
+{
+  backtrace_free (state, name, len, error_callback, data);
+  return NULL;
+}
+  return name;
+}
+
+#else /* !defined (HAVE_MACH_O_DYLD_H) */
+
+#define macho_get_executable_path(state, error_callback, data) NULL
+
+#endif /* !defined (HAVE_MACH_O_DYLD_H) */
+
 /* Initialize the fileline information from the executable.  Returns 1
on success, 0 on failure.  */
 
@@ -159,7 +192,7 @@ fileline_initialize (struct backtrace_state *state,
 
   descriptor = -1;
   called_error_callback = 0;
-  for (pass = 0; pass < 7; ++pass)
+  for (pass = 0; pass < 8; ++pass)
 {
   int does_not_exist;
 
@@ -188,6 +221,9 @@ fileline_initialize (struct backtrace_state *state,
case 6:
  filename = sysctl_exec_name2 (state, error_callback, data);
  break;
+   case 7:
+ filename = macho_get_executable_path (state, error_callback, data);
+ break;
default:
  abort ();
}


libbacktrace patch committed: Avoid ambiguous binary search

2020-09-08 Thread Ian Lance Taylor via Gcc-patches
This patch to libbacktrace avoids ambiguous binary searches.
Searching for a range match can cause the search order to not match
the sort order, which can cause libbacktrace to miss matching entries.
This patch allocates an extra entry at the end of function_addrs and
unit_addrs vectors, so that we can safely compare to the next entry
when searching.  It adjusts the matching code accordingly.  This fixes
https://github.com/ianlancetaylor/libbacktrace/issues/44.
Bootstrapped and ran libbacktrace and libgo tests on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian


* dwarf.c (function_addrs_search): Compare against the next entry
low address, not the high address.
(unit_addrs_search): Likewise.
(build_address_map): Add a trailing unit_addrs.
(read_function_entry): Add a trailing function_addrs.
(read_function_info): Likewise.
(report_inlined_functions): Search backward for function_addrs
match.
(dwarf_lookup_pc): Search backward for unit_addrs and
function_addrs matches.
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 006c8181622..386701bffea 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -1164,9 +1164,11 @@ function_addrs_compare (const void *v1, const void *v2)
   return strcmp (a1->function->name, a2->function->name);
 }
 
-/* Compare a PC against a function_addrs for bsearch.  Note that if
-   there are multiple ranges containing PC, which one will be returned
-   is unpredictable.  We compensate for that in dwarf_fileline.  */
+/* Compare a PC against a function_addrs for bsearch.  We always
+   allocate an entra entry at the end of the vector, so that this
+   routine can safely look at the next entry.  Note that if there are
+   multiple ranges containing PC, which one will be returned is
+   unpredictable.  We compensate for that in dwarf_fileline.  */
 
 static int
 function_addrs_search (const void *vkey, const void *ventry)
@@ -1178,7 +1180,7 @@ function_addrs_search (const void *vkey, const void 
*ventry)
   pc = *key;
   if (pc < entry->low)
 return -1;
-  else if (pc >= entry->high)
+  else if (pc > (entry + 1)->low)
 return 1;
   else
 return 0;
@@ -1249,9 +1251,11 @@ unit_addrs_compare (const void *v1, const void *v2)
   return 0;
 }
 
-/* Compare a PC against a unit_addrs for bsearch.  Note that if there
-   are multiple ranges containing PC, which one will be returned is
-   unpredictable.  We compensate for that in dwarf_fileline.  */
+/* Compare a PC against a unit_addrs for bsearch.  We always allocate
+   an entry entry at the end of the vector, so that this routine can
+   safely look at the next entry.  Note that if there are multiple
+   ranges containing PC, which one will be returned is unpredictable.
+   We compensate for that in dwarf_fileline.  */
 
 static int
 unit_addrs_search (const void *vkey, const void *ventry)
@@ -1263,7 +1267,7 @@ unit_addrs_search (const void *vkey, const void *ventry)
   pc = *key;
   if (pc < entry->low)
 return -1;
-  else if (pc >= entry->high)
+  else if (pc > (entry + 1)->low)
 return 1;
   else
 return 0;
@@ -2091,6 +2095,7 @@ build_address_map (struct backtrace_state *state, 
uintptr_t base_address,
   size_t i;
   struct unit **pu;
   size_t unit_offset = 0;
+  struct unit_addrs *pa;
 
   memset (>vec, 0, sizeof addrs->vec);
   memset (_vec->vec, 0, sizeof unit_vec->vec);
@@ -2231,6 +2236,17 @@ build_address_map (struct backtrace_state *state, 
uintptr_t base_address,
   if (info.reported_underflow)
 goto fail;
 
+  /* Add a trailing addrs entry, but don't include it in addrs->count.  */
+  pa = ((struct unit_addrs *)
+   backtrace_vector_grow (state, sizeof (struct unit_addrs),
+  error_callback, data, >vec));
+  if (pa == NULL)
+goto fail;
+  pa->low = 0;
+  --pa->low;
+  pa->high = pa->low;
+  pa->u = NULL;
+
   unit_vec->vec = units;
   unit_vec->count = units_count;
   return 1;
@@ -3404,8 +3420,23 @@ read_function_entry (struct backtrace_state *state, 
struct dwarf_data *ddata,
 
  if (fvec.count > 0)
{
+ struct function_addrs *p;
  struct function_addrs *faddrs;
 
+ /* Allocate a trailing entry, but don't include it
+in fvec.count.  */
+ p = ((struct function_addrs *)
+  backtrace_vector_grow (state,
+ sizeof (struct function_addrs),
+ error_callback, data,
+ ));
+ if (p == NULL)
+   return 0;
+ p->low = 0;
+ --p->low;
+ p->high = p->low;
+ p->function = NULL;
+
  if (!backtrace_vector_release (state, ,
 error_callback, data))
return 0;
@@ -3439,6 +3470,7 @@ read_function_info (struct backtrace_state 

libbacktrace patch committed: Correct tipo in comment

2020-09-08 Thread Ian Lance Taylor via Gcc-patches
This patch suggested by Ondřej Čertík fixes a typpo in a comment.
Bootstrapped and ran libbacktrace tests on x86_64-pc-linux-gnu.
Committed to mainline.

Ian

* simple.c (simple_unwind): Correct comment spelling.
diff --git a/libbacktrace/simple.c b/libbacktrace/simple.c
index b9b971af95e..9ba660c871c 100644
--- a/libbacktrace/simple.c
+++ b/libbacktrace/simple.c
@@ -55,7 +55,7 @@ struct backtrace_simple_data
   int ret;
 };
 
-/* Unwind library callback routine.  This is passd to
+/* Unwind library callback routine.  This is passed to
_Unwind_Backtrace.  */
 
 static _Unwind_Reason_Code


libbacktrace patch committed: Correct Mach-O memory allocation

2020-09-08 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch corrects the amount of memory allocated when
looking for the Mach-O dsym file.  We weren't allocating space for the
backslash.  Thanks to Alex Crichton for noticing this.  This also
fixes the amount of space released when freeing diralc in the same
function.  Thanks to Francois-Xavier Coudert for noticing that.
Bootstrapped and ran libbacktrace tests on x86_64-pc-linux-gnu.
Committed to mainline.

Ian


* macho.c (macho_add_dsym): Make space for '/' in dsym.  Use
correct length when freeing diralc.


libbacktrace patch committed: Correctly swap Mach-O fat 32-bit file offset

2020-09-08 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch correctly swaps the 32-bit file offset in a
Mach-O fat file.  This is based on a patch by Francois-Xavier Coudert
, who analyzed the problem.  This is for PR 96973.  Bootstrapped and
ran libbacktrace tests on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

PR libbacktrace/96973
 * macho.c (macho_add_fat): Correctly swap 32-bit file offset.
diff --git a/libbacktrace/macho.c b/libbacktrace/macho.c
index bd737226ca6..20dd3262d58 100644
--- a/libbacktrace/macho.c
+++ b/libbacktrace/macho.c
@@ -793,13 +793,24 @@ macho_add_fat (struct backtrace_state *state, const char 
*filename,
 
   for (i = 0; i < nfat_arch; ++i)
 {
-  struct macho_fat_arch_64 fat_arch;
   uint32_t fcputype;
+  uint64_t foffset;
 
   if (is_64)
-   memcpy (_arch,
-   (const char *) arch_view.data + i * arch_size,
-   arch_size);
+   {
+ struct macho_fat_arch_64 fat_arch_64;
+
+ memcpy (_arch_64,
+ (const char *) arch_view.data + i * arch_size,
+ arch_size);
+ fcputype = fat_arch_64.cputype;
+ foffset = fat_arch_64.offset;
+ if (swapped)
+   {
+ fcputype = __builtin_bswap32 (fcputype);
+ foffset = __builtin_bswap64 (foffset);
+   }
+   }
   else
{
  struct macho_fat_arch fat_arch_32;
@@ -807,26 +818,18 @@ macho_add_fat (struct backtrace_state *state, const char 
*filename,
  memcpy (_arch_32,
  (const char *) arch_view.data + i * arch_size,
  arch_size);
- fat_arch.cputype = fat_arch_32.cputype;
- fat_arch.cpusubtype = fat_arch_32.cpusubtype;
- fat_arch.offset = (uint64_t) fat_arch_32.offset;
- fat_arch.size = (uint64_t) fat_arch_32.size;
- fat_arch.align = fat_arch_32.align;
- fat_arch.reserved = 0;
+ fcputype = fat_arch_32.cputype;
+ foffset = (uint64_t) fat_arch_32.offset;
+ if (swapped)
+   {
+ fcputype = __builtin_bswap32 (fcputype);
+ foffset = (uint64_t) __builtin_bswap32 ((uint32_t) foffset);
+   }
}
 
-  fcputype = fat_arch.cputype;
-  if (swapped)
-   fcputype = __builtin_bswap32 (fcputype);
-
   if (fcputype == cputype)
{
- uint64_t foffset;
-
  /* FIXME: What about cpusubtype?  */
- foffset = fat_arch.offset;
- if (swapped)
-   foffset = __builtin_bswap64 (foffset);
  backtrace_release_view (state, _view, error_callback, data);
  return macho_add (state, filename, descriptor, foffset, match_uuid,
base_address, skip_symtab, error_callback, data,


libbacktrace patch committed: Only match magic number at start of file

2020-09-08 Thread Ian Lance Taylor via Gcc-patches
This patch fixes the libbacktrace file type detection, which is run at
configure time, to only look for a magic number at the very start of
the file.  Otherwise we can get confused if the bytes happen to appear
elsewhere on the first "line".  This is for PR 96971.  Bootstrapped
and ran libbacktrace tests on x86_64-pc-linux-gnu.  Committed to
mainline.

Ian

PR libbacktrace/96971
* filetype.awk: Only match magic number at start of line.
diff --git a/libbacktrace/filetype.awk b/libbacktrace/filetype.awk
index 14d91581f7e..1eefa7e72f0 100644
--- a/libbacktrace/filetype.awk
+++ b/libbacktrace/filetype.awk
@@ -1,13 +1,13 @@
 # An awk script to determine the type of a file.
-/\177ELF\001/  { if (NR == 1) { print "elf32"; exit } }
-/\177ELF\002/  { if (NR == 1) { print "elf64"; exit } }
-/\114\001/ { if (NR == 1) { print "pecoff"; exit } }
-/\144\206/ { if (NR == 1) { print "pecoff"; exit } }
-/\001\337/ { if (NR == 1) { print "xcoff32"; exit } }
-/\001\367/ { if (NR == 1) { print "xcoff64"; exit } }
-/\376\355\372\316/ { if (NR == 1) { print "macho"; exit } }
-/\316\372\355\376/ { if (NR == 1) { print "macho"; exit } }
-/\376\355\372\317/ { if (NR == 1) { print "macho"; exit } }
-/\317\372\355\376/ { if (NR == 1) { print "macho"; exit } }
-/\312\376\272\276/ { if (NR == 1) { print "macho"; exit } }
-/\276\272\376\312/ { if (NR == 1) { print "macho"; exit } }
+/^\177ELF\001/  { if (NR == 1) { print "elf32"; exit } }
+/^\177ELF\002/  { if (NR == 1) { print "elf64"; exit } }
+/^\114\001/ { if (NR == 1) { print "pecoff"; exit } }
+/^\144\206/ { if (NR == 1) { print "pecoff"; exit } }
+/^\001\337/ { if (NR == 1) { print "xcoff32"; exit } }
+/^\001\367/ { if (NR == 1) { print "xcoff64"; exit } }
+/^\376\355\372\316/ { if (NR == 1) { print "macho"; exit } }
+/^\316\372\355\376/ { if (NR == 1) { print "macho"; exit } }
+/^\376\355\372\317/ { if (NR == 1) { print "macho"; exit } }
+/^\317\372\355\376/ { if (NR == 1) { print "macho"; exit } }
+/^\312\376\272\276/ { if (NR == 1) { print "macho"; exit } }
+/^\276\272\376\312/ { if (NR == 1) { print "macho"; exit } }


libbacktrace patch committed: Add support for Mach-O 64-bit FAT files

2020-08-24 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch adds support for Mach-O 64-bit FAT files.
Bootstrapped and tested on x86_64-pc-linux-gnu.  Committed to
mainline.

Ian

libbacktrace/:
* macho.c (MACH_O_MH_MAGIC_FAT_64): Define.
(MACH_O_MH_CIGAM_FAT_64): Define.
(struct macho_fat_arch_64): Define.
(macho_add_fat): Add and use is_64 parameter.
(macho_add): Recognize 64-bit fat files.
diff --git a/libbacktrace/macho.c b/libbacktrace/macho.c
index 3aea70cdbbe..bd737226ca6 100644
--- a/libbacktrace/macho.c
+++ b/libbacktrace/macho.c
@@ -75,7 +75,7 @@ struct macho_header_64
 
 struct macho_header_fat
 {
-  uint32_t magic;  /* Magic number (MACH_O_MH_MAGIC_FAT) */
+  uint32_t magic;  /* Magic number (MACH_O_MH_(MAGIC|CIGAM)_FAT(_64)?) */
   uint32_t nfat_arch;   /* Number of components */
 };
 
@@ -85,6 +85,8 @@ struct macho_header_fat
 #define MACH_O_MH_MAGIC_64 0xfeedfacf
 #define MACH_O_MH_MAGIC_FAT0xcafebabe
 #define MACH_O_MH_CIGAM_FAT0xbebafeca
+#define MACH_O_MH_MAGIC_FAT_64 0xcafebabf
+#define MACH_O_MH_CIGAM_FAT_64 0xbfbafeca
 
 /* Value for the header filetype field.  */
 
@@ -105,6 +107,20 @@ struct macho_fat_arch
   uint32_t align;  /* Alignment of this entry */
 };
 
+/* A component of a 64-bit fat file.  This is used if the magic field
+   is MAGIC_FAT_64.  This is only used when some file size or file
+   offset is too large to represent in the 32-bit format.  */
+
+struct macho_fat_arch_64
+{
+  uint32_t cputype;/* CPU type */
+  uint32_t cpusubtype; /* CPU subtype */
+  uint64_t offset; /* File offset of this entry */
+  uint64_t size;   /* Size of this entry */
+  uint32_t align;  /* Alignment of this entry */
+  uint32_t reserved;   /* Reserved */
+};
+
 /* Values for the fat_arch cputype field (and the header cputype
field).  */
 
@@ -740,14 +756,14 @@ static int
 macho_add_fat (struct backtrace_state *state, const char *filename,
   int descriptor, int swapped, off_t offset,
   const unsigned char *match_uuid, uintptr_t base_address,
-  int skip_symtab, uint32_t nfat_arch,
+  int skip_symtab, uint32_t nfat_arch, int is_64,
   backtrace_error_callback error_callback, void *data,
   fileline *fileline_fn, int *found_sym)
 {
   int arch_view_valid;
   unsigned int cputype;
+  size_t arch_size;
   struct backtrace_view arch_view;
-  size_t archoffset;
   unsigned int i;
 
   arch_view_valid = 0;
@@ -765,21 +781,39 @@ macho_add_fat (struct backtrace_state *state, const char 
*filename,
   goto fail;
 #endif
 
+  if (is_64)
+arch_size = sizeof (struct macho_fat_arch_64);
+  else
+arch_size = sizeof (struct macho_fat_arch);
+
   if (!backtrace_get_view (state, descriptor, offset,
-  nfat_arch * sizeof (struct macho_fat_arch),
+  nfat_arch * arch_size,
   error_callback, data, _view))
 goto fail;
 
-  archoffset = 0;
   for (i = 0; i < nfat_arch; ++i)
 {
-  struct macho_fat_arch fat_arch;
+  struct macho_fat_arch_64 fat_arch;
   uint32_t fcputype;
 
-  memcpy (_arch,
- ((const char *) arch_view.data
-  + i * sizeof (struct macho_fat_arch)),
- sizeof fat_arch);
+  if (is_64)
+   memcpy (_arch,
+   (const char *) arch_view.data + i * arch_size,
+   arch_size);
+  else
+   {
+ struct macho_fat_arch fat_arch_32;
+
+ memcpy (_arch_32,
+ (const char *) arch_view.data + i * arch_size,
+ arch_size);
+ fat_arch.cputype = fat_arch_32.cputype;
+ fat_arch.cpusubtype = fat_arch_32.cpusubtype;
+ fat_arch.offset = (uint64_t) fat_arch_32.offset;
+ fat_arch.size = (uint64_t) fat_arch_32.size;
+ fat_arch.align = fat_arch_32.align;
+ fat_arch.reserved = 0;
+   }
 
   fcputype = fat_arch.cputype;
   if (swapped)
@@ -787,19 +821,17 @@ macho_add_fat (struct backtrace_state *state, const char 
*filename,
 
   if (fcputype == cputype)
{
- uint32_t foffset;
+ uint64_t foffset;
 
  /* FIXME: What about cpusubtype?  */
  foffset = fat_arch.offset;
  if (swapped)
-   foffset = __builtin_bswap32 (foffset);
+   foffset = __builtin_bswap64 (foffset);
  backtrace_release_view (state, _view, error_callback, data);
  return macho_add (state, filename, descriptor, foffset, match_uuid,
base_address, skip_symtab, error_callback, data,
fileline_fn, found_sym);
}
-
-  archoffset += sizeof (struct macho_fat_arch);
 }
 
   error_callback (data, "could not find executable in fat file", 0);
@@ -980,6 +1012,7 @@ macho_add (struct backtrace_state *state, const char 
*filename, int descriptor,
   hdroffset = offset + sizeof (struct macho_header_64);
   

libbacktrace patch committed: Mark state unused in ztest.c test_large

2020-05-13 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch marks the state parameter of test_large in
ztest.c as ATTRIBUTE_UNUSED.  The parameter is not used if HAVE_ZLIB
is not defined.  Bootstrapped and ran libbacktrace tests on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

2020-05-13  Ian Lance Taylor  

* ztest.c (test_large): Mark state ATTRIBUTE_UNUSED.
diff --git a/libbacktrace/ztest.c b/libbacktrace/ztest.c
index 2663c90061a..39476704972 100644
--- a/libbacktrace/ztest.c
+++ b/libbacktrace/ztest.c
@@ -294,7 +294,7 @@ average_time (const size_t *times, size_t trials)
 /* Test a larger text, if available.  */
 
 static void
-test_large (struct backtrace_state *state)
+test_large (struct backtrace_state *state ATTRIBUTE_UNUSED)
 {
 #ifdef HAVE_ZLIB
   unsigned char *orig_buf;


libbacktrace patch committed: Treat EACCES like ENOENT

2020-05-13 Thread Ian Lance Taylor via Gcc-patches
This patch to libbacktrace treats an EACCES error when opening a file
like an ENOENT error.  This case happens when running the libgo
syscall tests as root, when testing various ways of restricting a
child process.  Bootstrapped and ran libbacktrace and Go tests on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

2020-05-13  Ian Lance Taylor  

PR go/95061
* posix.c (backtrace_open): Treat EACCESS like ENOENT.
diff --git a/libbacktrace/posix.c b/libbacktrace/posix.c
index 356e72b4a3b..a2c88dd8e4a 100644
--- a/libbacktrace/posix.c
+++ b/libbacktrace/posix.c
@@ -67,7 +67,11 @@ backtrace_open (const char *filename, 
backtrace_error_callback error_callback,
   descriptor = open (filename, (int) (O_RDONLY | O_BINARY | O_CLOEXEC));
   if (descriptor < 0)
 {
-  if (does_not_exist != NULL && errno == ENOENT)
+  /* If DOES_NOT_EXIST is not NULL, then don't call ERROR_CALLBACK
+if the file does not exist.  We treat lacking permission to
+open the file as the file not existing; this case arises when
+running the libgo syscall package tests as root.  */
+  if (does_not_exist != NULL && (errno == ENOENT || errno == EACCES))
*does_not_exist = 1;
   else
error_callback (data, filename, errno);


libbacktrace patch committed: Declare getpagesize if necessary

2020-05-11 Thread Ian Lance Taylor via Gcc-patches
Reportedly mingw-w64-gcc has mmap and getpagesize but does not provide
a declaration of getpagesize in any header files.  Check for a
getpagesize declaration, and declare it if necessary.  This is for PR
95012.  Bootstrapped and ran libbacktrace tests on
x86_64-pc-linux-gnu.  Committed to master.

Ian

2020-05-11  Ian Lance Taylor  

PR libbacktrace/95012
* configure.ac: Check for getpagesize declaration.
* mmap.c: Declare getpagesize if necessary.
* mmapio.c: Likewise.
* configure: Regenerate.
* config.h.in: Regenerate.
* Makefile.in: Regenerate.
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 6f241c5bac0..de9cf628b47 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -376,7 +376,7 @@ if test "$have_fcntl" = "yes"; then
[Define to 1 if you have the fcntl function])
 fi
 
-AC_CHECK_DECLS(strnlen)
+AC_CHECK_DECLS(strnlen getpagesize)
 AC_CHECK_FUNCS(lstat readlink)
 
 # Check for getexecname function.
diff --git a/libbacktrace/mmap.c b/libbacktrace/mmap.c
index dd7d519cc56..6c8bd5d4a19 100644
--- a/libbacktrace/mmap.c
+++ b/libbacktrace/mmap.c
@@ -42,6 +42,10 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include "backtrace.h"
 #include "internal.h"
 
+#ifndef HAVE_DECL_GETPAGESIZE
+extern int getpagesize (void);
+#endif
+
 /* Memory allocation on systems that provide anonymous mmap.  This
permits the backtrace functions to be invoked from a signal
handler, assuming that mmap is async-signal safe.  */
diff --git a/libbacktrace/mmapio.c b/libbacktrace/mmapio.c
index 5dd39525ba1..69cd8065a49 100644
--- a/libbacktrace/mmapio.c
+++ b/libbacktrace/mmapio.c
@@ -40,6 +40,10 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include "backtrace.h"
 #include "internal.h"
 
+#ifndef HAVE_DECL_GETPAGESIZE
+extern int getpagesize (void);
+#endif
+
 #ifndef MAP_FAILED
 #define MAP_FAILED ((void *)-1)
 #endif


libbacktrace patch committed: Don't crash if no section headers

2020-05-09 Thread Ian Lance Taylor via Gcc-patches
This patch to libbacktrace, by Roland McGrath, avoids crashing if an
ELF file has no section headers.  Bootstrapped and ran libbacktrace
testsuite on x86_64-pc-linux-gnu.  This fixes
https://github.com/ianlancetaylor/libbacktrace/issues/41.  Committed
to master.

Ian

2020-05-09  Roland McGrath  

* elf.c (elf_add): Bail early if there are no section headers at all.
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 1216af86fd9..80a00506bd6 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -2781,6 +2781,9 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
   backtrace_release_view (state, _view, error_callback, data);
 }
 
+  if (shnum == 0 || shstrndx == 0)
+goto fail;
+
   /* To translate PC to file/line when using DWARF, we need to find
  the .debug_info and .debug_line sections.  */
 


libbacktrace patch committed: Don't free strtab if error after reading symbols

2020-05-09 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch fixes the ELF support so that after reading
symbol information we don't free the strtab, even if we encounter an
error later while reading debug info.  This fixes programs that try to
get symbol information even if they can't get backtrace information.
Bootstrapped and ran libbacktrace tests on x86_64-pc-linux-gnu.
Committed to mainline.

Ian

2020-05-09  Ian Lance Taylor  

* elf.c (elf_add): Don't free strtab if an error occurs after
recording symbol information.
index eb481c588e7..1216af86fd9 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -3011,6 +3011,7 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
 string table permanently.  */
   backtrace_release_view (state, _view, error_callback, data);
   symtab_view_valid = 0;
+  strtab_view_valid = 0;
 
   *found_sym = 1;
 


libbacktrace patch committed: Add Mach-O support

2020-05-09 Thread Ian Lance Taylor via Gcc-patches
This patch to libbacktrace adds Mach-O support.  Bootstrapped and
tested on macOS.  Most tests pass, but a couple still fail.  This is
for PR 88745.  Committed to master.

Ian

2020-05-09  Ian Lance Taylor  

PR libbacktrace/88745
* macho.c: New file.
* filetype.awk: Recognize Mach-O files.
* Makefile.am (FORMAT_FILES): Add macho.c.
(check_DATA): New variable.  Set to .dSYM if HAVE_DSYMUTIL.
(%.dSYM): New pattern target.
(test_macho_SOURCES, test_macho_CFLAGS): New targets.
(test_macho_LDADD): New target.
(BUILDTESTS): Add test_macho.
(macho.lo): Add dependencies.
* configure.ac: Recognize macho file type.  Check for
mach-o/dyld.h.  Don't try to run objcopy if we don't find it.
Look for dsymutil and define a HAVE_DSYMUTIL conditional.
* Makefile.in: Regenerate.
* configure: Regenerate.
* config.h.in: Regenerate.
diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am
index c73f6633a76..d3a9ba8843a 100644
--- a/libbacktrace/Makefile.am
+++ b/libbacktrace/Makefile.am
@@ -56,6 +56,7 @@ BACKTRACE_FILES = \
 
 FORMAT_FILES = \
elf.c \
+   macho.c \
pecoff.c \
unknown.c \
xcoff.c
@@ -84,18 +85,28 @@ libbacktrace_la_DEPENDENCIES = $(libbacktrace_la_LIBADD)
 
 # Testsuite.
 
-# Add test to this variable, if you want it to be build.
+# Add a test to this variable if you want it to be built.
 check_PROGRAMS =
 
-# Add test to this variable, if you want it to be run.
+# Add a test to this variable if you want it to be run.
 TESTS =
 
-# Add test to this variable, if you want it to be build and run.
+# Add a test to this variable if you want it to be built and run.
 BUILDTESTS =
 
+# Add a file to this variable if you want it to be built for testing.
+check_DATA =
+
 # Flags to use when compiling test programs.
 libbacktrace_TEST_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) -g
 
+if HAVE_DSYMUTIL
+
+%.dSYM: %
+   $(DSYMUTIL) $<
+
+endif HAVE_DSYMUTIL
+
 if NATIVE
 check_LTLIBRARIES = libbacktrace_alloc.la
 
@@ -163,6 +174,12 @@ test_elf_64_LDADD = libbacktrace_noformat.la elf_64.lo
 
 BUILDTESTS += test_elf_64
 
+test_macho_SOURCES = test_format.c testlib.c
+test_macho_CFLAGS = $(libbacktrace_TEST_CFLAGS)
+test_macho_LDADD = libbacktrace_noformat.la macho.lo
+
+BUILDTESTS += test_macho
+
 test_xcoff_32_SOURCES = test_format.c testlib.c
 test_xcoff_32_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 test_xcoff_32_LDADD = libbacktrace_noformat.la xcoff_32.lo
@@ -220,6 +237,10 @@ allocfail.sh: allocfail
 
 TESTS += allocfail.sh
 
+if HAVE_DSYMUTIL
+check_DATA += allocfail.dSYM
+endif HAVE_DSYMUTIL
+
 if HAVE_ELF
 if HAVE_OBJCOPY_DEBUGLINK
 
@@ -252,6 +273,10 @@ btest_LDADD = libbacktrace.la
 
 BUILDTESTS += btest
 
+if HAVE_DSYMUTIL
+check_DATA += btest.dSYM
+endif HAVE_DSYMUTIL
+
 if HAVE_ELF
 
 btest_lto_SOURCES = btest.c testlib.c
@@ -268,6 +293,10 @@ btest_alloc_LDADD = libbacktrace_alloc.la
 
 BUILDTESTS += btest_alloc
 
+if HAVE_DSYMUTIL
+check_DATA += btest_alloc.dSYM
+endif HAVE_DSYMUTIL
+
 if HAVE_DWZ
 
 %_dwz: %
@@ -294,12 +323,20 @@ stest_LDADD = libbacktrace.la
 
 BUILDTESTS += stest
 
+if HAVE_DSYMUTIL
+check_DATA += stest.dSYM
+endif HAVE_DSYMUTIL
+
 stest_alloc_SOURCES = $(stest_SOURCES)
 stest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 stest_alloc_LDADD = libbacktrace_alloc.la
 
 BUILDTESTS += stest_alloc
 
+if HAVE_DSYMUTIL
+check_DATA += stest_alloc.dSYM
+endif HAVE_DSYMUTIL
+
 if HAVE_ELF
 
 ztest_SOURCES = ztest.c testlib.c
@@ -329,10 +366,18 @@ edtest_LDADD = libbacktrace.la
 
 BUILDTESTS += edtest
 
+if HAVE_DSYMUTIL
+check_DATA += edtest.dSYM
+endif HAVE_DSYMUTIL
+
 edtest_alloc_SOURCES = $(edtest_SOURCES)
 edtest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 edtest_alloc_LDADD = libbacktrace_alloc.la
 
+if HAVE_DSYMUTIL
+check_DATA += edtest_alloc.dSYM
+endif HAVE_DSYMUTIL
+
 BUILDTESTS += edtest_alloc
 
 edtest2_build.c: gen_edtest2_build; @true
@@ -349,12 +394,20 @@ ttest_SOURCES = ttest.c testlib.c
 ttest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -pthread
 ttest_LDADD = libbacktrace.la
 
+if HAVE_DSYMUTIL
+check_DATA += ttest.dSYM
+endif HAVE_DSYMUTIL
+
 BUILDTESTS += ttest_alloc
 
 ttest_alloc_SOURCES = $(ttest_SOURCES)
 ttest_alloc_CFLAGS = $(ttest_CFLAGS)
 ttest_alloc_LDADD = libbacktrace_alloc.la
 
+if HAVE_DSYMUTIL
+check_DATA += ttest_alloc.dSYM
+endif HAVE_DSYMUTIL
+
 endif HAVE_PTHREAD
 
 if HAVE_OBJCOPY_DEBUGLINK
@@ -409,12 +462,20 @@ dwarf5_LDADD = libbacktrace.la
 
 BUILDTESTS += dwarf5
 
+if HAVE_DSYMUTIL
+check_DATA += dwarf5.dSYM
+endif HAVE_DSYMUTIL
+
 dwarf5_alloc_SOURCES = $(dwarf5_SOURCES)
 dwarf5_alloc_CFLAGS = $(dwarf5_CFLAGS)
 dwarf5_alloc_LDADD = libbacktrace_alloc.la
 
 BUILDTESTS += dwarf5_alloc
 
+if HAVE_DSYMUTIL
+check_DATA += dwarf5_alloc.dSYM
+endif HAVE_DSYMUTIL
+
 endif
 
 endif NATIVE
@@ -448,6 +509,7 @@ dwarf.lo: config.h $(INCDIR)/dwarf2.h $(INCDIR)/dwarf2.def \
$(INCDIR)/filenames.h backtrace.h internal.h
 elf.lo: config.h backtrace.h internal.h
 fileline.lo: config.h backtrace.h internal.h
+macho.lo: config.h backtrace.h 

libbacktrace patch committed: Support short reads

2020-05-09 Thread Ian Lance Taylor via Gcc-patches
This patch to libbacktrace handles short reads correctly.  Short reads
are unlikely, but they can reportedly happen when the debug sections
are very large and we aren't using mmap.  Bootstrapped and ran
libbacktrace tests on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

2020-05-09  Ian Lance Taylor  

* read.c (backtrace_get_view): Support short read.
diff --git a/libbacktrace/read.c b/libbacktrace/read.c
index 57e4701bbeb..1a6052bf613 100644
--- a/libbacktrace/read.c
+++ b/libbacktrace/read.c
@@ -50,7 +50,8 @@ backtrace_get_view (struct backtrace_state *state, int 
descriptor,
backtrace_error_callback error_callback,
void *data, struct backtrace_view *view)
 {
-  ssize_t got;
+  uint64_t got;
+  ssize_t r;
 
   if ((uint64_t) (size_t) size != size)
 {
@@ -70,15 +71,22 @@ backtrace_get_view (struct backtrace_state *state, int 
descriptor,
   view->data = view->base;
   view->len = size;
 
-  got = read (descriptor, view->base, size);
-  if (got < 0)
+  got = 0;
+  while (got < size)
 {
-  error_callback (data, "read", errno);
-  free (view->base);
-  return 0;
+  r = read (descriptor, view->base, size - got);
+  if (r < 0)
+   {
+ error_callback (data, "read", errno);
+ free (view->base);
+ return 0;
+   }
+  if (r == 0)
+   break;
+  got += (uint64_t) r;
 }
 
-  if ((size_t) got < size)
+  if (got < size)
 {
   error_callback (data, "file too short", 0);
   free (view->base);


libbacktrace patch committed: sometimes read debug sections individually

2020-05-09 Thread Ian Lance Taylor via Gcc-patches
This patch to libbacktrace changes it to read the debug sections as
individual sections if they are very large or are far apart.  This
uses less memory in some cases, and fixes some cases on 32-bit
systems.  In particular this fixes one of the problems in
https://github.com/ianlancetaylor/libbacktrace/issues/29.
Bootstrapped and ran libbacktrace tests on x86_64-pc-linux-gnu.
Committed to master.

Ian

2020-05-09  Ian Lance Taylor  

* elf.c (elf_add): If debug sections are very large or far apart,
read them individually rather than as a single view.
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 9a866eb5048..eb481c588e7 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -2659,10 +2659,13 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
   uint32_t debugaltlink_buildid_size;
   off_t min_offset;
   off_t max_offset;
+  off_t debug_size;
   struct backtrace_view debug_view;
   int debug_view_valid;
   unsigned int using_debug_view;
   uint16_t *zdebug_table;
+  struct backtrace_view split_debug_view[DEBUG_MAX];
+  unsigned char split_debug_view_valid[DEBUG_MAX];
   struct elf_ppc64_opd_data opd_data, *opd;
   struct dwarf_sections dwarf_sections;
 
@@ -2687,6 +2690,7 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
   debugaltlink_buildid_data = NULL;
   debugaltlink_buildid_size = 0;
   debug_view_valid = 0;
+  memset (_debug_view_valid[0], 0, sizeof split_debug_view_valid);
   opd = NULL;
 
   if (!backtrace_get_view (state, descriptor, 0, sizeof ehdr, error_callback,
@@ -3131,6 +3135,7 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
 
   min_offset = 0;
   max_offset = 0;
+  debug_size = 0;
   for (i = 0; i < (int) DEBUG_MAX; ++i)
 {
   off_t end;
@@ -3142,6 +3147,7 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
  end = sections[i].offset + sections[i].size;
  if (end > max_offset)
max_offset = end;
+ debug_size += sections[i].size;
}
   if (zsections[i].size != 0)
{
@@ -3150,6 +3156,7 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
  end = zsections[i].offset + zsections[i].size;
  if (end > max_offset)
max_offset = end;
+ debug_size += zsections[i].size;
}
 }
   if (min_offset == 0 || max_offset == 0)
@@ -3159,11 +3166,45 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
   return 1;
 }
 
-  if (!backtrace_get_view (state, descriptor, min_offset,
-  max_offset - min_offset,
-  error_callback, data, _view))
-goto fail;
-  debug_view_valid = 1;
+  /* If the total debug section size is large, assume that there are
+ gaps between the sections, and read them individually.  */
+
+  if (max_offset - min_offset < 0x2000
+  || max_offset - min_offset < debug_size + 0x1)
+{
+  if (!backtrace_get_view (state, descriptor, min_offset,
+  max_offset - min_offset,
+  error_callback, data, _view))
+   goto fail;
+  debug_view_valid = 1;
+}
+  else
+{
+  memset (_debug_view[0], 0, sizeof split_debug_view);
+  for (i = 0; i < (int) DEBUG_MAX; ++i)
+   {
+ struct debug_section_info *dsec;
+
+ if (sections[i].size != 0)
+   dsec = [i];
+ else if (zsections[i].size != 0)
+   dsec = [i];
+ else
+   continue;
+
+ if (!backtrace_get_view (state, descriptor, dsec->offset, dsec->size,
+  error_callback, data, _debug_view[i]))
+   goto fail;
+ split_debug_view_valid[i] = 1;
+
+ if (sections[i].size != 0)
+   sections[i].data = ((const unsigned char *)
+   split_debug_view[i].data);
+ else
+   zsections[i].data = ((const unsigned char *)
+split_debug_view[i].data);
+   }
+}
 
   /* We've read all we need from the executable.  */
   if (!backtrace_close (descriptor, error_callback, data))
@@ -3171,22 +3212,25 @@ elf_add (struct backtrace_state *state, const char 
*filename, int descriptor,
   descriptor = -1;
 
   using_debug_view = 0;
-  for (i = 0; i < (int) DEBUG_MAX; ++i)
+  if (debug_view_valid)
 {
-  if (sections[i].size == 0)
-   sections[i].data = NULL;
-  else
+  for (i = 0; i < (int) DEBUG_MAX; ++i)
{
- sections[i].data = ((const unsigned char *) debug_view.data
- + (sections[i].offset - min_offset));
- ++using_debug_view;
-   }
+ if (sections[i].size == 0)
+   sections[i].data = NULL;
+ else
+   {
+ sections[i].data = ((const unsigned char *) debug_view.data
+ + 

libbacktrace patch committed: get executable name on FreeBSD and NetBSD

2020-05-09 Thread Ian Lance Taylor via Gcc-patches
This libbacktrace patch adds the ability to fetch the executable name
on FreeBSD and NetBSD using sysctl when /proc is not mounted.
Bootstrapped and ran libbacktrace tests on x86_64-pc-linux-gnu.
Committed to mainline.

Ian

2020-05-08  Ian Lance Taylor  

* fileline.c (sysctl_exec_name): New static function.
(sysctl_exec_name1): New macro or static function.
(sysctl_exec_name2): Likewise.
(fileline_initialize): Try sysctl_exec_name[12].
* configure.ac: Check for sysctl args to fetch executable name.
* configure: Regenerate.
* config.h.in: Regenerate.
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 3730d7c4b06..5beed68ccf6 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -388,6 +388,36 @@ if test "$have_getexecname" = "yes"; then
   AC_DEFINE(HAVE_GETEXECNAME, 1, [Define if getexecname is available.])
 fi
 
+# Check for sysctl definitions.
+
+AC_CACHE_CHECK([for KERN_PROC],
+[libbacktrace_cv_proc],
+[AC_COMPILE_IFELSE(
+  [AC_LANG_PROGRAM([
+#include 
+#include 
+], [int mib0 = CTL_KERN; int mib1 = KERN_PROC; int mib2 = 
KERN_PROC_PATHNAME;])],
+  [libbacktrace_cv_proc=yes],
+  [libbacktrace_cv_proc=no])])
+if test "$libbacktrace_cv_proc" = "yes"; then
+  AC_DEFINE([HAVE_KERN_PROC], 1,
+[Define to 1 if you have KERN_PROC and KERN_PROC_PATHNAME in 
.])
+fi
+
+AC_CACHE_CHECK([for KERN_PROG_ARGS],
+[libbacktrace_cv_procargs],
+[AC_COMPILE_IFELSE(
+  [AC_LANG_PROGRAM([
+#include 
+#include 
+], [int mib0 = CTL_KERN; int mib1 = KERN_PROC_ARGS; int mib2 = 
KERN_PROC_PATHNAME;])],
+  [libbacktrace_cv_procargs=yes],
+  [libbacktrace_cv_procargs=no])])
+if test "$libbacktrace_cv_procargs" = "yes"; then
+  AC_DEFINE([HAVE_KERN_PROC_ARGS], 1,
+[Define to 1 if you have KERN_PROCARGS and KERN_PROC_PATHNAME in 
.])
+fi
+
 # Check for the clock_gettime function.
 AC_CHECK_FUNCS(clock_gettime)
 clock_gettime_link=
diff --git a/libbacktrace/fileline.c b/libbacktrace/fileline.c
index fd5edbe5ddb..cc1011e8b5d 100644
--- a/libbacktrace/fileline.c
+++ b/libbacktrace/fileline.c
@@ -39,6 +39,10 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include 
 #include 
 
+#if defined (HAVE_KERN_PROC_ARGS) || defined (HAVE_KERN_PROC)
+#include 
+#endif
+
 #include "backtrace.h"
 #include "internal.h"
 
@@ -46,6 +50,78 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #define getexecname() NULL
 #endif
 
+#if !defined (HAVE_KERN_PROC_ARGS) && !defined (HAVE_KERN_PROC)
+
+#define sysctl_exec_name1(state, error_callback, data) NULL
+#define sysctl_exec_name2(state, error_callback, data) NULL
+
+#else /* defined (HAVE_KERN_PROC_ARGS) || |defined (HAVE_KERN_PROC) */
+
+static char *
+sysctl_exec_name (struct backtrace_state *state,
+ int mib0, int mib1, int mib2, int mib3,
+ backtrace_error_callback error_callback, void *data)
+{
+  int mib[4];
+  size_t len;
+  char *name;
+  size_t rlen;
+
+  mib[0] = mib0;
+  mib[1] = mib1;
+  mib[2] = mib2;
+  mib[3] = mib3;
+
+  if (sysctl (mib, 4, NULL, , NULL, 0) < 0)
+return NULL;
+  name = (char *) backtrace_alloc (state, len, error_callback, data);
+  if (name == NULL)
+return NULL;
+  rlen = len;
+  if (sysctl (mib, 4, name, , NULL, 0) < 0)
+{
+  backtrace_free (state, name, len, error_callback, data);
+  return NULL;
+}
+  return name;
+}
+
+#ifdef HAVE_KERN_PROC_ARGS
+
+static char *
+sysctl_exec_name1 (struct backtrace_state *state,
+  backtrace_error_callback error_callback, void *data)
+{
+  /* This variant is used on NetBSD.  */
+  return sysctl_exec_name (state, CTL_KERN, KERN_PROC_ARGS, -1,
+  KERN_PROC_PATHNAME, error_callback, data);
+}
+
+#else
+
+#define sysctl_exec_name1(state, error_callback, data) NULL
+
+#endif
+
+#ifdef HAVE_KERN_PROC
+
+static char *
+sysctl_exec_name2 (struct backtrace_state *state,
+  backtrace_error_callback error_callback, void *data)
+{
+  /* This variant is used on FreeBSD.  */
+  return sysctl_exec_name (state, CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1,
+  error_callback, data);
+}
+
+#else
+
+#define sysctl_exec_name2(state, error_callback, data) NULL
+
+#endif
+
+#endif /* defined (HAVE_KERN_PROC_ARGS) || |defined (HAVE_KERN_PROC) */
+
 /* Initialize the fileline information from the executable.  Returns 1
on success, 0 on failure.  */
 
@@ -83,7 +159,7 @@ fileline_initialize (struct backtrace_state *state,
 
   descriptor = -1;
   called_error_callback = 0;
-  for (pass = 0; pass < 5; ++pass)
+  for (pass = 0; pass < 7; ++pass)
 {
   int does_not_exist;
 
@@ -106,6 +182,12 @@ fileline_initialize (struct backtrace_state *state,
(long) getpid ());
  filename = buf;
  break;
+   case 5:
+ filename = sysctl_exec_name1 (state, error_callback, data);
+ break;
+   case 6:
+ filename = sysctl_exec_name2 (state, error_callback, data);
+ break;
default:
  abort ();
}


libbacktrace patch committed: Update test file

2020-02-15 Thread Ian Lance Taylor
This libbacktrace patch updates the test file used for comparisons
with zlib.  The file that the test was previously using, from libgo,
no longer exists.  Use its replacement file instead.  Bootstrapped and
ran libbacktrace tests on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

2020-02-15  Ian Lance Taylor  

* ztest.c (test_large): Update file to current libgo test file.
diff --git a/libbacktrace/ztest.c b/libbacktrace/ztest.c
index 40f9c389a2a..2663c90061a 100644
--- a/libbacktrace/ztest.c
+++ b/libbacktrace/ztest.c
@@ -315,8 +315,8 @@ test_large (struct backtrace_state *state)
   size_t ctimes[16];
   size_t ztimes[16];
   static const char * const names[] = {
-"Mark.Twain-Tom.Sawyer.txt",
-"../libgo/go/compress/testdata/Mark.Twain-Tom.Sawyer.txt"
+"Isaac.Newton-Opticks.txt",
+"../libgo/go/testdata/Isaac.Newton-Opticks.txt",
   };
 
   orig_buf = NULL;


libbacktrace patch committed: Always build tests with -g

2020-02-03 Thread Ian Lance Taylor
This patch ensures that the libbacktrace tests are always built with
-g.  It also builds them with the default warning flags, so I had to
add a few casts to ztest.c to get it pass without warnings.  This
should fix PR 90636.  Bootstrapped and ran libbacktrace tests on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

2020-02-03  Ian Lance Taylor  

* Makefile.am (libbacktrace_TEST_CFLAGS): Define.
(test_elf32_CFLAGS): Use $(libbacktrace_test_CFLAGS).
(test_elf_64_CFLAGS, test_xcoff_32_CFLAGS): Likewise.
(test_xcoff_64_CFLAGS, test_pecoff_CFLAGS): Likewise.
(test_unknown_CFLAGS, unittest_CFLAGS): Likewise.
(unittest_alloc_CFLAGS, allocfail_CFLAGS): Likewise.
(b2test_CFLAGS, b3test_CFLAGS, btest_CFLAGS): Likewise.
(btest_lto_CFLAGS, btest_alloc_CFLAGS, stest_CFLAGS): Likewise.
(stest_alloc_CFLAGS): Likewise.
* Makefile.in: Regenerate.
* ztest.c (error_callback_compress): Mark vdata unused.
(test_large): Add casts to avoid warnings.
diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am
index b251b7bc34a..c73f6633a76 100644
--- a/libbacktrace/Makefile.am
+++ b/libbacktrace/Makefile.am
@@ -93,6 +93,9 @@ TESTS =
 # Add test to this variable, if you want it to be build and run.
 BUILDTESTS =
 
+# Flags to use when compiling test programs.
+libbacktrace_TEST_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) -g
+
 if NATIVE
 check_LTLIBRARIES = libbacktrace_alloc.la
 
@@ -149,41 +152,49 @@ xcoff_%.c: xcoff.c
mv $@.tmp $@
 
 test_elf_32_SOURCES = test_format.c testlib.c
+test_elf_32_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 test_elf_32_LDADD = libbacktrace_noformat.la elf_32.lo
 
 BUILDTESTS += test_elf_32
 
 test_elf_64_SOURCES = test_format.c testlib.c
+test_elf_64_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 test_elf_64_LDADD = libbacktrace_noformat.la elf_64.lo
 
 BUILDTESTS += test_elf_64
 
 test_xcoff_32_SOURCES = test_format.c testlib.c
+test_xcoff_32_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 test_xcoff_32_LDADD = libbacktrace_noformat.la xcoff_32.lo
 
 BUILDTESTS += test_xcoff_32
 
 test_xcoff_64_SOURCES = test_format.c testlib.c
+test_xcoff_64_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 test_xcoff_64_LDADD = libbacktrace_noformat.la xcoff_64.lo
 
 BUILDTESTS += test_xcoff_64
 
 test_pecoff_SOURCES = test_format.c testlib.c
+test_pecoff_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 test_pecoff_LDADD = libbacktrace_noformat.la pecoff.lo
 
 BUILDTESTS += test_pecoff
 
 test_unknown_SOURCES = test_format.c testlib.c
+test_unknown_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 test_unknown_LDADD = libbacktrace_noformat.la unknown.lo
 
 BUILDTESTS += test_unknown
 
 unittest_SOURCES = unittest.c testlib.c
+unittest_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 unittest_LDADD = libbacktrace.la
 
 BUILDTESTS += unittest
 
 unittest_alloc_SOURCES = $(unittest_SOURCES)
+unittest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 unittest_alloc_LDADD = libbacktrace_alloc.la
 
 BUILDTESTS += unittest_alloc
@@ -200,6 +211,7 @@ libbacktrace_instrumented_alloc_la_DEPENDENCIES = \
 instrumented_alloc.lo: alloc.c
 
 allocfail_SOURCES = allocfail.c testlib.c
+allocfail_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 allocfail_LDADD = libbacktrace_instrumented_alloc.la
 
 check_PROGRAMS += allocfail
@@ -212,7 +224,7 @@ if HAVE_ELF
 if HAVE_OBJCOPY_DEBUGLINK
 
 b2test_SOURCES = $(btest_SOURCES)
-b2test_CFLAGS = $(btest_CFLAGS)
+b2test_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 b2test_LDFLAGS = -Wl,--build-id
 b2test_LDADD = libbacktrace_elf_for_test.la
 
@@ -222,7 +234,7 @@ TESTS += b2test_buildid
 if HAVE_DWZ
 
 b3test_SOURCES = $(btest_SOURCES)
-b3test_CFLAGS = $(btest_CFLAGS)
+b3test_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 b3test_LDFLAGS = -Wl,--build-id
 b3test_LDADD = libbacktrace_elf_for_test.la
 
@@ -235,7 +247,7 @@ endif HAVE_OBJCOPY_DEBUGLINK
 endif HAVE_ELF
 
 btest_SOURCES = btest.c testlib.c
-btest_CFLAGS = $(AM_CFLAGS) -g -O
+btest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -O
 btest_LDADD = libbacktrace.la
 
 BUILDTESTS += btest
@@ -243,7 +255,7 @@ BUILDTESTS += btest
 if HAVE_ELF
 
 btest_lto_SOURCES = btest.c testlib.c
-btest_lto_CFLAGS = $(AM_CFLAGS) -g -O -flto
+btest_lto_CFLAGS = $(libbacktrace_TEST_CFLAGS) -O -flto
 btest_lto_LDADD = libbacktrace.la
 
 BUILDTESTS += btest_lto
@@ -251,7 +263,7 @@ BUILDTESTS += btest_lto
 endif HAVE_ELF
 
 btest_alloc_SOURCES = $(btest_SOURCES)
-btest_alloc_CFLAGS = $(btest_CFLAGS)
+btest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 btest_alloc_LDADD = libbacktrace_alloc.la
 
 BUILDTESTS += btest_alloc
@@ -277,11 +289,13 @@ endif HAVE_OBJCOPY_DEBUGLINK
 endif HAVE_DWZ
 
 stest_SOURCES = stest.c
+stest_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 stest_LDADD = libbacktrace.la
 
 BUILDTESTS += stest
 
 stest_alloc_SOURCES = $(stest_SOURCES)
+stest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 stest_alloc_LDADD = libbacktrace_alloc.la
 
 BUILDTESTS += stest_alloc
@@ -289,7 +303,7 @@ BUILDTESTS += stest_alloc
 if HAVE_ELF
 
 ztest_SOURCES = ztest.c testlib.c
-ztest_CFLAGS = -DSRCDIR=\"$(srcdir)\"
+ztest_CFLAGS = $(libbacktrace_TEST_CFLAGS) 

libbacktrace patch committed: Add DWARF 5 support

2019-12-13 Thread Ian Lance Taylor
This patch to libbacktrace adds DWARF 5 support.  I tested this with
GCC 8, GCC tip, and clang 8, using the -gdwarf-5 option.  Bootstrapped
and ran libbacktrace and libgo tests on x86_64-pc-linux-gnu.
Committed to mainline.

Ian

2019-12-13  Ian Lance Taylor  

Add DWARF 5 support.
* dwarf.c (struct attr): Add val field.
(enum attr_val_encoding): Add ATTR_VAL_ADDDRESS_INDEX,
ATTR_VAL_STRING_INDEX, ATTR_VAL_RNGLISTS_INDEX.
(struct line_header): Add addrsize field.
(struct line_header_format): Define.
(struct unit): Add str_offsets_base, addr_base, and rnglists_base
fields.
(read_uint24): New static function.
(read_attribute): Add implicit_val parameter.  Replace dwarf_str
and dwarf_str_size parameters with dwarf_sections parameter.  Add
support for new DWARF 5 forms.  Change all callers.
(resolve_string): New static function.
(resolve_addr_index): Likewise.
(read_abbrevs): Support DW_FORM_implicit_const.
(struct pcrange): Add lowpc_is_addr_index, highpc_is_addr_Index,
and ranges_is_index fields.
(update_pcrange): Support DWARF 5 encodings.
(add_high_low_range): New static function, split out of
add_ranges.
(add_ranges_from_ranges): Likewise.
(add_ranges_from_rnglists): New static function.
(add_ranges): Just call new helper functions.
(find_address_ranges): Use resolve_string for strings, after
reading all attributes.  Handle new DWARF 5 attributes.
(build_address_map): Support DWARF 5 compilation units.
(read_v2_paths): New static function, split out of
read_line_header.
(read_lnct): New static function.
(read_line_header_format_entries): Likewise.
(read_line_header): Add ddata parameter.  Support DWARF 5 line
headers.  Call new helper functions.  Change all callers.
(read_line_program): Use addrsize from line program header.  Don't
special case directory index 0 for DWARF 5.
(read_referenced_name): Use resolve_string.
(read_function_entry): Handle DWARF 5 encodings.  Use
resolve_string.
* internal.h (enum dwarf_section): Add DEBUG_ADDR,
DEBUG_STR_OFFSETS, DEBUG_LINE_STR, DEBUG_RNGLISTS.
* elf.c (dwarf_section_names): Add new section names.
* pecoff.c (dwarf_section_names): Likewise.
* xcoff.c (xcoff_add): Clear dwarf_sections before setting
fields.
* configure.ac: Define HAVE_DWARF5 automake conditional.
* Makefile.am (dwarf5_SOURCES): New variable if HAVE_DWARF5.
(dwarf5_CFLAGS, dwarf5_LDADD): Likewise.
(dwarf5_alloc_SOURCES, dwarf5_alloc_CFLAGS): Likewise.
(dwarf5_alloc_LDADD): Likewise.
(BUILDTESTS): Add dwarf5 tests if HAVE_DWARF5.
(CLEANFILES, clean-local): Define.
Index: Makefile.am
===
--- Makefile.am (revision 279211)
+++ Makefile.am (working copy)
@@ -385,12 +385,33 @@ BUILDTESTS += ctestg_alloc ctesta_alloc
 
 endif
 
+if HAVE_DWARF5
+
+dwarf5_SOURCES = btest.c testlib.c
+dwarf5_CFLAGS = $(AM_CFLAGS) -gdwarf-5
+dwarf5_LDADD = libbacktrace.la
+
+BUILDTESTS += dwarf5
+
+dwarf5_alloc_SOURCES = $(dwarf5_SOURCES)
+dwarf5_alloc_CFLAGS = $(dwarf5_CFLAGS)
+dwarf5_alloc_LDADD = libbacktrace_alloc.la
+
+BUILDTESTS += dwarf5_alloc
+
+endif
+
 endif NATIVE
 
 check_PROGRAMS += $(BUILDTESTS)
 
 TESTS += $(BUILDTESTS)
 
+CLEANFILES = $(TESTS) *.debug elf_for_test.c edtest2_build.c gen_edtest2_build
+
+clean-local:
+   -rm -rf usr
+
 # We can't use automake's automatic dependency tracking, because it
 # breaks when using bootstrap-lean.  Automatic dependency tracking
 # with GCC bootstrap will cause some of the objects to depend on
Index: configure.ac
===
--- configure.ac(revision 279211)
+++ configure.ac(working copy)
@@ -420,6 +420,17 @@ AC_SUBST(PTHREAD_CFLAGS)
 
 AM_CONDITIONAL(HAVE_PTHREAD, test "$libgo_cv_lib_pthread" = yes)
 
+dnl Test whether the compiler supports the -gdwarf-5 option.
+AC_CACHE_CHECK([whether -gdwarf-5 is supported],
+[libbacktrace_cv_lib_dwarf5],
+[CFLAGS_hold=$CFLAGS
+CFLAGS="$CFLAGS -gdwarf-5"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([int i;])],
+[libbacktrace_cv_lib_dwarf5=yes],
+[libbacktrace_cv_lib_dwarf5=no])
+CFLAGS=$CFLAGS_hold])
+AM_CONDITIONAL(HAVE_DWARF5, test "$libbacktrace_cv_lib_dwarf5" = yes)
+
 AC_CHECK_LIB([z], [compress],
 [AC_DEFINE(HAVE_ZLIB, 1, [Define if -lz is available.])])
 AM_CONDITIONAL(HAVE_ZLIB, test "$ac_cv_lib_z_compress" = yes)
Index: dwarf.c
===
--- dwarf.c (revision 279211)
+++ dwarf.c (working copy)
@@ -92,6 +92,8 @@ struct attr
   enum dwarf_attribute name;
   /* The attribute form.  */
   enum dwarf_form form;
+  /* The attribute value, for DW_FORM_implicit_const.  */
+  int64_t val;
 };
 
 /* A single DWARF abbreviation.  */
@@ -133,22 +135,29 @@ enum attr_val_encoding
   ATTR_VAL_NONE,
   /* An address.  */
   ATTR_VAL_ADDRESS,
+  /* An index into the .debug_addr section, whose value is relative to
+   * the DW_AT_addr_base attribute of the compilation unit.  */
+  ATTR_VAL_ADDRESS_INDEX,
   /* A unsigned integer.  */
   

libbacktrace patch committed: Remove duplication of address handling

2019-12-09 Thread Ian Lance Taylor
Before this patch libbacktrace duplicated the handling of
DW_AT_low_pc, DW_AT_high_pc, and DW_AT_ranges, once to build a mapping
from addresses to compilation units, and then again to build a mapping
from addresses to functions within a compilation unit.  This patch
removes the duplication into a pair of functions, one of which takes a
function pointer to actually add the appropriate mapping.  This is a
step toward adding DWARF 5 support, as DWARF 5 requires handling more
cases here, and it seemed painful to introduce further duplication.
Bootstrapped and ran libbacktrace and Go testsuites on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
Index: dwarf.c
===
--- dwarf.c (revision 279094)
+++ dwarf.c (working copy)
@@ -945,31 +945,28 @@ function_addrs_search (const void *vkey,
 return 0;
 }
 
-/* Add a new compilation unit address range to a vector.  Returns 1 on
-   success, 0 on failure.  */
+/* Add a new compilation unit address range to a vector.  This is
+   called via add_ranges.  Returns 1 on success, 0 on failure.  */
 
 static int
-add_unit_addr (struct backtrace_state *state, uintptr_t base_address,
-  struct unit_addrs addrs,
+add_unit_addr (struct backtrace_state *state, void *rdata,
+  uint64_t lowpc, uint64_t highpc,
   backtrace_error_callback error_callback, void *data,
-  struct unit_addrs_vector *vec)
+  void *pvec)
 {
+  struct unit *u = (struct unit *) rdata;
+  struct unit_addrs_vector *vec = (struct unit_addrs_vector *) pvec;
   struct unit_addrs *p;
 
-  /* Add in the base address of the module here, so that we can look
- up the PC directly.  */
-  addrs.low += base_address;
-  addrs.high += base_address;
-
   /* Try to merge with the last entry.  */
   if (vec->count > 0)
 {
   p = (struct unit_addrs *) vec->vec.base + (vec->count - 1);
-  if ((addrs.low == p->high || addrs.low == p->high + 1)
- && addrs.u == p->u)
+  if ((lowpc == p->high || lowpc == p->high + 1)
+ && u == p->u)
{
- if (addrs.high > p->high)
-   p->high = addrs.high;
+ if (highpc > p->high)
+   p->high = highpc;
  return 1;
}
 }
@@ -980,8 +977,12 @@ add_unit_addr (struct backtrace_state *s
   if (p == NULL)
 return 0;
 
-  *p = addrs;
+  p->low = lowpc;
+  p->high = highpc;
+  p->u = u;
+
   ++vec->count;
+
   return 1;
 }
 
@@ -1262,29 +1263,122 @@ lookup_abbrev (struct abbrevs *abbrevs,
   return (const struct abbrev *) p;
 }
 
-/* Add non-contiguous address ranges for a compilation unit.  Returns
-   1 on success, 0 on failure.  */
+/* This struct is used to gather address range information while
+   reading attributes.  We use this while building a mapping from
+   address ranges to compilation units and then again while mapping
+   from address ranges to function entries.  Normally either
+   lowpc/highpc is set or ranges is set.  */
+
+struct pcrange {
+  uint64_t lowpc;  /* The low PC value.  */
+  int have_lowpc;  /* Whether a low PC value was found.  */
+  uint64_t highpc; /* The high PC value.  */
+  int have_highpc; /* Whether a high PC value was found.  */
+  int highpc_is_relative;  /* Whether highpc is relative to lowpc.  */
+  uint64_t ranges; /* Offset in ranges section.  */
+  int have_ranges; /* Whether ranges is valid.  */
+};
+
+/* Update PCRANGE from an attribute value.  */
+
+static void
+update_pcrange (const struct attr* attr, const struct attr_val* val,
+   struct pcrange *pcrange)
+{
+  switch (attr->name)
+{
+case DW_AT_low_pc:
+  if (val->encoding == ATTR_VAL_ADDRESS)
+   {
+ pcrange->lowpc = val->u.uint;
+ pcrange->have_lowpc = 1;
+   }
+  break;
+
+case DW_AT_high_pc:
+  if (val->encoding == ATTR_VAL_ADDRESS)
+   {
+ pcrange->highpc = val->u.uint;
+ pcrange->have_highpc = 1;
+   }
+  else if (val->encoding == ATTR_VAL_UINT)
+   {
+ pcrange->highpc = val->u.uint;
+ pcrange->have_highpc = 1;
+ pcrange->highpc_is_relative = 1;
+   }
+  break;
+
+case DW_AT_ranges:
+  if (val->encoding == ATTR_VAL_UINT
+ || val->encoding == ATTR_VAL_REF_SECTION)
+   {
+ pcrange->ranges = val->u.uint;
+ pcrange->have_ranges = 1;
+   }
+  break;
+
+default:
+  break;
+}
+}
+
+/* Call ADD_RANGE for each lowpc/highpc pair in PCRANGE.  RDATA is
+   passed to ADD_RANGE, and is either a struct unit * or a struct
+   function *.  VEC is the vector we are adding ranges to, and is
+   either a struct unit_addrs_vector * or a struct function_vector *.
+   Returns 1 on success, 0 on error.  */
 
 static int
-add_unit_ranges (struct backtrace_state *state, uintptr_t base_address,
-struct unit *u, uint64_t ranges, 

libbacktrace patch committed: Declare test1 in edtest.c with noclone

2019-12-04 Thread Ian Lance Taylor
This libbacktrace patch adds the noclone attribute to the version of
test1 in edtest.c, to correspond to other versions of test1.
Bootstrapped and ran libbacktrace tests on x86_64-pc-linux-gnu.
Committed to mainline.

Ian

2019-12-04  Ian Lance Taylor  

* edtest.c (test1): Add noclone attribute.
Index: edtest.c
===
--- edtest.c(revision 278944)
+++ edtest.c(working copy)
@@ -43,8 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.  */
 
 #include "testlib.h"
 
-static int test1 (void) __attribute__ ((noinline, unused));
-static int test1 (void) __attribute__ ((noinline, unused));
+static int test1 (void) __attribute__ ((noinline, noclone, unused));
 extern int f2 (int);
 extern int f3 (int, int);
 


libbacktrace patch committed: Simplify DWARF section handling

2019-12-04 Thread Ian Lance Taylor
This libbacktrace patch simplifies the DWARF section handling.  This
is in preparation for DWARF 5 support, as DWARF 5 requires us to read
more sections.  Bootstrapped and ran libbacktrace and Go tests on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

2019-12-04  Ian Lance Taylor  

* internal.h (enum dwarf_section): Define.
(struct dwarf_sections): Define.
(backtrace_dwarf_add): Update declaration to replace specific
section parameters with dwarf_sections parameter.
* dwarf.c (struct dwarf_data): Replace specific section fields
with dwarf_sections field.
(read_attribute): Use dwarf_sections with altlink.
(build_address_map): Replace specific section parameters with
dwarf_sections parameter.  Change all callers.
(read_line_info): Use dwarf_sections with ddata.
(read_referenced_name): Likewise.
(add_function_ranges): Likewise.
(read_function_entry): Likewise.
(read_function_info): Likewise.
(build_dwarf_data): Replace specific section parameters with
dwarf_sections parameter.  Change all callers.
(backtrace_dwarf_add): Likewise.
* elf.c (enum debug_section): Remove.
(dwarf_section_names): Remove .zdebug names.
(elf_add): Track zsections separately.  Build dwarf_sections.
* pecoff.c (enum debug_section): Remove.
(struct debug_section_info): Remove data field.
(coff_add): Build dwarf_sections.
* xcoff.c (enum dwarf_section): Remove.  Replace DWSECT_xxx
references with DEBUG_xxx references.
(xcoff_add): Build dwarf_sections.
Index: dwarf.c
===
--- dwarf.c (revision 278944)
+++ dwarf.c (working copy)
@@ -373,18 +373,8 @@ struct dwarf_data
   struct unit **units;
   /* Number of units in the list.  */
   size_t units_count;
-  /* The unparsed .debug_info section.  */
-  const unsigned char *dwarf_info;
-  size_t dwarf_info_size;
-  /* The unparsed .debug_line section.  */
-  const unsigned char *dwarf_line;
-  size_t dwarf_line_size;
-  /* The unparsed .debug_ranges section.  */
-  const unsigned char *dwarf_ranges;
-  size_t dwarf_ranges_size;
-  /* The unparsed .debug_str section.  */
-  const unsigned char *dwarf_str;
-  size_t dwarf_str_size;
+  /* The unparsed DWARF debug data.  */
+  struct dwarf_sections dwarf_sections;
   /* Whether the data is big-endian or not.  */
   int is_bigendian;
   /* A vector used for function addresses.  We keep this here so that
@@ -871,13 +861,14 @@ read_attribute (enum dwarf_form form, st
val->encoding = ATTR_VAL_NONE;
return 1;
  }
-   if (offset >= altlink->dwarf_str_size)
+   if (offset >= altlink->dwarf_sections.size[DEBUG_STR])
  {
dwarf_buf_error (buf, "DW_FORM_GNU_strp_alt out of range");
return 0;
  }
val->encoding = ATTR_VAL_STRING;
-   val->u.string = (const char *) altlink->dwarf_str + offset;
+   val->u.string =
+ (const char *) altlink->dwarf_sections.data[DEBUG_STR] + offset;
return 1;
   }
 default:
@@ -1499,10 +1490,7 @@ find_address_ranges (struct backtrace_st
 
 static int
 build_address_map (struct backtrace_state *state, uintptr_t base_address,
-  const unsigned char *dwarf_info, size_t dwarf_info_size,
-  const unsigned char *dwarf_abbrev, size_t dwarf_abbrev_size,
-  const unsigned char *dwarf_ranges, size_t dwarf_ranges_size,
-  const unsigned char *dwarf_str, size_t dwarf_str_size,
+  const struct dwarf_sections *dwarf_sections,
   int is_bigendian, struct dwarf_data *altlink,
   backtrace_error_callback error_callback, void *data,
   struct unit_addrs_vector *addrs,
@@ -1525,9 +1513,9 @@ build_address_map (struct backtrace_stat
  not sure why.  */
 
   info.name = ".debug_info";
-  info.start = dwarf_info;
-  info.buf = dwarf_info;
-  info.left = dwarf_info_size;
+  info.start = dwarf_sections->data[DEBUG_INFO];
+  info.buf = info.start;
+  info.left = dwarf_sections->size[DEBUG_INFO];
   info.is_bigendian = is_bigendian;
   info.error_callback = error_callback;
   info.data = data;
@@ -1583,7 +1571,9 @@ build_address_map (struct backtrace_stat
 
   memset (>abbrevs, 0, sizeof u->abbrevs);
   abbrev_offset = read_offset (_buf, is_dwarf64);
-  if (!read_abbrevs (state, abbrev_offset, dwarf_abbrev, dwarf_abbrev_size,
+  if (!read_abbrevs (state, abbrev_offset,
+dwarf_sections->data[DEBUG_ABBREV],
+dwarf_sections->size[DEBUG_ABBREV],
 is_bigendian, error_callback, data, >abbrevs))
goto fail;
 
@@ -1610,8 +1600,10 @@ build_address_map (struct backtrace_stat
   u->function_addrs_count = 0;
 
   if (!find_address_ranges (state, base_address, _buf,
-   dwarf_str, dwarf_str_size,
-   dwarf_ranges, dwarf_ranges_size,
+   

libbacktrace patch committed: Only run ztest if HAVE_ELF

2019-03-11 Thread Ian Lance Taylor
This libbacktrace patch only runs the two ztest tests if HAVE_ELF is
true, since we only do uncompression on ELF.  This should fix PR
89699.  Bootstrapped and ran libbacktrace tests on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian


2019-03-11  Ian Lance Taylor  

PR libbacktrace/89669
* Makefile.am (BUILDTESTS): Only add ztest and ztest_alloc if
HAVE_ELF.
* Makefile.in: Regenerate.
Index: Makefile.am
===
--- Makefile.am (revision 269593)
+++ Makefile.am (working copy)
@@ -272,6 +272,8 @@ stest_alloc_LDADD = libbacktrace_alloc.l
 
 BUILDTESTS += stest_alloc
 
+if HAVE_ELF
+
 ztest_SOURCES = ztest.c testlib.c
 ztest_CFLAGS = -DSRCDIR=\"$(srcdir)\"
 ztest_LDADD = libbacktrace.la
@@ -291,6 +293,8 @@ ztest_alloc_CFLAGS = $(ztest_CFLAGS)
 
 BUILDTESTS += ztest_alloc
 
+endif HAVE_ELF
+
 edtest_SOURCES = edtest.c edtest2_build.c testlib.c
 edtest_LDADD = libbacktrace.la
 


libbacktrace patch committed: backtrace_create_state should be called once

2018-10-05 Thread Ian Lance Taylor
This patch to libbacktrace expands the comment for
backtrace_create_state to make clear that it should be called only
once.  There is no backtrace_free_state function.  While it would be
nice to have such a function, it's hard to write completely accurately
as libbacktrace doesn't currently track all memory allocations.
Committed to mainline.

Ian

2018-10-05  Ian Lance Taylor  

PR libbacktrace/87529
* backtrace.h: Document that backtrace_create_state should be
called only once.
Index: backtrace.h
===
--- backtrace.h (revision 264813)
+++ backtrace.h (working copy)
@@ -92,7 +92,13 @@ typedef void (*backtrace_error_callback)
use appropriate atomic operations.  If THREADED is zero the state
may only be accessed by one thread at a time.  This returns a state
pointer on success, NULL on error.  If an error occurs, this will
-   call the ERROR_CALLBACK routine.  */
+   call the ERROR_CALLBACK routine.
+
+   Calling this function allocates resources that can not be freed.
+   There is no backtrace_free_state function.  The state is used to
+   cache information that is expensive to recompute.  Programs are
+   expected to call this function at most once and to save the return
+   value for all later calls to backtrace functions.  */
 
 extern struct backtrace_state *backtrace_create_state (
 const char *filename, int threaded,


Re: libbacktrace patch committed: Call munmap after memory test

2018-04-17 Thread Ian Lance Taylor
On Tue, Apr 17, 2018 at 10:29 AM, Ian Lance Taylor  wrote:
> On Tue, Apr 17, 2018 at 10:21 AM, Tom de Vries  wrote:
>> On 04/17/2018 03:59 PM, Ian Lance Taylor wrote:
>>>
>>> The bug report https://github.com/ianlancetaylor/libbacktrace/issues/13
>>> points out that when backtrace_full checks whether memory is
>>> available, it doesn't necessarily release that memory.  It will stay
>>> on the free list, so libbacktrace will use more and more memory over
>>> time.  This patch fixes that problem by explicitly calling munmap.
>>> Bootstrapped and ran libbacktrace and Go tests on x86_64-pc-linux-gnu.
>>> Committed to mainline.
>>>
>>> Ian
>>>
>>>
>>> 2018-04-17  Ian Lance Taylor  
>>>
>>> * backtrace.c (backtrace_full): When testing whether we can
>>> allocate memory, call mmap directly, and munmap the memory.
>>>
>>>
>>> patch.txt
>>>
>>>
>>> Index: backtrace.c
>>> ===
>>> --- backtrace.c (revision 259359)
>>> +++ backtrace.c (working copy)
>>> @@ -32,12 +32,26 @@ POSSIBILITY OF SUCH DAMAGE.  */
>>> #include "config.h"
>>>   +#include 
>>>   #include 
>>>   +#if !BACKTRACE_USES_MALLOC
>>> +#include 
>>> +#endif
>>> +
>>
>>
>> Hi,
>>
>> this breaks the nvptx build:
>> ...
>> libbacktrace/backtrace.c:39:10: fatal error: sys/mman.h: No such file or
>> directory
>>  #include 
>>   ^~~~
>> compilation terminated.
>
> Sorry about that.  Committed this patch, which should fix that problem.

Actually, never mind.  Looks like this didn't fix the problem.  I'm
just reverting back to the state as of earlier today.

Ian

2018-04-17  Ian Lance Taylor  

* backtrace.c: Revert last two changes.  Don't call mmap
directly.
Index: backtrace.c
===
--- backtrace.c (revision 259439)
+++ backtrace.c (working copy)
@@ -32,27 +32,12 @@ POSSIBILITY OF SUCH DAMAGE.  */
 
 #include "config.h"
 
-#include 
 #include 
 
-#include "backtrace-supported.h"
-
-#if !BACKTRACE_USES_MALLOC
-#include 
-#endif
-
 #include "unwind.h"
 #include "backtrace.h"
 #include "internal.h"
 
-#ifndef MAP_ANONYMOUS
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-
-#ifndef MAP_FAILED
-#define MAP_FAILED ((void *)-1)
-#endif
-
 /* The main backtrace_full routine.  */
 
 /* Data passed through _Unwind_Backtrace.  */
@@ -119,6 +104,7 @@ backtrace_full (struct backtrace_state *
backtrace_error_callback error_callback, void *data)
 {
   struct backtrace_data bdata;
+  void *p;
 
   bdata.skip = skip + 1;
   bdata.state = state;
@@ -127,25 +113,16 @@ backtrace_full (struct backtrace_state *
   bdata.data = data;
   bdata.ret = 0;
 
-#if !BACKTRACE_USES_MALLOC
-  {
-size_t pagesize;
-void *page;
-
-/* If we can't allocate any memory at all, don't try to produce
-   file/line information.  */
-pagesize = getpagesize ();
-page = mmap (NULL, pagesize, PROT_READ | PROT_WRITE, 
-MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-if (page == MAP_FAILED)
-  bdata.can_alloc = 0;
-else
-  {
-   munmap (page, pagesize);
-   bdata.can_alloc = 1;
-  }
-  }
-#endif
+  /* If we can't allocate any memory at all, don't try to produce
+ file/line information.  */
+  p = backtrace_alloc (state, 4096, NULL, NULL);
+  if (p == NULL)
+bdata.can_alloc = 0;
+  else
+{
+  backtrace_free (state, p, 4096, NULL, NULL);
+  bdata.can_alloc = 1;
+}
 
   _Unwind_Backtrace (unwind, );
   return bdata.ret;


Re: libbacktrace patch committed: Call munmap after memory test

2018-04-17 Thread Ian Lance Taylor
On Tue, Apr 17, 2018 at 10:21 AM, Tom de Vries  wrote:
> On 04/17/2018 03:59 PM, Ian Lance Taylor wrote:
>>
>> The bug report https://github.com/ianlancetaylor/libbacktrace/issues/13
>> points out that when backtrace_full checks whether memory is
>> available, it doesn't necessarily release that memory.  It will stay
>> on the free list, so libbacktrace will use more and more memory over
>> time.  This patch fixes that problem by explicitly calling munmap.
>> Bootstrapped and ran libbacktrace and Go tests on x86_64-pc-linux-gnu.
>> Committed to mainline.
>>
>> Ian
>>
>>
>> 2018-04-17  Ian Lance Taylor  
>>
>> * backtrace.c (backtrace_full): When testing whether we can
>> allocate memory, call mmap directly, and munmap the memory.
>>
>>
>> patch.txt
>>
>>
>> Index: backtrace.c
>> ===
>> --- backtrace.c (revision 259359)
>> +++ backtrace.c (working copy)
>> @@ -32,12 +32,26 @@ POSSIBILITY OF SUCH DAMAGE.  */
>> #include "config.h"
>>   +#include 
>>   #include 
>>   +#if !BACKTRACE_USES_MALLOC
>> +#include 
>> +#endif
>> +
>
>
> Hi,
>
> this breaks the nvptx build:
> ...
> libbacktrace/backtrace.c:39:10: fatal error: sys/mman.h: No such file or
> directory
>  #include 
>   ^~~~
> compilation terminated.

Sorry about that.  Committed this patch, which should fix that problem.

Ian


2018-04-17  Ian Lance Taylor  

* backtrace.c: Include backtrace-supported.h before checking
BACKTRACE_USES_MALLOC.
Index: backtrace.c
===
--- backtrace.c (revision 259434)
+++ backtrace.c (working copy)
@@ -35,13 +35,14 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include 
 #include 
 
+#include "backtrace-supported.h"
+
 #if !BACKTRACE_USES_MALLOC
 #include 
 #endif
 
 #include "unwind.h"
 #include "backtrace.h"
-#include "backtrace-supported.h"
 #include "internal.h"
 
 #ifndef MAP_ANONYMOUS


Re: libbacktrace patch committed: Call munmap after memory test

2018-04-17 Thread Tom de Vries

On 04/17/2018 03:59 PM, Ian Lance Taylor wrote:

The bug report https://github.com/ianlancetaylor/libbacktrace/issues/13
points out that when backtrace_full checks whether memory is
available, it doesn't necessarily release that memory.  It will stay
on the free list, so libbacktrace will use more and more memory over
time.  This patch fixes that problem by explicitly calling munmap.
Bootstrapped and ran libbacktrace and Go tests on x86_64-pc-linux-gnu.
Committed to mainline.

Ian


2018-04-17  Ian Lance Taylor  

* backtrace.c (backtrace_full): When testing whether we can
allocate memory, call mmap directly, and munmap the memory.


patch.txt


Index: backtrace.c
===
--- backtrace.c (revision 259359)
+++ backtrace.c (working copy)
@@ -32,12 +32,26 @@ POSSIBILITY OF SUCH DAMAGE.  */
  
  #include "config.h"
  
+#include 

  #include 
  
+#if !BACKTRACE_USES_MALLOC

+#include 
+#endif
+


Hi,

this breaks the nvptx build:
...
libbacktrace/backtrace.c:39:10: fatal error: sys/mman.h: No such file or 
directory

 #include 
  ^~~~
compilation terminated.
...

Thanks,
- Tom


  #include "unwind.h"
  #include "backtrace.h"
+#include "backtrace-supported.h"
  #include "internal.h"
  
+#ifndef MAP_ANONYMOUS

+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
  /* The main backtrace_full routine.  */
  
  /* Data passed through _Unwind_Backtrace.  */

@@ -104,7 +118,6 @@ backtrace_full (struct backtrace_state *
backtrace_error_callback error_callback, void *data)
  {
struct backtrace_data bdata;
-  void *p;
  
bdata.skip = skip + 1;

bdata.state = state;
@@ -113,16 +126,25 @@ backtrace_full (struct backtrace_state *
bdata.data = data;
bdata.ret = 0;
  
-  /* If we can't allocate any memory at all, don't try to produce

- file/line information.  */
-  p = backtrace_alloc (state, 4096, NULL, NULL);
-  if (p == NULL)
-bdata.can_alloc = 0;
-  else
-{
-  backtrace_free (state, p, 4096, NULL, NULL);
-  bdata.can_alloc = 1;
-}
+#if !BACKTRACE_USES_MALLOC
+  {
+size_t pagesize;
+void *page;
+
+/* If we can't allocate any memory at all, don't try to produce
+   file/line information.  */
+pagesize = getpagesize ();
+page = mmap (NULL, pagesize, PROT_READ | PROT_WRITE,
+MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+if (page == MAP_FAILED)
+  bdata.can_alloc = 0;
+else
+  {
+   munmap (page, pagesize);
+   bdata.can_alloc = 1;
+  }
+  }
+#endif
  
_Unwind_Backtrace (unwind, );

return bdata.ret;





libbacktrace patch committed: Call munmap after memory test

2018-04-17 Thread Ian Lance Taylor
The bug report https://github.com/ianlancetaylor/libbacktrace/issues/13
points out that when backtrace_full checks whether memory is
available, it doesn't necessarily release that memory.  It will stay
on the free list, so libbacktrace will use more and more memory over
time.  This patch fixes that problem by explicitly calling munmap.
Bootstrapped and ran libbacktrace and Go tests on x86_64-pc-linux-gnu.
Committed to mainline.

Ian


2018-04-17  Ian Lance Taylor  

* backtrace.c (backtrace_full): When testing whether we can
allocate memory, call mmap directly, and munmap the memory.
Index: backtrace.c
===
--- backtrace.c (revision 259359)
+++ backtrace.c (working copy)
@@ -32,12 +32,26 @@ POSSIBILITY OF SUCH DAMAGE.  */
 
 #include "config.h"
 
+#include 
 #include 
 
+#if !BACKTRACE_USES_MALLOC
+#include 
+#endif
+
 #include "unwind.h"
 #include "backtrace.h"
+#include "backtrace-supported.h"
 #include "internal.h"
 
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
 /* The main backtrace_full routine.  */
 
 /* Data passed through _Unwind_Backtrace.  */
@@ -104,7 +118,6 @@ backtrace_full (struct backtrace_state *
backtrace_error_callback error_callback, void *data)
 {
   struct backtrace_data bdata;
-  void *p;
 
   bdata.skip = skip + 1;
   bdata.state = state;
@@ -113,16 +126,25 @@ backtrace_full (struct backtrace_state *
   bdata.data = data;
   bdata.ret = 0;
 
-  /* If we can't allocate any memory at all, don't try to produce
- file/line information.  */
-  p = backtrace_alloc (state, 4096, NULL, NULL);
-  if (p == NULL)
-bdata.can_alloc = 0;
-  else
-{
-  backtrace_free (state, p, 4096, NULL, NULL);
-  bdata.can_alloc = 1;
-}
+#if !BACKTRACE_USES_MALLOC
+  {
+size_t pagesize;
+void *page;
+
+/* If we can't allocate any memory at all, don't try to produce
+   file/line information.  */
+pagesize = getpagesize ();
+page = mmap (NULL, pagesize, PROT_READ | PROT_WRITE, 
+MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+if (page == MAP_FAILED)
+  bdata.can_alloc = 0;
+else
+  {
+   munmap (page, pagesize);
+   bdata.can_alloc = 1;
+  }
+  }
+#endif
 
   _Unwind_Backtrace (unwind, );
   return bdata.ret;


libbacktrace patch committed: Close debuginfo files

2018-01-31 Thread Ian Lance Taylor
This patch to libbacktrace closes any debuginfo files that we opened.
Bootstrapped and ran libbacktrace tests on x86_64-pc-linux-gnu.  This
should fix https://golang.org/issue/23626.  Committed to mainline.

Ian


2018-01-31  Ian Lance Taylor  

* elf.c (elf_add): Close descriptor if we use a debugfile.
* btest.c (check_open_files): New static function.
(main): Call check_open_files.
Index: btest.c
===
--- btest.c (revision 257217)
+++ btest.c (working copy)
@@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include 
 #include 
 #include 
+#include 
 
 #include "filenames.h"
 
@@ -456,6 +457,25 @@ test5 (void)
   return failures;
 }
 
+/* Check that are no files left open.  */
+
+static void
+check_open_files (void)
+{
+  int i;
+
+  for (i = 3; i < 10; i++)
+{
+  if (close (i) == 0)
+   {
+ fprintf (stderr,
+  "ERROR: descriptor %d still open after tests complete\n",
+  i);
+ ++failures;
+   }
+}
+}
+
 /* Run all the tests.  */
 
 int
@@ -474,5 +494,7 @@ main (int argc ATTRIBUTE_UNUSED, char **
 #endif
 #endif
 
+  check_open_files ();
+
   exit (failures ? EXIT_FAILURE : EXIT_SUCCESS);
 }
Index: elf.c
===
--- elf.c   (revision 257217)
+++ elf.c   (working copy)
@@ -2929,12 +2929,19 @@ elf_add (struct backtrace_state *state,
 error_callback, data);
   if (d >= 0)
{
+ int ret;
+
  backtrace_release_view (state, _view, error_callback, data);
  if (debuglink_view_valid)
backtrace_release_view (state, _view, error_callback,
data);
- return elf_add (state, NULL, d, base_address, error_callback, data,
- fileline_fn, found_sym, found_dwarf, 0, 1);
+ ret = elf_add (state, NULL, d, base_address, error_callback, data,
+fileline_fn, found_sym, found_dwarf, 0, 1);
+ if (ret < 0)
+   backtrace_close (d, error_callback, data);
+ else
+   backtrace_close (descriptor, error_callback, data);
+ return ret;
}
 }
 
@@ -2953,10 +2960,17 @@ elf_add (struct backtrace_state *state,
   data);
   if (d >= 0)
{
+ int ret;
+
  backtrace_release_view (state, _view, error_callback,
  data);
- return elf_add (state, NULL, d, base_address, error_callback, data,
- fileline_fn, found_sym, found_dwarf, 0, 1);
+ ret = elf_add (state, NULL, d, base_address, error_callback, data,
+fileline_fn, found_sym, found_dwarf, 0, 1);
+ if (ret < 0)
+   backtrace_close (d, error_callback, data);
+ else
+   backtrace_close(descriptor, error_callback, data);
+ return ret;
}
 }
 


libbacktrace patch committed: Only free sym_view if it is valid

2018-01-25 Thread Ian Lance Taylor
Another libbacktrace patch to avoid use of uninitialized memory: only
free sym_view if it is valid.  Committed to mainline.

Ian

2018-01-25  Ian Lance Taylor  

* pecoff.c (coff_add): Only release syms_view if it is valid.
Index: pecoff.c
===
--- pecoff.c(revision 257052)
+++ pecoff.c(working copy)
@@ -804,8 +804,11 @@ coff_add (struct backtrace_state *state,
 
   backtrace_release_view (state, _view, error_callback, data);
   sects_view_valid = 0;
-  backtrace_release_view (state, _view, error_callback, data);
-  syms_view_valid = 0;
+  if (syms_view_valid)
+{
+  backtrace_release_view (state, _view, error_callback, data);
+  syms_view_valid = 0;
+}
 
   /* Read all the debug sections in a single view, since they are
  probably adjacent in the file.  We never release this view.  */


libbacktrace patch committed: Another memcpy -> coff_read4 fix

2018-01-25 Thread Ian Lance Taylor
This libbacktrace patch fixes another cases where memcpy was used in a
way that would leave some bytes uninitialized on a 64-bit system.
Committed to mainline.

Ian

2018-01-25  Ian Lance Taylor  

* pecoff.c (coff_add): Another memcpy -> coff_read4 fix.
Index: pecoff.c
===
--- pecoff.c(revision 257040)
+++ pecoff.c(working copy)
@@ -631,10 +631,10 @@ coff_add (struct backtrace_state *state,
 goto fail;
 
   {
-const char *vptr = (const char *)fhdr_view.data;
+const unsigned char *vptr = fhdr_view.data;
 
 if (vptr[0] == 'M' && vptr[1] == 'Z')
-  memcpy (_off, vptr + 0x3c, 4);
+  fhdr_off = coff_read4 (vptr + 0x3c);
 else
   fhdr_off = 0;
   }


libbacktrace patch committed: Fix setting str_size on PE/COFF

2018-01-24 Thread Ian Lance Taylor
This libbacktrace patch fixes the setting of str_size on PE/COFF to
not leave some bytes uninitialized on a 64-bit host.  Committed to
mainline.

Ian

2018-01-24  Ian Lance Taylor  

* pecoff.c (coff_add): Use coff_read4, not memcpy.
Index: pecoff.c
===
--- pecoff.c(revision 257038)
+++ pecoff.c(working copy)
@@ -727,7 +727,7 @@ coff_add (struct backtrace_state *state,
goto fail;
   syms_view_valid = 1;
 
-  memcpy (_size, syms_view.data + syms_size, 4);
+  str_size = coff_read4 (syms_view.data + syms_size);
 
   str_off = syms_off + syms_size;
 


libbacktrace patch committed: Only keep 16 entries on free list

2018-01-24 Thread Ian Lance Taylor
PR 68239 points out that libbacktrace can sometimes take a long time
scanning the list of free memory blocks looking for one that is large
enough.  Since the libbacktrace memory allocator does not have to be
perfect in practice, only keep the 16 largest entries on the free
list.  Bootstrapped and ran libbacktrace and libgo tests on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

2018-01-24  Ian Lance Taylor  

PR other/68239
* mmap.c (backtrace_free_locked): Don't put more than 16 entries
on the free list.
Index: mmap.c
===
--- mmap.c  (revision 257038)
+++ mmap.c  (working copy)
@@ -69,11 +69,33 @@ struct backtrace_freelist_struct
 static void
 backtrace_free_locked (struct backtrace_state *state, void *addr, size_t size)
 {
-  /* Just leak small blocks.  We don't have to be perfect.  */
+  /* Just leak small blocks.  We don't have to be perfect.  Don't put
+ more than 16 entries on the free list, to avoid wasting time
+ searching when allocating a block.  If we have more than 16
+ entries, leak the smallest entry.  */
+
   if (size >= sizeof (struct backtrace_freelist_struct))
 {
+  size_t c;
+  struct backtrace_freelist_struct **ppsmall;
+  struct backtrace_freelist_struct **pp;
   struct backtrace_freelist_struct *p;
 
+  c = 0;
+  ppsmall = NULL;
+  for (pp = >freelist; *pp != NULL; pp = &(*pp)->next)
+   {
+ if (ppsmall == NULL || (*pp)->size < (*ppsmall)->size)
+   ppsmall = pp;
+ ++c;
+   }
+  if (c >= 16)
+   {
+ if (size <= (*ppsmall)->size)
+   return;
+ *ppsmall = (*ppsmall)->next;
+   }
+
   p = (struct backtrace_freelist_struct *) addr;
   p->next = state->freelist;
   p->size = size;


libbacktrace patch committed: Fix handling of inflate default dist table

2018-01-16 Thread Ian Lance Taylor
I misunderstood how the dist codes are handled in block type 1.  I
also think'od the length of the codes for the default table.  This
patch fixes these problems, along with a test case that exposes them.
Bootstrapped and ran libbacktrace tests on x86_64-pc-linux-gnu.
Committed to mainline.

Ian

2018-01-16  Ian Lance Taylor  

* elf.c (codes) [GENERATE_FIXED_HUFFMAN_TABLE]: Fix size to be
288.
(main) [GENERATE_FIXED_HUFFMAN_TABLE]: Pass 288 to
elf_zlib_inflate_table.  Generate elf_zlib_default_dist_table.
(elf_zlib_default_table): Update.
(elf_zlib_default_dist_table): New static array.
(elf_zlib_inflate): Use elf_zlib_default_dist_table for dist table
for block type 1.
* ztest.c (struct zlib_test): Add uncompressed_len.
(tests): Initialize uncompressed_len field.  Add new test case.
(test_samples): Use uncompressed_len field.
Index: elf.c
===
--- elf.c   (revision 256593)
+++ elf.c   (working copy)
@@ -1461,7 +1461,7 @@ elf_zlib_inflate_table (unsigned char *c
 #include 
 
 static uint16_t table[ZDEBUG_TABLE_SIZE];
-static unsigned char codes[287];
+static unsigned char codes[288];
 
 int
 main ()
@@ -1476,7 +1476,7 @@ main ()
 codes[i] = 7;
   for (i = 280; i <= 287; ++i)
 codes[i] = 8;
-  if (!elf_zlib_inflate_table ([0], 287, [0], [0]))
+  if (!elf_zlib_inflate_table ([0], 288, [0], [0]))
 {
   fprintf (stderr, "elf_zlib_inflate_table failed\n");
   exit (EXIT_FAILURE);
@@ -1495,48 +1495,72 @@ main ()
   printf ("\n");
 }
   printf ("};\n");
+  printf ("\n");
+
+  for (i = 0; i < 32; ++i)
+codes[i] = 5;
+  if (!elf_zlib_inflate_table ([0], 32, [0], [0]))
+{
+  fprintf (stderr, "elf_zlib_inflate_table failed\n");
+  exit (EXIT_FAILURE);
+}
+
+  printf ("static const uint16_t elf_zlib_default_dist_table[%#zx] =\n",
+ final_next_secondary + 0x100);
+  printf ("{\n");
+  for (i = 0; i < final_next_secondary + 0x100; i += 8)
+{
+  size_t j;
+
+  printf (" ");
+  for (j = i; j < final_next_secondary + 0x100 && j < i + 8; ++j)
+   printf (" %#x,", table[j]);
+  printf ("\n");
+}
+  printf ("};\n");
+
   return 0;
 }
 
 #endif
 
-/* The fixed table generated by the #ifdef'ed out main function
+/* The fixed tables generated by the #ifdef'ed out main function
above.  */
 
 static const uint16_t elf_zlib_default_table[0x170] =
 {
-  0xd00, 0xe50, 0xe10, 0xf18, 0xd10, 0xe70, 0xe30, 0x1232,
-  0xd08, 0xe60, 0xe20, 0x1212, 0xe00, 0xe80, 0xe40, 0x1252,
-  0xd04, 0xe58, 0xe18, 0x1202, 0xd14, 0xe78, 0xe38, 0x1242,
-  0xd0c, 0xe68, 0xe28, 0x1222, 0xe08, 0xe88, 0xe48, 0x1262,
-  0xd02, 0xe54, 0xe14, 0xf1c, 0xd12, 0xe74, 0xe34, 0x123a,
-  0xd0a, 0xe64, 0xe24, 0x121a, 0xe04, 0xe84, 0xe44, 0x125a,
-  0xd06, 0xe5c, 0xe1c, 0x120a, 0xd16, 0xe7c, 0xe3c, 0x124a,
-  0xd0e, 0xe6c, 0xe2c, 0x122a, 0xe0c, 0xe8c, 0xe4c, 0x126a,
-  0xd01, 0xe52, 0xe12, 0xf1a, 0xd11, 0xe72, 0xe32, 0x1236,
-  0xd09, 0xe62, 0xe22, 0x1216, 0xe02, 0xe82, 0xe42, 0x1256,
-  0xd05, 0xe5a, 0xe1a, 0x1206, 0xd15, 0xe7a, 0xe3a, 0x1246,
-  0xd0d, 0xe6a, 0xe2a, 0x1226, 0xe0a, 0xe8a, 0xe4a, 0x1266,
-  0xd03, 0xe56, 0xe16, 0xf1e, 0xd13, 0xe76, 0xe36, 0x123e,
-  0xd0b, 0xe66, 0xe26, 0x121e, 0xe06, 0xe86, 0xe46, 0x125e,
-  0xd07, 0xe5e, 0xe1e, 0x120e, 0xd17, 0xe7e, 0xe3e, 0x124e,
-  0xd0f, 0xe6e, 0xe2e, 0x122e, 0xe0e, 0xe8e, 0xe4e, 0x126e,
-  0xd00, 0xe51, 0xe11, 0xf19, 0xd10, 0xe71, 0xe31, 0x1234,
-  0xd08, 0xe61, 0xe21, 0x1214, 0xe01, 0xe81, 0xe41, 0x1254,
-  0xd04, 0xe59, 0xe19, 0x1204, 0xd14, 0xe79, 0xe39, 0x1244,
-  0xd0c, 0xe69, 0xe29, 0x1224, 0xe09, 0xe89, 0xe49, 0x1264,
-  0xd02, 0xe55, 0xe15, 0xf1d, 0xd12, 0xe75, 0xe35, 0x123c,
-  0xd0a, 0xe65, 0xe25, 0x121c, 0xe05, 0xe85, 0xe45, 0x125c,
-  0xd06, 0xe5d, 0xe1d, 0x120c, 0xd16, 0xe7d, 0xe3d, 0x124c,
-  0xd0e, 0xe6d, 0xe2d, 0x122c, 0xe0d, 0xe8d, 0xe4d, 0x126c,
-  0xd01, 0xe53, 0xe13, 0xf1b, 0xd11, 0xe73, 0xe33, 0x1238,
-  0xd09, 0xe63, 0xe23, 0x1218, 0xe03, 0xe83, 0xe43, 0x1258,
-  0xd05, 0xe5b, 0xe1b, 0x1208, 0xd15, 0xe7b, 0xe3b, 0x1248,
-  0xd0d, 0xe6b, 0xe2b, 0x1228, 0xe0b, 0xe8b, 0xe4b, 0x1268,
-  0xd03, 0xe57, 0xe17, 0x1200, 0xd13, 0xe77, 0xe37, 0x1240,
-  0xd0b, 0xe67, 0xe27, 0x1220, 0xe07, 0xe87, 0xe47, 0x1260,
-  0xd07, 0xe5f, 0xe1f, 0x1210, 0xd17, 0xe7f, 0xe3f, 0x1250,
-  0xd0f, 0xe6f, 0xe2f, 0x1230, 0xe0f, 0xe8f, 0xe4f, 0,
+  0xd00, 0xe50, 0xe10, 0xf18, 0xd10, 0xe70, 0xe30, 0x1230,
+  0xd08, 0xe60, 0xe20, 0x1210, 0xe00, 0xe80, 0xe40, 0x1250,
+  0xd04, 0xe58, 0xe18, 0x1200, 0xd14, 0xe78, 0xe38, 0x1240,
+  0xd0c, 0xe68, 0xe28, 0x1220, 0xe08, 0xe88, 0xe48, 0x1260,
+  0xd02, 0xe54, 0xe14, 0xf1c, 0xd12, 0xe74, 0xe34, 0x1238,
+  0xd0a, 0xe64, 0xe24, 0x1218, 0xe04, 0xe84, 0xe44, 0x1258,
+  0xd06, 0xe5c, 0xe1c, 0x1208, 0xd16, 0xe7c, 0xe3c, 0x1248,
+  0xd0e, 0xe6c, 0xe2c, 0x1228, 0xe0c, 0xe8c, 0xe4c, 0x1268,
+  0xd01, 0xe52, 0xe12, 0xf1a, 0xd11, 0xe72, 0xe32, 0x1234,
+  0xd09, 0xe62, 0xe22, 0x1214, 0xe02, 0xe82, 0xe42, 0x1254,
+  0xd05, 

Re: libbacktrace patch committed: Support compressed debug sections

2017-11-07 Thread Ian Lance Taylor
On Sat, Nov 4, 2017 at 3:07 AM, Gerald Pfeifer  wrote:
> On Fri, 6 Oct 2017, Ian Lance Taylor wrote:
>> Thanks for the report.  I committed this patch, which I hope will fix
>> the problem.
>
>> * ztest.c (test_large): Pass unsigned long *, not size_t *, to
>> zlib uncompress function.
>
> Thank you, yes it did.  (Sorry, I thought I had responded back
> then, but apparently only in my mind, not with my keyboard.)
>
> I'm seeing the following as part of my nightly builds, though:
>
>test hello: got uncompressed length 0, want 13
>test goodbye: got uncompressed length 0, want 14
>inflate large: got uncompressed length 0, want 387851
>
> Any idea what this might be?

No, no idea, sorry.  That seems strange, as though the uncompressor is
not doing anything for some reason.  Can you debug a bit?

Ian


Re: libbacktrace patch committed: Support compressed debug sections

2017-11-04 Thread Gerald Pfeifer
On Fri, 6 Oct 2017, Ian Lance Taylor wrote:
> Thanks for the report.  I committed this patch, which I hope will fix
> the problem.

> * ztest.c (test_large): Pass unsigned long *, not size_t *, to
> zlib uncompress function.

Thank you, yes it did.  (Sorry, I thought I had responded back 
then, but apparently only in my mind, not with my keyboard.)

I'm seeing the following as part of my nightly builds, though:

   test hello: got uncompressed length 0, want 13
   test goodbye: got uncompressed length 0, want 14
   inflate large: got uncompressed length 0, want 387851

Any idea what this might be?

Gerald


Re: GCC 7 libbacktrace patch committed: Ignore compressed debug sections

2017-10-10 Thread Ian Lance Taylor
On Tue, Oct 10, 2017 at 12:47 PM, Paolo Carlini
 wrote:
>
> On 10/10/2017 18:55, Ian Lance Taylor wrote:
>>
>> Index: elf.c
>> ===
>> --- elf.c   (revision 253593)
>> +++ elf.c   (working copy)
>> @@ -103,6 +103,7 @@
>>   #undef SHT_SYMTAB
>>   #undef SHT_STRTAB
>>   #undef SHT_DYNSYM
>> +#undef SFH_COMPRESSED
>>   #undef STT_OBJECT
>>   #undef STT_FUNC
>
> You appear to have a typo here: SFH_COMPRESSED instead of SHF_COMPRESSED.
> That breaks the bootstrap for me:
>
> ../../../../gcc-7-branch/libsanitizer/libbacktrace/../../libbacktrace/elf.c:199:0:
> error: "SHF_COMPRESSED" redefined [-Werror]
>  #define SHF_COMPRESSED 0x800
>
> I'm going to test and commit the obvious fix, if nobody beats me to it.

Argh.  Sorry about that.  Please do commit the obvious fix.  Thanks.

Ian


Re: GCC 7 libbacktrace patch committed: Ignore compressed debug sections

2017-10-10 Thread Paolo Carlini

Hi,

On 10/10/2017 18:55, Ian Lance Taylor wrote:

Index: elf.c
===
--- elf.c   (revision 253593)
+++ elf.c   (working copy)
@@ -103,6 +103,7 @@
  #undef SHT_SYMTAB
  #undef SHT_STRTAB
  #undef SHT_DYNSYM
+#undef SFH_COMPRESSED
  #undef STT_OBJECT
  #undef STT_FUNC
You appear to have a typo here: SFH_COMPRESSED instead of 
SHF_COMPRESSED. That breaks the bootstrap for me:


../../../../gcc-7-branch/libsanitizer/libbacktrace/../../libbacktrace/elf.c:199:0: 
error: "SHF_COMPRESSED" redefined [-Werror]

 #define SHF_COMPRESSED 0x800

I'm going to test and commit the obvious fix, if nobody beats me to it.

Paolo.


GCC 7 libbacktrace patch committed: Ignore compressed debug sections

2017-10-10 Thread Ian Lance Taylor
This patch to the GCC 7 libbacktrace ignores compressed debug
sections.  If we don't, the DWARF reader reports an error.  Since the
GCC 7 libbacktrace does not support uncompressing the debug sections,
ignoring them is the best approach (on trunk, we uncompress).  This is
for PR 80914.  Bootstrapped and ran libbacktrace tests on
x86_64-pc-linux-gnu.  Committed to GCC 7 branch.

Ian

2017-10-10  Ian Lance Taylor  

PR go/80914
* elf.c (SHF_COMPRESSED): Define.
(elf_add): Ignore debug sections with SHF_COMPRESSED set.
Index: elf.c
===
--- elf.c   (revision 253593)
+++ elf.c   (working copy)
@@ -103,6 +103,7 @@
 #undef SHT_SYMTAB
 #undef SHT_STRTAB
 #undef SHT_DYNSYM
+#undef SFH_COMPRESSED
 #undef STT_OBJECT
 #undef STT_FUNC
 
@@ -195,6 +196,8 @@
 #define SHT_STRTAB 3
 #define SHT_DYNSYM 11
 
+#define SHF_COMPRESSED 0x800
+
 #if BACKTRACE_ELF_SIZE == 32
 
 typedef struct
@@ -700,7 +703,8 @@
 
   for (j = 0; j < (int) DEBUG_MAX; ++j)
{
- if (strcmp (name, debug_section_names[j]) == 0)
+ if (strcmp (name, debug_section_names[j]) == 0
+  && (shdr->sh_flags & SHF_COMPRESSED) == 0)
{
  sections[j].offset = shdr->sh_offset;
  sections[j].size = shdr->sh_size;


Re: libbacktrace patch committed: Support compressed debug sections

2017-10-06 Thread Ian Lance Taylor
On Fri, Oct 6, 2017 at 3:22 AM, Gerald Pfeifer  wrote:
> On Thu, 28 Sep 2017, Ian Lance Taylor wrote:
>> This patch to libbacktrace adds support for compressed debug sections.
>> 2017-09-28  Ian Lance Taylor  
>>
>> PR other/67165
>> * elf.c (__builtin_prefetch): Define if not __GNUC__.
>> (unlikely): Define.
>> (SHF_UNCOMPRESSED, ELFCOMPRESS_ZLIB): Define.
>> (b_elf_chdr): Define type.
>> (enum debug_section): Add ZDEBUG_xxx values.
>
> Since this change I am seeing the following in my night GCC build
> and test logs on FreeBSD systems:
>
> gmake[2]: autogen: Command not found
> gmake[2]: *** [Makefile:176: check] Error 127
> gmake[1]: *** [Makefile:3759: check-fixincludes] Error 2
> /scratch/tmp/gerald/GCC-HEAD/libbacktrace/ztest.c: In function 'test_large':
> /scratch/tmp/gerald/GCC-HEAD/libbacktrace/ztest.c:384:41: warning: passing 
> argument 2 of 'uncompress' from incompatible pointer type 
> [-Wincompatible-pointer-types]
>r = uncompress (uncompressed_buf, _bufsize,
>  ^
> In file included from /scratch/tmp/gerald/GCC-HEAD/libbacktrace/ztest.c:43:0:
> /usr/include/zlib.h:1265:21: note: expected 'uLongf * {aka long unsigned int 
> *}' but argument is of type 'size_t * {aka unsigned int *}'
>  ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
>  ^~
> /scratch/tmp/gerald/GCC-HEAD/libbacktrace/ztest.c: In function 'test_large':
> /scratch/tmp/gerald/GCC-HEAD/libbacktrace/ztest.c:384:41: warning: passing 
> argument 2 of 'uncompress' from incompatible pointer type 
> [-Wincompatible-pointer-types]
>r = uncompress (uncompressed_buf, _bufsize,
>  ^
> In file included from /scratch/tmp/gerald/GCC-HEAD/libbacktrace/ztest.c:43:0:
> /usr/include/zlib.h:1265:21: note: expected 'uLongf * {aka long unsigned int 
> *}' but argument is of type 'size_t * {aka unsigned int *}'
>  ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
>  ^~
> gmake[4]: *** [Makefile:306: check-DEJAGNU] Error 1
> gmake[3]: *** [Makefile:350: check-am] Error 2
> gmake[2]: *** [Makefile:904: check-recursive] Error 1
> gmake[1]: *** [Makefile:22343: check-target-libgomp] Error 2
> Fatal error 'mutex is on list' at line 272 in file 
> /usr/src/lib/libthr/thread/thr_mutex.c (errno = 0)
> Fatal error 'mutex is on list' at line 272 in file 
> /usr/src/lib/libthr/thread/thr_mutex.c (errno = 0)
> gmake: *** [Makefile:2286: do-check] Error 2

Thanks for the report.  I committed this patch, which I hope will fix
the problem.

Ian

2017-10-06  Ian Lance Taylor  

* ztest.c (test_large): Pass unsigned long *, not size_t *, to
zlib uncompress function.
Index: ztest.c
===
--- ztest.c (revision 253490)
+++ ztest.c (working copy)
@@ -369,6 +369,8 @@ test_large (struct backtrace_state *stat
 
   for (i = 0; i < trials; ++i)
 {
+  unsigned long uncompress_sizearg;
+
   cid = ZLIB_CLOCK_GETTIME_ARG;
   if (clock_gettime (cid, ) < 0)
{
@@ -406,7 +408,8 @@ test_large (struct backtrace_state *stat
  return;
}
 
-  r = uncompress (uncompressed_buf, _bufsize,
+  uncompress_sizearg = uncompressed_bufsize;
+  r = uncompress (uncompressed_buf, _sizearg,
  compressed_buf + 12, compressed_bufsize - 12);
 
   if (clock_gettime (cid, ) < 0)


Re: libbacktrace patch committed: Support compressed debug sections

2017-10-06 Thread Gerald Pfeifer
On Thu, 28 Sep 2017, Ian Lance Taylor wrote:
> This patch to libbacktrace adds support for compressed debug sections.
> 2017-09-28  Ian Lance Taylor  
> 
> PR other/67165
> * elf.c (__builtin_prefetch): Define if not __GNUC__.
> (unlikely): Define.
> (SHF_UNCOMPRESSED, ELFCOMPRESS_ZLIB): Define.
> (b_elf_chdr): Define type.
> (enum debug_section): Add ZDEBUG_xxx values.

Since this change I am seeing the following in my night GCC build
and test logs on FreeBSD systems:

gmake[2]: autogen: Command not found
gmake[2]: *** [Makefile:176: check] Error 127
gmake[1]: *** [Makefile:3759: check-fixincludes] Error 2
/scratch/tmp/gerald/GCC-HEAD/libbacktrace/ztest.c: In function 'test_large':
/scratch/tmp/gerald/GCC-HEAD/libbacktrace/ztest.c:384:41: warning: passing 
argument 2 of 'uncompress' from incompatible pointer type 
[-Wincompatible-pointer-types]
   r = uncompress (uncompressed_buf, _bufsize,
 ^
In file included from /scratch/tmp/gerald/GCC-HEAD/libbacktrace/ztest.c:43:0:
/usr/include/zlib.h:1265:21: note: expected 'uLongf * {aka long unsigned int 
*}' but argument is of type 'size_t * {aka unsigned int *}'
 ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
 ^~
/scratch/tmp/gerald/GCC-HEAD/libbacktrace/ztest.c: In function 'test_large':
/scratch/tmp/gerald/GCC-HEAD/libbacktrace/ztest.c:384:41: warning: passing 
argument 2 of 'uncompress' from incompatible pointer type 
[-Wincompatible-pointer-types]
   r = uncompress (uncompressed_buf, _bufsize,
 ^
In file included from /scratch/tmp/gerald/GCC-HEAD/libbacktrace/ztest.c:43:0:
/usr/include/zlib.h:1265:21: note: expected 'uLongf * {aka long unsigned int 
*}' but argument is of type 'size_t * {aka unsigned int *}'
 ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
 ^~
gmake[4]: *** [Makefile:306: check-DEJAGNU] Error 1
gmake[3]: *** [Makefile:350: check-am] Error 2
gmake[2]: *** [Makefile:904: check-recursive] Error 1
gmake[1]: *** [Makefile:22343: check-target-libgomp] Error 2
Fatal error 'mutex is on list' at line 272 in file 
/usr/src/lib/libthr/thread/thr_mutex.c (errno = 0)
Fatal error 'mutex is on list' at line 272 in file 
/usr/src/lib/libthr/thread/thr_mutex.c (errno = 0)
gmake: *** [Makefile:2286: do-check] Error 2

Gerald


libbacktrace patch committed: Minor decompression improvement

2017-10-05 Thread Ian Lance Taylor
I've committed a patch to libbacktrace to speed up decompression a few
percent by loading 32-bit values rather than 8-bit bytes.
Bootstrapped and ran libbacktrace and Go tests on x86_64-pc-linux-gnu.
Committed to mainline.

Ian

2017-10-05  Ian Lance Taylor  

* elf.c (elf_zlib_fetch): Change pval argument to uint64_t *.
Read a four byte integer.
(elf_zlib_inflate): Change val to uint64_t.  Align pin to a 32-bit
boundary before ever calling elf_zlib_fetch.
* ztest.c (test_large): Simplify print statements a bit.
Index: elf.c
===
--- elf.c   (revision 253376)
+++ elf.c   (working copy)
@@ -1031,11 +1031,12 @@ elf_zlib_failed(void)
 
 static int
 elf_zlib_fetch (const unsigned char **ppin, const unsigned char *pinend,
-   uint32_t *pval, unsigned int *pbits)
+   uint64_t *pval, unsigned int *pbits)
 {
   unsigned int bits;
   const unsigned char *pin;
-  uint32_t val;
+  uint64_t val;
+  uint32_t next;
 
   bits = *pbits;
   if (bits >= 15)
@@ -1043,20 +1044,25 @@ elf_zlib_fetch (const unsigned char **pp
   pin = *ppin;
   val = *pval;
 
-  if (unlikely (pinend - pin < 2))
+  if (unlikely (pinend - pin < 4))
 {
   elf_zlib_failed ();
   return 0;
 }
-  val |= pin[0] << bits;
-  val |= pin[1] << (bits + 8);
-  bits += 16;
-  pin += 2;
-
-  /* We will need the next two bytes soon.  We ask for high temporal
- locality because we will need the whole cache line soon.  */
-  __builtin_prefetch (pin, 0, 3);
-  __builtin_prefetch (pin + 1, 0, 3);
+
+  /* We've ensured that PIN is aligned.  */
+  next = *(const uint32_t *)pin;
+
+#if __BYTE_ORDER == __ORDER_BIG_ENDIAN
+  next = __builtin_bswap32 (next);
+#endif
+
+  val |= (uint64_t)next << bits;
+  bits += 32;
+  pin += 4;
+
+  /* We will need the next four bytes soon.  */
+  __builtin_prefetch (pin, 0, 0);
 
   *ppin = pin;
   *pval = val;
@@ -1566,7 +1572,7 @@ elf_zlib_inflate (const unsigned char *p
   poutend = pout + sout;
   while ((pinend - pin) > 4)
 {
-  uint32_t val;
+  uint64_t val;
   unsigned int bits;
   int last;
 
@@ -1601,10 +1607,19 @@ elf_zlib_inflate (const unsigned char *p
}
   pin += 2;
 
-  /* Read blocks until one is marked last.  */
+  /* Align PIN to a 32-bit boundary.  */
 
   val = 0;
   bits = 0;
+  while uintptr_t) pin) & 3) != 0)
+   {
+ val |= (uint64_t)*pin << bits;
+ bits += 8;
+ ++pin;
+   }
+
+  /* Read blocks until one is marked last.  */
+
   last = 0;
 
   while (!last)
@@ -1671,6 +1686,14 @@ elf_zlib_inflate (const unsigned char *p
  pout += len;
  pin += len;
 
+ /* Align PIN.  */
+ while uintptr_t) pin) & 3) != 0)
+   {
+ val |= (uint64_t)*pin << bits;
+ bits += 8;
+ ++pin;
+   }
+
  /* Go around to read the next block.  */
  continue;
}
Index: ztest.c
===
--- ztest.c (revision 253377)
+++ ztest.c (working copy)
@@ -432,9 +432,9 @@ test_large (struct backtrace_state *stat
   ctime = average_time (ctimes, trials);
   ztime = average_time (ztimes, trials);
 
-  printf ("backtrace time: %zu ns\n", ctime);
-  printf ("zlib time:: %zu ns\n", ztime);
-  printf ("percentage: %g\n", (double) ztime / (double) ctime);
+  printf ("backtrace: %zu ns\n", ctime);
+  printf ("zlib : %zu ns\n", ztime);
+  printf ("ratio: %g\n", (double) ztime / (double) ctime);
 
   return;
 


Re: libbacktrace patch committed: Support compressed debug sections

2017-10-02 Thread Ian Lance Taylor
Thanks for the fixes.  I made some style tweaks, committed as follows
after bootstrap and testing.

Ian

2017-10-02  Ian Lance Taylor  

* ztest.c: #include .
(TEST_TIMING): Don't define, don't test.
(xclock_gettime, xclockid_t): Define if !HAVE_CLOCK_GETTIME.
(clockid_t, clock_gettime, CLOCK_REALTIME): Likewise.
(ZLIB_CLOCK_GETTIME_ARG): Define.
* configure.ac: Change clock_gettime_link to CLOCK_GETTIME_LINK.
* Makefile.am: Likewise.
* configure, Makefile.in: Rebuild.
Index: Makefile.am
===
--- Makefile.am (revision 253376)
+++ Makefile.am (working copy)
@@ -108,7 +108,7 @@ ztest_LDADD = libbacktrace.la
 if HAVE_ZLIB
 ztest_LDADD += -lz
 endif
-ztest_LDADD += $(clock_gettime_link)
+ztest_LDADD += $(CLOCK_GETTIME_LINK)
 
 check_PROGRAMS += ztest
 
Index: configure.ac
===
--- configure.ac(revision 253376)
+++ configure.ac(working copy)
@@ -397,11 +397,11 @@ clock_gettime_link=
 # we're using this for test timing only.
 if test "$ac_cv_func_clock_gettime" = no; then
   AC_CHECK_LIB(rt, clock_gettime,
-[clock_gettime_link=-lrt
+[CLOCK_GETTIME_LINK=-lrt
  AC_DEFINE(HAVE_CLOCK_GETTIME, 1,
   [Define to 1 if you have the `clock_gettime' function.])])
 fi
-AC_SUBST(clock_gettime_link)
+AC_SUBST(CLOCK_GETTIME_LINK)
 
 dnl Test whether the compiler supports the -pthread option.
 AC_CACHE_CHECK([whether -pthread is supported],
Index: ztest.c
===
--- ztest.c (revision 253376)
+++ ztest.c (working copy)
@@ -32,6 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.  */
 
 #include "config.h"
 
+#include 
 #include 
 #include 
 #include 
@@ -43,16 +44,37 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include 
 #endif
 
-#ifdef HAVE_CLOCK_GETTIME
-# define TEST_TIMING
-#endif
-
 #include "backtrace.h"
 #include "backtrace-supported.h"
 
 #include "internal.h"
 #include "testlib.h"
 
+#ifndef HAVE_CLOCK_GETTIME
+
+typedef int xclockid_t;
+
+static int
+xclock_gettime (xclockid_t id ATTRIBUTE_UNUSED,
+   struct timespec *ts ATTRIBUTE_UNUSED)
+{
+  errno = EINVAL;
+  return -1;
+}
+
+#define clockid_t xclockid_t
+#define clock_gettime xclock_gettime
+#undef CLOCK_REALTIME
+#define CLOCK_REALTIME 0
+
+#endif /* !defined(HAVE_CLOCK_GETTIME) */
+
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+#define ZLIB_CLOCK_GETTIME_ARG CLOCK_PROCESS_CPUTIME_ID
+#else
+#define ZLIB_CLOCK_GETTIME_ARG CLOCK_REALTIME
+#endif
+
 /* Some tests for the local zlib inflation code.  */
 
 struct zlib_test
@@ -161,7 +183,7 @@ test_samples (struct backtrace_state *st
 }
 }
 
-#if defined HAVE_ZLIB && defined TEST_TIMING
+#ifdef HAVE_ZLIB
 
 /* Given a set of TRIALS timings, discard the lowest and highest
values and return the mean average of the rest.  */
@@ -220,7 +242,6 @@ test_large (struct backtrace_state *stat
   unsigned char *uncompressed_buf;
   size_t uncompressed_bufsize;
   int r;
-# ifdef TEST_TIMING
   clockid_t cid;
   struct timespec ts1;
   struct timespec ts2;
@@ -229,7 +250,6 @@ test_large (struct backtrace_state *stat
   const size_t trials = 16;
   size_t ctimes[16];
   size_t ztimes[16];
-# endif /* TEST_TIMING */
   static const char * const names[] = {
 "Mark.Twain-Tom.Sawyer.txt",
 "../libgo/go/compress/testdata/Mark.Twain-Tom.Sawyer.txt"
@@ -347,16 +367,13 @@ test_large (struct backtrace_state *stat
 
   printf ("PASS: inflate large\n");
 
-# ifdef TEST_TIMING
-
   for (i = 0; i < trials; ++i)
 {
-  cid = CLOCK_REALTIME;
-#ifdef CLOCK_PROCESS_CPUTIME_ID
-  cid = CLOCK_PROCESS_CPUTIME_ID;
-#endif
+  cid = ZLIB_CLOCK_GETTIME_ARG;
   if (clock_gettime (cid, ) < 0)
{
+ if (errno == EINVAL)
+   return;
  perror ("clock_gettime");
  return;
}
@@ -419,8 +436,6 @@ test_large (struct backtrace_state *stat
   printf ("zlib time:: %zu ns\n", ztime);
   printf ("percentage: %g\n", (double) ztime / (double) ctime);
 
-# endif /* TEST_TIMING */
-
   return;
 
  fail:


Re: libbacktrace patch committed: Support compressed debug sections

2017-10-02 Thread Thomas Schwinge
Hi!

On Mon, 02 Oct 2017 14:00:36 +0200, I wrote:
> On Thu, 28 Sep 2017 17:30:53 -0700, Ian Lance Taylor  wrote:
> > This patch to libbacktrace adds support for compressed debug sections.
> > [...]
> 
> > --- ztest.c (revision 0)
> > +++ ztest.c (working copy)
> > @@ -0,0 +1,446 @@
> > +/* ztest.c -- Test for libbacktrace inflate code.
> > +[...]
> > +  cid = CLOCK_REALTIME;
> > +#ifdef CLOCK_PROCESS_CPUTIME_ID
> > +  cid = CLOCK_PROCESS_CPUTIME_ID;
> > +#endif
> > +  if (clock_gettime (cid, ) < 0)
> > +[...]
> 
> On an elderly system, I ran into that not linking [...]

> {+ztest-ztest.o: In function `test_large':+}
> {+[...]/source-gcc/libbacktrace/ztest.c:350: undefined reference to 
> `clock_gettime'+}

That's because the version of glibc used still provided clock_gettime in
librt only.

Committed to trunk r253345, as obvious:

commit 0b986d3d7a36d3b3f84a0221f8a48af55e9aa08a
Author: tschwinge 
Date:   Mon Oct 2 11:56:39 2017 +

libbacktrace: Support the case that clock_gettime is in librt

libbacktrace/
PR other/67165
* Makefile.am: Append the content of clock_gettime_link to
ztest_LDADD.
* configure.ac: Test for the case that clock_gettime is in librt.
* Makefile.in: Regenerate.
* configure: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@253345 
138bc75d-0d04-0410-961f-82ee72b054a4
---
 libbacktrace/ChangeLog|  7 ++
 libbacktrace/Makefile.am  |  1 +
 libbacktrace/Makefile.in  |  6 +++--
 libbacktrace/configure| 56 +--
 libbacktrace/configure.ac | 12 ++
 5 files changed, 78 insertions(+), 4 deletions(-)

diff --git libbacktrace/ChangeLog libbacktrace/ChangeLog
index 0e4cfd2..fde5a1b 100644
--- libbacktrace/ChangeLog
+++ libbacktrace/ChangeLog
@@ -1,6 +1,13 @@
 2017-10-02  Thomas Schwinge  
 
PR other/67165
+   * Makefile.am: Append the content of clock_gettime_link to
+   ztest_LDADD.
+   * configure.ac: Test for the case that clock_gettime is in librt.
+   * Makefile.in: Regenerate.
+   * configure: Likewise.
+
+   PR other/67165
* configure.ac: Check for clock_gettime.
* config.h.in: Regenerate.
* configure: Likewise.
diff --git libbacktrace/Makefile.am libbacktrace/Makefile.am
index 11d94eb..b4f4df4 100644
--- libbacktrace/Makefile.am
+++ libbacktrace/Makefile.am
@@ -108,6 +108,7 @@ ztest_LDADD = libbacktrace.la
 if HAVE_ZLIB
 ztest_LDADD += -lz
 endif
+ztest_LDADD += $(clock_gettime_link)
 
 check_PROGRAMS += ztest
 
diff --git libbacktrace/Makefile.in libbacktrace/Makefile.in
index ceb769d..30a1442 100644
--- libbacktrace/Makefile.in
+++ libbacktrace/Makefile.in
@@ -165,7 +165,7 @@ ttest_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) 
$(LIBTOOLFLAGS) \
 @NATIVE_TRUE@  ztest-testlib.$(OBJEXT)
 ztest_OBJECTS = $(am_ztest_OBJECTS)
 @NATIVE_TRUE@ztest_DEPENDENCIES = libbacktrace.la \
-@NATIVE_TRUE@  $(am__DEPENDENCIES_1)
+@NATIVE_TRUE@  $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
 ztest_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(ztest_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
@@ -287,6 +287,7 @@ build_cpu = @build_cpu@
 build_os = @build_os@
 build_vendor = @build_vendor@
 builddir = @builddir@
+clock_gettime_link = @clock_gettime_link@
 datadir = @datadir@
 datarootdir = @datarootdir@
 docdir = @docdir@
@@ -383,7 +384,8 @@ TESTS = $(check_PROGRAMS) $(am__append_4)
 @NATIVE_TRUE@stest_LDADD = libbacktrace.la
 @NATIVE_TRUE@ztest_SOURCES = ztest.c testlib.c
 @NATIVE_TRUE@ztest_CFLAGS = -DSRCDIR=\"$(srcdir)\"
-@NATIVE_TRUE@ztest_LDADD = libbacktrace.la $(am__append_2)
+@NATIVE_TRUE@ztest_LDADD = libbacktrace.la $(am__append_2) \
+@NATIVE_TRUE@  $(clock_gettime_link)
 @NATIVE_TRUE@edtest_SOURCES = edtest.c edtest2_build.c testlib.c
 @NATIVE_TRUE@edtest_LDADD = libbacktrace.la
 @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ttest_SOURCES = ttest.c testlib.c
diff --git libbacktrace/configure libbacktrace/configure
index 062dc77..57ca5eb 100755
--- libbacktrace/configure
+++ libbacktrace/configure
@@ -614,6 +614,7 @@ HAVE_ZLIB_TRUE
 HAVE_PTHREAD_FALSE
 HAVE_PTHREAD_TRUE
 PTHREAD_CFLAGS
+clock_gettime_link
 BACKTRACE_USES_MALLOC
 ALLOC_FILE
 VIEW_FILE
@@ -11145,7 +11146,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11148 "configure"
+#line 11149 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11251,7 +11252,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11254 "configure"
+#line 11255 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12759,6 +12760,57 @@ _ACEOF
 fi
 done
 
+clock_gettime_link=
+# At least for glibc, 

Re: libbacktrace patch committed: Support compressed debug sections

2017-10-02 Thread Thomas Schwinge
Hi!

On Thu, 28 Sep 2017 17:30:53 -0700, Ian Lance Taylor  wrote:
> This patch to libbacktrace adds support for compressed debug sections.
> [...]

> --- ztest.c   (revision 0)
> +++ ztest.c   (working copy)
> @@ -0,0 +1,446 @@
> +/* ztest.c -- Test for libbacktrace inflate code.
> +[...]
> +  cid = CLOCK_REALTIME;
> +#ifdef CLOCK_PROCESS_CPUTIME_ID
> +  cid = CLOCK_PROCESS_CPUTIME_ID;
> +#endif
> +  if (clock_gettime (cid, ) < 0)
> +[...]

On an elderly system, I ran into that not linking, and thus *all*
libbacktrace testing disappearing:

[...]
{+ztest-ztest.o: In function `test_large':+}
{+[...]/source-gcc/libbacktrace/ztest.c:350: undefined reference to 
`clock_gettime'+}
{+[...]/source-gcc/libbacktrace/ztest.c:368: undefined reference to 
`clock_gettime'+}
{+[...]/source-gcc/libbacktrace/ztest.c:378: undefined reference to 
`clock_gettime'+}
{+[...]/source-gcc/libbacktrace/ztest.c:387: undefined reference to 
`clock_gettime'+}
{+collect2: error: ld returned 1 exit status+}
{+make[3]: *** [ztest] Error 1+}
[...]
[-make[3]: Leaving directory `[...]/build-gcc/libbacktrace'-]
[-make  check-TESTS-]
[-make[3]: Entering directory `[...]/build-gcc/libbacktrace'-]
[-objcopy --only-keep-debug btest btest.debug-]
[-objcopy --strip-debug --add-gnu-debuglink=btest.debug btest dtest-]
[-PASS: backtrace_full noinline-]
[-PASS: backtrace_full inline-]
[-PASS: backtrace_simple noinline-]
[-PASS: backtrace_simple inline-]
[-PASS: backtrace_syminfo variable-]
[-PASS: btest-]
[-PASS: stest-]
[-PASS: backtrace_full alloc stress-]
[-PASS: edtest-]
[-PASS: threaded backtrace_full noinline-]
[-PASS: ttest-]
[-PASS: backtrace_full noinline-]
[-PASS: backtrace_full inline-]
[-PASS: backtrace_simple noinline-]
[-PASS: backtrace_simple inline-]
[-PASS: backtrace_syminfo variable-]
[-PASS: dtest-]
[-==[PID][PID][PID][PID]-]
[-All 5 tests passed-]
[-==[PID][PID][PID][PID]-]
make[3]: Leaving directory `[...]/build-gcc/libbacktrace'
{+make[2]: *** [check-am] Error 2+}
{+make[2]: Target `check' not remade because of errors.+}
make[2]: Leaving directory `[...]/build-gcc/libbacktrace'
{+make[1]: *** [check-libbacktrace] Error 2+}
[...]

Committed to trunk r253344, as obvious:

commit c476d11ef7dbd508067067fbd0b8450d27f1f057
Author: tschwinge 
Date:   Mon Oct 2 11:56:25 2017 +

libbacktrace: Conditionalize test timing on clock_gettime availability

libbacktrace/
PR other/67165
* configure.ac: Check for clock_gettime.
* config.h.in: Regenerate.
* configure: Likewise.
* ztest.c (average_time, test_large): Conditionalize test timing
on clock_gettime availability.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@253344 
138bc75d-0d04-0410-961f-82ee72b054a4
---
 libbacktrace/ChangeLog|  9 +
 libbacktrace/config.h.in  |  3 +++
 libbacktrace/configure| 13 +
 libbacktrace/configure.ac |  3 +++
 libbacktrace/ztest.c  | 12 +++-
 5 files changed, 39 insertions(+), 1 deletion(-)

diff --git libbacktrace/ChangeLog libbacktrace/ChangeLog
index 9597a68..0e4cfd2 100644
--- libbacktrace/ChangeLog
+++ libbacktrace/ChangeLog
@@ -1,3 +1,12 @@
+2017-10-02  Thomas Schwinge  
+
+   PR other/67165
+   * configure.ac: Check for clock_gettime.
+   * config.h.in: Regenerate.
+   * configure: Likewise.
+   * ztest.c (average_time, test_large): Conditionalize test timing
+   on clock_gettime availability.
+
 2017-09-29  Tony Reix  
 
* xcoff.c: Initial support for DWARF debug sections in XCOFF.
diff --git libbacktrace/config.h.in libbacktrace/config.h.in
index a9f70da..c19b6e4 100644
--- libbacktrace/config.h.in
+++ libbacktrace/config.h.in
@@ -9,6 +9,9 @@
 /* Define to 1 if you have the __atomic functions */
 #undef HAVE_ATOMIC_FUNCTIONS
 
+/* Define to 1 if you have the `clock_gettime' function. */
+#undef HAVE_CLOCK_GETTIME
+
 /* Define to 1 if you have the declaration of `strnlen', and to 0 if you
don't. */
 #undef HAVE_DECL_STRNLEN
diff --git libbacktrace/configure libbacktrace/configure
index ece4151..062dc77 100755
--- libbacktrace/configure
+++ libbacktrace/configure
@@ -12747,6 +12747,19 @@ $as_echo "#define HAVE_GETEXECNAME 1" >>confdefs.h
 
 fi
 
+# Check for the clock_gettime function.
+for ac_func in clock_gettime
+do :
+  ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
+if test "x$ac_cv_func_clock_gettime" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_CLOCK_GETTIME 1
+_ACEOF
+
+fi
+done
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -pthread is 
supported" >&5
 $as_echo_n "checking whether -pthread is 

libbacktrace patch committed: Support compressed debug sections

2017-09-28 Thread Ian Lance Taylor
This patch to libbacktrace adds support for compressed debug sections.
Rather than require all users of libbacktrace to link against -lz, I
wrote new code in libbacktrace to inflate a zlib stream.  Because the
code does not have to be as flexible as zlib, and because it is only
used to uncompress from one memory buffer to another and therefore
does not need to provide a streaming interface, and because I wasted a
day speeding it up, it's a few percent faster than zlib (at least as
measured by the simple benchmark in the new ztest.c file).

This fixes PR 67165.

Bootstrapped and ran libbacktrace and Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

2017-09-28  Ian Lance Taylor  

PR other/67165
* elf.c (__builtin_prefetch): Define if not __GNUC__.
(unlikely): Define.
(SHF_UNCOMPRESSED, ELFCOMPRESS_ZLIB): Define.
(b_elf_chdr): Define type.
(enum debug_section): Add ZDEBUG_xxx values.
(debug_section_names): Add names for new sections.
(struct debug_section_info): Add compressed field.
(elf_zlib_failed, elf_zlib_fetch): New static functions.
(HUFFMAN_TABLE_SIZE, HUFFMAN_VALUE_MASK): Define.
(HUFFMAN_BITS_SHIFT, HUFFMAN_BITS_MASK): Define.
(HUFFMAN_SECONDARY_SHIFT): Define.
(ZDEBUG_TABLE_SIZE): Define.
(ZDEBUG_TABLE_CODELEN_OFFSET, ZDEBUG_TABLE_WORK_OFFSET): Define.
(final_next_secondary): New static variable if
BACKTRACE_GENERATE_FIXED_HUFFMAN_TABLE.
(elf_zlib_inflate_table): New static function.
(BACKTRACE_GENERATE_FIXED_HUFFMAN_TABLE): If define, define main
function to produce fixed Huffman table.
(elf_zlib_default_table): New static variable.
(elf_zlib_inflate): New static function.
(elf_zlib_verify_checksum): Likewise.
(elf_zlib_inflate_and_verify): Likewise.
(elf_uncompress_zdebug): Likewise.
(elf_uncompress_chdr): Likewise.
(backtrace_uncompress_zdebug): New extern function.
(elf_add): Look for .zdebug sections and SHF_COMPRESSED debug
sections, and uncompress them.
* internal.h (backtrace_compress_zdebug): Declare.
* ztest.c: New file.
* configure.ac: Check for -lz and check whether the linker
supports --compress-debug-sections.
* Makefile.am (ztest_SOURCES): New variable.
(ztest_CFLAGS, ztest_LDADD): New variables.
(check_PROGRAMS): Add ztest.
(ctestg_SOURCES): New variable.
(ctestg_CFLAGS, ctestg_LDFLAGS, ctestg_LDADD): New variables.
(ctesta_SOURCES): New variable.
(ctesta_CFLAGS, ctesta_LDFLAGS, ctesta_LDADD): New variables.
(check_PROGRAMS): Add ctestg and ctesta.
* configure, config.h.in, Makefile.in: Rebuild.
Index: Makefile.am
===
--- Makefile.am (revision 253270)
+++ Makefile.am (working copy)
@@ -101,6 +101,16 @@ stest_LDADD = libbacktrace.la
 
 check_PROGRAMS += stest
 
+ztest_SOURCES = ztest.c testlib.c
+ztest_CFLAGS = -DSRCDIR=\"$(srcdir)\"
+ztest_LDADD = libbacktrace.la
+
+if HAVE_ZLIB
+ztest_LDADD += -lz
+endif
+
+check_PROGRAMS += ztest
+
 edtest_SOURCES = edtest.c edtest2_build.c testlib.c
 edtest_LDADD = libbacktrace.la
 
@@ -132,6 +142,22 @@ dtest: btest
 
 endif HAVE_OBJCOPY_DEBUGLINK
 
+if HAVE_COMPRESSED_DEBUG
+
+ctestg_SOURCES = btest.c testlib.c
+ctestg_CFLAGS = $(AM_CFLAGS) -g
+ctestg_LDFLAGS = -Wl,--compress-debug-sections=zlib-gnu
+ctestg_LDADD = libbacktrace.la
+
+ctesta_SOURCES = btest.c testlib.c
+ctesta_CFLAGS = $(AM_CFLAGS) -g
+ctesta_LDFLAGS = -Wl,--compress-debug-sections=zlib-gabi
+ctesta_LDADD = libbacktrace.la
+
+check_PROGRAMS += ctestg ctesta
+
+endif
+
 endif NATIVE
 
 # We can't use automake's automatic dependency tracking, because it
Index: configure.ac
===
--- configure.ac(revision 253270)
+++ configure.ac(working copy)
@@ -405,6 +405,23 @@ AC_SUBST(PTHREAD_CFLAGS)
 
 AM_CONDITIONAL(HAVE_PTHREAD, test "$libgo_cv_lib_pthread" = yes)
 
+AC_CHECK_LIB([z], [compress], [])
+if test $ac_cv_lib_z_compress = "yes"; then
+  AC_DEFINE(HAVE_ZLIB, 1, [Define if -lz is available.])
+fi
+AM_CONDITIONAL(HAVE_ZLIB, test "$ac_cv_lib_z_compress" = yes)
+
+dnl Test whether the linker supports the --compress_debug_sections option.
+AC_CACHE_CHECK([whether --compress-debug-sections is supported],
+[libgo_cv_ld_compress],
+[LDFLAGS_hold=$LDFLAGS
+LDFLAGS="$LDFLAGS -Wl,--compress-debug-sections=zlib-gnu"
+AC_LINK_IFELSE([AC_LANG_PROGRAM(,)],
+[libgo_cv_ld_compress=yes],
+[libgo_cv_ld_compress=no])
+LDFLAGS=$LDFLAGS_hold])
+AM_CONDITIONAL(HAVE_COMPRESSED_DEBUG, test "$libgo_cv_ld_compress" = yes)
+
 AC_ARG_VAR(OBJCOPY, [location of objcopy])
 AC_CHECK_PROG(OBJCOPY, objcopy, objcopy,)
 AC_CACHE_CHECK([whether objcopy supports debuglink],
Index: elf.c
===
--- elf.c   (revision 253270)
+++ elf.c   (working copy)
@@ -56,6 +56,13 @@ POSSIBILITY OF SUCH DAMAGE.  */
  #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
 #endif
 
+#ifndef __GNUC__
+#define __builtin_prefetch(p, r, l)
+#define unlikely(x) (x)
+#else
+#define unlikely(x) 

libbacktrace patch committed: Replace lstat and readlink if not available

2017-09-22 Thread Ian Lance Taylor
This patch to libbacktrace provides dummy versions of lstat and
readlink if they are not available on the system.  Bootstrapped and
ran libbacktrace tests on x86_64-pc-linux-gnu both normally and with a
hand-edited config.h.  Committed to mainline.

Ian

2017-09-22  Ian Lance Taylor  

PR sanitizer/77631
* configure.ac: Check for lstat and readlink.
* elf.c (lstat, readlink): Provide dummy versions if real versions
are not available.
* configure, config.h.in: Rebuild.
Index: configure.ac
===
--- configure.ac(revision 253093)
+++ configure.ac(working copy)
@@ -373,6 +373,7 @@ if test "$have_fcntl" = "yes"; then
 fi
 
 AC_CHECK_DECLS(strnlen)
+AC_CHECK_FUNCS(lstat readlink)
 
 # Check for getexecname function.
 if test -n "${with_target_subdir}"; then
Index: elf.c
===
--- elf.c   (revision 253093)
+++ elf.c   (working copy)
@@ -75,6 +75,35 @@ xstrnlen (const char *s, size_t maxlen)
 
 #endif
 
+#ifndef HAVE_LSTAT
+
+/* Dummy version of lstat for systems that don't have it.  */
+
+static int
+xlstat (const char *path ATTRIBUTE_UNUSED, struct stat *st ATTRIBUTE_UNUSED)
+{
+  return -1;
+}
+
+#define lstat xlstat
+
+#endif
+
+#ifndef HAVE_READLINK
+
+/* Dummy version of readlink for systems that don't have it.  */
+
+static ssize_t
+xreadlink (const char *path ATTRIBUTE_UNUSED, char *buf ATTRIBUTE_UNUSED,
+  size_t bufsz ATTRIBUTE_UNUSED)
+{
+  return -1;
+}
+
+#define readlink xreadlink
+
+#endif
+
 #ifndef HAVE_DL_ITERATE_PHDR
 
 /* Dummy version of dl_iterate_phdr for systems that don't have it.  */


libbacktrace patch committed: Fix uninitialized field

2017-09-21 Thread Ian Lance Taylor
I somehow failed to initialize the exe_filename field of phdr_data,
which most likely led to PR 82284.  Bootstrapped and ran libbacktrace
tests for this obvious fix.  Committed to mainline.

Ian


2017-09-21  Ian Lance Taylor  

PR go/82284
* elf.c (backtrace_initialize): Set pd.exe_filename.
Index: elf.c
===
--- elf.c   (revision 253076)
+++ elf.c   (working copy)
@@ -1489,6 +1489,7 @@
   pd.fileline_fn = _fileline_fn;
   pd.found_sym = _sym;
   pd.found_dwarf = _dwarf;
+  pd.exe_filename = filename;
   pd.exe_descriptor = ret < 0 ? descriptor : -1;
 
   dl_iterate_phdr (phdr_callback, (void *) );


libbacktrace patch committed: Fix race on parallel initialization

2017-06-11 Thread Ian Lance Taylor
The code in libbacktrace had a race when doing parallel
initialization: if two threads start to initialize at the same time,
and one completes first, the other, while running in
backtrace_initialize, may see that the structure is initialized and
thus not change *fileline_fn.  The caller will then set
state->fileline_fn to *fileline_fn, but since backtrace_initialize has
not changed it that will be NULL.  The effect is that if the timing is
right the code can then call a NULL function pointer.

This patch fixes the problem by always initializing *fileline_fn in
backtrace_initialize.  It adds a test in ttest.c that does 10
backtraces in parallel with an new state.

To make writing the test easier I copied the test support functions
out of btest.c into testlib.c.  While doing that I eliminated some of
the duplication in edtest.c by making that use testlib.c as well.

Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

Ian
Index: Makefile.am
===
--- Makefile.am (revision 249070)
+++ Makefile.am (working copy)
@@ -89,7 +89,7 @@ TESTS = $(check_PROGRAMS)
 
 if NATIVE
 
-btest_SOURCES = btest.c
+btest_SOURCES = btest.c testlib.c
 btest_CFLAGS = $(AM_CFLAGS) -g -O
 btest_LDADD = libbacktrace.la
 
@@ -100,7 +100,7 @@ stest_LDADD = libbacktrace.la
 
 check_PROGRAMS += stest
 
-edtest_SOURCES = edtest.c edtest2_build.c
+edtest_SOURCES = edtest.c edtest2_build.c testlib.c
 edtest_LDADD = libbacktrace.la
 
 check_PROGRAMS += edtest
@@ -111,6 +111,16 @@ gen_edtest2_build: $(srcdir)/edtest2.c
$(SHELL) $(srcdir)/../move-if-change tmp-edtest2_build.c edtest2_build.c
echo timestamp > $@
 
+if HAVE_PTHREAD
+
+check_PROGRAMS += ttest
+
+ttest_SOURCES = ttest.c testlib.c
+ttest_CFLAGS = -pthread
+ttest_LDADD = libbacktrace.la
+
+endif HAVE_PTHREAD
+
 endif NATIVE
 
 # We can't use automake's automatic dependency tracking, because it
Index: btest.c
===
--- btest.c (revision 249070)
+++ btest.c (working copy)
@@ -43,237 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include "backtrace.h"
 #include "backtrace-supported.h"
 
-/* Portable attribute syntax.  Actually some of these tests probably
-   won't work if the attributes are not recognized.  */
-
-#ifndef GCC_VERSION
-# define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
-#endif
-
-#if (GCC_VERSION < 2007)
-# define __attribute__(x)
-#endif
-
-#ifndef ATTRIBUTE_UNUSED
-# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
-#endif
-
-/* Used to collect backtrace info.  */
-
-struct info
-{
-  char *filename;
-  int lineno;
-  char *function;
-};
-
-/* Passed to backtrace callback function.  */
-
-struct bdata
-{
-  struct info *all;
-  size_t index;
-  size_t max;
-  int failed;
-};
-
-/* Passed to backtrace_simple callback function.  */
-
-struct sdata
-{
-  uintptr_t *addrs;
-  size_t index;
-  size_t max;
-  int failed;
-};
-
-/* Passed to backtrace_syminfo callback function.  */
-
-struct symdata
-{
-  const char *name;
-  uintptr_t val, size;
-  int failed;
-};
-
-/* The backtrace state.  */
-
-static void *state;
-
-/* The number of failures.  */
-
-static int failures;
-
-/* Return the base name in a path.  */
-
-static const char *
-base (const char *p)
-{
-  const char *last;
-  const char *s;
-
-  last = NULL;
-  for (s = p; *s != '\0'; ++s)
-{
-  if (IS_DIR_SEPARATOR (*s))
-   last = s + 1;
-}
-  return last != NULL ? last : p;
-}
-
-/* Check an entry in a struct info array.  */
-
-static void
-check (const char *name, int index, const struct info *all, int want_lineno,
-   const char *want_function, int *failed)
-{
-  if (*failed)
-return;
-  if (all[index].filename == NULL || all[index].function == NULL)
-{
-  fprintf (stderr, "%s: [%d]: missing file name or function name\n",
-  name, index);
-  *failed = 1;
-  return;
-}
-  if (strcmp (base (all[index].filename), "btest.c") != 0)
-{
-  fprintf (stderr, "%s: [%d]: got %s expected test.c\n", name, index,
-  all[index].filename);
-  *failed = 1;
-}
-  if (all[index].lineno != want_lineno)
-{
-  fprintf (stderr, "%s: [%d]: got %d expected %d\n", name, index,
-  all[index].lineno, want_lineno);
-  *failed = 1;
-}
-  if (strcmp (all[index].function, want_function) != 0)
-{
-  fprintf (stderr, "%s: [%d]: got %s expected %s\n", name, index,
-  all[index].function, want_function);
-  *failed = 1;
-}
-}
-
-/* The backtrace callback function.  */
-
-static int
-callback_one (void *vdata, uintptr_t pc ATTRIBUTE_UNUSED,
- const char *filename, int lineno, const char *function)
-{
-  struct bdata *data = (struct bdata *) vdata;
-  struct info *p;
-
-  if (data->index >= data->max)
-{
-  fprintf (stderr, "callback_one: callback called too many times\n");
-  data->failed = 1;
-  

libbacktrace patch committed: Update dependencies

2015-09-11 Thread Ian Lance Taylor
Although libbacktrace uses automake, it can't use automatic dependency
tracking, because it breaks when using bootstrap-lean (PR 54732).  The
dependencies for sort.lo and stest.lo were never added to the list.
Also, the dependencies for backtrace.lo were not updated for my recent
change to that file.  This patch fixes the problem.  Committed to
mainline.

Ian

2015-09-11  Ian Lance Taylor  

* Makefile.am (backtrace.lo): Depend on internal.h.
(sort.lo, stest.lo): Add explicit dependencies.
* Makefile.in: Rebuild.
Index: Makefile.am
===
--- Makefile.am (revision 227673)
+++ Makefile.am (working copy)
@@ -116,7 +116,7 @@ endif NATIVE
 
 INCDIR = $(top_srcdir)/../include
 alloc.lo: config.h backtrace.h internal.h
-backtrace.lo: config.h backtrace.h
+backtrace.lo: config.h backtrace.h internal.h
 btest.lo: (INCDIR)/filenames.h backtrace.h backtrace-supported.h
 dwarf.lo: config.h $(INCDIR)/dwarf2.h $(INCDIR)/dwarf2.def \
$(INCDIR)/filenames.h backtrace.h internal.h
@@ -130,5 +130,7 @@ posix.lo: config.h backtrace.h internal.
 print.lo: config.h backtrace.h internal.h
 read.lo: config.h backtrace.h internal.h
 simple.lo: config.h backtrace.h internal.h
+sort.lo: config.h backtrace.h internal.h
+stest.lo: config.h backtrace.h internal.h
 state.lo: config.h backtrace.h backtrace-supported.h internal.h
 unknown.lo: config.h backtrace.h internal.h


libbacktrace patch committed: fix test for mmap failure

2015-09-08 Thread Ian Lance Taylor
PR 67457 points out a crash in libbacktrace when there is no memory
available.  This is because the code testing the mmap result for
failure is broken.  This patch fixes it.  Bootstrapped and ran
libbacktrace tests.  Committed to mainline.

Ian


2015-09-08  Ian Lance Taylor  

PR other/67457
* mmap.c (backtrace_alloc): Correct test for mmap failure.
Index: mmap.c
===
--- mmap.c  (revision 227528)
+++ mmap.c  (working copy)
@@ -139,7 +139,7 @@ backtrace_alloc (struct backtrace_state
   asksize = (size + pagesize - 1) & ~ (pagesize - 1);
   page = mmap (NULL, asksize, PROT_READ | PROT_WRITE,
   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-  if (page == NULL)
+  if (page == MAP_FAILED)
error_callback (data, "mmap", errno);
   else
{


Re: libbacktrace patch committed: Graceful fallback if out of memory

2015-09-08 Thread Hans-Peter Nilsson
> From: Ian Lance Taylor 
> Date: Tue, 8 Sep 2015 18:46:21 +0200


> PR other/67457
> * backtrace.c: #include "internal.h".
> (struct backtrace_data): Add can_alloc field.
> (unwind): If can_alloc is false, don't try to get file/line
> information.
> (backtrace_full): Set can_alloc field in bdata.
> * alloc.c (backtrace_alloc): Don't call error_callback if it is
> NULL.
> * mmap.c (backtrace_alloc): Likewise.
> * internal.h: Update comments for backtrace_alloc and
> backtrace_free.

> Index: backtrace.c
> ===
> --- backtrace.c   (revision 227528)
> +++ backtrace.c   (working copy)
> @@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.  */
>  
>  #include "unwind.h"
>  #include "backtrace.h"
> +#include "internal.h"
>  
>  /* The main backtrace_full routine.  */
>  


I don't know about your environment, but for me (cross from
x86_64-linux to cris-elf) that causes a:

/bin/sh ./libtool --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. 
-I/tmp/hpautotest-gcc0/gcc/libbacktrace  -I 
/tmp/hpautotest-gcc0/gcc/libbacktrace/../include -I 
/tmp/hpautotest-gcc0/gcc/libbacktrace/../libgcc -I ../libgcc  -funwind-tables 
-frandom-seed=backtrace.lo -W -Wall -Wwrite-strings -Wstrict-prototypes 
-Wmissing-prototypes -Wold-style-definition -Wmissing-format-attribute 
-Wcast-qual  -g -O2 -c -o backtrace.lo 
/tmp/hpautotest-gcc0/gcc/libbacktrace/backtrace.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. 
-I/tmp/hpautotest-gcc0/gcc/libbacktrace -I 
/tmp/hpautotest-gcc0/gcc/libbacktrace/../include -I 
/tmp/hpautotest-gcc0/gcc/libbacktrace/../libgcc -I ../libgcc -funwind-tables 
-frandom-seed=backtrace.lo -W -Wall -Wwrite-strings -Wstrict-prototypes 
-Wmissing-prototypes -Wold-style-definition -Wmissing-format-attribute 
-Wcast-qual -g -O2 -c /tmp/hpautotest-gcc0/gcc/libbacktrace/backtrace.c  -fPIC 
-DPIC -o .libs/backtrace.o
In file included from /tmp/hpautotest-gcc0/gcc/libbacktrace/backtrace.c:37:
/tmp/hpautotest-gcc0/gcc/libbacktrace/internal.h:182: error: expected 
declaration specifiers or '...' before 'off_t'
make[3]: *** [backtrace.lo] Error 1
make[3]: Leaving directory `/tmp/hpautotest-gcc0/cris-elf/gccobj/libbacktrace'
make[2]: *** [all] Error 2
make[2]: Leaving directory `/tmp/hpautotest-gcc0/cris-elf/gccobj/libbacktrace'
make[1]: *** [all-libbacktrace] Error 2
make[1]: Leaving directory `/tmp/hpautotest-gcc0/cris-elf/gccobj'
make: *** [all] Error 2

I've committed the following as obvious, following the pattern
of the other files including internal.h, after observing
all-libbacktrace (i.e. built for the host) complete.

libbacktrace:
* backtrace.c: #include .

Index: backtrace.c
===
--- backtrace.c (revision 227567)
+++ backtrace.c (working copy)
@@ -32,6 +32,8 @@ POSSIBILITY OF SUCH DAMAGE.  */
 
 #include "config.h"
 
+#include 
+
 #include "unwind.h"
 #include "backtrace.h"
 #include "internal.h"

brgds, H-P


Re: libbacktrace patch committed: Graceful fallback if out of memory

2015-09-08 Thread Ian Lance Taylor
On Tue, Sep 8, 2015 at 5:00 PM, Hans-Peter Nilsson
 wrote:
>
> I've committed the following as obvious, following the pattern
> of the other files including internal.h, after observing
> all-libbacktrace (i.e. built for the host) complete.
>
> libbacktrace:
> * backtrace.c: #include .

Thanks.

Ian


libbacktrace patch committed: Graceful fallback if out of memory

2015-09-08 Thread Ian Lance Taylor
I've committed this libbacktrace patch to mainline to do a graceful
fallback if no memory can be allocated.  In that case we print out the
PC addresses without trying to resolve file/line information.  This is
imperfect but better than the earlier behaviour of producing a series
of error messages.  Tested with libbacktrace and Go testsuites.
Committed to mainline.

Ian

2015-09-08  Ian Lance Taylor  

PR other/67457
* backtrace.c: #include "internal.h".
(struct backtrace_data): Add can_alloc field.
(unwind): If can_alloc is false, don't try to get file/line
information.
(backtrace_full): Set can_alloc field in bdata.
* alloc.c (backtrace_alloc): Don't call error_callback if it is
NULL.
* mmap.c (backtrace_alloc): Likewise.
* internal.h: Update comments for backtrace_alloc and
backtrace_free.
Index: alloc.c
===
--- alloc.c (revision 227528)
+++ alloc.c (working copy)
@@ -44,7 +44,8 @@ POSSIBILITY OF SUCH DAMAGE.  */
backtrace functions may not be safely invoked from a signal
handler.  */
 
-/* Allocate memory like malloc.  */
+/* Allocate memory like malloc.  If ERROR_CALLBACK is NULL, don't
+   report an error.  */
 
 void *
 backtrace_alloc (struct backtrace_state *state ATTRIBUTE_UNUSED,
@@ -55,7 +56,10 @@ backtrace_alloc (struct backtrace_state
 
   ret = malloc (size);
   if (ret == NULL)
-error_callback (data, "malloc", errno);
+{
+  if (error_callback)
+   error_callback (data, "malloc", errno);
+}
   return ret;
 }
 
Index: backtrace.c
===
--- backtrace.c (revision 227528)
+++ backtrace.c (working copy)
@@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.  */
 
 #include "unwind.h"
 #include "backtrace.h"
+#include "internal.h"
 
 /* The main backtrace_full routine.  */
 
@@ -53,6 +54,8 @@ struct backtrace_data
   void *data;
   /* Value to return from backtrace_full.  */
   int ret;
+  /* Whether there is any memory available.  */
+  int can_alloc;
 };
 
 /* Unwind library callback routine.  This is passed to
@@ -80,8 +83,11 @@ unwind (struct _Unwind_Context *context,
   if (!ip_before_insn)
 --pc;
 
-  bdata->ret = backtrace_pcinfo (bdata->state, pc, bdata->callback,
-bdata->error_callback, bdata->data);
+  if (!bdata->can_alloc)
+bdata->ret = bdata->callback (bdata->data, pc, NULL, 0, NULL);
+  else
+bdata->ret = backtrace_pcinfo (bdata->state, pc, bdata->callback,
+  bdata->error_callback, bdata->data);
   if (bdata->ret != 0)
 return _URC_END_OF_STACK;
 
@@ -96,6 +102,7 @@ backtrace_full (struct backtrace_state *
backtrace_error_callback error_callback, void *data)
 {
   struct backtrace_data bdata;
+  void *p;
 
   bdata.skip = skip + 1;
   bdata.state = state;
@@ -103,6 +110,18 @@ backtrace_full (struct backtrace_state *
   bdata.error_callback = error_callback;
   bdata.data = data;
   bdata.ret = 0;
+
+  /* If we can't allocate any memory at all, don't try to produce
+ file/line information.  */
+  p = backtrace_alloc (state, 4096, NULL, NULL);
+  if (p == NULL)
+bdata.can_alloc = 0;
+  else
+{
+  backtrace_free (state, p, 4096, NULL, NULL);
+  bdata.can_alloc = 1;
+}
+
   _Unwind_Backtrace (unwind, );
   return bdata.ret;
 }
Index: internal.h
===
--- internal.h  (revision 227528)
+++ internal.h  (working copy)
@@ -201,13 +201,15 @@ extern int backtrace_close (int descript
 extern void backtrace_qsort (void *base, size_t count, size_t size,
 int (*compar) (const void *, const void *));
 
-/* Allocate memory.  This is like malloc.  */
+/* Allocate memory.  This is like malloc.  If ERROR_CALLBACK is NULL,
+   this does not report an error, it just returns NULL.  */
 
 extern void *backtrace_alloc (struct backtrace_state *state, size_t size,
  backtrace_error_callback error_callback,
  void *data) ATTRIBUTE_MALLOC;
 
-/* Free memory allocated by backtrace_alloc.  */
+/* Free memory allocated by backtrace_alloc.  If ERROR_CALLBACK is
+   NULL, this does not report an error.  */
 
 extern void backtrace_free (struct backtrace_state *state, void *mem,
size_t size,
Index: mmap.c
===
--- mmap.c  (revision 227529)
+++ mmap.c  (working copy)
@@ -77,7 +77,8 @@ backtrace_free_locked (struct backtrace_
 }
 }
 
-/* Allocate memory like malloc.  */
+/* Allocate memory like malloc.  If ERROR_CALLBACK is NULL, don't
+   report an error.  */
 
 void *
 backtrace_alloc (struct backtrace_state *state,
@@ -140,7 +141,10 @@ backtrace_alloc (struct backtrace_state
   page = mmap (NULL, asksize, PROT_READ | PROT_WRITE,
   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

libbacktrace patch committed: Fix load_pointer if no atomic or sync functions

2014-10-23 Thread Ian Taylor
This patch to libbacktrace fixes the type returned by the backup
definition of backtrace_atomic_load_pointer for the case where
libbacktrace is compiled with neither the atomic nor the sync
functions available.  This case does not arise in general but could
arise from other uses of the library, or when building stage 1 with a
very old host compiler.  Bootstrapped and ran libbacktrace tests on
x86_64-unknown-linux-gnu, which proves nothing, really.

Ian


2014-10-23  Ian Lance Taylor  i...@google.com

* internal.h (backtrace_atomic_load_pointer) [no atomic or sync]:
Fix to return void *.
Index: internal.h
===
--- internal.h  (revision 216522)
+++ internal.h  (working copy)
@@ -99,7 +99,7 @@ extern void backtrace_atomic_store_int (
 /* We have neither the sync nor the atomic functions.  These will
never be called.  */
 
-#define backtrace_atomic_load_pointer(p) (abort(), 0)
+#define backtrace_atomic_load_pointer(p) (abort(), (void *) NULL)
 #define backtrace_atomic_load_int(p) (abort(), 0)
 #define backtrace_atomic_store_pointer(p, v) abort()
 #define backtrace_atomic_store_size_t(p, v) abort()


libbacktrace patch committed: Fixes for large binaries

2014-05-08 Thread Ian Lance Taylor
While testing on a large Google binary, I noticed that libbacktrace is
allocating an inordinate amount of memory.  The binary winds up with
377,944 entries in the unit_addrs vector.  Each entry is 24 bytes, so
this is 9,070,656 bytes, which is not too terrible.  Unfortunately, for
some reason I thought that when a libbacktrace vector is larger than a
page the code should only allocate one additional page at a time.  This
vector requires 2215 4096-byte pages.  Growing the vector one page at a
time allocates a total of something like (2215 * 2214) / 2 pages, which
turns out to be nearly 1.5G.  Allocating 1.5G to represent a vector of
size 9M is not desirable.

It's true that when the vector grows, the old memory can be reused.  But
there is nothing in libbacktrace that is going to reuse that much
memory.  And even worse, there was a bug in the vector_grow routine that
caused it to fail to correctly report the size of the old vector, so the
memory had no chance of being reused anyhow.

This patch fixes vector growth to double the number of pages requested
each time.  It fixes vector growth to record the correct size of the old
vector being freed.

The patch also adds some code to simply munmap large blocks of allocated
memory.  It's unlikely in practice that libbacktrace will ever be able
to reuse a large block, so it's probably better to hand the memory back
rather than hold onto it for no purpose.

Bootstrapped and tested on x86_64-unknown-linux-gnu.  Committed to 4.9
branch and mainline.

Ian


2014-05-08  Ian Lance Taylor  i...@google.com

* mmap.c (backtrace_free): If freeing a large aligned block of
memory, call munmap rather than holding onto it.
(backtrace_vector_grow): When growing a vector, double the number
of pages requested.  When releasing the old version of a grown
vector, pass the correct size to backtrace_free.


Index: ChangeLog
===
--- ChangeLog	(revision 210248)
+++ ChangeLog	(working copy)
@@ -1,3 +1,11 @@
+2014-05-08  Ian Lance Taylor  i...@google.com
+
+	* mmap.c (backtrace_free): If freeing a large aligned block of
+	memory, call munmap rather than holding onto it.
+	(backtrace_vector_grow): When growing a vector, double the number
+	of pages requested.  When releasing the old version of a grown
+	vector, pass the correct size to backtrace_free.
+
 2014-03-07  Ian Lance Taylor  i...@google.com
 
 	* sort.c (backtrace_qsort): Use middle element as pivot.
Index: mmap.c
===
--- mmap.c	(revision 210248)
+++ mmap.c	(working copy)
@@ -164,6 +164,26 @@ backtrace_free (struct backtrace_state *
 {
   int locked;
 
+  /* If we are freeing a large aligned block, just release it back to
+ the system.  This case arises when growing a vector for a large
+ binary with lots of debug info.  Calling munmap here may cause us
+ to call mmap again if there is also a large shared library; we
+ just live with that.  */
+  if (size = 16 * 4096)
+{
+  size_t pagesize;
+
+  pagesize = getpagesize ();
+  if (((uintptr_t) addr  (pagesize - 1)) == 0
+	   (size  (pagesize - 1)) == 0)
+	{
+	  /* If munmap fails for some reason, just add the block to
+	 the freelist.  */
+	  if (munmap (addr, size) == 0)
+	return;
+	}
+}
+
   /* If we can acquire the lock, add the new space to the free list.
  If we can't acquire the lock, just leak the memory.
  __sync_lock_test_and_set returns the old state of the lock, so we
@@ -209,14 +229,18 @@ backtrace_vector_grow (struct backtrace_
 	alc = pagesize;
 	}
   else
-	alc = (alc + pagesize - 1)  ~ (pagesize - 1);
+	{
+	  alc *= 2;
+	  alc = (alc + pagesize - 1)  ~ (pagesize - 1);
+	}
   base = backtrace_alloc (state, alc, error_callback, data);
   if (base == NULL)
 	return NULL;
   if (vec-base != NULL)
 	{
 	  memcpy (base, vec-base, vec-size);
-	  backtrace_free (state, vec-base, vec-alc, error_callback, data);
+	  backtrace_free (state, vec-base, vec-size + vec-alc,
+			  error_callback, data);
 	}
   vec-base = base;
   vec-alc = alc - vec-size;


libbacktrace patch committed: Speed up sort

2014-03-07 Thread Ian Lance Taylor
The new libbacktrace sort routine has, no doubt, many flaws, but one is
quite significant.  The backtrace data tends to be roughly sorted in
practice (though unfortunately not perfectly sorted).  By pivoting on
the first element in the array, the sort routine was tending to maximize
the number of recursive steps.  This patch uses the middle element array
as the pivot.  This reduced the backtrace time on a large executable by
two orders of magnitude.

Bootstrapped and ran Go and sanitizer testsuites on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


2014-03-07  Ian Lance Taylor  i...@google.com

* sort.c (backtrace_qsort): Use middle element as pivot.


Index: sort.c
===
--- sort.c	(revision 208402)
+++ sort.c	(working copy)
@@ -69,6 +69,12 @@ backtrace_qsort (void *basearg, size_t c
   if (count  2)
 return;
 
+  /* The symbol table and DWARF tables, which is all we use this
+ routine for, tend to be roughly sorted.  Pick the middle element
+ in the array as our pivot point, so that we are more likely to
+ cut the array in half for each recursion step.  */
+  swap (base, base + (count / 2) * size, size);
+
   mid = 0;
   for (i = 1; i  count; i++)
 {


Re: libbacktrace patch committed (Was: Re: [jit] Update TODO.rst)

2013-10-18 Thread David Malcolm
On Thu, 2013-10-17 at 21:28 -0700, Ian Lance Taylor wrote:
 On Thu, Oct 17, 2013 at 8:54 PM, David Malcolm dmalc...@redhat.com wrote:
 
  +* segfault seen in libbacktrace, when an ICE occurs
 
 That reminded me to commit this libbacktrace patch I worked up a
 couple of weeks ago.  Previously if some debug section was missing,
 the code could compute the wrong min_offset.  The missing section
 would have a zero offset, so min_offset would be set to zero, and
 would then be set to the offset of the next section, even though that
 one might not be the minimum.  That could lead to a segfault in some
 cases, though I don't know if that is the issue that David is seeing.

Thanks - your patch has fixed the issue I was seeing, and I now reliably
get backtraces when an ICE happens within libgccjit.so.

Now to try to fix things so that ICEs can't happen...

Dave



  1   2   >