[PATCH] Update config.guess and config.sub

2018-07-05 Thread Sebastian Huber
* config.guess: Sync with upstream version 2018-06-26.
* config.sub: Sync with upstream version 2018-07-02.
---
 config.guess | 6 +++---
 config.sub   | 8 +++-
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/config.guess b/config.guess
index 883a6713bf0..445c406836e 100755
--- a/config.guess
+++ b/config.guess
@@ -2,7 +2,7 @@
 # Attempt to guess a canonical system name.
 #   Copyright 1992-2018 Free Software Foundation, Inc.
 
-timestamp='2018-05-19'
+timestamp='2018-06-26'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -894,8 +894,8 @@ EOF
# other systems with GNU libc and userland
echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' 
| tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
exit ;;
-i*86:Minix:*:*)
-   echo "$UNAME_MACHINE"-pc-minix
+*:Minix:*:*)
+   echo "$UNAME_MACHINE"-unknown-minix
exit ;;
 aarch64:Linux:*:*)
echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
diff --git a/config.sub b/config.sub
index d1f5b549034..072700fb037 100755
--- a/config.sub
+++ b/config.sub
@@ -2,7 +2,7 @@
 # Configuration validation subroutine script.
 #   Copyright 1992-2018 Free Software Foundation, Inc.
 
-timestamp='2018-05-24'
+timestamp='2018-07-02'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -1125,6 +1125,12 @@ case $basic_machine in
ps2)
basic_machine=i386-ibm
;;
+   riscv)
+   basic_machine=riscv32-unknown
+   ;;
+   riscv-*)
+   basic_machine=`echo "$basic_machine" | sed 's/^riscv/riscv32/'`
+   ;;
rm[46]00)
basic_machine=mips-siemens
;;
-- 
2.13.7



Re: [PATCH] Update config.guess and config.sub

2018-07-05 Thread Sebastian Huber

On 05/07/18 14:00, Sebastian Huber wrote:

* config.guess: Sync with upstream version 2018-06-26.
* config.sub: Sync with upstream version 2018-07-02.


I would like to back port this also to GCC 8.

--
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail  : sebastian.hu...@embedded-brains.de
PGP : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.



Re: [PATCH] Update config.guess and config.sub

2018-07-05 Thread Sebastian Huber

On 05/07/18 18:51, Palmer Dabbelt wrote:


I'm not sure what the policy is on getting config stuff approved for 
commit, but just FYI there's another RISC-V related patch to 
config.sub that changes the behavior of "riscv-*" tuples.  I'm 
assuming we should take both, as it's odd to sync half way to the head 
of config. 


I updated Binutils (master and binutils-2_31-branch) and GCC (master) to 
use the latest versions of config.sub (2018-07-03) and config.guess  
(2018-06-26).


--
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail  : sebastian.hu...@embedded-brains.de
PGP : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.



Re: [PATCH] libatomic: Provide gthr.h default implementation

2023-05-30 Thread Sebastian Huber

On 30.05.23 11:53, Richard Biener wrote:

On Tue, May 23, 2023 at 11:28 AM Sebastian Huber
  wrote:

On 10.01.23 16:38, Sebastian Huber wrote:

On 19/12/2022 17:02, Sebastian Huber wrote:

Build libatomic for all targets.  Use gthr.h to provide a default
implementation.  If the thread model is "single", then this
implementation will
not work if for example atomic operations are used for thread/interrupt
synchronization.

Is this and the related -fprofile-update=atomic patch something for GCC 14?

Now that the GCC 14 development is in progress, what about this patch?

Sorry, there doesn't seem to be a main maintainer for libatomic and your patch
touches targets which didn't have it before.

Can you explain how this affects the ABI of targets not having (needing?!)
libatomic?  It might help if you can say this is still opt-in and targets not
building libatomic right now would not with your patch and targets already
building libatomic have no changes with your patch.

That said - what kind of ABI implications has providing libatomic support
for a target that didn't do so before?


Sorry for the missing context. The root problem I want to solve is 
getting gcov support for multi-threaded applications. For this we need 
atomic 64-bit operations, see also:


https://gcc.gnu.org/pipermail/gcc-patches/2022-December/608620.html

The libatomic patch lets it build for every target. Targets with no 
explicit support will use the gthr.h API to provide a default 
implementation.


An alternative would be to use the RTEMS approach which uses the 
following API (provided by Newlib  for RTEMS):


#include 
#include 

__BEGIN_DECLS

__uint32_t _Libatomic_Protect_start(void *);

void _Libatomic_Protect_end(void *, __uint32_t);

void _Libatomic_Lock_n(void *, __size_t);

void _Libatomic_Unlock_n(void *, __size_t);

__END_DECLS

We could also leave libatomic as is, but then you may get unresolved 
references if you use -fprofile-update=atomic with the patch mentioned 
above.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] libatomic: Provide gthr.h default implementation

2023-05-30 Thread Sebastian Huber

On 30.05.23 13:17, Richard Biener wrote:

The alternative would be to provide the required subset of atomic
library functions from libgcov.a and emit calls to that directly?
The locked data isn't part of any ABI so no compatibility guarantee
needs to be maintained?


So, if atomic operations are not available in hardware, then I should 
emit calls to libgcov.a which would use gthr.h to implement them? I 
guess that I can to this, but it needs a bit of time.


Should I add the libgcov functions to builtin_decl_explicit()?

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] Introduce hardbool attribute for C

2022-07-08 Thread Sebastian Huber

On 08.07.22 08:58, Richard Biener via Gcc-patches wrote:

On Thu, Jul 7, 2022 at 10:00 PM Alexandre Oliva via Gcc-patches
  wrote:


This patch introduces hardened booleans in C.  The hardbool attribute,
when attached to an integral type, turns it into an enumerate type
with boolean semantics, using the named or implied constants as
representations for false and true.

Expressions of such types decay to _Bool, trapping if the value is
neither true nor false, and _Bool can convert implicitly back to them.
Other conversions go through _Bool first.

Regstrapped on x86_64-linux-gnu.  Ok to install?

Does this follow some other compilers / language?  Is such feature used
in existing code?  Why is it useful to allow arbitrary values for true/false?
Why is the default 0 and ~0 rather than 0 and 1 as for _Bool?


Maybe this helps to catch errors caused by radiation which resulted in a 
bit flip in a processor register or other memory. If you use a single 
bit for true/false you can't detect such an error without special hardware.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] Add condition coverage profiling

2022-07-08 Thread Sebastian Huber

Hello Jørgen,

some time passed. It would be nice if you could give a status update. I 
am quite interested in your work.


Best regards,
Sebastian

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] Add condition coverage profiling

2022-07-12 Thread Sebastian Huber

Hello Jørgen,

thanks for the updated patch. I used it for a test suite run and the 
results look quite good.


Could you please add this hunk to your patch set:

diff --git a/libgcc/libgcov-merge.c b/libgcc/libgcov-merge.c
index 89741f637e1..9e3e8ee5657 100644
--- a/libgcc/libgcov-merge.c
+++ b/libgcc/libgcov-merge.c
@@ -33,6 +33,11 @@ void __gcov_merge_add (gcov_type *counters 
__attribute__ ((unused)),

unsigned n_counters __attribute__ ((unused))) {}
 #endif

+#ifdef L_gcov_merge_ior
+void __gcov_merge_ior (gcov_type *counters  __attribute__ ((unused)),
+  unsigned n_counters __attribute__ ((unused))) {}
+#endif
+
 #ifdef L_gcov_merge_topn
 void __gcov_merge_topn (gcov_type *counters  __attribute__ ((unused)),
unsigned n_counters __attribute__ ((unused))) {}

It is necessary to use gcov in freestanding environments (inhibit_libc 
is defined).


The condition profiling found one spot for which we have insufficient 
condition coverage:


function _Leap_year called 227 returned 100% blocks executed 100%
  227:   54:static bool _Leap_year(
-:   55:  uint32_t year
-:   56:)
-:   57:{
  227:   58:  return (((year % 4) == 0) && ((year % 100) != 0)) || 
((year % 400) == 0);

branch  0 taken 19% (fallthrough)
branch  1 taken 81%
branch  2 taken 16% (fallthrough)
branch  3 taken 84%
branch  4 taken 4% (fallthrough)
branch  5 taken 96%
conditions covered 5/6
condition  1 not covered (false)
-:   59:}

This is because we don't test with the year 2100 for example. This value 
would result in:


year % 4 == 0: true
year % 100 != 0: false
year % 400 == 0: false

It was not immediately clear to me what the

"conditions covered 5/6
condition  1 not covered (false)"

is supposed to tell me. I guess a reasonable interpretation is: 
condition 1 (which is "(year % 100) != 0" should be false and determine 
the outcome of the decision.


What could be a bit confusing is that we have "conditions covered 5/6", 
however, there are only three conditions (0: (year % 4) == 0, 1: (year % 
100) != 0, 2: (year % 400) == 0). Maybe it would be more clear if the 
report says "condition variants covered 5/6" or something like this.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] Add condition coverage profiling

2022-07-15 Thread Sebastian Huber

On 15.07.22 13:47, Jørgen Kvalsvik via Gcc-patches wrote:

2. New vocabulary for the output - decisions for, well, the decisions. It also
writes at most one line per condition:

decisions covered 1/4
condition  0 not covered (true false)
condition  1 not covered (true)


Do we really have multiple decisions? I think we have only one decision 
composed of conditions and zero or more boolean operators. We have 
variants of condition outcomes.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH] RTEMS: Add -ftls-model=local-exec to multilibs

2022-07-20 Thread Sebastian Huber
Use the local-exec TLS model for all multilibs of all RTEMS targets with proper
TLS support.

gcc/ChangeLog:

* config/arm/t-rtems (MULTILIB_EXTRA_OPTS): Define to use
-ftls-model=local-exec.
* config/i386/t-rtems (MULTILIB_EXTRA_OPTS): Likewise.
* config/m68k/t-rtems (MULTILIB_EXTRA_OPTS): Likewise.
* config/microblaze/t-rtems (MULTILIB_EXTRA_OPTS): Likewise.
* config/nios2/t-rtems (MULTILIB_EXTRA_OPTS): Likewise.
* config/riscv/t-rtems (MULTILIB_EXTRA_OPTS): Likewise.
* config/rs6000/t-rtems (MULTILIB_EXTRA_OPTS): Likewise.
* config/sparc/t-rtems (MULTILIB_EXTRA_OPTS): Likewise.
---
 gcc/config/arm/t-rtems| 1 +
 gcc/config/i386/t-rtems   | 1 +
 gcc/config/m68k/t-rtems   | 1 +
 gcc/config/microblaze/t-rtems | 1 +
 gcc/config/nios2/t-rtems  | 1 +
 gcc/config/riscv/t-rtems  | 2 ++
 gcc/config/rs6000/t-rtems | 1 +
 gcc/config/sparc/t-rtems  | 2 ++
 8 files changed, 10 insertions(+)

diff --git a/gcc/config/arm/t-rtems b/gcc/config/arm/t-rtems
index b2fcf572bca..aaf11355b11 100644
--- a/gcc/config/arm/t-rtems
+++ b/gcc/config/arm/t-rtems
@@ -8,6 +8,7 @@ MULTILIB_EXCEPTIONS =
 MULTILIB_REUSE =
 MULTILIB_MATCHES   =
 MULTILIB_REQUIRED  =
+MULTILIB_EXTRA_OPTS= ftls-model=local-exec
 
 # Enumeration of multilibs
 
diff --git a/gcc/config/i386/t-rtems b/gcc/config/i386/t-rtems
index 692c99484b3..83b95a6e53d 100644
--- a/gcc/config/i386/t-rtems
+++ b/gcc/config/i386/t-rtems
@@ -24,3 +24,4 @@ MULTILIB_MATCHES += march?pentium=march?k6 
march?pentiumpro=march?athlon
 MULTILIB_EXCEPTIONS = \
 march=pentium/*msoft-float* \
 march=pentiumpro/*msoft-float*
+MULTILIB_EXTRA_OPTS = ftls-model=local-exec
diff --git a/gcc/config/m68k/t-rtems b/gcc/config/m68k/t-rtems
index 0997afebc94..53a585e3018 100644
--- a/gcc/config/m68k/t-rtems
+++ b/gcc/config/m68k/t-rtems
@@ -7,3 +7,4 @@ M68K_MLIB_CPU += && (match(MLIB, "^68") \
 || MLIB == "5329" \
 || MLIB == "5407" \
 || MLIB == "5475")
+MULTILIB_EXTRA_OPTS = ftls-model=local-exec
diff --git a/gcc/config/microblaze/t-rtems b/gcc/config/microblaze/t-rtems
index d0c38261aaa..c9c9716ab62 100644
--- a/gcc/config/microblaze/t-rtems
+++ b/gcc/config/microblaze/t-rtems
@@ -1 +1,2 @@
 # Custom multilibs for RTEMS
+MULTILIB_EXTRA_OPTS = ftls-model=local-exec
diff --git a/gcc/config/nios2/t-rtems b/gcc/config/nios2/t-rtems
index beda8328bd2..3c9fbc69c83 100644
--- a/gcc/config/nios2/t-rtems
+++ b/gcc/config/nios2/t-rtems
@@ -8,6 +8,7 @@ MULTILIB_EXCEPTIONS =
 MULTILIB_REUSE =
 MULTILIB_MATCHES   =
 MULTILIB_REQUIRED  =
+MULTILIB_EXTRA_OPTS= ftls-model=local-exec
 
 # Enumeration of multilibs
 
diff --git a/gcc/config/riscv/t-rtems b/gcc/config/riscv/t-rtems
index 41f5927fc87..bb49e559ec5 100644
--- a/gcc/config/riscv/t-rtems
+++ b/gcc/config/riscv/t-rtems
@@ -1,3 +1,5 @@
+MULTILIB_EXTRA_OPTS= ftls-model=local-exec
+
 MULTILIB_OPTIONS   =
 MULTILIB_DIRNAMES  =
 
diff --git a/gcc/config/rs6000/t-rtems b/gcc/config/rs6000/t-rtems
index 4f8c147be3e..ba7177bf0f5 100644
--- a/gcc/config/rs6000/t-rtems
+++ b/gcc/config/rs6000/t-rtems
@@ -23,6 +23,7 @@ MULTILIB_DIRNAMES =
 MULTILIB_MATCHES =
 MULTILIB_EXCEPTIONS =
 MULTILIB_REQUIRED =
+MULTILIB_EXTRA_OPTS = ftls-model=local-exec
 
 MULTILIB_OPTIONS += 
mcpu=403/mcpu=505/mcpu=603e/mcpu=604/mcpu=860/mcpu=7400/mcpu=8540/mcpu=e6500
 MULTILIB_DIRNAMES += m403 m505 m603e m604 m860 m7400 m8540 me6500
diff --git a/gcc/config/sparc/t-rtems b/gcc/config/sparc/t-rtems
index c58836c1e96..1917eda322e 100644
--- a/gcc/config/sparc/t-rtems
+++ b/gcc/config/sparc/t-rtems
@@ -17,6 +17,8 @@
 # .
 #
 
+MULTILIB_EXTRA_OPTS = ftls-model=local-exec
+
 MULTILIB_OPTIONS = msoft-float mcpu=v8/mcpu=leon3/mcpu=leon3v7/mcpu=leon \
   mfix-ut699/mfix-at697f/mfix-gr712rc
 MULTILIB_DIRNAMES = soft v8 leon3 leon3v7 leon ut699 at697f gr712rc
-- 
2.35.3



[PATCH v2] RTEMS: Add -ftls-model=local-exec to multilibs

2022-07-21 Thread Sebastian Huber
Use the local-exec TLS model for all multilibs of all RTEMS targets with proper
TLS support.

gcc/ChangeLog:

* config.gcc (aarch64-*-rtems*): Extend tmake_file.
* config/arm/t-rtems (MULTILIB_EXTRA_OPTS): Define to use
-ftls-model=local-exec.
* config/i386/t-rtems (MULTILIB_EXTRA_OPTS): Likewise.
* config/m68k/t-rtems (MULTILIB_EXTRA_OPTS): Likewise.
* config/microblaze/t-rtems (MULTILIB_EXTRA_OPTS): Likewise.
* config/nios2/t-rtems (MULTILIB_EXTRA_OPTS): Likewise.
* config/riscv/t-rtems (MULTILIB_EXTRA_OPTS): Likewise.
* config/rs6000/t-rtems (MULTILIB_EXTRA_OPTS): Likewise.
* config/sparc/t-rtems (MULTILIB_EXTRA_OPTS): Likewise.
* config/aarch64/t-aarch64-rtems: New file.
---
v2:

* Include aarch64. This required a new RTEMS-specific file.

 gcc/config.gcc |  1 +
 gcc/config/aarch64/t-aarch64-rtems | 20 
 gcc/config/arm/t-rtems |  1 +
 gcc/config/i386/t-rtems|  1 +
 gcc/config/m68k/t-rtems|  1 +
 gcc/config/microblaze/t-rtems  |  1 +
 gcc/config/nios2/t-rtems   |  1 +
 gcc/config/riscv/t-rtems   |  2 ++
 gcc/config/rs6000/t-rtems  |  1 +
 gcc/config/sparc/t-rtems   |  2 ++
 10 files changed, 31 insertions(+)
 create mode 100644 gcc/config/aarch64/t-aarch64-rtems

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 4e3b15bb5e9..c8041723d2a 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1093,6 +1093,7 @@ aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems*)
 ;;
aarch64-*-rtems*)
tm_file="${tm_file} aarch64/rtems.h rtems.h"
+   tmake_file="${tmake_file} aarch64/t-aarch64-rtems"
;;
esac
case $target in
diff --git a/gcc/config/aarch64/t-aarch64-rtems 
b/gcc/config/aarch64/t-aarch64-rtems
new file mode 100644
index 000..049ea4fa7c0
--- /dev/null
+++ b/gcc/config/aarch64/t-aarch64-rtems
@@ -0,0 +1,20 @@
+# Machine description for AArch64 architecture.
+#  Copyright (C) 2022 Free Software Foundation, Inc.
+#
+#  This file is part of GCC.
+#
+#  GCC is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 3, or (at your option)
+#  any later version.
+#
+#  GCC is distributed in the hope that it will be useful, but
+#  WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with GCC; see the file COPYING3.  If not see
+#  .
+
+MULTILIB_EXTRA_OPTS = ftls-model=local-exec
diff --git a/gcc/config/arm/t-rtems b/gcc/config/arm/t-rtems
index b2fcf572bca..aaf11355b11 100644
--- a/gcc/config/arm/t-rtems
+++ b/gcc/config/arm/t-rtems
@@ -8,6 +8,7 @@ MULTILIB_EXCEPTIONS =
 MULTILIB_REUSE =
 MULTILIB_MATCHES   =
 MULTILIB_REQUIRED  =
+MULTILIB_EXTRA_OPTS= ftls-model=local-exec
 
 # Enumeration of multilibs
 
diff --git a/gcc/config/i386/t-rtems b/gcc/config/i386/t-rtems
index 692c99484b3..83b95a6e53d 100644
--- a/gcc/config/i386/t-rtems
+++ b/gcc/config/i386/t-rtems
@@ -24,3 +24,4 @@ MULTILIB_MATCHES += march?pentium=march?k6 
march?pentiumpro=march?athlon
 MULTILIB_EXCEPTIONS = \
 march=pentium/*msoft-float* \
 march=pentiumpro/*msoft-float*
+MULTILIB_EXTRA_OPTS = ftls-model=local-exec
diff --git a/gcc/config/m68k/t-rtems b/gcc/config/m68k/t-rtems
index 0997afebc94..53a585e3018 100644
--- a/gcc/config/m68k/t-rtems
+++ b/gcc/config/m68k/t-rtems
@@ -7,3 +7,4 @@ M68K_MLIB_CPU += && (match(MLIB, "^68") \
 || MLIB == "5329" \
 || MLIB == "5407" \
 || MLIB == "5475")
+MULTILIB_EXTRA_OPTS = ftls-model=local-exec
diff --git a/gcc/config/microblaze/t-rtems b/gcc/config/microblaze/t-rtems
index d0c38261aaa..c9c9716ab62 100644
--- a/gcc/config/microblaze/t-rtems
+++ b/gcc/config/microblaze/t-rtems
@@ -1 +1,2 @@
 # Custom multilibs for RTEMS
+MULTILIB_EXTRA_OPTS = ftls-model=local-exec
diff --git a/gcc/config/nios2/t-rtems b/gcc/config/nios2/t-rtems
index beda8328bd2..3c9fbc69c83 100644
--- a/gcc/config/nios2/t-rtems
+++ b/gcc/config/nios2/t-rtems
@@ -8,6 +8,7 @@ MULTILIB_EXCEPTIONS =
 MULTILIB_REUSE =
 MULTILIB_MATCHES   =
 MULTILIB_REQUIRED  =
+MULTILIB_EXTRA_OPTS= ftls-model=local-exec
 
 # Enumeration of multilibs
 
diff --git a/gcc/config/riscv/t-rtems b/gcc/config/riscv/t-rtems
index 41f5927fc87..bb49e559ec5 100644
--- a/gcc/config/riscv/t-rtems
+++ b/gcc/config/riscv/t-rtems
@@ -1,3 +1,5 @@
+MULTILIB_EXTRA_OPTS= ftls-model=local-exec
+
 MULTILIB_OPTIONS   =
 MULTILIB_DIRNAMES  =
 
diff --git a/gcc/config/rs6000/t-rtems b/gcc/config/rs6000/t-rtems
index 4f8c147be3e..ba71

[GCC 12] libstdc++: Fix lifetime bugs for non-TLS eh_globals [PR105880]

2022-07-21 Thread Sebastian Huber
From: Jonathan Wakely 

This ensures that the single-threaded fallback buffer eh_globals is not
destroyed during program termination, using the same immortalization
technique used for error category objects.

Also ensure that init._M_init can still be read after init has been
destroyed, by making it a static data member.

libstdc++-v3/ChangeLog:

PR libstdc++/105880
* libsupc++/eh_globals.cc (eh_globals): Ensure constant init and
prevent destruction during termination.
(__eh_globals_init::_M_init): Replace with static member _S_init.
(__cxxabiv1::__cxa_get_globals_fast): Update.
(__cxxabiv1::__cxa_get_globals): Likewise.

(cherry picked from commit 1e65f2ed99024f23c56f7b6a961898bcaa882a92)
---

Would it be acceptable to back port this fix to GCC 12?

 libstdc++-v3/libsupc++/eh_globals.cc | 51 
 1 file changed, 37 insertions(+), 14 deletions(-)

diff --git a/libstdc++-v3/libsupc++/eh_globals.cc 
b/libstdc++-v3/libsupc++/eh_globals.cc
index 3a003b89edf..768425c0f40 100644
--- a/libstdc++-v3/libsupc++/eh_globals.cc
+++ b/libstdc++-v3/libsupc++/eh_globals.cc
@@ -64,8 +64,26 @@ __cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
 
 #else
 
-// Single-threaded fallback buffer.
-static __cxa_eh_globals eh_globals;
+#if __has_cpp_attribute(clang::require_constant_initialization)
+#  define __constinit [[clang::require_constant_initialization]]
+#endif
+
+namespace
+{
+  struct constant_init
+  {
+union {
+  unsigned char unused;
+  __cxa_eh_globals obj;
+};
+constexpr constant_init() : obj() { }
+
+~constant_init() { /* do nothing, union member is not destroyed */ }
+  };
+
+  // Single-threaded fallback buffer.
+  __constinit constant_init eh_globals;
+}
 
 #if __GTHREADS
 
@@ -90,32 +108,37 @@ eh_globals_dtor(void* ptr)
 struct __eh_globals_init
 {
   __gthread_key_t  _M_key;
-  bool _M_init;
+  static bool  _S_init;
 
-  __eh_globals_init() : _M_init(false)
-  { 
+  __eh_globals_init()
+  {
 if (__gthread_active_p())
-  _M_init = __gthread_key_create(&_M_key, eh_globals_dtor) == 0; 
+  _S_init = __gthread_key_create(&_M_key, eh_globals_dtor) == 0;
   }
 
   ~__eh_globals_init()
   {
-if (_M_init)
+if (_S_init)
   __gthread_key_delete(_M_key);
-_M_init = false;
+_S_init = false;
   }
+
+  __eh_globals_init(const __eh_globals_init&) = delete;
+  __eh_globals_init& operator=(const __eh_globals_init&) = delete;
 };
 
+bool __eh_globals_init::_S_init = false;
+
 static __eh_globals_init init;
 
 extern "C" __cxa_eh_globals*
 __cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
 {
   __cxa_eh_globals* g;
-  if (init._M_init)
+  if (init._S_init)
 g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key));
   else
-g = &eh_globals;
+g = &eh_globals.obj;
   return g;
 }
 
@@ -123,7 +146,7 @@ extern "C" __cxa_eh_globals*
 __cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
 {
   __cxa_eh_globals* g;
-  if (init._M_init)
+  if (init._S_init)
 {
   g = static_cast<__cxa_eh_globals*>(__gthread_getspecific(init._M_key));
   if (!g)
@@ -140,7 +163,7 @@ __cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
}
 }
   else
-g = &eh_globals;
+g = &eh_globals.obj;
   return g;
 }
 
@@ -148,11 +171,11 @@ __cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
 
 extern "C" __cxa_eh_globals*
 __cxxabiv1::__cxa_get_globals_fast() _GLIBCXX_NOTHROW
-{ return &eh_globals; }
+{ return &eh_globals.obj; }
 
 extern "C" __cxa_eh_globals*
 __cxxabiv1::__cxa_get_globals() _GLIBCXX_NOTHROW
-{ return &eh_globals; }
+{ return &eh_globals.obj; }
 
 #endif
 
-- 
2.35.3



[PATCH 2/2] RTEMS: Use local-exec TLS model by default

2022-07-22 Thread Sebastian Huber
gcc/ChangeLog:

* config/rtems.h (SUBTARGET_CC1_SPEC): Undef and define.
---
 gcc/config/rtems.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/config/rtems.h b/gcc/config/rtems.h
index 95bcdc41b2f..4742b1f3722 100644
--- a/gcc/config/rtems.h
+++ b/gcc/config/rtems.h
@@ -56,3 +56,7 @@
 /* Prefer int for int32_t (see stdint-newlib.h).  */
 #undef STDINT_LONG32
 #define STDINT_LONG32 (INT_TYPE_SIZE != 32 && LONG_TYPE_SIZE == 32)
+
+/* Default to local-exec TLS model.  */
+#undef SUBTARGET_CC1_SPEC
+#define SUBTARGET_CC1_SPEC " %{!ftls-model=*:-ftls-model=local-exec}"
-- 
2.35.3



[PATCH 1/2] Allow subtarget customization of CC1_SPEC

2022-07-22 Thread Sebastian Huber
gcc/ChangeLog:

* gcc.cc (SUBTARGET_CC1_SPEC): Define if not defined.
(CC1_SPEC): Define to SUBTARGET_CC1_SPEC.
* config/arm/arm.h (CC1_SPEC): Remove.
* config/arc/arc.h (CC1_SPEC): Append SUBTARGET_CC1_SPEC.
* config/cris/cris.h (CC1_SPEC): Likewise.
* config/frv/frv.h (CC1_SPEC): Likewise.
* config/i386/i386.h (CC1_SPEC): Likewise.
* config/ia64/ia64.h (CC1_SPEC): Likewise.
* config/lm32/lm32.h (CC1_SPEC): Likewise.
* config/m32r/m32r.h (CC1_SPEC): Likewise.
* config/mcore/mcore.h (CC1_SPEC): Likewise.
* config/microblaze/microblaze.h: Likewise.
* config/nds32/nds32.h (CC1_SPEC): Likewise.
* config/nios2/nios2.h (CC1_SPEC): Likewise.
* config/pa/pa.h (CC1_SPEC): Likewise.
* config/rs6000/sysv4.h (CC1_SPEC): Likewise.
* config/rx/rx.h (CC1_SPEC): Likewise.
* config/sparc/sparc.h (CC1_SPEC): Likewise.
---
 gcc/config/arc/arc.h   | 3 ++-
 gcc/config/arm/arm.h   | 4 
 gcc/config/cris/cris.h | 3 ++-
 gcc/config/frv/frv.h   | 2 +-
 gcc/config/i386/i386.h | 2 +-
 gcc/config/ia64/ia64.h | 2 +-
 gcc/config/lm32/lm32.h | 2 +-
 gcc/config/m32r/m32r.h | 2 +-
 gcc/config/mcore/mcore.h   | 2 +-
 gcc/config/microblaze/microblaze.h | 3 ++-
 gcc/config/nds32/nds32.h   | 2 +-
 gcc/config/nios2/nios2.h   | 2 +-
 gcc/config/pa/pa.h | 2 +-
 gcc/config/rs6000/sysv4.h  | 3 ++-
 gcc/config/rx/rx.h | 3 ++-
 gcc/config/sparc/sparc.h   | 2 +-
 gcc/gcc.cc | 8 +++-
 17 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index 539a1662084..177287b11aa 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -68,7 +68,8 @@ along with GCC; see the file COPYING3.  If not see
 #define CC1_SPEC "%{EB:%{EL:%emay not use both -EB and -EL}}   \
 %{EB:-mbig-endian} %{EL:-mlittle-endian}   \
 %{G*}  \
