Re: [PATCH 5/4] libbacktrace: improve getting debug information for loaded dlls

2024-05-03 Thread Ian Lance Taylor via Gcc
On Thu, May 2, 2024 at 12:23 PM Björn Schäpers  wrote:
>
> Am 28.04.2024 um 20:16 schrieb Ian Lance Taylor:
> >
> > Which of your other patches are still relevant?  Thanks.
> >
> only this one.

Thanks.  Committed.

Ian


[gcc r15-140] libbacktrace: add DLLS as they are loaded

2024-05-03 Thread Ian Lance Taylor via Gcc-cvs
https://gcc.gnu.org/g:b69dac54ef769a33bcdca6de243c1b08e05c7881

commit r15-140-gb69dac54ef769a33bcdca6de243c1b08e05c7881
Author: Ian Lance Taylor 
Date:   Fri May 3 15:23:23 2024 -0700

libbacktrace: add DLLS as they are loaded

Patch from Björn Schäpers.

* pecoff.c (struct dll_notification_data): Define.
(LDR_DLL_NOTIFICATION): New typedef.
(LDR_REGISTER_FUNCTION): New typedef.
(struct dll_notification_context): Define.
(dll_notification): New static function.
(backtrace_initialize): Register DLL notification.

Diff:
---
 libbacktrace/pecoff.c | 106 ++
 1 file changed, 106 insertions(+)

diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c
index 4f267841178..bbb59e26d7a 100644
--- a/libbacktrace/pecoff.c
+++ b/libbacktrace/pecoff.c
@@ -61,6 +61,34 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #undef Module32Next
 #endif
 #endif
+
+#if defined(_ARM_)
+#define NTAPI
+#else
+#define NTAPI __stdcall
+#endif
+
+/* This is a simplified (but binary compatible) version of what Microsoft
+   defines in their documentation. */
+struct dll_notification_data
+{
+  ULONG reserved;
+  /* The name as UNICODE_STRING struct. */
+  PVOID full_dll_name;
+  PVOID base_dll_name;
+  PVOID dll_base;
+  ULONG size_of_image;
+};
+
+#define LDR_DLL_NOTIFICATION_REASON_LOADED 1
+
+typedef LONG NTSTATUS;
+typedef VOID CALLBACK (*LDR_DLL_NOTIFICATION)(ULONG,
+ struct dll_notification_data*,
+ PVOID);
+typedef NTSTATUS NTAPI (*LDR_REGISTER_FUNCTION)(ULONG,
+   LDR_DLL_NOTIFICATION, PVOID,
+   PVOID*);
 #endif
 
 /* Coff file header.  */
@@ -911,6 +939,53 @@ coff_add (struct backtrace_state *state, int descriptor,
   return 0;
 }
 
+#ifdef HAVE_WINDOWS_H
+struct dll_notification_context
+{
+  struct backtrace_state *state;
+  backtrace_error_callback error_callback;
+  void *data;
+};
+
+static VOID CALLBACK
+dll_notification (ULONG reason,
+ struct dll_notification_data *notification_data,
+ PVOID context)
+{
+  char module_name[MAX_PATH];
+  int descriptor;
+  struct dll_notification_context* dll_context =
+(struct dll_notification_context*) context;
+  struct backtrace_state *state = dll_context->state;
+  void *data = dll_context->data;
+  backtrace_error_callback error_callback = dll_context->data;
+  fileline fileline;
+  int found_sym;
+  int found_dwarf;
+  HMODULE module_handle;
+
+  if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
+return;
+
+  if (!GetModuleHandleExW ((GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
+   | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT),
+  (wchar_t*) notification_data->dll_base,
+  _handle))
+return;
+
+  if (!GetModuleFileNameA ((HMODULE) module_handle, module_name, MAX_PATH - 1))
+return;
+
+  descriptor = backtrace_open (module_name, error_callback, data, NULL);
+
+  if (descriptor < 0)
+return;
+
+  coff_add (state, descriptor, error_callback, data, , _sym,
+   _dwarf, (uintptr_t) module_handle);
+}
+#endif /* defined(HAVE_WINDOWS_H) */
+
 /* Initialize the backtrace data we need from an ELF executable.  At
the ELF level, all we need to do is find the debug info
sections.  */
@@ -933,6 +1008,8 @@ backtrace_initialize (struct backtrace_state *state,
 #endif
 
 #ifdef HAVE_WINDOWS_H
+  HMODULE nt_dll_handle;
+
   module_handle = (uintptr_t) GetModuleHandle (NULL);
 #endif
 
@@ -980,6 +1057,35 @@ backtrace_initialize (struct backtrace_state *state,
 }
 #endif
 
+#ifdef HAVE_WINDOWS_H
+  nt_dll_handle = GetModuleHandleW (L"ntdll.dll");
+  if (nt_dll_handle)
+{
+  LDR_REGISTER_FUNCTION register_func;
+  const char register_name[] = "LdrRegisterDllNotification";
+  register_func = (void*) GetProcAddress (nt_dll_handle,
+ register_name);
+
+  if (register_func)
+   {
+ PVOID cookie;
+ struct dll_notification_context *context
+   = backtrace_alloc (state,
+  sizeof (struct dll_notification_context),
+  error_callback, data);
+
+ if (context)
+   {
+ context->state = state;
+ context->data = data;
+ context->error_callback = error_callback;
+
+ register_func (0, _notification, context, );
+   }
+   }
+}
+#endif /* defined(HAVE_WINDOWS_H) */
+
   if (!state->threaded)
 {
   if (found_sym)


Re: Updated Sourceware infrastructure plans

2024-05-02 Thread Ian Lance Taylor via Gcc
On Wed, May 1, 2024 at 11:48 PM Richard Biener
 wrote:
>
> We'd only know for sure if we try.  But then I'm almost 100% sure that
> having to click in a GUI is slower than 'nrOK^X' in the text-mode mail UA
> I am using for "quick" patch review.  It might be comparable to the
> review parts I do in the gmail UI or when I have to download attachments
> and cut parts into the reply.  It might be also more convenient
> for "queued" for review patches which just end up in New state in either
> inbox.

Gerritt does not require clicking in a GUI, though that is of course
the more widely used option.  Patches can be approved from the command
line.


> But then would using gitlab or any similar service enforce the use of
> pull requests / forks for each change done or can I just continue to
> post patches and push them from the command-line for changes I
> can approve myself?

Gerritt permits submitting patches from the command line for people
who can self-approve.


> Btw, for any forge like tool I'd even consider there'd be the requirement
> that _all_ functionality is also accessible via a documented (stable) API,
> aka there's command-line tooling available or at least possible to write.

True of Gerritt.

Ian


[gcc r15-53] runtime: dump registers on Solaris

2024-04-29 Thread Ian Lance Taylor via Gcc-cvs
https://gcc.gnu.org/g:a05efc8bf5ed329ea7d9b1740c326bdc6b04e37a

commit r15-53-ga05efc8bf5ed329ea7d9b1740c326bdc6b04e37a
Author: Ian Lance Taylor 
Date:   Sun Apr 28 13:30:39 2024 -0700

runtime: dump registers on Solaris

Patch by Rainer Orth .

Fixes PR go/106813

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/581724

Diff:
---
 gcc/go/gofrontend/MERGE   |  2 +-
 libgo/runtime/go-signal.c | 63 ---
 2 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 8a2810d5b2d..9a4b402573a 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-1f0c8364cd35026a647aa4e66ee4d8563c8a5d27
+60f985a7852632834936b4b859aa75d9df88f038
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c
index aa1b6305ad0..c48c8ee58e3 100644
--- a/libgo/runtime/go-signal.c
+++ b/libgo/runtime/go-signal.c
@@ -216,6 +216,10 @@ getSiginfoCode(siginfo_t *info)
return (uintptr)(info->si_code);
 }
 
+#if defined(__sparc__) && defined(__arch64__) && defined(__linux__)
+  #define gregs mc_gregs
+#endif
+
 struct getSiginfoRet {
uintptr sigaddr;
uintptr sigpc;
@@ -242,9 +246,9 @@ getSiginfo(siginfo_t *info, void *context 
__attribute__((unused)))
// Use unportable code to pull it from context, and if that fails
// try a stack backtrace across the signal handler.
 
-#if defined(__x86_64__) && defined(__linux__)
+#if defined(__x86_64__) && (defined(__linux__) || (defined(__sun__) && 
defined(__svr4__)))
ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.gregs[REG_RIP];
-#elif defined(__i386__) && defined(__linux__)
+#elif defined(__i386__) && (defined(__linux__) || (defined(__sun__) && 
defined(__svr4__)))
ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.gregs[REG_EIP];
 #elif defined(__alpha__) && defined(__linux__)
ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.sc_pc;
@@ -263,6 +267,9 @@ getSiginfo(siginfo_t *info, void *context 
__attribute__((unused)))
 #elif defined(__NetBSD__)
ret.sigpc = _UC_MACHINE_PC(((ucontext_t*)(context)));
 #endif
+#if defined(__sparc__) && (defined(__linux__) || (defined(__sun__) && 
defined(__svr4__)))
+   ret.sigpc = ((ucontext_t*)(context))->uc_mcontext.gregs[REG_PC];
+#endif
 