-"
+"  \
+SUBTARGET_CC1_SPEC
 extern const char *arc_cpu_to_as (int argc, const char **argv);
 
 #define EXTRA_SPEC_FUNCTIONS   \
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index f479540812a..24fdf7fde23 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -91,10 +91,6 @@ extern tree arm_bf16_ptr_type_node;
 #undef  CPP_SPEC
 #define CPP_SPEC "%(subtarget_cpp_spec)"
 
-#ifndef CC1_SPEC
-#define CC1_SPEC ""
-#endif
-
 /* This macro defines names of additional specifications to put in the specs
that can be used in various specifications like CC1_SPEC.  Its definition
is an initializer with a subgrouping for each command option.
diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h
index 6edfe13d92c..ed89b3fa6b0 100644
--- a/gcc/config/cris/cris.h
+++ b/gcc/config/cris/cris.h
@@ -135,7 +135,8 @@ extern int cris_cpu_version;
   %{metrax100:-march=v8}\
   %{march=*:-march=%*}\
   %{mcpu=*:-mcpu=%*}\
-  %(cc1_subtarget)"
+  %(cc1_subtarget)" \
+  SUBTARGET_CC1_SPEC
 
 /* For the cris-*-elf subtarget.  */
 #define CRIS_CC1_SUBTARGET_SPEC \
diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h
index 8cd67f75b09..b0f39ee238e 100644
--- a/gcc/config/frv/frv.h
+++ b/gcc/config/frv/frv.h
@@ -115,7 +115,7 @@
 
Do not define this macro if it does not need to do anything.  */
 /* For ABI compliance, we need to put bss data into the normal data section.  
*/
-#define CC1_SPEC "%{G*}"
+#define CC1_SPEC "%{G*}" SUBTARGET_CC1_SPEC
 
 #undef LINK_SPEC
 #define LINK_SPEC "\
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index f16df633e84..f1ceb6b2557 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -614,7 +614,7 @@ extern const char *host_detect_local_cpu (int argc, const 
char **argv);
 #define TARGET_D_HAS_STDCALL_CONVENTION ix86_d_has_stdcall_convention
 
 #ifndef CC1_SPEC
-#define CC1_SPEC "%(cc1_cpu) "
+#define CC1_SPEC "%(cc1_cpu) " SUBTARGET_CC1_SPEC
 #endif
 
 /* This macro defines names of additional specifications to put in the
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index bd0ef35e9a4..0e11cef0edc 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -51,7 +51,7 @@ do {  \
   { "asm_extra", ASM_EXTRA_SPEC }, \
   SUBTARGET_EXTRA_SPECS
 
-#define CC1_SPEC "%(cc1_cpu) "
+#define CC1_SPEC "%(cc1_cpu) " SUBTARGET_CC1_SPEC
 
 #define ASM_EXTRA_SPEC ""
 
diff --git a/gcc/config/lm32/lm32.h b/gcc/config/lm32/lm32.h
index 23f66c90446..65a9141cd94 100644
--- a/gcc/config/lm32/lm32.h
+++ b/gcc/config/lm32/lm32.h
@@ -63,7 +63,7 @@
 #define LIB_SPEC "%{!T*:-T sim.ld}"
 
 #undef  CC1_SPEC
-#define CC1_SPEC "%{G*}"
+#define CC1_SPEC "%{G*}" SUBTARGET_CC1_SPEC
 
 /*---

Re: [PATCH 1/2] Allow subtarget customization of CC1_SPEC

2022-07-24 Thread Sebastian Huber

Hallo Jose,

On 22/07/2022 16:02, Jose E. Marchesi wrote:

I find "subtarget" confusing in this context.

If it is about rtems.h, linux.h or sol2.h, wouldn't this be better
called OS_CC1_SPEC or similar?  These files specify configurations that
apply to a set of targets, not to a subset of a target...


Iain Sandoe told me that for the GCC implementation the OSs are 
sub-targets of the architecture:


https://gcc.gnu.org/pipermail/gcc/2022-July/239158.html

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] Add condition coverage profiling

2022-08-04 Thread Sebastian Huber

On 02/08/2022 09:58, Jørgen Kvalsvik wrote:

Based on this established terminology I can think of a few good candidates:

condition outcomes covered n/m
outcomes covered n/m

What do you think?


Both are fine, but I would prefer "condition outcomes covered n/m".

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH 1/2] Allow subtarget customization of CC1_SPEC

2022-08-04 Thread Sebastian Huber

On 22/07/2022 15:02, Sebastian Huber wrote:

gcc/ChangeLog:

* gcc.cc (SUBTARGET_CC1_SPEC): Define if not defined.
(CC1_SPEC): Define to SUBTARGET_CC1_SPEC.
* config/arm/arm.h (CC1_SPEC): Remove.
* config/arc/arc.h (CC1_SPEC): Append SUBTARGET_CC1_SPEC.
* config/cris/cris.h (CC1_SPEC): Likewise.
* config/frv/frv.h (CC1_SPEC): Likewise.
* config/i386/i386.h (CC1_SPEC): Likewise.
* config/ia64/ia64.h (CC1_SPEC): Likewise.
* config/lm32/lm32.h (CC1_SPEC): Likewise.
* config/m32r/m32r.h (CC1_SPEC): Likewise.
* config/mcore/mcore.h (CC1_SPEC): Likewise.
* config/microblaze/microblaze.h: Likewise.
* config/nds32/nds32.h (CC1_SPEC): Likewise.
* config/nios2/nios2.h (CC1_SPEC): Likewise.
* config/pa/pa.h (CC1_SPEC): Likewise.
* config/rs6000/sysv4.h (CC1_SPEC): Likewise.
* config/rx/rx.h (CC1_SPEC): Likewise.
* config/sparc/sparc.h (CC1_SPEC): Likewise.


Could someone please have a look at this patch set?

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] libgomp: Fix build for -fshort-enums

2023-07-03 Thread Sebastian Huber

On 22.05.23 14:51, Sebastian Huber wrote:

Make sure that the API enums have at least the size of int.  Otherwise the
following build error may occur:

In file included from gcc/libgomp/env.c:34:
./libgomp_f.h: In function 'omp_check_defines':
./libgomp_f.h:77:8: error: size of array 'test' is negative
77 |   char test[(28 != sizeof (omp_lock_t)
   |^~~~

libgomp/ChangeLog:

* omp.h.in (omp_alloctrait_key_t):  Add __omp_alloctrait_key_t_max__
with a value of the int type maximum.
---
  libgomp/omp.h.in | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libgomp/omp.h.in b/libgomp/omp.h.in
index bd1286c2a3f..3b1612fcb15 100644
--- a/libgomp/omp.h.in
+++ b/libgomp/omp.h.in
@@ -146,7 +146,8 @@ typedef enum omp_alloctrait_key_t
omp_atk_fallback = 5,
omp_atk_fb_data = 6,
omp_atk_pinned = 7,
-  omp_atk_partition = 8
+  omp_atk_partition = 8,
+  __omp_alloctrait_key_t_max__ = __INT_MAX__
  } omp_alloctrait_key_t;
  
  typedef enum omp_alloctrait_value_t


Could someone please have a look at this.

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[gcc] RTEMS: Tune multilib selection

2023-02-23 Thread Sebastian Huber
gcc/ChangeLog:

* config/riscv/t-rtems: Keep only -mcmodel=medany 64-bit multilibs.
Add non-compact 32-bit multilibs.
---
 gcc/config/riscv/t-rtems | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/gcc/config/riscv/t-rtems b/gcc/config/riscv/t-rtems
index 41f5927fc87..19b12030895 100644
--- a/gcc/config/riscv/t-rtems
+++ b/gcc/config/riscv/t-rtems
@@ -1,8 +1,8 @@
 MULTILIB_OPTIONS   =
 MULTILIB_DIRNAMES  =
 
-MULTILIB_OPTIONS   += 
march=rv32i/march=rv32im/march=rv32imafd/march=rv32iac/march=rv32imac/march=rv32imafc/march=rv64imafd/march=rv64imac/march=rv64imafdc
-MULTILIB_DIRNAMES  += rv32i   rv32im   rv32imafd   rv32iac 
  rv32imac   rv32imafc   rv64imafd   rv64imac   rv64imafdc
+MULTILIB_OPTIONS   += 
march=rv32i/march=rv32iac/march=rv32im/march=rv32ima/march=rv32imac/march=rv32imaf/march=rv32imafc/march=rv32imafd/march=rv32imafdc/march=rv64ima/march=rv64imac/march=rv64imafd/march=rv64imafdc
+MULTILIB_DIRNAMES  += rv32i   rv32iac   rv32im   rv32ima   
rv32imac   rv32imaf   rv32imafc   rv32imafd   rv32imafdc   
rv64ima   rv64imac   rv64imafd   rv64imafdc
 
 MULTILIB_OPTIONS   += 
mabi=ilp32/mabi=ilp32f/mabi=ilp32d/mabi=lp64/mabi=lp64d
 MULTILIB_DIRNAMES  += ilp32  ilp32f  ilp32d  lp64  lp64d
@@ -12,14 +12,15 @@ MULTILIB_DIRNAMES   += medany
 
 MULTILIB_REQUIRED  =
 MULTILIB_REQUIRED  += march=rv32i/mabi=ilp32
-MULTILIB_REQUIRED  += march=rv32im/mabi=ilp32
-MULTILIB_REQUIRED  += march=rv32imafd/mabi=ilp32d
 MULTILIB_REQUIRED  += march=rv32iac/mabi=ilp32
+MULTILIB_REQUIRED  += march=rv32im/mabi=ilp32
+MULTILIB_REQUIRED  += march=rv32ima/mabi=ilp32
 MULTILIB_REQUIRED  += march=rv32imac/mabi=ilp32
+MULTILIB_REQUIRED  += march=rv32imaf/mabi=ilp32f
 MULTILIB_REQUIRED  += march=rv32imafc/mabi=ilp32f
-MULTILIB_REQUIRED  += march=rv64imafd/mabi=lp64d
-MULTILIB_REQUIRED  += march=rv64imafd/mabi=lp64d/mcmodel=medany
-MULTILIB_REQUIRED  += march=rv64imac/mabi=lp64
+MULTILIB_REQUIRED  += march=rv32imafd/mabi=ilp32d
+MULTILIB_REQUIRED  += march=rv32imafdc/mabi=ilp32d
+MULTILIB_REQUIRED  += march=rv64ima/mabi=lp64/mcmodel=medany
 MULTILIB_REQUIRED  += march=rv64imac/mabi=lp64/mcmodel=medany
-MULTILIB_REQUIRED  += march=rv64imafdc/mabi=lp64d
+MULTILIB_REQUIRED  += march=rv64imafd/mabi=lp64d/mcmodel=medany
 MULTILIB_REQUIRED  += march=rv64imafdc/mabi=lp64d/mcmodel=medany
-- 
2.35.3



Re: [gcc] RTEMS: Tune multilib selection

2023-02-23 Thread Sebastian Huber

On 23.02.23 19:38, Palmer Dabbelt wrote:
On Thu, 23 Feb 2023 03:48:26 PST (-0800), 
sebastian.hu...@embedded-brains.de wrote:

gcc/ChangeLog:

* config/riscv/t-rtems: Keep only -mcmodel=medany 64-bit multilibs.
Add non-compact 32-bit multilibs.
---
 gcc/config/riscv/t-rtems | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/gcc/config/riscv/t-rtems b/gcc/config/riscv/t-rtems
index 41f5927fc87..19b12030895 100644
--- a/gcc/config/riscv/t-rtems
+++ b/gcc/config/riscv/t-rtems
@@ -1,8 +1,8 @@
 MULTILIB_OPTIONS    =
 MULTILIB_DIRNAMES    =

-MULTILIB_OPTIONS    += 
march=rv32i/march=rv32im/march=rv32imafd/march=rv32iac/march=rv32imac/march=rv32imafc/march=rv64imafd/march=rv64imac/march=rv64imafdc
-MULTILIB_DIRNAMES    += rv32i   rv32im   rv32imafd 
rv32iac   rv32imac   rv32imafc   rv64imafd rv64imac   
rv64imafdc
+MULTILIB_OPTIONS    += 
march=rv32i/march=rv32iac/march=rv32im/march=rv32ima/march=rv32imac/march=rv32imaf/march=rv32imafc/march=rv32imafd/march=rv32imafdc/march=rv64ima/march=rv64imac/march=rv64imafd/march=rv64imafdc
+MULTILIB_DIRNAMES    += rv32i   rv32iac   rv32im 
rv32ima   rv32imac   rv32imaf   rv32imafc rv32imafd   
rv32imafdc   rv64ima   rv64imac rv64imafd   rv64imafdc


 MULTILIB_OPTIONS    += 
mabi=ilp32/mabi=ilp32f/mabi=ilp32d/mabi=lp64/mabi=lp64d
 MULTILIB_DIRNAMES    += ilp32  ilp32f  ilp32d  lp64  
lp64d

@@ -12,14 +12,15 @@ MULTILIB_DIRNAMES    += medany

 MULTILIB_REQUIRED    =
 MULTILIB_REQUIRED    += march=rv32i/mabi=ilp32
-MULTILIB_REQUIRED    += march=rv32im/mabi=ilp32
-MULTILIB_REQUIRED    += march=rv32imafd/mabi=ilp32d
 MULTILIB_REQUIRED    += march=rv32iac/mabi=ilp32
+MULTILIB_REQUIRED    += march=rv32im/mabi=ilp32
+MULTILIB_REQUIRED    += march=rv32ima/mabi=ilp32
 MULTILIB_REQUIRED    += march=rv32imac/mabi=ilp32
+MULTILIB_REQUIRED    += march=rv32imaf/mabi=ilp32f
 MULTILIB_REQUIRED    += march=rv32imafc/mabi=ilp32f
-MULTILIB_REQUIRED    += march=rv64imafd/mabi=lp64d
-MULTILIB_REQUIRED    += march=rv64imafd/mabi=lp64d/mcmodel=medany
-MULTILIB_REQUIRED    += march=rv64imac/mabi=lp64
+MULTILIB_REQUIRED    += march=rv32imafd/mabi=ilp32d
+MULTILIB_REQUIRED    += march=rv32imafdc/mabi=ilp32d
+MULTILIB_REQUIRED    += march=rv64ima/mabi=lp64/mcmodel=medany
 MULTILIB_REQUIRED    += march=rv64imac/mabi=lp64/mcmodel=medany
-MULTILIB_REQUIRED    += march=rv64imafdc/mabi=lp64d
+MULTILIB_REQUIRED    += march=rv64imafd/mabi=lp64d/mcmodel=medany
 MULTILIB_REQUIRED    += march=rv64imafdc/mabi=lp64d/mcmodel=medany


Reviewed-by: Palmer Dabbelt 

IMO it's fine to remove multilibs from the default set.  It could be 
seen as breaking users, but IIRC last time we talked about something 
like this it was OK as otherwise we're going to end up with a huge set 
of multilibs for defunct ISAs.  This one is also extra safe, since 
moving to medany shouldn't break any users (aside from maybe a slight 
performance issue).


Thanks for the review. Which performance issue may show up here?


Are you aiming for GCC-13 with this?  I wouldn't be opposed to that: 
there's some risk of breaking users this late in the process, but my 
guess is that most of them aren't looking until release anyway.  Still 
better to hold off, but if there's something in RTEMS land that benefits 
from this being early then I think it's fine.


RTEMS has its own release cycle, so I would back port this change to all 
GCC branches which may be used with RTEMS 6 and this is GCC 10 or later.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH] libgomp: Fix build for -fshort-enums

2023-05-22 Thread Sebastian Huber
Make sure that the API enums have at least the size of int.  Otherwise the
following build error may occur:

In file included from gcc/libgomp/env.c:34:
./libgomp_f.h: In function 'omp_check_defines':
./libgomp_f.h:77:8: error: size of array 'test' is negative
   77 |   char test[(28 != sizeof (omp_lock_t)
  |^~~~

libgomp/ChangeLog:

* omp.h.in (omp_alloctrait_key_t):  Add __omp_alloctrait_key_t_max__
with a value of the int type maximum.
---
 libgomp/omp.h.in | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libgomp/omp.h.in b/libgomp/omp.h.in
index bd1286c2a3f..3b1612fcb15 100644
--- a/libgomp/omp.h.in
+++ b/libgomp/omp.h.in
@@ -146,7 +146,8 @@ typedef enum omp_alloctrait_key_t
   omp_atk_fallback = 5,
   omp_atk_fb_data = 6,
   omp_atk_pinned = 7,
-  omp_atk_partition = 8
+  omp_atk_partition = 8,
+  __omp_alloctrait_key_t_max__ = __INT_MAX__
 } omp_alloctrait_key_t;
 
 typedef enum omp_alloctrait_value_t
-- 
2.35.3



Re: [PATCH] libatomic: Provide gthr.h default implementation

2023-05-23 Thread Sebastian Huber

On 10.01.23 16:38, Sebastian Huber wrote:

On 19/12/2022 17:02, Sebastian Huber wrote:

Build libatomic for all targets.  Use gthr.h to provide a default
implementation.  If the thread model is "single", then this 
implementation will

not work if for example atomic operations are used for thread/interrupt
synchronization.


Is this and the related -fprofile-update=atomic patch something for GCC 14?


Now that the GCC 14 development is in progress, what about this patch?

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH] RTEMS: Fix GCC specification

2021-01-22 Thread Sebastian Huber
The use of -nostdlib and -nodefaultlibs disables the processing of
LIB_SPEC (%L) as specified by LINK_COMMAND_SPEC and thus disables the
default linker script for RTEMS.  Move the linker script to
STARTFILE_SPEC which is controlled by -nostdlib and -nostartfiles.  This
fits better since the linker script defines the platform start file
provided by the board support package in RTEMS.

gcc/

* config/rtems.h (STARTFILE_SPEC): Remove nostdlib and
nostartfiles handling since this is already done by
LINK_COMMAND_SPEC.  Evaluate qnolinkcmds.
(ENDFILE_SPEC): Remove nostdlib and nostartfiles handling since this
is already done by LINK_COMMAND_SPEC.
(LIB_SPECS): Remove nostdlib and nodefaultlibs handling since
this is already done by LINK_COMMAND_SPEC.  Remove qnolinkcmds
evaluation.
---
 gcc/config/rtems.h | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/gcc/config/rtems.h b/gcc/config/rtems.h
index 743161c4bac..e5cba75d345 100644
--- a/gcc/config/rtems.h
+++ b/gcc/config/rtems.h
@@ -36,11 +36,11 @@
  */
 #undef STARTFILE_SPEC
 #define STARTFILE_SPEC "%{!qrtems:crt0%O%s} " \
-"%{qrtems:%{!nostdlib:%{!nostartfiles:" RTEMS_STARTFILE_SPEC "}}}"
+"%{qrtems:" RTEMS_STARTFILE_SPEC " %{!qnolinkcmds:-T linkcmds%s}}"
 
 #undef ENDFILE_SPEC
 #define ENDFILE_SPEC \
-"%{qrtems:%{!nostdlib:%{!nostartfiles:" RTEMS_ENDFILE_SPEC "}}}"
+"%{qrtems:" RTEMS_ENDFILE_SPEC "}"
 
 /*
  * Some targets do not set up LIB_SPECS, override it, here.
@@ -49,9 +49,7 @@
 
 #undef LIB_SPEC
 #define LIB_SPEC "%{!qrtems:" STD_LIB_SPEC "} " \
-"%{qrtems:%{!nostdlib:%{!nodefaultlibs:" \
-"--start-group -lrtemsbsp -lrtemscpu -latomic -lc -lgcc --end-group} " \
-"%{!qnolinkcmds:-T linkcmds%s}}}"
+"%{qrtems:--start-group -lrtemsbsp -lrtemscpu -latomic -lc -lgcc --end-group}"
 
 #define TARGET_POSIX_IO
 
-- 
2.26.2



Re: [PATCH] RISC-V: Always define MULTILIB_DEFAULTS

2021-01-25 Thread Sebastian Huber

Hello Kito,

On 20/11/2020 09:33, Kito Cheng wrote:

  - Define MULTILIB_DEFAULTS can reduce the total number of multilib if
the default arch and ABI are listed in the multilib config.

  - This also simplify the implementation of --with-multilib-list.

gcc/ChangeLog:

* config.gcc (riscv*-*-*): Add TARGET_RISCV_DEFAULT_ABI and
TARGET_RISCV_DEFAULT_ARCH to tm_defines.
Remove including riscv/withmultilib.h for --with-multilib-list.
* config/riscv/riscv.h (STRINGIZING): New.
(__STRINGIZING): Ditto.
(MULTILIB_DEFAULTS): Ditto.
* config/riscv/withmultilib.h: Remove.


I think this change broke the multilib generation for RTEMS (git 
bisect). I had to apply this local patch to build 
a5ad5d5c478ee7bebf057161bb8715ee7d286875:


diff --git a/gcc/config.gcc b/gcc/config.gcc
index 6f1ee62f7fd..7449c470265 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -4612,7 +4612,6 @@ case "${target}" in
    exit 1
    ;;
    esac
- with_arch=`${srcdir}/config/riscv/arch-canonicalize ${with_arch}`
    tm_defines="${tm_defines} 
TARGET_RISCV_DEFAULT_ARCH=${with_arch}"


    # Make sure --with-abi is valid.  If it was not specified,

With this commit we have:

./gcc/xgcc -print-multi-lib
.;
rv32i/ilp32;@march=rv32i@mabi=ilp32
rv32im/ilp32;@march=rv32im@mabi=ilp32
rv32iac/ilp32;@march=rv32iac@mabi=ilp32
rv32imac/ilp32;@march=rv32imac@mabi=ilp32
rv32imafc/ilp32f;@march=rv32imafc@mabi=ilp32f
rv64imafd/lp64d;@march=rv64imafd@mabi=lp64d
rv64imafd/lp64d/medany;@march=rv64imafd@mabi=lp64d@mcmodel=medany
rv64imac/lp64;@march=rv64imac@mabi=lp64
rv64imac/lp64/medany;@march=rv64imac@mabi=lp64@mcmodel=medany
rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d
rv64imafdc/lp64d/medany;@march=rv64imafdc@mabi=lp64d@mcmodel=medany

./gcc/xgcc -print-multi-directory -march=rv32imafd -mabi=ilp32d
rv32imafd/ilp32d

So for this option set it prints a multilib directory which is not 
listed. Also GCC seems to use this directory for the search paths and 
cannot find multilib specific C++ header files for example.


In the commit before (3a5d8ed231a0329822b7c032ba0834991732d2a0) we have:

./gcc/xgcc -print-multi-lib
.;
rv32i/ilp32;@march=rv32i@mabi=ilp32
rv32im/ilp32;@march=rv32im@mabi=ilp32
rv32imafd/ilp32d;@march=rv32imafd@mabi=ilp32d <-- HERE
rv32iac/ilp32;@march=rv32iac@mabi=ilp32
rv32imac/ilp32;@march=rv32imac@mabi=ilp32
rv32imafc/ilp32f;@march=rv32imafc@mabi=ilp32f
rv64imafd/lp64d;@march=rv64imafd@mabi=lp64d
rv64imafd/lp64d/medany;@march=rv64imafd@mabi=lp64d@mcmodel=medany
rv64imac/lp64;@march=rv64imac@mabi=lp64
rv64imac/lp64/medany;@march=rv64imac@mabi=lp64@mcmodel=medany
rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d
rv64imafdc/lp64d/medany;@march=rv64imafdc@mabi=lp64d@mcmodel=medany

./gcc/xgcc -print-multi-directory -march=rv32imafd -mabi=ilp32d
rv32imafd/ilp32d

I was not able to figure out what prevents the generation of the 
rv32imafd/ilp32d multilib in commit 
a5ad5d5c478ee7bebf057161bb8715ee7d286875. The gcc/tm.h contains this:


gcc/tm.h:#ifndef TARGET_RISCV_DEFAULT_ARCH
gcc/tm.h:# define TARGET_RISCV_DEFAULT_ARCH rv32gc
gcc/tm.h:#ifndef TARGET_RISCV_DEFAULT_ABI
gcc/tm.h:# define TARGET_RISCV_DEFAULT_ABI ilp32d

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/



Re: [PATCH] PR target/98878 - Incorrect multilib list for riscv*-rtems

2021-02-04 Thread Sebastian Huber

On 04/02/2021 11:01, Kito Cheng wrote:


gcc/ChangeLog:

* gcc.c (print_multilib_info): Check all required argument is provided
by default arg.


Thanks, with this patch the riscv-rtems* target works again.

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/



Re: [PATCH v3] gcov: Add __gcov_info_to_gdca()

2021-08-05 Thread Sebastian Huber

On 05/08/2021 14:53, Martin Liška wrote:

On 7/23/21 11:39 AM, Sebastian Huber wrote:
Add __gcov_info_to_gcda() to libgcov to get the gcda data for a gcda 
info in a

freestanding environment.  It is intended to be used with the
-fprofile-info-section option.  A crude test program which doesn't use 
a linker
script is (use "gcc -coverage -fprofile-info-section -lgcc test.c" to 
compile

it):


The patch can be installed once the following nits are fixed:


Thanks for the review, I checked it in like this:

https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=9124bbe1857f0d3a3015d6461d5f8d04f07cab85

I hope the format is now all right.

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH v3] gcov: Add __gcov_info_to_gdca()

2021-08-06 Thread Sebastian Huber

Hello Christophe,

On 06/08/2021 09:50, Christophe Lyon wrote:

Looks like there's a problem with your patch:
  
/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc1/./gcc/xgcc
 
-B/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc1/./gcc/
 
-B/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/bin/
 
-B/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/lib/
 -isystem 
/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/include
 -isystem 
/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/tools/arm-none-eabi/sys-include
    -g -O2 -O2  -g -O2 -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE  -W -Wall 
-Wno-narrowing -Wwrite-strings -Wcast-qual -Wstrict-prototypes 
-Wmissing-prototypes -Wold-style-definition  -isystem ./include -fno-inline -g 
-DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc  -fno-inline 
-I. -I. -I../.././gcc 
-I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc 
-I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/. 
-I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/../gcc 
-I/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/../include    
-o _gcov.o -MT _gcov.o -MD -MP -MF _gcov.dep -DL_gcov -c 
/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/libgcov-driver.c

In file included from 
/tmp/1784442_7.tmpdir/aci-gcc-fsf/sources/gcc-fsf/gccsrc/libgcc/libgcov-driver.c:29:
/tmp/1784442_7.tmpdir/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-arm-none-eabi/gcc1/gcc/include/stdint.h:9:16: 
fatal error: stdint.h: No such file or directory

     9 | # include_next 
       |                ^~
compilation terminated.
make[2]: *** [Makefile:928: _gcov.o] Error 1
make[2]: *** Waiting for unfinished jobs

Can you check?


I already feared that the  include may cause problems, from 
the commit message:


"With this patch,  is included in libgcov-driver.c even if 
inhibit_libc is defined.  This header file should be also available for 
freestanding environments.  If this is not the case, then we have to 
define intptr_t somehow."


What about the attached patch?

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/
>From 9e91c623116313312408a8809f32eac1f7ef6b16 Mon Sep 17 00:00:00 2001
From: Sebastian Huber 
Date: Fri, 6 Aug 2021 09:57:43 +0200
Subject: [PATCH] gcov: Remove  from libgcov-driver.c

In the patch to add __gcov_info_to_gcda(), the include of  was added
to libgcov-driver.c even if inhibit_libc is defined.  It turned out that this
header file is not always available.  Remove the include of  and
replace the intptr_t with the compiler provided __INTPTR_TYPE__.

libgcc/

	* libgcov-driver.c (#include ): Remove.
	(write_topn_counters): Use __INTPTR_TYPE__ instead of intptr_t.
---
 libgcc/libgcov-driver.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 9d7bc9c79950..087f71e01077 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -26,8 +26,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #include "libgcov.h"
 #include "gcov-io.h"
 
-#include 
-
 /* Return 1, if all counter values are zero, otherwise 0. */
 
 static inline int
@@ -453,7 +451,7 @@ write_topn_counters (const struct gcov_ctr_info *ci_ptr,
   gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2];
   unsigned sizes = 0;
 
-  for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start;
+  for (struct gcov_kvp *node = (struct gcov_kvp *)(__INTPTR_TYPE__)start;
 	   node != NULL; node = node->next)
 	++sizes;
 
@@ -472,7 +470,7 @@ write_topn_counters (const struct gcov_ctr_info *ci_ptr,
   gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2];
 
   unsigned j = 0;
-  for (struct gcov_kvp *node = (struct gcov_kvp *)(intptr_t)start;
+  for (struct gcov_kvp *node = (struct gcov_kvp *)(__INTPTR_TYPE__)start;
 	   j < list_sizes[i]; node = node->next, j++)
 	{
 	  dump_counter (node->value, dump_fn, arg);
-- 
2.26.2



Re: [PATCH v3] gcov: Add __gcov_info_to_gdca()

2021-08-06 Thread Sebastian Huber

On 06/08/2021 12:26, Martin Liška wrote:

On 8/6/21 10:05 AM, Sebastian Huber wrote:

What about the attached patch?


The patch is fine, please install it.


Thanks, I checked it in.

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH] gcov: Add -fprofile-update=force-atomic

2021-08-09 Thread Sebastian Huber
If get_gcov_type() returns a 64-bit type, then 64-bit atomic operations in
hardware are required for the "atomic" method.  Add a new method to force
atomic operations even if a library implementation (libatomic) must be used.

gcc/

* common.opt (fprofile-update): Add force-atomic method.
* coretypes.h (profile_update): Add PROFILE_UPDATE_FORCE_ATOMIC.
* doc/invoke.texi (fprofile-update): Document force-atomic method.
* tree-profile.c (tree_profiling): Support force-atomic method.
---
 gcc/common.opt  |  5 -
 gcc/coretypes.h |  3 ++-
 gcc/doc/invoke.texi | 14 +-
 gcc/tree-profile.c  |  2 ++
 4 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/gcc/common.opt b/gcc/common.opt
index d9da1131eda..ea887c987af 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2247,7 +2247,7 @@ Enable correction of flow inconsistent profile data input.
 
 fprofile-update=
 Common Joined RejectNegative Enum(profile_update) Var(flag_profile_update) 
Init(PROFILE_UPDATE_SINGLE)
--fprofile-update=[single|atomic|prefer-atomic] Set the profile update method.
+-fprofile-update=[single|atomic|prefer-atomic|force-atomic]Set the profile 
update method.
 
 fprofile-filter-files=
 Common Joined RejectNegative Var(flag_profile_filter_files)
@@ -2285,6 +2285,9 @@ Enum(profile_update) String(atomic) 
Value(PROFILE_UPDATE_ATOMIC)
 EnumValue
 Enum(profile_update) String(prefer-atomic) Value(PROFILE_UPDATE_PREFER_ATOMIC)
 
+EnumValue
+Enum(profile_update) String(force-atomic) Value(PROFILE_UPDATE_FORCE_ATOMIC)
+
 fprofile-prefix-path=
 Common Joined RejectNegative Var(profile_prefix_path)
 Remove prefix from absolute path before mangling name for -fprofile-generate= 
and -fprofile-use=.
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 406572e947d..ded8e718994 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -209,7 +209,8 @@ enum offload_abi {
 enum profile_update {
   PROFILE_UPDATE_SINGLE,
   PROFILE_UPDATE_ATOMIC,
-  PROFILE_UPDATE_PREFER_ATOMIC
+  PROFILE_UPDATE_PREFER_ATOMIC,
+  PROFILE_UPDATE_FORCE_ATOMIC
 };
 
 /* Type of profile reproducibility methods.  */
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index a64cec5387e..df920545ac1 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -14905,11 +14905,11 @@ part of the path and keep all file names relative to 
the main build directory.
 @item -fprofile-update=@var{method}
 @opindex fprofile-update
 
-Alter the update method for an application instrumented for profile
-feedback based optimization.  The @var{method} argument should be one of
-@samp{single}, @samp{atomic} or @samp{prefer-atomic}.
-The first one is useful for single-threaded applications,
-while the second one prevents profile corruption by emitting thread-safe code.
+Alter the update method for an application instrumented for profile feedback
+based optimization or code-coverage.  The @var{method} argument should be one
+of @samp{single}, @samp{atomic}, @samp{prefer-atomic} or @samp{force-atomic}.
+The first one is useful for single-threaded applications, while the second one
+prevents profile corruption by emitting thread-safe code.
 
 @strong{Warning:} When an application does not properly join all threads
 (or creates an detached thread), a profile file can be still corrupted.
@@ -14919,6 +14919,10 @@ when supported by a target, or to @samp{single} 
otherwise.  The GCC driver
 automatically selects @samp{prefer-atomic} when @option{-pthread}
 is present in the command line.
 
+Using @samp{force-atomic} forces the use of an @samp{atomic} method even if the
+target does not support it directly in hardware and a library implementation
+must be used instead.
+
 @item -fprofile-filter-files=@var{regex}
 @opindex fprofile-filter-files
 
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 5a74cc96e13..ac2ef4ccdf2 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -718,6 +718,8 @@ tree_profiling (void)
   else if (flag_profile_update == PROFILE_UPDATE_PREFER_ATOMIC)
 flag_profile_update = can_support_atomic
   ? PROFILE_UPDATE_ATOMIC : PROFILE_UPDATE_SINGLE;
+  else if (flag_profile_update == PROFILE_UPDATE_FORCE_ATOMIC)
+flag_profile_update = PROFILE_UPDATE_ATOMIC;
 
   /* This is a small-ipa pass that gets called only once, from
  cgraphunit.c:ipa_passes().  */
-- 
2.26.2



Re: [PATCH] gcov: Add -fprofile-update=force-atomic

2021-08-09 Thread Sebastian Huber




On 09/08/2021 12:19, Richard Biener wrote:

On Mon, Aug 9, 2021 at 10:01 AM Sebastian Huber
  wrote:

If get_gcov_type() returns a 64-bit type, then 64-bit atomic operations in
hardware are required for the "atomic" method.  Add a new method to force
atomic operations even if a library implementation (libatomic) must be used.

I do wonder about the =atomic behavior here - I'd expected that to
be equivalent to force-atomic...


Yes, this method just maps to the "atomic" method:

+  else if (flag_profile_update == PROFILE_UPDATE_FORCE_ATOMIC)
+flag_profile_update = PROFILE_UPDATE_ATOMIC;



With =force-atomic the user will need to eventually link to -latomic
himself, correct?  What happens for targets that do not have libatomic support?
See libatomic/configure.tgt - is that something we can test for and error/warn?


The compiler will generate a library call:

main:
save%sp, -96, %sp
mov 0, %o3
mov 1, %o2
mov 0, %o1
sethi   %hi(__gcov0.main), %o0
call__atomic_fetch_add_8, 0
 or %o0, %lo(__gcov0.main), %o0
sethi   %hi(x), %g1
ld  [%g1+%lo(x)], %i0
jmp %i7+8
 restore

The __atomic_fetch_add_8 is usually provided by libatomic. If a target 
doesn't have it, then you get a linker error. I am not sure how the 
compiler could warn, since it is built before libatomic.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH] gcov: Add GCOV_TYPE_SIZE target macro

2021-08-09 Thread Sebastian Huber
If -fprofile-update=atomic is used, then the target must provide atomic
operations for the counters of the type returned by get_gcov_type().
This is a 64-bit type for targets which have a 64-bit long long type.
On 32-bit targets this could be an issue since they may not provide
64-bit atomic operations.  Allow targets to override the default type
size with the new GCOV_TYPE_SIZE target macro.

gcc/

* config/sparc/rtemself.h (GCOV_TYPE_SIZE): Define.
* coverage.c (get_gcov_type): Use GCOV_TYPE_SIZE.
* defaults.h (GCOV_TYPE_SIZE): Define default.
* tree-profile.c (gimple_gen_edge_profiler): Use precision of
gcov_type_node.
(gimple_gen_time_profiler): Likewise.
---
 gcc/config/sparc/rtemself.h | 2 ++
 gcc/coverage.c  | 3 +--
 gcc/defaults.h  | 4 
 gcc/tree-profile.c  | 4 ++--
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/gcc/config/sparc/rtemself.h b/gcc/config/sparc/rtemself.h
index fa972af640c..ac4f70c48c4 100644
--- a/gcc/config/sparc/rtemself.h
+++ b/gcc/config/sparc/rtemself.h
@@ -40,3 +40,5 @@
 
 /* Use the default */
 #undef LINK_GCC_C_SEQUENCE_SPEC
+
+#define GCOV_TYPE_SIZE 32
diff --git a/gcc/coverage.c b/gcc/coverage.c
index ac9a9fdad22..e655c164d66 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -145,8 +145,7 @@ static void coverage_obj_finish (vec *);
 tree
 get_gcov_type (void)
 {
-  scalar_int_mode mode
-= smallest_int_mode_for_size (LONG_LONG_TYPE_SIZE > 32 ? 64 : 32);
+  scalar_int_mode mode = smallest_int_mode_for_size (GCOV_TYPE_SIZE);
   return lang_hooks.types.type_for_mode (mode, false);
 }
 
diff --git a/gcc/defaults.h b/gcc/defaults.h
index ba79a8e48ed..1cf06d26176 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -1475,4 +1475,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 typedef TARGET_UNIT target_unit;
 #endif
 
+#ifndef GCOV_TYPE_SIZE
+#define GCOV_TYPE_SIZE (LONG_LONG_TYPE_SIZE > 32 ? 64 : 32)
+#endif
+
 #endif  /* ! GCC_DEFAULTS_H */
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 5a74cc96e13..cf46912631c 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -250,7 +250,7 @@ gimple_gen_edge_profiler (int edgeno, edge e)
 {
   /* __atomic_fetch_add (&counter, 1, MEMMODEL_RELAXED); */
   tree addr = tree_coverage_counter_addr (GCOV_COUNTER_ARCS, edgeno);
-  tree f = builtin_decl_explicit (LONG_LONG_TYPE_SIZE > 32
+  tree f = builtin_decl_explicit (TYPE_PRECISION (gcov_type_node) > 32
  ? BUILT_IN_ATOMIC_FETCH_ADD_8:
  BUILT_IN_ATOMIC_FETCH_ADD_4);
   gcall *stmt = gimple_build_call (f, 3, addr, one,
@@ -525,7 +525,7 @@ gimple_gen_time_profiler (unsigned tag)
  tree_time_profiler_counter);
   gassign *assign = gimple_build_assign (ptr, NOP_EXPR, addr);
   gsi_insert_before (&gsi, assign, GSI_NEW_STMT);
-  tree f = builtin_decl_explicit (LONG_LONG_TYPE_SIZE > 32
+  tree f = builtin_decl_explicit (TYPE_PRECISION (gcov_type_node) > 32
  ? BUILT_IN_ATOMIC_ADD_FETCH_8:
  BUILT_IN_ATOMIC_ADD_FETCH_4);
   gcall *stmt = gimple_build_call (f, 3, ptr, one,
-- 
2.26.2



Re: [PATCH] gcov: Add -fprofile-update=force-atomic

2021-08-09 Thread Sebastian Huber

On 09/08/2021 10:00, Sebastian Huber wrote:

If get_gcov_type() returns a 64-bit type, then 64-bit atomic operations in
hardware are required for the "atomic" method.  Add a new method to force
atomic operations even if a library implementation (libatomic) must be used.

gcc/

* common.opt (fprofile-update): Add force-atomic method.
* coretypes.h (profile_update): Add PROFILE_UPDATE_FORCE_ATOMIC.
* doc/invoke.texi (fprofile-update): Document force-atomic method.
* tree-profile.c (tree_profiling): Support force-atomic method.


This patch was replaced by a different approach:

https://gcc.gnu.org/pipermail/gcc-patches/2021-August/576993.html

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] gcov: Add GCOV_TYPE_SIZE target macro

2021-08-09 Thread Sebastian Huber

On 09/08/2021 15:58, Sebastian Huber wrote:

If -fprofile-update=atomic is used, then the target must provide atomic
operations for the counters of the type returned by get_gcov_type().
This is a 64-bit type for targets which have a 64-bit long long type.
On 32-bit targets this could be an issue since they may not provide
64-bit atomic operations.  Allow targets to override the default type
size with the new GCOV_TYPE_SIZE target macro.

gcc/

* config/sparc/rtemself.h (GCOV_TYPE_SIZE): Define.
* coverage.c (get_gcov_type): Use GCOV_TYPE_SIZE.
* defaults.h (GCOV_TYPE_SIZE): Define default.
* tree-profile.c (gimple_gen_edge_profiler): Use precision of
gcov_type_node.
(gimple_gen_time_profiler): Likewise.


The patch is incorrect. With this patch the compiler view of the gcov 
type doesn't match the libgcov view. I have to do some changes in 
libgcov.h in this area:


#if LONG_LONG_TYPE_SIZE > 32
typedef signed gcov_type __attribute__ ((mode (DI)));
typedef unsigned gcov_type_unsigned __attribute__ ((mode (DI)));
#else
typedef signed gcov_type __attribute__ ((mode (SI)));
typedef unsigned gcov_type_unsigned __attribute__ ((mode (SI)));
#endif

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH v2] gcov: Add GCOV_TYPE_SIZE target macro

2021-08-09 Thread Sebastian Huber
If -fprofile-update=atomic is used, then the target must provide atomic
operations for the counters of the type returned by get_gcov_type().
This is a 64-bit type for targets which have a 64-bit long long type.
On 32-bit targets this could be an issue since they may not provide
64-bit atomic operations.  Allow targets to override the default type
size with the new GCOV_TYPE_SIZE target macro.

If a 32-bit gcov type size is used, then there is currently a warning in
libgcov-driver.c in a dead code block due to
sizeof (counter) == sizeof (gcov_unsigned_t):

libgcc/libgcov-driver.c: In function 'dump_counter':
libgcc/libgcov-driver.c:401:46: warning: right shift count >= width of type 
[-Wshift-count-overflow]
  401 | dump_unsigned ((gcov_unsigned_t)(counter >> 32), dump_fn, arg);
  |  ^~

gcc/

* config/sparc/rtemself.h (GCOV_TYPE_SIZE): Define.
* coverage.c (get_gcov_type): Use GCOV_TYPE_SIZE.
* defaults.h (GCOV_TYPE_SIZE): Define default.
* tree-profile.c (gimple_gen_edge_profiler): Use precision of
gcov_type_node.
(gimple_gen_time_profiler): Likewise.

libgcc/

* libgcov.h (gcov_type): Define using GCOV_TYPE_SIZE.
(gcov_type_unsigned): Likewise.
---
 gcc/config/sparc/rtemself.h | 2 ++
 gcc/coverage.c  | 3 +--
 gcc/defaults.h  | 8 
 gcc/tree-profile.c  | 4 ++--
 libgcc/libgcov.h| 6 +++---
 5 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/gcc/config/sparc/rtemself.h b/gcc/config/sparc/rtemself.h
index fa972af640cc..ac4f70c48c43 100644
--- a/gcc/config/sparc/rtemself.h
+++ b/gcc/config/sparc/rtemself.h
@@ -40,3 +40,5 @@
 
 /* Use the default */
 #undef LINK_GCC_C_SEQUENCE_SPEC
+
+#define GCOV_TYPE_SIZE 32
diff --git a/gcc/coverage.c b/gcc/coverage.c
index ac9a9fdad228..e655c164d664 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -145,8 +145,7 @@ static void coverage_obj_finish (vec *);
 tree
 get_gcov_type (void)
 {
-  scalar_int_mode mode
-= smallest_int_mode_for_size (LONG_LONG_TYPE_SIZE > 32 ? 64 : 32);
+  scalar_int_mode mode = smallest_int_mode_for_size (GCOV_TYPE_SIZE);
   return lang_hooks.types.type_for_mode (mode, false);
 }
 
diff --git a/gcc/defaults.h b/gcc/defaults.h
index ba79a8e48edd..242ae7a75a09 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -1475,4 +1475,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. 
 If not, see
 typedef TARGET_UNIT target_unit;
 #endif
 
+#ifndef GCOV_TYPE_SIZE
+#if LONG_LONG_TYPE_SIZE > 32
+#define GCOV_TYPE_SIZE 64
+#else
+#define GCOV_TYPE_SIZE 32
+#endif
+#endif
+
 #endif  /* ! GCC_DEFAULTS_H */
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 5a74cc96e132..cf46912631cb 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -250,7 +250,7 @@ gimple_gen_edge_profiler (int edgeno, edge e)
 {
   /* __atomic_fetch_add (&counter, 1, MEMMODEL_RELAXED); */
   tree addr = tree_coverage_counter_addr (GCOV_COUNTER_ARCS, edgeno);
-  tree f = builtin_decl_explicit (LONG_LONG_TYPE_SIZE > 32
+  tree f = builtin_decl_explicit (TYPE_PRECISION (gcov_type_node) > 32
  ? BUILT_IN_ATOMIC_FETCH_ADD_8:
  BUILT_IN_ATOMIC_FETCH_ADD_4);
   gcall *stmt = gimple_build_call (f, 3, addr, one,
@@ -525,7 +525,7 @@ gimple_gen_time_profiler (unsigned tag)
  tree_time_profiler_counter);
   gassign *assign = gimple_build_assign (ptr, NOP_EXPR, addr);
   gsi_insert_before (&gsi, assign, GSI_NEW_STMT);
-  tree f = builtin_decl_explicit (LONG_LONG_TYPE_SIZE > 32
+  tree f = builtin_decl_explicit (TYPE_PRECISION (gcov_type_node) > 32
  ? BUILT_IN_ATOMIC_ADD_FETCH_8:
  BUILT_IN_ATOMIC_ADD_FETCH_4);
   gcall *stmt = gimple_build_call (f, 3, ptr, one,
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 9c537253293f..ffa93c89cb0d 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -52,7 +52,7 @@
 #if __CHAR_BIT__ == 8
 typedef unsigned gcov_unsigned_t __attribute__ ((mode (SI)));
 typedef unsigned gcov_position_t __attribute__ ((mode (SI)));
-#if LONG_LONG_TYPE_SIZE > 32
+#if GCOV_TYPE_SIZE > 32
 typedef signed gcov_type __attribute__ ((mode (DI)));
 typedef unsigned gcov_type_unsigned __attribute__ ((mode (DI)));
 #else
@@ -63,7 +63,7 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode 
(SI)));
 #if __CHAR_BIT__ == 16
 typedef unsigned gcov_unsigned_t __attribute__ ((mode (HI)));
 typedef unsigned gcov_position_t __attribute__ ((mode (HI)));
-#if LONG_LONG_TYPE_SIZE > 32
+#if GCOV_TYPE_SIZE > 32
 typedef signed gcov_type __attribute__ ((mode (SI)));
 typedef unsigned gcov_type_unsigned __attribute__ ((mode (SI)));
 #else
@@ -73,7 +73,7 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode 
(HI)));
 #else
 typedef unsigned gcov_unsigned_t __attribute__ ((mode

Re: [PATCH v2] gcov: Add GCOV_TYPE_SIZE target macro

2021-08-10 Thread Sebastian Huber

On 10/08/2021 19:30, Joseph Myers wrote:

On Tue, 10 Aug 2021, Sebastian Huber wrote:


If -fprofile-update=atomic is used, then the target must provide atomic
operations for the counters of the type returned by get_gcov_type().
This is a 64-bit type for targets which have a 64-bit long long type.
On 32-bit targets this could be an issue since they may not provide
64-bit atomic operations.  Allow targets to override the default type
size with the new GCOV_TYPE_SIZE target macro.

Any target macro needs to be documented in tm.texi.in (and tm.texi
regenerated).

Please don't add new target macros that are used in both host and target
code; every such macro is an obstruction to removing inclusion of the host
tm.h from libgcc.  The appropriate way to handle sharing such
configuration information is to provide a target hook in the host compiler
code, and then make c-cppbuiltin.c:c_cpp_builtins define a corresponding
predefined macro under the "if (flag_building_libgcc)" conditional.
(Although a target hook is generally preferable to a target macro for
host-side configuration, when a target macro is used on the host it's
still desirable not to use it directly in target libraries but to use a
predefined macro instead.)


Ok, I understood how I can add a compiler provided define for libgcov. 
What is not clear to me is how I can add a target hook, set a default 
value, and customize it for a target/system. Is this described here


https://gcc.gnu.org/onlinedocs/gccint/Target-Structure.html

?

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH v3] gcov: Add TARGET_GCOV_TYPE_SIZE target macro

2021-08-10 Thread Sebastian Huber
If -fprofile-update=atomic is used, then the target must provide atomic
operations for the counters of the type returned by get_gcov_type().
This is a 64-bit type for targets which have a 64-bit long long type.
On 32-bit targets this could be an issue since they may not provide
64-bit atomic operations.  Allow targets to override the default type
size with the new TARGET_GCOV_TYPE_SIZE target macro.

If a 32-bit gcov type size is used, then there is currently a warning in
libgcov-driver.c in a dead code block due to
sizeof (counter) == sizeof (gcov_unsigned_t):

libgcc/libgcov-driver.c: In function 'dump_counter':
libgcc/libgcov-driver.c:401:46: warning: right shift count >= width of type 
[-Wshift-count-overflow]
  401 | dump_unsigned ((gcov_unsigned_t)(counter >> 32), dump_fn, arg);
  |  ^~

gcc/

* c-family/c-cppbuiltin.c (c_cpp_builtins): Define
__LIBGCC_GCOV_TYPE_SIZE if flag_building_libgcc is true.
* config/sparc/rtemself.h (TARGET_GCOV_TYPE_SIZE): Redefine.
* coverage.c (get_gcov_type): Use targetm.gcov_type_size.
* doc/tm.texi (TARGET_GCOV_TYPE_SIZE): Add hook under "Misc".
* doc/tm.texi.in: Regenerate.
* target.def (gcov_type_size): New POD hook.
* tree-profile.c (gimple_gen_edge_profiler): Use precision of
gcov_type_node.
(gimple_gen_time_profiler): Likewise.

libgcc/

* libgcov.h (gcov_type): Define using __LIBGCC_GCOV_TYPE_SIZE.
(gcov_type_unsigned): Likewise.
---
 gcc/c-family/c-cppbuiltin.c |  2 ++
 gcc/config/sparc/rtemself.h |  3 +++
 gcc/coverage.c  |  3 +--
 gcc/doc/tm.texi | 11 +++
 gcc/doc/tm.texi.in  |  2 ++
 gcc/target.def  | 12 
 gcc/tree-profile.c  |  4 ++--
 libgcc/libgcov.h|  6 +++---
 8 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index f79f939bd10f..e85b60c79f49 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -1450,6 +1450,8 @@ c_cpp_builtins (cpp_reader *pfile)
   /* For libgcov.  */
   builtin_define_with_int_value ("__LIBGCC_VTABLE_USES_DESCRIPTORS__",
 TARGET_VTABLE_USES_DESCRIPTORS);
+  builtin_define_with_int_value ("__LIBGCC_GCOV_TYPE_SIZE",
+TARGET_GCOV_TYPE_SIZE);
 }
 
   /* For use in assembly language.  */
diff --git a/gcc/config/sparc/rtemself.h b/gcc/config/sparc/rtemself.h
index fa972af640cc..87a3ceb640c0 100644
--- a/gcc/config/sparc/rtemself.h
+++ b/gcc/config/sparc/rtemself.h
@@ -40,3 +40,6 @@
 
 /* Use the default */
 #undef LINK_GCC_C_SEQUENCE_SPEC
+
+#undef TARGET_GCOV_TYPE_SIZE
+#define TARGET_GCOV_TYPE_SIZE 32
diff --git a/gcc/coverage.c b/gcc/coverage.c
index ac9a9fdad228..6166247ad179 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -145,8 +145,7 @@ static void coverage_obj_finish (vec *);
 tree
 get_gcov_type (void)
 {
-  scalar_int_mode mode
-= smallest_int_mode_for_size (LONG_LONG_TYPE_SIZE > 32 ? 64 : 32);
+  scalar_int_mode mode = smallest_int_mode_for_size (targetm.gcov_type_size);
   return lang_hooks.types.type_for_mode (mode, false);
 }
 
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index a30fdcbbf3d6..429e7edf0e9d 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -12588,3 +12588,14 @@ Return an RTX representing @var{tagged_pointer} with 
its tag set to zero.
 Store the result in @var{target} if convenient.
 The default clears the top byte of the original pointer.
 @end deftypefn
+
+@deftypevr {Target Hook} HOST_WIDE_INT TARGET_GCOV_TYPE_SIZE
+The gcov type size in bits.  This type is used for example for counters
+incremented by profiling and code-coverage events.  The default value is 64,
+if the type size of long long is greater than 32, otherwise the default
+value is 32.  A 64-bit type is recommended to avoid overflows of the
+counters.  If the @option{-fprofile-update=atomic} is used, then the
+counters are incremented using atomic operations.  Targets not supporting
+64-bit atomic operations may override the default value and request a 32-bit
+type.
+@end deftypevr
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 611fc500ac86..fdf16b901c53 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -8180,3 +8180,5 @@ maintainer is familiar with.
 @hook TARGET_MEMTAG_EXTRACT_TAG
 
 @hook TARGET_MEMTAG_UNTAGGED_POINTER
+
+@hook TARGET_GCOV_TYPE_SIZE
diff --git a/gcc/target.def b/gcc/target.def
index 7676d5e626e3..b94c2c40dcf1 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -7104,6 +7104,18 @@ DEFHOOK
  void, (void),
  NULL)
 
+DEFHOOKPOD
+(gcov_type_size,
+ "The gcov type size in bits.  This type is used for example for counters\n\
+incremented by profiling and code-coverage events.  The default value is 64,\n\
+if the type size of long long is greater than 32, otherwise the default\n\
+value is 3

[PATCH v4] gcov: Add TARGET_GCOV_TYPE_SIZE target hook

2021-08-12 Thread Sebastian Huber
If -fprofile-update=atomic is used, then the target must provide atomic
operations for the counters of the type returned by get_gcov_type().
This is a 64-bit type for targets which have a 64-bit long long type.
On 32-bit targets this could be an issue since they may not provide
64-bit atomic operations.  Allow targets to override the default type
size with the new TARGET_GCOV_TYPE_SIZE target hook.

If a 32-bit gcov type size is used, then there is currently a warning in
libgcov-driver.c in a dead code block due to
sizeof (counter) == sizeof (gcov_unsigned_t):

libgcc/libgcov-driver.c: In function 'dump_counter':
libgcc/libgcov-driver.c:401:46: warning: right shift count >= width of type 
[-Wshift-count-overflow]
  401 | dump_unsigned ((gcov_unsigned_t)(counter >> 32), dump_fn, arg);
  |  ^~

gcc/

* c-family/c-cppbuiltin.c (c_cpp_builtins): Define
__LIBGCC_GCOV_TYPE_SIZE if flag_building_libgcc is true.
* config/sparc/rtemself.h (SPARC_GCOV_TYPE_SIZE): Define.
* config/sparc/sparc.c (sparc_gcov_type_size): New.
(TARGET_GCOV_TYPE_SIZE): Redefine if SPARC_GCOV_TYPE_SIZE is defined.
* coverage.c (get_gcov_type): Use targetm.gcov_type_size().
* doc/tm.texi (TARGET_GCOV_TYPE_SIZE): Add hook under "Misc".
* doc/tm.texi.in: Regenerate.
* target.def (gcov_type_size): New target hook.
* targhooks.c (default_gcov_type_size): New.
* targhooks.h (default_gcov_type_size): Declare.
* tree-profile.c (gimple_gen_edge_profiler): Use precision of
gcov_type_node.
(gimple_gen_time_profiler): Likewise.

libgcc/

* libgcov.h (gcov_type): Define using __LIBGCC_GCOV_TYPE_SIZE.
(gcov_type_unsigned): Likewise.
---
 gcc/c-family/c-cppbuiltin.c |  2 ++
 gcc/config/sparc/rtemself.h |  2 ++
 gcc/config/sparc/sparc.c| 11 +++
 gcc/coverage.c  |  2 +-
 gcc/doc/tm.texi | 11 +++
 gcc/doc/tm.texi.in  |  2 ++
 gcc/target.def  | 12 
 gcc/targhooks.c |  7 +++
 gcc/targhooks.h |  2 ++
 gcc/tree-profile.c  |  4 ++--
 libgcc/libgcov.h|  6 +++---
 11 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index f79f939bd10f..3fa62bc4fe76 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -1450,6 +1450,8 @@ c_cpp_builtins (cpp_reader *pfile)
   /* For libgcov.  */
   builtin_define_with_int_value ("__LIBGCC_VTABLE_USES_DESCRIPTORS__",
 TARGET_VTABLE_USES_DESCRIPTORS);
+  builtin_define_with_int_value ("__LIBGCC_GCOV_TYPE_SIZE",
+targetm.gcov_type_size());
 }
 
   /* For use in assembly language.  */
diff --git a/gcc/config/sparc/rtemself.h b/gcc/config/sparc/rtemself.h
index fa972af640cc..d64ce9012daf 100644
--- a/gcc/config/sparc/rtemself.h
+++ b/gcc/config/sparc/rtemself.h
@@ -40,3 +40,5 @@
 
 /* Use the default */
 #undef LINK_GCC_C_SEQUENCE_SPEC
+
+#define SPARC_GCOV_TYPE_SIZE 32
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 04fc80f0ee62..06f41d7bb53f 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -944,6 +944,17 @@ char sparc_hard_reg_printed[8];
 #undef TARGET_ZERO_CALL_USED_REGS
 #define TARGET_ZERO_CALL_USED_REGS sparc_zero_call_used_regs
 
+#ifdef SPARC_GCOV_TYPE_SIZE
+static HOST_WIDE_INT
+sparc_gcov_type_size (void)
+{
+  return SPARC_GCOV_TYPE_SIZE;
+}
+
+#undef TARGET_GCOV_TYPE_SIZE
+#define TARGET_GCOV_TYPE_SIZE sparc_gcov_type_size
+#endif
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Return the memory reference contained in X if any, zero otherwise.  */
diff --git a/gcc/coverage.c b/gcc/coverage.c
index ac9a9fdad228..10d7f8366cb5 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -146,7 +146,7 @@ tree
 get_gcov_type (void)
 {
   scalar_int_mode mode
-= smallest_int_mode_for_size (LONG_LONG_TYPE_SIZE > 32 ? 64 : 32);
+= smallest_int_mode_for_size (targetm.gcov_type_size ());
   return lang_hooks.types.type_for_mode (mode, false);
 }
 
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index a30fdcbbf3d6..f68f42638a11 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -12588,3 +12588,14 @@ Return an RTX representing @var{tagged_pointer} with 
its tag set to zero.
 Store the result in @var{target} if convenient.
 The default clears the top byte of the original pointer.
 @end deftypefn
+
+@deftypefn {Target Hook} HOST_WIDE_INT TARGET_GCOV_TYPE_SIZE (void)
+Returns the gcov type size in bits.  This type is used for example for
+counters incremented by profiling and code-coverage events.  The default
+value is 64, if the type size of long long is greater than 32, otherwise the
+default value is 32.  A 64-bit type is recommended to avoid overflows of the
+counters.  If the @option{-fprofile-update=a

Re: [PATCH v4] gcov: Add TARGET_GCOV_TYPE_SIZE target hook

2021-08-12 Thread Sebastian Huber

On 12/08/2021 13:19, Martin Liška wrote:
One small nit, once you sent a new patch version, can you please 
describe what has changed

since the previous one?


Yes, sorry.

In v4 I changed the target macro to a target hook. Also the 
TARGET_GCOV_TYPE_SIZE is now redefined in sparc.c using an 
architecture-specific define (SPARC_GCOV_TYPE_SIZE).


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH v4] gcov: Add TARGET_GCOV_TYPE_SIZE target hook

2021-08-16 Thread Sebastian Huber

On 16/08/2021 14:33, Martin Liška wrote:

On 8/12/21 6:13 PM, Joseph Myers wrote:

This is not a review of the patch, but I think this version addresses all
the issues I had with previous versions regarding target macro/hook
handling.


And I'm fine with the GCOV part. Please install the patch.


Thanks for the review, I checked it in.

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH] Use __builtin_trap() for abort() if inhibit_libc

2021-08-17 Thread Sebastian Huber
abort() is used in gcc_assert() and gcc_unreachable() which is used by target
libraries such as libgcov.a.  This patch changes the abort() definition under
certain conditions.  If inhibit_libc is defined and abort is not already
defined, then abort() is defined to __builtin_trap().

The inhibit_libc define is usually defined if GCC is built for targets running
in embedded systems which may optionally use a C standard library.  If
inhibit_libc is defined, then there may be still a full featured abort()
available.  abort() is a heavy weight function which depends on signals and
file streams.  For statically linked applications, this means that a dependency
on gcc_assert() pulls in the support for signals and file streams.  This could
prevent using gcov to test low end targets for example.  Using __builtin_trap()
avoids these dependencies if the target implements a "trap" instruction.  The
application or operating system could use a trap handler to react to failed GCC
runtime checks which caused a trap.

gcc/

* tsystem.h (abort): Define abort() if inhibit_libc is defined and it
is not already defined.
---
 gcc/tsystem.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/tsystem.h b/gcc/tsystem.h
index e1e6a96a4f48..5c72c69ff3ed 100644
--- a/gcc/tsystem.h
+++ b/gcc/tsystem.h
@@ -59,7 +59,7 @@ extern int atexit (void (*)(void));
 #endif
 
 #ifndef abort
-extern void abort (void) __attribute__ ((__noreturn__));
+#define abort() __builtin_trap ()
 #endif
 
 #ifndef strlen
-- 
2.26.2



Re: [PATCH] Use __builtin_trap() for abort() if inhibit_libc

2021-08-30 Thread Sebastian Huber

Hello Christophe,

it seems there are a couple of more abort() declarations:

libgcc/unwind-arm-common.inc:extern void abort (void);
libgcc/config/c6x/pr-support.c:extern void abort (void);
libgcc/config/arm/pr-support.c:extern void abort (void);
libgcc/config/arm/linux-atomic-64bit.c:extern void abort (void);
libgcc/fp-bit.c:   external to abort if abort is not used by the 
function, and the stubs

libgcc/fp-bit.c:extern void abort (void);

I will prepare a patch.

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] Use __builtin_trap() for abort() if inhibit_libc