if (ret.sigpc == 0) {
// Skip getSiginfo/sighandler/sigtrampgo/sigtramp/handler.
@@ -285,7 +292,7 @@ void dumpregs(siginfo_t *, void *)
 void
 dumpregs(siginfo_t *info __attribute__((unused)), void *context 
__attribute__((unused)))
 {
-#if defined(__x86_64__) && defined(__linux__)
+#if defined(__x86_64__) && (defined(__linux__) || (defined(__sun__) && 
defined(__svr4__)))
{
mcontext_t *m = &((ucontext_t*)(context))->uc_mcontext;
 
@@ -306,12 +313,22 @@ dumpregs(siginfo_t *info __attribute__((unused)), void 
*context __attribute__((u
runtime_printf("r14%X\n", m->gregs[REG_R14]);
runtime_printf("r15%X\n", m->gregs[REG_R15]);
runtime_printf("rip%X\n", m->gregs[REG_RIP]);
+#if defined(REG_EFL)
runtime_printf("rflags %X\n", m->gregs[REG_EFL]);
+#elif defined(REG_RFL)
+   runtime_printf("rflags %X\n", m->gregs[REG_RFL]);
+#endif
+#if defined(REG_CSGSFS)
runtime_printf("cs %X\n", m->gregs[REG_CSGSFS] & 0x);
runtime_printf("fs %X\n", (m->gregs[REG_CSGSFS] >> 16) & 
0x);
runtime_printf("gs %X\n", (m->gregs[REG_CSGSFS] >> 32) & 
0x);
+#elif defined(REG_CS) && defined(REG_FS) && defined(REG_GS)
+   runtime_printf("cs %X\n", m->gregs[REG_CS]);
+   runtime_printf("fs %X\n", m->gregs[REG_FS]);
+   runtime_printf("gs %X\n", m->gregs[REG_GS]);
+#endif
  }
-#elif defined(__i386__) && defined(__linux__)
+#elif defined(__i386__) && (defined(__linux__) || (defined(__sun__) && 
defined(__svr4__)))
{
mcontext_t *m = &((ucontext_t*)(context))->uc_mcontext;
 
@@ -423,5 +440,43 @@ dumpregs(siginfo_t *info __attribute__((unused)), void 
*context __attribute__((u
runtime_printf("pc %X\n", m->pc);
runtime_printf("pstate %X\n", m->pstate);
  }
+#elif defined(__sparc__) && (defined(__linux__) || (defined(__sun__) && 
defined(__svr4__)))
+   {
+   mcontext_t *m = &((ucontext_t*)(context))->uc_mcontext;
+
+#ifdef __sparcv9
+  #define REG_FMT "%X"
+#else
+  #define REG_FMT "%x"
+#endif
+
+#ifdef REG_CCR
+   runtime_printf("ccr  " REG_FMT "\n", m->gregs[REG_CCR]);
+#else
+   runtime_printf("psr  " REG_FMT "\n", m->gregs[REG_PSR]);
+#endif
+   runtime_printf("pc   " REG_FMT "\n", m->gregs[REG_PC]);
+   

[gcc r15-52] runtime: use

2024-04-29 Thread Ian Lance Taylor via Gcc-cvs
https://gcc.gnu.org/g:678dc5e85053f1a1ca76997eec95ba8823bb6830

commit r15-52-g678dc5e85053f1a1ca76997eec95ba8823bb6830
Author: Ian Lance Taylor 
Date:   Sun Apr 28 09:57:35 2024 -0700

runtime: use 

 has been available since C99. Use it rather than defining
our own boolean type and values.

Fixes https://gcc.gnu.org/PR114875

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/582275

Diff:
---
 gcc/go/gofrontend/MERGE | 2 +-
 libgo/runtime/runtime.h | 7 +--
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 50d430d5034..8a2810d5b2d 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-98e92493db2ab7857a5934a950a830fc1f95a4e5
+1f0c8364cd35026a647aa4e66ee4d8563c8a5d27
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h
index 699770d53ad..da31e11bb77 100644
--- a/libgo/runtime/runtime.h
+++ b/libgo/runtime/runtime.h
@@ -7,6 +7,7 @@
 #include "go-assert.h"
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -51,7 +52,6 @@ typedef uintptr   uintreg;
 
 /* Defined types.  */
 
-typedef_Bool   bool;
 typedefuint8   byte;
 typedefstruct  g   G;
 typedefstruct  mutex   Lock;
@@ -114,11 +114,6 @@ extern M*  runtime_m(void);
 extern G*  runtime_g(void)
   __asm__(GOSYM_PREFIX "runtime.getg");
 
-enum
-{
-   true= 1,
-   false   = 0,
-};
 enum
 {
PtrSize = sizeof(void*),


Re: [PATCH 5/4] libbacktrace: improve getting debug information for loaded dlls

2024-04-28 Thread Ian Lance Taylor via Gcc
On Thu, Apr 25, 2024 at 1:15 PM Björn Schäpers  wrote:
>
> > Attached is the combined version of the two patches, only implementing the
> > variant with the tlhelp32 API.
> >
> > Tested on x86 and x86_64 windows.
> >
> > Kind regards,
> > Björn.
>
> A friendly ping.

Thanks.  Committed as follows.

Which of your other patches are still relevant?  Thanks.

Ian
942a9cf2a958113d2ab46f5b015c36e569abedcf
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 3e0075a2b79..59e9c415db8 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -380,6 +380,10 @@ if test "$have_loadquery" = "yes"; then
 fi
 
 AC_CHECK_HEADERS(windows.h)
+AC_CHECK_HEADERS(tlhelp32.h, [], [],
+[#ifdef HAVE_WINDOWS_H
+#  include 
+#endif])
 
 # Check for the fcntl function.
 if test -n "${with_target_subdir}"; then
diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c
index 9e437d810c7..4f267841178 100644
--- a/libbacktrace/pecoff.c
+++ b/libbacktrace/pecoff.c
@@ -49,6 +49,18 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #endif
 
 #include 
+
+#ifdef HAVE_TLHELP32_H
+#include 
+
+#ifdef UNICODE
+/* If UNICODE is defined, all the symbols are replaced by a macro to use the
+   wide variant. But we need the ansi variant, so undef the macros. */
+#undef MODULEENTRY32
+#undef Module32First
+#undef Module32Next
+#endif
+#endif
 #endif
 
 /* Coff file header.  */
@@ -592,7 +604,8 @@ coff_syminfo (struct backtrace_state *state, uintptr_t addr,
 static int
 coff_add (struct backtrace_state *state, int descriptor,
  backtrace_error_callback error_callback, void *data,
- fileline *fileline_fn, int *found_sym, int *found_dwarf)
+ fileline *fileline_fn, int *found_sym, int *found_dwarf,
+ uintptr_t module_handle ATTRIBUTE_UNUSED)
 {
   struct backtrace_view fhdr_view;
   off_t fhdr_off;
@@ -870,12 +883,7 @@ coff_add (struct backtrace_state *state, int descriptor,
 }
 
 #ifdef HAVE_WINDOWS_H
-  {
-uintptr_t module_handle;
-
-module_handle = (uintptr_t) GetModuleHandle (NULL);
-base_address = module_handle - image_base;
-  }
+  base_address = module_handle - image_base;
 #endif
 
   if (!backtrace_dwarf_add (state, base_address, _sections,
@@ -917,12 +925,61 @@ backtrace_initialize (struct backtrace_state *state,
   int found_sym;
   int found_dwarf;
   fileline coff_fileline_fn;
+  uintptr_t module_handle = 0;
+#ifdef HAVE_TLHELP32_H
+  fileline module_fileline_fn;
+  int module_found_sym;
+  HANDLE snapshot;
+#endif
+
+#ifdef HAVE_WINDOWS_H
+  module_handle = (uintptr_t) GetModuleHandle (NULL);
+#endif
 
   ret = coff_add (state, descriptor, error_callback, data,
- _fileline_fn, _sym, _dwarf);
+ _fileline_fn, _sym, _dwarf, module_handle);
   if (!ret)
 return 0;
 
+#ifdef HAVE_TLHELP32_H
+  do
+{
+  snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0);
+}
+  while (snapshot == INVALID_HANDLE_VALUE
+&& GetLastError () == ERROR_BAD_LENGTH);
+
+  if (snapshot != INVALID_HANDLE_VALUE)
+{
+  MODULEENTRY32 entry;
+  BOOL ok;
+  entry.dwSize = sizeof (MODULEENTRY32);
+
+  for (ok = Module32First (snapshot, ); ok; ok = Module32Next 
(snapshot, ))
+   {
+ if (strcmp (filename, entry.szExePath) == 0)
+   continue;
+
+ module_handle = (uintptr_t) entry.hModule;
+ if (module_handle == 0)
+   continue;
+
+ descriptor = backtrace_open (entry.szExePath, error_callback, data,
+  NULL);
+ if (descriptor < 0)
+   continue;
+
+ coff_add (state, descriptor, error_callback, data,
+   _fileline_fn, _found_sym, _dwarf,
+   module_handle);
+ if (module_found_sym)
+   found_sym = 1;
+   }
+
+  CloseHandle (snapshot);
+}
+#endif
+
   if (!state->threaded)
 {
   if (found_sym)


[gcc r15-25] libbacktrace: load Windows modules

2024-04-28 Thread Ian Lance Taylor via Gcc-cvs
https://gcc.gnu.org/g:942a9cf2a958113d2ab46f5b015c36e569abedcf

commit r15-25-g942a9cf2a958113d2ab46f5b015c36e569abedcf
Author: Ian Lance Taylor 
Date:   Sun Apr 28 11:14:17 2024 -0700

libbacktrace: load Windows modules

Patch from Björn Schäpers .

* configure.ac: Checked for tlhelp32.h
* pecoff.c: Include  if available.
(backtrace_initialize): Use tlhelp32 api for a snapshot to
detect loaded modules.
(coff_add): New argument for the module handle of the file,
to get the base address.
* configure, config.h.in: Regenerate.

Diff:
---
 libbacktrace/config.h.in  |  3 ++
 libbacktrace/configure| 15 ++
 libbacktrace/configure.ac |  4 +++
 libbacktrace/pecoff.c | 73 +--
 4 files changed, 87 insertions(+), 8 deletions(-)

diff --git a/libbacktrace/config.h.in b/libbacktrace/config.h.in
index ee2616335c7..9b8ab88ab63 100644
--- a/libbacktrace/config.h.in
+++ b/libbacktrace/config.h.in
@@ -101,6 +101,9 @@
 /* Define to 1 if you have the  header file. */
 #undef HAVE_SYS_TYPES_H
 
+/* Define to 1 if you have the  header file. */
+#undef HAVE_TLHELP32_H
+
 /* Define to 1 if you have the  header file. */
 #undef HAVE_UNISTD_H
 
diff --git a/libbacktrace/configure b/libbacktrace/configure
index d6d6606a72c..ab94a85f45c 100755
--- a/libbacktrace/configure
+++ b/libbacktrace/configure
@@ -13523,6 +13523,21 @@ fi
 
 done
 
+for ac_header in tlhelp32.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "tlhelp32.h" 
"ac_cv_header_tlhelp32_h" "#ifdef HAVE_WINDOWS_H
+#  include 
+#endif
+"
+if test "x$ac_cv_header_tlhelp32_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_TLHELP32_H 1
+_ACEOF
+
+fi
+
+done
+
 
 # Check for the fcntl function.
 if test -n "${with_target_subdir}"; then
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 3e0075a2b79..59e9c415db8 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -380,6 +380,10 @@ if test "$have_loadquery" = "yes"; then
 fi
 
 AC_CHECK_HEADERS(windows.h)
+AC_CHECK_HEADERS(tlhelp32.h, [], [],
+[#ifdef HAVE_WINDOWS_H
+#  include 
+#endif])
 
 # Check for the fcntl function.
 if test -n "${with_target_subdir}"; then
diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c
index 9e437d810c7..4f267841178 100644
--- a/libbacktrace/pecoff.c
+++ b/libbacktrace/pecoff.c
@@ -49,6 +49,18 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #endif
 
 #include 
+
+#ifdef HAVE_TLHELP32_H
+#include 
+
+#ifdef UNICODE
+/* If UNICODE is defined, all the symbols are replaced by a macro to use the
+   wide variant. But we need the ansi variant, so undef the macros. */
+#undef MODULEENTRY32
+#undef Module32First
+#undef Module32Next
+#endif
+#endif
 #endif
 
 /* Coff file header.  */
@@ -592,7 +604,8 @@ coff_syminfo (struct backtrace_state *state, uintptr_t addr,
 static int
 coff_add (struct backtrace_state *state, int descriptor,
  backtrace_error_callback error_callback, void *data,
- fileline *fileline_fn, int *found_sym, int *found_dwarf)
+ fileline *fileline_fn, int *found_sym, int *found_dwarf,
+ uintptr_t module_handle ATTRIBUTE_UNUSED)
 {
   struct backtrace_view fhdr_view;
   off_t fhdr_off;
@@ -870,12 +883,7 @@ coff_add (struct backtrace_state *state, int descriptor,
 }
 
 #ifdef HAVE_WINDOWS_H
-  {
-uintptr_t module_handle;
-
-module_handle = (uintptr_t) GetModuleHandle (NULL);
-base_address = module_handle - image_base;
-  }
+  base_address = module_handle - image_base;
 #endif
 
   if (!backtrace_dwarf_add (state, base_address, _sections,
@@ -917,12 +925,61 @@ backtrace_initialize (struct backtrace_state *state,
   int found_sym;
   int found_dwarf;
   fileline coff_fileline_fn;
+  uintptr_t module_handle = 0;
+#ifdef HAVE_TLHELP32_H
+  fileline module_fileline_fn;
+  int module_found_sym;
+  HANDLE snapshot;
+#endif
+
+#ifdef HAVE_WINDOWS_H
+  module_handle = (uintptr_t) GetModuleHandle (NULL);
+#endif
 
   ret = coff_add (state, descriptor, error_callback, data,
- _fileline_fn, _sym, _dwarf);
+ _fileline_fn, _sym, _dwarf, module_handle);
   if (!ret)
 return 0;
 
+#ifdef HAVE_TLHELP32_H
+  do
+{
+  snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0);
+}
+  while (snapshot == INVALID_HANDLE_VALUE
+&& GetLastError () == ERROR_BAD_LENGTH);
+
+  if (snapshot != INVALID_HANDLE_VALUE)
+{
+  MODULEENTRY32 entry;
+  BOOL ok;
+  entry.dwSize = sizeof (MODULEENTRY32);
+
+  for (ok = Module32First (snapshot, ); ok; ok = Module32Next 
(snapshot, ))
+   {
+ if (strcmp (filename, entry.szExePath) == 0)
+   continue;
+
+ module_handle = (uintptr_t) entry.hModule;
+ if (module_handle == 0)
+   continue;
+
+ descriptor = backtrace_open (entry.szExePath, error_callback, data,
+  NULL);
+   

[gcc r14-10095] libbacktrace: test --compress-debug-sections=ARG for each ARG

2024-04-23 Thread Ian Lance Taylor via Gcc-cvs
https://gcc.gnu.org/g:d2f05fed44951001de3cb02c9193c687e9376170

commit r14-10095-gd2f05fed44951001de3cb02c9193c687e9376170
Author: Ian Lance Taylor 
Date:   Tue Apr 23 10:00:03 2024 -0700

libbacktrace: test --compress-debug-sections=ARG for each ARG

This should fix a testsuite problem with Solaris ld that supports zlib
but not zlib-gabi.

* configure.ac: Test --compress-debug-sections=zlib-gnu and
--compress-debug-sections=zlib-gabi separately, setting new
automake conditionals.
* Makefile.am (ctestg, ctestg_alloc): Only build if
HAVE_COMPRESSED_DEBUG_ZLIB_GNU.
(ctesta, ctesta_alloc): Only build if
HAVE_COMPRESSED_DEBUG_ZLIB_GABI.
(ctestzstd_alloc): New test if HAVE_COMPRESSED_DEBUG_ZSTD.
* configure, Makefile.in: Regenerate.

Diff:
---
 libbacktrace/Makefile.am  |  41 ++
 libbacktrace/Makefile.in  | 186 +++---
 libbacktrace/configure|  80 +++-
 libbacktrace/configure.ac |  23 --
 4 files changed, 214 insertions(+), 116 deletions(-)

diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am
index 5677ecd8865..bed42c29329 100644
--- a/libbacktrace/Makefile.am
+++ b/libbacktrace/Makefile.am
@@ -493,19 +493,37 @@ endif HAVE_OBJCOPY_DEBUGLINK
  $<
$(OBJCOPY) --strip-all $< $@
 
-if HAVE_COMPRESSED_DEBUG
+if HAVE_COMPRESSED_DEBUG_ZLIB_GNU
 
 ctestg_SOURCES = btest.c testlib.c
 ctestg_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 ctestg_LDFLAGS = -Wl,--compress-debug-sections=zlib-gnu 
$(libbacktrace_testing_ldflags)
 ctestg_LDADD = libbacktrace.la
 
+ctestg_alloc_SOURCES = $(ctestg_SOURCES)
+ctestg_alloc_CFLAGS = $(ctestg_CFLAGS)
+ctestg_alloc_LDFLAGS = $(ctestg_LDFLAGS) $(libbacktrace_testing_ldflags)
+ctestg_alloc_LDADD = libbacktrace_alloc.la
+
+BUILDTESTS += ctestg ctestg_alloc
+
+endif
+
+if HAVE_COMPRESSED_DEBUG_ZLIB_GABI
+
 ctesta_SOURCES = btest.c testlib.c
 ctesta_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 ctesta_LDFLAGS = -Wl,--compress-debug-sections=zlib-gabi 
$(libbacktrace_testing_ldflags)
 ctesta_LDADD = libbacktrace.la
 
-BUILDTESTS += ctestg ctesta
+ctesta_alloc_SOURCES = $(ctesta_SOURCES)
+ctesta_alloc_CFLAGS = $(ctesta_CFLAGS)
+ctesta_alloc_LDFLAGS = $(ctesta_LDFLAGS) $(libbacktrace_testing_ldflags)
+ctesta_alloc_LDADD = libbacktrace_alloc.la
+
+BUILDTESTS += ctesta ctesta_alloc
+
+endif
 
 if HAVE_COMPRESSED_DEBUG_ZSTD
 
@@ -514,21 +532,12 @@ ctestzstd_CFLAGS = $(libbacktrace_TEST_CFLAGS)
 ctestzstd_LDFLAGS = -Wl,--compress-debug-sections=zstd 
$(libbacktrace_testing_ldflags)
 ctestzstd_LDADD = libbacktrace.la
 
-BUILDTESTS += ctestzstd
-
-endif
-
-ctestg_alloc_SOURCES = $(ctestg_SOURCES)
-ctestg_alloc_CFLAGS = $(ctestg_CFLAGS)
-ctestg_alloc_LDFLAGS = $(ctestg_LDFLAGS) $(libbacktrace_testing_ldflags)
-ctestg_alloc_LDADD = libbacktrace_alloc.la
-
-ctesta_alloc_SOURCES = $(ctesta_SOURCES)
-ctesta_alloc_CFLAGS = $(ctesta_CFLAGS)
-ctesta_alloc_LDFLAGS = $(ctesta_LDFLAGS) $(libbacktrace_testing_ldflags)
-ctesta_alloc_LDADD = libbacktrace_alloc.la
+ctestzstd_alloc_SOURCES = $(ctestzstd_SOURCES)
+ctestzstd_alloc_CFLAGS = $(ctestzstd_CFLAGS)
+ctestzstd_alloc_LDFLAGS = $(ctestzstd_LDFLAGS) $(libbacktrace_testing_ldflags)
+ctestzstd_alloc_LDADD = libbacktrace_alloc.la
 
-BUILDTESTS += ctestg_alloc ctesta_alloc
+BUILDTESTS += ctestzstd ctestzstd_alloc
 
 endif
 
diff --git a/libbacktrace/Makefile.in b/libbacktrace/Makefile.in
index 49852a21d37..0260ca81798 100644
--- a/libbacktrace/Makefile.in
+++ b/libbacktrace/Makefile.in
@@ -153,9 +153,9 @@ TESTS = $(am__append_4) $(MAKETESTS) $(am__EXEEXT_16)
 @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@@USE_DSYMUTIL_TRUE@ttest.dSYM \
 @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@@USE_DSYMUTIL_TRUE@ttest_alloc.dSYM
 @HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_22 = btest_gnudebuglink 
btest_gnudebuglinkfull
-@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__append_23 = ctestg ctesta
-@HAVE_COMPRESSED_DEBUG_TRUE@@HAVE_COMPRESSED_DEBUG_ZSTD_TRUE@@NATIVE_TRUE@am__append_24
 = ctestzstd
-@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__append_25 = ctestg_alloc 
ctesta_alloc
+@HAVE_COMPRESSED_DEBUG_ZLIB_GNU_TRUE@@NATIVE_TRUE@am__append_23 = ctestg 
ctestg_alloc
+@HAVE_COMPRESSED_DEBUG_ZLIB_GABI_TRUE@@NATIVE_TRUE@am__append_24 = ctesta 
ctesta_alloc
+@HAVE_COMPRESSED_DEBUG_ZSTD_TRUE@@NATIVE_TRUE@am__append_25 = ctestzstd 
ctestzstd_alloc
 @HAVE_DWARF5_TRUE@@NATIVE_TRUE@am__append_26 = dwarf5 dwarf5_alloc
 @HAVE_DWARF5_TRUE@@NATIVE_TRUE@@USE_DSYMUTIL_TRUE@am__append_27 =  \
 @HAVE_DWARF5_TRUE@@NATIVE_TRUE@@USE_DSYMUTIL_TRUE@ dwarf5.dSYM \
@@ -239,12 +239,12 @@ libbacktrace_noformat_la_OBJECTS =  \
 @NATIVE_TRUE@am__EXEEXT_8 = edtest$(EXEEXT) edtest_alloc$(EXEEXT)
 @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@am__EXEEXT_9 = ttest$(EXEEXT) \
 @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@   ttest_alloc$(EXEEXT)
-@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__EXEEXT_10 =  \

Re: Updated Sourceware infrastructure plans

2024-04-23 Thread Ian Lance Taylor via Gcc
On Tue, Apr 23, 2024 at 2:32 AM Richard Earnshaw (lists) via Gcc
 wrote:
>
> I've been forced to use gerrit occasionally.  I hate it.  No, I LOATHE it.  
> The UI is anything but intuitive with features hidden behind unobvious 
> selections.  IMO It's not a tool for a casual developer, which makes it a bad 
> introduction to developing software.

I would be shocked if GCC ever adopted Gerrit.  But I don't understand
this objection.  Yes, Gerrit is not a tool for a casual developer.
But so what?  Casual developers don't have to use it, except that they
have to run a particular git command to submit a patch.  It's the GCC
maintainers who have to use Gerrit.

Ian


Re: Sourceware mitigating and preventing the next xz-backdoor

2024-04-03 Thread Ian Lance Taylor via Gcc
On Wed, Apr 3, 2024 at 11:05 AM Toon Moene  wrote:
>
> Two questions arise (as far as I am concerned):
>
> 1. Do daemons like sshd *have* to be linked with shared libraries ?
> Or could it be left to the security minded of the downstream
> (binary) distributions to link it statically with known & proven
> correct libraries ?

I like static linking personally, but it seems like glibc has made a
decision that shared linking is much preferred over static.  That said
my guess is that this kind of attack would have been effective on any
executable built as PIE.  It relied on using an IFUNC hook to adjust
the PLT entry for a different function.  And, of course, most
executables are built as PIE these days, because that is more secure
against different kinds of attacks.

> 2. Is it a limitation of the Unix / Linux daemon concept that, once
> such a process needs root access, it has to have root access
> *always* - even when performing trivial tasks like compressing
> data ?
>
> I recall quite well (vis-a-vis question 2) that the VMS equivalent would
> drop all privileges at the start of the code, and request only those
> relevant when actually needed (e.g., to open a file for reading that was
> owned by [the equivalent on VMS] of root - or perform other functions
> that only root could do), and then drop them immediately afterwards again.

Note that the attack really didn't have anything to do with
compressing data.  The library used an IFUNC to change the PLT of a
different function, so it effectively took control of the code that
verified the cryptographic key.  The only part of the attack that
involved compression was the fact that it happened to live in a
compression library.  And it wouldn't matter whether the code that
verified the cryptographic key was run as root either; the effect of
the attack was to say that the key was OK, and that sshd should
execute the command, and of course that execution must be done on
behalf of the requesting user, which (as I understand it) could be
root.

Ian


Re: Sourceware mitigating and preventing the next xz-backdoor

2024-04-02 Thread Ian Lance Taylor via Gcc
On Tue, Apr 2, 2024 at 1:21 PM Paul Koning via Gcc  wrote:
>
> Would it help to require (rather than just recommend) "don't use root except 
> for the actual 'install' step" ?

Seems reasonable, but note that it wouldn't make any difference to
this attack.  The liblzma library was modified to corrupt the sshd
binary, when sshd was linked against liblzma.  The actual attack
occurred via a connection to a corrupt sshd.  If sshd was running as
root, as is normal, the attacker had root access to the machine.  None
of the attacking steps had anything to do with having root access
while building or installing the program.

Ian


[gcc r14-9698] compiler: use correct size and comparison in index value overflow check

2024-03-27 Thread Ian Lance Taylor via Gcc-cvs
https://gcc.gnu.org/g:bd8a3eecc4edffad6e5091ae42c1cb1c1730b2ab

commit r14-9698-gbd8a3eecc4edffad6e5091ae42c1cb1c1730b2ab
Author: Ian Lance Taylor 
Date:   Wed Mar 27 13:37:45 2024 -0700

compiler: use correct size and comparison in index value overflow check

This has apparently been wrong since I introduced the code ten years ago.

Fixes PR go/114500

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/574835

Diff:
---
 gcc/go/gofrontend/MERGE  | 2 +-
 gcc/go/gofrontend/expressions.cc | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index de6e21fb3b5..50d430d5034 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-3f597287b6b858794dabdfe1bf83b386aad18102
+98e92493db2ab7857a5934a950a830fc1f95a4e5
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 8429e553eac..238d5a56ca2 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -18790,7 +18790,7 @@ Composite_literal_expression::lower_array(Type* type)
 
  Named_type* ntype = Type::lookup_integer_type("int");
  Integer_type* inttype = ntype->integer_type();
- if (sizeof(index) <= static_cast(inttype->bits() * 8)
+ if (sizeof(index) >= static_cast(inttype->bits() / 8)
  && index >> (inttype->bits() - 1) != 0)
{
  go_error_at(index_expr->location(), "index value overflow");


[gcc r14-9695] gcc/testsuite/go.test: update issue16016

2024-03-27 Thread Ian Lance Taylor via Gcc-cvs
https://gcc.gnu.org/g:9ff034fcff8ccab6eb82bf2cd36e2d24b2df9b78

commit r14-9695-g9ff034fcff8ccab6eb82bf2cd36e2d24b2df9b78
Author: Ian Lance Taylor 
Date:   Wed Mar 27 11:44:42 2024 -0700

gcc/testsuite/go.test: update issue16016

This backports https://go.dev/cl/574536 into the GCC testsuite.

Fixes PR go/114453

Diff:
---
 gcc/testsuite/go.test/test/fixedbugs/issue16016.go | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/go.test/test/fixedbugs/issue16016.go 
b/gcc/testsuite/go.test/test/fixedbugs/issue16016.go
index e738e1dba0e..b1947f5548d 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/issue16016.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/issue16016.go
@@ -6,7 +6,10 @@
 
 package main
 
-import "time"
+import (
+   "runtime"
+   "time"
+)
 
 type T struct{}
 
@@ -24,8 +27,19 @@ type Q interface {
 }
 
 func main() {
+   var count = 1
+   if runtime.Compiler == "gccgo" {
+   // On targets without split-stack libgo allocates
+   // a large stack for each goroutine. On 32-bit
+   // systems this test can run out of memory.
+   const intSize = 32 << (^uint(0) >> 63) // 32 or 64
+   if intSize < 64 {
+   count = 100
+   }
+   }
+
var q Q = {{}}
-   for i := 0; i < 1; i++ {
+   for i := 0; i < count; i++ {
go func() {
defer q.Foo([]interface{}{"meow"})
time.Sleep(100 * time.Millisecond)


[gcc r14-9693] compiler: initialize local variable in lower_method_expression

2024-03-27 Thread Ian Lance Taylor via Gcc-cvs
https://gcc.gnu.org/g:f85d3362cdb4bab611508dd9a38d9015c02ff7ca

commit r14-9693-gf85d3362cdb4bab611508dd9a38d9015c02ff7ca
Author: Ian Lance Taylor 
Date:   Tue Mar 26 13:00:03 2024 -0700

compiler: initialize local variable in lower_method_expression

Fixes PR go/114463

Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/574476

Diff:
---
 gcc/go/gofrontend/MERGE  | 2 +-
 gcc/go/gofrontend/expressions.cc | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 73cb095322c..de6e21fb3b5 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-e15a14e410b8fc5d28012d5b313cb6c8476c7df9
+3f597287b6b858794dabdfe1bf83b386aad18102
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 51ff0206129..8429e553eac 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -9059,7 +9059,7 @@ Selector_expression::lower_method_expression(Gogo* gogo)
 
   Named_type* nt = type->named_type();
   Struct_type* st = type->struct_type();
-  bool is_ambiguous;
+  bool is_ambiguous = false;
   Method* method = NULL;
   if (nt != NULL)
 method = nt->method_function(name, _ambiguous);


[gcc r14-9402] libbacktrace: don't assume compressed section is aligned

2024-03-08 Thread Ian Lance Taylor via Gcc-cvs
https://gcc.gnu.org/g:5825bd0e0d0040126e78269e56c9b9f533e2a520

commit r14-9402-g5825bd0e0d0040126e78269e56c9b9f533e2a520
Author: Ian Lance Taylor 
Date:   Fri Mar 8 13:55:34 2024 -0800

libbacktrace: don't assume compressed section is aligned

Patch originally by GitHub user ubyte at
https://github.com/ianlancetaylor/libbacktrace/pull/120.

* elf.c (elf_uncompress_chdr): Don't assume compressed section is
aligned.

Diff:
---
 libbacktrace/elf.c | 23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

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;


Re: [PATCH 5/4] libbacktrace: improve getting debug information for loaded dlls

2024-01-25 Thread Ian Lance Taylor via Gcc
On Thu, Jan 25, 2024 at 11:53 AM Björn Schäpers  wrote:
>
> Am 23.01.2024 um 23:37 schrieb Ian Lance Taylor:
> > On Thu, Jan 4, 2024 at 2:33 PM Björn Schäpers  wrote:
> >>
> >> Am 03.01.2024 um 00:12 schrieb Björn Schäpers:
> >>> Am 30.11.2023 um 20:53 schrieb Ian Lance Taylor:
>  On Fri, Jan 20, 2023 at 2:55 AM Björn Schäpers  wrote:
> >
> > From: Björn Schäpers 
> >
> > Fixes https://github.com/ianlancetaylor/libbacktrace/issues/53, except
> > that libraries loaded after the backtrace_initialize are not handled.
> > But as far as I can see that's the same for elf.
> 
>  Thanks, but I don't want a patch that loops using goto statements.
>  Please rewrite to avoid that.  It may be simpler to call a function.
> 
>  Also starting with a module count of 1000 seems like a lot.  Do
>  typical Windows programs load that many modules?
> 
>  Ian
> 
> 
> >>>
> >>> Rewritten using a function.
> >>>
> >>> If that is commited, could you attribute that commit to me 
> >>> (--author="Björn
> >>> Schäpers ")?
> >>>
> >>> Thanks and kind regards,
> >>> Björn.
> >>
> >> I noticed that under 64 bit libraries loaded with LoadLibrary were missing.
> >> EnumProcessModules stated the correct number of modules, but did not fill 
> >> the
> >> the HMODULEs, but set them to 0. While trying to investigate I noticed if 
> >> I do
> >> the very same thing from main (in C++) I even got fewer module HMODULEs.
> >>
> >> So I went a different way. This detects all libraries correctly, in 32 and 
> >> 64
> >> bit. The question is, if it should be a patch on top of the previous, or 
> >> should
> >> they be merged, or even only this solution and drop the EnumProcessModules 
> >> variant?
> >
> > Is there any reason to use both patches?  Seems simpler to just use
> > this one if it works.  Thanks.
> >
> > Ian
>
> This one needs the tlhelp32 header and its functions, which are (accoridng to
> the microsoft documentation) are only available since Windows XP rsp. Windows
> Server 2003.
>
> If that's no problem, and in my opinion it shouldn't be, then I can basically
> drop patch 4 and rebase this one.

I don't see that as a problem.  It seems like the patch will fall back
cleanly on ancient Windows and simply fail to pick up other loaded
DLLs.  I think that is fine.  I'll look for an updated patch.  Thanks.

Ian


Re: [PATCH 5/4] libbacktrace: improve getting debug information for loaded dlls

2024-01-23 Thread Ian Lance Taylor via Gcc
On Thu, Jan 4, 2024 at 2:33 PM Björn Schäpers  wrote:
>
> Am 03.01.2024 um 00:12 schrieb Björn Schäpers:
> > Am 30.11.2023 um 20:53 schrieb Ian Lance Taylor:
> >> On Fri, Jan 20, 2023 at 2:55 AM Björn Schäpers  wrote:
> >>>
> >>> From: Björn Schäpers 
> >>>
> >>> Fixes https://github.com/ianlancetaylor/libbacktrace/issues/53, except
> >>> that libraries loaded after the backtrace_initialize are not handled.
> >>> But as far as I can see that's the same for elf.
> >>
> >> Thanks, but I don't want a patch that loops using goto statements.
> >> Please rewrite to avoid that.  It may be simpler to call a function.
> >>
> >> Also starting with a module count of 1000 seems like a lot.  Do
> >> typical Windows programs load that many modules?
> >>
> >> Ian
> >>
> >>
> >
> > Rewritten using a function.
> >
> > If that is commited, could you attribute that commit to me (--author="Björn
> > Schäpers ")?
> >
> > Thanks and kind regards,
> > Björn.
>
> I noticed that under 64 bit libraries loaded with LoadLibrary were missing.
> EnumProcessModules stated the correct number of modules, but did not fill the
> the HMODULEs, but set them to 0. While trying to investigate I noticed if I do
> the very same thing from main (in C++) I even got fewer module HMODULEs.
>
> So I went a different way. This detects all libraries correctly, in 32 and 64
> bit. The question is, if it should be a patch on top of the previous, or 
> should
> they be merged, or even only this solution and drop the EnumProcessModules 
> variant?

Is there any reason to use both patches?  Seems simpler to just use
this one if it works.  Thanks.

Ian


Re: [PATCH 4/4] libbacktrace: get debug information for loaded dlls

2023-11-30 Thread Ian Lance Taylor via Gcc
On Fri, Jan 20, 2023 at 2:55 AM Björn Schäpers  wrote:
>
> From: Björn Schäpers 
>
> Fixes https://github.com/ianlancetaylor/libbacktrace/issues/53, except
> that libraries loaded after the backtrace_initialize are not handled.
> But as far as I can see that's the same for elf.

Thanks, but I don't want a patch that loops using goto statements.
Please rewrite to avoid that.  It may be simpler to call a function.

Also starting with a module count of 1000 seems like a lot.  Do
typical Windows programs load that many modules?

Ian




> Tested on x86_64-linux and i686-w64-mingw32.
>
> -- >8 --
>
> * pecoff.c (coff_add): New argument for the module handle of the
> file, to get the base address.
> * pecoff.c (backtrace_initialize): Iterate over loaded libraries
> and call coff_add.
>
> Signed-off-by: Björn Schäpers 
> ---
>  libbacktrace/pecoff.c | 76 ---
>  1 file changed, 72 insertions(+), 4 deletions(-)
>
> diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c
> index 296f1357b5f..40395109e51 100644
> --- a/libbacktrace/pecoff.c
> +++ b/libbacktrace/pecoff.c
> @@ -49,6 +49,7 @@ POSSIBILITY OF SUCH DAMAGE.  */
>  #endif
>
>  #include 
> +#include 
>  #endif
>
>  /* Coff file header.  */
> @@ -592,7 +593,8 @@ coff_syminfo (struct backtrace_state *state, uintptr_t 
> addr,
>  static int
>  coff_add (struct backtrace_state *state, int descriptor,
>   backtrace_error_callback error_callback, void *data,
> - fileline *fileline_fn, int *found_sym, int *found_dwarf)
> + fileline *fileline_fn, int *found_sym, int *found_dwarf,
> + uintptr_t module_handle ATTRIBUTE_UNUSED)
>  {
>struct backtrace_view fhdr_view;
>off_t fhdr_off;
> @@ -623,7 +625,6 @@ coff_add (struct backtrace_state *state, int descriptor,
>int is_64;
>uintptr_t image_base;
>uintptr_t base_address = 0;
> -  uintptr_t module_handle;
>struct dwarf_sections dwarf_sections;
>
>*found_sym = 0;
> @@ -871,7 +872,6 @@ coff_add (struct backtrace_state *state, int descriptor,
>  }
>
>  #ifdef HAVE_WINDOWS_H
> -module_handle = (uintptr_t) GetModuleHandleW (NULL);
>  base_address = module_handle - image_base;
>  #endif
>
> @@ -914,12 +914,80 @@ backtrace_initialize (struct backtrace_state *state,
>int found_sym;
>int found_dwarf;
>fileline coff_fileline_fn;
> +  uintptr_t module_handle = 0;
> +
> +#ifdef HAVE_WINDOWS_H
> +  DWORD i;
> +  DWORD module_count;
> +  DWORD bytes_needed_for_modules;
> +  HMODULE *modules;
> +  char module_name[MAX_PATH];
> +  int module_found_sym;
> +  fileline module_fileline_fn;
> +
> +  module_handle = (uintptr_t) GetModuleHandleW (NULL);
> +#endif
>
>ret = coff_add (state, descriptor, error_callback, data,
> - _fileline_fn, _sym, _dwarf);
> + _fileline_fn, _sym, _dwarf, module_handle);
>if (!ret)
>  return 0;
>
> +#ifdef HAVE_WINDOWS_H
> +  module_count = 1000;
> + alloc_modules:
> +  modules = backtrace_alloc (state, module_count * sizeof(HMODULE),
> +error_callback, data);
> +  if (modules == NULL)
> +goto skip_modules;
> +  if (!EnumProcessModules (GetCurrentProcess (), modules, module_count,
> +  _needed_for_modules))
> +{
> +  error_callback(data, "Could not enumerate process modules",
> +(int) GetLastError ());
> +  goto free_modules;
> +}
> +  if (bytes_needed_for_modules > module_count * sizeof(HMODULE))
> +{
> +  backtrace_free (state, modules, module_count * sizeof(HMODULE),
> + error_callback, data);
> +  // Add an extra of 2, if some module is loaded in another thread.
> +  module_count = bytes_needed_for_modules / sizeof(HMODULE) + 2;
> +  modules = NULL;
> +  goto alloc_modules;
> +}
> +
> +  for (i = 0; i < bytes_needed_for_modules / sizeof(HMODULE); ++i)
> +{
> +  if (GetModuleFileNameA (modules[i], module_name, MAX_PATH - 1))
> +   {
> + if (strcmp (filename, module_name) == 0)
> +   continue;
> +
> + module_handle = (uintptr_t) GetModuleHandleA (module_name);
> + if (module_handle == 0)
> +   continue;
> +
> + descriptor = backtrace_open (module_name, error_callback, data, 
> NULL);
> + if (descriptor < 0)
> +   continue;
> +
> + coff_add (state, descriptor, error_callback, data,
> +   _fileline_fn, _found_sym, _dwarf,
> +   module_handle);
> + if (module_found_sym)
> +   found_sym = 1;
> +   }
> +}
> +
> + free_modules:
> +  if (modules)
> +backtrace_free(state, modules, module_count * sizeof(HMODULE),
> +  error_callback, data);
> +  modules = NULL;
> + skip_modules:
> +#endif
> +
>if (!state->threaded)
>  {
>if (found_sym)
> --
> 2.38.1
>


Re: [PATCH 3/4] libbacktrace: work with aslr on windows

2023-11-30 Thread Ian Lance Taylor via Gcc
On Mon, Nov 20, 2023 at 11:58 AM Björn Schäpers  wrote:
>
> An updated version, using neither A or W, but just the macro.

Thanks.  Committed as follows.

Ian
1017495bc91d40570f58c37e88ca013164782129
diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c
index 56af4828e27..f976a963bf3 100644
--- a/libbacktrace/pecoff.c
+++ b/libbacktrace/pecoff.c
@@ -39,6 +39,18 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include "backtrace.h"
 #include "internal.h"
 
+#ifdef HAVE_WINDOWS_H
+#ifndef WIN32_MEAN_AND_LEAN
+#define WIN32_MEAN_AND_LEAN
+#endif
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+#include 
+#endif
+
 /* Coff file header.  */
 
 typedef struct {
@@ -610,6 +622,7 @@ coff_add (struct backtrace_state *state, int descriptor,
   int debug_view_valid;
   int is_64;
   uintptr_t image_base;
+  uintptr_t base_address = 0;
   struct dwarf_sections dwarf_sections;
 
   *found_sym = 0;
@@ -856,7 +869,16 @@ coff_add (struct backtrace_state *state, int descriptor,
  + (sections[i].offset - min_offset));
 }
 
-  if (!backtrace_dwarf_add (state, /* base_address */ 0, _sections,
+#ifdef HAVE_WINDOWS_H
+  {
+uintptr_t module_handle;
+
+module_handle = (uintptr_t) GetModuleHandle (NULL);
+base_address = module_handle - image_base;
+  }
+#endif
+
+  if (!backtrace_dwarf_add (state, base_address, _sections,
0, /* FIXME: is_bigendian */
NULL, /* altlink */
error_callback, data, fileline_fn,


Re: [PATCH 2/4] libbacktrace: detect executable path on windows

2023-11-29 Thread Ian Lance Taylor via Gcc
On Mon, Nov 20, 2023 at 11:57 AM Björn Schäpers  wrote:
>
> this is what I'm using with GCC 12 and 13 on my windows machines, rebased onto
> the current HEAD.

Thanks.  Committed as follows.

Ian

* fileline.c: Include  if available.
(windows_get_executable_path): New static function.
(fileline_initialize): Call windows_get_executable_path.
* configure.ac: Checked for windows.h
* configure: Regenerate.
* config.h.in: Regenerate.
0ee01dfacbcc9bc05d11433a69c0a0ac13afa42f
diff --git a/libbacktrace/config.h.in b/libbacktrace/config.h.in
index a4f5bf6..ee2616335c7 100644
--- a/libbacktrace/config.h.in
+++ b/libbacktrace/config.h.in
@@ -104,6 +104,9 @@
 /* Define to 1 if you have the  header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you have the  header file. */
+#undef HAVE_WINDOWS_H
+
 /* Define if -lz is available. */
 #undef HAVE_ZLIB
 
diff --git a/libbacktrace/configure b/libbacktrace/configure
index 0ccc060901d..7ade966b54d 100755
--- a/libbacktrace/configure
+++ b/libbacktrace/configure
@@ -13509,6 +13509,19 @@ $as_echo "#define HAVE_LOADQUERY 1" >>confdefs.h
 
 fi
 
+for ac_header in windows.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" 
"$ac_includes_default"
+if test "x$ac_cv_header_windows_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_WINDOWS_H 1
+_ACEOF
+
+fi
+
+done
+
+
 # Check for the fcntl function.
 if test -n "${with_target_subdir}"; then
case "${host}" in
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 71cd50f8cdf..00acb42eb6d 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -379,6 +379,8 @@ if test "$have_loadquery" = "yes"; then
   AC_DEFINE(HAVE_LOADQUERY, 1, [Define if AIX loadquery is available.])
 fi
 
+AC_CHECK_HEADERS(windows.h)
+
 # Check for the fcntl function.
 if test -n "${with_target_subdir}"; then
case "${host}" in
diff --git a/libbacktrace/fileline.c b/libbacktrace/fileline.c
index 0e560b44e7a..773f3a92969 100644
--- a/libbacktrace/fileline.c
+++ b/libbacktrace/fileline.c
@@ -47,6 +47,18 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include 
 #endif
 
+#ifdef HAVE_WINDOWS_H
+#ifndef WIN32_MEAN_AND_LEAN
+#define WIN32_MEAN_AND_LEAN
+#endif
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+#include 
+#endif
+
 #include "backtrace.h"
 #include "internal.h"
 
@@ -165,6 +177,37 @@ macho_get_executable_path (struct backtrace_state *state,
 
 #endif /* !HAVE_DECL__PGMPTR */
 
+#ifdef HAVE_WINDOWS_H
+
+#define FILENAME_BUF_SIZE (MAX_PATH)
+
+static char *
+windows_get_executable_path (char *buf, backtrace_error_callback 
error_callback,
+void *data)
+{
+  size_t got;
+  int error;
+
+  got = GetModuleFileNameA (NULL, buf, FILENAME_BUF_SIZE - 1);
+  error = GetLastError ();
+  if (got == 0
+  || (got == FILENAME_BUF_SIZE - 1 && error == ERROR_INSUFFICIENT_BUFFER))
+{
+  error_callback (data,
+ "could not get the filename of the current executable",
+ error);
+  return NULL;
+}
+  return buf;
+}
+
+#else /* !defined (HAVE_WINDOWS_H) */
+
+#define windows_get_executable_path(buf, error_callback, data) NULL
+#define FILENAME_BUF_SIZE 64
+
+#endif /* !defined (HAVE_WINDOWS_H) */
+
 /* Initialize the fileline information from the executable.  Returns 1
on success, 0 on failure.  */
 
@@ -178,7 +221,7 @@ fileline_initialize (struct backtrace_state *state,
   int called_error_callback;
   int descriptor;
   const char *filename;
-  char buf[64];
+  char buf[FILENAME_BUF_SIZE];
 
   if (!state->threaded)
 failed = state->fileline_initialization_failed;
@@ -202,7 +245,7 @@ fileline_initialize (struct backtrace_state *state,
 
   descriptor = -1;
   called_error_callback = 0;
-  for (pass = 0; pass < 9; ++pass)
+  for (pass = 0; pass < 10; ++pass)
 {
   int does_not_exist;
 
@@ -239,6 +282,9 @@ fileline_initialize (struct backtrace_state *state,
case 8:
  filename = macho_get_executable_path (state, error_callback, data);
  break;
+   case 9:
+ filename = windows_get_executable_path (buf, error_callback, data);
+ break;
default:
  abort ();
}


Re: libgo: Consider '--with-build-sysroot=[...]' for target libraries' build-tree testing (instead of build-time 'CC' etc.) [PR109951] (was: [PATCH 3/4] libgo/test: Fix compilation for build sysroot)

2023-09-12 Thread Ian Lance Taylor via Gcc-patches
On Tue, Sep 12, 2023 at 4:16 AM Thomas Schwinge  wrote:
>
> As we've found, this is conceptually problematic, as discussed in
> 
> "Consider '--with-build-sysroot=[...]' for target libraries' build-tree 
> testing (instead of build-time 'CC' etc.)
> [PR109951]".
> I therefore suggest to apply to libgo the conceptually same changes
> as I've just pushed for libgomp:
> 
> "libgomp: Consider '--with-build-sysroot=[...]' for target libraries' 
> build-tree testing (instead of build-time 'CC'
> etc.) [PR91884, PR109951]".
> OK to push (via Ian/Go upstream) the attached
> "libgo: Consider '--with-build-sysroot=[...]' for target libraries' 
> build-tree testing (instead of build-time 'CC' etc.) [PR109951]"?
>
> By the way, I've tested this one via hard-coding
> 'libgo/configure.ac:USE_DEJAGNU' to 'yes', and observing that my
> "quick hack to replicate the original requirement"
> ('internal_error ("MISSING SYSROOT");') no longer triggers.

Thanks.  Committed.

Ian


godump.cc patch committed: Handle _BitInt

2023-09-06 Thread Ian Lance Taylor via Gcc-patches
This patch to godump.cc adds support for BITINT_TYPE.  Bootstrapped
and ran godump and Go tests on x86_64-pc-linux-gnu.  Committed to
mainline.

Ian

gcc/
PR go/111310
* godump.cc (go_format_type): Handle BITINT_TYPE.

gcc/testsuite/
PR go/111310
   * gcc.misc-tests/godump-1.c: Add _BitInt test cases.
diff --git a/gcc/godump.cc b/gcc/godump.cc
index 0893d5fbc97..bdd2d108d76 100644
--- a/gcc/godump.cc
+++ b/gcc/godump.cc
@@ -760,6 +760,25 @@ go_format_type (class godump_container *container, tree 
type,
   }
   break;
 
+case BITINT_TYPE:
+  {
+   const char *s;
+   char buf[100];
+
+   s = go_get_uinttype_for_precision (TYPE_PRECISION (type),
+  TYPE_UNSIGNED (type));
+   if (s == NULL)
+ {
+   snprintf (buf, sizeof buf, "INVALID-bitint-%u%s",
+ TYPE_PRECISION (type),
+ TYPE_UNSIGNED (type) ? "u" : "");
+   s = buf;
+   ret = false;
+ }
+   obstack_grow (ob, s, strlen(s));
+  }
+  break;
+
 case REAL_TYPE:
   {
const char *s;
diff --git a/gcc/testsuite/gcc.misc-tests/godump-1.c 
b/gcc/testsuite/gcc.misc-tests/godump-1.c
index 95dabdc0e4c..f359a657827 100644
--- a/gcc/testsuite/gcc.misc-tests/godump-1.c
+++ b/gcc/testsuite/gcc.misc-tests/godump-1.c
@@ -234,6 +234,17 @@ const char cc_v1;
 cc_t cc_v2;
 /* { dg-final { scan-file godump-1.out "(?n)^var _cc_v2 _cc_t$" } } */
 
+_BitInt(32) b32_v;
+/* { dg-final { scan-file godump-1.out "(?n)^var _b32_v int32$" } } */
+
+_BitInt(64) b64_v;
+/* { dg-final { scan-file godump-1.out "(?n)^var _b64_v int64$" } } */
+
+unsigned _BitInt(32) b32u_v;
+/* { dg-final { scan-file godump-1.out "(?n)^var _b32u_v uint32$" } } */
+
+_BitInt(33) b33_v;
+/* { dg-final { scan-file godump-1.out "(?n)^// var _b33_v INVALID-bitint-33$" 
} } */
 
 /*** pointer and array types ***/
 typedef void *vp_t;


libgo patch committed: permit $AR to include options

2023-09-06 Thread Ian Lance Taylor via Gcc-patches
This libgo patch changes the go tool to permit the AR environment
variable to include options.  This mirrors the way it already handles
the CC environment variable.

This ports https://go.dev/cl/526275 to the gofrontend repo.

This is needed for gccgo testing because the top-level GCC Makefile
now passes a --plugin option to ar if it supports one.

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

Ian
dab7163feedc99bd94549ee490031f86f8d0a6ca
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 83ab3e2d64c..30710e856cb 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-d04b024021bb7dbaa434a6d902bd12beb08e315f
+53cdfab53ce79d8dfc1df01a696d4ffc43f17c3d
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/go/cmd/go/internal/work/gccgo.go 
b/libgo/go/cmd/go/internal/work/gccgo.go
index c1026c71e01..3e07f8791eb 100644
--- a/libgo/go/cmd/go/internal/work/gccgo.go
+++ b/libgo/go/cmd/go/internal/work/gccgo.go
@@ -45,12 +45,8 @@ func (gccgoToolchain) linker() string {
return GccgoBin
 }
 
-func (gccgoToolchain) ar() string {
-   ar := cfg.Getenv("AR")
-   if ar == "" {
-   ar = "ar"
-   }
-   return ar
+func (gccgoToolchain) ar() []string {
+   return envList("AR", "ar")
 }
 
 func checkGccgoBin() {


Re: [RFC] GCC Security policy

2023-08-08 Thread Ian Lance Taylor via Gcc-patches
On Tue, Aug 8, 2023 at 7:37 AM Jakub Jelinek  wrote:
>
> BTW, I think we should perhaps differentiate between production ready
> libraries (e.g. libgcc, libstdc++, libgomp, libatomic, libgfortran, 
> libquadmath,
> libssp) vs. e.g. the sanitizer libraries which are meant for debugging and
> I believe it is highly risky to run them in programs with extra priviledges
> - e.g. I think they use getenv rather than *secure_getenv to get at various
> tweaks for their behavior including where logging will happen and upstream
> doesn't really care.
> And not really sure what to say about lesser used language support
> libraries, libada, libphobos, libgo, libgm2, ... nor what to say about
> libvtv etc.

libgo is a complicated case because it has a lot of components
including a web server with TLS support, so there are a lot of
potential security issues for programs that use libgo.  The upstream
security policy is https://go.dev/security/policy.  I'm not sure what
to say about libgo in GCC, since realistically the support for
security problems is best-effort.  I guess we should at least accept
security reports, even if we can't promise to fix them quickly.

Ian


Re: [RFC] GCC Security policy

2023-08-08 Thread Ian Lance Taylor via Gcc-patches
On Tue, Aug 8, 2023 at 6:02 AM Jakub Jelinek via Gcc-patches
 wrote:
>
> On Tue, Aug 08, 2023 at 02:52:57PM +0200, Richard Biener via Gcc-patches 
> wrote:
> > There's probably external tools to do this, not sure if we should replicate
> > things in the driver for this.
> >
> > But sure, I think the driver is the proper point to address any of such
> > issues - iff we want to address them at all.  Maybe a nice little
> > google summer-of-code project ;)
>
> What I'd really like to avoid is having all compiler bugs (primarily ICEs)
> considered to be security bugs (e.g. DoS category), it would be terrible to
> release every week a new compiler because of the "security" issues.
> Running compiler on untrusted sources can trigger ICEs (which we want to fix
> but there will always be some), or run into some compile time and/or compile
> memory issue (we have various quadratic or worse spots), compiler stack
> limits (deeply nested stuff e.g. during parsing but other areas as well).
> So, people running fuzzers and reporting issues is great, but if they'd get
> a CVE assigned for each ice-on-invalid-code, ice-on-valid-code,
> each compile-time-hog and each memory-hog, that wouldn't be useful.
> Runtime libraries or security issues in the code we generate for valid
> sources are of course a different thing.


I wonder if a security policy should say something about the -fplugin
option.  I agree that an ICE is not a security issue, but I wonder how
many people are aware that a poorly chosen command line option can
direct the compiler to run arbitrary code.  For that matter the same
is true of setting the GCC_EXEC_PREFIX environment variable, and no
doubt several other environment variables.  My point is not that we
should change these, but that a security policy should draw attention
to the fact that there are cases in which the compiler will
unexpectedly run other programs.

Ian


Re: [PATCH] [libbacktrace] fix up broken test

2023-08-03 Thread Ian Lance Taylor via Gcc-patches
On Thu, Aug 3, 2023 at 6:27 AM Richard Biener via Gcc-patches
 wrote:
>
> zstdtest has some inline data where some testcases lack the
> uncompressed length field.  Thus it computes that but still
> ends up allocating memory for the uncompressed buffer based on
> that (zero) length.  Oops.  Causes memory corruption if the
> allocator returns non-NULL.
>
> Tested on x86_64-unknown-linux-gnu, pushed as obvious.
>
> libbacktrace/
> * zstdtest.c (test_samples): Properly compute the allocation
> size for the uncompressed data.

Thanks.

Ian


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:


libgo patch committet: Don't collect package CGOLDFLAGS

2023-07-20 Thread Ian Lance Taylor via Gcc-patches
This libgo patch to the go command sources stops collecting package
CGOLDFLAGS when using gccgo.  The flags are already collected via
cmd/cgo.

The gccgo_link_c test is tweaked to do real linking as with this
change the cgo ldflags are not fully reflected in go build -n output,
since they now only come from the built archive.

This is a backport of https://go.dev/cl/497117 from the main repo.

This is for https://go.dev/issue/60287.

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

Ian
d2437e29edbe2673867d0e965d6431aff5cec941
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index c44cdc2baac..83ab3e2d64c 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-92152c88ea8e2dd9e8c67e91bf4ae5e3edf1b506
+d04b024021bb7dbaa434a6d902bd12beb08e315f
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/go/cmd/go/internal/work/gccgo.go 
b/libgo/go/cmd/go/internal/work/gccgo.go
index 1e8250002ee..c1026c71e01 100644
--- a/libgo/go/cmd/go/internal/work/gccgo.go
+++ b/libgo/go/cmd/go/internal/work/gccgo.go
@@ -413,16 +413,9 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, 
out, importcfg string
}
 
for _, a := range allactions {
-   // Gather CgoLDFLAGS, but not from standard packages.
-   // The go tool can dig up runtime/cgo from GOROOT and
-   // think that it should use its CgoLDFLAGS, but gccgo
-   // doesn't use runtime/cgo.
if a.Package == nil {
continue
}
-   if !a.Package.Standard {
-   cgoldflags = append(cgoldflags, a.Package.CgoLDFLAGS...)
-   }
if len(a.Package.CgoFiles) > 0 {
usesCgo = true
}
@@ -452,9 +445,6 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, 
out, importcfg string
 
ldflags = append(ldflags, cgoldflags...)
ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
-   if root.Package != nil {
-   ldflags = append(ldflags, root.Package.CgoLDFLAGS...)
-   }
if cfg.Goos != "aix" {
ldflags = str.StringList("-Wl,-(", ldflags, "-Wl,-)")
}
diff --git a/libgo/go/cmd/go/testdata/script/gccgo_link_c.txt 
b/libgo/go/cmd/go/testdata/script/gccgo_link_c.txt
index db2a29128b2..8d67ae2bc7e 100644
--- a/libgo/go/cmd/go/testdata/script/gccgo_link_c.txt
+++ b/libgo/go/cmd/go/testdata/script/gccgo_link_c.txt
@@ -4,8 +4,9 @@
 [!cgo] skip
 [!exec:gccgo] skip
 
-go build -n -compiler gccgo cgoref
+! go build -x -compiler gccgo cgoref
 stderr 'gccgo.*\-L [^ ]*alibpath \-lalib' # make sure that Go-inline "#cgo 
LDFLAGS:" ("-L alibpath -lalib") passed to gccgo linking stage
+! stderr 'gccgo.*-lalib.*-lalib' # make sure -lalib is only passed once
 
 -- cgoref/cgoref.go --
 package main


Re: wishlist: support for shorter pointers

2023-07-03 Thread Ian Lance Taylor via Gcc
On Wed, Jun 28, 2023 at 11:21 PM Rafał Pietrak via Gcc  wrote:
>
> W dniu 28.06.2023 o 17:44, Richard Earnshaw (lists) pisze:
> [---]
> > I think I understand what you're asking for but:
> > 1) You'd need a new ABI specification to handle this, probably involving
> > register assignments (for the 'segment' addresses), the initialization
> > of those at startup, assembler and linker extensions to allow for
> > relocations describing the symbols, etc.
>
> I was thinking about that, and it doesn't look as requiring that deep
> rewrites. ABI spec, that  could accomodate the functionality could be as
> little as one additional attribute to linker segments.

If I understand correctly, you are looking for something like the x32
mode that was available for a while on x86_64 processors:
https://en.wikipedia.org/wiki/X32_ABI .  That was a substantial amount
of work including changes to the compiler, assembler, linker, standard
library, and kernel.  And at least to me it's never seemed
particularly popular.

Ian


Re: New version of gnu assembler

2023-07-02 Thread Ian Lance Taylor via Gcc
On Sun, Jul 2, 2023 at 9:50 AM Dave Blanchard  wrote:
>
> On Sat, 01 Jul 2023 13:33:07 +0100
> Sam James via Gcc  wrote:
>
> > If you've taken files from Binutils BFD, please make sure you preserve
> > the copyright headers too.
>
> Why? How is that important? That's all you have to say about this?
>
> Copyright is an abomination, and especially so the GPL; particularly the 
> GPLv3. I hope he deleted the copyright notice.
>
> OP: Good work and nice project. The GNU ecosystem is full of bloated shitware 
> and cruft, and it's nice to see people working to get rid of all the junk so 
> we can have software that is actually usable and maintainable.

Please be respectful.  Thanks.

Ian


Re: Merge from trunk to gccgo branch

2023-06-26 Thread Ian Lance Taylor via Gcc-patches
I merged trunk revision 3a39a31b8ae9c6465434aefa657f7fcc86f905c0 to
the gccgo branch.

Ian


Go patch committed: Support -fgo-importcfg

2023-06-26 Thread Ian Lance Taylor via Gcc-patches
The gc Go compiler has a -importcfg option that takes a file that
provides a mapping from import paths to the files that satisfy those
imports.  This is used by the go build tool to let the compiler read
imported packages directly out of the build cache.  Without this
option the go build tool has to construct a tree of files to provide
the same mapping in the file system.

This patch to the Go frontend adds a -fgo-importcfg option that does
the same thing.  The go build tool already uses this option if it is
supported; with this patch, it is supported.

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

Ian

* lang.opt (fgo-importcfg): New option.
* go-c.h (struct go_create_gogo_args): Add importcfg field.
* go-lang.cc (go_importcfg): New static variable.
(go_langhook_init): Set args.importcfg.
(go_langhook_handle_option): Handle -fgo-importcfg.
* gccgo.texi (Invoking gccgo): Document -fgo-importcfg.
cd4f91ed9786caf207d6d68bf2e64f986ed19735
diff --git a/gcc/go/gccgo.texi b/gcc/go/gccgo.texi
index 4ab1a76818f..90651af8384 100644
--- a/gcc/go/gccgo.texi
+++ b/gcc/go/gccgo.texi
@@ -271,6 +271,14 @@ pattern to a list of file names, and @code{Files} maps 
each file name
 to a full path to the file.  This option is intended for use by the
 @command{go} command to implement @code{//go:embed}.
 
+@cindex @option{-fgo-importcfg}
+@item -fgo-importcfg=@var{file}
+Identify a file that provides mappings for import package paths found
+in the Go source files.  The file can contain two commands:
+@code{importpath} to rename import paths for vendoring and
+@code{packagefile} to map from package path to files containing export
+data.  This option is intended for use by the @command{go} command.
+
 @cindex @option{-g for gccgo}
 @item -g
 This is the standard @command{gcc} option (@pxref{Debugging Options, ,
diff --git a/gcc/go/go-c.h b/gcc/go/go-c.h
index c6050382aa8..6a2b57b3b44 100644
--- a/gcc/go/go-c.h
+++ b/gcc/go/go-c.h
@@ -41,6 +41,7 @@ struct go_create_gogo_args
   const char* prefix;
   const char* relative_import_path;
   const char* c_header;
+  const char* importcfg;
   const char* embedcfg;
   Backend* backend;
   Linemap* linemap;
diff --git a/gcc/go/go-lang.cc b/gcc/go/go-lang.cc
index c6c147b20a5..e85a4bfe949 100644
--- a/gcc/go/go-lang.cc
+++ b/gcc/go/go-lang.cc
@@ -90,6 +90,7 @@ static const char *go_prefix = NULL;
 static const char *go_relative_import_path = NULL;
 static const char *go_c_header = NULL;
 static const char *go_embedcfg = NULL;
+static const char *go_importcfg = NULL;
 
 /* Language hooks.  */
 
@@ -111,6 +112,7 @@ go_langhook_init (void)
   args.relative_import_path = go_relative_import_path;
   args.c_header = go_c_header;
   args.embedcfg = go_embedcfg;
+  args.importcfg = go_importcfg;
   args.check_divide_by_zero = go_check_divide_zero;
   args.check_divide_overflow = go_check_divide_overflow;
   args.compiling_runtime = go_compiling_runtime;
@@ -286,6 +288,10 @@ go_langhook_handle_option (
   go_embedcfg = arg;
   break;
 
+case OPT_fgo_importcfg_:
+  go_importcfg = arg;
+  break;
+
 default:
   /* Just return 1 to indicate that the option is valid.  */
   break;
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index ff07b1a1fa6..c44cdc2baac 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-68a756b6aadc901534cfad2b1e73fae9e34f
+92152c88ea8e2dd9e8c67e91bf4ae5e3edf1b506
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/embed.cc b/gcc/go/gofrontend/embed.cc
index 0584f707ce6..6dada5efc2a 100644
--- a/gcc/go/gofrontend/embed.cc
+++ b/gcc/go/gofrontend/embed.cc
@@ -19,8 +19,8 @@
 
 // Read a file into *DATA.  Returns false on error.
 
-static bool
-read_file(const char* filename, Location loc, std::string* data)
+bool
+Gogo::read_file(const char* filename, Location loc, std::string* data)
 {
   int fd = open(filename, O_RDONLY | O_BINARY);
   if (fd < 0)
@@ -346,7 +346,8 @@ Gogo::read_embedcfg(const char *filename)
 bool
 Embedcfg_reader::initialize_from_file()
 {
-  if (!read_file(this->filename_, Linemap::unknown_location(), >data_))
+  if (!Gogo::read_file(this->filename_, Linemap::unknown_location(),
+  >data_))
 return false;
   if (this->data_.empty())
 {
@@ -849,7 +850,7 @@ Gogo::initializer_for_embeds(Type* type,
}
 
   std::string data;
-  if (!read_file(this->embed_files_[paths[0]].c_str(), loc, ))
+  if (!Gogo::read_file(this->embed_files_[paths[0]].c_str(), loc, ))
return Expression::make_error(loc);
 
   Expression* e = Expression::make_string(data, loc);
@@ -909,7 +910,7 @@ Gogo::initializer_for_embeds(Type* type,
   std::string data;
   if ((*pp)[pp->size() - 1] != '/')
{
- if (!read_file(this->embed_files_[*pp].c_str(), loc, ))
+ if 

Go patch committed: Support bootstrapping Go 1.21

2023-06-23 Thread Ian Lance Taylor via Gcc-patches
compiler, libgo: support bootstrapping gc compiler

In the Go 1.21 release the package internal/profile imports
internal/lazyregexp.  That works when bootstrapping with Go 1.17,
because that compiler has internal/lazyregep and permits importing it.
We also have internal/lazyregexp in libgo, but since it is not
installed it is not available for importing.  This patch adds
internal/lazyregexp to the list of internal packages that are
installed for bootstrapping.

The Go 1.21, and earlier, releases have a couple of functions in the
internal/abi package that are always fully intrinsified.  The Go
frontend recognizes and intrinsifies those functions as well.
However, the Go frontend was also building function descriptors for
references to the functions without calling them, which failed because
there was nothing to refer to.  That is OK for the gc compiler, which
guarantees that the functions are only called, not referenced.  This
patch arranges to not generate function descriptors for these
functions.

This helps address https://go.dev/issue/60913.

Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline and GCC 12 and 13 branches.

Ian
2ad5553091d8afbc21bbd3a29a419df359e7aacc
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index a028350ba8e..ff07b1a1fa6 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-195060166e6045408a2cb95e6aa88c6f0b98f20b
+68a756b6aadc901534cfad2b1e73fae9e34f
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 2112de6abfc..d276bd811cc 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -12272,7 +12272,8 @@ Call_expression::intrinsify(Gogo* gogo,
   return Runtime::make_call(code, loc, 3, a1, a2, a3);
 }
 }
-  else if (package == "internal/abi")
+  else if (package == "internal/abi"
+  || package == "bootstrap/internal/abi") // for bootstrapping gc
 {
   if (is_method)
return NULL;
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 9197eef3e38..980db1ea07e 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -3296,6 +3296,9 @@ class Create_function_descriptors : public Traverse
   int
   expression(Expression**);
 
+  static bool
+  skip_descriptor(Gogo* gogo, const Named_object*);
+
  private:
   Gogo* gogo_;
 };
@@ -3306,6 +3309,9 @@ class Create_function_descriptors : public Traverse
 int
 Create_function_descriptors::function(Named_object* no)
 {
+  if (Create_function_descriptors::skip_descriptor(this->gogo_, no))
+return TRAVERSE_CONTINUE;
+
   if (no->is_function()
   && no->func_value()->enclosing() == NULL
   && !no->func_value()->is_method()
@@ -3393,6 +3399,28 @@ Create_function_descriptors::expression(Expression** 
pexpr)
   return TRAVERSE_CONTINUE;
 }
 
+// The gc compiler has some special cases that it always compiles as
+// intrinsics.  For those we don't want to generate a function
+// descriptor, as there will be no code for it to refer to.
+
+bool
+Create_function_descriptors::skip_descriptor(Gogo* gogo,
+const Named_object* no)
+{
+  const std::string& pkgpath(no->package() == NULL
+? gogo->pkgpath()
+: no->package()->pkgpath());
+
+  // internal/abi is the standard library package,
+  // bootstrap/internal/abi is the name used when bootstrapping the gc
+  // compiler.
+
+  return ((pkgpath == "internal/abi"
+  || pkgpath == "bootstrap/internal/abi")
+ && (no->name() == "FuncPCABI0"
+ || no->name() == "FuncPCABIInternal"));
+}
+
 // Create function descriptors as needed.  We need a function
 // descriptor for all exported functions and for all functions that
 // are referenced without being called.
@@ -3414,7 +3442,8 @@ Gogo::create_function_descriptors()
   if (no->is_function_declaration()
  && !no->func_declaration_value()->type()->is_method()
  && !Linemap::is_predeclared_location(no->location())
- && !Gogo::is_hidden_name(no->name()))
+ && !Gogo::is_hidden_name(no->name())
+ && !Create_function_descriptors::skip_descriptor(this, no))
fndecls.push_back(no);
 }
   for (std::vector::const_iterator p = fndecls.begin();
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index 920f8cc7071..c95dc2106cd 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -417,6 +417,7 @@ toolexeclibgounicode_DATA = \
 # Some internal packages are needed to bootstrap the gc toolchain.
 toolexeclibgointernaldir = $(toolexeclibgodir)/internal
 toolexeclibgointernal_DATA = \
+   internal/lazyregexp.gox \
internal/reflectlite.gox \
internal/unsafeheader.gox
 
diff --git a/libgo/go/internal/abi/abi.go 

Re: [PATCH 1/2] go: update usage of TARGET_AIX to TARGET_AIX_OS

2023-06-22 Thread Ian Lance Taylor via Gcc-patches
On Thu, Jun 22, 2023, 4:47 PM Peter Bergner  wrote:

> On 6/22/23 6:37 PM, Peter Bergner via Gcc-patches wrote:
> > On 6/16/23 12:01 PM, Ian Lance Taylor via Gcc-patches wrote:
> >> On Fri, Jun 16, 2023 at 9:00 AM Paul E. Murphy via Gcc-patches
> >>  wrote:
> >>>
> >>> TARGET_AIX is defined to a non-zero value on linux and maybe other
> >>> powerpc64le targets.  This leads to unexpected behavior such as
> >>> dropping the .go_export section when linking a shared library
> >>> on linux/powerpc64le.
> >>>
> >>> Instead, use TARGET_AIX_OS to toggle AIX specific behavior.
> >>>
> >>> Fixes golang/go#60798.
> >>>
> >>> gcc/go/ChangeLog:
> >>>
> >>> * go-backend.cc [TARGET_AIX]: Rename and update usage to
> >>> TARGET_AIX_OS.
> >>> * go-lang.cc: Likewise.
> >>
> >> This is OK.
> >>
> >> Thanks.
> >>
> >> Ian
> >
> > I pushed this to trunk for Paul.
>
> I see this is broken on the release branches too.  Are backports ok
> after some burn-in on trunk?
>

Yes.  Thanks.

Ian

>


Go patch committed: Determine types of Slice_{value, info} expressions

2023-06-21 Thread Ian Lance Taylor via Gcc-patches
This patch to the Go frontend determines the types of a couple of
expressions types that accidentally failed to recurse into their
subexpressions.  The test case for this is https://go.dev/cl/505015.
Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

Ian
f42544e04a131cee886cb7cdc65df1e2f09baf8c
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index dbb2d68f909..a028350ba8e 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-6a1d165c2218cd127ee937a1f45599075762f716
+195060166e6045408a2cb95e6aa88c6f0b98f20b
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 4ac55af7433..2112de6abfc 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -18307,6 +18307,16 @@ Slice_value_expression::do_traverse(Traverse* traverse)
   return TRAVERSE_CONTINUE;
 }
 
+// Determine type of a slice value.
+
+void
+Slice_value_expression::do_determine_type(const Type_context*)
+{
+  this->valmem_->determine_type_no_context();
+  this->len_->determine_type_no_context();
+  this->cap_->determine_type_no_context();
+}
+
 Expression*
 Slice_value_expression::do_copy()
 {
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index 3d7e78711bd..bdb7ccd010d 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -4364,8 +4364,7 @@ class Slice_value_expression : public Expression
   { return this->type_; }
 
   void
-  do_determine_type(const Type_context*)
-  { }
+  do_determine_type(const Type_context*);
 
   Expression*
   do_copy();
@@ -4419,7 +4418,7 @@ class Slice_info_expression : public Expression
 
   void
   do_determine_type(const Type_context*)
-  { }
+  { this->slice_->determine_type_no_context(); }
 
   Expression*
   do_copy()


Merge from trunk to gccgo branch

2023-06-21 Thread Ian Lance Taylor via Gcc-patches
I merged trunk revision 577223aebc7acdd31e62b33c1682fe54a622ae27 to
the gccgo branch.

Ian


Re: libgo patch committed: Use a C function to call mmap

2023-06-20 Thread Ian Lance Taylor via Gcc-patches
On Tue, Jun 20, 2023 at 11:35 AM Andreas Schwab  wrote:
>
> On Jun 20 2023, Ian Lance Taylor via Gcc-patches wrote:
>
> > This libgo patches changes the runtime pacakge to use a C function to call 
> > mmap.
> >
> > The final argument to mmap, of type off_t, varies. In
> > https://go.dev/cl/445375
> > (https://gcc.gnu.org/pipermail/gcc-patches/2022-October/604158.html)
> > we changed it to always use the C off_t type, but that broke 32-bit
> > big-endian Linux systems.
>
> This has nothing to do with big-endian, armv7 isn't big-endian.

OK, but I think that it does have something to do with big-endian.
The bug was that on some 32-bit systems it was passing a 64-bit value
to a function that expected a 32-bit value.  The problem didn't show
up on 32-bit x86 because it is little-endian, and did show up on
32-bit PPC because it is big-endian.  I guess the armv7 case was
failing for a different reason.

Ian


libgo patch committed: Use a C function to call mmap

2023-06-20 Thread Ian Lance Taylor via Gcc-patches
This libgo patches changes the runtime pacakge to use a C function to call mmap.

The final argument to mmap, of type off_t, varies. In
https://go.dev/cl/445375
(https://gcc.gnu.org/pipermail/gcc-patches/2022-October/604158.html)
we changed it to always use the C off_t type, but that broke 32-bit
big-endian Linux systems.  On those systems, using the C off_t type
requires calling the mmap64 function.  In C this is automatically
handled by the  file.  In Go, we would have to change the
magic //extern comment to call mmap64 when appropriate.  Rather than
try to get that right, we instead go through a C function that uses C
implicit type conversions to pick the right type.

This fixes https://gcc.gnu.org/PR110297.

Bootstrapped and tested on x86_64-pc-linux-gnu and
powerpc-pc-linux-gnu (32-bit and 64-bit).  Committed to trunk and GCC
13 branch.

Ian
7f5a6c8a27190daf9daadf5e9f14ef5f4ece
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 1191a8d663d..dbb2d68f909 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-a3a3c3a2d1bc6a8ca51b302d08c94ef27cdd8f0f
+6a1d165c2218cd127ee937a1f45599075762f716
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index 207d5a98127..920f8cc7071 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -462,6 +462,7 @@ runtime_files = \
runtime/go-memclr.c \
runtime/go-memmove.c \
runtime/go-memequal.c \
+   runtime/go-mmap.c \
runtime/go-nanotime.c \
runtime/go-now.c \
runtime/go-nosys.c \
diff --git a/libgo/go/runtime/mem_gccgo.go b/libgo/go/runtime/mem_gccgo.go
index 1e84f4f5c56..e7b51ff37cc 100644
--- a/libgo/go/runtime/mem_gccgo.go
+++ b/libgo/go/runtime/mem_gccgo.go
@@ -14,8 +14,8 @@ import (
 //go:linkname sysAlloc
 //go:linkname sysFree
 
-//extern mmap
-func sysMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off 
_libgo_off_t_type) unsafe.Pointer
+//extern __go_mmap
+func sysMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off 
uintptr) unsafe.Pointer
 
 //extern munmap
 func munmap(addr unsafe.Pointer, length uintptr) int32
@@ -38,7 +38,7 @@ func init() {
 }
 
 func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uintptr) 
(unsafe.Pointer, int) {
-   p := sysMmap(addr, n, prot, flags, fd, _libgo_off_t_type(off))
+   p := sysMmap(addr, n, prot, flags, fd, off)
if uintptr(p) == _MAP_FAILED {
return nil, errno()
}
diff --git a/libgo/runtime/go-mmap.c b/libgo/runtime/go-mmap.c
new file mode 100644
index 000..b2327ba68f5
--- /dev/null
+++ b/libgo/runtime/go-mmap.c
@@ -0,0 +1,21 @@
+/* go-mmap.c -- functions for calling C mmap functions.
+
+   Copyright 2023 The Go Authors. All rights reserved.
+   Use of this source code is governed by a BSD-style
+   license that can be found in the LICENSE file.  */
+
+#include "config.h"
+
+#include 
+#include 
+
+/* The exact C function to call varies between mmap and mmap64, and
+   the size of the off_t argument also varies.  Here we provide a
+   function that Go code can call with consistent types.  */
+
+void *
+__go_mmap(void *addr, uintptr_t length, int32_t prot, int32_t flags,
+ int32_t fd, uintptr_t offset)
+{
+  return mmap(addr, length, prot, flags, fd, offset);
+}
diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h
index b3dc4fd2414..699770d53ad 100644
--- a/libgo/runtime/runtime.h
+++ b/libgo/runtime/runtime.h
@@ -355,9 +355,6 @@ boolruntime_notetsleepg(Note*, int64)  // false - 
timeout
 /*
  * low level C-called
  */
-#define runtime_mmap mmap
-#define runtime_munmap munmap
-#define runtime_madvise madvise
 #define runtime_memclr(buf, size) __builtin_memset((buf), 0, (size))
 #define runtime_getcallerpc() __builtin_return_address(0)
 


libgo patch committed: Add benchmarks and examples to test list

2023-06-16 Thread Ian Lance Taylor via Gcc-patches
In https://go.dev/cl/384695
(https://gcc.gnu.org/pipermail/gcc-patches/2022-February/590289.html)
I simplified the code that built lists of benchmarks, examples, and
fuzz tests, and managed to break it. This patch corrects the code to
once again make the benchmarks available, and to run the examples with
output and the fuzz targets.

Doing this revealed a test failure in internal/fuzz on 32-bit x86: a
signalling NaN is turned into a quiet NaN on the 387 floating-point
stack that GCC uses by default. This CL skips the test.

This fixes https://go.dev/issue/60826.

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

Ian
bc6bd0d608da1609c1caeb04ab795a83720add55
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 702257009d2..1191a8d663d 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-737de90a63002d4872b19772a7116404ee5815b4
+a3a3c3a2d1bc6a8ca51b302d08c94ef27cdd8f0f
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/go/internal/fuzz/encoding_test.go 
b/libgo/go/internal/fuzz/encoding_test.go
index 8e3800eb77f..53fc5b8dc71 100644
--- a/libgo/go/internal/fuzz/encoding_test.go
+++ b/libgo/go/internal/fuzz/encoding_test.go
@@ -6,6 +6,7 @@ package fuzz
 
 import (
"math"
+   "runtime"
"strconv"
"testing"
"unicode"
@@ -330,6 +331,14 @@ func FuzzFloat64RoundTrip(f *testing.F) {
f.Add(math.Float64bits(math.Inf(-1)))
 
f.Fuzz(func(t *testing.T, u1 uint64) {
+   // The signaling NaN test fails on 32-bit x86 with gccgo,
+   // which uses the 387 floating-point stack by default.
+   // Converting a signaling NaN in and out of the stack
+   // changes the NaN to a quiet NaN.
+   if runtime.GOARCH == "386" && u1 == 0x7FF1 {
+   t.Skip("skipping signalling NaN test on 386 with gccgo")
+   }
+
x1 := math.Float64frombits(u1)
 
b := marshalCorpusFile(x1)
diff --git a/libgo/testsuite/gotest b/libgo/testsuite/gotest
index 0a0a7e14d74..33c98d804d6 100755
--- a/libgo/testsuite/gotest
+++ b/libgo/testsuite/gotest
@@ -577,13 +577,13 @@ symtogo() {
 # Find Go benchmark/fuzz/example functions.
 # The argument is the function name prefix.
 findfuncs() {
-   pattern='$1([^a-z].*)?'
+   pattern="$1([^a-z].*)?"
syms=$($NM -p -v _gotest_.o | egrep " $text .*\."$pattern'$' | fgrep -v 
' __go_' | egrep -v '\.\.\w+$' | sed 's/.* //')
if $havex; then
xsyms=$($NM -p -v $xofile | egrep " $text .*\."$pattern'$' | fgrep 
-v ' __go_' | egrep -v '\.\.\w+$' | sed 's/.* //')
syms="$syms $xsyms"
fi
-$(symtogo "$benchmarksyms")
+symtogo "$syms"
 }
 
 # Takes an example name and puts any output into the file example.txt.
@@ -643,11 +643,13 @@ exampleoutput() {
fi
if $havex; then
needxtest=false
-   if test -n "$testxsyms" -o -n "$benchmarkxsyms"; then
+   if test -n "$testxsyms"; then
+   needxtest=true
+   elif echo "$benchmarks" | grep '_test\.' >/dev/null; then
needxtest=true
else
# Check whether any example has output.
-   for i in $(symtogo "$examplexsyms"); do
+   for i in $(echo "$examples" | grep '_test\.'); do
exampleoutput $i
if test -f example.txt; then
rm -f example.txt


Re: [PATCH 1/2] go: update usage of TARGET_AIX to TARGET_AIX_OS

2023-06-16 Thread Ian Lance Taylor via Gcc-patches
On Fri, Jun 16, 2023 at 9:00 AM Paul E. Murphy via Gcc-patches
 wrote:
>
> TARGET_AIX is defined to a non-zero value on linux and maybe other
> powerpc64le targets.  This leads to unexpected behavior such as
> dropping the .go_export section when linking a shared library
> on linux/powerpc64le.
>
> Instead, use TARGET_AIX_OS to toggle AIX specific behavior.
>
> Fixes golang/go#60798.
>
> gcc/go/ChangeLog:
>
> * go-backend.cc [TARGET_AIX]: Rename and update usage to
> TARGET_AIX_OS.
> * go-lang.cc: Likewise.

This is OK.

Thanks.

Ian


Re: When do I need -fnon-call-exceptions?

2023-06-07 Thread Ian Lance Taylor via Gcc
On Wed, Jun 7, 2023 at 10:09 AM Helmut Zeisel via Gcc  wrote:
>
> I wrote some simple program that set a signal handler for SIGFPE, throws a 
> C++ exception in the signal handler
> and catches the exception.
> I compiled with and without -fnon-call-exceptions (on x64 Linux).
> In both cases, the result was the same: the exception was caught and the 
> destructors were called as expected.
> I also tried "-fno-non-call-exceptions -fexceptions" and got the same result.
>
> My question: when do I really need -fnon-call-exceptions?
> Is there some simple program where I can see the difference whether it is on 
> or off??

On x864 Linux -fasynchronous-unwind-tables is the default.  That is
probably sufficient to make your test case work.

Ian


Re: [PATCH] libgcc: Use initarray section type for .init_stack

2023-05-31 Thread Ian Lance Taylor via Gcc-patches
On Wed, May 31, 2023 at 12:41 AM Kewen.Lin via Gcc-patches
 wrote:
>
> >> libgcc/ChangeLog:
> >>
> >>  * config/i386/morestack.S: Use @init_array rather than
> >>  @progbits for section type of section .init_array.
> >>  * config/rs6000/morestack.S: Likewise.
> >>  * config/s390/morestack.S: Likewise.
> >
> > s390 parts are ok. I did run a bootstrap and regression. Looks all good. 
> > Thanks!
>
> Thanks for testing this on s390, really appreciate!
>
> Hi Ian & Uros,
>
> Do you have any concerns on this, or does it look good to you?

This is OK.

Thanks.

Ian


libgo patch committed: Add syscall.prlimit

2023-05-11 Thread Ian Lance Taylor via Gcc-patches
As of https://go.dev/cl/476695 the package golang.org/x/sys/unix
expects a syscall.prlimit function to exist.  This libgo patch adds
that function.  This is for https://go.dev/issue/46279 and
https://go.dev/issue/59712.  Since this is a small patch and is needed
to compile the widely used x/sys/unix package, committed to tip and to
GCC 11, 12, and 13 branches.

Ian
ba8160449c646138a3a9e1723ac1db0716a8b103
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index e133650ad91..702257009d2 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-0411a2733fd468e69f1998edd91e8fe3ba40ff9e
+737de90a63002d4872b19772a7116404ee5815b4
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/go/syscall/libcall_linux.go 
b/libgo/go/syscall/libcall_linux.go
index 19ae4393cf1..03ca7261b59 100644
--- a/libgo/go/syscall/libcall_linux.go
+++ b/libgo/go/syscall/libcall_linux.go
@@ -189,6 +189,14 @@ func Gettid() (tid int) {
 //sys  PivotRoot(newroot string, putold string) (err error)
 //pivot_root(newroot *byte, putold *byte) _C_int
 
+// Used by golang.org/x/sys/unix.
+//sys  prlimit(pid int, resource int, newlimit *Rlimit, oldlimit *Rlimit) (err 
error)
+//prlimit(pid Pid_t, resource _C_int, newlimit *Rlimit, oldlimit *Rlimit) 
_C_int
+
+func Prlimit(pid int, resource int, newlimit *Rlimit, oldlimit *Rlimit) error {
+   return prlimit(pid, resource, newlimit, oldlimit)
+}
+
 //sys  Removexattr(path string, attr string) (err error)
 //removexattr(path *byte, name *byte) _C_int
 


Re: More C type errors by default for GCC 14

2023-05-09 Thread Ian Lance Taylor via Gcc
On Tue, May 9, 2023 at 9:45 AM Florian Weimer via Gcc  wrote:
>
> The part David quoted above is about this:
>
> $ gcc -fno-gnu89-inline -std=gnu89 t.c
> cc1: error: ‘-fno-gnu89-inline’ is only supported in GNU99 or C99 mode
>
> And some packages need -fno-gnu89-inline, but also rely on implicit ints
> and implicit function declarations heavily.  With a purely C89-based
> opt-out and the -fno-gnu89-inline limitation, we wouldn't have a way to
> compile these self-contradictory programs.  Hence the idea of
> -fpermissive, in addition to the -std=gnu89 escape hatch.
>
> But perhaps the -fno-gnu89-inline limitation is easy to eliminate.  The
> remaining reason for -fpermissive would be a flag that is accepted by
> both gcc and g++, in case a package build system passes CFLAGS to g++ as
> well, which sometimes happens.  And -fno-gnu89-inline is currently not
> accepted by g++.  But in the Fedora package set, this (some C++ and a
> C89 requirement) must be exceedingly rare because it's a subset of the
> already tiny set of -fno-gnu89-inline -std=gnu89 packages.

I think I wrote that error, back in 2007, because I thought it was odd
to rely on the C99 semantics for inline functions when not using C99.
And to encourage people to move to C99.  But I wouldn't be surprised
if the compiler just works without the error.  It would just require
adding a few test cases similar to gcc.dg/inline-18.c through
inline-21.c (well, inline-21.c would have to be removed or rewritten).

Ian


libgo patch committed: Remove test ordering dependency in mime

2023-04-07 Thread Ian Lance Taylor via Gcc-patches
This libgo patch removes a test ordering dependency in the mime
package.  This is a backport of https://go.dev/cl/421442 from the
upstream repo.  This fixes https://go.dev/issue/51648.  Bootstrapped
and ran mime tests on x86_64-pc-linux-gnu.  Committed to mainline.

Ian
f22c12d7361d22d47cce73d342edf2e1ebf20520
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index addef6f8f51..e133650ad91 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-63ba7dd52f2cc49dab4b70ac81309296a920d4dc
+0411a2733fd468e69f1998edd91e8fe3ba40ff9e
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/go/mime/type_test.go b/libgo/go/mime/type_test.go
index 5e4d25cc872..5769c6a55de 100644
--- a/libgo/go/mime/type_test.go
+++ b/libgo/go/mime/type_test.go
@@ -14,7 +14,10 @@ import (
 func setMimeInit(fn func()) (cleanup func()) {
once = sync.Once{}
testInitMime = fn
-   return func() { testInitMime = nil }
+   return func() {
+   testInitMime = nil
+   once = sync.Once{}
+   }
 }
 
 func clearMimeTypes() {
diff --git a/libgo/go/mime/type_unix_test.go b/libgo/go/mime/type_unix_test.go
index 4d109aa71a2..43db44b7aa1 100644
--- a/libgo/go/mime/type_unix_test.go
+++ b/libgo/go/mime/type_unix_test.go
@@ -11,6 +11,7 @@ import (
 )
 
 func initMimeUnixTest(t *testing.T) {
+   once.Do(initMime)
err := loadMimeGlobsFile("testdata/test.types.globs2")
if err != nil {
t.Fatal(err)


Merge from trunk to gccgo branch

2023-03-29 Thread Ian Lance Taylor via Gcc-patches
I merged trunk revision aa8f4242efc99f24de73c59d53996f28db28c13f to
the gccgo branch.

Ian


Go patch committed: Mark Call_expression multi-results as result struct

2023-03-28 Thread Ian Lance Taylor via Gcc-patches
This patch to the Go frontend marks a Call_expression multiple results
struct as a result struct.  In https://go.dev/cl/343873 we stopped
padding zero-sized trailing fields in functions that return multiple
results where the last result is zero-sized. This CL makes the
corresponding change on the caller side.

The test case is https://go.dev/cl/479898.

This fixes https://go.dev/issue/55242.

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

Ian
c8e7c9c973e6b0b3a3a061619831bc5df371f2ef
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 8c8025dec2e..addef6f8f51 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-9ffd6e679ff0e3a908d0ec2ed5c6efa1de827c3f
+63ba7dd52f2cc49dab4b70ac81309296a920d4dc
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 53901306ef7..4ac55af7433 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -11267,6 +11267,7 @@ Call_expression::do_lower(Gogo* gogo, Named_object* 
function,
 
   Struct_type* st = Type::make_struct_type(sfl, loc);
   st->set_is_struct_incomparable();
+  st->set_is_results_struct();
   this->call_temp_ = Statement::make_temporary(st, NULL, loc);
   inserter->insert(this->call_temp_);
 }


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;


Go patch committed: Add missing Slice_info_expression::do_traverse

2023-03-22 Thread Ian Lance Taylor via Gcc-patches
This patch to the Go frontend adds the missing
Slice_info_expression::do_traverse method.  Lack of the method caused
https://go.dev/issue/59169.  The test case is
https://go.dev/cl/478217.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline and GCC 12 branch.

Ian
187edaf5e88b548db4e6790b723be1f8d1dab2d5
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 4a1a4c8c021..8c8025dec2e 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-8c786f716c58d7973623c2b9293e2ad360877817
+9ffd6e679ff0e3a908d0ec2ed5c6efa1de827c3f
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index a1e3733aa1d..3d7e78711bd 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -4410,6 +4410,10 @@ class Slice_info_expression : public Expression
   { return this->slice_info_; }
 
  protected:
+  int
+  do_traverse(Traverse* traverse)
+  { return Expression::traverse(>slice_, traverse); }
+
   Type*
   do_type();
 


Add notes for Go to gcc 12 and 13 changes file

2023-03-20 Thread Ian Lance Taylor via Gcc-patches
I committed this patch to the gcc-wwwdocs repo to add some notes about
Go to the gcc 12 and 13 changes file.

Ian

pat
e24f9ef56c11c69fc07bddf9a708ea2fc662f2b3
diff --git a/htdocs/gcc-12/changes.html b/htdocs/gcc-12/changes.html
index c47d3285..d565c217 100644
--- a/htdocs/gcc-12/changes.html
+++ b/htdocs/gcc-12/changes.html
@@ -618,7 +618,14 @@ function Multiply (S1, S2 : Sign) return Sign is
   
 
 
-
+Go
+
+
+  GCC 12 provides a complete implementation of the Go 1.18 user
+packages.
+  Although Go 1.18 includes support for generic programming, that
+support is not yet available in GCC.
+
 
 
 libgccjit
diff --git a/htdocs/gcc-13/changes.html b/htdocs/gcc-13/changes.html
index a4b71ffa..4fae1f7a 100644
--- a/htdocs/gcc-13/changes.html
+++ b/htdocs/gcc-13/changes.html
@@ -380,7 +380,14 @@ a work-in-progress.
   
 
 
-
+Go
+
+
+  GCC 13, like GCC 12, provides a complete implementation of the
+Go 1.18 user packages.
+  Although Go 1.18 includes support for generic programming, that
+support is not yet available in GCC.
+
 
 Modula-2
 


Re: Now gcc-13: [Fwd: [PATCH] gcc-12: Re-enable split-stack support for GNU/Hurd.]

2023-03-15 Thread Ian Lance Taylor via Gcc-patches
On Wed, Mar 15, 2023 at 9:14 AM Svante Signell  wrote:
>
> Package: gcc-snapshot
> Version: 1:20230315-1
> Severity: important
> Tags: patch
> User: debian-h...@lists.debian.org
> Usertags: hurd
> Affects: gcc-snapshot
> X-Debbugs-CC: debian-h...@lists.debian.org
>
> Hello, seems like the patch gcc_config_gnu.h.diff, in debian gcc-12 named:
> pr104290-followup.diff was lost (again).
>
> How can this patch ever become upstreamed??
>
> It seems like sending to gcc-patches is not enough. Create a regression bug?
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104290 is already reported as a
> regression, it has to be updated to cover upstream releases of gcc-13 now.
>
> For gcc-12 Debian has been carrying it as:
> pr104290-followup.diff
>
> Submitting this problem as new bug to Debian/gcc-13/gcc-snapshot!
>
> Thanks!
>
>
>
> -- Forwarded message --
> From: Svante Signell 
> To: gcc-patches 
> Cc: Ian Lance Taylor , Matthias Klose 
> Bcc:
> Date: Wed, 23 Feb 2022 11:13:50 +0100
> Subject: [PATCH] gcc-12: Re-enable split-stack support for GNU/Hurd.
> Hello,
>
> In line of porting the latest build of libgo/go with gcc-12 to GNU/Hurd, 
> support
> of split-stack was found to be removed.
>
> After patching the files in libgo the build of gotools fails:
> go1: error: '-fsplit-stack' currently only supported on GNU/Linux
> go1: error: '-fsplit-stack' is not supported by this compiler configuration
>
> The attached patch defines OPTION_GLIBC_P(opts) and OPTION_GLIBC that was lost
> in config/gnu.h, needed to enable split-stack support for GNU/Hurd.
>
> This problem happened with the latest commit as discussed in the mail thread
> starting with 
> https://gcc.gnu.org/pipermail/gcc-patches/2022-January/588973.html
> .
>
> The file first doing this check is: (first error: ..)
> src/gcc/common/config/i386/i386-common.cc
> in function:
> static bool ix86_supports_split_stack (bool report,
> struct gcc_options *opts ATTRIBUTE_UNUSED)
>
> and secondly in:src/gcc/opts.cc: (second error: ...)
> in function:
> void
> finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
> location_t loc)
>
> The checking logic is in function ix86_supports_split_stack():
> #if defined(TARGET_THREAD_SPLIT_STACK_OFFSET) && defined(OPTION_GLIBC_P)
>   if (!OPTION_GLIBC_P (opts))
> #endif
> {
>   if (report)
> error ("%<-fsplit-stack%> currently only supported on GNU/Linux");
>   return false;
> }
>
>   bool ret = true;
>
> In case of GNU/Hurd TARGET_THREAD_SPLIT_STACK_OFFSET is defined as well as
> OPTION_GLIBC_P but OPTION_GLIBC_P(opts) is needed to. The attached patch to
> src/gcc/config/gnu.h creates that definition. For GNU/Hurd, gnu.h is included 
> in
> the configure stage:
> Configuring stage 1 in ./gcc
> ...
> Using the following target machine macro files:
> ...
> ../../src/gcc/config/gnu.h
>
> For a longer history about this bug see:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104290
>
> Additionally, I would propose the text in 
> gcc/common/config/i386/i386-common.cc
> to change from:
> error ("%<-fsplit-stack%> currently only supported on GNU/Linux");
> to:
> error ("%<-fsplit-stack%> currently only supported on GLIBC-based systems");


If GNU/Hurd requires glibc, then I think it would be simpler to define
OPTION_GLIBC and OPTION_GLIBC_P as true.

Adding Thomas Schwinge as the GNU/Hurd maintainer.

Ian


Re: [PATCH] Always define `WIN32_LEAN_AND_MEAN` before

2023-03-05 Thread Ian Lance Taylor via Gcc-patches
On Fri, Mar 3, 2023 at 10:47 PM Xi Ruoyao  wrote:
>
> On Sat, 2023-01-07 at 06:52 +, Jonathan Yong via Gcc-patches wrote:
> > On 1/6/23 18:10, Jakub Jelinek wrote:
> > > On Sat, Jan 07, 2023 at 02:01:05AM +0800, LIU Hao via Gcc-patches
> > > wrote:
> > > > libgomp/
> > > >
> > > > PR middle-end/108300
> > > > * config/mingw32/proc.c: Define `WIN32_LEAN_AND_MEAN`
> > > > before
> > > > .
> > >
> > > This change is ok for trunk.
> > >
> > > Jakub
> > >
> >
> > Pushed to master branch, thanks LH.
>
> The patch touches libgo (w/o mentioning it in the ChangeLog).  I guess
> you need to contribute the libgo part into the upstream Go runtime or
> the change will be undone when Ian merges libgo next time.

Thanks, I've reverted the part of the patch that applies to libgo.

It's not worth changing upstream because gccgo doesn't support Windows
anyhow, and because that change is gone in the even-more-upstream
sources.

Ian


Re: [PATCH 2/4] libbacktrace: detect executable path on windows

2023-02-05 Thread Ian Lance Taylor via Gcc
On Sun, Feb 5, 2023 at 1:21 AM Björn Schäpers  wrote:
>
> Am 24.01.2023 um 19:32 schrieb Ian Lance Taylor:
> > On Tue, Jan 24, 2023 at 10:12 AM Eli Zaretskii via Gcc-patches
> >  wrote:
> >>
> >>> From: Ian Lance Taylor 
> >>> Date: Tue, 24 Jan 2023 09:58:10 -0800
> >>> Cc: g...@hazardy.de, gcc-patc...@gcc.gnu.org, gcc@gcc.gnu.org
> >>>
> >>> I'd rather that the patch look like the appended.  Can someone with a
> >>> Windows system test to see what that builds and passes the tests?
> >>
> >> ENOPATCH
> >
> > Gah.
> >
> > Ian
> >
> That seems to be my original patch, right? That one I have tested (and
> am actually using) on x86 and x64 windows.

It's very similar but I changed the windows_get_executable_path function.

Ian


Re: [PATCH 2/4] libbacktrace: detect executable path on windows

2023-02-05 Thread Ian Lance Taylor via Gcc-patches
On Sun, Feb 5, 2023 at 1:21 AM Björn Schäpers  wrote:
>
> Am 24.01.2023 um 19:32 schrieb Ian Lance Taylor:
> > On Tue, Jan 24, 2023 at 10:12 AM Eli Zaretskii via Gcc-patches
> >  wrote:
> >>
> >>> From: Ian Lance Taylor 
> >>> Date: Tue, 24 Jan 2023 09:58:10 -0800
> >>> Cc: g...@hazardy.de, gcc-patches@gcc.gnu.org, g...@gcc.gnu.org
> >>>
> >>> I'd rather that the patch look like the appended.  Can someone with a
> >>> Windows system test to see what that builds and passes the tests?
> >>
> >> ENOPATCH
> >
> > Gah.
> >
> > Ian
> >
> That seems to be my original patch, right? That one I have tested (and
> am actually using) on x86 and x64 windows.

It's very similar but I changed the windows_get_executable_path function.

Ian


Re: [PATCH 2/4] libbacktrace: detect executable path on windows

2023-01-24 Thread Ian Lance Taylor via Gcc
On Tue, Jan 24, 2023 at 10:12 AM Eli Zaretskii via Gcc-patches
 wrote:
>
> > From: Ian Lance Taylor 
> > Date: Tue, 24 Jan 2023 09:58:10 -0800
> > Cc: g...@hazardy.de, gcc-patc...@gcc.gnu.org, gcc@gcc.gnu.org
> >
> > I'd rather that the patch look like the appended.  Can someone with a
> > Windows system test to see what that builds and passes the tests?
>
> ENOPATCH

Gah.

Ian
diff --git a/libbacktrace/config.h.in b/libbacktrace/config.h.in
index 94621c2e385..29d1ad3911a 100644
--- a/libbacktrace/config.h.in
+++ b/libbacktrace/config.h.in
@@ -100,6 +100,9 @@
 /* Define to 1 if you have the  header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you have the  header file. */
+#undef HAVE_WINDOWS_H
+
 /* Define if -lz is available. */
 #undef HAVE_ZLIB
 
diff --git a/libbacktrace/configure b/libbacktrace/configure
index 6af2c04c81a..0a27cfb7799 100755
--- a/libbacktrace/configure
+++ b/libbacktrace/configure
@@ -13409,6 +13409,19 @@ $as_echo "#define HAVE_LOADQUERY 1" >>confdefs.h
 
 fi
 
+for ac_header in windows.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" 
"$ac_includes_default"
+if test "x$ac_cv_header_windows_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_WINDOWS_H 1
+_ACEOF
+
+fi
+
+done
+
+
 # Check for the fcntl function.
 if test -n "${with_target_subdir}"; then
case "${host}" in
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 39e6bf41e35..e3e10abd7b5 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -377,6 +377,8 @@ if test "$have_loadquery" = "yes"; then
   AC_DEFINE(HAVE_LOADQUERY, 1, [Define if AIX loadquery is available.])
 fi
 
+AC_CHECK_HEADERS(windows.h)
+
 # Check for the fcntl function.
 if test -n "${with_target_subdir}"; then
case "${host}" in
diff --git a/libbacktrace/fileline.c b/libbacktrace/fileline.c
index 674bf33cdcf..e110b54ee24 100644
--- a/libbacktrace/fileline.c
+++ b/libbacktrace/fileline.c
@@ -47,6 +47,18 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include 
 #endif
 
+#ifdef HAVE_WINDOWS_H
+#ifndef WIN32_MEAN_AND_LEAN
+#define WIN32_MEAN_AND_LEAN
+#endif
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+#include 
+#endif
+
 #include "backtrace.h"
 #include "internal.h"
 
@@ -155,6 +167,27 @@ macho_get_executable_path (struct backtrace_state *state,
 
 #endif /* !defined (HAVE_MACH_O_DYLD_H) */
 
+#ifdef HAVE_WINDOWS_H
+
+static char *
+windows_get_executable_path (char *buf, backtrace_error_callback 
error_callback,
+void *data)
+{
+  size_t got;
+
+  got = GetModuleFileNameA (NULL, buf, MAX_PATH - 1);
+  if (got == 0
+  || (got == MAX_PATH - 1 && GetLastError () == ERROR_INSUFFICIENT_BUFFER))
+return NULL;
+  return buf;
+}
+
+#else /* !defined (HAVE_WINDOWS_H) */
+
+#define windows_get_executable_path(buf, error_callback, data) NULL
+
+#endif /* !defined (HAVE_WINDOWS_H) */
+
 /* Initialize the fileline information from the executable.  Returns 1
on success, 0 on failure.  */
 
@@ -168,7 +201,11 @@ fileline_initialize (struct backtrace_state *state,
   int called_error_callback;
   int descriptor;
   const char *filename;
+#ifdef HAVE_WINDOWS_H
+  char buf[MAX_PATH];
+#else
   char buf[64];
+#endif
 
   if (!state->threaded)
 failed = state->fileline_initialization_failed;
@@ -192,7 +229,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;
 
@@ -224,6 +261,9 @@ fileline_initialize (struct backtrace_state *state,
case 7:
  filename = macho_get_executable_path (state, error_callback, data);
  break;
+   case 8:
+ filename = windows_get_executable_path (buf, error_callback, data);
+ break;
default:
  abort ();
}


Re: [PATCH 2/4] libbacktrace: detect executable path on windows

2023-01-24 Thread Ian Lance Taylor via Gcc-patches
On Tue, Jan 24, 2023 at 10:12 AM Eli Zaretskii via Gcc-patches
 wrote:
>
> > From: Ian Lance Taylor 
> > Date: Tue, 24 Jan 2023 09:58:10 -0800
> > Cc: g...@hazardy.de, gcc-patches@gcc.gnu.org, g...@gcc.gnu.org
> >
> > I'd rather that the patch look like the appended.  Can someone with a
> > Windows system test to see what that builds and passes the tests?
>
> ENOPATCH

Gah.

Ian
diff --git a/libbacktrace/config.h.in b/libbacktrace/config.h.in
index 94621c2e385..29d1ad3911a 100644
--- a/libbacktrace/config.h.in
+++ b/libbacktrace/config.h.in
@@ -100,6 +100,9 @@
 /* Define to 1 if you have the  header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you have the  header file. */
+#undef HAVE_WINDOWS_H
+
 /* Define if -lz is available. */
 #undef HAVE_ZLIB
 
diff --git a/libbacktrace/configure b/libbacktrace/configure
index 6af2c04c81a..0a27cfb7799 100755
--- a/libbacktrace/configure
+++ b/libbacktrace/configure
@@ -13409,6 +13409,19 @@ $as_echo "#define HAVE_LOADQUERY 1" >>confdefs.h
 
 fi
 
+for ac_header in windows.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" 
"$ac_includes_default"
+if test "x$ac_cv_header_windows_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_WINDOWS_H 1
+_ACEOF
+
+fi
+
+done
+
+
 # Check for the fcntl function.
 if test -n "${with_target_subdir}"; then
case "${host}" in
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 39e6bf41e35..e3e10abd7b5 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -377,6 +377,8 @@ if test "$have_loadquery" = "yes"; then
   AC_DEFINE(HAVE_LOADQUERY, 1, [Define if AIX loadquery is available.])
 fi
 
+AC_CHECK_HEADERS(windows.h)
+
 # Check for the fcntl function.
 if test -n "${with_target_subdir}"; then
case "${host}" in
diff --git a/libbacktrace/fileline.c b/libbacktrace/fileline.c
index 674bf33cdcf..e110b54ee24 100644
--- a/libbacktrace/fileline.c
+++ b/libbacktrace/fileline.c
@@ -47,6 +47,18 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include 
 #endif
 
+#ifdef HAVE_WINDOWS_H
+#ifndef WIN32_MEAN_AND_LEAN
+#define WIN32_MEAN_AND_LEAN
+#endif
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+#include 
+#endif
+
 #include "backtrace.h"
 #include "internal.h"
 
@@ -155,6 +167,27 @@ macho_get_executable_path (struct backtrace_state *state,
 
 #endif /* !defined (HAVE_MACH_O_DYLD_H) */
 
+#ifdef HAVE_WINDOWS_H
+
+static char *
+windows_get_executable_path (char *buf, backtrace_error_callback 
error_callback,
+void *data)
+{
+  size_t got;
+
+  got = GetModuleFileNameA (NULL, buf, MAX_PATH - 1);
+  if (got == 0
+  || (got == MAX_PATH - 1 && GetLastError () == ERROR_INSUFFICIENT_BUFFER))
+return NULL;
+  return buf;
+}
+
+#else /* !defined (HAVE_WINDOWS_H) */
+
+#define windows_get_executable_path(buf, error_callback, data) NULL
+
+#endif /* !defined (HAVE_WINDOWS_H) */
+
 /* Initialize the fileline information from the executable.  Returns 1
on success, 0 on failure.  */
 
@@ -168,7 +201,11 @@ fileline_initialize (struct backtrace_state *state,
   int called_error_callback;
   int descriptor;
   const char *filename;
+#ifdef HAVE_WINDOWS_H
+  char buf[MAX_PATH];
+#else
   char buf[64];
+#endif
 
   if (!state->threaded)
 failed = state->fileline_initialization_failed;
@@ -192,7 +229,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;
 
@@ -224,6 +261,9 @@ fileline_initialize (struct backtrace_state *state,
case 7:
  filename = macho_get_executable_path (state, error_callback, data);
  break;
+   case 8:
+ filename = windows_get_executable_path (buf, error_callback, data);
+ break;
default:
  abort ();
}


Re: [PATCH 2/4] libbacktrace: detect executable path on windows

2023-01-24 Thread Ian Lance Taylor via Gcc-patches
On Tue, Jan 24, 2023 at 8:53 AM Eli Zaretskii via Gcc-patches
 wrote:
>
> > From: Ian Lance Taylor 
> > Date: Tue, 24 Jan 2023 06:35:21 -0800
> > Cc: g...@hazardy.de, gcc-patches@gcc.gnu.org, g...@gcc.gnu.org
> >
> > > > On Windows it seems that MAX_PATH is not
> > > > a true limit, as an extended length path may be up to 32767 bytes.
> > >
> > > The limit of 32767 characters (not bytes, AFAIK) is only applicable
> > > when using the Unicode (a.k.a. "wide") versions of the Windows Win32
> > > APIs, see
> > >
> > >   
> > > https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
> > >
> > > Since the above code uses GetModuleFileNameA, which is an "ANSI"
> > > single-byte API, it is still subject to the MAX_PATH limitation, and
> > > MAX_PATH is defined as 260 on Windows headers.
> >
> > Thanks.  Should this code be using GetModuleFileNameW?  Or would that
> > mean that the later call to open will fail?
>
> We'd need to use _wopen or somesuch, and the file name will have to be
> a wchar_t array, not a char array, yes.  So this is not very practical
> when file names need to be passed between functions, unless they are
> converted to UTF-8 (and back again before using them in Windows APIs).
>
> And note that even then, the 260-byte limit could be lifted only if
> the user has a new enough Windows version _and_ has opted in to the
> long-name feature by turning it on in the Registry.  Otherwise, file
> names used in "wide" APIs can only break the 260-byte limit if they
> use the special format "\\?\D:\foo\bar", which means file names
> specified by user outside of the program or file names that come from
> other programs will need to be reformatted to this special format.
>
> > 260 bytes does not seem like very much for a path name these days.
>
> That's true.  But complications with using longer file names are still
> a PITA on Windows, even though they are a step closer to practically
> possible.


OK, thanks.

I'd rather that the patch look like the appended.  Can someone with a
Windows system test to see what that builds and passes the tests?
Thanks.

Ian


Re: [PATCH 2/4] libbacktrace: detect executable path on windows

2023-01-24 Thread Ian Lance Taylor via Gcc
On Tue, Jan 24, 2023 at 8:53 AM Eli Zaretskii via Gcc-patches
 wrote:
>
> > From: Ian Lance Taylor 
> > Date: Tue, 24 Jan 2023 06:35:21 -0800
> > Cc: g...@hazardy.de, gcc-patc...@gcc.gnu.org, gcc@gcc.gnu.org
> >
> > > > On Windows it seems that MAX_PATH is not
> > > > a true limit, as an extended length path may be up to 32767 bytes.
> > >
> > > The limit of 32767 characters (not bytes, AFAIK) is only applicable
> > > when using the Unicode (a.k.a. "wide") versions of the Windows Win32
> > > APIs, see
> > >
> > >   
> > > https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
> > >
> > > Since the above code uses GetModuleFileNameA, which is an "ANSI"
> > > single-byte API, it is still subject to the MAX_PATH limitation, and
> > > MAX_PATH is defined as 260 on Windows headers.
> >
> > Thanks.  Should this code be using GetModuleFileNameW?  Or would that
> > mean that the later call to open will fail?
>
> We'd need to use _wopen or somesuch, and the file name will have to be
> a wchar_t array, not a char array, yes.  So this is not very practical
> when file names need to be passed between functions, unless they are
> converted to UTF-8 (and back again before using them in Windows APIs).
>
> And note that even then, the 260-byte limit could be lifted only if
> the user has a new enough Windows version _and_ has opted in to the
> long-name feature by turning it on in the Registry.  Otherwise, file
> names used in "wide" APIs can only break the 260-byte limit if they
> use the special format "\\?\D:\foo\bar", which means file names
> specified by user outside of the program or file names that come from
> other programs will need to be reformatted to this special format.
>
> > 260 bytes does not seem like very much for a path name these days.
>
> That's true.  But complications with using longer file names are still
> a PITA on Windows, even though they are a step closer to practically
> possible.


OK, thanks.

I'd rather that the patch look like the appended.  Can someone with a
Windows system test to see what that builds and passes the tests?
Thanks.

Ian


Re: [PATCH 2/4] libbacktrace: detect executable path on windows

2023-01-24 Thread Ian Lance Taylor via Gcc
On Tue, Jan 24, 2023 at 5:11 AM Eli Zaretskii via Gcc-patches
 wrote:
>
> > Date: Mon, 23 Jan 2023 15:00:56 -0800
> > Cc: gcc-patc...@gcc.gnu.org, gcc@gcc.gnu.org
> > From: Ian Lance Taylor via Gcc 
> >
> > > +#ifdef HAVE_WINDOWS_H
> > > +
> > > +static char *
> > > +windows_get_executable_path (char *buf, backtrace_error_callback 
> > > error_callback,
> > > +void *data)
> > > +{
> > > +  if (GetModuleFileNameA (NULL, buf, MAX_PATH - 1) == 0)
> > > +{
> > > +  error_callback (data,
> > > + "could not get the filename of the current 
> > > executable",
> > > + (int) GetLastError ());
> > > +  return NULL;
> > > +}
> > > +  return buf;
> > > +}
> >
> > Thanks, but this seems incomplete.  The docs for GetModuleFileNameA
> > say that if the pathname is too long to fit into the buffer it returns
> > the size of the buffer and sets the error to
> > ERROR_INSUFFICIENT_BUFFER.  It seems to me that in that case we should
> > allocate a larger buffer and try again.
>
> This is correct in general, but not in this particular case.
>
> > On Windows it seems that MAX_PATH is not
> > a true limit, as an extended length path may be up to 32767 bytes.
>
> The limit of 32767 characters (not bytes, AFAIK) is only applicable
> when using the Unicode (a.k.a. "wide") versions of the Windows Win32
> APIs, see
>
>   
> https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
>
> Since the above code uses GetModuleFileNameA, which is an "ANSI"
> single-byte API, it is still subject to the MAX_PATH limitation, and
> MAX_PATH is defined as 260 on Windows headers.

Thanks.  Should this code be using GetModuleFileNameW?  Or would that
mean that the later call to open will fail?

260 bytes does not seem like very much for a path name these days.

Ian


Re: [PATCH 2/4] libbacktrace: detect executable path on windows

2023-01-24 Thread Ian Lance Taylor via Gcc-patches
On Tue, Jan 24, 2023 at 5:11 AM Eli Zaretskii via Gcc-patches
 wrote:
>
> > Date: Mon, 23 Jan 2023 15:00:56 -0800
> > Cc: gcc-patches@gcc.gnu.org, g...@gcc.gnu.org
> > From: Ian Lance Taylor via Gcc 
> >
> > > +#ifdef HAVE_WINDOWS_H
> > > +
> > > +static char *
> > > +windows_get_executable_path (char *buf, backtrace_error_callback 
> > > error_callback,
> > > +void *data)
> > > +{
> > > +  if (GetModuleFileNameA (NULL, buf, MAX_PATH - 1) == 0)
> > > +{
> > > +  error_callback (data,
> > > + "could not get the filename of the current 
> > > executable",
> > > + (int) GetLastError ());
> > > +  return NULL;
> > > +}
> > > +  return buf;
> > > +}
> >
> > Thanks, but this seems incomplete.  The docs for GetModuleFileNameA
> > say that if the pathname is too long to fit into the buffer it returns
> > the size of the buffer and sets the error to
> > ERROR_INSUFFICIENT_BUFFER.  It seems to me that in that case we should
> > allocate a larger buffer and try again.
>
> This is correct in general, but not in this particular case.
>
> > On Windows it seems that MAX_PATH is not
> > a true limit, as an extended length path may be up to 32767 bytes.
>
> The limit of 32767 characters (not bytes, AFAIK) is only applicable
> when using the Unicode (a.k.a. "wide") versions of the Windows Win32
> APIs, see
>
>   
> https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
>
> Since the above code uses GetModuleFileNameA, which is an "ANSI"
> single-byte API, it is still subject to the MAX_PATH limitation, and
> MAX_PATH is defined as 260 on Windows headers.

Thanks.  Should this code be using GetModuleFileNameW?  Or would that
mean that the later call to open will fail?

260 bytes does not seem like very much for a path name these days.

Ian


Re: [PATCH 2/4] libbacktrace: detect executable path on windows

2023-01-23 Thread Ian Lance Taylor via Gcc-patches
On Fri, Jan 20, 2023 at 2:56 AM Björn Schäpers  wrote:
>
> From: Björn Schäpers 
>
> This is actually needed so that libstdc++'s  implementation
> to be able to work on windows.
>
> Tested on x86_64-linux and i686-w64-mingw32.
>
> -- >8 --
>
> * configure.ac: Add a check for windows.h.
> * configure, config.h.in: Regenerate.
> * fileline.c: Add windows_get_executable_path.
> * fileline.c (fileline_initialiez): Add a pass using
> windows_get_executable_path.
>
> +#ifdef HAVE_WINDOWS_H
> +
> +static char *
> +windows_get_executable_path (char *buf, backtrace_error_callback 
> error_callback,
> +void *data)
> +{
> +  if (GetModuleFileNameA (NULL, buf, MAX_PATH - 1) == 0)
> +{
> +  error_callback (data,
> + "could not get the filename of the current executable",
> + (int) GetLastError ());
> +  return NULL;
> +}
> +  return buf;
> +}

Thanks, but this seems incomplete.  The docs for GetModuleFileNameA
say that if the pathname is too long to fit into the buffer it returns
the size of the buffer and sets the error to
ERROR_INSUFFICIENT_BUFFER.  It seems to me that in that case we should
allocate a larger buffer and try again.  And, in general, it will be
simpler if we always allocate the buffer, as macho_get_executable_path
does.  Unfortunately it appears that Windows does not provide a way to
ask for the required length.  On Windows it seems that MAX_PATH is not
a true limit, as an extended length path may be up to 32767 bytes.

So probably something like (untested)

static char *
windows_get_executable_path (struct backtrace_state *state,
 backtrace_error_callback error_callback,
 void *data)
{
  uint32_t len;
  char *buf;

  len = MAX_PATH;
  while (1)
{
  uint32_t got;

  name = (char *) backtrace_alloc (state, len, error_callback, data);
  if (name == NULL)
return NULL;
  got = GetModuleFileNameA (NULL, name, len);
  if (got < len - 1) /* -1 because NULB is not counted */
return name;
  backtrace_free (state, name, len, error_callback, data);
  if (GetLastError () != ERROR_INSUFFICIENT_BUFFER)
return NULL;
  len *= 2;
}
}

Ian


Re: [PATCH 2/4] libbacktrace: detect executable path on windows

2023-01-23 Thread Ian Lance Taylor via Gcc
On Fri, Jan 20, 2023 at 2:56 AM Björn Schäpers  wrote:
>
> From: Björn Schäpers 
>
> This is actually needed so that libstdc++'s  implementation
> to be able to work on windows.
>
> Tested on x86_64-linux and i686-w64-mingw32.
>
> -- >8 --
>
> * configure.ac: Add a check for windows.h.
> * configure, config.h.in: Regenerate.
> * fileline.c: Add windows_get_executable_path.
> * fileline.c (fileline_initialiez): Add a pass using
> windows_get_executable_path.
>
> +#ifdef HAVE_WINDOWS_H
> +
> +static char *
> +windows_get_executable_path (char *buf, backtrace_error_callback 
> error_callback,
> +void *data)
> +{
> +  if (GetModuleFileNameA (NULL, buf, MAX_PATH - 1) == 0)
> +{
> +  error_callback (data,
> + "could not get the filename of the current executable",
> + (int) GetLastError ());
> +  return NULL;
> +}
> +  return buf;
> +}

Thanks, but this seems incomplete.  The docs for GetModuleFileNameA
say that if the pathname is too long to fit into the buffer it returns
the size of the buffer and sets the error to
ERROR_INSUFFICIENT_BUFFER.  It seems to me that in that case we should
allocate a larger buffer and try again.  And, in general, it will be
simpler if we always allocate the buffer, as macho_get_executable_path
does.  Unfortunately it appears that Windows does not provide a way to
ask for the required length.  On Windows it seems that MAX_PATH is not
a true limit, as an extended length path may be up to 32767 bytes.

So probably something like (untested)

static char *
windows_get_executable_path (struct backtrace_state *state,
 backtrace_error_callback error_callback,
 void *data)
{
  uint32_t len;
  char *buf;

  len = MAX_PATH;
  while (1)
{
  uint32_t got;

  name = (char *) backtrace_alloc (state, len, error_callback, data);
  if (name == NULL)
return NULL;
  got = GetModuleFileNameA (NULL, name, len);
  if (got < len - 1) /* -1 because NULB is not counted */
return name;
  backtrace_free (state, name, len, error_callback, data);
  if (GetLastError () != ERROR_INSUFFICIENT_BUFFER)
return NULL;
  len *= 2;
}
}

Ian


Re: [PATCH 1/4] libbacktrace: change all pc related variables to uintptr_t

2023-01-20 Thread Ian Lance Taylor via Gcc
On Fri, Jan 20, 2023 at 2:54 AM Björn Schäpers  wrote:
>
> From: Björn Schäpers 
>
> It's the right thing to do, since the PC shouldn't go out of the
> uintptr_t domain, and in backtrace_pcinfo the pc is uintptr_t.
> This is a preparation for a following patch.
>
> Tested on x86_64-linux and i686-w64-mingw32.

Thanks.  Committed like so, with some additional tweaks.

For future reference, when pinging a patch, please reply to the
original patch to maintain the thread.  Or at least mention the
original patch.  It was still on my list, I just hadn't gotten to it.
Thanks.

Ian

Change variables holding PC values from uint64_t to uintptr_t.
Patch by Björn Schäpers.
* dwarf.c (struct function_addrs): Change low and high fields to
uintptr_t.
(struct unit_addrs): Likewise.
(resolve_addr_index): Change address parameter to uintptr_t*.
(add_unit_addr): Change lowpc and highpc parameters to uintptr_t.
(add_function_range): Likewise.
(struct pcrange): Change lowpc and highpc fields to uintptr_t.
(add_low_high_range): Change add_range lowpc and highpc parameters
to uintptr_t.
(add_ranges_from_ranges): Likewise.
(add_ranges_from_rnglists): Likewise.
(add_low_high_range): Chnage lowpc and highpc variables to
uintpr_t.
(add_ranges_from_rnglists): Change some local variables to
uintptr_t.
(add_ranges_from_ranges): Change base parameter to uintptr_t.
(add_ranges_from_rnglists): Likewise.
(read_function_entry): Likewise.
(resolve_addr_index): Add explicit casts to uintptr_t.
(update_pcrange): Likewise.
(add_ranges_from_ranges): Likewise.
(add_ranges_from_rnglists): Likewise.
(read_function_entry): Likewise.
0c193cabe1d8f209359f3ccb8e74cf87b38fc4bc
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 2d41f3b0397..8ff1fb3ce3d 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -136,7 +136,7 @@ enum attr_val_encoding
   /* 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.  */
+ the DW_AT_addr_base attribute of the compilation unit.  */
   ATTR_VAL_ADDRESS_INDEX,
   /* A unsigned integer.  */
   ATTR_VAL_UINT,
@@ -274,8 +274,8 @@ struct function
 struct function_addrs
 {
   /* Range is LOW <= PC < HIGH.  */
-  uint64_t low;
-  uint64_t high;
+  uintptr_t low;
+  uintptr_t high;
   /* Function for this address range.  */
   struct function *function;
 };
@@ -356,8 +356,8 @@ struct unit
 struct unit_addrs
 {
   /* Range is LOW <= PC < HIGH.  */
-  uint64_t low;
-  uint64_t high;
+  uintptr_t low;
+  uintptr_t high;
   /* Compilation unit for this address range.  */
   struct unit *u;
 };
@@ -1094,7 +1094,7 @@ resolve_addr_index (const struct dwarf_sections 
*dwarf_sections,
uint64_t addr_base, int addrsize, int is_bigendian,
uint64_t addr_index,
backtrace_error_callback error_callback, void *data,
-   uint64_t *address)
+   uintptr_t *address)
 {
   uint64_t offset;
   struct dwarf_buf addr_buf;
@@ -1115,7 +1115,7 @@ resolve_addr_index (const struct dwarf_sections 
*dwarf_sections,
   addr_buf.data = data;
   addr_buf.reported_underflow = 0;
 
-  *address = read_address (_buf, addrsize);
+  *address = (uintptr_t) read_address (_buf, addrsize);
   return 1;
 }
 
@@ -1194,7 +1194,7 @@ function_addrs_search (const void *vkey, const void 
*ventry)
 
 static int
 add_unit_addr (struct backtrace_state *state, void *rdata,
-  uint64_t lowpc, uint64_t highpc,
+  uintptr_t lowpc, uintptr_t highpc,
   backtrace_error_callback error_callback, void *data,
   void *pvec)
 {
@@ -1530,10 +1530,10 @@ lookup_abbrev (struct abbrevs *abbrevs, uint64_t code,
lowpc/highpc is set or ranges is set.  */
 
 struct pcrange {
-  uint64_t lowpc;  /* The low PC value.  */
+  uintptr_t lowpc; /* The low PC value.  */
   int have_lowpc;  /* Whether a low PC value was found.  */
   int lowpc_is_addr_index; /* Whether lowpc is in .debug_addr.  */
-  uint64_t highpc; /* The high PC value.  */
+  uintptr_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.  */
   int highpc_is_addr_index;/* Whether highpc is in .debug_addr.  */
@@ -1553,12 +1553,12 @@ update_pcrange (const struct attr* attr, const struct 
attr_val* val,
 case DW_AT_low_pc:
   if (val->encoding == ATTR_VAL_ADDRESS)
{
- pcrange->lowpc = val->u.uint;
+ pcrange->lowpc = (uintptr_t) val->u.uint;
  pcrange->have_lowpc = 1;
}
   else if (val->encoding == ATTR_VAL_ADDRESS_INDEX)
{
- pcrange->lowpc = val->u.uint;
+ pcrange->lowpc = (uintptr_t) val->u.uint;
  pcrange->have_lowpc = 1;
  pcrange->lowpc_is_addr_index = 1;
}
@@ 

Re: [PATCH 1/4] libbacktrace: change all pc related variables to uintptr_t

2023-01-20 Thread Ian Lance Taylor via Gcc-patches
On Fri, Jan 20, 2023 at 2:54 AM Björn Schäpers  wrote:
>
> From: Björn Schäpers 
>
> It's the right thing to do, since the PC shouldn't go out of the
> uintptr_t domain, and in backtrace_pcinfo the pc is uintptr_t.
> This is a preparation for a following patch.
>
> Tested on x86_64-linux and i686-w64-mingw32.

Thanks.  Committed like so, with some additional tweaks.

For future reference, when pinging a patch, please reply to the
original patch to maintain the thread.  Or at least mention the
original patch.  It was still on my list, I just hadn't gotten to it.
Thanks.

Ian

Change variables holding PC values from uint64_t to uintptr_t.
Patch by Björn Schäpers.
* dwarf.c (struct function_addrs): Change low and high fields to
uintptr_t.
(struct unit_addrs): Likewise.
(resolve_addr_index): Change address parameter to uintptr_t*.
(add_unit_addr): Change lowpc and highpc parameters to uintptr_t.
(add_function_range): Likewise.
(struct pcrange): Change lowpc and highpc fields to uintptr_t.
(add_low_high_range): Change add_range lowpc and highpc parameters
to uintptr_t.
(add_ranges_from_ranges): Likewise.
(add_ranges_from_rnglists): Likewise.
(add_low_high_range): Chnage lowpc and highpc variables to
uintpr_t.
(add_ranges_from_rnglists): Change some local variables to
uintptr_t.
(add_ranges_from_ranges): Change base parameter to uintptr_t.
(add_ranges_from_rnglists): Likewise.
(read_function_entry): Likewise.
(resolve_addr_index): Add explicit casts to uintptr_t.
(update_pcrange): Likewise.
(add_ranges_from_ranges): Likewise.
(add_ranges_from_rnglists): Likewise.
(read_function_entry): Likewise.
0c193cabe1d8f209359f3ccb8e74cf87b38fc4bc
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 2d41f3b0397..8ff1fb3ce3d 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -136,7 +136,7 @@ enum attr_val_encoding
   /* 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.  */
+ the DW_AT_addr_base attribute of the compilation unit.  */
   ATTR_VAL_ADDRESS_INDEX,
   /* A unsigned integer.  */
   ATTR_VAL_UINT,
@@ -274,8 +274,8 @@ struct function
 struct function_addrs
 {
   /* Range is LOW <= PC < HIGH.  */
-  uint64_t low;
-  uint64_t high;
+  uintptr_t low;
+  uintptr_t high;
   /* Function for this address range.  */
   struct function *function;
 };
@@ -356,8 +356,8 @@ struct unit
 struct unit_addrs
 {
   /* Range is LOW <= PC < HIGH.  */
-  uint64_t low;
-  uint64_t high;
+  uintptr_t low;
+  uintptr_t high;
   /* Compilation unit for this address range.  */
   struct unit *u;
 };
@@ -1094,7 +1094,7 @@ resolve_addr_index (const struct dwarf_sections 
*dwarf_sections,
uint64_t addr_base, int addrsize, int is_bigendian,
uint64_t addr_index,
backtrace_error_callback error_callback, void *data,
-   uint64_t *address)
+   uintptr_t *address)
 {
   uint64_t offset;
   struct dwarf_buf addr_buf;
@@ -1115,7 +1115,7 @@ resolve_addr_index (const struct dwarf_sections 
*dwarf_sections,
   addr_buf.data = data;
   addr_buf.reported_underflow = 0;
 
-  *address = read_address (_buf, addrsize);
+  *address = (uintptr_t) read_address (_buf, addrsize);
   return 1;
 }
 
@@ -1194,7 +1194,7 @@ function_addrs_search (const void *vkey, const void 
*ventry)
 
 static int
 add_unit_addr (struct backtrace_state *state, void *rdata,
-  uint64_t lowpc, uint64_t highpc,
+  uintptr_t lowpc, uintptr_t highpc,
   backtrace_error_callback error_callback, void *data,
   void *pvec)
 {
@@ -1530,10 +1530,10 @@ lookup_abbrev (struct abbrevs *abbrevs, uint64_t code,
lowpc/highpc is set or ranges is set.  */
 
 struct pcrange {
-  uint64_t lowpc;  /* The low PC value.  */
+  uintptr_t lowpc; /* The low PC value.  */
   int have_lowpc;  /* Whether a low PC value was found.  */
   int lowpc_is_addr_index; /* Whether lowpc is in .debug_addr.  */
-  uint64_t highpc; /* The high PC value.  */
+  uintptr_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.  */
   int highpc_is_addr_index;/* Whether highpc is in .debug_addr.  */
@@ -1553,12 +1553,12 @@ update_pcrange (const struct attr* attr, const struct 
attr_val* val,
 case DW_AT_low_pc:
   if (val->encoding == ATTR_VAL_ADDRESS)
{
- pcrange->lowpc = val->u.uint;
+ pcrange->lowpc = (uintptr_t) val->u.uint;
  pcrange->have_lowpc = 1;
}
   else if (val->encoding == ATTR_VAL_ADDRESS_INDEX)
{
- pcrange->lowpc = val->u.uint;
+ pcrange->lowpc = (uintptr_t) val->u.uint;
  pcrange->have_lowpc = 1;
  pcrange->lowpc_is_addr_index = 1;
}
@@ 

Go patch committed: Define builtin functions

2023-01-17 Thread Ian Lance Taylor via Gcc-patches
This patch by Andrew Pinski defines two builtin functions that are
used by the middle-end.  This fixes PR 108426.  Bootstrapped and
tested on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

PR go/108426
* go-gcc.cc (Gcc_backend::Gcc_backend): Define __builtin_ctzl and
__builtin_clzl.  Patch by Andrew Pinski.
2bee478038d75487b52e35e29e54c70e4bfa1e2b
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index a4a0e5d903e..07c34a58241 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -627,6 +627,11 @@ Gcc_backend::Gcc_backend()
unsigned_type_node,
NULL_TREE),
   builtin_const);
+  this->define_builtin(BUILT_IN_CTZL, "__builtin_ctzl", "ctzl",
+ build_function_type_list(integer_type_node,
+  long_unsigned_type_node,
+  NULL_TREE),
+ builtin_const);
   this->define_builtin(BUILT_IN_CTZLL, "__builtin_ctzll", "ctzll",
   build_function_type_list(integer_type_node,
long_long_unsigned_type_node,
@@ -637,6 +642,11 @@ Gcc_backend::Gcc_backend()
unsigned_type_node,
NULL_TREE),
   builtin_const);
+  this->define_builtin(BUILT_IN_CLZL, "__builtin_clzl", "clzl",
+ build_function_type_list(integer_type_node,
+  long_unsigned_type_node,
+  NULL_TREE),
+ builtin_const);
   this->define_builtin(BUILT_IN_CLZLL, "__builtin_clzll", "clzll",
   build_function_type_list(integer_type_node,
long_long_unsigned_type_node,


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


Re: [PATCH] go: fix clang warnings

2022-12-22 Thread Ian Lance Taylor via Gcc-patches
On Wed, Dec 21, 2022 at 12:05 AM Martin Liška  wrote:
>
> The patch fixes the following Clang warnings:
>
> gcc/go/gofrontend/escape.cc:1290:17: warning: private field 'fn_' is not used 
> [-Wunused-private-field]
> gcc/go/gofrontend/escape.cc:3478:19: warning: private field 'context_' is not 
> used [-Wunused-private-field]
> gcc/go/gofrontend/lex.h:564:15: warning: private field 'input_file_name_' is 
> not used [-Wunused-private-field]
> gcc/go/gofrontend/types.cc:5788:20: warning: private field 'call_' is not 
> used [-Wunused-private-field]
> gcc/go/gofrontend/wb.cc:206:9: warning: private field 'gogo_' is not used 
> [-Wunused-private-field]
>
> Ready for master?

Thanks.  Committed to mainline.

Ian


Re: [PATCH] libgo: check if -lucontext is required for {make, set, get}context

2022-12-20 Thread Ian Lance Taylor via Gcc-patches
On Mon, Dec 19, 2022 at 8:59 AM  wrote:
>
> From: Sören Tempel 
>
> This patch is similar to the existing check for librt. If libucontext
> is installed and libucontext.a provides the aforementioned symbols, then
> it is added to $LIBS. If not, no error is emitted. We could,
> alternatively, also check libc.a for these symbols and thus prefer libc
> over libucontext if both are installed and provide the symbols. If
> deemed desirable, this could be achieved by changing the invocation
> to AC_SEARCH_LIBS([makecontext], [c ucontext]).
>
> This version of this patch has been tested on x86_64 Alpine Linux Edge
> (libucontext 1.2 + musl 1.2.3) and Arch Linux (glibc 2.36). On the
> latter, the check is a no-op and $LIBS is not modified.

Thanks.  I don't see a reason to check for all the functions.
Committed like so after testing on x86_64-pc-linux-gnu with glibc.

Ian
e1e810e2f1d4f6c45021741cb3f8d7f2be15926d
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index d8c4e02d6e6..d123c746fb2 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-9906861dc86c1733bb304d3d45b1534adb32712c
+ecc2a2e70e44fa76a75b12d0893bc1702b72a1b4
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/configure b/libgo/configure
index 460fdad70a8..a607dbff68e 100755
--- a/libgo/configure
+++ b/libgo/configure
@@ -14818,6 +14818,63 @@ fi
 
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing 
makecontext" >&5
+$as_echo_n "checking for library containing makecontext... " >&6; }
+if ${ac_cv_search_makecontext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char makecontext ();
+int
+main ()
+{
+return makecontext ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' ucontext; do
+  if test -z "$ac_lib"; then
+ac_res="none required"
+  else
+ac_res=-l$ac_lib
+LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_makecontext=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+conftest$ac_exeext
+  if ${ac_cv_search_makecontext+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_makecontext+:} false; then :
+
+else
+  ac_cv_search_makecontext=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_makecontext" >&5
+$as_echo "$ac_cv_search_makecontext" >&6; }
+ac_res=$ac_cv_search_makecontext
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing 
sched_yield" >&5
 $as_echo_n "checking for library containing sched_yield... " >&6; }
 if ${ac_cv_search_sched_yield+:} false; then :
diff --git a/libgo/configure.ac b/libgo/configure.ac
index 09554a37a23..a59aa091d1d 100644
--- a/libgo/configure.ac
+++ b/libgo/configure.ac
@@ -570,6 +570,9 @@ PTHREAD_LIBS=
 AC_CHECK_LIB([pthread], [pthread_create], PTHREAD_LIBS=-lpthread)
 AC_SUBST(PTHREAD_LIBS)
 
+dnl Test if -lucontext is required for makecontext.
+AC_SEARCH_LIBS([makecontext], [ucontext])
+
 dnl Test if -lrt is required for sched_yield or nanosleep or clock_gettime.
 AC_SEARCH_LIBS([sched_yield], [rt])
 AC_SEARCH_LIBS([nanosleep], [rt])


Re: Add zstd support to libbacktrace

2022-12-16 Thread Ian Lance Taylor via Gcc-patches
Some more tweaks of the libbacktrace zstd decompressor to make
decompressing slightly faster: unpack all the literal data into the
output buffer, rather than using scratch space.  Bootstrapped and ran
libbacktrace tests on x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* elf.c (elf_fetch_backward_init): New static function.
(ZSTD_TABLE_SIZE): Use huffman scratch space size rather than
literal size.
(ZSTD_TABLE_WORK_LIT_SIZE): Don't define.
(elf_zstd_read_huff): Use elf_fetch_backward_init.
(elf_zstd_read_literals): New static function.
(ZSTD_LIT_RAW, ZSTD_LIT_RLE, ZSTD_LIT_HUFF): Don't define.
(struct elf_zstd_literals): Don't define.
(elf_zstd_literal_output): Remove static function.
(elf_zstd_decompress): Use elf_fetch_backward_init and
elf_zstd_read_literals.  Rewrite literal copying.<
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index ece02db27f1..135a94245a4 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -1223,6 +1223,57 @@ elf_fetch_bits_backward (const unsigned char **ppin,
   return 1;
 }
 
+/* Initialize backward fetching when the bitstream starts with a 1 bit in the
+   last byte in memory (which is the first one that we read).  This is used by
+   zstd decompression.  Returns 1 on success, 0 on error.  */
+
+static int
+elf_fetch_backward_init (const unsigned char **ppin,
+const unsigned char *pinend,
+uint64_t *pval, unsigned int *pbits)
+{
+  const unsigned char *pin;
+  unsigned int stream_start;
+  uint64_t val;
+  unsigned int bits;
+
+  pin = *ppin;
+  stream_start = (unsigned int)*pin;
+  if (unlikely (stream_start == 0))
+{
+  elf_uncompress_failed ();
+  return 0;
+}
+  val = 0;
+  bits = 0;
+
+  /* Align to a 32-bit boundary.  */
+  while uintptr_t)pin) & 3) != 0)
+{
+  val <<= 8;
+  val |= (uint64_t)*pin;
+  bits += 8;
+  --pin;
+}
+
+  val <<= 8;
+  val |= (uint64_t)*pin;
+  bits += 8;
+
+  *ppin = pin;
+  *pval = val;
+  *pbits = bits;
+  if (!elf_fetch_bits_backward (ppin, pinend, pval, pbits))
+return 0;
+
+  *pbits -= __builtin_clz (stream_start) - (sizeof (unsigned int) - 1) * 8 + 1;
+
+  if (!elf_fetch_bits_backward (ppin, pinend, pval, pbits))
+return 0;
+
+  return 1;
+}
+
 /* Huffman code tables, like the rest of the zlib format, are defined
by RFC 1951.  We store a Huffman code table as a series of tables
stored sequentially in memory.  Each entry in a table is 16 bits.
@@ -2617,14 +2668,13 @@ elf_zlib_inflate_and_verify (const unsigned char *pin, 
size_t sin,
- scratch space, one of
  - to build an FSE table: 512 uint16_t values == 1024 bytes
  - to build a Huffman tree: 512 uint16_t + 256 uint32_t == 2048 bytes
- - buffer for literal values == 2048 bytes
 */
 
 #define ZSTD_TABLE_SIZE\
   (2 * 512 * sizeof (struct elf_zstd_fse_baseline_entry)   \
+ 256 * sizeof (struct elf_zstd_fse_baseline_entry) \
+ 2048 * sizeof (uint16_t)  \
-   + 2048)
+   + 512 * sizeof (uint16_t) + 256 * sizeof (uint32_t))
 
 #define ZSTD_TABLE_LITERAL_FSE_OFFSET (0)
 
@@ -2642,8 +2692,6 @@ elf_zlib_inflate_and_verify (const unsigned char *pin, 
size_t sin,
 #define ZSTD_TABLE_WORK_OFFSET \
   (ZSTD_TABLE_HUFFMAN_OFFSET + 2048 * sizeof (uint16_t))
 
-#define ZSTD_TABLE_WORK_LIT_SIZE 2048
-
 /* An entry in a zstd FSE table.  */
 
 struct elf_zstd_fse_entry
@@ -3427,7 +3475,6 @@ elf_zstd_read_huff (const unsigned char **ppin, const 
unsigned char *pinend,
   uint16_t *scratch;
   const unsigned char *pfse;
   const unsigned char *pback;
-  unsigned char stream_start;
   uint64_t val;
   unsigned int bits;
   unsigned int state1, state2;
@@ -3454,31 +3501,8 @@ elf_zstd_read_huff (const unsigned char **ppin, const 
unsigned char *pinend,
 FSE_TABLE.  */
 
   pback = pin + hdr - 1;
-  stream_start = *pback;
-  if (unlikely (stream_start == 0))
-   {
- elf_uncompress_failed ();
- return 0;
-   }
-  val = 0;
-  bits = 0;
-  while uintptr_t)pback) & 3) != 0)
-   {
- val <<= 8;
- val |= (uint64_t)*pback;
- bits += 8;
- --pback;
-   }
-  val <<= 8;
-  val |= (uint64_t)*pback;
-  bits += 8;
-
-  if (!elf_fetch_bits_backward (, pfse, , ))
-   return 0;
-
-  bits -= __builtin_clz (stream_start) - 24 + 1;
 
-  if (!elf_fetch_bits_backward (, pfse, , ))
+  if (!elf_fetch_backward_init (, pfse, , ))
return 0;
 
   bits -= fse_table_bits;
@@ -3702,331 +3726,615 @@ elf_zstd_read_huff (const unsigned char **ppin, const 
unsigned char *pinend,
   return 1;
 }
 
-/* The information used to decompress a sequence code, which can be a literal
-   length, an offset, or a match length.  */
+/* Read and decompress the literals and store them ending at POUTEND.  This
+   works because we are going to use all the 

libgo patch committed: Bump major version

2022-12-12 Thread Ian Lance Taylor via Gcc-patches
This libgo patch bumps the major version.  The current version is the
same as for GCC 12, but there have been minor changes like new type
descriptors that make it impossible to run Go programs built with GCC
12 with the current GCC.  This fixes https://gcc.gnu.org/PR108057.
Bootstrapped on x86_64-pc-linux-gnu.  Committed to mainline.

Ian
3c2e866832dd5612de1468807bc144e4824593c7
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index a26f779557d..d8c4e02d6e6 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-1c5bfd57131b68b91d8400bb017f35d416f7aa7b
+9906861dc86c1733bb304d3d45b1534adb32712c
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/configure.ac b/libgo/configure.ac
index 274fcfc35c7..09554a37a23 100644
--- a/libgo/configure.ac
+++ b/libgo/configure.ac
@@ -10,7 +10,7 @@ AC_INIT(package-unused, version-unused,, libgo)
 AC_CONFIG_SRCDIR(Makefile.am)
 AC_CONFIG_HEADER(config.h)
 
-libtool_VERSION=21:0:0
+libtool_VERSION=22:0:0
 AC_SUBST(libtool_VERSION)
 
 AM_ENABLE_MULTILIB(, ..)


Re: Add zstd support to libbacktrace

2022-12-09 Thread Ian Lance Taylor via Gcc-patches
On Wed, Dec 7, 2022 at 4:22 PM Ian Lance Taylor  wrote:
>
> This patch adds zstd support to libbacktrace, to support the new
> linker option --compress-debug-sections=zstd.

This patch rewrites and simplifies the main zstd decompression loop
using some ideas from the reference implementation.  This speeds it up
a bit, although it still runs at about 35% of the speed of the
reference implementaiton.  Bootstrapped and ran libbacktrace tests on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* elf.c (ZSTD_TABLE_*): Use elf_zstd_fse_baseline_entry.
(ZSTD_ENCODE_BASELINE_BITS): Define.
(ZSTD_DECODE_BASELINE, ZSTD_DECODE_BASEBITS): Define.
(elf_zstd_literal_length_base): New static const array.
(elf_zstd_match_length_base): Likewise.
(struct elf_zstd_fse_baseline_entry): Define.
(elf_zstd_make_literal_baseline_fse): New static function.
(elf_zstd_make_offset_baseline_fse): Likewise.
(elf_zstd_make_match_baseline_fse): Likewise.
(print_table, main): Use elf_zstd_fse_baseline_entry.
(elf_zstd_lit_table, elf_zstd_match_table): Likewise.
(elf_zstd_offset_table): Likewise.
(struct elf_zstd_seq_decode): Likewise.  Remove use_rle and rle
fields.
(elf_zstd_unpack_seq_decode): Use elf_zstd_fse_baseline_entry,
taking a conversion function.  Convert RLE to FSE.
(elf_zstd_literal_length_baseline): Remove.
(elf_zstd_literal_length_bits): Remove.
(elf_zstd_match_length_baseline): Remove.
(elf_zstd_match_length_bits): Remove.
(elf_zstd_decompress): Use elf_zstd_fse_baseline_entry.  Rewrite
and simplify main loop.
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 15e6f284db6..ece02db27f1 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -2610,9 +2610,9 @@ elf_zlib_inflate_and_verify (const unsigned char *pin, 
size_t sin,
 }
 
 /* For working memory during zstd compression, we need
-   - a literal length FSE table: 512 32-bit values == 2048 bytes
-   - a match length FSE table: 512 32-bit values == 2048 bytes
-   - a offset FSE table: 256 32-bit values == 1024 bytes
+   - a literal length FSE table: 512 64-bit values == 4096 bytes
+   - a match length FSE table: 512 64-bit values == 4096 bytes
+   - a offset FSE table: 256 64-bit values == 2048 bytes
- a Huffman tree: 2048 uint16_t values == 4096 bytes
- scratch space, one of
  - to build an FSE table: 512 uint16_t values == 1024 bytes
@@ -2620,21 +2620,24 @@ elf_zlib_inflate_and_verify (const unsigned char *pin, 
size_t sin,
  - buffer for literal values == 2048 bytes
 */
 
-#define ZSTD_TABLE_SIZE\
-  (2 * 512 * sizeof (struct elf_zstd_fse_entry)\
-   + 256 * sizeof (struct elf_zstd_fse_entry)  \
-   + 2048 * sizeof (uint16_t)  \
+#define ZSTD_TABLE_SIZE\
+  (2 * 512 * sizeof (struct elf_zstd_fse_baseline_entry)   \
+   + 256 * sizeof (struct elf_zstd_fse_baseline_entry) \
+   + 2048 * sizeof (uint16_t)  \
+ 2048)
 
 #define ZSTD_TABLE_LITERAL_FSE_OFFSET (0)
 
-#define ZSTD_TABLE_MATCH_FSE_OFFSET (512 * sizeof (struct elf_zstd_fse_entry))
+#define ZSTD_TABLE_MATCH_FSE_OFFSET\
+  (512 * sizeof (struct elf_zstd_fse_baseline_entry))
 
-#define ZSTD_TABLE_OFFSET_FSE_OFFSET \
-  (ZSTD_TABLE_MATCH_FSE_OFFSET + 512 * sizeof (struct elf_zstd_fse_entry))
+#define ZSTD_TABLE_OFFSET_FSE_OFFSET   \
+  (ZSTD_TABLE_MATCH_FSE_OFFSET \
+   + 512 * sizeof (struct elf_zstd_fse_baseline_entry))
 
-#define ZSTD_TABLE_HUFFMAN_OFFSET \
-  (ZSTD_TABLE_OFFSET_FSE_OFFSET + 256 * sizeof (struct elf_zstd_fse_entry))
+#define ZSTD_TABLE_HUFFMAN_OFFSET  \
+  (ZSTD_TABLE_OFFSET_FSE_OFFSET
\
+   + 256 * sizeof (struct elf_zstd_fse_baseline_entry))
 
 #define ZSTD_TABLE_WORK_OFFSET \
   (ZSTD_TABLE_HUFFMAN_OFFSET + 2048 * sizeof (uint16_t))
@@ -2645,8 +2648,11 @@ elf_zlib_inflate_and_verify (const unsigned char *pin, 
size_t sin,
 
 struct elf_zstd_fse_entry
 {
+  /* The value that this FSE entry represents.  */
   unsigned char symbol;
+  /* The number of bits to read to determine the next state.  */
   unsigned char bits;
+  /* Add the bits to this base to get the next state.  */
   uint16_t base;
 };
 
@@ -2925,6 +2931,270 @@ elf_zstd_build_fse (const int16_t *norm, int idx, 
uint16_t *next,
   return 1;
 }
 
+/* Encode the baseline and bits into a single 32-bit value.  */
+
+#define ZSTD_ENCODE_BASELINE_BITS(baseline, basebits)  \
+  ((uint32_t)(baseline) | ((uint32_t)(basebits) << 24))
+
+#define ZSTD_DECODE_BASELINE(baseline_basebits)\
+  ((uint32_t)(baseline_basebits) & 0xff)
+
+#define ZSTD_DECODE_BASEBITS(baseline_basebits)\
+  ((uint32_t)(baseline_basebits) >> 24)
+
+/* Given a literal length code, we need to read a number of bits and add that
+   to a baseline.  For states 0 to 15 the baseline is the state and the number
+   of bits is zero.  */
+
+#define 

Add zstd support to libbacktrace

2022-12-07 Thread Ian Lance Taylor via Gcc-patches
This patch adds zstd support to libbacktrace, to support the new
linker option --compress-debug-sections=zstd.

The zstd format is fairly complicated, so it's likely that there are
some bugs here.  It does pass the tests, at least.

Unfortunately this decompressor only runs at about 1/3 the speed to
the zstd library decompressor.  Still, it's smaller and simpler, and I
think it uses less memory.  Plus of course it uses the signal-safe
libbacktrace memory allocator.  Perhaps people can make a bit faster
over time.

Bootstrapped and ran libbacktrace and Go tests while using a linker
that compressed using zstd.

Committed to mainline.

Ian

Support decompressing --compress-debug-sections=zstd.
* configure.ac: Check for zstd library and
--compress-debug-sections=zstd linker option.
* Makefile.am (zstdtest_*): New targets.
(zstdtest_alloc_*, ctestzstd_*): New targets.
(BUILDTESTS): Add zstdtest, zstdtest_alloc, ctestzstd as
appropriate.
* elf.c (ELFCOMPRESS_ZSTD): Define.
(elf_fetch_bits): Rename from elf_zlib_fetch.  Update uses.
(elf_fetch_bits_backward): New static function.
(ZLIB_HUFFMAN_*): Rename from HUFFMAN_*.  Update uses.
(ZLIB_TABLE_*): Rename from ZDEBUG_TABLE_*.  Update uses.
(ZSTD_TABLE_*): Define.
(struct elf_zstd_fse_entry): Define.
(elf_zstd_read_fse): New static function.
(elf_zstd_build_fse): Likewise.
(lit): Define if BACKTRACE_GENERATE_ZSTD_FSE_TABLES.
(match, offset, next, print_table, main): Likewise.
(elf_zstd_lit_table): New static const array.
(elf_zstd_match_table, elf_zstd_offset_table): Likewise.
(elf_zstd_read_huff): New static function.
(struct elf_zstd_seq_decode): Define.
(elf_zstd_unpack_seq_decode): New static function.
(ZSTD_LIT_*): Define.
(struct elf_zstd_literals): Define.
(elf_zstd_literal_output): New static function.
(ZSTD_LITERAL_LENGTH_BASELINE_OFFSET): Define.
(elf_zstd_literal_length_baseline): New static const array.
(elf_zstd_literal_length_bits): Likewise.
(ZSTD_MATCH_LENGTH_BASELINE_OFFSET): Define.
(elf_zstd_match_length_baseline): New static const array.
(elf_zstd_match_length_bits): Likewise.
(elf_zstd_decompress): New static function.
(ZDEBUG_TABLE_SIZE): New definition.
(elf_uncompress_chdr): Support ELF_COMPRESS_ZSTD.
(backtrace_uncompress_zstd): New function.
(elf_add): Use ZLIB_TABLE_SIZE for zlib-gnu sections.
* internal.h (backtrace_uncompress_zstd): Declare.
* zstdtest.c: New file.
* configure, config.h.in, Makefile.in: Regenerate.
diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am
index 9f8516d00e2..047b573c29a 100644
--- a/libbacktrace/Makefile.am
+++ b/libbacktrace/Makefile.am
@@ -368,6 +368,25 @@ ztest_alloc_CFLAGS = $(ztest_CFLAGS)
 
 BUILDTESTS += ztest_alloc
 
+zstdtest_SOURCES = zstdtest.c testlib.c
+zstdtest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -DSRCDIR=\"$(srcdir)\"
+zstdtest_LDADD = libbacktrace.la
+zstdtest_alloc_LDADD = libbacktrace_alloc.la
+
+if HAVE_ZSTD
+zstdtest_LDADD += -lzstd
+zstdtest_alloc_LDADD += -lzstd
+endif
+zstdtest_LDADD += $(CLOCK_GETTIME_LINK)
+zstdtest_alloc_LDADD += $(CLOCK_GETTIME_LINK)
+
+BUILDTESTS += zstdtest
+
+zstdtest_alloc_SOURCES = $(zstdtest_SOURCES)
+zstdtest_alloc_CFLAGS = $(zstdtest_CFLAGS)
+
+BUILDTESTS += zstdtest_alloc
+
 endif HAVE_ELF
 
 edtest_SOURCES = edtest.c edtest2_build.c testlib.c
@@ -450,6 +469,17 @@ ctesta_LDADD = libbacktrace.la
 
 BUILDTESTS += ctestg ctesta
 
+if HAVE_COMPRESSED_DEBUG_ZSTD
+
+ctestzstd_SOURCES = btest.c testlib.c
+ctestzstd_CFLAGS = $(libbacktrace_TEST_CFLAGS)
+ctestzstd_LDFLAGS = -Wl,--compress-debug-sections=zstd
+ctestzstd_LDADD = libbacktrace.la
+
+BUILDTESTS += ctestzstd
+
+endif
+
 ctestg_alloc_SOURCES = $(ctestg_SOURCES)
 ctestg_alloc_CFLAGS = $(ctestg_CFLAGS)
 ctestg_alloc_LDFLAGS = $(ctestg_LDFLAGS)
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index 1daaa2f62d2..d0a0475cfa8 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -495,6 +495,21 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM(,)],
 LDFLAGS=$LDFLAGS_hold])
 AM_CONDITIONAL(HAVE_COMPRESSED_DEBUG, test "$libgo_cv_ld_compress" = yes)
 
+AC_CHECK_LIB([zstd], [ZSTD_compress],
+[AC_DEFINE(HAVE_ZSTD, 1, [Define if -lzstd is available.])])
+AM_CONDITIONAL(HAVE_ZSTD, test "$ac_cv_lib_zstd_ZSTD_compress" = yes)
+
+dnl Test whether the linker supports --compress-debug-sections=zstd option.
+AC_CACHE_CHECK([whether --compress-debug-sections=zstd is supported],
+[libgo_cv_ld_compress_zstd],
+[LDFLAGS_hold=$LDFLAGS
+LDFLAGS="$LDFLAGS -Wl,--compress-debug-sections=zstd"
+AC_LINK_IFELSE([AC_LANG_PROGRAM(,)],
+[libgo_cv_ld_compress_zstd=yes],
+[libgo_cv_ld_compress_zstd=no])
+LDFLAGS=$LDFLAGS_hold])
+AM_CONDITIONAL(HAVE_COMPRESSED_DEBUG_ZSTD, test "$libgo_cv_ld_compress_zstd" = 
yes)
+
 AC_ARG_VAR(OBJCOPY, [location of objcopy])
 AC_CHECK_PROG(OBJCOPY, objcopy, objcopy,)
 AC_CHECK_PROG(READELF, readelf, readelf)
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 181d195fe35..15e6f284db6 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -184,6 +184,7 @@ 

Re: [PATCH v2] libgo: Don't rely on GNU-specific strerror_r variant on Linux

2022-11-30 Thread Ian Lance Taylor via Gcc-patches
On Tue, Nov 29, 2022 at 4:10 PM Ian Lance Taylor  wrote:
>
> On Tue, Nov 29, 2022 at 9:54 AM  wrote:
> >
> > From: Sören Tempel 
> >
> > On glibc, there are two versions of strerror_r: An XSI-compliant and a
> > GNU-specific version. The latter is only available on glibc. In order
> > to avoid duplicating the post-processing code of error messages, this
> > commit provides a separate strerror_go symbol which always refers to the
> > XSI-compliant version of strerror_r (even on glibc) by selectively
> > undefining the corresponding feature test macro.
> >
> > Previously, gofrontend assumed that the GNU-specific version of
> > strerror_r was always available on Linux (which isn't the case when
> > using a musl as a libc, for example). This commit thereby improves
> > compatibility with Linux systems that are not using glibc.
> >
> > Tested on x86_64 Alpine Linux Edge and Arch Linux (glibc 2.36).
>
> Thanks.  I committed a version of this, as attached.

I've committed this follow-on patch for Hurd.

Ian
91607eba8fe49c064192122ec60a3e03dd8f2515
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 984d8324004..a26f779557d 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-fef6aa3c1678cdbe7dca454b2cebb369d8ba81bf
+1c5bfd57131b68b91d8400bb017f35d416f7aa7b
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/runtime/go-strerror.c b/libgo/runtime/go-strerror.c
index 13d1d91df84..8ff5ffbdfec 100644
--- a/libgo/runtime/go-strerror.c
+++ b/libgo/runtime/go-strerror.c
@@ -12,7 +12,7 @@
exists to selectively undefine it and provides an alias to the
XSI-compliant version of strerror_r(3).  */
 
-#ifdef __linux__
+#if defined(__linux__) || defined(__gnu_hurd__)
 
 /* Force selection of XSI-compliant strerror_r by glibc.  */
 #undef XOPEN_SOURCE
@@ -21,7 +21,7 @@
 #define _POSIX_C_SOURCE 200112L
 #undef _GNU_SOURCE
 
-#endif /* __linux__ */
+#endif /* defined(__linux__) || defined(__gnu_hurd__) */
 
 #include 
 


Re: [PATCH v2] libgo: Don't rely on GNU-specific strerror_r variant on Linux

2022-11-29 Thread Ian Lance Taylor via Gcc-patches
On Tue, Nov 29, 2022 at 9:54 AM  wrote:
>
> From: Sören Tempel 
>
> On glibc, there are two versions of strerror_r: An XSI-compliant and a
> GNU-specific version. The latter is only available on glibc. In order
> to avoid duplicating the post-processing code of error messages, this
> commit provides a separate strerror_go symbol which always refers to the
> XSI-compliant version of strerror_r (even on glibc) by selectively
> undefining the corresponding feature test macro.
>
> Previously, gofrontend assumed that the GNU-specific version of
> strerror_r was always available on Linux (which isn't the case when
> using a musl as a libc, for example). This commit thereby improves
> compatibility with Linux systems that are not using glibc.
>
> Tested on x86_64 Alpine Linux Edge and Arch Linux (glibc 2.36).

Thanks.  I committed a version of this, as attached.

Ian
b6c6a3d64f2e4e9347733290aca3c75898c44b2e
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 7e531c3f90b..984d8324004 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-5e658f4659c551330ea68f5667e4f951b218f32d
+fef6aa3c1678cdbe7dca454b2cebb369d8ba81bf
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index b03e6553e90..207d5a98127 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -465,6 +465,7 @@ runtime_files = \
runtime/go-nanotime.c \
runtime/go-now.c \
runtime/go-nosys.c \
+   runtime/go-strerror.c \
runtime/go-reflect-call.c \
runtime/go-setenv.c \
runtime/go-signal.c \
diff --git a/libgo/go/syscall/errstr.go b/libgo/go/syscall/errstr.go
index 59f7a82c6d7..9f688e2a0c7 100644
--- a/libgo/go/syscall/errstr.go
+++ b/libgo/go/syscall/errstr.go
@@ -4,23 +4,19 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !hurd && !linux
-// +build !hurd,!linux
-
 package syscall
 
-//sysnbstrerror_r(errnum int, buf []byte) (err Errno)
-//strerror_r(errnum _C_int, buf *byte, buflen Size_t) _C_int
+import "internal/bytealg"
+
+//extern go_strerror
+func go_strerror(_C_int, *byte, Size_t) _C_int
 
 func Errstr(errnum int) string {
-   for len := 128; ; len *= 2 {
-   b := make([]byte, len)
-   errno := strerror_r(errnum, b)
+   for size := 128; ; size *= 2 {
+   b := make([]byte, size)
+   errno := go_strerror(_C_int(errnum), [0], Size_t(len(b)))
if errno == 0 {
-   i := 0
-   for b[i] != 0 {
-   i++
-   }
+   i := bytealg.IndexByte(b, 0)
// Lowercase first letter: Bad -> bad, but
// STREAM -> STREAM.
if i > 1 && 'A' <= b[0] && b[0] <= 'Z' && 'a' <= b[1] 
&& b[1] <= 'z' {
@@ -29,7 +25,7 @@ func Errstr(errnum int) string {
return string(b[:i])
}
if errno != ERANGE {
-   return "errstr failure"
+   return "strerror_r failure"
}
}
 }
diff --git a/libgo/go/syscall/errstr_glibc.go b/libgo/go/syscall/errstr_glibc.go
deleted file mode 100644
index 03a327dbc90..000
--- a/libgo/go/syscall/errstr_glibc.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// errstr_glibc.go -- GNU/Linux and GNU/Hurd specific error strings.
-
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// We use this rather than errstr.go because on GNU/Linux sterror_r
-// returns a pointer to the error message, and may not use buf at all.
-
-//go:build hurd || linux
-// +build hurd linux
-
-package syscall
-
-import "unsafe"
-
-//sysnbstrerror_r(errnum int, b []byte) (errstr *byte)
-//strerror_r(errnum _C_int, b *byte, len Size_t) *byte
-
-func Errstr(errnum int) string {
-   a := make([]byte, 128)
-   p := strerror_r(errnum, a)
-   b := (*[1000]byte)(unsafe.Pointer(p))
-   i := 0
-   for b[i] != 0 {
-   i++
-   }
-   // Lowercase first letter: Bad -> bad, but STREAM -> STREAM.
-   if i > 1 && 'A' <= b[0] && b[0] <= 'Z' && 'a' <= b[1] && b[1] <= 'z' {
-   c := b[0] + 'a' - 'A'
-   return string(c) + string(b[1:i])
-   }
-   return string(b[:i])
-}
diff --git a/libgo/runtime/go-strerror.c b/libgo/runtime/go-strerror.c
new file mode 100644
index 000..13d1d91df84
--- /dev/null
+++ b/libgo/runtime/go-strerror.c
@@ -0,0 +1,37 @@
+/* go-strerror.c -- wrapper around XSI-compliant strerror_r.
+
+   Copyright 2022 The Go Authors. All rights reserved.
+   Use of this source code is governed by a BSD-style
+   license that can be found in the LICENSE 

Re: [PATCH] lto: Stream current working directory for first streamed relative filename and adjust relative paths [PR93865]

2022-11-14 Thread Ian Lance Taylor via Gcc-patches
On Thu, Sep 10, 2020 at 1:39 AM Jakub Jelinek via Gcc-patches
 wrote:
>
> If the gcc -c -flto ... commands to compile some or all objects are run in a
> different directory (or in different directories) from the directory in
> which the gcc -flto link line is invoked, then the .debug_line will be
> incorrect if there are any relative filenames, it will use those relative
> filenames while .debug_info will contain a different DW_AT_comp_dir.
>
> The following patch streams (at most once after each clear_line_info)
> the current working directory (what we record in DW_AT_comp_dir) when
> encountering the first relative pathname, and when reading the location info
> reads it back and if the current working directory at that point is
> different from the saved one, adjusts relative paths by adding a relative
> prefix how to go from the current working directory to the previously saved
> path (with a fallback e.g. for DOS e:\\foo vs. d:\\bar change to use
> absolute directory).
>
> Bootstrapped/regtested on x86_64-linux (both lto bootstrap and normal one;
> i686-linux doesn't build due to some unrelated libgo bugs), ok for trunk?
>
> 2020-09-10  Jakub Jelinek  
>
> PR debug/93865
> * lto-streamer.h (struct output_block): Add emit_pad member.
> * lto-streamer-out.c: Include toplev.h.
> (clear_line_info): Set emit_pwd.
> (lto_output_location_1): Encode the ob->current_file != xloc.file
> bit directly into the location number.  If changing file, emit
> additionally a bit whether pwd is emitted and emit it before the
> first relative pathname since clear_line_info.
> (output_function, output_constructor): Don't call clear_line_info
> here.
> * lto-streamer-in.c (struct string_pair_map): New type.
> (struct string_pair_map_hasher): New type.
> (string_pair_map_hasher::hash): New method.
> (string_pair_map_hasher::equal): New method.
> (path_name_pair_hash_table, string_pair_map_allocator): New variables.
> (relative_path_prefix, canon_relative_path_prefix,
> canon_relative_file_name): New functions.
> (canon_file_name): Add relative_prefix argument, if non-NULL
> and string is a relative path, return canon_relative_file_name.
> (lto_location_cache::input_location_and_block): Decode file change
> bit from the location number.  If changing file, unpack bit whether
> pwd is streamed and stream in pwd.  Adjust canon_file_name caller.
> (lto_free_file_name_hash): Delete path_name_pair_hash_table
> and string_pair_map_allocator.


Hi, I've noticed that this patch is incomplete.  It streams the result
of get_src_pwd without passing it through remap_debug_filename.  As in
comp_dir_output in dwarf2out.cc, we should always remap all file and
directory names, including the result of get_src_pwd.

Ian




> --- gcc/lto-streamer.h.jj   2020-09-09 09:08:13.102815586 +0200
> +++ gcc/lto-streamer.h  2020-09-09 12:36:13.120070769 +0200
> @@ -718,6 +718,7 @@ struct output_block
>int current_col;
>bool current_sysp;
>bool reset_locus;
> +  bool emit_pwd;
>tree current_block;
>
>/* Cache of nodes written in this section.  */
> --- gcc/lto-streamer-out.c.jj   2020-09-09 09:08:13.077815963 +0200
> +++ gcc/lto-streamer-out.c  2020-09-09 13:21:34.093021582 +0200
> @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.
>  #include "file-prefix-map.h" /* remap_debug_filename()  */
>  #include "output.h"
>  #include "ipa-utils.h"
> +#include "toplev.h"
>
>
>  static void lto_write_tree (struct output_block*, tree, bool);
> @@ -61,6 +62,7 @@ clear_line_info (struct output_block *ob
>ob->current_col = 0;
>ob->current_sysp = false;
>ob->reset_locus = true;
> +  ob->emit_pwd = true;
>/* Initialize to something that will never appear as block,
>   so that the first location with block in a function etc.
>   always streams a change_block bit and the first block.  */
> @@ -189,9 +191,6 @@ lto_output_location_1 (struct output_blo
>  {
>location_t loc = LOCATION_LOCUS (orig_loc);
>
> -  bp_pack_int_in_range (bp, 0, RESERVED_LOCATION_COUNT,
> -   loc < RESERVED_LOCATION_COUNT
> -   ? loc : RESERVED_LOCATION_COUNT);
>if (loc >= RESERVED_LOCATION_COUNT)
>  {
>expanded_location xloc = expand_location (loc);
> @@ -207,13 +206,30 @@ lto_output_location_1 (struct output_blo
>   ob->reset_locus = false;
> }
>
> -  bp_pack_value (bp, ob->current_file != xloc.file, 1);
> +  /* As RESERVED_LOCATION_COUNT is 2, we can use the spare value of
> +3 without wasting additional bits to signalize file change.
> +If RESERVED_LOCATION_COUNT changes, reconsider this.  */
> +  gcc_checking_assert (RESERVED_LOCATION_COUNT == 2);
> +  bp_pack_int_in_range (bp, 0, RESERVED_LOCATION_COUNT + 1,
> +   

Go patch committed: Define __atomic_fetch_add functions

2022-11-09 Thread Ian Lance Taylor via Gcc-patches
This patch to the GCC-specific part of the Go frontend defines the
__atomic_fetch_add functions.  The frontend only generates calls to
the __atomic_add_fetch functions, but in some cases the middle-end can
transform the latter into the former.  This patch is originally by
Marc Poulhiès.  This fixes PR  107581.  Bootstrapped and ran Go
testsuite on x86_64-pc-linux-gnu.  Committed to mainline.

Ian
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 1ba7206caeb..6e5887aecab 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -886,16 +886,20 @@ Gcc_backend::Gcc_backend()
uint32_type_node,
integer_type_node,
NULL_TREE);
-  this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_4, "__atomic_add_fetch_4", 
NULL,
-   t, 0);
+  this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_4, "__atomic_add_fetch_4",
+  NULL, t, 0);
+  this->define_builtin(BUILT_IN_ATOMIC_FETCH_ADD_4, "__atomic_fetch_add_4",
+  NULL, t, 0);
 
   t = build_function_type_list(uint64_type_node,
ptr_type_node,
uint64_type_node,
integer_type_node,
NULL_TREE);
-  this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8", 
NULL,
-   t, 0);
+  this->define_builtin(BUILT_IN_ATOMIC_ADD_FETCH_8, "__atomic_add_fetch_8",
+  NULL, t, 0);
+  this->define_builtin(BUILT_IN_ATOMIC_FETCH_ADD_8, "__atomic_fetch_add_8",
+  NULL, t, 0);
 
   t = build_function_type_list(unsigned_char_type_node,
   ptr_type_node,


Re: [PATCH] libgo: use _off_t for mmap offset argument

2022-10-27 Thread Ian Lance Taylor via Gcc-patches
On Sat, Oct 22, 2022 at 6:45 AM Sören Tempel  wrote:
>
> PING.
>
> soe...@soeren-tempel.net wrote:
> > From: Sören Tempel 
> >
> > On glibc-based systems, off_t is a 32-bit type on 32-bit systems and a
> > 64-bit type on 64-bit systems by default. However, on systems using musl
> > libc off_t is unconditionally a 64-bit type. As such, it is insufficient
> > to use a uintptr type for the mmap offset parameter.
> >
> > Presently, the (incorrect) mmap declaration causes a libgo run-time
> > failure on 32-bit musl systems (fatal error: runtime: cannot allocate
> > memory). This commit fixes this run-time error.
> >
> > Signed-off-by: Sören Tempel 
> > ---
> > This implements what has been proposed by Ian in a GitHub comment
> > https://github.com/golang/go/issues/51280#issuecomment-1046322011
> >
> > I don't have access to a 32-bit glibc system to test this on but
> > this does seem to work fine on 32-bit and 64-bit musl systems.

Thanks.  Committed as follows using _libgo_off_t_type to avoid the
confusion between off_t and off64_t.

Sorry for the delay.

Ian
11a5fc0c76aedb100b5d7ecc7dd4bed33d850bb8
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 5b95b38a541..7e531c3f90b 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-6c188108858e3ae8c8ea8e4cc55427d8cf01bbc8
+5e658f4659c551330ea68f5667e4f951b218f32d
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/go/runtime/mem_gccgo.go b/libgo/go/runtime/mem_gccgo.go
index fa3389d857e..1e84f4f5c56 100644
--- a/libgo/go/runtime/mem_gccgo.go
+++ b/libgo/go/runtime/mem_gccgo.go
@@ -15,7 +15,7 @@ import (
 //go:linkname sysFree
 
 //extern mmap
-func sysMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off 
uintptr) unsafe.Pointer
+func sysMmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off 
_libgo_off_t_type) unsafe.Pointer
 
 //extern munmap
 func munmap(addr unsafe.Pointer, length uintptr) int32
@@ -38,7 +38,7 @@ func init() {
 }
 
 func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uintptr) 
(unsafe.Pointer, int) {
-   p := sysMmap(addr, n, prot, flags, fd, off)
+   p := sysMmap(addr, n, prot, flags, fd, _libgo_off_t_type(off))
if uintptr(p) == _MAP_FAILED {
return nil, errno()
}
@@ -47,6 +47,7 @@ func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd 
int32, off uintptr) (u
 
 // Don't split the stack as this method may be invoked without a valid G, which
 // prevents us from allocating more stack.
+//
 //go:nosplit
 func sysAlloc(n uintptr, sysStat *sysMemStat) unsafe.Pointer {
p, err := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, 
mmapFD, 0)
@@ -165,6 +166,7 @@ func sysHugePage(v unsafe.Pointer, n uintptr) {
 
 // Don't split the stack as this function may be invoked without a valid G,
 // which prevents us from allocating more stack.
+//
 //go:nosplit
 func sysFree(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) {
sysStat.add(-int64(n))


Go patch committed: Treat S("") as a string constant

2022-10-10 Thread Ian Lance Taylor via Gcc-patches
This Go frontend patch treats S("") as a string constant.  The
compiler neglected to notice that a conversion from a string constant
to a string type was a valid string constant.

I didn't add a test case because this only caused a compiler failure
when compiling without optimization, which is not the normal case, and
is not a case that we test.

This fixes https://go.dev/issue/56113.

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

Ian
29b0fe393859729215b0db5d28f2faea30c6ec32
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 1c2466090f1..5b95b38a541 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-164f2aeb1deec4c11e55b8bfb152ff7ff4c1dd4c
+6c188108858e3ae8c8ea8e4cc55427d8cf01bbc8
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 247ae1bba34..71838b14629 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -4092,6 +4092,9 @@ Type_conversion_expression::do_numeric_constant_value(
 bool
 Type_conversion_expression::do_string_constant_value(std::string* val) const
 {
+  if (this->type_->is_string_type() && this->expr_->type()->is_string_type())
+return this->expr_->string_constant_value(val);
+
   if (this->type_->is_string_type()
   && this->expr_->type()->integer_type() != NULL)
 {


Go patch committed: Only build thunk struct type when needed

2022-10-10 Thread Ian Lance Taylor via Gcc-patches
This patch to the Go frontend delays building the struct type for a
go/defer thunk until it is needed.  We were building it in the
determine_types pass.  Now, we delay until the
simplify_thunk_statements pass.  That ensures that we are consistent
in determining whether an argument is constant.

With this change we no longer need to add a field for a call to
recover, as the simplify_thunk_statements pass runs after the
build_recover_thunks pass, so the additional argument will already
have been added to the call.

The test case for this is https://go.dev/cl/440297.

This fixes https://go.dev/issue/56109.

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

Ian
10c26259a8ea34a63a14e85b18e6066766ad6a7a
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 10ed3fee67c..1c2466090f1 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-50707b4b51266166ce9bcf9de187e35760ec50f9
+164f2aeb1deec4c11e55b8bfb152ff7ff4c1dd4c
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index b442830b0b7..af8c7d15998 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -2349,7 +2349,7 @@ Thunk_statement::Thunk_statement(Statement_classification 
classification,
 Call_expression* call,
 Location location)
 : Statement(classification, location),
-  call_(call), struct_type_(NULL)
+  call_(call)
 {
 }
 
@@ -2430,15 +2430,6 @@ void
 Thunk_statement::do_determine_types()
 {
   this->call_->determine_type_no_context();
-
-  // Now that we know the types of the call, build the struct used to
-  // pass parameters.
-  Call_expression* ce = this->call_->call_expression();
-  if (ce == NULL)
-return;
-  Function_type* fntype = ce->get_function_type();
-  if (fntype != NULL && !this->is_simple(fntype))
-this->struct_type_ = this->build_struct(fntype);
 }
 
 // Check types in a thunk statement.
@@ -2581,6 +2572,8 @@ Thunk_statement::simplify_statement(Gogo* gogo, 
Named_object* function,
   if (this->is_simple(fntype))
 return false;
 
+  Struct_type* struct_type = this->build_struct(fntype);
+
   Expression* fn = ce->fn();
   Interface_field_reference_expression* interface_method =
 fn->interface_field_reference_expression();
@@ -2600,7 +2593,7 @@ Thunk_statement::simplify_statement(Gogo* gogo, 
Named_object* function,
   std::string thunk_name = gogo->thunk_name();
 
   // Build the thunk.
-  this->build_thunk(gogo, thunk_name);
+  this->build_thunk(gogo, thunk_name, struct_type);
 
   // Generate code to call the thunk.
 
@@ -2630,8 +2623,7 @@ Thunk_statement::simplify_statement(Gogo* gogo, 
Named_object* function,
 
   // Build the struct.
   Expression* constructor =
-Expression::make_struct_composite_literal(this->struct_type_, vals,
- location);
+Expression::make_struct_composite_literal(struct_type, vals, location);
 
   // Allocate the initialized struct on the heap.
   constructor = Expression::make_heap_expression(constructor, location);
@@ -2745,15 +2737,6 @@ Thunk_statement::build_struct(Function_type* fntype)
   fields->push_back(Struct_field(tid));
 }
 
-  // The predeclared recover function has no argument.  However, we
-  // add an argument when building recover thunks.  Handle that here.
-  if (ce->is_recover_call())
-{
-  fields->push_back(Struct_field(Typed_identifier("can_recover",
- Type::lookup_bool_type(),
- location)));
-}
-
   const Expression_list* args = ce->args();
   if (args != NULL)
 {
@@ -2781,7 +2764,8 @@ Thunk_statement::build_struct(Function_type* fntype)
 // artificial, function.
 
 void
-Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name)
+Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name,
+Struct_type* struct_type)
 {
   Location location = this->location();
 
@@ -2807,7 +2791,7 @@ Thunk_statement::build_thunk(Gogo* gogo, const 
std::string& thunk_name)
   // which is a pointer to the special structure we build.
   const char* const parameter_name = "__go_thunk_parameter";
   Typed_identifier_list* thunk_parameters = new Typed_identifier_list();
-  Type* pointer_to_struct_type = Type::make_pointer_type(this->struct_type_);
+  Type* pointer_to_struct_type = Type::make_pointer_type(struct_type);
   thunk_parameters->push_back(Typed_identifier(parameter_name,
   pointer_to_struct_type,
   location));
@@ -2914,7 +2898,7 @@ Thunk_statement::build_thunk(Gogo* gogo, const 
std::string& thunk_name)
 }
 
   Expression_list* call_params = 

Go patch committed: better argument checking for builtins

2022-10-06 Thread Ian Lance Taylor via Gcc-patches
This patch to the Go frontend by Than McIntosh does some better
argument type checking for some builtin functions.  This avoids a
compiler crash on cases like panic(panic("bad")).  This fixes
https://go.dev/issue/56071.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
05c581aef882b3a6369acde2d37a437ef144705c
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 4793c821eba..10ed3fee67c 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-8f1a91aeff400d572857895b7f5e863ec5a4d93e
+50707b4b51266166ce9bcf9de187e35760ec50f9
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 2492d9fe735..247ae1bba34 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -10316,7 +10316,12 @@ Builtin_call_expression::do_check_types(Gogo*)
 case BUILTIN_PANIC:
 case BUILTIN_SIZEOF:
 case BUILTIN_ALIGNOF:
-  this->check_one_arg();
+  if (this->check_one_arg())
+{
+ Expression* arg = this->one_arg();
+ if (arg->type()->is_void_type())
+   this->report_error(_("argument to builtin has void type"));
+}
   break;
 
 case BUILTIN_RECOVER:


Re: [PATCH v2] libgo: Portable access to thread ID in struct sigevent

2022-09-27 Thread Ian Lance Taylor via Gcc-patches
On Fri, Sep 23, 2022 at 6:59 AM  wrote:
>
> From: Sören Tempel 
>
> Tested on x86_64 Arch Linux (glibc) and Alpine Linux (musl libc).
>
> Previously, libgo relied on the _sigev_un implementation-specific
> field in struct sigevent, which is only available on glibc. This
> patch uses the sigev_notify_thread_id macro instead which is mandated
> by timer_create(2). In theory, this should work with any libc
> implementation for Linux. Unfortunately, there is an open glibc bug
> as glibc does not define this macro. For this reason, a glibc-specific
> workaround is required. Other libcs (such as musl) define the macro
> and don't require the workaround.
>
> This makes go_signal compatible with musl libc.
>
> See: https://sourceware.org/bugzilla/show_bug.cgi?id=27417

Thanks.  Committed with some changes, as appended.

Sorry for the delay.

Ian
e73d9fcafbd07bc3714fbaf8a82db71d50015c92
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 73aa712dbdf..4793c821eba 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-0140cca9bc0fad1108c7ed369376ac71cc4bfecf
+8f1a91aeff400d572857895b7f5e863ec5a4d93e
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/go/runtime/os_linux.go b/libgo/go/runtime/os_linux.go
index 96fb178870e..2b2d827cee8 100644
--- a/libgo/go/runtime/os_linux.go
+++ b/libgo/go/runtime/os_linux.go
@@ -22,6 +22,12 @@ type mOS struct {
profileTimerValid uint32
 }
 
+// setSigeventTID is written in C to set the sigev_notify_thread_id
+// field of a sigevent struct.
+//
+//go:noescape
+func setSigeventTID(*_sigevent, int32)
+
 func getProcID() uint64 {
return uint64(gettid())
 }
@@ -52,9 +58,12 @@ const (
 )
 
 // Atomically,
+//
 // if(*addr == val) sleep
+//
 // Might be woken up spuriously; that's allowed.
 // Don't sleep longer than ns; ns < 0 means forever.
+//
 //go:nosplit
 func futexsleep(addr *uint32, val uint32, ns int64) {
// Some Linux kernels have a bug where futex of
@@ -73,6 +82,7 @@ func futexsleep(addr *uint32, val uint32, ns int64) {
 }
 
 // If any procs are sleeping on addr, wake up at most cnt.
+//
 //go:nosplit
 func futexwakeup(addr *uint32, cnt uint32) {
ret := futex(unsafe.Pointer(addr), _FUTEX_WAKE_PRIVATE, cnt, nil, nil, 
0)
@@ -365,7 +375,7 @@ func setThreadCPUProfiler(hz int32) {
var sevp _sigevent
sevp.sigev_notify = _SIGEV_THREAD_ID
sevp.sigev_signo = _SIGPROF
-   *((*int32)(unsafe.Pointer(_sigev_un))) = int32(mp.procid)
+   setSigeventTID(, int32(mp.procid))
ret := timer_create(_CLOCK_THREAD_CPUTIME_ID, , )
if ret != 0 {
// If we cannot create a timer for this M, leave 
profileTimerValid false
diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c
index 528d9b6d9fe..aa1b6305ad0 100644
--- a/libgo/runtime/go-signal.c
+++ b/libgo/runtime/go-signal.c
@@ -183,6 +183,24 @@ setSigactionHandler(struct sigaction* sa, uintptr handler)
sa->sa_sigaction = (void*)(handler);
 }
 
+#ifdef __linux__
+
+// Workaround for https://sourceware.org/bugzilla/show_bug.cgi?id=27417
+#ifndef sigev_notify_thread_id
+  #define sigev_notify_thread_id _sigev_un._tid
+#endif
+
+void setSigeventTID(struct sigevent*, int32_t)
+   __asm__ (GOSYM_PREFIX "runtime.setSigeventTID");
+
+void
+setSigeventTID(struct sigevent *sev, int32_t v)
+{
+   sev->sigev_notify_thread_id = v;
+}
+
+#endif // defined(__linux__)
+
 // C code to fetch values from the siginfo_t and ucontext_t pointers
 // passed to a signal handler.
 


libgo patch committed: Synchronize empty struct field handling

2022-09-27 Thread Ian Lance Taylor via Gcc-patches
This libgo patch by Funan Zeng synchronizes the handling of empty
struct fields between the Go frontend and the libgo FFI code.  In the
compiler the logic for allocating one byte for the last field of a
struct is:
1. the last field has zero size
2. the struct itself does not have zero size
3. the last field is not blank
This patch adds the last two conditions to runtime.structToFFI.  This
is for https://go.dev/issue/55146.  Bootstrapped and ran Go testsuite
on x86_64-pc-linux-gnu.  Committed to mainline.

Ian
085bacba3502ff77c70a7660c19a68f50e9b7877
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index f7a7985287d..73aa712dbdf 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-42efec8c126cf3787bc7c89d9c7f224eff7c5a21
+0140cca9bc0fad1108c7ed369376ac71cc4bfecf
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/go/runtime/ffi.go b/libgo/go/runtime/ffi.go
index cd8479ef551..86ce5b85d04 100644
--- a/libgo/go/runtime/ffi.go
+++ b/libgo/go/runtime/ffi.go
@@ -4,6 +4,7 @@
 
 // Only build this file if libffi is supported.
 
+//go:build libffi
 // +build libffi
 
 package runtime
@@ -221,9 +222,6 @@ func stringToFFI() *__ffi_type {
 // structToFFI returns an ffi_type for a Go struct type.
 func structToFFI(typ *structtype) *__ffi_type {
c := len(typ.fields)
-   if c == 0 {
-   return emptyStructToFFI()
-   }
if typ.typ.kind != 0 {
return ffi_type_pointer()
}
@@ -231,6 +229,7 @@ func structToFFI(typ *structtype) *__ffi_type {
fields := make([]*__ffi_type, 0, c+1)
checkPad := false
lastzero := false
+   sawnonzero := false
for i, v := range typ.fields {
// Skip zero-sized fields; they confuse libffi,
// and there is no value to pass in any case.
@@ -239,10 +238,13 @@ func structToFFI(typ *structtype) *__ffi_type {
// next field.
if v.typ.size == 0 {
checkPad = true
-   lastzero = true
+   if v.name == nil || *v.name != "_" {
+   lastzero = true
+   }
continue
}
lastzero = false
+   sawnonzero = true
 
if checkPad {
off := uintptr(0)
@@ -263,6 +265,10 @@ func structToFFI(typ *structtype) *__ffi_type {
fields = append(fields, typeToFFI(v.typ))
}
 
+   if !sawnonzero {
+   return emptyStructToFFI()
+   }
+
if lastzero {
// The compiler adds one byte padding to non-empty struct ending
// with a zero-sized field (types.cc:get_backend_struct_fields).


Merge from trunk to gccgo branch

2022-09-22 Thread Ian Lance Taylor via Gcc-patches
I've merged trunk revision f35be1268c996d993ab0b4ff329734d467474445 to
the gccgo branch.

Ian


libgo patch committed: Add cgo.Incomplete

2022-09-22 Thread Ian Lance Taylor via Gcc-patches
This libgo patch changes the cgo command to use runtime/cgo.Incomplete
instead of //go:notinheap, and to define the new type in the
runtime/cgo package.  This ports https://go.dev/cl/421879 to libgo.
This is a quick port to update libgo to work with the version of cgo
in gc mainline.  A more complete port will follow, changing the gc
version of cmd/cgo to choose an approach based on feature testing the
gccgo in use.  Bootstrapped and tested on x86_64-pc-linux-gnu.
Committed to mainline.

Ian
c69b87678d3c4e9b995b8ccb51fb38c75a134323
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index dce38e727a7..f7a7985287d 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-6543b7fc6da533eb976b37649a925e7fd5a521fa
+42efec8c126cf3787bc7c89d9c7f224eff7c5a21
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/go/cmd/cgo/gcc.go b/libgo/go/cmd/cgo/gcc.go
index 02391495bbe..e786aeaafa9 100644
--- a/libgo/go/cmd/cgo/gcc.go
+++ b/libgo/go/cmd/cgo/gcc.go
@@ -132,12 +132,11 @@ func (p *Package) addToFlag(flag string, args []string) {
 //
 // For example, the following string:
 //
-// `a b:"c d" 'e''f'  "g\""`
+// `a b:"c d" 'e''f'  "g\""`
 //
 // Would be parsed as:
 //
-// []string{"a", "b:c d", "ef", `g"`}
-//
+// []string{"a", "b:c d", "ef", `g"`}
 func splitQuoted(s string) (r []string, err error) {
var args []string
arg := make([]rune, len(s))
@@ -1156,13 +1155,19 @@ func (p *Package) mangle(f *File, arg *ast.Expr, 
addPosition bool) (ast.Expr, bo
 
 // checkIndex checks whether arg has the form [i], possibly inside
 // type conversions. If so, then in the general case it writes
-//_cgoIndexNN := a
-//_cgoNN := [i] // with type conversions, if any
+//
+// _cgoIndexNN := a
+// _cgoNN := [i] // with type conversions, if any
+//
 // to sb, and writes
-//_cgoCheckPointer(_cgoNN, _cgoIndexNN)
+//
+// _cgoCheckPointer(_cgoNN, _cgoIndexNN)
+//
 // to sbCheck, and returns true. If a is a simple variable or field reference,
 // it writes
-//_cgoIndexNN := 
+//
+// _cgoIndexNN := 
+//
 // and dereferences the uses of _cgoIndexNN. Taking the address avoids
 // making a copy of an array.
 //
@@ -1210,10 +1215,14 @@ func (p *Package) checkIndex(sb, sbCheck *bytes.Buffer, 
arg ast.Expr, i int) boo
 
 // checkAddr checks whether arg has the form , possibly inside type
 // conversions. If so, it writes
-//_cgoBaseNN := 
-//_cgoNN := _cgoBaseNN // with type conversions, if any
+//
+// _cgoBaseNN := 
+// _cgoNN := _cgoBaseNN // with type conversions, if any
+//
 // to sb, and writes
-//_cgoCheckPointer(_cgoBaseNN, true)
+//
+// _cgoCheckPointer(_cgoBaseNN, true)
+//
 // to sbCheck, and returns true. This tells _cgoCheckPointer to check
 // just the contents of the pointer being passed, not any other part
 // of the memory allocation. This is run after checkIndex, which looks
@@ -2131,8 +2140,8 @@ type typeConv struct {
// Type names X for which there exists an XGetTypeID function with type 
func() CFTypeID.
getTypeIDs map[string]bool
 
-   // badStructs contains C structs that should be marked NotInHeap.
-   notInHeapStructs map[string]bool
+   // incompleteStructs contains C structs that should be marked 
Incomplete.
+   incompleteStructs map[string]bool
 
// Predeclared types.
bool   ast.Expr
@@ -2145,7 +2154,6 @@ type typeConv struct {
string ast.Expr
goVoid ast.Expr // _Ctype_void, denotes 
C's void
goVoidPtr  ast.Expr // unsafe.Pointer or 
*byte
-   goVoidPtrNoHeapast.Expr // 
*_Ctype_void_notinheap, like goVoidPtr but marked NotInHeap
 
ptrSize int64
intSize int64
@@ -2169,7 +2177,7 @@ func (c *typeConv) Init(ptrSize, intSize int64) {
c.m = make(map[string]*Type)
c.ptrs = make(map[string][]*Type)
c.getTypeIDs = make(map[string]bool)
-   c.notInHeapStructs = make(map[string]bool)
+   c.incompleteStructs = make(map[string]bool)
c.bool = c.Ident("bool")
c.byte = c.Ident("byte")
c.int8 = c.Ident("int8")
@@ -2188,7 +2196,6 @@ func (c *typeConv) Init(ptrSize, intSize int64) {
c.void = c.Ident("void")
c.string = c.Ident("string")
c.goVoid = c.Ident("_Ctype_void")
-   c.goVoidPtrNoHeap = c.Ident("*_Ctype_void_notinheap")
 
// Normally cgo translates void* to unsafe.Pointer,
// but for historical reasons -godefs uses *byte instead.
@@ -2531,19 +2538,13 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos 
token.Pos, parent string) *Typ
// other than try to determine a Go representation.
tt := *t
tt.C = {"%s %s", 

Re: libgo patch committed: Make runtime.Version return a useful value

2022-09-13 Thread Ian Lance Taylor via Gcc-patches
On Tue, Jun 28, 2022 at 10:20 AM Ian Lance Taylor  wrote:
>
> This libgo patch makes runtime.Version return a meaningful string.
> This also means that "go version" will print something useful, e.g.,
>
> go version go1.18 gccgo (GCC) 12.0.1 20220216 (experimental) linux/amd64
>
> This fixes https://go.dev/issue/51850.
>
> Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
> to mainline.

I've committed this to the GCC 12 branch, for PR 106747.

Ian


Re: libgo patch committed: Ignore __morestack in runtime.Callers

2022-09-13 Thread Ian Lance Taylor via Gcc-patches
On Tue, Sep 6, 2022 at 6:40 PM Ian Lance Taylor  wrote:
>
> This libgo patch ignores the __morestack function in runtime.Callers.
> We were ignoring all functions starting with "__morestack_", but not
> the function "__morestack" itself.  Without this change, some tests
> such as recover.go started failing recently, though I'm not sure
> exactly what changed.  Bootstrapped and ran Go testsuite on
> x86_64-pc-linux-gnu.  Committed to mainline.

I've also committed this patch to GCC 12 branch.

Ian


libgo patch committed: Ignore __morestack in runtime.Callers

2022-09-06 Thread Ian Lance Taylor via Gcc-patches
This libgo patch ignores the __morestack function in runtime.Callers.
We were ignoring all functions starting with "__morestack_", but not
the function "__morestack" itself.  Without this change, some tests
such as recover.go started failing recently, though I'm not sure
exactly what changed.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
c0852b51b7a68ada822955eb7ef83d933cc33e47
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index ca797045d66..dce38e727a7 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-d53e8a0e94e34dc609e34dd5e404debda2640cfb
+6543b7fc6da533eb976b37649a925e7fd5a521fa
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/runtime/go-callers.c b/libgo/runtime/go-callers.c
index 31783696a08..1d4dee66279 100644
--- a/libgo/runtime/go-callers.c
+++ b/libgo/runtime/go-callers.c
@@ -107,7 +107,7 @@ callback (void *data, uintptr_t pc, const char *filename, 
int lineno,
   p = function;
   if (__builtin_strncmp (p, "___", 3) == 0)
++p;
-  if (__builtin_strncmp (p, "__morestack_", 12) == 0)
+  if (__builtin_strncmp (p, "__morestack", 11) == 0)
return 0;
 }
   else if (filename != NULL)


Re: gccgo emits GIMPLE with temporaries for boolean expressions unlike gcc, gdc

2022-08-10 Thread Ian Lance Taylor via Gcc
On Wed, Aug 3, 2022 at 6:26 AM j  wrote:
>
> I've proposed a patch [1] for condition coverage profiling in gcc,
> implemented in the middle-end alongside the branch coverage. I've
> written most of the tests for C and a few for C++ and finally got around
> to try it with a toy example for D and go and noticed something odd
> about Go's CFG construction.
>
> abc.c:
>  int fn (int a, int b, int c) {
>  if (a && (b || c))
>  return a;
>  else
>  return b * c;
>  }
>
> abc.d:
>  int fn (int a, int b, int c) {
>  if (a && (b || c))
>  return a;
>  else
>  return b * c;
>  }
>
> abc.go:
>  func fn (a int, b int, c int) int {
>  a_ := a != 0;
>  b_ := b != 0;
>  c_ := c != 0;
>
>  if a_ && (b_ || c_) {
>  return 1;
>  } else {
>  return 0;
>  }
>  }
>
> All were built with gcc --coverage -fprofile-conditions (my patch, but
> it does not affect this) and no optimization. The C and D programs
> behaved as expected:
>
> gcov --conditions abc.d:
>
>  3:3:int fn (int a, int b, int c) {
> 3*:4:if (a && (b || c))
> conditions outcomes covered 3/6
> condition  1 not covered (false)
> condition  2 not covered (true)
> condition  2 not covered (false)
>  1:5:return a;
>  -:6:else
>  2:7:return b * c;
>
>
> gcov --conditions abc.go:
>  3:5:func fn (a int, b int, c int) int {
>  3:6:a_ := a != 0;
>  3:7:b_ := b != 0;
>  3:8:c_ := c != 0;
>  -:9:
> 3*:   10:if a_ && (b_ || c_) {
> condition outcomes covered 2/2
> condition outcomes covered 1/2
> condition  0 not covered (true)
> condition outcomes covered 2/2
>  1:   11:return 1;
>  -:   12:} else {
>  2:   13:return 0;
>  -:   14:}
>  -:   15:}
>
> So I dumped the gimple gcc -fdump-tree-gimple abc.go:
>
> int main.fn (int a, int b, int c)
> {
>int D.2725;
>int $ret0;
>
>$ret0 = 0;
>{
>  bool a_;
>  bool b_;
>  bool c_;
>
>  a_ = a != 0;
>  b_ = b != 0;
>  c_ = c != 0;
>  {
>{
>  GOTMP.0 = a_;
>  if (GOTMP.0 != 0) goto ; else goto ;
>  :
>  {
>{
>  GOTMP.1 = b_;
>  _1 = ~GOTMP.1;
>  if (_1 != 0) goto ; else goto ;
>  :
>  {
>GOTMP.1 = c_;
>  }
>  :
>}
>GOTMP.2 = GOTMP.1;
>GOTMP.0 = GOTMP.2;
>  }
>  :
>}
>if (GOTMP.0 != 0) goto ; else goto ;
>:
>
>
>
>{
>  {
>$ret0 = 1;
>D.2725 = $ret0;
>// predicted unlikely by early return (on trees) predictor.
>return D.2725;
>  }
>}
>:
>{
>  {
>$ret0 = 0;
>D.2725 = $ret0;
>// predicted unlikely by early return (on trees) predictor.
>return D.2725;
>  }
>}
>  }
>}
> }
>
> Where as D (and C) is more-or-less as you would expect:
>
> int fn (int a, int b, int c)
>
>
>
> {
>int D.7895;
>
>if (a != 0) goto ; else goto ;
>:
>if (b != 0) goto ; else goto ;
>:
>if (c != 0) goto ; else goto ;
>:
>D.7895 = a;
>// predicted unlikely by early return (on trees) predictor.
>return D.7895;
>:
>D.7895 = b * c;
>// predicted unlikely by early return (on trees) predictor.
>return D.7895;
> }
>
> Clearly the decision inference algorithm is unable to properly
> instrument to Go program for condition coverage because of the use of
> temporaries in the emitted GIMPLE. The question is: is this intentional
> and/or required from Go's semantics or could it be considered a defect?
> Is emitting the GIMPLE without the use of temporaries feasible at all?

The Go frontend converts && and || expressions into code that uses
explicit if statements.  This is done largely as an internal
simplification.  Go has rules about the order in which function calls
and certain other kinds of expressions must be evaluated.  Separating
out the order of evaluation imposed by && and || simplifies the
implementation of the other order of evaluation rules.

Ian


Re: [PATCH] PR bootstrap/106472: Add libgo depends on libbacktrace to Makefile.def

2022-07-30 Thread Ian Lance Taylor via Gcc-patches
On Sat, Jul 30, 2022 at 2:38 PM Roger Sayle  wrote:
>
>
> This patch fixes PR bootstrap/106472 by adding a missing dependency
> to Makefile.def to allow make bootstrap when configured using
> "--enable-languages=go" (and not using make with multiple threads).
>
> Tested on x86-64-pc-linux-gnu.  Ok for mainline?
>
>
> 2022-07-30  Roger Sayle  
>
> ChangeLog
> PR bootstrap/106472
> * Makefile.def (dependencies): Make configure-target-libgo depend
> upon all-target-libbacktrace.

This is OK.  Thanks.

Ian


Re: [PATCH] libgo: Explicitly define SYS_timer_settime for 32-bit musl targets

2022-07-30 Thread Ian Lance Taylor via Gcc-patches
On Thu, Jul 28, 2022 at 11:15 AM  wrote:
>
> From: Sören Tempel 
>
> On 32-bit systems, musl only defines SYS_timer_settime32 not
> SYS_timer_settime. This causes the following compilation error:
>
> os_linux.go:251:30: error: reference to undefined name 
> '_SYS_timer_settime'
>   251 | return int32(syscall(_SYS_timer_settime, 
> uintptr(timerid), uintptr(flags), uintptr(unsafe.Pointer(new)), 
> uintptr(unsafe.Pointer(old)), 0, 0))
>   |  ^
>
> This commit fixes this error by "aliasing" SYS_timer_settime to
> SYS_timer_settime32 if the latter is defined. This is also what
> musl does internally [1].

Committed a slight variant of this, as appended.

Ian
f40686b01bdabba051e3b22165bb576e45ffca74
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 2f2fafde1f1..ca797045d66 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-a62f20ae78ddd41be682dde8cab075ca4f5dbb2a
+d53e8a0e94e34dc609e34dd5e404debda2640cfb
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/sysinfo.c b/libgo/sysinfo.c
index fc0210992fa..180f5c31d74 100644
--- a/libgo/sysinfo.c
+++ b/libgo/sysinfo.c
@@ -354,6 +354,11 @@ enum {
 };
 #endif
 
+#if !defined(SYS_timer_settime) && defined(SYS_timer_settime32)
+// musl defines SYS_timer_settim32 on 32-bit systems.
+#define SYS_timer_settime SYS_timer_settime32
+#endif
+
 #if defined(HAVE_LOFF_T)
 // loff_t can be defined as a macro; for -fgo-dump-spec make sure we
 // see a typedef.


Merge from trunk to gccgo branch

2022-07-27 Thread Ian Lance Taylor via Gcc-patches
I merged trunk revision 5eb9f117a361538834b9740d59219911680717d1 to
the gccgo branch.

Ian


Re: [PATCH] libgo: make match.sh POSIX-shell compatible

2022-07-22 Thread Ian Lance Taylor via Gcc-patches
On Tue, Jul 19, 2022 at 11:35 PM  wrote:
>
> From: Sören Tempel 
>
> The `(( expression ))` syntax is a Bash extension and not supported by
> POSIX shell [1]. However, the arithmetic expressions used by the
> gobuild() function can also be expressed using arithmetic POSIX
> expansions with `$(( expression ))` [2].
>
> Contrary to the Bash extension, arithmetic expansion doesn't set
> the return value if the expression is non-zero but instead just prints
> the expression result. Hence, the expression also needs to be negated.
> Without this patch, match.sh does currently not work correctly if
> /bin/sh is not a symlink to Bash.
>
> [1]: https://www.gnu.org/software/bash/manual/bash.html#Conditional-Constructs
> [2]: 
> https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04

Thanks.  Committed as follows, which also fixes the similar function
in the gotest script.

Ian
dbf607d2e92cbae9a7f7620b69b9272adbce6381
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 5ea0406cd8e..2f2fafde1f1 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-ff68b1a147eb60082fd60c198db0ef5477ade938
+a62f20ae78ddd41be682dde8cab075ca4f5dbb2a
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/match.sh b/libgo/match.sh
index 7ed587ff794..e5ed98de422 100755
--- a/libgo/match.sh
+++ b/libgo/match.sh
@@ -111,7 +111,7 @@ gobuild() {
 if test "$goarch" != "386"; then
line=$(echo "$line" | sed -e "s/\\(${wrap}\\)386\\(${wrap}\\)/\10\2/g")
 fi
-(($line))
+return $((!($line)))
 }
 
 matched=
diff --git a/libgo/testsuite/gotest b/libgo/testsuite/gotest
index 04e4267fbba..0a0a7e14d74 100755
--- a/libgo/testsuite/gotest
+++ b/libgo/testsuite/gotest
@@ -302,7 +302,7 @@ gobuild() {
 if test "$goarch" != "386"; then
line=$(echo "$line" | sed -e "s/\\(${wrap}\\)386\\(${wrap}\\)/\10\2/g")
 fi
-(($line))
+return $((!($line)))
 }
 
 case "x$gofiles" in


Re: libgo patch committed: Don't include in sysinfo.c

2022-07-21 Thread Ian Lance Taylor via Gcc-patches
On Thu, Jul 21, 2022 at 4:53 AM Martin Liška  wrote:
>
> On 7/21/22 12:19, Richard Biener via Gcc-patches wrote:
> > On Wed, Jul 13, 2022 at 6:03 PM Ian Lance Taylor via Gcc-patches
> >  wrote:
> >>
> >> This libgo patch stops including  when building
> >> gen-sysinfo.go.  Removing this doesn't change anything at least with
> >> glibc 2.33.  The include was added in https://go.dev/cl/6100049 but
> >> it's not clear why.  This should fix GCC PR 106266.  Bootstrapped and
> >> ran Go testsuite on x86_64-pc-linux-gnu.  Committed to mainline.
> >
> > Btw, active branches are affected the same way - can you please backport?
>
> I've just done that.

Thanks.

Ian


Go patch committed: Handle f().x if f returns a zero-sized type

2022-07-16 Thread Ian Lance Taylor via Gcc-patches
This patch to the Go frontend handles the case of f().x when the
function f returns a zero-sized type.  In that case the GCC interface
will have changed f to return void, as the GCC middle-end does not
have complete support for zero-sized types.  This patch handles the
case of void when in a struct field expression.  The test case for
this is https://go.dev/cl/417874.  This fixes
https://go.dev/issue/23870.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* go-gcc.cc (Gcc_backend::struct_field_expression): Handle a void
expression, as for f().x where f returns a zero-sized type.
2b7b330427a60c8a5ef00d940adde0160ce04f27
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 7b4b2adb058..1ba7206caeb 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -1707,6 +1707,13 @@ Gcc_backend::struct_field_expression(Bexpression* 
bstruct, size_t index,
   if (struct_tree == error_mark_node
   || TREE_TYPE(struct_tree) == error_mark_node)
 return this->error_expression();
+
+  // A function call that returns a zero-sized object will have been
+  // changed to return void.  A zero-sized object can have a
+  // (zero-sized) field, so support that case.
+  if (TREE_TYPE(struct_tree) == void_type_node)
+return bstruct;
+
   gcc_assert(TREE_CODE(TREE_TYPE(struct_tree)) == RECORD_TYPE);
   tree field = TYPE_FIELDS(TREE_TYPE(struct_tree));
   if (field == NULL_TREE)


Go patch committed: Don't crash on f(g()) if g returns a zero-sized value

2022-07-15 Thread Ian Lance Taylor via Gcc-patches
This patch to the GCC interface of the Go frontend fixes a crash in
f(g()) if g returns a zero-sized value.  In that case the GCC
interface modifies g to return void, since GCC's middle-end does not
have solid support for zero-sized values.  This patch detects the
f(g()) case and replaces the call to g() with (g(), zero).  The test
case for this is https://go.dev/cl/417481.  This fixes
https://go.dev/issue/23868.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

* go-gcc.cc (Gcc_backend::call_expression): Handle a void
argument, as for f(g()) where g returns a zero-sized type.
1eb1495f7d0fa9b49f6f3c34bbbf4dd1e850607c
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index f3de7a8c183..7b4b2adb058 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -2112,6 +2112,19 @@ Gcc_backend::call_expression(Bfunction*, // containing 
fcn for call
   args[i] = fn_args.at(i)->get_tree();
   if (args[i] == error_mark_node)
 return this->error_expression();
+  if (TREE_TYPE(args[i]) == void_type_node)
+   {
+ // This can happen for a case like f(g()) where g returns a
+ // zero-sized type, because in that case we've changed g to
+ // return void.
+ tree t = TYPE_ARG_TYPES(TREE_TYPE(TREE_TYPE(fn)));
+ for (size_t j = 0; j < i; ++j)
+   t = TREE_CHAIN(t);
+ tree arg_type = TREE_TYPE(TREE_VALUE(t));
+ args[i] = fold_build2_loc(EXPR_LOCATION(args[i]), COMPOUND_EXPR,
+   arg_type, args[i],
+   build_zero_cst(arg_type));
+   }
 }
 
   tree fndecl = fn;


libgo patch committed: Don't include in sysinfo.c

2022-07-13 Thread Ian Lance Taylor via Gcc-patches
This libgo patch stops including  when building
gen-sysinfo.go.  Removing this doesn't change anything at least with
glibc 2.33.  The include was added in https://go.dev/cl/6100049 but
it's not clear why.  This should fix GCC PR 106266.  Bootstrapped and
ran Go testsuite on x86_64-pc-linux-gnu.  Committed to mainline.

Ian
9b487dbc298242fdde127e7827e728545c308aac
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 7c5c45672d7..5ea0406cd8e 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-d295a0a2c96c0f7c3abd94fea3aa4e2303bf2af2
+ff68b1a147eb60082fd60c198db0ef5477ade938
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/libgo/sysinfo.c b/libgo/sysinfo.c
index a4259c02ded..fc0210992fa 100644
--- a/libgo/sysinfo.c
+++ b/libgo/sysinfo.c
@@ -158,9 +158,6 @@
 #if defined(HAVE_LINUX_ETHER_H)
 #include 
 #endif
-#if defined(HAVE_LINUX_FS_H)
-#include 
-#endif
 #if defined(HAVE_LINUX_REBOOT_H)
 #include 
 #endif


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:


Go patch committed: Propagate array length error marker

2022-07-05 Thread Ian Lance Taylor via Gcc-patches
This patch to the Go frontend propagates the array length error marker
farther, to avoid a compiler crash on invalid code.  This fixes
https://go.dev/issue/53639.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
c70a48a8f8f6a43b35f783b5672c9a3c0a363c31
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 461e2fdf271..7c5c45672d7 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-a209dca9ec918535977dcab99fd9bb60986ffacd
+d295a0a2c96c0f7c3abd94fea3aa4e2303bf2af2
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 00d35a965a9..2492d9fe735 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -8486,6 +8486,11 @@ Builtin_call_expression::do_flatten(Gogo* gogo, 
Named_object* function,
 pa != this->args()->end();
 ++pa)
  {
+   if ((*pa)->is_error_expression())
+ {
+   go_assert(saw_errors());
+   return Expression::make_error(loc);
+ }
if ((*pa)->is_nil_expression())
  {
Expression* nil = Expression::make_nil(loc);
@@ -13391,6 +13396,7 @@ Array_index_expression::do_check_types(Gogo*)
   if (array_type == NULL)
 {
   go_assert(this->array_->type()->is_error());
+  this->set_is_error();
   return;
 }
 
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 4995283bb60..9f34801f695 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -7429,7 +7429,10 @@ bool
 Array_type::do_verify()
 {
   if (this->element_type()->is_error_type())
-return false;
+{
+  this->set_is_error();
+  return false;
+}
   if (!this->verify_length())
 {
   this->length_ = Expression::make_error(this->length_->location());


  1   2   3   4   5   6   7   >