2021-08-30 Thread Sebastian Huber

On 30/08/2021 13:44, Richard Biener wrote:

On Mon, Aug 30, 2021 at 12:55 PM Sebastian Huber
  wrote:

Hello Christophe,

it seems there are a couple of more abort() declarations:

libgcc/unwind-arm-common.inc:extern void abort (void);
libgcc/config/c6x/pr-support.c:extern void abort (void);
libgcc/config/arm/pr-support.c:extern void abort (void);
libgcc/config/arm/linux-atomic-64bit.c:extern void abort (void);
libgcc/fp-bit.c:   external to abort if abort is not used by the
function, and the stubs
libgcc/fp-bit.c:extern void abort (void);

I will prepare a patch.

Less likley to break might be to simply wrap 'abort'
in parentheses to avoid macro expansion?


I think the abort declaration in libgcc/unwind-arm-common.inc is the 
only problematic spot since unwind-arm-common.inc includes tsystem.h.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH] Fix arm target build with inhibit_libc

2021-08-30 Thread Sebastian Huber
Do not declare abort in "libgcc/unwind-arm-common.inc" since it is already
provided by "tsystem.h".  It fixes the following build error:

In file included from libgcc/config/arm/unwind-arm.c:144:
libgcc/unwind-arm-common.inc:55:24: error: macro "abort" passed 1 arguments, 
but takes just 0
   55 | extern void abort (void);

libgcc/

* unwind-arm-common.inc (abort): Remove.
---
 libgcc/unwind-arm-common.inc | 4 
 1 file changed, 4 deletions(-)

diff --git a/libgcc/unwind-arm-common.inc b/libgcc/unwind-arm-common.inc
index c9b70c10d4f5..77ec02ec811e 100644
--- a/libgcc/unwind-arm-common.inc
+++ b/libgcc/unwind-arm-common.inc
@@ -50,10 +50,6 @@
 #define ARM_SIGCONTEXT_R0  0xc
 #endif
 
-/* We add a prototype for abort here to avoid creating a dependency on
-   target headers.  */
-extern void abort (void);
-
 /* Definitions for C++ runtime support routines.  We make these weak
declarations to avoid pulling in libsupc++ unnecessarily.  */
 typedef unsigned char bool;
-- 
2.26.2



Re: [PATCH 1/2] Allow subtarget customization of CC1_SPEC

2022-10-04 Thread Sebastian Huber

On 08/09/2022 07:33, Sebastian Huber wrote:

On 04/08/2022 15:02, Sebastian Huber wrote:

On 22/07/2022 15:02, Sebastian Huber wrote:

gcc/ChangeLog:

* gcc.cc (SUBTARGET_CC1_SPEC): Define if not defined.
(CC1_SPEC): Define to SUBTARGET_CC1_SPEC.
* config/arm/arm.h (CC1_SPEC): Remove.
* config/arc/arc.h (CC1_SPEC): Append SUBTARGET_CC1_SPEC.
* config/cris/cris.h (CC1_SPEC): Likewise.
* config/frv/frv.h (CC1_SPEC): Likewise.
* config/i386/i386.h (CC1_SPEC): Likewise.
* config/ia64/ia64.h (CC1_SPEC): Likewise.
* config/lm32/lm32.h (CC1_SPEC): Likewise.
* config/m32r/m32r.h (CC1_SPEC): Likewise.
* config/mcore/mcore.h (CC1_SPEC): Likewise.
* config/microblaze/microblaze.h: Likewise.
* config/nds32/nds32.h (CC1_SPEC): Likewise.
* config/nios2/nios2.h (CC1_SPEC): Likewise.
* config/pa/pa.h (CC1_SPEC): Likewise.
* config/rs6000/sysv4.h (CC1_SPEC): Likewise.
* config/rx/rx.h (CC1_SPEC): Likewise.
* config/sparc/sparc.h (CC1_SPEC): Likewise.


Could someone please have a look at this patch set?


Ping.


Would someone mind having a look at this patch set? If there is a better 
approach to customize the default TLS model, then please let me know.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] rs6000: Improve .machine

2022-03-10 Thread Sebastian Huber

On 04/03/2022 17:51, Segher Boessenkool wrote:

Hi!

This adds more correct .machine for most older CPUs.  It should be
conservative in the sense that everything we handled before we handle at
least as well now.  This does not yet revamp the server CPU handling, it
is too risky at this point in time.

Tested on powerpc64-linux {-m32,-m64}.  Also manually tested with all
-mcpu=, and the output of that passed through the GNU assembler.

I plan to commit this later today.


Could this be back ported to GCC 10 and 11? I would fix the following 
issue for -mcpu=405:


Error: unrecognized opcode: `dlmzb.'

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] rs6000: Improve .machine

2022-03-15 Thread Sebastian Huber

Hello Segher,

On 10/03/2022 11:11, Segher Boessenkool wrote:

On Thu, Mar 10, 2022 at 09:25:21AM +0100, Sebastian Huber wrote:

On 04/03/2022 17:51, Segher Boessenkool wrote:

This adds more correct .machine for most older CPUs.  It should be
conservative in the sense that everything we handled before we handle at
least as well now.  This does not yet revamp the server CPU handling, it
is too risky at this point in time.

Tested on powerpc64-linux {-m32,-m64}.  Also manually tested with all
-mcpu=, and the output of that passed through the GNU assembler.

I plan to commit this later today.

Could this be back ported to GCC 10 and 11? I would fix the following
issue for -mcpu=405:

Error: unrecognized opcode: `dlmzb.'

Good to hear!

Unfortunately there is PR104829 about this commit.  I don't see how the
commit can break anything (that wasn't already broken); it's not clear
how it happens at all, and neither me nor colleagues could reproduce it
so far.

So I won't yet backport it, but first wait what happens here.


now that the PR104829 is fixed could I back port

Segher Boessenkool (2):
  rs6000: Improve .machine
  rs6000: Do not use rs6000_cpu for .machine ppc and ppc64 (PR104829)

to GCC 10 and 11?

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH] gcov-tool: Allow merging of empty profile lists

2022-03-23 Thread Sebastian Huber
The gcov_profile_merge() already had code to deal with profile information
which had no counterpart to merge with.  For profile information from files
with no associated counterpart, the profile information is simply used as is
with the weighting transformation applied.  Make sure that gcov_profile_merge()
works with an empty target profile list.  Return the merged profile list.

gcc/
* gcov-tool.cc (gcov_profile_merge): Adjust return type.
(profile_merge): Allow merging of directories which contain no profile
files.

libgcc/
* libgcov-util.c (gcov_profile_merge): Return the list of merged
profiles.  Accept empty target and source profile lists.
---
 gcc/gcov-tool.cc  | 27 ++-
 libgcc/libgcov-util.c | 15 +--
 2 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index f4e42ae763c..2e4083a664d 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -40,7 +40,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #endif
 #include 
 
-extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, int, int);
+extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
+struct gcov_info*, int, int);
 extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -141,26 +142,18 @@ profile_merge (const char *d1, const char *d2, const char 
*out, int w1, int w2)
 {
   struct gcov_info *d1_profile;
   struct gcov_info *d2_profile;
-  int ret;
+  struct gcov_info *merged_profile;
 
   d1_profile = gcov_read_profile_dir (d1, 0);
-  if (!d1_profile)
-return 1;
-
-  if (d2)
-{
-  d2_profile = gcov_read_profile_dir (d2, 0);
-  if (!d2_profile)
-return 1;
+  d2_profile = gcov_read_profile_dir (d2, 0);
 
-  /* The actual merge: we overwrite to d1_profile.  */
-  ret = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
+  /* The actual merge: we overwrite to d1_profile.  */
+  merged_profile = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
 
-  if (ret)
-return ret;
-}
-
-  gcov_output_files (out, d1_profile);
+  if (merged_profile)
+gcov_output_files (out, merged_profile);
+  else if (verbose)
+fnotice (stdout, "no profile files were merged\n");
 
   return 0;
 }
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index ba7fb924b53..e5496f4ade2 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -677,13 +677,13 @@ find_match_gcov_info (struct gcov_info **array, int size,
Return 0 on success: without mismatch.
Reutrn 1 on error.  */
 
-int
+struct gcov_info *
 gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info 
*src_profile,
 int w1, int w2)
 {
   struct gcov_info *gi_ptr;
   struct gcov_info **tgt_infos;
-  struct gcov_info *tgt_tail;
+  struct gcov_info **tgt_tail;
   struct gcov_info **in_src_not_tgt;
   unsigned tgt_cnt = 0, src_cnt = 0;
   unsigned unmatch_info_cnt = 0;
@@ -703,7 +703,10 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
   for (gi_ptr = tgt_profile, i = 0; gi_ptr; gi_ptr = gi_ptr->next, i++)
 tgt_infos[i] = gi_ptr;
 
-  tgt_tail = tgt_infos[tgt_cnt - 1];
+  if (tgt_cnt)
+ tgt_tail = &tgt_infos[tgt_cnt - 1]->next;
+  else
+ tgt_tail = &tgt_profile;
 
   /* First pass on tgt_profile, we multiply w1 to all counters.  */
   if (w1 > 1)
@@ -732,14 +735,14 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
   gi_ptr = in_src_not_tgt[i];
   gcov_merge (gi_ptr, gi_ptr, w2 - 1);
   gi_ptr->next = NULL;
-  tgt_tail->next = gi_ptr;
-  tgt_tail = gi_ptr;
+  *tgt_tail = gi_ptr;
+  tgt_tail = &gi_ptr->next;
 }
 
   free (in_src_not_tgt);
   free (tgt_infos);
 
-  return 0;
+  return tgt_profile;
 }
 
 typedef gcov_type (*counter_op_fn) (gcov_type, void*, void*);
-- 
2.34.1



Re: [PATCH] gcov-tool: Allow merging of empty profile lists

2022-03-23 Thread Sebastian Huber

Hello Martin,

On 23/03/2022 13:19, Martin Liška wrote:

On 3/23/22 10:34, Sebastian Huber wrote:

Hello.

Thanks for the patch. Note we're in stage4, so the patch can eventually go
in in the next stage1.


ok, good.



The gcov_profile_merge() already had code to deal with profile 
information
which had no counterpart to merge with.  For profile information from 
files
with no associated counterpart, the profile information is simply used 
as is
with the weighting transformation applied.  Make sure that 
gcov_profile_merge()

works with an empty target profile list.  Return the merged profile list.


Can you please provide a simple demo with a pair of profiles
where I'll see what changes?


The background for this feature is that I would like to combine the gcov 
information obtained from several test executables. Each test executable 
will print something like this (log.txt):


*** BEGIN OF GCOV INFO ***

/home/EB/sebastian_h/src/lwip/b-xilinx_zynq_a9_qemu/init.gcda
YWRjZ1IzMEKtLjW3AQMAAADcaps855EX05p4KUUAAKEBOgEAAQAB
AAEAAQABAAEAAQEA
AQABAAEAAQABAAEAAQAA
AAABAQABAAEA
AAEAAQABAAEBAwAAACXn3k16
TDqmuIMwpAAAoQECAgABAwAAADzkvDcfSnvcuIMwpAAAoQH+AQMA
AACnWNZaIM7GWZ9hiOIAAKEBBAEBAwAAAPkGW3YHFUOO6Old
2wAAoQECAQABAwAAAIvy4CE9FxuM6Old2wAAoQECAQAB
AwAAANyvBDZiERlQ6Old2wAAoQECAQABAwAAACKQjCp2pYlIuIMwpAAAoQEC
AQABAwAAAKSSXEjQFDluuIMwpAAAoQH+AA==

...

*** END OF GCOV INFO ***

The attached script reads the log file and creates the *.gcda files 
using gcov-tool. Initially, the target files do not exist.






gcc/
* gcov-tool.cc (gcov_profile_merge): Adjust return type.
(profile_merge): Allow merging of directories which contain no 
profile

files.

libgcc/
* libgcov-util.c (gcov_profile_merge): Return the list of merged
profiles.  Accept empty target and source profile lists.
---
  gcc/gcov-tool.cc  | 27 ++-
  libgcc/libgcov-util.c | 15 +--
  2 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index f4e42ae763c..2e4083a664d 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -40,7 +40,8 @@ see the files COPYING3 and COPYING.RUNTIME 
respectively.  If not, see

  #endif
  #include 
-extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, 
int, int);

+extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
+ struct gcov_info*, int, int);
  extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
  extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
  extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -141,26 +142,18 @@ profile_merge (const char *d1, const char *d2, 
const char *out, int w1, int w2)

  {
    struct gcov_info *d1_profile;
    struct gcov_info *d2_profile;
-  int ret;
+  struct gcov_info *merged_profile;
    d1_profile = gcov_read_profile_dir (d1, 0);
-  if (!d1_profile)
-    return 1;
-
-  if (d2)
-    {
-  d2_profile = gcov_read_profile_dir (d2, 0);
-  if (!d2_profile)
-    return 1;
+  d2_profile = gcov_read_profile_dir (d2, 0);


Is it fine calling 'gcov_read_profile_dir (d2, 0)' without 'if (d2)'?


Yes, the caller ensures that d1 and d2 are both provided:

  if (argc - optind != 2)
merge_usage ();

  return profile_merge (argv[optind], argv[optind+1], output_dir, w1, w2);

Maybe we should provide a better error message, if the user doesn't 
provide two directories instead of the general usage message.





-  /* The actual merge: we overwrite to d1_profile.  */
-  ret = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
+  /* The actual merge: we overwrite to d1_profile.  */
+  merged_profile = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
-  if (ret)
-    return ret;
-    }
-
-  gcov_output_files (out, d1_profile);
+  if (merged_profile)
+    gcov_output_files (out, merged_profile);
+  else if (verbose)
+    fnotice (stdout, "no profile files were merged\n");
    return 0;
  }
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index ba7fb924b53..e5496f4ade2 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -677,13 +677,13 @@ find_match_gcov_info (struct gcov_info **array, 
int size,

 Return 0 on success: without mismatch.
 Reutrn 1 on error.  */


Please adjust the function comment.


Oh, yes.

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: A

Re: [PATCH v2] Document that the 'access' and 'nonnull' attributes are independent

2022-03-23 Thread Sebastian Huber

On 23/03/2022 17:31, Martin Sebor via Gcc-patches wrote:


The concern is that the constraints implied by atttributes access and
nonnull are independent of each other.  I would suggest to document
that without talking about dereferencing because that's not implied
by either of them.  E.g., something like this (feel free to tweak it
as you see fit):

   Note that the @code{access} attribute doesn't imply the same
   constraint as attribute @code{nonnull} (@pxref{Attribute nonnull}).
   The latter attribute should be used to annotate arguments that must
   never be null, regardless of the value of the size argument.


I would not give an advice on using the nonnull attribute here. This 
attribute could have pretty dangerous effects in the function definition 
(removal of null pointer checks).


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH v2] gcov-tool: Allow merging of empty profile lists

2022-03-24 Thread Sebastian Huber
The gcov_profile_merge() already had code to deal with profile information
which had no counterpart to merge with.  For profile information from files
with no associated counterpart, the profile information is simply used as is
with the weighting transformation applied.  Make sure that gcov_profile_merge()
works with an empty target profile list.  Return the merged profile list.

gcc/
* gcov-tool.cc (gcov_profile_merge): Adjust return type.
(profile_merge): Allow merging of directories which contain no profile
files.

libgcc/
* libgcov-util.c (gcov_profile_merge): Return the list of merged
profiles.  Accept empty target and source profile lists.
---
v2:

Adjust return value description for gcov_profile_merge().

 gcc/gcov-tool.cc  | 27 ++-
 libgcc/libgcov-util.c | 19 +++
 2 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index f4e42ae763c..2e4083a664d 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -40,7 +40,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #endif
 #include 
 
-extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, int, int);
+extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
+struct gcov_info*, int, int);
 extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -141,26 +142,18 @@ profile_merge (const char *d1, const char *d2, const char 
*out, int w1, int w2)
 {
   struct gcov_info *d1_profile;
   struct gcov_info *d2_profile;
-  int ret;
+  struct gcov_info *merged_profile;
 
   d1_profile = gcov_read_profile_dir (d1, 0);
-  if (!d1_profile)
-return 1;
-
-  if (d2)
-{
-  d2_profile = gcov_read_profile_dir (d2, 0);
-  if (!d2_profile)
-return 1;
+  d2_profile = gcov_read_profile_dir (d2, 0);
 
-  /* The actual merge: we overwrite to d1_profile.  */
-  ret = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
+  /* The actual merge: we overwrite to d1_profile.  */
+  merged_profile = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
 
-  if (ret)
-return ret;
-}
-
-  gcov_output_files (out, d1_profile);
+  if (merged_profile)
+gcov_output_files (out, merged_profile);
+  else if (verbose)
+fnotice (stdout, "no profile files were merged\n");
 
   return 0;
 }
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index ba7fb924b53..100f1b19f1a 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -674,16 +674,16 @@ find_match_gcov_info (struct gcov_info **array, int size,
 }
 
 /* Merge the list of gcov_info objects from SRC_PROFILE to TGT_PROFILE.
-   Return 0 on success: without mismatch.
-   Reutrn 1 on error.  */
+   Return the list of merged gcov_info objects.  Return NULL if the list is
+   empty.  */
 
-int
+struct gcov_info *
 gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info 
*src_profile,
 int w1, int w2)
 {
   struct gcov_info *gi_ptr;
   struct gcov_info **tgt_infos;
-  struct gcov_info *tgt_tail;
+  struct gcov_info **tgt_tail;
   struct gcov_info **in_src_not_tgt;
   unsigned tgt_cnt = 0, src_cnt = 0;
   unsigned unmatch_info_cnt = 0;
@@ -703,7 +703,10 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
   for (gi_ptr = tgt_profile, i = 0; gi_ptr; gi_ptr = gi_ptr->next, i++)
 tgt_infos[i] = gi_ptr;
 
-  tgt_tail = tgt_infos[tgt_cnt - 1];
+  if (tgt_cnt)
+ tgt_tail = &tgt_infos[tgt_cnt - 1]->next;
+  else
+ tgt_tail = &tgt_profile;
 
   /* First pass on tgt_profile, we multiply w1 to all counters.  */
   if (w1 > 1)
@@ -732,14 +735,14 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
   gi_ptr = in_src_not_tgt[i];
   gcov_merge (gi_ptr, gi_ptr, w2 - 1);
   gi_ptr->next = NULL;
-  tgt_tail->next = gi_ptr;
-  tgt_tail = gi_ptr;
+  *tgt_tail = gi_ptr;
+  tgt_tail = &gi_ptr->next;
 }
 
   free (in_src_not_tgt);
   free (tgt_infos);
 
-  return 0;
+  return tgt_profile;
 }
 
 typedef gcov_type (*counter_op_fn) (gcov_type, void*, void*);
-- 
2.34.1



Re: [PATCH] gcov-tool: Allow merging of empty profile lists

2022-03-24 Thread Sebastian Huber

On 24/03/2022 11:29, Martin Liška wrote:

On 3/23/22 15:50, Sebastian Huber wrote:
The attached script reads the log file and creates the *.gcda files 
using gcov-tool. Initially, the target files do not exist.


Now I've got your use-case and I like it. It's cool one can utilize GCOV 
even without a filesystem.


Yes, it basically works quite well. I try to make it a bit easier to 
use. What seems to be quite common is that tests for embedded systems 
report their test data through an in order character stream, for example 
through an UART device. I used this primitive encoding of the gcov 
information:


*** BEGIN OF GCOV INFO ***

/home/EB/sebastian_h/src/lwip/b-xilinx_zynq_a9_qemu/init.gcda
YWRjZ1IzMEKtLjW3AQMAAADcaps855EX05p4KUUAAKEBOgEAAQAB
AAEAAQABAAEAAQEA
AQABAAEAAQABAAEAAQAA
AAABAQABAAEA
AAEAAQABAAEBAwAAACXn3k16
TDqmuIMwpAAAoQECAgABAwAAADzkvDcfSnvcuIMwpAAAoQH+AQMA
AACnWNZaIM7GWZ9hiOIAAKEBBAEBAwAAAPkGW3YHFUOO6Old
2wAAoQECAQABAwAAAIvy4CE9FxuM6Old2wAAoQECAQAB
AwAAANyvBDZiERlQ6Old2wAAoQECAQABAwAAACKQjCp2pYlIuIMwpAAAoQEC
AQABAwAAAKSSXEjQFDluuIMwpAAAoQH+AA==

/home/EB/sebastian_h/src/lwip/b-xilinx_zynq_a9_qemu/src/netif/ethernet.gcda
YWRjZ1IzMEIwMjW3AQMAAAC+EBQuXa7stuNAYTkAAKEBCgEAAQAA
AQABAwQbGWmmhbpBJ5lR8AAAoQEmAQAA
AAEA
AAEAAAEB


...

*** END OF GCOV INFO ***

Maybe we could add the file path into the gcov information stream using 
a new tag:


#define GCOV_TAG_GCDA_FILE_NAME  ((gcov_unsigned_t)0xa500)

Then the complete gcov information can be dumped using a single base64 
encoded stream. We could add some support to the gcov-tool to read this 
stream and merge it into gcda files.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] gcov-tool: Allow merging of empty profile lists

2022-03-28 Thread Sebastian Huber

On 24/03/2022 13:03, Martin Liška wrote:

On 3/24/22 11:51, Sebastian Huber wrote:
Maybe we could add the file path into the gcov information stream 
using a new tag:


#define GCOV_TAG_GCDA_FILE_NAME  ((gcov_unsigned_t)0xa500)

Then the complete gcov information can be dumped using a single base64 
encoded stream. We could add some support to the gcov-tool to read 
this stream and merge it into gcda files.


I would support such patch!


Ok, good. I work currently on a prototype implementation. My use case 
would be like this.


Run a test executable which dumps all gcov info objects in a serial data 
stream. It could be encoded as base64. It could be also compressed. On 
the host you unpack the encoded data stream and feed it into gcov-tool 
using the new "merge-stream" subcommand:


gcov-tool --help
Usage: gcov-tool [OPTION]... SUB_COMMAND [OPTION]...

Offline tool to handle gcda counts

  -h, --helpPrint this help, then exit
  -v, --version Print version number, then exit
  merge-stream [options] [stream-file]  Merge coverage stream file (or 
stdin)

and coverage file contents
-v, --verbose   Verbose mode
-w, --weight Set weights (float point values)

Example:

base64 -d log.txt | gcov-tool merge-stream

The gcov-tool uses a new tag which contains the filename of the 
associated gcov info file:


gcov-dump b-xilinx_zynq_a9_qemu/init.gcda
b-xilinx_zynq_a9_qemu/init.gcda:data:magic `gcda':version `B20 '
b-xilinx_zynq_a9_qemu/init.gcda:stamp 3496756572
b-xilinx_zynq_a9_qemu/init.gcda:checksum 137326246
b-xilinx_zynq_a9_qemu/init.gcda:  a500:  62:FILENAME 
`/home/EB/sebastian_h/src/lwip/b-xilinx_zynq_a9_qemu/init.gcda'
b-xilinx_zynq_a9_qemu/init.gcda:  a100:   8:OBJECT_SUMMARY runs=0, 
sum_max=0
b-xilinx_zynq_a9_qemu/init.gcda:  0100:  12:FUNCTION 
ident=1016818396, lineno_checksum=0xd31791e7, cfg_checksum=0x4529789a

b-xilinx_zynq_a9_qemu/init.gcda:01a1: 232:COUNTERS arcs 29 counts

Should I generate this filename tag to all configurations or just in 
case inhibit_libc is defined?


Advantage:

* No dependency on the GCC configuration

Disadvantages:

* Bigger files
* Actual filename and the filename of the tag differ if file is moved
* Potential information leak

In any case, I would add the support for the (optional) filename tag to 
all readers.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] gcov-tool: Allow merging of empty profile lists

2022-03-30 Thread Sebastian Huber

On 30/03/2022 13:56, Martin Liška wrote:

Example:

base64 -d log.txt | gcov-tool merge-stream

The gcov-tool uses a new tag which contains the filename of the 
associated gcov info file:


gcov-dump b-xilinx_zynq_a9_qemu/init.gcda
b-xilinx_zynq_a9_qemu/init.gcda:data:magic `gcda':version `B20 '
b-xilinx_zynq_a9_qemu/init.gcda:stamp 3496756572
b-xilinx_zynq_a9_qemu/init.gcda:checksum 137326246
b-xilinx_zynq_a9_qemu/init.gcda:  a500:  62:FILENAME 
`/home/EB/sebastian_h/src/lwip/b-xilinx_zynq_a9_qemu/init.gcda'
b-xilinx_zynq_a9_qemu/init.gcda:  a100:   8:OBJECT_SUMMARY runs=0, 
sum_max=0
b-xilinx_zynq_a9_qemu/init.gcda:  0100:  12:FUNCTION 
ident=1016818396, lineno_checksum=0xd31791e7, cfg_checksum=0x4529789a

b-xilinx_zynq_a9_qemu/init.gcda:    01a1: 232:COUNTERS arcs 29 counts

Should I generate this filename tag to all configurations or just in 
case inhibit_libc is defined?


I would emit it unconditionally. Btw. why do you need the tag?


The tag was the easiest way to add the filename to the gcov information.

We need some gcov defined way to get the filename associated with a gcov 
information, so that the gcov-tool can generate the gcov files from the 
gcov information itself. In a hosted environment, it is not necessary to 
include the filename in the gcov information, since the instrumented 
executable already creates the gcov files. In a freestanding 
environment, the gcov information is not automatically stored to files 
since no file system may be available. Here, we can dump the gcov 
information through __gcov_info_to_gcda(). This dump is basically a 
concatenation of several gcov files.


An alternative to a tag inside the gcov data would be a header which is 
dumped before the gcov data and understood by the gcov-tool:


header : int32:filename-magic int32:version string

#define GCOV_FILENAME_MAGIC ((gcov_unsigned_t)0x6763666e) /* "gcfn" */

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] gcov-tool: Allow merging of empty profile lists

2022-03-30 Thread Sebastian Huber




On 30/03/2022 15:30, Sebastian Huber wrote:

On 30/03/2022 13:56, Martin Liška wrote:

Example:

base64 -d log.txt | gcov-tool merge-stream

The gcov-tool uses a new tag which contains the filename of the 
associated gcov info file:


gcov-dump b-xilinx_zynq_a9_qemu/init.gcda
b-xilinx_zynq_a9_qemu/init.gcda:data:magic `gcda':version `B20 '
b-xilinx_zynq_a9_qemu/init.gcda:stamp 3496756572
b-xilinx_zynq_a9_qemu/init.gcda:checksum 137326246
b-xilinx_zynq_a9_qemu/init.gcda:  a500:  62:FILENAME 
`/home/EB/sebastian_h/src/lwip/b-xilinx_zynq_a9_qemu/init.gcda'
b-xilinx_zynq_a9_qemu/init.gcda:  a100:   8:OBJECT_SUMMARY 
runs=0, sum_max=0
b-xilinx_zynq_a9_qemu/init.gcda:  0100:  12:FUNCTION 
ident=1016818396, lineno_checksum=0xd31791e7, cfg_checksum=0x4529789a
b-xilinx_zynq_a9_qemu/init.gcda:    01a1: 232:COUNTERS arcs 29 
counts


Should I generate this filename tag to all configurations or just in 
case inhibit_libc is defined?


I would emit it unconditionally. Btw. why do you need the tag?


The tag was the easiest way to add the filename to the gcov information.

We need some gcov defined way to get the filename associated with a gcov 
information, so that the gcov-tool can generate the gcov files from the 
gcov information itself. In a hosted environment, it is not necessary to 
include the filename in the gcov information, since the instrumented 
executable already creates the gcov files. In a freestanding 
environment, the gcov information is not automatically stored to files 
since no file system may be available. Here, we can dump the gcov 
information through __gcov_info_to_gcda(). This dump is basically a 
concatenation of several gcov files.


An alternative to a tag inside the gcov data would be a header which is 
dumped before the gcov data and understood by the gcov-tool:


header : int32:filename-magic int32:version string

#define GCOV_FILENAME_MAGIC ((gcov_unsigned_t)0x6763666e) /* "gcfn" */


Thanks for asking the question. The alternative with the header is much 
less intrusive. I will work on this approach now.


Another question, I would like to add an option to gcov-tool to 
transform the filenames using regular expressions (for example, remove 
or add a prefix). Can I use the C++  for this?


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH] gcov: Reword comment for gcov_read_string()

2022-03-30 Thread Sebastian Huber
gcc/

* gcov-io.cc (gcov_read_string): Reword documentation comment.
---
 gcc/gcov-io.cc | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index c2e9e2b6d64..72c40f8eaa0 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -473,9 +473,9 @@ mangle_path (char const *base)
 /* We need to expose the below function when compiling for gcov-tool.  */
 
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
-/* Read string from coverage file. Returns a pointer to a static
-   buffer, or NULL on empty string. You must copy the string before
-   calling another gcov function.  */
+/* Read string from coverage file.  Allocate the buffer for the string
+   from the heap or die.  Return a pointer to the string, or NULL on
+   empty string.  */
 
 GCOV_LINKAGE const char *
 gcov_read_string (void)
-- 
2.34.1



[RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool

2022-03-31 Thread Sebastian Huber
This patch set is a proof of concept.

The aim is to better support gcov in free-standing environments. For example,
you can run a test executable which dumps all gcov info objects in a serial
data stream using __gcov_info_to_gcda() and the new __gcov_filename_to_gcfn().
It could be encoded as base64. It could be also compressed. On the host you
unpack the encoded data stream and feed it into gcov-tool using the new
"merge-stream" subcommand:

gcov-tool --help
Usage: gcov-tool [OPTION]... SUB_COMMAND [OPTION]...

Offline tool to handle gcda counts

  -h, --helpPrint this help, then exit
  -v, --version Print version number, then exit
  merge-stream [options] [stream-file]  Merge coverage stream file (or stdin)
and coverage file contents
-v, --verbose   Verbose mode
-w, --weight Set weights (float point values)

Example:

base64 -d log.txt | gcov-tool merge-stream

The patch set does not change the format of gcda files.

TODO:

* Documentation
* Tests

Sebastian Huber (12):
  gcov-tool: Allow merging of empty profile lists
  gcov: Add mode to all gcov_open()
  gcov: Add open mode parameter to gcov_do_dump()
  gcov: Make gcov_seek() static
  gcov: Add __gcov_filename_to_gcfn()
  gcov-tool: Support file input from stdin
  gcov: Use xstrdup()
  gcov: Move prepend to list to read_gcda_file()
  gcov: Move gcov_open() to caller of read_gcda_file()
  gcov: Fix integer types in ftw_read_file()
  gcov: Record EOF error during read
  gcov-tool: Add merge-stream subcommand

 gcc/gcov-io.cc |  76 ++-
 gcc/gcov-io.h  |  35 +
 gcc/gcov-tool.cc   | 107 +-
 libgcc/gcov.h  |  17 -
 libgcc/libgcov-driver-system.c |   7 +-
 libgcc/libgcov-driver.c|  42 --
 libgcc/libgcov-util.c  | 135 +
 libgcc/libgcov.h   |   3 -
 8 files changed, 326 insertions(+), 96 deletions(-)

-- 
2.34.1



[RFC/gcov 01/12] gcov-tool: Allow merging of empty profile lists

2022-03-31 Thread Sebastian Huber
The gcov_profile_merge() already had code to deal with profile information
which had no counterpart to merge with.  For profile information from files
with no associated counterpart, the profile information is simply used as is
with the weighting transformation applied.  Make sure that gcov_profile_merge()
works with an empty target profile list.  Return the merged profile list.

gcc/
* gcov-tool.cc (gcov_profile_merge): Adjust return type.
(profile_merge): Allow merging of directories which contain no profile
files.

libgcc/
* libgcov-util.c (gcov_profile_merge): Return the list of merged
profiles.  Accept empty target and source profile lists.
---
 gcc/gcov-tool.cc  | 27 ++-
 libgcc/libgcov-util.c | 19 +++
 2 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index f4e42ae763c..2e4083a664d 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -40,7 +40,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #endif
 #include 
 
-extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, int, int);
+extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
+struct gcov_info*, int, int);
 extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -141,26 +142,18 @@ profile_merge (const char *d1, const char *d2, const char 
*out, int w1, int w2)
 {
   struct gcov_info *d1_profile;
   struct gcov_info *d2_profile;
-  int ret;
+  struct gcov_info *merged_profile;
 
   d1_profile = gcov_read_profile_dir (d1, 0);
-  if (!d1_profile)
-return 1;
-
-  if (d2)
-{
-  d2_profile = gcov_read_profile_dir (d2, 0);
-  if (!d2_profile)
-return 1;
+  d2_profile = gcov_read_profile_dir (d2, 0);
 
-  /* The actual merge: we overwrite to d1_profile.  */
-  ret = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
+  /* The actual merge: we overwrite to d1_profile.  */
+  merged_profile = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
 
-  if (ret)
-return ret;
-}
-
-  gcov_output_files (out, d1_profile);
+  if (merged_profile)
+gcov_output_files (out, merged_profile);
+  else if (verbose)
+fnotice (stdout, "no profile files were merged\n");
 
   return 0;
 }
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index ba7fb924b53..100f1b19f1a 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -674,16 +674,16 @@ find_match_gcov_info (struct gcov_info **array, int size,
 }
 
 /* Merge the list of gcov_info objects from SRC_PROFILE to TGT_PROFILE.
-   Return 0 on success: without mismatch.
-   Reutrn 1 on error.  */
+   Return the list of merged gcov_info objects.  Return NULL if the list is
+   empty.  */
 
-int
+struct gcov_info *
 gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info 
*src_profile,
 int w1, int w2)
 {
   struct gcov_info *gi_ptr;
   struct gcov_info **tgt_infos;
-  struct gcov_info *tgt_tail;
+  struct gcov_info **tgt_tail;
   struct gcov_info **in_src_not_tgt;
   unsigned tgt_cnt = 0, src_cnt = 0;
   unsigned unmatch_info_cnt = 0;
@@ -703,7 +703,10 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
   for (gi_ptr = tgt_profile, i = 0; gi_ptr; gi_ptr = gi_ptr->next, i++)
 tgt_infos[i] = gi_ptr;
 
-  tgt_tail = tgt_infos[tgt_cnt - 1];
+  if (tgt_cnt)
+ tgt_tail = &tgt_infos[tgt_cnt - 1]->next;
+  else
+ tgt_tail = &tgt_profile;
 
   /* First pass on tgt_profile, we multiply w1 to all counters.  */
   if (w1 > 1)
@@ -732,14 +735,14 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
   gi_ptr = in_src_not_tgt[i];
   gcov_merge (gi_ptr, gi_ptr, w2 - 1);
   gi_ptr->next = NULL;
-  tgt_tail->next = gi_ptr;
-  tgt_tail = gi_ptr;
+  *tgt_tail = gi_ptr;
+  tgt_tail = &gi_ptr->next;
 }
 
   free (in_src_not_tgt);
   free (tgt_infos);
 
-  return 0;
+  return tgt_profile;
 }
 
 typedef gcov_type (*counter_op_fn) (gcov_type, void*, void*);
-- 
2.34.1



[RFC/gcov 02/12] gcov: Add mode to all gcov_open()

2022-03-31 Thread Sebastian Huber
gcc/

* gcov-io.cc (gcov_open): Always use the mode parameter.
* gcov-io.h (gcov_open): Declare it unconditionally.

libgcc/

* libgcov-driver-system.c (gcov_exit_open_gcda_file): Open file for
reading and writing.
* libgcov-util.c (read_gcda_file): Open file for reading.
* libgcov.h (gcov_open): Delete declaration.
---
 gcc/gcov-io.cc | 7 ---
 gcc/gcov-io.h  | 5 +
 libgcc/libgcov-driver-system.c | 4 ++--
 libgcc/libgcov-util.c  | 2 +-
 libgcc/libgcov.h   | 1 -
 5 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 72c40f8eaa0..017a6e32a5d 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -89,15 +89,8 @@ from_file (gcov_unsigned_t value)
Return zero on failure, non-zero on success.  */
 
 GCOV_LINKAGE int
-#if IN_LIBGCOV
-gcov_open (const char *name)
-#else
 gcov_open (const char *name, int mode)
-#endif
 {
-#if IN_LIBGCOV
-  int mode = 0;
-#endif
 #if GCOV_LOCKED
   struct flock s_flock;
   int fd;
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 99ce7dbccc8..afe74b002f1 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -347,15 +347,12 @@ struct gcov_summary
functions for writing.  Your file may become corrupted if you break
these invariants.  */
 
-#if !IN_LIBGCOV
-GCOV_LINKAGE int gcov_open (const char */*name*/, int /*direction*/);
-#endif
-
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
 GCOV_LINKAGE int gcov_magic (gcov_unsigned_t, gcov_unsigned_t);
 #endif
 
 /* Available everywhere.  */
+GCOV_LINKAGE int gcov_open (const char *, int) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE int gcov_close (void) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE gcov_type gcov_read_counter (void) ATTRIBUTE_HIDDEN;
diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index eef6e3cbda1..9abb2fe7f74 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -309,7 +309,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
 
   gf->filename = replace_filename_variables (gf->filename);
 
-  if (!gcov_open (gf->filename))
+  if (!gcov_open (gf->filename, 0))
 {
   /* Open failed likely due to missed directory.
  Create directory and retry to open file. */
@@ -318,7 +318,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
   fprintf (stderr, "profiling:%s:Skip\n", gf->filename);
   return -1;
 }
-  if (!gcov_open (gf->filename))
+  if (!gcov_open (gf->filename, 0))
 {
   fprintf (stderr, "profiling:%s:Cannot open\n", gf->filename);
   return -1;
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 100f1b19f1a..db157220c9d 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -268,7 +268,7 @@ read_gcda_file (const char *filename)
 k_ctrs_mask[i] = 0;
   k_ctrs_types = 0;
 
-  if (!gcov_open (filename))
+  if (!gcov_open (filename, 1))
 {
   fnotice (stderr, "%s:cannot open\n", filename);
   return NULL;
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 40e845ce3ea..f190547e819 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -343,7 +343,6 @@ extern int __gcov_execve (const char *, char  *const [], 
char *const [])
   ATTRIBUTE_HIDDEN;
 
 /* Functions that only available in libgcov.  */
-GCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
   const struct gcov_summary *)
 ATTRIBUTE_HIDDEN;
-- 
2.34.1



[RFC/gcov 03/12] gcov: Add open mode parameter to gcov_do_dump()

2022-03-31 Thread Sebastian Huber
gcc/

* gcov-tool.cc (gcov_do_dump): Add mode parameter.
(gcov_output_files): Open files for reading and writing.

libgcc/

* libgcov-driver-system.c (gcov_exit_open_gcda_file): Add mode
parameter.  Pass mode to gcov_open() calls.
* libgcov-driver.c (dump_one_gcov):  Add mode parameter.  Pass mode to
gcov_exit_open_gcda_file() call.
(gcov_do_dump): Add mode parameter.  Pass mode to dump_one_gcov()
calls.
(__gcov_dump_one):  Open file for reading and writing.
---
 gcc/gcov-tool.cc   |  4 ++--
 libgcc/libgcov-driver-system.c |  7 ---
 libgcc/libgcov-driver.c| 12 ++--
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index 2e4083a664d..d712715cf7e 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -46,7 +46,7 @@ extern int gcov_profile_overlap (struct gcov_info*, struct 
gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
 extern struct gcov_info* gcov_read_profile_dir (const char*, int);
-extern void gcov_do_dump (struct gcov_info *, int);
+extern void gcov_do_dump (struct gcov_info *, int, int);
 extern const char *gcov_get_filename (struct gcov_info *list);
 extern void gcov_set_verbose (void);
 
@@ -124,7 +124,7 @@ gcov_output_files (const char *out, struct gcov_info 
*profile)
 fatal_error (input_location, "output file %s already exists in folder %s",
 filename, out);
 
-  gcov_do_dump (profile, 0);
+  gcov_do_dump (profile, 0, 0);
 
   ret = chdir (pwd);
   if (ret)
diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index 9abb2fe7f74..ac405c38e3a 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -261,7 +261,8 @@ allocate_filename_struct (struct gcov_filename *gf)
 
 static int
 gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
- struct gcov_filename *gf)
+ struct gcov_filename *gf,
+ int mode)
 {
   int append_slash = 0;
   const char *fname = gi_ptr->filename;
@@ -309,7 +310,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
 
   gf->filename = replace_filename_variables (gf->filename);
 
-  if (!gcov_open (gf->filename, 0))
+  if (!gcov_open (gf->filename, mode))
 {
   /* Open failed likely due to missed directory.
  Create directory and retry to open file. */
@@ -318,7 +319,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
   fprintf (stderr, "profiling:%s:Skip\n", gf->filename);
   return -1;
 }
-  if (!gcov_open (gf->filename, 0))
+  if (!gcov_open (gf->filename, mode))
 {
   fprintf (stderr, "profiling:%s:Cannot open\n", gf->filename);
   return -1;
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 7e52c5676e5..10831e84b61 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -595,14 +595,14 @@ write_one_data (const struct gcov_info *gi_ptr,
 static void
 dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
   unsigned run_counted ATTRIBUTE_UNUSED,
-  gcov_type run_max ATTRIBUTE_UNUSED)
+  gcov_type run_max ATTRIBUTE_UNUSED, int mode)
 {
   struct gcov_summary summary = {};
   int error;
   gcov_unsigned_t tag;
   fn_buffer = 0;
 
-  error = gcov_exit_open_gcda_file (gi_ptr, gf);
+  error = gcov_exit_open_gcda_file (gi_ptr, gf, mode);
   if (error == -1)
 return;
 
@@ -649,13 +649,13 @@ read_fatal:;
 
 /* Dump all the coverage counts for the program. It first computes program
summary and then traverses gcov_list list and dumps the gcov_info
-   objects one by one.  */
+   objects one by one.  Use MODE to open files.  */
 
 #if !IN_GCOV_TOOL
 static
 #endif
 void
-gcov_do_dump (struct gcov_info *list, int run_counted)
+gcov_do_dump (struct gcov_info *list, int run_counted, int mode)
 {
   struct gcov_info *gi_ptr;
   struct gcov_filename gf;
@@ -678,7 +678,7 @@ gcov_do_dump (struct gcov_info *list, int run_counted)
   /* Now merge each file.  */
   for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
 {
-  dump_one_gcov (gi_ptr, &gf, run_counted, run_max);
+  dump_one_gcov (gi_ptr, &gf, run_counted, run_max, mode);
   free (gf.filename);
 }
 
@@ -701,7 +701,7 @@ __gcov_dump_one (struct gcov_root *root)
   if (root->dumped)
 return;
 
-  gcov_do_dump (root->list, root->run_counted);
+  gcov_do_dump (root->list, root->run_counted, 0);
   
   root->dumped = 1;
   root->run_counted = 1;
-- 
2.34.1



[RFC/gcov 06/12] gcov-tool: Support file input from stdin

2022-03-31 Thread Sebastian Huber
gcc/

* gcov-io.cc (GCOV_MODE_STDIN): Define.
(gcov_position): For gcov-tool, return calculated position if file is
stdin.
(gcov_open):  For gcov-tool, use stdin if filename is NULL.
(gcov_close): For gcov-tool, do not close stdin.
(gcov_read_bytes): For gcov-tool, update position if file is stdin.
(gcov_sync): For gcov-tool, discard input if file is stdin.
---
 gcc/gcov-io.cc | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index fee3130f94a..177f81166a6 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -35,8 +35,13 @@ struct gcov_var
   int error;   /* < 0 overflow, > 0 disk error.  */
   int mode;/* < 0 writing, > 0 reading.  */
   int endian;  /* Swap endianness.  */
+#ifdef IN_GCOV_TOOL
+  gcov_position_t pos; /* File position for stdin support. */
+#endif
 } gcov_var;
 
+#define GCOV_MODE_STDIN 2
+
 /* Save the current position in the gcov file.  */
 /* We need to expose this function when compiling for gcov-tool.  */
 #ifndef IN_GCOV_TOOL
@@ -45,6 +50,10 @@ static inline
 gcov_position_t
 gcov_position (void)
 {
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.mode == GCOV_MODE_STDIN)
+return gcov_var.pos;
+#endif
   return ftell (gcov_var.file);
 }
 
@@ -108,6 +117,16 @@ gcov_open (const char *name, int mode)
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
   gcov_var.endian = 0;
 #endif
+#ifdef IN_GCOV_TOOL
+  gcov_var.pos = 0;
+  if (!name)
+{
+  gcov_nonruntime_assert (gcov_var.mode > 0);
+  gcov_var.file = stdin;
+  gcov_var.mode = GCOV_MODE_STDIN;
+  return 1;
+}
+#endif
 #if GCOV_LOCKED
   if (mode > 0)
 {
@@ -190,6 +209,11 @@ gcov_open (const char *name, int mode)
 GCOV_LINKAGE int
 gcov_close (void)
 {
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.file == stdin)
+gcov_var.file = 0;
+  else
+#endif
   if (gcov_var.file)
 {
   if (fclose (gcov_var.file))
@@ -363,6 +387,9 @@ gcov_read_bytes (void *buffer, unsigned count)
   if (read != 1)
 return NULL;
 
+#ifdef IN_GCOV_TOOL
+  gcov_var.pos += count;
+#endif
   return buffer;
 }
 
@@ -499,6 +526,17 @@ gcov_sync (gcov_position_t base, gcov_unsigned_t length)
 {
   gcov_nonruntime_assert (gcov_var.mode > 0);
   base += length;
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.mode == GCOV_MODE_STDIN)
+{
+  while (gcov_var.pos < base)
+   {
+ ++gcov_var.pos;
+ (void)fgetc(gcov_var.file);
+   }
+  return;
+}
+#endif
   fseek (gcov_var.file, base, SEEK_SET);
 }
 #endif
-- 
2.34.1



[RFC/gcov 04/12] gcov: Make gcov_seek() static

2022-03-31 Thread Sebastian Huber
This function is only used by gcov_write_length() in the gcov-io.cc file.

gcc/

* gcov-io.cc (gcov_seek): Make it static.
* gcov-io.h (struct gcov_summary): Do not mention gcov_seek().

libgcc/

* libgcov.h (gcov_seek): Remove define and declaration.
---
 gcc/gcov-io.cc   | 4 +---
 gcc/gcov-io.h| 6 +++---
 libgcc/libgcov.h | 2 --
 3 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 017a6e32a5d..fee3130f94a 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -294,17 +294,15 @@ gcov_write_filename (const char *filename)
 
   gcov_write_string (filename);
 }
-#endif
 
 /* Move to a given position in a gcov file.  */
 
-GCOV_LINKAGE void
+static void
 gcov_seek (gcov_position_t base)
 {
   fseek (gcov_var.file, base, SEEK_SET);
 }
 
-#if !IN_LIBGCOV
 /* Write a tag TAG and reserve space for the record length. Return a
value to be used for gcov_write_length.  */
 
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index afe74b002f1..204ae0ccf7f 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -340,9 +340,9 @@ struct gcov_summary
 /* Functions for reading and writing gcov files. In libgcov you can
open the file for reading then writing. Elsewhere you can open the
file either for reading or for writing. When reading a file you may
-   use the gcov_read_* functions, gcov_sync, gcov_position, &
-   gcov_error. When writing a file you may use the gcov_write
-   functions, gcov_seek & gcov_error. When a file is to be rewritten
+   use the gcov_read_* functions, gcov_sync, gcov_position, and
+   gcov_error. When writing a file you may use the gcov_write*
+   functions and gcov_error. When a file is to be rewritten
you use the functions for reading, then gcov_rewrite then the
functions for writing.  Your file may become corrupted if you break
these invariants.  */
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index f190547e819..487bd1464cd 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -115,7 +115,6 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode 
(QI)));
 #define gcov_open __gcov_open
 #define gcov_close __gcov_close
 #define gcov_position __gcov_position
-#define gcov_seek __gcov_seek
 #define gcov_rewrite __gcov_rewrite
 #define gcov_is_error __gcov_is_error
 #define gcov_write_unsigned __gcov_write_unsigned
@@ -346,7 +345,6 @@ extern int __gcov_execve (const char *, char  *const [], 
char *const [])
 GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
   const struct gcov_summary *)
 ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE void gcov_rewrite (void) ATTRIBUTE_HIDDEN;
 
 /* "Counts" stored in gcda files can be a real counter value, or
-- 
2.34.1



[RFC/gcov 07/12] gcov: Use xstrdup()

2022-03-31 Thread Sebastian Huber
Move duplication of filename to caller and use xstrdup() instead of custom
code.  This helps to reuse read_gcda_file() for other purposes.

libgcc/

* libgcov-util.c (read_gcda_file): Do not duplicate filename.
(ftw_read_file): Duplicate filename for read_gcda_file().
---
 libgcc/libgcov-util.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index db157220c9d..ae5712c0138 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -296,16 +296,11 @@ read_gcda_file (const char *filename)
  sizeof (struct gcov_ctr_info) * GCOV_COUNTERS, 1);
 
   obj_info->version = version;
+  obj_info->filename = filename;
   obstack_init (&fn_info);
   num_fn_info = 0;
   curr_fn_info = 0;
-  {
-size_t len = strlen (filename) + 1;
-char *str_dup = (char*) xmalloc (len);
 
-memcpy (str_dup, filename, len);
-obj_info->filename = str_dup;
-  }
 
   /* Read stamp.  */
   obj_info->stamp = gcov_read_unsigned ();
@@ -415,7 +410,7 @@ ftw_read_file (const char *filename,
   if (verbose)
 fnotice (stderr, "reading file: %s\n", filename);
 
-  obj_info = read_gcda_file (filename);
+  obj_info = read_gcda_file (xstrdup (filename));
   if (!obj_info)
 return 0;
 
-- 
2.34.1



[RFC/gcov 08/12] gcov: Move prepend to list to read_gcda_file()

2022-03-31 Thread Sebastian Huber
This helps to reuse read_gcda_file().

libgcc/

* libgcov-util.c (read_gcda_file): Prepend new info object to global
list.
(ftw_read_file): Remove list append here.
---
 libgcc/libgcov-util.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index ae5712c0138..d628c71479e 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -301,6 +301,9 @@ read_gcda_file (const char *filename)
   num_fn_info = 0;
   curr_fn_info = 0;
 
+  /* Prepend to gcov info list */
+  obj_info->next = gcov_info_head;
+  gcov_info_head = obj_info;
 
   /* Read stamp.  */
   obj_info->stamp = gcov_read_unsigned ();
@@ -392,7 +395,6 @@ ftw_read_file (const char *filename,
 {
   int filename_len;
   int suffix_len;
-  struct gcov_info *obj_info;
 
   /* Only read regular files.  */
   if (type != FTW_F)
@@ -410,12 +412,7 @@ ftw_read_file (const char *filename,
   if (verbose)
 fnotice (stderr, "reading file: %s\n", filename);
 
-  obj_info = read_gcda_file (xstrdup (filename));
-  if (!obj_info)
-return 0;
-
-  obj_info->next = gcov_info_head;
-  gcov_info_head = obj_info;
+  (void)read_gcda_file (xstrdup (filename));
 
   return 0;
 }
-- 
2.34.1



[RFC/gcov 09/12] gcov: Move gcov_open() to caller of read_gcda_file()

2022-03-31 Thread Sebastian Huber
This allows to reuse read_gcda_file() to read multiple objects from a single
file.

libgcc/

* libgcov-util.c (read_gcda_file): Do not open file.
(ftw_read_file): Open file here.
---
 libgcc/libgcov-util.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index d628c71479e..03902ed10b1 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -268,17 +268,10 @@ read_gcda_file (const char *filename)
 k_ctrs_mask[i] = 0;
   k_ctrs_types = 0;
 
-  if (!gcov_open (filename, 1))
-{
-  fnotice (stderr, "%s:cannot open\n", filename);
-  return NULL;
-}
-
   /* Read magic.  */
   if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
 {
   fnotice (stderr, "%s:not a gcov data file\n", filename);
-  gcov_close ();
   return NULL;
 }
 
@@ -287,7 +280,6 @@ read_gcda_file (const char *filename)
   if (version != GCOV_VERSION)
 {
   fnotice (stderr, "%s:incorrect gcov version %d vs %d \n", filename, 
version, GCOV_VERSION);
-  gcov_close ();
   return NULL;
 }
 
@@ -379,7 +371,6 @@ read_gcda_file (const char *filename)
 }
 
   read_gcda_finalize (obj_info);
-  gcov_close ();
 
   return obj_info;
 }
@@ -412,7 +403,14 @@ ftw_read_file (const char *filename,
   if (verbose)
 fnotice (stderr, "reading file: %s\n", filename);
 
+  if (!gcov_open (filename, 1))
+{
+  fnotice (stderr, "%s:cannot open\n", filename);
+  return 0;
+}
+
   (void)read_gcda_file (xstrdup (filename));
+  gcov_close ();
 
   return 0;
 }
-- 
2.34.1



[RFC/gcov 05/12] gcov: Add __gcov_filename_to_gcfn()

2022-03-31 Thread Sebastian Huber
gcc/

* gcov-io.h (GCOV_FILENAME_MAGIC): Define and document.

libgcc/

* gcov.h (__gcov_info_to_gcda): Mention __gcov_filename_to_gcfn().
(__gcov_filename_to_gcfn): Declare and document.
* libgcov-driver.c (dump_string): New.
(__gcov_filename_to_gcfn): Likewise.
---
 gcc/gcov-io.h   | 24 
 libgcc/gcov.h   | 17 -
 libgcc/libgcov-driver.c | 30 ++
 3 files changed, 62 insertions(+), 9 deletions(-)

diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 204ae0ccf7f..30947634d73 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -60,14 +60,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 
file : int32:magic int32:version int32:stamp record*
 
-   The magic ident is different for the notes and the data files.  The
-   magic ident is used to determine the endianness of the file, when
-   reading.  The version is the same for both files and is derived
-   from gcc's version number. The stamp value is used to synchronize
-   note and data files and to synchronize merging within a data
-   file. It need not be an absolute time stamp, merely a ticker that
-   increments fast enough and cycles slow enough to distinguish
-   different compile/run/compile cycles.
+   A filename header may be used to provide a filename for the data in
+   a stream of data to support gcov in freestanding environments.  This
+   header is used by the merge-stream subcommand of the gcov-tool.  The
+   format of the filename header is
+
+   filename-header : int32:magic int32:version string
+
+   The magic ident is different for the notes and the data files as
+   well as the filename header.  The magic ident is used to determine
+   the endianness of the file, when reading.  The version is the same
+   for both files and is derived from gcc's version number. The stamp
+   value is used to synchronize note and data files and to synchronize
+   merging within a data file. It need not be an absolute time stamp,
+   merely a ticker that increments fast enough and cycles slow enough
+   to distinguish different compile/run/compile cycles.
 
Although the ident and version are formally 32 bit numbers, they
are derived from 4 character ASCII strings.  The version number
@@ -228,6 +235,7 @@ typedef uint64_t gcov_type_unsigned;
 /* File magic. Must not be palindromes.  */
 #define GCOV_DATA_MAGIC ((gcov_unsigned_t)0x67636461) /* "gcda" */
 #define GCOV_NOTE_MAGIC ((gcov_unsigned_t)0x67636e6f) /* "gcno" */
+#define GCOV_FILENAME_MAGIC ((gcov_unsigned_t)0x6763666e) /* "gcfn" */
 
 #include "version.h"
 
diff --git a/libgcc/gcov.h b/libgcc/gcov.h
index cea93023920..cdd4206f625 100644
--- a/libgcc/gcov.h
+++ b/libgcc/gcov.h
@@ -43,7 +43,8 @@ extern void __gcov_dump (void);
stream.  The ALLOCATE_FN callback shall allocate memory with a size in
characters specified by the first callback parameter.  The ARG parameter is
a user-provided argument passed as the last argument to the callback
-   functions.  */
+   functions.  It is recommended to use the __gcov_filename_to_gcfn()
+   in the filename callback function.  */
 
 extern void
 __gcov_info_to_gcda (const struct gcov_info *__info,
@@ -52,4 +53,18 @@ __gcov_info_to_gcda (const struct gcov_info *__info,
 void *(*__allocate_fn) (unsigned, void *),
 void *__arg);
 
+/* Convert the FILENAME to a gcfn data stream.  The DUMP_FN callback is
+   subsequently called with chunks (the begin and length of the chunk are
+   passed as the first two callback parameters) of the gcfn data stream.
+   The ARG parameter is a user-provided argument passed as the last
+   argument to the DUMP_FN callback function.  This function is intended
+   to be used by the filename callback of __gcov_info_to_gcda().  The gcfn
+   data stream is used by the merge-stream subcommand of the gcov-tool to
+   get the filename associated with a gcda data stream.  */
+
+extern void
+__gcov_filename_to_gcfn (const char *__filename,
+void (*__dump_fn) (const void *, unsigned, void *),
+void *__arg);
+
 #endif /* GCC_GCOV_H */
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 10831e84b61..a44054a3cb3 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -410,6 +410,23 @@ dump_counter (gcov_type counter,
 dump_unsigned (0, dump_fn, arg);
 }
 
+/* Dump the STRING using the DUMP handler called with ARG.  */
+
+static inline void
+dump_string (const char *string,
+void (*dump_fn) (const void *, unsigned, void *),
+void *arg)
+{
+  unsigned length = 0;
+
+  if (string)
+length = strlen (string) + 1;
+
+  dump_unsigned (length, dump_fn, arg);
+  if (string)
+(*dump_fn) (string, length, arg);
+}
+
 #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
 
 /* Store all TOP N counters where each has a dynamic length.  */
@@ -780,4 +797,

[RFC/gcov 11/12] gcov: Record EOF error during read

2022-03-31 Thread Sebastian Huber
Use an enum for file error codes.

gcc/

* gcov-io.cc (gcov_file_error): New enum.
(gcov_var): Use gcov_file_error enum for the error member.
(gcov_open): Use GCOV_FILE_NO_ERROR.
(gcov_close): Use GCOV_FILE_WRITE_ERROR.
(gcov_write): Likewise.
(gcov_write_unsigned): Likewise.
(gcov_write_string): Likewise.
(gcov_read_bytes): Set error code if EOF is reached.
(gcov_read_counter): Use GCOV_FILE_COUNTER_OVERFLOW.
---
 gcc/gcov-io.cc | 27 +++
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 177f81166a6..60c762bf3a3 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -29,10 +29,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 
 static gcov_unsigned_t *gcov_read_words (void *buffer, unsigned);
 
+enum gcov_file_error {
+  GCOV_FILE_COUNTER_OVERFLOW = -1,
+  GCOV_FILE_NO_ERROR = 0,
+  GCOV_FILE_WRITE_ERROR = 1,
+  GCOV_FILE_EOF = 2
+};
+
 struct gcov_var
 {
   FILE *file;
-  int error;   /* < 0 overflow, > 0 disk error.  */
+  enum gcov_file_error error;
   int mode;/* < 0 writing, > 0 reading.  */
   int endian;  /* Swap endianness.  */
 #ifdef IN_GCOV_TOOL
@@ -113,7 +120,7 @@ gcov_open (const char *name, int mode)
 #endif
 
   gcov_nonruntime_assert (!gcov_var.file);
-  gcov_var.error = 0;
+  gcov_var.error = GCOV_FILE_NO_ERROR;
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
   gcov_var.endian = 0;
 #endif
@@ -217,7 +224,7 @@ gcov_close (void)
   if (gcov_var.file)
 {
   if (fclose (gcov_var.file))
-   gcov_var.error = 1;
+   gcov_var.error = GCOV_FILE_WRITE_ERROR;
 
   gcov_var.file = 0;
 }
@@ -253,7 +260,7 @@ gcov_write (const void *data, unsigned length)
 {
   gcov_unsigned_t r = fwrite (data, length, 1, gcov_var.file);
   if (r != 1)
-gcov_var.error = 1;
+gcov_var.error = GCOV_FILE_WRITE_ERROR;
 }
 
 /* Write unsigned VALUE to coverage file.  */
@@ -263,7 +270,7 @@ gcov_write_unsigned (gcov_unsigned_t value)
 {
   gcov_unsigned_t r = fwrite (&value, sizeof (value), 1, gcov_var.file);
   if (r != 1)
-gcov_var.error = 1;
+gcov_var.error = GCOV_FILE_WRITE_ERROR;
 }
 
 #if !IN_LIBGCOV
@@ -283,7 +290,7 @@ gcov_write_string (const char *string)
 {
   gcov_unsigned_t r = fwrite (string, length, 1, gcov_var.file);
   if (r != 1)
-   gcov_var.error = 1;
+   gcov_var.error = GCOV_FILE_WRITE_ERROR;
 }
 }
 #endif
@@ -385,7 +392,11 @@ gcov_read_bytes (void *buffer, unsigned count)
 
   unsigned read = fread (buffer, count, 1, gcov_var.file);
   if (read != 1)
-return NULL;
+{
+  if (feof (gcov_var.file))
+   gcov_var.error = GCOV_FILE_EOF;
+  return NULL;
+}
 
 #ifdef IN_GCOV_TOOL
   gcov_var.pos += count;
@@ -434,7 +445,7 @@ gcov_read_counter (void)
   if (sizeof (value) > sizeof (gcov_unsigned_t))
 value |= ((gcov_type) from_file (buffer[1])) << 32;
   else if (buffer[1])
-gcov_var.error = -1;
+gcov_var.error = GCOV_FILE_COUNTER_OVERFLOW;
 
   return value;
 }
-- 
2.34.1



[RFC/gcov 12/12] gcov-tool: Add merge-stream subcommand

2022-03-31 Thread Sebastian Huber
gcc/

* gcov-tool.cc (gcov_profile_merge_stream): Declare.
(print_merge_stream_usage_message): New.
(merge_stream_usage): Likewise.
(do_merge_stream): Likewise.
(print_usage): Call print_merge_stream_usage_message().
(main): Call do_merge_stream() to execute merge-stream subcommand.

libgcc/

* libgcov-util.c (consume_stream): New.
(get_target_profiles_for_merge): Likewise.
(gcov_profile_merge_stream): Likewise.
---
 gcc/gcov-tool.cc  | 76 
 libgcc/libgcov-util.c | 80 +++
 2 files changed, 156 insertions(+)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index d712715cf7e..d8572b184e9 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -42,6 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 
 extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
 struct gcov_info*, int, int);
+extern struct gcov_info *gcov_profile_merge_stream (const char *, int, int);
 extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -229,6 +230,78 @@ do_merge (int argc, char **argv)
   return profile_merge (argv[optind], argv[optind+1], output_dir, w1, w2);
 }
 
+/* Usage message for profile merge-stream.  */
+
+static void
+print_merge_stream_usage_message (int error_p)
+{
+  FILE *file = error_p ? stderr : stdout;
+
+  fnotice (file, "  merge-stream [options] [stream-file]  Merge coverage 
stream file (or stdin)\n"
+"and coverage file 
contents\n");
+  fnotice (file, "-v, --verbose   Verbose mode\n");
+  fnotice (file, "-w, --weight Set weights (float 
point values)\n");
+}
+
+static const struct option merge_stream_options[] =
+{
+  { "verbose",no_argument,   NULL, 'v' },
+  { "weight", required_argument, NULL, 'w' },
+  { 0, 0, 0, 0 }
+};
+
+/* Print merge-stream usage and exit.  */
+
+static void ATTRIBUTE_NORETURN
+merge_stream_usage (void)
+{
+  fnotice (stderr, "Merge-stream subcomand usage:");
+  print_merge_stream_usage_message (true);
+  exit (FATAL_EXIT_CODE);
+}
+
+/* Driver for profile merge-stream sub-command.  */
+
+static int
+do_merge_stream (int argc, char **argv)
+{
+  int opt;
+  int w1 = 1, w2 = 1;
+  struct gcov_info *merged_profile;
+
+  optind = 0;
+  while ((opt = getopt_long (argc, argv, "vw:",
+merge_stream_options, NULL)) != -1)
+{
+  switch (opt)
+   {
+   case 'v':
+ verbose = true;
+ gcov_set_verbose ();
+ break;
+   case 'w':
+ sscanf (optarg, "%d,%d", &w1, &w2);
+ if (w1 < 0 || w2 < 0)
+   fatal_error (input_location, "weights need to be non-negative");
+ break;
+   default:
+ merge_stream_usage ();
+   }
+}
+
+  if (argc - optind > 1)
+merge_stream_usage ();
+
+  merged_profile = gcov_profile_merge_stream (argv[optind], w1, w2);
+
+  if (merged_profile)
+gcov_do_dump (merged_profile, 0, -1);
+  else if (verbose)
+fnotice (stdout, "no profile files were merged\n");
+
+  return 0;
+}
+
 /* If N_VAL is no-zero, normalize the profile by setting the largest counter
counter value to N_VAL and scale others counters proportionally.
Otherwise, multiply the all counters by SCALE.  */
@@ -505,6 +578,7 @@ print_usage (int error_p)
   fnotice (file, "  -h, --helpPrint this help, 
then exit\n");
   fnotice (file, "  -v, --version Print version 
number, then exit\n");
   print_merge_usage_message (error_p);
+  print_merge_stream_usage_message (error_p);
   print_rewrite_usage_message (error_p);
   print_overlap_usage_message (error_p);
   fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
@@ -594,6 +668,8 @@ main (int argc, char **argv)
 
   if (!strcmp (sub_command, "merge"))
 return do_merge (argc - optind, argv + optind);
+  else if (!strcmp (sub_command, "merge-stream"))
+return do_merge_stream (argc - optind, argv + optind);
   else if (!strcmp (sub_command, "rewrite"))
 return do_rewrite (argc - optind, argv + optind);
   else if (!strcmp (sub_command, "overlap"))
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 622d5a9dc71..0fe60528b48 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -735,6 +735,86 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
   return tgt_profile;
 }
 
+struct gcov_info *
+consume_stream (const char *filename)
+{
+  read_profile_dir_init ();
+
+  while (true)
+{
+  unsigned version;
+  const char *filename_of_info;
+  struct gcov_info *obj_info;
+

[RFC/gcov 10/12] gcov: Fix integer types in ftw_read_file()

2022-03-31 Thread Sebastian Huber
libgcc/

* libgcov-util.c (ftw_read_file): Use size_t for strlen() variables.
---
 libgcc/libgcov-util.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 03902ed10b1..622d5a9dc71 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -384,8 +384,8 @@ ftw_read_file (const char *filename,
const struct stat *status ATTRIBUTE_UNUSED,
int type)
 {
-  int filename_len;
-  int suffix_len;
+  size_t filename_len;
+  size_t suffix_len;
 
   /* Only read regular files.  */
   if (type != FTW_F)
-- 
2.34.1



Re: [PATCH] Add condition coverage profiling

2022-04-04 Thread Sebastian Huber

Hello Jørgen,

having support for MC/DC coverage in GCC would be really nice. I tried 
out your latest patch on an arm cross-compiler with Newlib (inhibit_libc 
is defined). Could you please add the following fix to your patch:


diff --git a/libgcc/libgcov-merge.c b/libgcc/libgcov-merge.c
index 89741f637e1..9e3e8ee5657 100644
--- a/libgcc/libgcov-merge.c
+++ b/libgcc/libgcov-merge.c
@@ -33,6 +33,11 @@ void __gcov_merge_add (gcov_type *counters 
__attribute__ ((unused)),

unsigned n_counters __attribute__ ((unused))) {}
 #endif

+#ifdef L_gcov_merge_ior
+void __gcov_merge_ior (gcov_type *counters  __attribute__ ((unused)),
+  unsigned n_counters __attribute__ ((unused))) {}
+#endif
+
 #ifdef L_gcov_merge_topn
 void __gcov_merge_topn (gcov_type *counters  __attribute__ ((unused)),
unsigned n_counters __attribute__ ((unused))) {}

It seems that support for the new GCOV_TAG_CONDS is missing in gcov-tool 
and gcov-dump, see "tag_table" in gcc/gcov-dump.c and libgcc/libgcov-util.c.


On 21/03/2022 12:55, Jørgen Kvalsvik via Gcc-patches wrote:
[...]

Like Wahlen et al this implementation uses bitsets to store conditions,
which gcov later interprets. This is very fast, but introduces an max
limit for the number of terms in a single boolean expression. This limit
is the number of bits in a gcov_unsigned_type (which is typedef'd to
uint64_t), so for most practical purposes this would be acceptable.
limitation can be relaxed with a more sophisticated way of storing and
updating bitsets (for example length-encoding).


For multi-threaded applications using -fprofile-update=atomic is quite 
important. Unfortunately, not all 32-bit targets support 64-bit atomic 
operations in hardware. There is a target hook to select the size of 
gcov_type. Maybe a dedicated 64-bit type should be used for the bitfield 
using two 32-bit atomic OR if necessary.




In action it looks pretty similar to the branch coverage. The -g short
opt carries no significance, but was chosen because it was an available
option with the upper-case free too.

gcov --conditions:

 3:   17:void fn (int a, int b, int c, int d) {
 3:   18:if ((a && (b || c)) && d)
conditions covered 5/8
condition  1 not covered (false)
condition  2 not covered (true)
condition  2 not covered (false)
 1:   19:x = 1;
 -:   20:else
 2:   21:x = 2;
 3:   22:}


I have some trouble to understand the output. Would 8/8 mean that we 
have 100% MC/DC coverage? What does "not covered (false)" or "not 
covered (true)" mean?


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] rs6000: Improve .machine

2022-04-04 Thread Sebastian Huber

Hello Segher,

On 15/03/2022 23:29, Segher Boessenkool wrote:

On Tue, Mar 15, 2022 at 03:29:23PM +0100, Sebastian Huber wrote:

now that the PR104829 is fixed could I back port

Segher Boessenkool (2):
   rs6000: Improve .machine
   rs6000: Do not use rs6000_cpu for .machine ppc and ppc64 (PR104829)

to GCC 10 and 11?

I will do it, in a few days though.

Thanks for your enthusiasm :-),


would now be a good time to back port the fixes or do you want to wait 
for the GCC 12 release? I would be nice if the fixes are included in the 
GCC 10.4 release.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] Add condition coverage profiling

2022-04-05 Thread Sebastian Huber

Hello Jørgen,

On 04/04/2022 10:14, Sebastian Huber wrote:
It seems that support for the new GCOV_TAG_CONDS is missing in gcov-tool 
and gcov-dump, see "tag_table" in gcc/gcov-dump.c and 
libgcc/libgcov-util.c.


it seems that for gcov-tool no changes are necessary. You added the 
condition bit fields as a new counter to gcov-counter.def and they are 
already properly merged with the help of __gcov_merge_ior().


I guess for gcov-dump it could be useful to add support for 
GCOV_TAG_CONDS used in the notes files.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] Add condition coverage profiling

2022-04-06 Thread Sebastian Huber

On 05/04/2022 22:07, Jørgen Kvalsvik wrote:

In action it looks pretty similar to the branch coverage. The -g short
opt carries no significance, but was chosen because it was an available
option with the upper-case free too.

gcov --conditions:

  3:   17:void fn (int a, int b, int c, int d) {
  3:   18:    if ((a && (b || c)) && d)
conditions covered 5/8
condition  1 not covered (false)
condition  2 not covered (true)
condition  2 not covered (false)
  1:   19:    x = 1;
  -:   20:    else
  2:   21:    x = 2;
  3:   22:}

I have some trouble to understand the output. Would 8/8 mean that we have 100%
MC/DC coverage? What does "not covered (false)" or "not covered (true)" mean?


Yes, 8/8 would mean that the expression is 100% covered (all conditions take on
both values and have independent effect on the outcome). 


This is really great.


"not covered" is a
report of missing coverage, that is "condition  1 not covered (false)" means
that bit N (N = 1, b in this case) has not taken on false yet, and to achieve
100% coverage you need a test case where b = false.

The wording is arbitrary, and I tried to strike a balance between density,
clarity, grepability and noise. I am open to other suggestions that would
improve this.


Ok, for the default output this is good. The output can be explained in 
the documentation. I will try to help here.


In theory, would it be possible to print the state of the truth table 
with the information available in the gcda and gcno files? For example:


Truth table for: a && (b || c)) && d

0 | 1 | 2 | 3 || covered
--+---+---+---++
0 | X | X | X || Y
0 | X | X | X || Y
0 | X | X | X || Y
0 | X | X | X || Y
0 | X | X | X || Y
0 | X | X | X || Y
0 | X | X | X || Y
0 | X | X | X || Y
1 | 0 | 0 | X || N
1 | 0 | 0 | X || N
1 | 0 | 1 | 0 || N
1 | 0 | 1 | 1 || N
1 | 1 | X | 0 || Y
1 | 1 | X | 0 || Y
1 | 1 | X | 1 || Y
1 | 1 | X | 1 || Y

Would it be possible to map the condition index to a source code 
snippet? For example condition 1 to "b"?




Unrelated to this, in typing up some notes on this I found a few minor and one
quite significant (really, the masking algorithm is broken) error in the
algorithm, which I am working on correcting. I will propose the new patch with
these fixes too once I have finished writing and testing it.


Thanks a lot for this work.

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [RFC/gcov 00/12] Add merge-stream subcommand to gcov-tool

2022-04-07 Thread Sebastian Huber

Hello Martin,

thanks for the review. I am not really used to write func ().

On 07/04/2022 10:38, Martin Liška wrote:


TODO:

* Documentation


I would install the patches with documentation change bits.


Ok, I will add some documentation changes and send them with a v2 of the 
patch set after stage 0 opens.


I would like to add a chapter about the use of gcov in systems without a 
file system.





* Tests


Tests can be added after that.


Ok, good.

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] Add condition coverage profiling

2022-04-07 Thread Sebastian Huber

Hello Jørgen,

there could be an issue with conditions in for loops:

3:  189:  for (int a = 0; a <= 1; ++a) {
branch  0 taken 2
branch  1 taken 1 (fallthrough)
conditions covered 0/2
condition  0 not covered (true)
condition  0 not covered (false)

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] Add condition coverage profiling

2022-04-08 Thread Sebastian Huber

On 08/04/2022 09:33, Jørgen Kvalsvik wrote:

On 08/04/2022 09:28, Jørgen Kvalsvik wrote:

On 07/04/2022 18:53, Sebastian Huber wrote:

Hello Jørgen,

there could be an issue with conditions in for loops:

     3:  189:  for (int a = 0; a <= 1; ++a) {
branch  0 taken 2
branch  1 taken 1 (fallthrough)
conditions covered 0/2
condition  0 not covered (true)
condition  0 not covered (false)


Hello,

Thanks, I'll have a look at it. There should be a for loop in the test suite,
but I'll add this exact example and see if I can reproduce it. This should
obviously be 100% covered.

Sebastian,

I added this exact example to the test suite, but it reports 2/2 for me (linux
amd64). Do you have a very different system, and what flags did you use?


Thanks for having a look at this. My setup is a bit more complicated. I 
use an arm cross compiler and run an application on a simulator (Qemu). 
The *.gcda files are created by gcov-tool. It is probably an issue with 
my setup, so maybe we should ignore this issue at the moment.


When I move the code to a separate translation unit:

#include 

static __attribute__((__noinline__)) int f(int a, int b, int c, int d)
{
  if (a || (b && c) || d) {
return 1;
  } else {
return 2;
  }
}

void test(void)
{
  for (int a = 0; a <= 1; ++a) {
for (int b = 0; b <= 1; ++b) {
  for (int c = 0; c <= 1; ++c) {
for (int d = 0; d <= 1; ++d) {
  printf("%i\n", f(a, b, c, d));
}
  }
}
  }
}

I get the right report:

-:0:Source:conds.c
-:0:Graph:b-xilinx_zynq_a9_qemu/conds.gcno
-:0:Data:b-xilinx_zynq_a9_qemu/conds.gcda
-:0:Runs:0
-:1:#include 
-:2:
function f called 16 returned 100% blocks executed 100%
   16:3:static __attribute__((__noinline__)) int f(int a, int 
b, int c, int d)

-:4:{
   16:5:  if (a || (b && c) || d) {
branch  0 taken 8 (fallthrough)
branch  1 taken 8
branch  2 taken 4 (fallthrough)
branch  3 taken 4
branch  4 taken 2 (fallthrough)
branch  5 taken 2
branch  6 taken 3 (fallthrough)
branch  7 taken 3
conditions covered 8/8
   13:6:return 1;
-:7:  } else {
3:8:return 2;
-:9:  }
-:   10:}
-:   11:
function test called 1 returned 100% blocks executed 100%
1:   12:void test(void)
-:   13:{
3:   14:  for (int a = 0; a <= 1; ++a) {
branch  0 taken 2
branch  1 taken 1 (fallthrough)
conditions covered 2/2
6:   15:for (int b = 0; b <= 1; ++b) {
branch  0 taken 4
branch  1 taken 2 (fallthrough)
conditions covered 2/2
   12:   16:  for (int c = 0; c <= 1; ++c) {
branch  0 taken 8
branch  1 taken 4 (fallthrough)
conditions covered 2/2
   24:   17:for (int d = 0; d <= 1; ++d) {
branch  0 taken 16
branch  1 taken 8 (fallthrough)
conditions covered 2/2
   16:   18:  printf("%i\n", f(a, b, c, d));
call0 returned 16
call1 returned 16
-:   19:}
-:   20:  }
-:   21:}
-:   22:  }
1:   23:}

For exactly the same code in another translation unit with more other 
code I get this report:


function f called 16 returned 100% blocks executed 100%
   16:  172:static __attribute__((__noinline__)) int f(int a, int 
b, int c, int d)

-:  173:{
   16:  174:  if (a || (b && c) || d) {
branch  0 taken 8 (fallthrough)
branch  1 taken 8
branch  2 taken 4 (fallthrough)
branch  3 taken 4
branch  4 taken 2 (fallthrough)
branch  5 taken 2
branch  6 taken 3 (fallthrough)
branch  7 taken 3
conditions covered 8/8
   13:  175:return 1;
-:  176:  } else {
3:  177:return 2;
-:  178:  }
-:  179:}
-:  180:
function Init called 1 returned 0% blocks executed 93%
1:  181:static void Init( rtems_task_argument arg )
-:  182:{
-:  183:  struct ethernetif ethif;
-:  184:  struct netif *netif;
-:  185:
-:  186:  (void) arg;
1:  187:  netif = ðif.netif;
-:  188:
3:  189:  for (int a = 0; a <= 1; ++a) {
branch  0 taken 2
branch  1 taken 1 (fallthrough)
conditions covered 0/2
condition  0 not covered (true)
condition  0 not covered (false)
6:  190:for (int b = 0; b <= 1; ++b) {
branch  0 taken 4
branch  1 taken 2 (fallthrough)
conditions covered 0/2
condition  0 not covered (true)
condition  0 not covered (false)
   12:  191:  for (int c = 0; c <= 1; ++c) {
branch  0 taken 8
branch  1 taken 4 (fallthrough)
conditions covered 0/2
condition  0 not covered (true)
condition  0 not covered (false)
   24:  192:for (int d = 0; d <= 1; ++d) {
branch  0 taken 16
branch  1 taken 8 (fallthrough)
conditions covered 0/2
condition  0 not covered (true)
condition  0 not covered (false)
   16:  193:  printf("%i\n"

Re: [PATCH] Add condition coverage profiling

2022-04-21 Thread Sebastian Huber




On 17/04/2022 13:27, Jørgen Kvalsvik wrote:

In theory, would it be possible to print the state of the truth table with the
information available in the gcda and gcno files? For example:

Truth table for: a && (b || c)) && d

0 | 1 | 2 | 3 || covered
--+---+---+---++
0 | X | X | X || Y
0 | X | X | X || Y
0 | X | X | X || Y
0 | X | X | X || Y
0 | X | X | X || Y
0 | X | X | X || Y
0 | X | X | X || Y
0 | X | X | X || Y
1 | 0 | 0 | X || N
1 | 0 | 0 | X || N
1 | 0 | 1 | 0 || N
1 | 0 | 1 | 1 || N
1 | 1 | X | 0 || Y
1 | 1 | X | 0 || Y
1 | 1 | X | 1 || Y
1 | 1 | X | 1 || Y

Maybe? We would at least need to store the masking tables too, which right now
are implicitly stored as in the instrumentation. It's not too bad, but it
probably means the two functions should return some richer structure, which in
turn means a little bit of redesign. Computing the truth table itself shouldn't
be difficult.


Using the tool in the context of safety-critical application would 
normally require also a tool qualification. For GCC, this is a bit 
unrealistic. It would help if the tool output can be verified. Being 
able to inspect the masking tables could help a reviewer to check what 
the tool did for a sample set of inputs.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH] powerc: Fix asm machine directive for some CPUs

2022-01-18 Thread Sebastian Huber
For some CPUs, the assembler machine directive cannot be determined by ISA
flags.

gcc/

PR 104090/target
* config/rs6000/rs6000.cc (rs6000_machine_from_flags): Use also
rtems_cpu.
---
 gcc/config/rs6000/rs6000.cc | 28 
 1 file changed, 28 insertions(+)

diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 7a4ef5e6c0a8..d37775ece84d 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -5935,6 +5935,34 @@ const char *rs6000_machine;
 const char *
 rs6000_machine_from_flags (void)
 {
+  /* For some CPUs, the machine cannot be determined by ISA flags.  We have to
+ check them first.  */
+  switch (rs6000_cpu)
+{
+case PROCESSOR_PPC8540:
+case PROCESSOR_PPC8548:
+  return "e500";
+
+case PROCESSOR_PPCE300C2:
+case PROCESSOR_PPCE300C3:
+  return "e300";
+
+case PROCESSOR_PPCE500MC:
+  return "e500mc";
+
+case PROCESSOR_PPCE500MC64:
+  return "e500mc64";
+
+case PROCESSOR_PPCE5500:
+  return "e5500";
+
+case PROCESSOR_PPCE6500:
+  return "e6500";
+
+default:
+  break;
+}
+
   HOST_WIDE_INT flags = rs6000_isa_flags;
 
   /* Disable the flags that should never influence the .machine selection.  */
-- 
2.26.2



Re: [PATCH] powerc: Fix asm machine directive for some CPUs

2022-01-18 Thread Sebastian Huber

On 18/01/2022 22:42, Segher Boessenkool wrote:

+default:
+  break;

Please don't do that.  You can do

   default:
 break;
 break;
 /* And just to make sure:  */
 break;
 break;

and it will do exactly the same as not having a default at all.  Not
having such useless code is by far the most readable, so please don't
include a default case at all.


I removed the default case. I hope this is what you wanted.



Okay with those changes.  Thanks!


Thanks for having a look at this. I would like to back port this patch 
also to the GCC 10 and 11 branches.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] powerc: Fix asm machine directive for some CPUs

2022-02-02 Thread Sebastian Huber

On 19/01/2022 07:54, Sebastian Huber wrote:




Okay with those changes.  Thanks!


Thanks for having a look at this. I would like to back port this patch 
also to the GCC 10 and 11 branches.


The default is to ask for back ports after a break. Can I back port the 
patch (with the default: break) to GCC 10 and 11 now?


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [Ada] RTEMS: use hardware interrupts instead of signals for interrupt handling

2021-11-26 Thread Sebastian Huber

Hello Pierre-Marie,

On 11/10/2021 15:39, Pierre-Marie de Rodat via Gcc-patches wrote:

RTEMS supports attaching interrupt handlers to hardware interrupt
vectors, which is superior to the current approach of attaching handlers
to signals.  Direct attachment of handlers removes the execution
overhead of converting hardware interrupts to signals and their
subsequent propagation to the interrupt manager. It also removes the
limitation of the number of hardware interrupts that can be supported
under the signals model, as RTEMS is limited to 32 signals.

Tested on x86_64-pc-linux-gnu, committed on trunk


for Newlib internal locks, the OpenMP library (libgomp), and the C++ 
standard library we use self-contained synchronization objects for RTEMS 
defined by  which is provided by Newlib:


https://sourceware.org/git/?p=newlib-cygwin.git;a=blob;f=newlib/libc/sys/rtems/include/sys/lock.h;h=d6169025b1a0d10ded0e31982baff64453e69cae;hb=HEAD

Binary and counting semaphores are supported, for example:

void _Semaphore_Post_binary(struct _Semaphore_Control *);

Using this interface has the benefit that the storage for the 
synchronization objects is user-provided. So, there is no need to 
account for these objects in the configuration.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH] riscv/RTEMS: Add RISCV_GCOV_TYPE_SIZE

2022-10-26 Thread Sebastian Huber
The RV32A extension does not support 64-bit atomic operations.  For RTEMS, use
a 32-bit gcov type for RV32.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_gcov_type_size): New.
(TARGET_GCOV_TYPE_SIZE): Likewise.
* config/riscv/rtems.h (RISCV_GCOV_TYPE_SIZE): New.
---
 gcc/config/riscv/riscv.cc | 11 +++
 gcc/config/riscv/rtems.h  |  2 ++
 2 files changed, 13 insertions(+)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 4e18a43539a..1b7f4fb1981 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -6637,6 +6637,17 @@ riscv_vector_alignment (const_tree type)
 #undef TARGET_VECTOR_ALIGNMENT
 #define TARGET_VECTOR_ALIGNMENT riscv_vector_alignment
 
+#ifdef RISCV_GCOV_TYPE_SIZE
+static HOST_WIDE_INT
+riscv_gcov_type_size (void)
+{
+  return RISCV_GCOV_TYPE_SIZE;
+}
+
+#undef TARGET_GCOV_TYPE_SIZE
+#define TARGET_GCOV_TYPE_SIZE riscv_gcov_type_size
+#endif
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-riscv.h"
diff --git a/gcc/config/riscv/rtems.h b/gcc/config/riscv/rtems.h
index 14e5e59caaa..3982b24382f 100644
--- a/gcc/config/riscv/rtems.h
+++ b/gcc/config/riscv/rtems.h
@@ -29,3 +29,5 @@
builtin_define ("__USE_INIT_FINI__");   \
builtin_assert ("system=rtems");\
 } while (0)
+
+#define RISCV_GCOV_TYPE_SIZE (TARGET_64BIT ? 64 : 32)
-- 
2.35.3



Re: [PATCH 1/2] Allow subtarget customization of CC1_SPEC

2022-10-26 Thread Sebastian Huber

On 04/10/2022 11:47, Sebastian Huber wrote:

On 08/09/2022 07:33, Sebastian Huber wrote:

On 04/08/2022 15:02, Sebastian Huber wrote:

On 22/07/2022 15:02, Sebastian Huber wrote:

gcc/ChangeLog:

* gcc.cc (SUBTARGET_CC1_SPEC): Define if not defined.
(CC1_SPEC): Define to SUBTARGET_CC1_SPEC.
* config/arm/arm.h (CC1_SPEC): Remove.
* config/arc/arc.h (CC1_SPEC): Append SUBTARGET_CC1_SPEC.
* config/cris/cris.h (CC1_SPEC): Likewise.
* config/frv/frv.h (CC1_SPEC): Likewise.
* config/i386/i386.h (CC1_SPEC): Likewise.
* config/ia64/ia64.h (CC1_SPEC): Likewise.
* config/lm32/lm32.h (CC1_SPEC): Likewise.
* config/m32r/m32r.h (CC1_SPEC): Likewise.
* config/mcore/mcore.h (CC1_SPEC): Likewise.
* config/microblaze/microblaze.h: Likewise.
* config/nds32/nds32.h (CC1_SPEC): Likewise.
* config/nios2/nios2.h (CC1_SPEC): Likewise.
* config/pa/pa.h (CC1_SPEC): Likewise.
* config/rs6000/sysv4.h (CC1_SPEC): Likewise.
* config/rx/rx.h (CC1_SPEC): Likewise.
* config/sparc/sparc.h (CC1_SPEC): Likewise.


Could someone please have a look at this patch set?


Ping.


Would someone mind having a look at this patch set? If there is a better 
approach to customize the default TLS model, then please let me know.


It would be nice if someone could review the patch before the Stage 1 
ends at November 13th.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


Re: [PATCH] riscv/RTEMS: Add RISCV_GCOV_TYPE_SIZE

2022-10-27 Thread Sebastian Huber

On 28/10/2022 01:05, Palmer Dabbelt wrote:

On Thu, 27 Oct 2022 15:56:17 PDT (-0700), gcc-patches@gcc.gnu.org wrote:


On 10/26/22 01:49, Sebastian Huber wrote:
The RV32A extension does not support 64-bit atomic operations.  For 
RTEMS, use

a 32-bit gcov type for RV32.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_gcov_type_size): New.
(TARGET_GCOV_TYPE_SIZE): Likewise.
* config/riscv/rtems.h (RISCV_GCOV_TYPE_SIZE): New.


Why make this specific to rtems?  ISTM the logic behind this change
would apply independently of the os.


Reducing the gcov type to 32-bit has the drawback that the program 
runtime is reduced. I am not sure if this is generally acceptable.




Looks like rv32gc is just broken here:

$ cat test.s
int func(int x) { return x + 1; }
$ gcc -march=rv32gc -O3 -fprofile-update=atomic -fprofile-arcs test.c -S 
-o-

func(int):
    lui a4,%hi(__gcov0.func(int))
    lw  a5,%lo(__gcov0.func(int))(a4)
    lw  a2,%lo(__gcov0.func(int)+4)(a4)
    addi    a0,a0,1
    addi    a3,a5,1
    sltu    a5,a3,a5
    add a5,a5,a2
    sw  a3,%lo(__gcov0.func(int))(a4)
    sw  a5,%lo(__gcov0.func(int)+4)(a4)
    ret
_sub_I_00100_0:
    lui a0,%hi(.LANCHOR0)
    addi    a0,a0,%lo(.LANCHOR0)
    tail    __gcov_init
_sub_D_00100_1:
    tail    __gcov_exit
__gcov0.func(int):
    .zero   8

Those are not atomic...


Well, you get at least a warning:

test.c:1:1: warning: target does not support atomic profile update, 
single mode is selected


With the patch you get:

riscv-rtems6-gcc -march=rv32gc -O3 -fprofile-update=atomic 
-fprofile-arcs test.c -S -o-

func:
lui a5,%hi(__gcov0.func)
li  a4,1
addia5,a5,%lo(__gcov0.func)
amoadd.w zero,a4,0(a5)
addia0,a0,1
ret
.size   func, .-func

The Armv7-A doesn't have an issue with 64-bit atomics:

arm-rtems6-gcc -march=armv7-a -O3 -fprofile-update=atomic -fprofile-arcs 
test.c -S -o-

func:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
movwr3, #:lower16:.LANCHOR0
movtr3, #:upper16:.LANCHOR0
push{r4, r5, r6, r7}
mov r4, #1
mov r5, #0
.L2:
ldrexd  r6, r7, [r3]
addsr6, r6, r4
adc r7, r7, r5
strexd  r1, r6, r7, [r3]
cmp r1, #0
bne .L2
add r0, r0, #1
pop {r4, r5, r6, r7}
bx  lr

Maybe RV32 should also support LL/SC instructions with two 32-bit registers.

Another option would be to split the atomic increment into two parts as 
suggested by Jakub Jelinek:


https://patchwork.ozlabs.org/project/gcc/patch/19c4a81d-6ecd-8c6e-b641-e257c1959...@suse.cz/#1447334

Another option would be to use library calls if hardware atomics are not 
available.


--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[PATCH/gcc] RTEMS: Add -mvrsave multilibs

2022-09-01 Thread Sebastian Huber
gcc/ChangeLog:

* config/rs6000/rtems.h (CPP_OS_DEFAULT_SPEC): Define __PPC_VRSAVE__ if
-mvrsave is present.
* config/rs6000/t-rtems: Add -mvrsave multilib variants for
-mcpu=e6500.
---
 gcc/config/rs6000/rtems.h | 3 ++-
 gcc/config/rs6000/t-rtems | 5 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rtems.h b/gcc/config/rs6000/rtems.h
index 7ea9ebdb77b..683004eb07c 100644
--- a/gcc/config/rs6000/rtems.h
+++ b/gcc/config/rs6000/rtems.h
@@ -252,7 +252,8 @@
 %{mcpu=821:  %{!Dppc*: %{!Dmpc*: -Dmpc821}  } } \
 %{mcpu=860:  %{!Dppc*: %{!Dmpc*: -Dmpc860}  } } \
 %{mcpu=8540: %{!Dppc*: %{!Dmpc*: -Dppc8540}  } } \
-%{mcpu=e6500: -D__PPC_CPU_E6500__}"
+%{mcpu=e6500: -D__PPC_CPU_E6500__} \
+%{mvrsave: -D__PPC_VRSAVE__}"
 
 #undef ASM_DEFAULT_SPEC
 #defineASM_DEFAULT_SPEC "-mppc%{m64:64}"
diff --git a/gcc/config/rs6000/t-rtems b/gcc/config/rs6000/t-rtems
index 66c20aadea5..278ebb69e60 100644
--- a/gcc/config/rs6000/t-rtems
+++ b/gcc/config/rs6000/t-rtems
@@ -36,6 +36,9 @@ MULTILIB_DIRNAMES += nof gprsdouble
 MULTILIB_OPTIONS += mno-spe/mno-altivec
 MULTILIB_DIRNAMES += nospe noaltivec
 
+MULTILIB_OPTIONS += mvrsave
+MULTILIB_DIRNAMES += vrsave
+
 MULTILIB_MATCHES   += ${MULTILIB_MATCHES_ENDIAN}
 MULTILIB_MATCHES   += ${MULTILIB_MATCHES_SYSV}
 # Map 405 to 403
@@ -76,5 +79,7 @@ MULTILIB_REQUIRED += mcpu=8540/msoft-float/mno-spe
 MULTILIB_REQUIRED += mcpu=8540/mfloat-gprs=double
 MULTILIB_REQUIRED += mcpu=860
 MULTILIB_REQUIRED += mcpu=e6500/m32
+MULTILIB_REQUIRED += mcpu=e6500/m32/mvrsave
 MULTILIB_REQUIRED += mcpu=e6500/m32/msoft-float/mno-altivec
 MULTILIB_REQUIRED += mcpu=e6500/m64
+MULTILIB_REQUIRED += mcpu=e6500/m64/mvrsave
-- 
2.26.2



Re: [PATCH 1/2] Allow subtarget customization of CC1_SPEC

2022-09-07 Thread Sebastian Huber

On 04/08/2022 15:02, Sebastian Huber wrote:

On 22/07/2022 15:02, Sebastian Huber wrote:

gcc/ChangeLog:

* gcc.cc (SUBTARGET_CC1_SPEC): Define if not defined.
(CC1_SPEC): Define to SUBTARGET_CC1_SPEC.
* config/arm/arm.h (CC1_SPEC): Remove.
* config/arc/arc.h (CC1_SPEC): Append SUBTARGET_CC1_SPEC.
* config/cris/cris.h (CC1_SPEC): Likewise.
* config/frv/frv.h (CC1_SPEC): Likewise.
* config/i386/i386.h (CC1_SPEC): Likewise.
* config/ia64/ia64.h (CC1_SPEC): Likewise.
* config/lm32/lm32.h (CC1_SPEC): Likewise.
* config/m32r/m32r.h (CC1_SPEC): Likewise.
* config/mcore/mcore.h (CC1_SPEC): Likewise.
* config/microblaze/microblaze.h: Likewise.
* config/nds32/nds32.h (CC1_SPEC): Likewise.
* config/nios2/nios2.h (CC1_SPEC): Likewise.
* config/pa/pa.h (CC1_SPEC): Likewise.
* config/rs6000/sysv4.h (CC1_SPEC): Likewise.
* config/rx/rx.h (CC1_SPEC): Likewise.
* config/sparc/sparc.h (CC1_SPEC): Likewise.


Could someone please have a look at this patch set?


Ping.

--
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.hu...@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/


[gcov v2 00/14] Add merge-stream subcommand to gcov-tool

2022-04-25 Thread Sebastian Huber
This patch set is for GCC 13.

The aim is to better support gcov in free-standing environments. For example,
you can run a test executable which dumps all gcov info objects in a serial
data stream using __gcov_info_to_gcda() and the new __gcov_filename_to_gcfn().
It could be encoded as base64. It could be also compressed. On the host you
unpack the encoded data stream and feed it into gcov-tool using the new
"merge-stream" subcommand:

gcov-tool --help
Usage: gcov-tool [OPTION]... SUB_COMMAND [OPTION]...

Offline tool to handle gcda counts

  -h, --helpPrint this help, then exit
  -v, --version Print version number, then exit
  merge-stream [options] [stream-file]  Merge coverage stream file (or stdin)
and coverage file contents
-v, --verbose   Verbose mode
-w, --weight Set weights (float point values)

Example:

base64 -d log.txt | gcov-tool merge-stream

The patch set does not change the format of .gcda files.

TODO:

* Tests for gcov-tool

v2:

* Address review comments from v1

* Simple test for __gcov_filename_to_gcfn()

* Use xstrerror()

* Add documentation

Sebastian Huber (14):
  gcov-tool: Allow merging of empty profile lists
  gcov: Add mode to all gcov_open()
  gcov: Add open mode parameter to gcov_do_dump()
  gcov: Make gcov_seek() static
  gcov: Add __gcov_filename_to_gcfn()
  gcov-tool: Support file input from stdin
  gcov: Use xstrdup()
  gcov: Move prepend to list to read_gcda_file()
  gcov: Move gcov_open() to caller of read_gcda_file()
  gcov: Fix integer types in ftw_read_file()
  gcov: Record EOF error during read
  gcov-tool: Add merge-stream subcommand
  gcov: Use xstrerror()
  gcov: Add section for freestanding environments

 gcc/doc/gcov-tool.texi   |  36 +++
 gcc/doc/gcov.texi| 375 +++
 gcc/doc/invoke.texi  |  31 +-
 gcc/gcov-io.cc   |  79 +++--
 gcc/gcov-io.h|  35 ++-
 gcc/gcov-tool.cc | 107 +--
 gcc/testsuite/gcc.dg/gcov-info-to-gcda.c |  36 ++-
 libgcc/gcov.h|  17 +-
 libgcc/libgcov-driver-system.c   |   7 +-
 libgcc/libgcov-driver.c  |  44 ++-
 libgcc/libgcov-util.c| 150 +++--
 libgcc/libgcov.h |   3 -
 12 files changed, 803 insertions(+), 117 deletions(-)

-- 
2.34.1



[gcov v2 01/14] gcov-tool: Allow merging of empty profile lists

2022-04-25 Thread Sebastian Huber
The gcov_profile_merge() already had code to deal with profile information
which had no counterpart to merge with.  For profile information from files
with no associated counterpart, the profile information is simply used as is
with the weighting transformation applied.  Make sure that gcov_profile_merge()
works with an empty target profile list.  Return the merged profile list.

gcc/
* gcov-tool.cc (gcov_profile_merge): Adjust return type.
(profile_merge): Allow merging of directories which contain no profile
files.

libgcc/
* libgcov-util.c (gcov_profile_merge): Return the list of merged
profiles.  Accept empty target and source profile lists.
---
 gcc/gcov-tool.cc  | 27 ++-
 libgcc/libgcov-util.c | 19 +++
 2 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index f4e42ae763c..2e4083a664d 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -40,7 +40,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #endif
 #include 
 
-extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, int, int);
+extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
+struct gcov_info*, int, int);
 extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -141,26 +142,18 @@ profile_merge (const char *d1, const char *d2, const char 
*out, int w1, int w2)
 {
   struct gcov_info *d1_profile;
   struct gcov_info *d2_profile;
-  int ret;
+  struct gcov_info *merged_profile;
 
   d1_profile = gcov_read_profile_dir (d1, 0);
-  if (!d1_profile)
-return 1;
-
-  if (d2)
-{
-  d2_profile = gcov_read_profile_dir (d2, 0);
-  if (!d2_profile)
-return 1;
+  d2_profile = gcov_read_profile_dir (d2, 0);
 
-  /* The actual merge: we overwrite to d1_profile.  */
-  ret = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
+  /* The actual merge: we overwrite to d1_profile.  */
+  merged_profile = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
 
-  if (ret)
-return ret;
-}
-
-  gcov_output_files (out, d1_profile);
+  if (merged_profile)
+gcov_output_files (out, merged_profile);
+  else if (verbose)
+fnotice (stdout, "no profile files were merged\n");
 
   return 0;
 }
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index ba7fb924b53..100f1b19f1a 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -674,16 +674,16 @@ find_match_gcov_info (struct gcov_info **array, int size,
 }
 
 /* Merge the list of gcov_info objects from SRC_PROFILE to TGT_PROFILE.
-   Return 0 on success: without mismatch.
-   Reutrn 1 on error.  */
+   Return the list of merged gcov_info objects.  Return NULL if the list is
+   empty.  */
 
-int
+struct gcov_info *
 gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info 
*src_profile,
 int w1, int w2)
 {
   struct gcov_info *gi_ptr;
   struct gcov_info **tgt_infos;
-  struct gcov_info *tgt_tail;
+  struct gcov_info **tgt_tail;
   struct gcov_info **in_src_not_tgt;
   unsigned tgt_cnt = 0, src_cnt = 0;
   unsigned unmatch_info_cnt = 0;
@@ -703,7 +703,10 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
   for (gi_ptr = tgt_profile, i = 0; gi_ptr; gi_ptr = gi_ptr->next, i++)
 tgt_infos[i] = gi_ptr;
 
-  tgt_tail = tgt_infos[tgt_cnt - 1];
+  if (tgt_cnt)
+ tgt_tail = &tgt_infos[tgt_cnt - 1]->next;
+  else
+ tgt_tail = &tgt_profile;
 
   /* First pass on tgt_profile, we multiply w1 to all counters.  */
   if (w1 > 1)
@@ -732,14 +735,14 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
   gi_ptr = in_src_not_tgt[i];
   gcov_merge (gi_ptr, gi_ptr, w2 - 1);
   gi_ptr->next = NULL;
-  tgt_tail->next = gi_ptr;
-  tgt_tail = gi_ptr;
+  *tgt_tail = gi_ptr;
+  tgt_tail = &gi_ptr->next;
 }
 
   free (in_src_not_tgt);
   free (tgt_infos);
 
-  return 0;
+  return tgt_profile;
 }
 
 typedef gcov_type (*counter_op_fn) (gcov_type, void*, void*);
-- 
2.34.1



[gcov v2 02/14] gcov: Add mode to all gcov_open()

2022-04-25 Thread Sebastian Huber
gcc/

* gcov-io.cc (gcov_open): Always use the mode parameter.
* gcov-io.h (gcov_open): Declare it unconditionally.

libgcc/

* libgcov-driver-system.c (gcov_exit_open_gcda_file): Open file for
reading and writing.
* libgcov-util.c (read_gcda_file): Open file for reading.
* libgcov.h (gcov_open): Delete declaration.
---
 gcc/gcov-io.cc | 7 ---
 gcc/gcov-io.h  | 5 +
 libgcc/libgcov-driver-system.c | 4 ++--
 libgcc/libgcov-util.c  | 2 +-
 libgcc/libgcov.h   | 1 -
 5 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 72c40f8eaa0..017a6e32a5d 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -89,15 +89,8 @@ from_file (gcov_unsigned_t value)
Return zero on failure, non-zero on success.  */
 
 GCOV_LINKAGE int
-#if IN_LIBGCOV
-gcov_open (const char *name)
-#else
 gcov_open (const char *name, int mode)
-#endif
 {
-#if IN_LIBGCOV
-  int mode = 0;
-#endif
 #if GCOV_LOCKED
   struct flock s_flock;
   int fd;
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 99ce7dbccc8..afe74b002f1 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -347,15 +347,12 @@ struct gcov_summary
functions for writing.  Your file may become corrupted if you break
these invariants.  */
 
-#if !IN_LIBGCOV
-GCOV_LINKAGE int gcov_open (const char */*name*/, int /*direction*/);
-#endif
-
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
 GCOV_LINKAGE int gcov_magic (gcov_unsigned_t, gcov_unsigned_t);
 #endif
 
 /* Available everywhere.  */
+GCOV_LINKAGE int gcov_open (const char *, int) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE int gcov_close (void) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE gcov_type gcov_read_counter (void) ATTRIBUTE_HIDDEN;
diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index eef6e3cbda1..9abb2fe7f74 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -309,7 +309,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
 
   gf->filename = replace_filename_variables (gf->filename);
 
-  if (!gcov_open (gf->filename))
+  if (!gcov_open (gf->filename, 0))
 {
   /* Open failed likely due to missed directory.
  Create directory and retry to open file. */
@@ -318,7 +318,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
   fprintf (stderr, "profiling:%s:Skip\n", gf->filename);
   return -1;
 }
-  if (!gcov_open (gf->filename))
+  if (!gcov_open (gf->filename, 0))
 {
   fprintf (stderr, "profiling:%s:Cannot open\n", gf->filename);
   return -1;
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 100f1b19f1a..db157220c9d 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -268,7 +268,7 @@ read_gcda_file (const char *filename)
 k_ctrs_mask[i] = 0;
   k_ctrs_types = 0;
 
-  if (!gcov_open (filename))
+  if (!gcov_open (filename, 1))
 {
   fnotice (stderr, "%s:cannot open\n", filename);
   return NULL;
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 40e845ce3ea..f190547e819 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -343,7 +343,6 @@ extern int __gcov_execve (const char *, char  *const [], 
char *const [])
   ATTRIBUTE_HIDDEN;
 
 /* Functions that only available in libgcov.  */
-GCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
   const struct gcov_summary *)
 ATTRIBUTE_HIDDEN;
-- 
2.34.1



[gcov v2 04/14] gcov: Make gcov_seek() static

2022-04-25 Thread Sebastian Huber
This function is only used by gcov_write_length() in the gcov-io.cc file.

gcc/

* gcov-io.cc (gcov_seek): Make it static.
* gcov-io.h (struct gcov_summary): Do not mention gcov_seek().

libgcc/

* libgcov.h (gcov_seek): Remove define and declaration.
---
 gcc/gcov-io.cc   | 4 +---
 gcc/gcov-io.h| 6 +++---
 libgcc/libgcov.h | 2 --
 3 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 017a6e32a5d..fee3130f94a 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -294,17 +294,15 @@ gcov_write_filename (const char *filename)
 
   gcov_write_string (filename);
 }
-#endif
 
 /* Move to a given position in a gcov file.  */
 
-GCOV_LINKAGE void
+static void
 gcov_seek (gcov_position_t base)
 {
   fseek (gcov_var.file, base, SEEK_SET);
 }
 
-#if !IN_LIBGCOV
 /* Write a tag TAG and reserve space for the record length. Return a
value to be used for gcov_write_length.  */
 
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index afe74b002f1..204ae0ccf7f 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -340,9 +340,9 @@ struct gcov_summary
 /* Functions for reading and writing gcov files. In libgcov you can
open the file for reading then writing. Elsewhere you can open the
file either for reading or for writing. When reading a file you may
-   use the gcov_read_* functions, gcov_sync, gcov_position, &
-   gcov_error. When writing a file you may use the gcov_write
-   functions, gcov_seek & gcov_error. When a file is to be rewritten
+   use the gcov_read_* functions, gcov_sync, gcov_position, and
+   gcov_error. When writing a file you may use the gcov_write*
+   functions and gcov_error. When a file is to be rewritten
you use the functions for reading, then gcov_rewrite then the
functions for writing.  Your file may become corrupted if you break
these invariants.  */
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index f190547e819..487bd1464cd 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -115,7 +115,6 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode 
(QI)));
 #define gcov_open __gcov_open
 #define gcov_close __gcov_close
 #define gcov_position __gcov_position
-#define gcov_seek __gcov_seek
 #define gcov_rewrite __gcov_rewrite
 #define gcov_is_error __gcov_is_error
 #define gcov_write_unsigned __gcov_write_unsigned
@@ -346,7 +345,6 @@ extern int __gcov_execve (const char *, char  *const [], 
char *const [])
 GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
   const struct gcov_summary *)
 ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE void gcov_rewrite (void) ATTRIBUTE_HIDDEN;
 
 /* "Counts" stored in gcda files can be a real counter value, or
-- 
2.34.1



[gcov v2 12/14] gcov-tool: Add merge-stream subcommand

2022-04-25 Thread Sebastian Huber
gcc/

* doc/gcov-tool.texi: Document merge-stream subcommand.
* doc/invoke.texi (fprofile-info-section): Mention merge-stream
subcommand of gcov-tool.
* gcov-tool.cc (gcov_profile_merge_stream): Declare.
(print_merge_stream_usage_message): New.
(merge_stream_usage): Likewise.
(do_merge_stream): Likewise.
(print_usage): Call print_merge_stream_usage_message().
(main): Call do_merge_stream() to execute merge-stream subcommand.

libgcc/

* libgcov-util.c (consume_stream): New.
(get_target_profiles_for_merge): Likewise.
(gcov_profile_merge_stream): Likewise.
---
 gcc/doc/gcov-tool.texi | 36 
 gcc/doc/invoke.texi|  5 +++
 gcc/gcov-tool.cc   | 76 +
 libgcc/libgcov-util.c  | 95 ++
 4 files changed, 212 insertions(+)

diff --git a/gcc/doc/gcov-tool.texi b/gcc/doc/gcov-tool.texi
index d79dbc94a8c..77150836acc 100644
--- a/gcc/doc/gcov-tool.texi
+++ b/gcc/doc/gcov-tool.texi
@@ -52,6 +52,10 @@ Current gcov-tool supports the following functionalities:
 @item
 merge two sets of profiles with weights.
 
+@item
+read a stream of profiles with associated filenames and merge it with a set of
+profiles with weights.
+
 @item
 read one set of profile and rewrite profile contents. One can scale or
 normalize the count values.
@@ -64,6 +68,12 @@ Collect the profiles for different set of inputs, and use 
this tool to merge
 them. One can specify the weight to factor in the relative importance of
 each input.
 
+@item
+Collect profiles from target systems without a filesystem (freestanding
+environments).  Merge the collected profiles with associated profiles
+present on the host system.  One can specify the weight to factor in the
+relative importance of each input.
+
 @item
 Rewrite the profile after removing a subset of the gcda files, while 
maintaining
 the consistency of the summary and the histogram.
@@ -117,6 +127,10 @@ gcov-tool merge [merge-options] @var{directory1} 
@var{directory2}
  [@option{-v}|@option{--verbose}]
  [@option{-w}|@option{--weight} @var{w1,w2}]
 
+gcov-tool merge-stream [merge-stream-options] [@var{file}]
+ [@option{-v}|@option{--verbose}]
+ [@option{-w}|@option{--weight} @var{w1,w2}]
+
 gcov-tool rewrite [rewrite-options] @var{directory}
  [@option{-n}|@option{--normalize} @var{long_long_value}]
  [@option{-o}|@option{--output} @var{directory}]
@@ -169,6 +183,28 @@ Set the merge weights of the @var{directory1} and 
@var{directory2},
 respectively. The default weights are 1 for both.
 @end table
 
+@item merge-stream
+Collect profiles with associated filenames from a @emph{gcfn} and @emph{gcda}
+data stream.  Read the stream from the file specified by @var{file} or from
+@file{stdin}.  Merge the profiles with associated profiles in the host
+filesystem.  Apply the optional weights while merging profiles.
+
+For the generation of a @emph{gcfn} and @emph{gcda} data stream on the target
+system, please have a look at the @code{__gcov_filename_to_gcfn()} and
+@code{__gcov_info_to_gcda()} functions declared in @code{#include }.
+@table @gcctabopt
+
+@item -v
+@itemx --verbose
+Set the verbose mode.
+
+@item -w @var{w1},@var{w2}
+@itemx --weight @var{w1},@var{w2}
+Set the merge weights of the profiles from the @emph{gcfn} and @emph{gcda} data
+stream and the associated profiles in the host filesystem, respectively.  The
+default weights are 1 for both.
+@end table
+
 @item rewrite
 Read the specified profile directory and rewrite to a new directory.
 @table @gcctabopt
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index af5495e75c6..cef0fa9f084 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -15537,6 +15537,11 @@ main (void)
 @}
 @end smallexample
 
+The @command{merge-stream} subcommand of @command{gcov-tool} may be used to
+deserialize the data stream generated by the @code{__gcov_filename_to_gcfn} and
+@code{__gcov_info_to_gcda} functions and merge the profile information into
+@file{.gcda} files on the host filesystem.
+
 @item -fprofile-note=@var{path}
 @opindex fprofile-note
 
diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index d712715cf7e..ceb250143c8 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -42,6 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 
 extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
 struct gcov_info*, int, int);
+extern struct gcov_info *gcov_profile_merge_stream (const char *, int, int);
 extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -229,6 +230,78 @@ do_merge (int argc, char **argv)
   return profile_merge (argv[optind], argv[optind+1], output_dir, w1, w2);
 }
 
+/* Usage message f

[gcov v2 03/14] gcov: Add open mode parameter to gcov_do_dump()

2022-04-25 Thread Sebastian Huber
gcc/

* gcov-tool.cc (gcov_do_dump): Add mode parameter.
(gcov_output_files): Open files for reading and writing.

libgcc/

* libgcov-driver-system.c (gcov_exit_open_gcda_file): Add mode
parameter.  Pass mode to gcov_open() calls.
* libgcov-driver.c (dump_one_gcov):  Add mode parameter.  Pass mode to
gcov_exit_open_gcda_file() call.
(gcov_do_dump): Add mode parameter.  Pass mode to dump_one_gcov()
calls.
(__gcov_dump_one):  Open file for reading and writing.
---
 gcc/gcov-tool.cc   |  4 ++--
 libgcc/libgcov-driver-system.c |  7 ---
 libgcc/libgcov-driver.c| 12 ++--
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index 2e4083a664d..d712715cf7e 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -46,7 +46,7 @@ extern int gcov_profile_overlap (struct gcov_info*, struct 
gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
 extern struct gcov_info* gcov_read_profile_dir (const char*, int);
-extern void gcov_do_dump (struct gcov_info *, int);
+extern void gcov_do_dump (struct gcov_info *, int, int);
 extern const char *gcov_get_filename (struct gcov_info *list);
 extern void gcov_set_verbose (void);
 
@@ -124,7 +124,7 @@ gcov_output_files (const char *out, struct gcov_info 
*profile)
 fatal_error (input_location, "output file %s already exists in folder %s",
 filename, out);
 
-  gcov_do_dump (profile, 0);
+  gcov_do_dump (profile, 0, 0);
 
   ret = chdir (pwd);
   if (ret)
diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index 9abb2fe7f74..ac405c38e3a 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -261,7 +261,8 @@ allocate_filename_struct (struct gcov_filename *gf)
 
 static int
 gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
- struct gcov_filename *gf)
+ struct gcov_filename *gf,
+ int mode)
 {
   int append_slash = 0;
   const char *fname = gi_ptr->filename;
@@ -309,7 +310,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
 
   gf->filename = replace_filename_variables (gf->filename);
 
-  if (!gcov_open (gf->filename, 0))
+  if (!gcov_open (gf->filename, mode))
 {
   /* Open failed likely due to missed directory.
  Create directory and retry to open file. */
@@ -318,7 +319,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
   fprintf (stderr, "profiling:%s:Skip\n", gf->filename);
   return -1;
 }
-  if (!gcov_open (gf->filename, 0))
+  if (!gcov_open (gf->filename, mode))
 {
   fprintf (stderr, "profiling:%s:Cannot open\n", gf->filename);
   return -1;
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 7e52c5676e5..10831e84b61 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -595,14 +595,14 @@ write_one_data (const struct gcov_info *gi_ptr,
 static void
 dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
   unsigned run_counted ATTRIBUTE_UNUSED,
-  gcov_type run_max ATTRIBUTE_UNUSED)
+  gcov_type run_max ATTRIBUTE_UNUSED, int mode)
 {
   struct gcov_summary summary = {};
   int error;
   gcov_unsigned_t tag;
   fn_buffer = 0;
 
-  error = gcov_exit_open_gcda_file (gi_ptr, gf);
+  error = gcov_exit_open_gcda_file (gi_ptr, gf, mode);
   if (error == -1)
 return;
 
@@ -649,13 +649,13 @@ read_fatal:;
 
 /* Dump all the coverage counts for the program. It first computes program
summary and then traverses gcov_list list and dumps the gcov_info
-   objects one by one.  */
+   objects one by one.  Use MODE to open files.  */
 
 #if !IN_GCOV_TOOL
 static
 #endif
 void
-gcov_do_dump (struct gcov_info *list, int run_counted)
+gcov_do_dump (struct gcov_info *list, int run_counted, int mode)
 {
   struct gcov_info *gi_ptr;
   struct gcov_filename gf;
@@ -678,7 +678,7 @@ gcov_do_dump (struct gcov_info *list, int run_counted)
   /* Now merge each file.  */
   for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
 {
-  dump_one_gcov (gi_ptr, &gf, run_counted, run_max);
+  dump_one_gcov (gi_ptr, &gf, run_counted, run_max, mode);
   free (gf.filename);
 }
 
@@ -701,7 +701,7 @@ __gcov_dump_one (struct gcov_root *root)
   if (root->dumped)
 return;
 
-  gcov_do_dump (root->list, root->run_counted);
+  gcov_do_dump (root->list, root->run_counted, 0);
   
   root->dumped = 1;
   root->run_counted = 1;
-- 
2.34.1



[gcov v2 09/14] gcov: Move gcov_open() to caller of read_gcda_file()

2022-04-25 Thread Sebastian Huber
This allows to reuse read_gcda_file() to read multiple objects from a single
file.

libgcc/

* libgcov-util.c (read_gcda_file): Do not open file.
(ftw_read_file): Open file here.
---
 libgcc/libgcov-util.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 906ea645547..6093a74531d 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -268,17 +268,10 @@ read_gcda_file (const char *filename)
 k_ctrs_mask[i] = 0;
   k_ctrs_types = 0;
 
-  if (!gcov_open (filename, 1))
-{
-  fnotice (stderr, "%s:cannot open\n", filename);
-  return NULL;
-}
-
   /* Read magic.  */
   if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
 {
   fnotice (stderr, "%s:not a gcov data file\n", filename);
-  gcov_close ();
   return NULL;
 }
 
@@ -287,7 +280,6 @@ read_gcda_file (const char *filename)
   if (version != GCOV_VERSION)
 {
   fnotice (stderr, "%s:incorrect gcov version %d vs %d \n", filename, 
version, GCOV_VERSION);
-  gcov_close ();
   return NULL;
 }
 
@@ -379,7 +371,6 @@ read_gcda_file (const char *filename)
 }
 
   read_gcda_finalize (obj_info);
-  gcov_close ();
 
   return obj_info;
 }
@@ -412,7 +403,14 @@ ftw_read_file (const char *filename,
   if (verbose)
 fnotice (stderr, "reading file: %s\n", filename);
 
+  if (!gcov_open (filename, 1))
+{
+  fnotice (stderr, "%s:cannot open\n", filename);
+  return 0;
+}
+
   (void)read_gcda_file (xstrdup (filename));
+  gcov_close ();
 
   return 0;
 }
-- 
2.34.1



[gcov v2 11/14] gcov: Record EOF error during read

2022-04-25 Thread Sebastian Huber
Use an enum for file error codes.

gcc/

* gcov-io.cc (gcov_file_error): New enum.
(gcov_var): Use gcov_file_error enum for the error member.
(gcov_open): Use GCOV_FILE_NO_ERROR.
(gcov_close): Use GCOV_FILE_WRITE_ERROR.
(gcov_write): Likewise.
(gcov_write_unsigned): Likewise.
(gcov_write_string): Likewise.
(gcov_read_bytes): Set error code if EOF is reached.
(gcov_read_counter): Use GCOV_FILE_COUNTER_OVERFLOW.
---
 gcc/gcov-io.cc | 30 ++
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 7e1fb10b612..fdf745e6ce1 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -29,10 +29,20 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 
 static gcov_unsigned_t *gcov_read_words (void *buffer, unsigned);
 
+/* Indicates the last gcov file access error or that no error occurred
+   so far.  */
+enum gcov_file_error
+{
+  GCOV_FILE_COUNTER_OVERFLOW = -1,
+  GCOV_FILE_NO_ERROR = 0,
+  GCOV_FILE_WRITE_ERROR = 1,
+  GCOV_FILE_EOF = 2
+};
+
 struct gcov_var
 {
   FILE *file;
-  int error;   /* < 0 overflow, > 0 disk error.  */
+  enum gcov_file_error error;
   int mode;/* < 0 writing, > 0 reading.  */
   int endian;  /* Swap endianness.  */
 #ifdef IN_GCOV_TOOL
@@ -113,7 +123,7 @@ gcov_open (const char *name, int mode)
 #endif
 
   gcov_nonruntime_assert (!gcov_var.file);
-  gcov_var.error = 0;
+  gcov_var.error = GCOV_FILE_NO_ERROR;
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
   gcov_var.endian = 0;
 #endif
@@ -217,7 +227,7 @@ gcov_close (void)
   if (gcov_var.file)
 {
   if (fclose (gcov_var.file))
-   gcov_var.error = 1;
+   gcov_var.error = GCOV_FILE_WRITE_ERROR;
 
   gcov_var.file = 0;
 }
@@ -253,7 +263,7 @@ gcov_write (const void *data, unsigned length)
 {
   gcov_unsigned_t r = fwrite (data, length, 1, gcov_var.file);
   if (r != 1)
-gcov_var.error = 1;
+gcov_var.error = GCOV_FILE_WRITE_ERROR;
 }
 
 /* Write unsigned VALUE to coverage file.  */
@@ -263,7 +273,7 @@ gcov_write_unsigned (gcov_unsigned_t value)
 {
   gcov_unsigned_t r = fwrite (&value, sizeof (value), 1, gcov_var.file);
   if (r != 1)
-gcov_var.error = 1;
+gcov_var.error = GCOV_FILE_WRITE_ERROR;
 }
 
 #if !IN_LIBGCOV
@@ -283,7 +293,7 @@ gcov_write_string (const char *string)
 {
   gcov_unsigned_t r = fwrite (string, length, 1, gcov_var.file);
   if (r != 1)
-   gcov_var.error = 1;
+   gcov_var.error = GCOV_FILE_WRITE_ERROR;
 }
 }
 #endif
@@ -385,7 +395,11 @@ gcov_read_bytes (void *buffer, unsigned count)
 
   unsigned read = fread (buffer, count, 1, gcov_var.file);
   if (read != 1)
-return NULL;
+{
+  if (feof (gcov_var.file))
+   gcov_var.error = GCOV_FILE_EOF;
+  return NULL;
+}
 
 #ifdef IN_GCOV_TOOL
   gcov_var.pos += count;
@@ -434,7 +448,7 @@ gcov_read_counter (void)
   if (sizeof (value) > sizeof (gcov_unsigned_t))
 value |= ((gcov_type) from_file (buffer[1])) << 32;
   else if (buffer[1])
-gcov_var.error = -1;
+gcov_var.error = GCOV_FILE_COUNTER_OVERFLOW;
 
   return value;
 }
-- 
2.34.1



[gcov v2 14/14] gcov: Add section for freestanding environments

2022-04-25 Thread Sebastian Huber
gcc/

* doc/gcov.texi (Profiling and Test Coverage in Freestanding
Environments): New section.
---
 gcc/doc/gcov.texi | 375 ++
 1 file changed, 375 insertions(+)

diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi
index fc39da0f02d..751a11314f3 100644
--- a/gcc/doc/gcov.texi
+++ b/gcc/doc/gcov.texi
@@ -41,6 +41,8 @@ test code coverage in your programs.
 * Gcov and Optimization::   Using gcov with GCC optimization.
 * Gcov Data Files:: The files used by gcov.
 * Cross-profiling:: Data file relocation.
+* Freestanding Environments::   How to use profiling and test
+coverage in freestanding environments.
 @end menu
 
 @node Gcov Intro
@@ -971,3 +973,376 @@ setting will name the data file 
@file{/target/run/build/foo.gcda}.
 You must move the data files to the expected directory tree in order to
 use them for profile directed optimizations (@option{-fprofile-use}), or to
 use the @command{gcov} tool.
+
+@node Freestanding Environments
+@section Profiling and Test Coverage in Freestanding Environments
+
+In case your application runs in a hosted environment such as GNU/Linux, then
+this section is likely not relevant to you.  This section is intended for
+application developers targeting freestanding environments (for example
+embedded systems) with limited resources.  In particular, systems or test cases
+which do not support constructors/destructors or the C library file I/O.  In
+this section, the @dfn{target system} runs your application instrumented for
+profiling or test coverage.  You develop and analyze your application on the
+@dfn{host system}.  We give now an overview how profiling and test coverage can
+be obtained in this scenario followed by a tutorial which can be exercised on
+the host system.  Finally, some system initialization caveats are listed.
+
+@subsection Overview
+
+For an application instrumented for profiling or test coverage, the compiler
+generates some global data structures which are updated by instrumentation code
+while the application runs.  These data structures are called the @dfn{gcov
+information}.  Normally, when the application exits, the gcov information is
+stored to @file{.gcda} files.  There is one file per translation unit
+instrumented for profiling or test coverage.  The function
+@code{__gcov_exit()}, which stores the gcov information to a file, is called by
+a global destructor function for each translation unit instrumented for
+profiling or test coverage.  It runs at process exit.  In a global constructor
+function, the @code{__gcov_init()} function is called to register the gcov
+information of a translation unit in a global list.  In some situations, this
+procedure does not work.  Firstly, if you want to profile the global
+constructor or exit processing of an operating system, the compiler generated
+functions may conflict with the test objectives.  Secondly, you may want to
+test early parts of the system initialization or abnormal program behaviour
+which do not allow a global constructor or exit processing.  Thirdly, you need
+a filesystem to store the files.
+
+The @option{-fprofile-info-section} GCC option enables you to use profiling and
+test coverage in freestanding environments.  This option disables the use of
+global constructors and destructors for the gcov information.  Instead, a
+pointer to the gcov information is stored in a special linker input section for
+each translation unit which is compiled with this option.  By default, the
+section name is @code{.gcov_info}.  The gcov information is statically
+initialized.  The pointers to the gcov information from all translation units
+of an executable can be collected by the linker in a continuous memory block.
+For the GNU linker, the below linker script output section definition can be
+used to achieve this:
+
+@smallexample
+  .gcov_info  :
+  @{
+PROVIDE (__gcov_info_start = .);
+KEEP (*(.gcov_info))
+PROVIDE (__gcov_info_end = .);
+  @}
+@end smallexample
+
+The linker will provide two global symbols, @code{__gcov_info_start} and
+@code{__gcov_info_end}, which define the start and end of the array of pointers
+to gcov information blocks, respectively.  The @code{KEEP ()} directive is
+required to prevent a garbage collection of the pointers.  They are not
+directly referenced by anything in the executable.  The section may be placed
+in a read-only memory area.
+
+In order to transfer the profiling and test coverage data from the target to
+the host system, the application has to provide a function to produce a
+reliable in order byte stream from the target to the host.  The byte stream may
+be compressed and encoded using error detection and correction codes to meet
+application-specific requirements.  The GCC provided @file{libgcov} target
+library provides two functions, @code{__gcov_info_to_gcda()} and
+@code{__gcov_filename_to_gcfn()}, to generate a b

[gcov v2 10/14] gcov: Fix integer types in ftw_read_file()

2022-04-25 Thread Sebastian Huber
libgcc/

* libgcov-util.c (ftw_read_file): Use size_t for strlen() variables.
---
 libgcc/libgcov-util.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 6093a74531d..bf96f508db0 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -384,8 +384,8 @@ ftw_read_file (const char *filename,
const struct stat *status ATTRIBUTE_UNUSED,
int type)
 {
-  int filename_len;
-  int suffix_len;
+  size_t filename_len;
+  size_t suffix_len;
 
   /* Only read regular files.  */
   if (type != FTW_F)
-- 
2.34.1



[gcov v2 08/14] gcov: Move prepend to list to read_gcda_file()

2022-04-25 Thread Sebastian Huber
This helps to reuse read_gcda_file().

libgcc/

* libgcov-util.c (read_gcda_file): Prepend new info object to global
list.
(ftw_read_file): Remove list append here.
---
 libgcc/libgcov-util.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index ae5712c0138..906ea645547 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -301,6 +301,9 @@ read_gcda_file (const char *filename)
   num_fn_info = 0;
   curr_fn_info = 0;
 
+  /* Prepend to global gcov info list.  */
+  obj_info->next = gcov_info_head;
+  gcov_info_head = obj_info;
 
   /* Read stamp.  */
   obj_info->stamp = gcov_read_unsigned ();
@@ -392,7 +395,6 @@ ftw_read_file (const char *filename,
 {
   int filename_len;
   int suffix_len;
-  struct gcov_info *obj_info;
 
   /* Only read regular files.  */
   if (type != FTW_F)
@@ -410,12 +412,7 @@ ftw_read_file (const char *filename,
   if (verbose)
 fnotice (stderr, "reading file: %s\n", filename);
 
-  obj_info = read_gcda_file (xstrdup (filename));
-  if (!obj_info)
-return 0;
-
-  obj_info->next = gcov_info_head;
-  gcov_info_head = obj_info;
+  (void)read_gcda_file (xstrdup (filename));
 
   return 0;
 }
-- 
2.34.1



[gcov v2 07/14] gcov: Use xstrdup()

2022-04-25 Thread Sebastian Huber
Move duplication of filename to caller and use xstrdup() instead of custom
code.  This helps to reuse read_gcda_file() for other purposes.

libgcc/

* libgcov-util.c (read_gcda_file): Do not duplicate filename.
(ftw_read_file): Duplicate filename for read_gcda_file().
---
 libgcc/libgcov-util.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index db157220c9d..ae5712c0138 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -296,16 +296,11 @@ read_gcda_file (const char *filename)
  sizeof (struct gcov_ctr_info) * GCOV_COUNTERS, 1);
 
   obj_info->version = version;
+  obj_info->filename = filename;
   obstack_init (&fn_info);
   num_fn_info = 0;
   curr_fn_info = 0;
-  {
-size_t len = strlen (filename) + 1;
-char *str_dup = (char*) xmalloc (len);
 
-memcpy (str_dup, filename, len);
-obj_info->filename = str_dup;
-  }
 
   /* Read stamp.  */
   obj_info->stamp = gcov_read_unsigned ();
@@ -415,7 +410,7 @@ ftw_read_file (const char *filename,
   if (verbose)
 fnotice (stderr, "reading file: %s\n", filename);
 
-  obj_info = read_gcda_file (filename);
+  obj_info = read_gcda_file (xstrdup (filename));
   if (!obj_info)
 return 0;
 
-- 
2.34.1



[gcov v2 06/14] gcov-tool: Support file input from stdin

2022-04-25 Thread Sebastian Huber
gcc/

* gcov-io.cc (GCOV_MODE_STDIN): Define.
(gcov_position): For gcov-tool, return calculated position if file is
stdin.
(gcov_open):  For gcov-tool, use stdin if filename is NULL.
(gcov_close): For gcov-tool, do not close stdin.
(gcov_read_bytes): For gcov-tool, update position if file is stdin.
(gcov_sync): For gcov-tool, discard input if file is stdin.
---
 gcc/gcov-io.cc | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index fee3130f94a..7e1fb10b612 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -35,8 +35,13 @@ struct gcov_var
   int error;   /* < 0 overflow, > 0 disk error.  */
   int mode;/* < 0 writing, > 0 reading.  */
   int endian;  /* Swap endianness.  */
+#ifdef IN_GCOV_TOOL
+  gcov_position_t pos; /* File position for stdin support.  */
+#endif
 } gcov_var;
 
+#define GCOV_MODE_STDIN 2
+
 /* Save the current position in the gcov file.  */
 /* We need to expose this function when compiling for gcov-tool.  */
 #ifndef IN_GCOV_TOOL
@@ -45,6 +50,10 @@ static inline
 gcov_position_t
 gcov_position (void)
 {
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.mode == GCOV_MODE_STDIN)
+return gcov_var.pos;
+#endif
   return ftell (gcov_var.file);
 }
 
@@ -108,6 +117,16 @@ gcov_open (const char *name, int mode)
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
   gcov_var.endian = 0;
 #endif
+#ifdef IN_GCOV_TOOL
+  gcov_var.pos = 0;
+  if (!name)
+{
+  gcov_nonruntime_assert (gcov_var.mode > 0);
+  gcov_var.file = stdin;
+  gcov_var.mode = GCOV_MODE_STDIN;
+  return 1;
+}
+#endif
 #if GCOV_LOCKED
   if (mode > 0)
 {
@@ -190,6 +209,11 @@ gcov_open (const char *name, int mode)
 GCOV_LINKAGE int
 gcov_close (void)
 {
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.file == stdin)
+gcov_var.file = 0;
+  else
+#endif
   if (gcov_var.file)
 {
   if (fclose (gcov_var.file))
@@ -363,6 +387,9 @@ gcov_read_bytes (void *buffer, unsigned count)
   if (read != 1)
 return NULL;
 
+#ifdef IN_GCOV_TOOL
+  gcov_var.pos += count;
+#endif
   return buffer;
 }
 
@@ -499,6 +526,17 @@ gcov_sync (gcov_position_t base, gcov_unsigned_t length)
 {
   gcov_nonruntime_assert (gcov_var.mode > 0);
   base += length;
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.mode == GCOV_MODE_STDIN)
+{
+  while (gcov_var.pos < base)
+   {
+ ++gcov_var.pos;
+ (void)fgetc (gcov_var.file);
+   }
+  return;
+}
+#endif
   fseek (gcov_var.file, base, SEEK_SET);
 }
 #endif
-- 
2.34.1



[gcov v2 13/14] gcov: Use xstrerror()

2022-04-25 Thread Sebastian Huber
libgcc/

* libgcov-util.c (ftw_read_file): Improve notice using xstrerror().
(gcov_profile_merge_stream): Likewise.
---
 libgcc/libgcov-util.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 2508e21..ba4670b3c0d 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -405,7 +405,7 @@ ftw_read_file (const char *filename,
 
   if (!gcov_open (filename, 1))
 {
-  fnotice (stderr, "%s:cannot open\n", filename);
+  fnotice (stderr, "%s:cannot open:%s\n", filename, xstrerror (errno));
   return 0;
 }
 
@@ -819,7 +819,7 @@ gcov_profile_merge_stream (const char *filename, int w1, 
int w2)
 
   if (!gcov_open (filename, 1))
 {
-  fnotice (stderr, "%s:cannot open\n", filename);
+  fnotice (stderr, "%s:cannot open:%s\n", filename, xstrerror (errno));
   return NULL;
 }
 
-- 
2.34.1



[gcov v2 05/14] gcov: Add __gcov_filename_to_gcfn()

2022-04-25 Thread Sebastian Huber
gcc/

* doc/invoke.texi (fprofile-info-section): Mention
__gcov_filename_to_gcfn().  Use "freestanding" to match with C11
standard language.  Fix minor example code issues.
* gcov-io.h (GCOV_FILENAME_MAGIC): Define and document.

gcc/testsuite/

* gcc.dg/gcov-info-to-gcda.c: Test __gcov_filename_to_gcfn().

libgcc/

* gcov.h (__gcov_info_to_gcda): Mention __gcov_filename_to_gcfn().
(__gcov_filename_to_gcfn): Declare and document.
* libgcov-driver.c (dump_string): New.
(__gcov_filename_to_gcfn): Likewise.
(__gcov_info_to_gcda): Adjust comment to match C11 standard language.
---
 gcc/doc/invoke.texi  | 26 -
 gcc/gcov-io.h| 24 ++--
 gcc/testsuite/gcc.dg/gcov-info-to-gcda.c | 36 +++-
 libgcc/gcov.h| 17 ++-
 libgcc/libgcov-driver.c  | 32 -
 5 files changed, 105 insertions(+), 30 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 07b440190c3..af5495e75c6 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -15462,7 +15462,7 @@ profile information generated by 
@option{-fprofile-arcs} is placed in the
 specified section for each translation unit.  This option disables the profile
 information registration through a constructor and it disables the profile
 information processing through a destructor.  This option is not intended to be
-used in hosted environments such as GNU/Linux.  It targets free-standing
+used in hosted environments such as GNU/Linux.  It targets freestanding
 environments (for example embedded systems) with limited resources which do not
 support constructors/destructors or the C library file I/O.
 
@@ -15487,14 +15487,8 @@ for example like this:
 #include 
 #include 
 
-extern const struct gcov_info *__gcov_info_start[];
-extern const struct gcov_info *__gcov_info_end[];
-
-static void
-filename (const char *f, void *arg)
-@{
-  puts (f);
-@}
+extern const struct gcov_info *const __gcov_info_start[];
+extern const struct gcov_info *const __gcov_info_end[];
 
 static void
 dump (const void *d, unsigned n, void *arg)
@@ -15505,6 +15499,12 @@ dump (const void *d, unsigned n, void *arg)
 printf ("%02x", c[i]);
 @}
 
+static void
+filename (const char *f, void *arg)
+@{
+  __gcov_filename_to_gcfn (f, dump, arg );
+@}
+
 static void *
 allocate (unsigned length, void *arg)
 @{
@@ -15514,8 +15514,8 @@ allocate (unsigned length, void *arg)
 static void
 dump_gcov_info (void)
 @{
-  const struct gcov_info **info = __gcov_info_start;
-  const struct gcov_info **end = __gcov_info_end;
+  const struct gcov_info *const *info = __gcov_info_start;
+  const struct gcov_info *const *end = __gcov_info_end;
 
   /* Obfuscate variable to prevent compiler optimizations.  */
   __asm__ ("" : "+r" (info));
@@ -15530,9 +15530,9 @@ dump_gcov_info (void)
 @}
 
 int
-main()
+main (void)
 @{
-  dump_gcov_info();
+  dump_gcov_info ();
   return 0;
 @}
 @end smallexample
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 204ae0ccf7f..30947634d73 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -60,14 +60,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 
file : int32:magic int32:version int32:stamp record*
 
-   The magic ident is different for the notes and the data files.  The
-   magic ident is used to determine the endianness of the file, when
-   reading.  The version is the same for both files and is derived
-   from gcc's version number. The stamp value is used to synchronize
-   note and data files and to synchronize merging within a data
-   file. It need not be an absolute time stamp, merely a ticker that
-   increments fast enough and cycles slow enough to distinguish
-   different compile/run/compile cycles.
+   A filename header may be used to provide a filename for the data in
+   a stream of data to support gcov in freestanding environments.  This
+   header is used by the merge-stream subcommand of the gcov-tool.  The
+   format of the filename header is
+
+   filename-header : int32:magic int32:version string
+
+   The magic ident is different for the notes and the data files as
+   well as the filename header.  The magic ident is used to determine
+   the endianness of the file, when reading.  The version is the same
+   for both files and is derived from gcc's version number. The stamp
+   value is used to synchronize note and data files and to synchronize
+   merging within a data file. It need not be an absolute time stamp,
+   merely a ticker that increments fast enough and cycles slow enough
+   to distinguish different compile/run/compile cycles.
 
Although the ident and version are formally 32 bit numbers, they
are derived from 4 character ASCII strings.  The version number
@@ -228,6 +235,7 @@ typedef uint64_t gcov_type_unsigned;
 /* File magic. Must not be palindromes.  

  1   2   3   4   5   >