public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v12 0/11 Add support for CRC64 generation in linker
@ 2023-03-06 13:31 binutils
  2023-03-06 13:31 ` [PATCH v12 01/11] DIGEST: LICENSING binutils
                   ` (11 more replies)
  0 siblings, 12 replies; 22+ messages in thread
From: binutils @ 2023-03-06 13:31 UTC (permalink / raw)
  To: binutils; +Cc: nickc

Patchset XII
testsuite fixed to skip some tests.

Too limited flash space
* tic4x-coff, tic54x-cof
No support for the ".section" directive
(Neither are flash based micros and unlikely to use the feature)
* ns32k-pc532-macho
* pdp11-dec-aout
* powerpc-ibm-aix5.2.0
* rs6000-aix4.3.3
* alpha-linuxecoff

Patchset XI
During final generation of CRC, the output sections will be searched
for the section that contains the address of the digest
and this will be the selected section.

The 'DIGEST SECTION "name"' command is removed.

Added multiple test for error conditions when testing DIGEST

Patchset 10
Forget patchset IX.
Managed to push the master branch.
This is the real thing.

Patchset IX
Endian:
Default small endian.
Override with switches: -BE, -LE
Override in label using [#BE] and [#LE]

  DIGEST "<label>[#BE|#LE]" "CRC32"              (start, end)
  DIGEST "<label>[#BE|#LE]" "CRC64-ECMA"         (start, end)
  DIGEST "<label>[#BE|#LE]" "CRC64-GO-ISO"       (start, end)
  DIGEST "<label>[#BE|#LE]" "CRC64-GO-ISO-R"     (start, end)
  DIGEST "<label>[#BE|#LE]" "CRC64-WE"           (start, end)
  DIGEST "<label>[#BE|#LE]" "CRC64-XZ"           (start, end)
  DIGEST "<label>[#BE|#LE]"  POLY (<params>)     (start, end)
  DIGEST TABLE "<label>[#BE|#LE]"
  DIGEST SECTION "<section>"

Improve error messages. Some warnings are now errors.
Handle reported errors.
Keep DIGEST SECTION "name", but the whole feature should be deleted.

Patchset VIII
Memory in testsuite reduced to 16kB ROM and 4 kB RAM
All situated in the first 64 KB.

Patchset VII

Rebased against master
Fixed whitespace errors
Run indent on CRC files
Moved license to ld directory and renamed to COPYING.<website>
Added comments to COPYING.www.sunshine2k.de explaining what it is.

Patchset six
Commands changes so you always get little endian
but can override this in the linker command file.

  DIGEST "<label>[.BE]" "CRC32"              (start, end)
  DIGEST "<label>[.BE]" "CRC64-ECMA"         (start, end)
  DIGEST "<label>[.BE]" "CRC64-GO-ISO"       (start, end)
  DIGEST "<label>[.BE]" "CRC64-GO-ISO-R"     (start, end)
  DIGEST "<label>[.BE]" "CRC64-WE"           (start, end)
  DIGEST "<label>[.BE]" "CRC64-XZ"           (start, end)
  DIGEST "<label>[.BE]"  POLY (<params>)     (start, end)
  DIGEST TABLE "<label>[.BE]"
  DIGEST SECTION "<section>"

Each command has a label, which gets defined (not include ".BE")

It has been built natively as well as with the following setup
to configure.

  --target=x86_64-pc-linux-gnu
  --target=x86_64-w64-mingw32
  --target=aarch64-linux-gnu
  --target=powerpc64-linux-gnu
  --target=mips-elf
  --enable-targets=all --enable-64-bit-bfd 

A testsuite for all predefined algorithms are added.
The testsuite calculates the CRC for the "123456789"
string which is common.
The expected checksum value is provided.
The check ensures that a table is generated, but does not
check the binary contents of the table.
It is indirectly checked by using the same table for the
algorithm

The "DIGEST POLY" commands are checked by using
the the "CRC32" and "CRC64-ECMA" polynomes and parameters.

There is an online calculator at
http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

There are no testsuites for the DEBUG ON|OFF, TIMESTAMP and
"DIGEST SECTION" commands yet.

The testsuite will fail if "DEBUG ON" is executed due to
verbose output.

The TIMESTAMP output varies with time and is difficult to test.

The DIGEST SECTION command is not tested, because this
need a little extra discussion.
I have not seen any other suitable sections being generated.

Since the information at http://www.sunshine2k.de/ has
been very useful, their license (MIT) is added.

Code examples for the CRC check routines that needs to be in the
user source is added to the documentation with copyright statements.
Should they be there, or is it enough to have the license
in the source code?

The Makefile.in is manually generated since I had a HDD crash
and upgraded to a new disk and installed Ubuntu 22.04.
The autotools are upgraded to 2.71. The build system
did not like this, so I installed 2.69.
This changes a lot more than the autotools-2.69 in Ubuntu 18.04
so I resorted to manual edit of Makefile.in.

Maybe someone should run autotools and generate this automatically
instead of applying the the manual edit.

Added instructions to build ldint.pdf which is not buildable today.

The system has only been tested on a PC == little endian.
I do not have a big endian host, but maybe someone could
test it on such a host.

The way endianess is implemented, it is easy for the user
to supply a workaround by specifying another endianess.



Fifth patchset.

+* The linker script has a new command to insert a timestamp
+  TIMESTAMP
+  inserts the current time (seconds since Epoch) as a 64-bit value
+
+* The linker script syntax has new commands for debugging a linker script
+  DEBUG ON  turns on debugging
+  DEBUG OFF turns off debugging
+
+* The linker script syntax has new commands for handling CRC-32/64 calculations
+  on the '.text' section
+  It uses code from https://www.libcrc.org/
+
+  DIGEST "CRC32"              (start, end)
+  DIGEST "CRC64-ECMA"         (start, end)
+  DIGEST "CRC64-ISO"          (start, end)
+  DIGEST "CRC64-WE"           (start, end)
+  DIGEST POLY (size, polynome)(start, end)
+  DIGEST POLYI(size, polynome)(start, end) (inversion during CRC calculation)
+  DIGEST TABLE
+  DIGEST SECTION "<section>

ran indent on the new files.

The *.d files in the testsuite was edited to 
reduce size and to remove all '(' characters.
The new linker can link using the testsuite/ld-script/*.t
linker files, but they do not pass the 'make check-ld'
test.

Fourth patchset.
Get rid of binaries in testsuite.

Here is the third patchset for introducing CRC64 generation.
This has focused on supporting maintainability of the feature.
In order to do so, CRC32 generation has been introduced to
detect issues when extending the linker with another algoritm
for checking integrity of the image.
This will simplify adding other algorithms like SHA algoritms
in the future.

In addition, the TIMESTAMP command is used to store the current time
in seconds since Epoch is stored in the image.

The main routine for calculating CRCs has been broken down
in subroutines which allow other algorithms.

An algorithm typically needs
<type> *init_<algo>_tab( <type> poly )
<type> calc_<algo>_inv( const unsigned char *input_str, size_t num_bytes );
<type> calc_<algo>    ( const unsigned char *input_str, size_t num_bytes );
void lang_add_<algo>_syndrome(bool invert, bfd_vma poly)
void lang_add_<algo>_table(void)

The common functions are:
* bool get_text_section_contents(void)
  This reads the '.text' section and its contents
  Pointers are stored in the global variables
  asection *text_section
  char     *text_contents
* bool set_crc_checksum(bfd_vma crc, bfd_vma addr, bfd_vma size)
  Stores the CRC at the index addr. The size of the CRC in bytes is specified.
  Storing something larger that 64-bit is not supported here.
* bool symbol_lookup(char *name, bfd_vma *val)
  Gets the value of a symbol into 'val'. Returns false if not found.

To add CRC32 support means adding the following commands
* CRC32 CRC32                    '(' crc_start ',' crc_end ')'
* CRC32 POLY  '[' mustbe_exp ']' '(' crc_start ',' crc_end ')'
* CRC32 POLYI '[' mustbe_exp ']' '(' crc_start ',' crc_end ')'

================
Here is the second patchset for introducing CRC64 generation in the linker
This is mainly looking at indentation and whitespace errors.
The patches applies cleanly without whitespace error
except for the last patch which contains the testsuite.
When the contents of .text is printed out, sometimes
the last byte of a line in the CRC table is a space.
This is reported as a whitespace error.

Supports the following new linker commands:
* CRC64 ECMA                     '(' crc_start ',' crc_end ')'
* CRC64 ISO                      '(' crc_start ',' crc_end ')'
* CRC64 POLY  '[' mustbe_exp ']' '(' crc_start ',' crc_end ')'
* CRC64 POLYI '[' mustbe_exp ']' '(' crc_start ',' crc_end ')'
* CRC64 TABLE

ECMA  == 0x42F0E1EBA9EA3693
ISO   == 0xD800000000000000
POLY  == Allows your own polynome
POLYI == Allows your own polynome, with inversion during calc

The CRC is calculated from crc_start to crc_end (not included)

The "CRC64 <polynome> command
* Allows specifying the polynom (ECMA(default), ISO or your own)
* Allows for inversion in the CRC calculation (CRC64-WE)
* Allows specifying the area that should be checked.
* reserves room for the CRC (8 bytes)
* Declares a symbol ___CRC64___ for the address of the CRC.
* Declares a symbol ___CRC64_START___ for the first address of the checked area
* Declares a symbol ___CRC64_END___ for the first address after the checked area

The symbols names are declared in "checksum.h".
If the names are unsuitable, it is easy to change.

The CRC TABLE command
  This is used to speed up the CRC calculation.
* Creates a 2kB table which speeds up the CRC calculation
* Can insert the 2kB table into the .text section at current location.
* Declares a symbol ___CRC64_TABLE___ if the table is inserted.

Comments on the code:

The process of calculation involves:
* Check if CRC is requested
* Validation of CRC prerequisites
* get .text section
* get .text section contents
* calculate CRC over the area
* insert the CRC in the correct location
====================================

This version also supports the
* DEBUG ON
* DEBUG OFF
turning on/off yydebug
I find it useful for debugging the build, but it can easly be removed.

This patch contains a lot of debug output, that is enabled by
#define DEBUG_CRC 1
This should be removed in the final version.

The ld.texi stuff needs some more work. Not very experienced with that.

Added an entry in NEWS

Added 4 test cases for the different CRC64 polynome commands.
All testcases generate a CRC table.

The code is using the libcrc released under an MIT license found in
* https://www.libcrc.org/
* https://github.com/lammertb/libcrc/tree/v2.0
Author:  Lammert Bies
A license for libcrc is added to the patch.

[PATCH v12 01/11] DIGEST: LICENSING
[PATCH v12 02/11] DIGEST: NEWS
[PATCH v12 03/11] DIGEST: Documentation
[PATCH v12 04/11] DIGEST: testsuite
[PATCH v12 05/11] DIGEST: ldlex.l
[PATCH v12 06/11] DIGEST: ldgram.y
[PATCH v12 07/11] DIGEST: ldmain.c
[PATCH v12 08/11] DIGEST: ldlang.*: add timestamp
[PATCH v12 09/11] DIGEST: calculation
[PATCH v12 10/11] DIGEST: Makefile.*
[PATCH v12 11/11] Build ldint


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v12 01/11] DIGEST: LICENSING
  2023-03-06 13:31 [PATCH v12 0/11 Add support for CRC64 generation in linker binutils
@ 2023-03-06 13:31 ` binutils
  2023-03-06 13:31 ` [PATCH v12 02/11] DIGEST: NEWS binutils
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: binutils @ 2023-03-06 13:31 UTC (permalink / raw)
  To: binutils; +Cc: nickc, Ulf Samuelsson

From: Ulf Samuelsson <ulf@emagii.com>

Signed-off-by: Ulf Samuelsson <ulf@emagii.com>
---
 ld/COPYING.www.libcrc.org    | 45 ++++++++++++++++++++++++++++++++++++
 ld/COPYING.www.sunshine2k.de | 25 ++++++++++++++++++++
 2 files changed, 70 insertions(+)
 create mode 100755 ld/COPYING.www.libcrc.org
 create mode 100644 ld/COPYING.www.sunshine2k.de

diff --git a/ld/COPYING.www.libcrc.org b/ld/COPYING.www.libcrc.org
new file mode 100755
index 00000000000..e8b7226ab89
--- /dev/null
+++ b/ld/COPYING.www.libcrc.org
@@ -0,0 +1,45 @@
+The GNU linker contains CRC routines that are used to implement the
+DIGEST CRC32/64 commands in the output section.
+
+The CRC routines are extracted from LIBCRC available at
+* https://www.libcrc.org/
+* https://github.com/lammertb/libcrc/tree/v2.0
+
+The license file from libcrc is below.
+================================================================================
+/*
+ * Library: libcrc
+ * File:    src/crc64.c
+ * Author:  Lammert Bies
+ *
+ * This file is licensed under the MIT License as stated below
+ *
+ * Copyright (c) 2016 Lammert Bies
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Description
+ * -----------
+ * The source file src/crc64.c contains the routines which are needed to
+ * calculate a 64 bit CRC value of a sequence of bytes.
+ */
+================================================================================
+NOTE: The user could/(should) extract the CRC calculation routines
+      and add to their program.
+      The linker can add the table, but not the calculation routines.
diff --git a/ld/COPYING.www.sunshine2k.de b/ld/COPYING.www.sunshine2k.de
new file mode 100644
index 00000000000..636496fe047
--- /dev/null
+++ b/ld/COPYING.www.sunshine2k.de
@@ -0,0 +1,25 @@
+The ld.bfd linker contains code from the http://www.sunshine2k.de/ website
+This code is released under the license below
+================================================================================
+All content of this website is released under the MIT license as follows:
+
+Copyright (c) 2021 Bastian Molkenthin
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+================================================================================
-- 
2.34.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v12 02/11] DIGEST: NEWS
  2023-03-06 13:31 [PATCH v12 0/11 Add support for CRC64 generation in linker binutils
  2023-03-06 13:31 ` [PATCH v12 01/11] DIGEST: LICENSING binutils
@ 2023-03-06 13:31 ` binutils
  2023-03-06 13:31 ` [PATCH v12 03/11] DIGEST: Documentation binutils
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: binutils @ 2023-03-06 13:31 UTC (permalink / raw)
  To: binutils; +Cc: nickc, Ulf Samuelsson

From: Ulf Samuelsson <ulf@emagii.com>

Signed-off-by: Ulf Samuelsson <ulf@emagii.com>
---
 ld/NEWS | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 73 insertions(+), 4 deletions(-)

diff --git a/ld/NEWS b/ld/NEWS
index 4b91f2c3b0a..b79023ecb95 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,74 @@
 -*- text -*-
 
+* The linker script has a new command to insert a timestamp
+  TIMESTAMP
+  inserts the current time (seconds since Epoch) as a 64-bit value
+
+* The linker script syntax has new commands for debugging a linker script
+  DEBUG ON  turns on debugging
+  DEBUG OFF turns off debugging
+
+* The linker script syntax has new commands for handling CRC-32/64 calculations
+  on the '.text' section
+  It uses code from https://www.libcrc.org/
+
+  DIGEST "<label>[#<endian>]" "CRC32"              (start, end)
+  DIGEST "<label>[#<endian>]" "CRC64-ECMA"         (start, end)
+  DIGEST "<label>[#<endian>]" "CRC64-GO-ISO"       (start, end)
+  DIGEST "<label>[#<endian>]" "CRC64-GO-ISO-R"     (start, end)
+  DIGEST "<label>[#<endian>]" "CRC64-WE"           (start, end)
+  DIGEST "<label>[#<endian>]" "CRC64-XZ"           (start, end)
+  DIGEST "<label>[#<endian>]"  POLY (<params>)     (start, end)
+  DIGEST TABLE "<label>[#<endian>]"
+
+  The CRC32, CRC64-ECMA, CRC64-ISO, CRC64-WE and POLY defines
+  the polynome to use and reserves space for the 32/64-bit CRC in the
+  current section (default ".text"). It also defines a label "<label>".
+  The endian can be specified through "#BE" or "#LE" modifiers for
+  big endian or little endian. This overrides the "-BE" or "-LE" switches on the
+  command line. If no specification is used, little endian
+  digest and table will be emitted.
+  The generated label does not include the modifier.
+
+  When generating a custom polynome you have to supply parameters
+  in the  following order
+  * size            {32 | 64 }
+  * polynome
+  * initial         initial value of crc
+  * xor value       xor with this before returning result
+  * input reflect   bitreverse input data
+  * output reflect  bitreverse result
+  * reciprocal      bitreverse polynome
+
+  These terms are explained at
+  http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html
+
+  The 32 bit DIGEST <polynome> command defines some global symbols.
+  ___CRC32___ is the address of the CRC64 checksum
+  ___CRC32_START___ is the address where CRC calculation starts
+  ___CRC32_END___ The CRC calculation ends before this address.
+
+  The 64-bit DIGEST <polynome> command defines some global symbols.
+  ___CRC64___ is the address of the CRC64 checksum
+  ___CRC64_START___ is the address where CRC calculation starts
+  ___CRC64_END___ The CRC calculation ends before this address.
+
+  All three symbols must refer to addresses in the selected section.
+  If they are defined at the end of the linking process, then
+  the CRC## will be calculated between
+
+    ___CRC##_START___ .. ___CRC##_END___ -1
+
+  and the result will be inserted at ___CRC##___.
+
+  ___CRC##___ must be outside the region where CRC is calculated
+
+  The DIGEST TABLE command generates a table for CRC generation.
+  A table is not neccessary, but will speed up the calculation.
+  It defines the ___CRC##_TABLE___ symbol at the start of the table.
+  The user may choose to add this table to his code instead of using
+  the linker.
+
 * The linker script syntax has two new commands for inserting text into output
   sections:
     ASCII (<size>) "string"
@@ -41,16 +110,16 @@ Changes in 2.39:
   re-enabled via the --warn-rwx-segments option.
 
   New configure options can also control these new features:
-  
+
   --enable-warn-execstack=no
      will disable the warnings about creating an executable stack.
-     
+
   --enable-warn-execstack=yes
      will make --warn-execstack enabled by default.
-     
+
   --enable-warn-rwx-segments=no
      will make --no-warn-rwx-segments enabled by default.
-     
+
   --enable-default-execstack=no
      will stop the creation of an executable stack simply because an input file
      is missing a .note.GNU-stack section, even on architectures where this
-- 
2.34.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v12 03/11] DIGEST: Documentation
  2023-03-06 13:31 [PATCH v12 0/11 Add support for CRC64 generation in linker binutils
  2023-03-06 13:31 ` [PATCH v12 01/11] DIGEST: LICENSING binutils
  2023-03-06 13:31 ` [PATCH v12 02/11] DIGEST: NEWS binutils
@ 2023-03-06 13:31 ` binutils
  2023-03-06 13:31 ` [PATCH v12 04/11] DIGEST: testsuite binutils
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: binutils @ 2023-03-06 13:31 UTC (permalink / raw)
  To: binutils; +Cc: nickc, Ulf Samuelsson

From: Ulf Samuelsson <ulf@emagii.com>

Signed-off-by: Ulf Samuelsson <ulf@emagii.com>
---
 ld/ld.texi | 498 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 494 insertions(+), 4 deletions(-)

diff --git a/ld/ld.texi b/ld/ld.texi
index 3367075cae8..c21d849fe24 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -5302,7 +5302,7 @@ __stop_SECNAME, where SECNAME is the name of the section.  These
 indicate the start address and end address of the output section
 respectively.  Note: most section names are not representable as
 C identifiers because they contain a @samp{.} character.
-
+@page
 @node Output Section Data
 @subsection Output Section Data
 @cindex data
@@ -5353,10 +5353,28 @@ whereas this will work:
 @smallexample
 SECTIONS @{@ .text : @{@ *(.text) ; LONG(1) @}@ .data : @{@ *(.data) @}@ @}@
 @end smallexample
-
+@page
 @cindex output section strings
 @kindex ASCII (@var{expression}) ``@var{string}''
 @kindex ASCIZ ``@var{string}''
+@code{ASCII strings}
+@sp 1
+@multitable @columnfractions .25 .20 .30 .20 .05
+@item
+ASCIZ
+@tab
+@tab
+"<string"
+@tab
+@item
+ASCII
+@tab
+(<size>)
+@tab
+"<string"
+@tab
+@end multitable
+@sp 1
 You can include a zero-terminated string in an output section by using
 @code{ASCIZ}.  The keyword is followed by a string which is stored at
 the current value of the location counter including adding a zero byte
@@ -5381,18 +5399,490 @@ it must be enclosed in double quotes.
 The string can have C escape characters like '\n', '\r', '\t' and
 octal numbers.  The '\"' escape is not supported.  Nor are escaped hex
 values.
-
+@sp 2
 Example 1: This is string of 16 characters and will create a 32 byte
 area:
 @smallexample
   ASCII (32) "This is 16 bytes"
 @end smallexample
-
+@sp 2
 Example 2: This is a string of 16 characters and will create a 17 byte
 area:
 @smallexample
   ASCIZ "This is 16 bytes"
 @end smallexample
+@page
+@cindex output section strings
+@kindex DIGEST "<label>[#<endian>]" "CRC64-ECMA"   (@var{expr}, @var{expr})
+@kindex DIGEST "<label>[#<endian>]" "CRC64-ISO"    (@var{expr}, @var{expr})
+@kindex DIGEST "<label>[#<endian>]" "CRC64-ISO-R"  (@var{expr}, @var{expr})
+@kindex DIGEST "<label>[#<endian>]" "CRC64-WE"     (@var{expr}, @var{expr})
+@kindex DIGEST "<label>[#<endian>]" "CRC64-XZ"     (@var{expr}, @var{expr})
+@kindex DIGEST "<label>[#<endian>]" "CRC32"        (@var{expr}, @var{expr})
+@kindex DIGEST "<label>[#<endian>]"  POLY (@var{<parms>}) (@var{expr}, @var{expr})
+
+@code{CRC Calculation}
+@sp 1
+@multitable @columnfractions .20 .27 .28 .25
+@item
+DIGEST
+@tab
+"<label>[#<endian>]"
+@tab
+"CRC32"
+@tab
+(start, end)
+@item
+DIGEST
+@tab
+"<label>[#<endian>]"
+@tab
+"CRC64-ECMA"
+@tab
+(start, end)
+@item
+DIGEST
+@tab
+"<label>[#<endian>]"
+@tab
+"CRC64-GO-ISO"
+@tab
+(start, end)
+@item
+DIGEST
+@tab
+"<label>[#<endian>]"
+@tab
+"CRC64-GO-ISO-R"
+@tab
+(start, end)
+@item
+DIGEST
+@tab
+"<label>[#<endian>]"
+@tab
+"CRC64-WE"
+@tab
+(start, end)
+@item
+DIGEST
+@tab
+"<label>[#<endian>]"
+@tab
+"CRC64-XZ"
+@tab
+(start, end)
+@item
+DIGEST
+@tab
+"<label>[#<endian>]"
+@tab
+POLY (<params>)
+@tab
+(start, end)
+@item
+DIGEST TABLE
+@tab
+"<label>[#<endian>]"
+@tab
+@tab
+(start, end)
+@end multitable
+
+You can calculate the CRC of a part of an output section through the
+@code{DIGEST} command. The default section is the @code{".text"} section.
+The commands take parameters for a label, a @code{polynome} and then two more,
+specifying range of the checked area.  The end address is the first address
+past the checked area.
+
+The checksum is generated in little endian format, but this can be overridden by
+adding a @code{#BE} or @code{#LE} modifier to the label string.
+The generated label does not include the modifier. The endian can also be
+specified on the command line using @code{-BE} or @code{-LE}.
+
+@sp 1
+There is one predefined 32-bit polynome
+
+@multitable @columnfractions .3 .4 .4
+@item
+* @code{CRC32}
+@tab
+@code{0x04C11DB7}
+@tab
+@end multitable
+
+There are five predefined 64-bit polynomes
+
+@multitable @columnfractions .3 .4 .4
+@item
+* @code{CRC64-ECMA}
+@tab
+@code{0x42F0E1EBA9EA3693}
+@tab
+@item
+* @code{CRC64-ISO}
+@tab
+@code{0x000000000000001B}
+@tab
+@item
+* @code{CRC64-ISO-R}
+@tab
+@code{0xD800000000000000}
+@tab
+@item
+* @code{CRC64-WE}
+@tab
+@code{0x42F0E1EBA9EA3693}
+@tab
+@item
+* @code{CRC64-XZ}
+@tab
+@code{0x42F0E1EBA9EA3693}
+@tab
+@end multitable
+@sp 1
+You can also select your own @code{polynome} using the @code{DIGEST POLY}.
+
+It takes the following @code{parameters} separated by commas.
+
+@multitable @columnfractions .3 .7
+@item
+@code{size}
+@tab
+size of CRC (32 or 64)
+@item
+@code{polynome}
+@tab
+@item
+@code{initial}
+@tab
+initial value of crc before calculation
+@item
+@code{xor}
+@tab
+xor result before return
+@item
+@code{input reflect}
+@tab
+bitreverse input data
+@item
+@code{output reflect}
+@tab
+bitreverse result (before xor'ing)
+@item
+@code{reciprocal}
+@tab
+bitreverse polynome before generating table
+@end multitable
+
+The parameters are explained in detail in
+
+@code{http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html}
+
+Some of the predefined polynomes are the same, but differs in the other
+parameters.
+@page
+The 32-bit <polynome> command defines the following global symbols.
+
+@multitable @columnfractions .3 .7
+@item
+@code{___CRC32___}
+@tab
+address of the CRC32 checksum
+@item
+@code{___CRC32_START___}
+@tab
+first address in the checked area.
+@item
+@code{___CRC32_END___}
+@tab
+first address past the checked area.
+@end multitable
+@sp 2
+The 64-bit <polynome> command defines the following global symbols.
+
+@multitable @columnfractions .3 .7
+@item
+@code{___CRC64___}
+@tab
+address of the CRC64 checksum
+@item
+@code{___CRC64_START___}
+@tab
+first address in the checked area.
+@item
+@code{___CRC64_END___}
+@tab
+first address past the checked area.
+@end multitable
+@sp 2
+Note: The generated CRC value must be stored outside the checked area.
+@sp 2
+Example 1: This request a CRC check using the @code{ECMA} algorithm
+
+@smallexample
+  DIGEST "C64" "CRC64-ECMA" (START_CHECK,END_TEXT)
+@end smallexample
+
+The user can retrieve the CRC value through the @code{C64} label.
+@sp 2
+Example 2: This request a CRC check using the @code{ISO} algorithm
+
+           The checksum is stored as big endian
+
+@smallexample
+  DIGEST "C64I#BE" "CRC64-ISO" (START_CHECK,END_TEXT)
+@end smallexample
+
+The user can retrieve the big endian CRC value through the @code{C64I} label.
+@sp 2
+Example 3: This request a CRC check using a user defined @code{polynome}
+
+           The setup is the "CRC32" algorithm
+
+@smallexample
+  DIGEST "CRC" POLY (32, 0x04C11DB7,~0,~0,1,1,0) (START_CHECK,END_TEXT)
+@end smallexample
+
+The user can retrieve the CRC value through the @code{CRC} label.
+@sp 2
+Example 4: This request a CRC check using the @code{CRC32} polynome
+
+@smallexample
+  DIGEST "C32.SE" (START_CHECK,END_TEXT)
+@end smallexample
+
+The user can retrieve the CRC value through the @code{C32} label.
+
+@page
+@cindex output section strings
+@kindex DIGEST TABLE "<label>[#<endian>]"
+@page
+The @code{DIGEST TABLE} command creates a 1 or 2 kByte table for a table-driven
+CRC calculation.  This speeds up the CRC calculation over a non-table-driver
+version since you can handle 8 bits at a time, instead of 1 bit.
+
+The table generated is for the @code{polynome} selected using a
+@code{DIGEST <polynome>} command.
+
+The command will define the label supplied as a parameter.
+The table will be in small endian, unless the @code{.BE} or @code{.LE} extension
+is given to the label.
+It also defines a symbol based on the size of the polynome.
+
+@enumerate
+@item
+@code{___CRC32_TABLE___}       address of the CRC32 table, or
+@item
+@code{___CRC64_TABLE___}       address of the CRC64 table
+@end enumerate
+
+@sp 2
+Example 1: Generate a 1 kB table
+
+(assuming a previous @code{DIGEST "CRC32"} command)
+
+@smallexample
+  DIGEST TABLE "crc_tab32"
+@end smallexample
+
+The user must declare @code{extern uint32_t *crc_tab32;} in his code.
+@sp 2
+Example 2: Generate a 2 kB table in big endian format.
+
+(assuming a previous @code{DIGEST "CRC64-###"} command)
+
+@smallexample
+  DIGEST TABLE "crc_tab64.be"
+@end smallexample
+
+The user must declare @code{extern uint64_t *crc_tab64;} in his code.
+
+Using the tables:
+           The user must include CRC code in the application to test the CRC
+@sp 2
+
+@multitable @columnfractions .15 .85
+@item
+Example 1:
+@tab
+Calculating CRC-64
+@end multitable
+@sp 1
+@multitable @columnfractions .05 .95
+@item
+@tab
+Copyright (c) 2016 Lammert Bies
+@item
+@tab
+Copyright (c) 2021 Bastian Molkenthin
+@item
+@tab
+Copyright (c) 2023 Ulf Samuelsson
+@end multitable
+@sp 2
+@smallexample
+#define SHIFT(t)   ((sizeof(t)-1)*8)
+uint64_t calc_crc64
+  (algorithm_desc_t * dsc, const unsigned char *input_str, size_t num_bytes)
+@{
+  uint64_t crc;
+  const unsigned char *ptr;
+  uint64_t *crc_tab = dsc->crc_tab;
+  uint64_t index;
+
+  if ((ptr = input_str) == NULL)
+    return 0;
+
+  if (crc_tab == NULL)
+    return 0;
+
+
+  crc = dsc->initial;
+  if (dsc->reciprocal)
+    @{
+      for (uint32_t i = 0; i < num_bytes; i++)
+        @{
+          index = ((crc >> 0) ^ (uint64_t) * ptr++) & 0x00000000000000FFull;
+          crc = (crc >> 8) ^ crc_tab[index];
+        @}
+    @}
+  else
+    @{
+      uint32_t shift = SHIFT (uint64_t);
+      for (uint32_t i = 0; i < num_bytes; i++)
+        @{
+          const unsigned char c = *ptr++;
+          uint64_t rc = (uint64_t) (dsc->ireflect ? reflect8 (c) : c);
+          crc = (crc ^ (rc << shift));
+          index = (uint32_t) (crc >> shift);
+          crc = (crc << 8);
+          crc = (crc ^ (crc_tab[index]));
+        @}
+    @}
+  crc = (dsc->oreflect ? reflect64 (crc) : crc);
+  crc = crc ^ dsc->xor_val;
+  return crc;
+@}  /* calc_crc64 */
+@end smallexample
+@page
+@multitable @columnfractions .15 .85
+@item
+Example 2:
+@tab
+Calculating CRC-32
+@end multitable
+@sp 1
+@multitable @columnfractions .05 .95
+@item
+@tab
+Copyright (c) 2016 Lammert Bies
+@item
+@tab
+Copyright (c) 2021 Bastian Molkenthin
+@item
+@tab
+Copyright (c) 2023 Ulf Samuelsson
+@end multitable
+@sp 2
+@smallexample
+#define SHIFT(t)   ((sizeof(t)-1)*8)
+uint32_t
+calc_crc32 (algorithm_desc_t * dsc, const unsigned char *input_str,
+            size_t num_bytes)
+@{
+  uint32_t crc;
+  const unsigned char *ptr;
+  uint32_t index;
+  uint32_t *crc_tab = dsc->crc_tab;
+
+  if ((ptr = input_str) == NULL)
+    return 0;
+
+  if (crc_tab == NULL)
+    return 0;
+
+  crc = dsc->initial;
+
+  if (dsc->reciprocal)
+    @{
+      for (uint32_t i = 0; i < num_bytes; i++)
+        @{
+          index = ((crc >> 0) ^ (uint32_t) * ptr++) & 0x000000FFul;
+          crc = (crc >> 8) ^ crc_tab[index];
+        @}
+    @}
+  else
+    @{
+      uint32_t shift = SHIFT (uint32_t);
+      for (uint32_t i = 0; i < num_bytes; i++)
+        @{
+          const unsigned char c = *ptr++;
+          uint32_t rc = (uint32_t) (dsc->ireflect ? reflect8 (c) : c);
+          crc = (crc ^ (rc << shift));
+          index = (uint32_t) (crc >> shift);
+          crc = (crc << 8);
+          crc = (crc ^ (crc_tab[index]));
+        @}
+    @}
+  crc = (dsc->oreflect ? reflect32 (crc) : crc);
+  crc = crc ^ dsc->xor_val;
+  return crc;
+@} /* calc_crc32 */
+@end smallexample
+@page
+@multitable @columnfractions .15 .85
+@item
+Example 3:
+@tab
+Calculating CRC-32 using optimized routine
+@end multitable
+@sp 1
+@multitable @columnfractions .05 .95
+@item
+@tab
+Copyright (c) 2016 Lammert Bies
+@item
+@tab
+Copyright (c) 2021 Bastian Molkenthin
+@item
+@tab
+Copyright (c) 2023 Ulf Samuelsson
+@end multitable
+@sp 2
+@smallexample
+#define SHIFT(t)   ((sizeof(t)-1)*8)
+extern uint32_t *crc_tab;
+
+uint32_t
+calc_crc32 (const unsigned char *input_str, size_t num_bytes)
+@{
+  uint32_t crc;
+  const unsigned char *ptr;
+  uint32_t index;
+  uint32_t shift = SHIFT (uint32_t);
+
+  if ((ptr = input_str) == NULL)
+    return 0;
+
+  crc = 0xFFFFFFFF;
+  for (uint32_t i = 0; i < num_bytes; i++)
+    @{
+      const unsigned char c = *ptr++;
+      crc = (crc ^ (c << shift));
+      index = (uint32_t) (crc >> shift);
+      crc = (crc << 8);
+      crc = (crc ^ (crc_tab[index]));
+    @}
+  return crc ^ 0xFFFFFFFF;
+@} /* calc_crc32 */
+@end smallexample
+@page
+@cindex output section strings
+@kindex TIMESTAMP
+
+The @code{TIMESTAMP} command creates 64-bit integer with the number of seconds
+since Epoch (1970-01-01 00:00).
 
 @kindex FILL(@var{expression})
 @cindex holes, filling
-- 
2.34.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v12 04/11] DIGEST: testsuite
  2023-03-06 13:31 [PATCH v12 0/11 Add support for CRC64 generation in linker binutils
                   ` (2 preceding siblings ...)
  2023-03-06 13:31 ` [PATCH v12 03/11] DIGEST: Documentation binutils
@ 2023-03-06 13:31 ` binutils
  2023-03-06 13:31 ` [PATCH v12 05/11] DIGEST: ldlex.l binutils
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: binutils @ 2023-03-06 13:31 UTC (permalink / raw)
  To: binutils; +Cc: nickc, Ulf Samuelsson

From: Ulf Samuelsson <ulf@emagii.com>

Signed-off-by: Ulf Samuelsson <ulf@emagii.com>
---
 ld/testsuite/ld-scripts/begin_tag.inc         |  9 +++
 ld/testsuite/ld-scripts/crc32-poly.d          | 26 +++++++++
 ld/testsuite/ld-scripts/crc32-poly.s          | 21 +++++++
 ld/testsuite/ld-scripts/crc32-poly.t          | 42 ++++++++++++++
 ld/testsuite/ld-scripts/crc32.d               | 26 +++++++++
 ld/testsuite/ld-scripts/crc32.s               | 21 +++++++
 ld/testsuite/ld-scripts/crc32.t               | 41 ++++++++++++++
 .../ld-scripts/crc64-bad-endian-contents.d    |  6 ++
 .../ld-scripts/crc64-bad-endian-contents.s    | 21 +++++++
 .../ld-scripts/crc64-bad-endian-contents.t    | 44 +++++++++++++++
 .../ld-scripts/crc64-bad-endian-size.d        |  6 ++
 .../ld-scripts/crc64-bad-endian-size.s        | 21 +++++++
 .../ld-scripts/crc64-bad-endian-size.t        | 44 +++++++++++++++
 ld/testsuite/ld-scripts/crc64-bad-label-2.d   |  6 ++
 ld/testsuite/ld-scripts/crc64-bad-label-2.s   | 21 +++++++
 ld/testsuite/ld-scripts/crc64-bad-label-2.t   | 44 +++++++++++++++
 ld/testsuite/ld-scripts/crc64-bad-label.d     |  6 ++
 ld/testsuite/ld-scripts/crc64-bad-label.s     | 21 +++++++
 ld/testsuite/ld-scripts/crc64-bad-label.t     | 44 +++++++++++++++
 ld/testsuite/ld-scripts/crc64-ecma.d          | 26 +++++++++
 ld/testsuite/ld-scripts/crc64-ecma.s          | 21 +++++++
 ld/testsuite/ld-scripts/crc64-ecma.t          | 44 +++++++++++++++
 ld/testsuite/ld-scripts/crc64-in-section.d    |  6 ++
 ld/testsuite/ld-scripts/crc64-in-section.s    | 21 +++++++
 ld/testsuite/ld-scripts/crc64-in-section.t    | 45 +++++++++++++++
 ld/testsuite/ld-scripts/crc64-iso.d           | 26 +++++++++
 ld/testsuite/ld-scripts/crc64-iso.s           | 21 +++++++
 ld/testsuite/ld-scripts/crc64-iso.t           | 43 ++++++++++++++
 ld/testsuite/ld-scripts/crc64-iso_be.d        | 26 +++++++++
 ld/testsuite/ld-scripts/crc64-iso_be.s        | 21 +++++++
 ld/testsuite/ld-scripts/crc64-iso_be.t        | 43 ++++++++++++++
 .../ld-scripts/crc64-multiple-digest.d        |  6 ++
 .../ld-scripts/crc64-multiple-digest.s        | 21 +++++++
 .../ld-scripts/crc64-multiple-digest.t        | 45 +++++++++++++++
 ld/testsuite/ld-scripts/crc64-poly-size.d     |  6 ++
 ld/testsuite/ld-scripts/crc64-poly-size.s     | 21 +++++++
 ld/testsuite/ld-scripts/crc64-poly-size.t     | 43 ++++++++++++++
 ld/testsuite/ld-scripts/crc64-poly.d          | 26 +++++++++
 ld/testsuite/ld-scripts/crc64-poly.s          | 21 +++++++
 ld/testsuite/ld-scripts/crc64-poly.t          | 43 ++++++++++++++
 ld/testsuite/ld-scripts/crc64-reverse-area.d  |  6 ++
 ld/testsuite/ld-scripts/crc64-reverse-area.s  | 21 +++++++
 ld/testsuite/ld-scripts/crc64-reverse-area.t  | 44 +++++++++++++++
 ld/testsuite/ld-scripts/crc64-same-section.d  |  6 ++
 ld/testsuite/ld-scripts/crc64-same-section.s  | 21 +++++++
 ld/testsuite/ld-scripts/crc64-same-section.t  | 47 ++++++++++++++++
 ld/testsuite/ld-scripts/crc64-section.d       | 26 +++++++++
 ld/testsuite/ld-scripts/crc64-section.s       | 21 +++++++
 ld/testsuite/ld-scripts/crc64-section.t       | 56 +++++++++++++++++++
 .../ld-scripts/crc64-unknown-digest.d         |  6 ++
 .../ld-scripts/crc64-unknown-digest.s         | 21 +++++++
 .../ld-scripts/crc64-unknown-digest.t         | 44 +++++++++++++++
 ld/testsuite/ld-scripts/crc_data.inc          |  9 +++
 ld/testsuite/ld-scripts/digest_table.inc      |  6 ++
 ld/testsuite/ld-scripts/digest_table_be.inc   |  6 ++
 ld/testsuite/ld-scripts/end_tag.inc           |  9 +++
 ld/testsuite/ld-scripts/script.exp            | 17 ++++++
 57 files changed, 1411 insertions(+)
 create mode 100644 ld/testsuite/ld-scripts/begin_tag.inc
 create mode 100644 ld/testsuite/ld-scripts/crc32-poly.d
 create mode 100644 ld/testsuite/ld-scripts/crc32-poly.s
 create mode 100644 ld/testsuite/ld-scripts/crc32-poly.t
 create mode 100644 ld/testsuite/ld-scripts/crc32.d
 create mode 100644 ld/testsuite/ld-scripts/crc32.s
 create mode 100644 ld/testsuite/ld-scripts/crc32.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-bad-endian-contents.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-bad-endian-contents.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-bad-endian-contents.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-bad-endian-size.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-bad-endian-size.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-bad-endian-size.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-bad-label-2.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-bad-label-2.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-bad-label-2.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-bad-label.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-bad-label.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-bad-label.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-ecma.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-ecma.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-ecma.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-in-section.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-in-section.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-in-section.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-iso.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-iso.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-iso.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-iso_be.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-iso_be.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-iso_be.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-multiple-digest.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-multiple-digest.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-multiple-digest.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-poly-size.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-poly-size.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-poly-size.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-poly.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-poly.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-poly.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-reverse-area.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-reverse-area.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-reverse-area.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-same-section.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-same-section.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-same-section.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-section.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-section.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-section.t
 create mode 100644 ld/testsuite/ld-scripts/crc64-unknown-digest.d
 create mode 100644 ld/testsuite/ld-scripts/crc64-unknown-digest.s
 create mode 100644 ld/testsuite/ld-scripts/crc64-unknown-digest.t
 create mode 100644 ld/testsuite/ld-scripts/crc_data.inc
 create mode 100644 ld/testsuite/ld-scripts/digest_table.inc
 create mode 100644 ld/testsuite/ld-scripts/digest_table_be.inc
 create mode 100644 ld/testsuite/ld-scripts/end_tag.inc

diff --git a/ld/testsuite/ld-scripts/begin_tag.inc b/ld/testsuite/ld-scripts/begin_tag.inc
new file mode 100644
index 00000000000..ef395bbe717
--- /dev/null
+++ b/ld/testsuite/ld-scripts/begin_tag.inc
@@ -0,0 +1,9 @@
+      BYTE(0x43);
+      BYTE(0x4F);
+      BYTE(0x44);
+      BYTE(0x45);
+      BYTE(0xDE);
+      BYTE(0xAD);
+      BYTE(0xBE);
+      BYTE(0xEF);
+      QUAD(0);
diff --git a/ld/testsuite/ld-scripts/crc32-poly.d b/ld/testsuite/ld-scripts/crc32-poly.d
new file mode 100644
index 00000000000..726534d32d9
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc32-poly.d
@@ -0,0 +1,26 @@
+#source: crc32-poly.s
+#ld: -T crc32-poly.t
+#objdump: -s -j .text
+#target: [is_elf_format] [is_coff_format]
+#notarget: [is_aout_format]
+#xfail: tic4x-*-* tic54x-*-*
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
+
+.*:     file format .*
+
+Contents of section .text:
+ 1200 434f4445 deadbeef 00000000 00000000  CODE............
+ 1210 cbf43926 00000000 00000000 00000000  ..9&............
+ 1220 cbf43926 00000000 00000000 00000000  ..9&............
+ 1230 00000000 00000000 deadbeef 434f4445  ............CODE
+ 1240 31323334 35363738 3900ffff ffffffff  123456789.......
+ 1250 434f4445 00000000 00000000 00000000  CODE............
+ 1260 ffffffff ffffffff ffffffff ffffffff  .*
+#...
+ 17e0 434f4445 deadbeef 00000000 00000000  CODE............
+ 17f0 44494745 53542054 41424c45 00000000  DIGEST TABLE....
+#...
+ 1c00 454e4420 5441424c 45000000 00000000  END TABLE.......
+ 1c10 00000000 00000000 deadbeef 434f4445  ............CODE
+#pass
diff --git a/ld/testsuite/ld-scripts/crc32-poly.s b/ld/testsuite/ld-scripts/crc32-poly.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc32-poly.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc32-poly.t b/ld/testsuite/ld-scripts/crc32-poly.t
new file mode 100644
index 00000000000..a2b7d130ba7
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc32-poly.t
@@ -0,0 +1,42 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0xCB);
+      BYTE(0xF4);
+      BYTE(0x39);
+      BYTE(0x26);
+      LONG(0x0);
+      QUAD(0x0);
+
+
+      crc32 = .;
+      DIGEST "_CRC32#BE" POLY(32, 0x04C11DB7, 0xFFFFFFFF,0xFFFFFFFF,1,1,0 )(ecc_start , ecc_end)
+      LONG(0);
+      QUAD(0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc32.d b/ld/testsuite/ld-scripts/crc32.d
new file mode 100644
index 00000000000..e35eaf8e53e
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc32.d
@@ -0,0 +1,26 @@
+#source: crc32.s
+#ld: -T crc32.t
+#objdump: -s -j .text
+#target: [is_elf_format] [is_coff_format]
+#notarget: [is_aout_format]
+#xfail: tic4x-*-* tic54x-*-*
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
+
+.*:     file format .*
+
+Contents of section .text:
+ 1200 434f4445 deadbeef 00000000 00000000  CODE............
+ 1210 cbf43926 00000000 00000000 00000000  ..9&............
+ 1220 cbf43926 00000000 00000000 00000000  ..9&............
+ 1230 00000000 00000000 deadbeef 434f4445  ............CODE
+ 1240 31323334 35363738 3900ffff ffffffff  123456789.......
+ 1250 434f4445 00000000 00000000 00000000  CODE............
+ 1260 ffffffff ffffffff ffffffff ffffffff  .*
+#...
+ 17e0 434f4445 deadbeef 00000000 00000000  CODE............
+ 17f0 44494745 53542054 41424c45 00000000  DIGEST TABLE....
+#...
+ 1c00 454e4420 5441424c 45000000 00000000  END TABLE.......
+ 1c10 00000000 00000000 deadbeef 434f4445  ............CODE
+#pass
diff --git a/ld/testsuite/ld-scripts/crc32.s b/ld/testsuite/ld-scripts/crc32.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc32.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc32.t b/ld/testsuite/ld-scripts/crc32.t
new file mode 100644
index 00000000000..b218ef1424f
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc32.t
@@ -0,0 +1,41 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0xCB);
+      BYTE(0xF4);
+      BYTE(0x39);
+      BYTE(0x26);
+      LONG(0x0);
+      QUAD(0x0);
+
+      crc32 = .;
+      DIGEST "_CRC32#BE" "CRC32" (ecc_start , ecc_end);
+      LONG(0);
+      QUAD(0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-bad-endian-contents.d b/ld/testsuite/ld-scripts/crc64-bad-endian-contents.d
new file mode 100644
index 00000000000..09df3cb2bbf
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-bad-endian-contents.d
@@ -0,0 +1,6 @@
+#source: crc64-bad-endian-size.s
+#ld: -T crc64-bad-endian-size.t
+# error: .*: bad 'endian' .* in digest label.*
+#skip: tic4x-coff, tic54x-cof
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
diff --git a/ld/testsuite/ld-scripts/crc64-bad-endian-contents.s b/ld/testsuite/ld-scripts/crc64-bad-endian-contents.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-bad-endian-contents.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-bad-endian-contents.t b/ld/testsuite/ld-scripts/crc64-bad-endian-contents.t
new file mode 100644
index 00000000000..8eecaf06dc8
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-bad-endian-contents.t
@@ -0,0 +1,44 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0x6C);
+      BYTE(0x40);
+      BYTE(0xDF);
+      BYTE(0x5F);
+      BYTE(0x0B);
+      BYTE(0x49);
+      BYTE(0x73);
+      BYTE(0x47);
+
+      QUAD(0x0);
+
+      crc64 = .;
+      DIGEST "_CRC64#NE" "CRC64-ECMA" (ecc_start , ecc_end);
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-bad-endian-size.d b/ld/testsuite/ld-scripts/crc64-bad-endian-size.d
new file mode 100644
index 00000000000..09df3cb2bbf
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-bad-endian-size.d
@@ -0,0 +1,6 @@
+#source: crc64-bad-endian-size.s
+#ld: -T crc64-bad-endian-size.t
+# error: .*: bad 'endian' .* in digest label.*
+#skip: tic4x-coff, tic54x-cof
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
diff --git a/ld/testsuite/ld-scripts/crc64-bad-endian-size.s b/ld/testsuite/ld-scripts/crc64-bad-endian-size.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-bad-endian-size.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-bad-endian-size.t b/ld/testsuite/ld-scripts/crc64-bad-endian-size.t
new file mode 100644
index 00000000000..8f9cd600773
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-bad-endian-size.t
@@ -0,0 +1,44 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0x6C);
+      BYTE(0x40);
+      BYTE(0xDF);
+      BYTE(0x5F);
+      BYTE(0x0B);
+      BYTE(0x49);
+      BYTE(0x73);
+      BYTE(0x47);
+
+      QUAD(0x0);
+
+      crc64 = .;
+      DIGEST "_CRC64#BEG" "CRC64-ECMA" (ecc_start , ecc_end);
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-bad-label-2.d b/ld/testsuite/ld-scripts/crc64-bad-label-2.d
new file mode 100644
index 00000000000..8e9d1604470
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-bad-label-2.d
@@ -0,0 +1,6 @@
+#source: crc64-bad-label-2.s
+#ld: -T crc64-bad-label-2.t
+# error: .*: Illegal label .* in digest command.*
+#skip: tic4x-coff, tic54x-cof
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
diff --git a/ld/testsuite/ld-scripts/crc64-bad-label-2.s b/ld/testsuite/ld-scripts/crc64-bad-label-2.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-bad-label-2.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-bad-label-2.t b/ld/testsuite/ld-scripts/crc64-bad-label-2.t
new file mode 100644
index 00000000000..19782bf827d
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-bad-label-2.t
@@ -0,0 +1,44 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0x6C);
+      BYTE(0x40);
+      BYTE(0xDF);
+      BYTE(0x5F);
+      BYTE(0x0B);
+      BYTE(0x49);
+      BYTE(0x73);
+      BYTE(0x47);
+
+      QUAD(0x0);
+
+      crc64 = .;
+      DIGEST "_CRC^64#BE" "CRC64-ECMA" (ecc_start , ecc_end);
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-bad-label.d b/ld/testsuite/ld-scripts/crc64-bad-label.d
new file mode 100644
index 00000000000..9215a10fc8f
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-bad-label.d
@@ -0,0 +1,6 @@
+#source: crc64-bad-label.s
+#ld: -T crc64-bad-label.t
+# error: .*: Illegal label .* in digest command.*
+#skip: tic4x-coff, tic54x-cof
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
diff --git a/ld/testsuite/ld-scripts/crc64-bad-label.s b/ld/testsuite/ld-scripts/crc64-bad-label.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-bad-label.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-bad-label.t b/ld/testsuite/ld-scripts/crc64-bad-label.t
new file mode 100644
index 00000000000..8c0941c674b
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-bad-label.t
@@ -0,0 +1,44 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0x6C);
+      BYTE(0x40);
+      BYTE(0xDF);
+      BYTE(0x5F);
+      BYTE(0x0B);
+      BYTE(0x49);
+      BYTE(0x73);
+      BYTE(0x47);
+
+      QUAD(0x0);
+
+      crc64 = .;
+      DIGEST "0_CRC64#BE" "CRC64-ECMA" (ecc_start , ecc_end);
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-ecma.d b/ld/testsuite/ld-scripts/crc64-ecma.d
new file mode 100644
index 00000000000..06b0476e627
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-ecma.d
@@ -0,0 +1,26 @@
+#source: crc64-ecma.s
+#ld: -T crc64-ecma.t
+#objdump: -s -j .text
+#target: [is_elf_format] [is_coff_format]
+#notarget: [is_aout_format]
+#xfail: tic4x-*-* tic54x-*-*
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
+
+.*:     file format .*
+
+Contents of section .text:
+ 1200 434f4445 deadbeef 00000000 00000000  CODE............
+ 1210 6c40df5f 0b497347 00000000 00000000  l@._.IsG........
+ 1220 6c40df5f 0b497347 00000000 00000000  l@._.IsG........
+ 1230 00000000 00000000 deadbeef 434f4445  ............CODE
+ 1240 31323334 35363738 3900ffff ffffffff  123456789.......
+ 1250 434f4445 00000000 00000000 00000000  CODE............
+ 1260 ffffffff ffffffff ffffffff ffffffff  .*
+#...
+ 17e0 434f4445 deadbeef 00000000 00000000  CODE............
+ 17f0 44494745 53542054 41424c45 00000000  DIGEST TABLE....
+#...
+ 2000 454e4420 5441424c 45000000 00000000  END TABLE.......
+ 2010 00000000 00000000 deadbeef 434f4445  ............CODE
+#pass
diff --git a/ld/testsuite/ld-scripts/crc64-ecma.s b/ld/testsuite/ld-scripts/crc64-ecma.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-ecma.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-ecma.t b/ld/testsuite/ld-scripts/crc64-ecma.t
new file mode 100644
index 00000000000..2a82039a93e
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-ecma.t
@@ -0,0 +1,44 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0x6C);
+      BYTE(0x40);
+      BYTE(0xDF);
+      BYTE(0x5F);
+      BYTE(0x0B);
+      BYTE(0x49);
+      BYTE(0x73);
+      BYTE(0x47);
+
+      QUAD(0x0);
+
+      crc64 = .;
+      DIGEST "_CRC64#BE" "CRC64-ECMA" (ecc_start , ecc_end);
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-in-section.d b/ld/testsuite/ld-scripts/crc64-in-section.d
new file mode 100644
index 00000000000..6f9d678b7fc
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-in-section.d
@@ -0,0 +1,6 @@
+#source: crc64-in-section.s
+#ld: -T crc64-in-section.t
+#error: .*: CRC located inside checked area
+#skip: tic4x-coff, tic54x-cof
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
diff --git a/ld/testsuite/ld-scripts/crc64-in-section.s b/ld/testsuite/ld-scripts/crc64-in-section.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-in-section.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-in-section.t b/ld/testsuite/ld-scripts/crc64-in-section.t
new file mode 100644
index 00000000000..e2e8cd99e8b
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-in-section.t
@@ -0,0 +1,45 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0x6C);
+      BYTE(0x40);
+      BYTE(0xDF);
+      BYTE(0x5F);
+      BYTE(0x0B);
+      BYTE(0x49);
+      BYTE(0x73);
+      BYTE(0x47);
+
+      QUAD(0x0);
+
+      crc64 = .;
+      bad_start = .;
+      DIGEST "_CRC64#BE" "CRC64-ECMA" (bad_start , ecc_end);
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-iso.d b/ld/testsuite/ld-scripts/crc64-iso.d
new file mode 100644
index 00000000000..11f85c18adf
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-iso.d
@@ -0,0 +1,26 @@
+#source: crc64-iso.s
+#ld: -T crc64-iso.t
+#objdump: -s -j .text
+#target: [is_elf_format] [is_coff_format]
+#notarget: [is_aout_format]
+#xfail: tic4x-*-* tic54x-*-*
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
+
+.*:     file format .*
+
+Contents of section .text:
+ 1200 434f4445 deadbeef 00000000 00000000  CODE............
+ 1210 b90956c7 75a41001 00000000 00000000  ..V.u...........
+ 1220 b90956c7 75a41001 00000000 00000000  ..V.u...........
+ 1230 00000000 00000000 deadbeef 434f4445  ............CODE
+ 1240 31323334 35363738 3900ffff ffffffff  123456789.......
+ 1250 434f4445 00000000 00000000 00000000  CODE............
+ 1260 ffffffff ffffffff ffffffff ffffffff  .*
+#...
+ 17e0 434f4445 deadbeef 00000000 00000000  CODE............
+ 17f0 44494745 53542054 41424c45 00000000  DIGEST TABLE....
+#...
+ 2000 454e4420 5441424c 45000000 00000000  END TABLE.......
+ 2010 00000000 00000000 deadbeef 434f4445  ............CODE
+#pass
diff --git a/ld/testsuite/ld-scripts/crc64-iso.s b/ld/testsuite/ld-scripts/crc64-iso.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-iso.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-iso.t b/ld/testsuite/ld-scripts/crc64-iso.t
new file mode 100644
index 00000000000..20dedc47d12
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-iso.t
@@ -0,0 +1,43 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0xb9);
+      BYTE(0x09);
+      BYTE(0x56);
+      BYTE(0xc7);
+      BYTE(0x75);
+      BYTE(0xa4);
+      BYTE(0x10);
+      BYTE(0x01);
+      QUAD(0x0);
+
+      crc64 = .;
+      DIGEST "_CRC64#BE" "CRC64-GO-ISO" (ecc_start , ecc_end)
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-iso_be.d b/ld/testsuite/ld-scripts/crc64-iso_be.d
new file mode 100644
index 00000000000..e256b414c5d
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-iso_be.d
@@ -0,0 +1,26 @@
+#source: crc64-iso_be.s
+#ld: -T crc64-iso_be.t
+#objdump: -s -j .text
+#target: [is_elf_format] [is_coff_format]
+#notarget: [is_aout_format]
+#xfail: tic4x-*-* tic54x-*-*
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
+
+.*:     file format .*
+
+Contents of section .text:
+ 1200 434f4445 deadbeef 00000000 00000000  CODE............
+ 1210 0110a475 c75609b9 00000000 00000000  ...u.V..........
+ 1220 0110a475 c75609b9 00000000 00000000  ...u.V..........
+ 1230 00000000 00000000 deadbeef 434f4445  ............CODE
+ 1240 31323334 35363738 3900ffff ffffffff  123456789.......
+ 1250 434f4445 00000000 00000000 00000000  CODE............
+ 1260 ffffffff ffffffff ffffffff ffffffff  .*
+#...
+ 17e0 434f4445 deadbeef 00000000 00000000  CODE............
+ 17f0 44494745 53542054 41424c45 00000000  DIGEST TABLE....
+#...
+ 2000 454e4420 5441424c 45000000 00000000  END TABLE.......
+ 2010 00000000 00000000 deadbeef 434f4445  ............CODE
+#pass
diff --git a/ld/testsuite/ld-scripts/crc64-iso_be.s b/ld/testsuite/ld-scripts/crc64-iso_be.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-iso_be.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-iso_be.t b/ld/testsuite/ld-scripts/crc64-iso_be.t
new file mode 100644
index 00000000000..22cc37ca304
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-iso_be.t
@@ -0,0 +1,43 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0x01);
+      BYTE(0x10);
+      BYTE(0xa4);
+      BYTE(0x75);
+      BYTE(0xc7);
+      BYTE(0x56);
+      BYTE(0x09);
+      BYTE(0xb9);
+      QUAD(0x0);
+
+      crc64 = .;
+      DIGEST "_CRC64" "CRC64-GO-ISO" (ecc_start , ecc_end)
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table_be.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-multiple-digest.d b/ld/testsuite/ld-scripts/crc64-multiple-digest.d
new file mode 100644
index 00000000000..5a1e5ccf3ca
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-multiple-digest.d
@@ -0,0 +1,6 @@
+#source: crc64-multiple-digest.s
+#ld: -T crc64-multiple-digest.t
+# error: .*: Duplicate digest .*
+#skip: tic4x-coff, tic54x-cof
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
diff --git a/ld/testsuite/ld-scripts/crc64-multiple-digest.s b/ld/testsuite/ld-scripts/crc64-multiple-digest.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-multiple-digest.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-multiple-digest.t b/ld/testsuite/ld-scripts/crc64-multiple-digest.t
new file mode 100644
index 00000000000..49c1119ad1c
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-multiple-digest.t
@@ -0,0 +1,45 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0x6C);
+      BYTE(0x40);
+      BYTE(0xDF);
+      BYTE(0x5F);
+      BYTE(0x0B);
+      BYTE(0x49);
+      BYTE(0x73);
+      BYTE(0x47);
+
+      QUAD(0x0);
+
+      crc64 = .;
+      DIGEST "_CRC64A#BE" "CRC64-ECMA" (ecc_start , ecc_end);
+      DIGEST "_CRC64B#BE" "CRC64-ISO" (ecc_start , ecc_end);
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-poly-size.d b/ld/testsuite/ld-scripts/crc64-poly-size.d
new file mode 100644
index 00000000000..841dd830ff0
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-poly-size.d
@@ -0,0 +1,6 @@
+#source: crc64-poly-size.s
+#ld: -T crc64-poly-size.t
+# error: .*: Illegal Size in DIGEST: .*
+#skip: tic4x-coff, tic54x-cof
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
diff --git a/ld/testsuite/ld-scripts/crc64-poly-size.s b/ld/testsuite/ld-scripts/crc64-poly-size.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-poly-size.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-poly-size.t b/ld/testsuite/ld-scripts/crc64-poly-size.t
new file mode 100644
index 00000000000..8dad7186b9f
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-poly-size.t
@@ -0,0 +1,43 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0x6C);
+      BYTE(0x40);
+      BYTE(0xDF);
+      BYTE(0x5F);
+      BYTE(0x0B);
+      BYTE(0x49);
+      BYTE(0x73);
+      BYTE(0x47);
+      QUAD(0x0);
+
+      crc64 = .;
+      DIGEST "_CRC64#BE" POLY(80,0x42F0E1EBA9EA3693,0,0,0,0,0)(ecc_start , ecc_end)
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-poly.d b/ld/testsuite/ld-scripts/crc64-poly.d
new file mode 100644
index 00000000000..6be05b6aed8
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-poly.d
@@ -0,0 +1,26 @@
+#source: crc64-poly.s
+#ld: -T crc64-poly.t
+#objdump: -s -j .text
+#target: [is_elf_format] [is_coff_format]
+#notarget: [is_aout_format]
+#xfail: tic4x-*-* tic54x-*-*
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
+
+.*:     file format .*
+
+Contents of section .text:
+ 1200 434f4445 deadbeef 00000000 00000000  CODE............
+ 1210 6c40df5f 0b497347 00000000 00000000  l@._.IsG........
+ 1220 6c40df5f 0b497347 00000000 00000000  l@._.IsG........
+ 1230 00000000 00000000 deadbeef 434f4445  ............CODE
+ 1240 31323334 35363738 3900ffff ffffffff  123456789.......
+ 1250 434f4445 00000000 00000000 00000000  CODE............
+ 1260 ffffffff ffffffff ffffffff ffffffff  .*
+#...
+ 17e0 434f4445 deadbeef 00000000 00000000  CODE............
+ 17f0 44494745 53542054 41424c45 00000000  DIGEST TABLE....
+#...
+ 2000 454e4420 5441424c 45000000 00000000  END TABLE.......
+ 2010 00000000 00000000 deadbeef 434f4445  ............CODE
+#pass
diff --git a/ld/testsuite/ld-scripts/crc64-poly.s b/ld/testsuite/ld-scripts/crc64-poly.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-poly.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-poly.t b/ld/testsuite/ld-scripts/crc64-poly.t
new file mode 100644
index 00000000000..fb357caedf9
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-poly.t
@@ -0,0 +1,43 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0x6C);
+      BYTE(0x40);
+      BYTE(0xDF);
+      BYTE(0x5F);
+      BYTE(0x0B);
+      BYTE(0x49);
+      BYTE(0x73);
+      BYTE(0x47);
+      QUAD(0x0);
+
+      crc64 = .;
+      DIGEST "_CRC64#BE" POLY(64,0x42F0E1EBA9EA3693,0,0,0,0,0)(ecc_start , ecc_end)
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-reverse-area.d b/ld/testsuite/ld-scripts/crc64-reverse-area.d
new file mode 100644
index 00000000000..344e8d28ed9
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-reverse-area.d
@@ -0,0 +1,6 @@
+#source: crc64-reverse-area.s
+#ld: -T crc64-reverse-area.t
+# error: .*: CRC area starts after its end location.*
+#skip: tic4x-coff, tic54x-cof
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
diff --git a/ld/testsuite/ld-scripts/crc64-reverse-area.s b/ld/testsuite/ld-scripts/crc64-reverse-area.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-reverse-area.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-reverse-area.t b/ld/testsuite/ld-scripts/crc64-reverse-area.t
new file mode 100644
index 00000000000..27aef4413a0
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-reverse-area.t
@@ -0,0 +1,44 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0x6C);
+      BYTE(0x40);
+      BYTE(0xDF);
+      BYTE(0x5F);
+      BYTE(0x0B);
+      BYTE(0x49);
+      BYTE(0x73);
+      BYTE(0x47);
+
+      QUAD(0x0);
+
+      crc64 = .;
+      DIGEST "_CRC64#BE" "CRC64-ECMA" (ecc_end, ecc_start);
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-same-section.d b/ld/testsuite/ld-scripts/crc64-same-section.d
new file mode 100644
index 00000000000..787145a6432
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-same-section.d
@@ -0,0 +1,6 @@
+#source: crc64-same-section.s
+#ld: -T crc64-same-section.t
+#error: .*: The CRC digest and table should be inside the .*
+#skip: tic4x-coff, tic54x-cof
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
diff --git a/ld/testsuite/ld-scripts/crc64-same-section.s b/ld/testsuite/ld-scripts/crc64-same-section.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-same-section.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-same-section.t b/ld/testsuite/ld-scripts/crc64-same-section.t
new file mode 100644
index 00000000000..47c96f556a7
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-same-section.t
@@ -0,0 +1,47 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .crc ALIGN (0x200) :
+    {
+      crc64 = .;
+      DIGEST "_CRC64#BE" "CRC64-ECMA" (ecc_start , ecc_end);
+    } > rom
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0x6C);
+      BYTE(0x40);
+      BYTE(0xDF);
+      BYTE(0x5F);
+      BYTE(0x0B);
+      BYTE(0x49);
+      BYTE(0x73);
+      BYTE(0x47);
+
+      QUAD(0x0);
+
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-section.d b/ld/testsuite/ld-scripts/crc64-section.d
new file mode 100644
index 00000000000..16e625b71c9
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-section.d
@@ -0,0 +1,26 @@
+#source: crc64-section.s
+#ld: -T crc64-section.t
+#objdump: -s -j .foo
+#target: [is_elf_format] [is_coff_format]
+#notarget: [is_aout_format]
+#xfail: tic4x-*-* tic54x-*-*
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
+
+.*:     file format .*
+
+Contents of section .foo:
+ 1200 434f4445 deadbeef 00000000 00000000  CODE............
+ 1210 6c40df5f 0b497347 00000000 00000000  l@._.IsG........
+ 1220 6c40df5f 0b497347 00000000 00000000  l@._.IsG........
+ 1230 00000000 00000000 deadbeef 434f4445  ............CODE
+ 1240 31323334 35363738 3900ffff ffffffff  123456789.......
+ 1250 434f4445 00000000 00000000 00000000  CODE............
+ 1260 ffffffff ffffffff ffffffff ffffffff  .*
+#...
+ 17e0 434f4445 deadbeef 00000000 00000000  CODE............
+ 17f0 44494745 53542054 41424c45 00000000  DIGEST TABLE....
+#...
+ 2000 454e4420 5441424c 45000000 00000000  END TABLE.......
+ 2010 00000000 00000000 deadbeef 434f4445  ............CODE
+#pass
diff --git a/ld/testsuite/ld-scripts/crc64-section.s b/ld/testsuite/ld-scripts/crc64-section.s
new file mode 100644
index 00000000000..99ff9f84960
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-section.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .foo
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-section.t b/ld/testsuite/ld-scripts/crc64-section.t
new file mode 100644
index 00000000000..7cfcdf7beb4
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-section.t
@@ -0,0 +1,56 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .foo ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0x6C);
+      BYTE(0x40);
+      BYTE(0xDF);
+      BYTE(0x5F);
+      BYTE(0x0B);
+      BYTE(0x49);
+      BYTE(0x73);
+      BYTE(0x47);
+
+      QUAD(0x0);
+
+      crc64 = .;
+      DIGEST "_CRC64#BE" "CRC64-ECMA" (ecc_start , ecc_end);
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      ecc_start = .;
+      ASCIZ "123456789"
+      ecc_end = . - 1;
+      . = ALIGN(0x10);
+
+      entry = .;
+      *(.foo)
+      . = ALIGN(0x100);
+      BYTE(1);
+      INCLUDE "digest_table.inc"
+    } > rom
+  .text ALIGN (0x200) :
+    {
+      *(.text)
+      QUAD(0x0)
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc64-unknown-digest.d b/ld/testsuite/ld-scripts/crc64-unknown-digest.d
new file mode 100644
index 00000000000..051b06c8879
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-unknown-digest.d
@@ -0,0 +1,6 @@
+#source: crc64-unknown-digest.s
+#ld: -T crc64-unknown-digest.t
+# error: .*: Unknown digest.*
+#skip: tic4x-coff, tic54x-cof
+#skip: ns32k-pc532-macho, pdp11-dec-aout, powerpc-ibm-aix5.2.0
+#skip: rs6000-aix4.3.3, alpha-linuxecoff
diff --git a/ld/testsuite/ld-scripts/crc64-unknown-digest.s b/ld/testsuite/ld-scripts/crc64-unknown-digest.s
new file mode 100644
index 00000000000..e4ffb15af62
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-unknown-digest.s
@@ -0,0 +1,21 @@
+    .extern ecc_start
+	.section .text
+main:
+	.byte 0x43
+	.byte 0x4F
+	.byte 0x44
+	.byte 0x45
+    .long 0
+    .long 0
+    .long 0
+	.section .data
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xde
+    .byte 0xad
+    .byte 0xbe
+    .byte 0xef
+	.section .bss
+	.long 0
diff --git a/ld/testsuite/ld-scripts/crc64-unknown-digest.t b/ld/testsuite/ld-scripts/crc64-unknown-digest.t
new file mode 100644
index 00000000000..9f4c900924c
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc64-unknown-digest.t
@@ -0,0 +1,44 @@
+MEMORY {
+  rom : ORIGIN = 0x000000, LENGTH = 0x4000
+  ram : ORIGIN = 0x008000, LENGTH = 0x1000
+}
+
+_start = 0x000000;
+SECTIONS
+{
+  . = 0x1000 + SIZEOF_HEADERS;
+  .text ALIGN (0x200) :
+
+    {
+      FILL(0xFF)
+      header = .;
+      INCLUDE "begin_tag.inc"
+
+      expected = .;
+      BYTE(0x6C);
+      BYTE(0x40);
+      BYTE(0xDF);
+      BYTE(0x5F);
+      BYTE(0x0B);
+      BYTE(0x49);
+      BYTE(0x73);
+      BYTE(0x47);
+
+      QUAD(0x0);
+
+      crc64 = .;
+      DIGEST "_CRC64#BE" "TCRC64-ECMA" (ecc_start , ecc_end);
+      QUAD(0x0);
+
+      INCLUDE "end_tag.inc"
+
+      INCLUDE "crc_data.inc"
+
+      INCLUDE "digest_table.inc"
+    } > rom
+
+  .data : AT (0x008000) { *(.data) } >ram /* NO default AT>rom */
+  . = ALIGN(0x20);
+  .bss : { *(.bss) } >ram /* NO default AT>rom */
+  /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/crc_data.inc b/ld/testsuite/ld-scripts/crc_data.inc
new file mode 100644
index 00000000000..176a4689493
--- /dev/null
+++ b/ld/testsuite/ld-scripts/crc_data.inc
@@ -0,0 +1,9 @@
+      ecc_start = .;
+      ASCIZ "123456789"
+      ecc_end = . - 1;
+      . = ALIGN(0x10);
+
+      entry = .;
+      *(.text)
+      . = ALIGN(0x100);
+      BYTE(1);
diff --git a/ld/testsuite/ld-scripts/digest_table.inc b/ld/testsuite/ld-scripts/digest_table.inc
new file mode 100644
index 00000000000..fb40a4fa024
--- /dev/null
+++ b/ld/testsuite/ld-scripts/digest_table.inc
@@ -0,0 +1,6 @@
+      . = ALIGN(2048) - 32;
+      INCLUDE "begin_tag.inc"
+      ASCII (16) "DIGEST TABLE"
+      DIGEST TABLE "CRCTAB"
+      ASCII (16) "END TABLE"
+      INCLUDE "end_tag.inc"
diff --git a/ld/testsuite/ld-scripts/digest_table_be.inc b/ld/testsuite/ld-scripts/digest_table_be.inc
new file mode 100644
index 00000000000..eec712d9eff
--- /dev/null
+++ b/ld/testsuite/ld-scripts/digest_table_be.inc
@@ -0,0 +1,6 @@
+      . = ALIGN(2048) - 32;
+      INCLUDE "begin_tag.inc"
+      ASCII (16) "DIGEST TABLE"
+      DIGEST TABLE "CRCTAB.BE"
+      ASCII (16) "END TABLE"
+      INCLUDE "end_tag.inc"
diff --git a/ld/testsuite/ld-scripts/end_tag.inc b/ld/testsuite/ld-scripts/end_tag.inc
new file mode 100644
index 00000000000..4c80854b062
--- /dev/null
+++ b/ld/testsuite/ld-scripts/end_tag.inc
@@ -0,0 +1,9 @@
+      QUAD(0);
+      BYTE(0xDE);
+      BYTE(0xAD);
+      BYTE(0xBE);
+      BYTE(0xEF);
+      BYTE(0x43);
+      BYTE(0x4F);
+      BYTE(0x44);
+      BYTE(0x45);
diff --git a/ld/testsuite/ld-scripts/script.exp b/ld/testsuite/ld-scripts/script.exp
index 56e12da8e61..64767d87f83 100644
--- a/ld/testsuite/ld-scripts/script.exp
+++ b/ld/testsuite/ld-scripts/script.exp
@@ -229,6 +229,23 @@ foreach test_script $test_script_list {
 
 run_dump_test "asciz"
 run_dump_test "ascii"
+run_dump_test "crc64-ecma"
+run_dump_test "crc64-iso"
+run_dump_test "crc64-iso_be"
+run_dump_test "crc64-poly"
+run_dump_test "crc32"
+run_dump_test "crc32-poly"
+run_dump_test "crc64-reverse-area"
+run_dump_test "crc64-in-section"
+run_dump_test "crc64-same-section"
+run_dump_test "crc64-multiple-digest"
+run_dump_test "crc64-unknown-digest"
+run_dump_test "crc64-poly-size"
+run_dump_test "crc64-bad-label"
+run_dump_test "crc64-bad-label-2"
+run_dump_test "crc64-bad-endian-size"
+run_dump_test "crc64-bad-endian-contents"
+
 run_dump_test "align-with-input"
 run_dump_test "pr20302"
 run_dump_test "output-section-types"
-- 
2.34.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v12 05/11] DIGEST: ldlex.l
  2023-03-06 13:31 [PATCH v12 0/11 Add support for CRC64 generation in linker binutils
                   ` (3 preceding siblings ...)
  2023-03-06 13:31 ` [PATCH v12 04/11] DIGEST: testsuite binutils
@ 2023-03-06 13:31 ` binutils
  2023-03-06 13:31 ` [PATCH v12 06/11] DIGEST: ldgram.y binutils
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: binutils @ 2023-03-06 13:31 UTC (permalink / raw)
  To: binutils; +Cc: nickc, Ulf Samuelsson

From: Ulf Samuelsson <ulf@emagii.com>

Signed-off-by: Ulf Samuelsson <ulf@emagii.com>
---
 ld/ldlex.l | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/ld/ldlex.l b/ld/ldlex.l
index 910e7ea3b8b..a240538be6b 100644
--- a/ld/ldlex.l
+++ b/ld/ldlex.l
@@ -298,6 +298,13 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
 <SCRIPT>"AFTER"				{ RTOKEN(AFTER); }
 <SCRIPT>"BEFORE"			{ RTOKEN(BEFORE); }
 <WILD>"FILL"				{ RTOKEN(FILL); }
+<WILD>"DIGEST"				{ RTOKEN(DIGEST); }
+<WILD>"POLY"				{ RTOKEN(POLY); }
+<WILD>"TABLE"				{ RTOKEN(TABLE); }
+<WILD>"TIMESTAMP"			{ RTOKEN(TIMESTAMP); }
+<WILD>"DEBUG"				{ RTOKEN(DEBUG); }
+<WILD>"ON"				{ RTOKEN(ON); }
+<WILD>"OFF"				{ RTOKEN(OFF); }
 <SCRIPT>"STARTUP"			{ RTOKEN(STARTUP); }
 <SCRIPT>"OUTPUT_FORMAT"			{ RTOKEN(OUTPUT_FORMAT); }
 <SCRIPT>"OUTPUT_ARCH"			{ RTOKEN(OUTPUT_ARCH); }
-- 
2.34.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v12 06/11] DIGEST: ldgram.y
  2023-03-06 13:31 [PATCH v12 0/11 Add support for CRC64 generation in linker binutils
                   ` (4 preceding siblings ...)
  2023-03-06 13:31 ` [PATCH v12 05/11] DIGEST: ldlex.l binutils
@ 2023-03-06 13:31 ` binutils
  2023-03-06 13:31 ` [PATCH v12 07/11] DIGEST: ldmain.c binutils
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: binutils @ 2023-03-06 13:31 UTC (permalink / raw)
  To: binutils; +Cc: nickc, Ulf Samuelsson

From: Ulf Samuelsson <ulf@emagii.com>

Signed-off-by: Ulf Samuelsson <ulf@emagii.com>
---
 ld/ldgram.y | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 60 insertions(+), 1 deletion(-)

diff --git a/ld/ldgram.y b/ld/ldgram.y
index 26e56fe1566..ea0c569279a 100644
--- a/ld/ldgram.y
+++ b/ld/ldgram.y
@@ -41,6 +41,7 @@
 #include "mri.h"
 #include "ldctor.h"
 #include "ldlex.h"
+#include "lddigest.h"
 
 #ifndef YYDEBUG
 #define YYDEBUG 1
@@ -130,6 +131,9 @@ static int error_index;
 %token DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
 %token SORT_BY_NAME SORT_BY_ALIGNMENT SORT_NONE
 %token SORT_BY_INIT_PRIORITY
+%token DIGEST POLY POLYI TABLE
+%token TIMESTAMP
+%token DEBUG ON OFF
 %token '{' '}'
 %token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH
 %token INHIBIT_COMMON_ALLOCATION FORCE_GROUP_ALLOCATION
@@ -668,7 +672,7 @@ statement:
 		{
 		  lang_add_data ((int) $1, $3);
 		}
-        | ASCII '(' mustbe_exp ')' NAME
+	| ASCII '(' mustbe_exp ')' NAME
 		{
 		  /* 'value' is a memory leak, do we care?  */
 		  etree_type *value = $3;
@@ -685,6 +689,31 @@ statement:
 		{
 		  lang_add_fill ($3);
 		}
+	| DIGEST NAME
+		{ /* CRC_ADDRESS is set in <polynome>, but polynome reserves space, so we use a temporary */
+		  digest_label = lang_get_label($2, &digest_big_endian);
+		  lang_add_assignment (exp_assign (digest_label, exp_nameop (NAME, "."), false));
+		}
+		polynome '(' mustbe_exp ',' mustbe_exp ')'
+		{
+		  if (polynome_valid)
+		    {
+		      lang_add_assignment (exp_assign (CRC_ADDRESS, exp_nameop (NAME, digest_label), false));
+		      lang_add_assignment (exp_assign (CRC_START, $6, false));
+		      lang_add_assignment (exp_assign (CRC_END,   $8, false));
+		    }
+		}
+	| DIGEST TABLE NAME
+		{
+		  bool       big_endian;
+		  const char *label = lang_get_label($3, &big_endian);
+		  lang_add_assignment (exp_assign (label, exp_nameop (NAME,"."), false));
+		  lang_add_digest_table (big_endian);
+		}
+	| TIMESTAMP
+		{
+		  lang_add_timestamp ();
+		}
 	| ASSERT_K
 		{ ldlex_expression (); }
 	  '(' exp ',' NAME ')' separator
@@ -692,13 +721,43 @@ statement:
 		  ldlex_popstate ();
 		  lang_add_assignment (exp_assert ($4, $6));
 		}
+	| DEBUG ON
+		{
+		  yydebug = 1;
+		}
+	| DEBUG OFF
+		{
+		  yydebug = 0;
+		}
 	| INCLUDE filename
 		{
 		  ldfile_open_command_file ($2);
 		}
+
 	  statement_list_opt END
 	;
 
+polynome:
+	NAME
+		{
+		  polynome_valid = lang_set_digest($1);
+		}
+	| POLY '(' mustbe_exp ','
+		   mustbe_exp ',' mustbe_exp ',' mustbe_exp ','
+		   mustbe_exp ',' mustbe_exp ',' mustbe_exp ')'
+		{
+		  lang_add_digest (
+			$3->value.value,	/* size			*/
+			$5->value.value,	/* polynome		*/
+			$7->value.value,	/* initial value	*/
+			$9->value.value,	/* xor     value	*/
+			$11->value.value,	/* input   reflected	*/
+			$13->value.value,	/* output  reflected	*/
+			$15->value.value	/* reciprocal		*/
+			);
+		  polynome_valid = true;
+		}
+
 statement_list:
 		statement_list statement
 	|	statement
-- 
2.34.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v12 07/11] DIGEST: ldmain.c
  2023-03-06 13:31 [PATCH v12 0/11 Add support for CRC64 generation in linker binutils
                   ` (5 preceding siblings ...)
  2023-03-06 13:31 ` [PATCH v12 06/11] DIGEST: ldgram.y binutils
@ 2023-03-06 13:31 ` binutils
  2023-03-06 13:31 ` [PATCH v12 08/11] DIGEST: ldlang.*: add timestamp binutils
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: binutils @ 2023-03-06 13:31 UTC (permalink / raw)
  To: binutils; +Cc: nickc, Ulf Samuelsson

From: Ulf Samuelsson <ulf@emagii.com>

Signed-off-by: Ulf Samuelsson <ulf@emagii.com>
---
 ld/ldmain.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ld/ldmain.c b/ld/ldmain.c
index 25cc89b72f9..6bd17c87469 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -34,6 +34,7 @@
 #include "ldwrite.h"
 #include "ldexp.h"
 #include "ldlang.h"
+#include "lddigest.h"
 #include <ldgram.h>
 #include "ldlex.h"
 #include "ldfile.h"
@@ -527,6 +528,7 @@ main (int argc, char **argv)
 
   ldwrite ();
 
+  lang_generate_digest();		/* Calculate and store CRC on request */
   if (config.map_file != NULL)
     lang_map ();
   if (command_line.cref)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v12 08/11] DIGEST: ldlang.*: add timestamp
  2023-03-06 13:31 [PATCH v12 0/11 Add support for CRC64 generation in linker binutils
                   ` (6 preceding siblings ...)
  2023-03-06 13:31 ` [PATCH v12 07/11] DIGEST: ldmain.c binutils
@ 2023-03-06 13:31 ` binutils
  2023-03-06 13:31 ` [PATCH v12 09/11] DIGEST: calculation binutils
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: binutils @ 2023-03-06 13:31 UTC (permalink / raw)
  To: binutils; +Cc: nickc, Ulf Samuelsson

From: Ulf Samuelsson <ulf@emagii.com>

Signed-off-by: Ulf Samuelsson <ulf@emagii.com>
---
 ld/ldlang.c | 8 ++++++++
 ld/ldlang.h | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/ld/ldlang.c b/ld/ldlang.c
index 295de015da9..77917027f83 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -20,6 +20,7 @@
 
 #include "sysdep.h"
 #include <limits.h>
+#include <time.h>
 #include "bfd.h"
 #include "libiberty.h"
 #include "filenames.h"
@@ -8520,6 +8521,13 @@ lang_add_string (size_t size, const char *s)
   free (string);
 }
 
+/* Store the time of linking in the image */
+void
+lang_add_timestamp (void)
+{
+  lang_add_data (QUAD, exp_intop ((bfd_vma) time (0)));
+}
+
 /* Create a new reloc statement.  RELOC is the BFD relocation type to
    generate.  HOWTO is the corresponding howto structure (we could
    look this up, but the caller has already done so).  SECTION is the
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 2300fa5b2a3..ef785ae5cad 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -649,6 +649,8 @@ extern void lang_add_data
 extern bfd_vma charcount(const char *s);
 extern void lang_add_string
   (size_t, const char *s);
+extern void lang_add_timestamp
+  (void);
 extern void lang_add_reloc
   (bfd_reloc_code_real_type, reloc_howto_type *, asection *, const char *,
    union etree_union *);
-- 
2.34.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v12 09/11] DIGEST: calculation
  2023-03-06 13:31 [PATCH v12 0/11 Add support for CRC64 generation in linker binutils
                   ` (7 preceding siblings ...)
  2023-03-06 13:31 ` [PATCH v12 08/11] DIGEST: ldlang.*: add timestamp binutils
@ 2023-03-06 13:31 ` binutils
  2023-03-06 13:31 ` [PATCH v12 10/11] DIGEST: Makefile.* binutils
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 22+ messages in thread
From: binutils @ 2023-03-06 13:31 UTC (permalink / raw)
  To: binutils; +Cc: nickc, Ulf Samuelsson

From: Ulf Samuelsson <ulf@emagii.com>

Signed-off-by: Ulf Samuelsson <ulf@emagii.com>
---
 ld/ldcrc32.c      | 179 +++++++++
 ld/ldcrc64.c      | 180 +++++++++
 ld/lddigest.c     | 903 ++++++++++++++++++++++++++++++++++++++++++++++
 ld/lddigest.h     | 183 ++++++++++
 ld/lddigest_tab.c | 136 +++++++
 ld/ldreflect.c    |  99 +++++
 ld/ldreflect.h    |  37 ++
 7 files changed, 1717 insertions(+)
 create mode 100644 ld/ldcrc32.c
 create mode 100644 ld/ldcrc64.c
 create mode 100644 ld/lddigest.c
 create mode 100755 ld/lddigest.h
 create mode 100644 ld/lddigest_tab.c
 create mode 100644 ld/ldreflect.c
 create mode 100644 ld/ldreflect.h

diff --git a/ld/ldcrc32.c b/ld/ldcrc32.c
new file mode 100644
index 00000000000..8b7de1d6e72
--- /dev/null
+++ b/ld/ldcrc32.c
@@ -0,0 +1,179 @@
+/*
+ * Library: ldlibcrc
+ * Author:  Lammert Bies, Bastian Molkenthin, Ulf Samuelsson
+ *
+ * This file is licensed under the MIT License as stated below
+ *
+ * Copyright (c) 2016 Lammert Bies
+ * Copyright (c) 2013 Ulf Samuelsson (ulf@emagii.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "lddigest.h"
+#include "ldreflect.h"
+
+#define SHIFT(t)   ((sizeof(t)-1)*8)
+/* ============ CRC-32 LIBCRC functions ======================================*/
+
+/*
+ * void _init_crc32_tab (uint32_t *crc_tab,  uint32_t poly);
+ *
+ * For optimal speed, the CRC32 calculation uses a table with pre-calculated
+ * bit patterns which are used in the XOR operations in the program.
+ * _init_crc32_tab is copyright (c) 2016 Lammert Bies
+ */
+static void
+_init_crc32_tab (uint32_t * crc_tab, uint32_t poly)
+{
+  uint32_t crc;
+  uint32_t shift = SHIFT (uint32_t);
+  for (uint32_t i = 0; i < 256; i++)
+    {
+      crc = i << shift;
+      for (uint32_t j = 0; j < 8; j++)
+	{
+	  if ((crc & 0x80000000u) != 0)
+	    {
+	      crc = (crc << 1) ^ poly;
+	    }
+	  else
+	    {
+	      crc = crc << 1;
+	    }
+	}
+      crc_tab[i] = crc;
+    }
+}				/* _init_crc32__tab */
+
+/*
+ * void _init_crc32_reciprocal_tab (uint32_t *crc_tab,  uint32_t poly);
+ *
+ * For optimal speed, the CRC32 calculation uses a table with pre-calculated
+ * bit patterns which are used in the XOR operations in the program.
+ * _init_crc32_reciprocal_tab is copyright (c) 2021 Bastian Molkenthin
+ */
+static void
+_init_crc32_reciprocal_tab (uint32_t * crc_tab, uint32_t poly)
+{
+  uint32_t crc;
+  uint32_t reflected_poly = reflect32 (poly);
+  for (uint32_t i = 0; i < 256; i++)
+    {
+      crc = i;
+      for (uint32_t j = 0; j < 8; j++)
+	{
+	  if (crc & 0x00000001U)
+	    {
+	      crc >>= 1;
+	      crc ^= reflected_poly;
+	    }
+	  else
+	    {
+	      crc = crc >> 1;
+	    }
+	}
+      crc_tab[i] = crc;
+    }
+}				/* _init_crc32_reciprocal_tab */
+
+/*
+ * void init_crc32_tab( void );
+ *
+ * For optimal speed, the CRC32 calculation uses a table with pre-calculated
+ * bit patterns which are used in the XOR operations in the program.
+ * The table can be calculated in a normal or a reciprocal version.
+ * init_crc64_tab is copyright (c) 2023 Ulf Samuelsson
+ */
+uint32_t *
+init_crc32_tab (algorithm_desc_t * dsc)
+{
+  uint32_t *crc_tab = malloc (256 * sizeof (uint32_t));
+
+  if (crc_tab == NULL)
+    return NULL;
+
+  if (dsc->reciprocal)
+    {
+      _init_crc32_reciprocal_tab (crc_tab, dsc->poly.d32._0);
+    }
+  else
+    {
+      _init_crc32_tab (crc_tab, dsc->poly.d32._0);
+    }
+
+  return crc_tab;
+}				/* init_crc32_tab */
+
+/*
+ * uint32_t calc_crc32(algorithm_desc_t *dsc, const unsigned char *input_str, size_t num_bytes);
+ *
+ * The function calc_crc32() calculates in one pass the common 32 bit CRC value for
+ * a byte string that is passed to the function together with a parameter
+ * indicating the length.
+ * calc_crc32 is
+ *   copyright (c) 2016 Lammert Bies
+ *   copyright (c) 2021 Bastian Molkenthin
+ *   copyright (c) 2023 Ulf Samuelsson
+ */
+uint32_t
+calc_crc32 (algorithm_desc_t * dsc, const unsigned char *input_str,
+	    size_t num_bytes)
+{
+  uint32_t crc;
+  const unsigned char *ptr;
+  uint32_t index;
+  uint32_t *crc_tab = dsc->crc_tab;
+
+  if ((ptr = input_str) == NULL)
+    return 0;
+
+  if (crc_tab == NULL)
+    return 0;
+
+  crc = dsc->initial.d32._0;
+
+  if (dsc->reciprocal)
+    {
+      for (uint32_t i = 0; i < num_bytes; i++)
+	{
+	  index = ((crc >> 0) ^ (uint32_t) * ptr++) & 0x000000FFul;
+	  crc = (crc >> 8) ^ crc_tab[index];
+	}
+    }
+  else
+    {
+      uint32_t shift = SHIFT (uint32_t);
+      for (uint32_t i = 0; i < num_bytes; i++)
+	{
+	  const unsigned char c = *ptr++;
+	  uint32_t rc = (uint32_t) (dsc->ireflect ? reflect8 (c) : c);
+	  crc = (crc ^ (rc << shift));
+	  index = (uint32_t) (crc >> shift);
+	  crc = (crc << 8);
+	  crc = (crc ^ (crc_tab[index]));
+	}
+    }
+  crc = (dsc->oreflect ? reflect32 (crc) : crc);
+  crc = crc ^ dsc->xor_val.d32._0;
+  return crc;
+}				/* calc_crc32 */
diff --git a/ld/ldcrc64.c b/ld/ldcrc64.c
new file mode 100644
index 00000000000..c94ff21bdcb
--- /dev/null
+++ b/ld/ldcrc64.c
@@ -0,0 +1,180 @@
+/*
+ * Library: ldlibcrc
+ * Author:  Lammert Bies, Bastian Molkenthin, Ulf Samuelsson
+ *
+ * This file is licensed under the MIT License as stated below
+ *
+ * Copyright (c) 2016 Lammert Bies
+ * Copyright (c) 2021 Bastian Molkenthin
+ * Copyright (c) 2023 Ulf Samuelsson (ulf@emagii.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "lddigest.h"
+#include "ldreflect.h"
+
+#define SHIFT(t)   ((sizeof(t)-1)*8)
+/* ============ CRC-64 LIBCRC functions ======================================*/
+
+/*
+ * uint64_t *init_crc64_tab(algorithm_desc_t *dsc) ;
+ *
+ * For optimal speed, the CRC64 calculation uses a table with pre-calculated
+ * bit patterns which are used in the XOR operations in the program.
+ * init_crc64_tab is copyright (c) 2016 Lammert Bies
+ */
+static void
+_init_crc64_tab (uint64_t * crc_tab, uint64_t poly)
+{
+  uint64_t crc;
+  uint32_t shift = SHIFT (uint64_t);
+  for (uint64_t i = 0; i < 256; i++)
+    {
+      crc = i << shift;
+      for (uint64_t j = 0; j < 8; j++)
+	{
+	  if ((crc & 0x8000000000000000ull) != 0)
+	    {
+	      crc = (crc << 1) ^ poly;
+	    }
+	  else
+	    {
+	      crc = crc << 1;
+	    }
+	}
+      crc_tab[i] = crc;
+    }
+}				/* _init_crc64_tab */
+
+/*
+ * _init_crc64_reciprocal_tab (uint64_t *crc_tab,  uint64_t poly);
+ *
+ * For optimal speed, the CRC64 calculation uses a table with pre-calculated
+ * bit patterns which are used in the XOR operations in the program.
+ * _init_crc64_reciprocal_tab is copyright (c) 2021 Bastian Molkenthin
+ */
+
+static void
+_init_crc64_reciprocal_tab (uint64_t * crc_tab, uint64_t poly)
+{
+  uint64_t crc;
+  uint64_t reflected_poly = reflect64 (poly);
+  for (uint64_t i = 0; i < 256; i++)
+    {
+      crc = i;
+      for (uint64_t j = 0; j < 8; j++)
+	{
+	  if ((crc & 0x0000000000000001ULL) != 0)
+	    {
+	      crc >>= 1;
+	      crc ^= reflected_poly;
+	    }
+	  else
+	    {
+	      crc >>= 1;
+	    }
+	}
+      crc_tab[i] = crc;
+    }
+}				/* _init_crc64_reciprocal_tab */
+
+/*
+ * uint64_t *init_crc64_tab(algorithm_desc_t *dsc) ;
+ *
+ * For optimal speed, the CRC64 calculation uses a table with pre-calculated
+ * bit patterns which are used in the XOR operations in the program.
+ * init_crc64_tab is copyright (c) 2023 Ulf Samuelsson
+ */
+uint64_t *
+init_crc64_tab (algorithm_desc_t * dsc)
+{
+  uint64_t *crc_tab = malloc (256 * sizeof (uint64_t));
+
+  if (crc_tab == NULL)
+    return NULL;
+
+  if (dsc->reciprocal)
+    {
+      _init_crc64_reciprocal_tab (crc_tab, dsc->poly.d64);
+    }
+  else
+    {
+      _init_crc64_tab (crc_tab, dsc->poly.d64);
+    }
+  return crc_tab;
+
+}				/* init_crc64_tab */
+
+/*
+ * uint64_t calc_crc64
+ *   (algorithm_desc_t *dsc, const unsigned char *input_str, size_t num_bytes);
+ *
+ * The function calc_crc64() calculates in one pass the 64 bit CRC value
+ * for a byte string that is passed to the function together with a
+ * parameter indicating the length.
+ * calc_crc64 is
+ *   copyright (c) 2016 Lammert Bies
+ *   copyright (c) 2021 Bastian Molkenthin
+ *   copyright (c) 2023 Ulf Samuelsson
+ */
+uint64_t calc_crc64
+  (algorithm_desc_t * dsc, const unsigned char *input_str, size_t num_bytes)
+{
+  uint64_t crc;
+  const unsigned char *ptr;
+  uint64_t *crc_tab = dsc->crc_tab;
+  uint64_t index;
+
+  if ((ptr = input_str) == NULL)
+    return 0;
+
+  if (crc_tab == NULL)
+    return 0;
+
+
+  crc = dsc->initial.d64;
+  if (dsc->reciprocal)
+    {
+      for (uint32_t i = 0; i < num_bytes; i++)
+	{
+	  index = ((crc >> 0) ^ (uint64_t) * ptr++) & 0x00000000000000FFull;
+	  crc = (crc >> 8) ^ crc_tab[index];
+	}
+    }
+  else
+    {
+      uint32_t shift = SHIFT (uint64_t);
+      for (uint32_t i = 0; i < num_bytes; i++)
+	{
+	  const unsigned char c = *ptr++;
+	  uint64_t rc = (uint64_t) (dsc->ireflect ? reflect8 (c) : c);
+	  crc = (crc ^ (rc << shift));
+	  index = (uint32_t) (crc >> shift);
+	  crc = (crc << 8);
+	  crc = (crc ^ (crc_tab[index]));
+	}
+    }
+  crc = (dsc->oreflect ? reflect64 (crc) : crc);
+  crc = crc ^ dsc->xor_val.d64;
+  return crc;
+}				/* calc_crc64 */
diff --git a/ld/lddigest.c b/ld/lddigest.c
new file mode 100644
index 00000000000..d0bb4db73ab
--- /dev/null
+++ b/ld/lddigest.c
@@ -0,0 +1,903 @@
+/* Linker command language support.
+   Copyright (C) 1991-2023 Ulf Samuelsson <ulf@emagii.com>
+
+   This file is part of the GNU Binutils.
+
+   This program 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 of the License, or
+   (at your option) any later version.
+
+   This program 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 this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#define	DEBUG_CRC	0
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "safe-ctype.h"
+#include "obstack.h"
+#include "bfdlink.h"
+#include "ctf-api.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include <ldgram.h>
+#include "ldlex.h"
+#include "ldmisc.h"
+#include "lddigest.h"
+
+/* CRC calculation on output section */
+asection *text_section;
+unsigned char *text_contents = NULL;
+
+char *CRC_ADDRESS = NULL;
+char *CRC_START = NULL;
+char *CRC_END = NULL;
+char *CRC_TABLE = NULL;
+
+
+
+
+
+const char *digest_section = ".text";
+const char *digest_label = "___CRC_LABEL__";
+bool digest_big_endian = false;
+bool polynome_valid = false;
+
+static bool
+big_endian_host (void)
+{
+  union
+  {
+    uint32_t i;
+    char c[4];
+  } e = { 0x01000000 };
+
+  return e.c[0];
+}
+
+#if     0
+static bool
+swap_endian (void)
+{
+  if (big_endian_host ())
+    {
+      return !link_info.big_endian;
+    }
+  else
+    {
+      return link_info.big_endian;
+    }
+}
+#endif
+
+/* ============ CRC-32 public functions ======================================*/
+
+void
+lang_add_crc32_syndrome (algorithm_desc_t * a)
+{
+  CRC_ADDRESS = CRC32_ADDRESS;
+  CRC_START = CRC32_START;
+  CRC_END = CRC32_END;
+  CRC_TABLE = CRC32_TABLE;
+
+  lang_add_data (LONG, exp_intop (0));	/* Reserve room for the ECC value */
+  a->crc_tab = init_crc32_tab (a);
+  if (a->crc_tab == NULL)
+    {
+      einfo (_("%F%P: can not allocate memory for CRC table: %E\n"));
+      return;
+    }
+}
+
+static void
+lang_add_crc32_table (bool big_endian)
+{
+  uint32_t *crc32_table = algorithm.crc_tab;	/* Use a precomputed, if it exists */
+  bool local_table = false;
+  if (crc32_table == NULL)
+    {				/* No luck, create a table */
+      crc32_table = init_crc32_tab (&algorithm);
+      if (crc32_table == NULL)
+	{
+	  einfo (_("%F%P: can not allocate memory for CRC table: %E\n"));
+	  return;
+	}
+      local_table = true;
+    }
+  for (bfd_vma i = 0; i < 256; i++)
+    {
+      uint32_t elem = crc32_table[i];
+      if (big_endian)
+	{
+	  elem = __builtin_bswap32 (elem);
+	}
+      lang_add_data (LONG, exp_intop (elem));
+    }
+  if (local_table)
+    free (crc32_table);
+}
+
+/* ============ CRC-64 public functions ======================================*/
+
+void
+lang_add_crc64_syndrome (algorithm_desc_t * a)
+{
+  CRC_ADDRESS = CRC64_ADDRESS;
+  CRC_START = CRC64_START;
+  CRC_END = CRC64_END;
+  CRC_TABLE = CRC64_TABLE;
+  lang_add_data (QUAD, exp_intop (0));	/* Reserve room for the ECC value */
+  a->crc_tab = init_crc64_tab (a);
+  if (a->crc_tab == NULL)
+    {
+      einfo (_("%F%P: can not allocate memory for CRC table: %E\n"));
+      return;
+    }
+}
+
+#if (DEBUG_CRC == 1)
+static void
+print_hash64_table (algorithm_desc_t * a)
+{
+  uint64_t *crc_tab = a->crc_tab;
+  uint32_t i;
+  if (crc_tab == NULL)
+    {
+      printf ("%-20ssBad Table\n", a->name);
+      return;
+
+    }
+
+  i = 0;
+  printf ("%03d\t", i);
+  printf ("0x%016lx, ", crc_tab[i + 0]);
+  printf ("0x%016lx, ", crc_tab[i + 1]);
+  printf ("0x%016lx, ", crc_tab[i + 2]);
+  printf ("0x%016lx\n", crc_tab[i + 3]);
+  printf ("\t...\n");
+  i = 252;
+  printf ("%03d\t", i);
+  printf ("0x%016lx, ", crc_tab[i + 0]);
+  printf ("0x%016lx, ", crc_tab[i + 1]);
+  printf ("0x%016lx, ", crc_tab[i + 2]);
+  printf ("0x%016lx\n", crc_tab[i + 3]);
+  printf ("\n");
+}
+#else
+#define print_hash64_table(x)
+#endif
+
+static void
+lang_add_crc64_table (bool big_endian)
+{
+  bfd_vma *crc64_table = algorithm.crc_tab;	/* Use a precomputed, if it exists */
+  bool local_table = false;
+  if (crc64_table == NULL)
+    {				/* No luck, create a table */
+      crc64_table = init_crc64_tab (&algorithm);
+      if (crc64_table == NULL)
+	{
+	  einfo (_("%F%P: can not allocate memory for CRC table: %E\n"));
+	  return;
+	}
+      local_table = true;
+    }
+  print_hash64_table (&algorithm);
+  for (bfd_vma i = 0; i < 256; i++)
+    {
+      bfd_vma elem = crc64_table[i];
+      if (big_endian)
+	{
+	  elem = __builtin_bswap64 (elem);
+	}
+      if (link_info.big_endian)
+	{
+	  elem = __builtin_bswap64 (elem);
+	}
+
+      lang_add_data (QUAD, exp_intop (elem));
+    }
+  if (local_table)
+    free (crc64_table);
+}
+
+/* ============ DIGEST COMMON functions ======================================*/
+
+void
+lang_add_digest (bfd_vma size,
+		 bfd_vma poly,
+		 bfd_vma initial,
+		 bfd_vma xor_val,
+		 bfd_vma ireflect, bfd_vma oreflect, bfd_vma reciprocal)
+{
+  if (algorithm.crc_algo != no_algo)	/* We only allow one CRC <polynom> */
+    {
+      einfo (_("%X%P: Duplicate digest \"%s\"\n"), "in POLY command");
+      return;
+    }
+
+  algorithm.name = "CUSTOM";
+  algorithm.big_endian = digest_big_endian;
+  if (size == 64)
+    {
+      algorithm.crc_algo = crc_algo_64;
+      algorithm.crc_size = size;
+      algorithm.poly.d64 = poly;	/* Set the polynom */
+      algorithm.initial.d64 = initial;	/* Set seed */
+      algorithm.xor_val.d64 = xor_val;	/* final XOR value */
+      algorithm.ireflect = ireflect;
+      algorithm.oreflect = oreflect;
+      algorithm.crc_tab = NULL;
+      algorithm.reciprocal = reciprocal;
+      algorithm.expected.d64 = 0;
+
+      lang_add_crc64_syndrome (&algorithm);
+    }
+  else if (size == 32)
+    {
+      algorithm.crc_algo = crc_algo_32;
+      algorithm.crc_size = size;
+      algorithm.poly.d32._0 = poly;	/* Set the polynom */
+      algorithm.initial.d32._0 = initial;	/* Set seed */
+      algorithm.xor_val.d32._0 = xor_val;	/* final XOR value */
+      algorithm.ireflect = ireflect;
+      algorithm.oreflect = oreflect;
+      algorithm.crc_tab = NULL;
+      algorithm.reciprocal = reciprocal;
+      algorithm.expected.d32._0 = 0;
+      lang_add_crc32_syndrome (&algorithm);
+    }
+  else
+    {
+      einfo (_("%F%P: Illegal Size in DIGEST: %E\n"));
+      return;
+    }
+}
+
+static bool
+id_start_char (char c)
+{
+  bool OK = false;
+  if (('a' <= c) && (c <= 'z'))
+    OK |= true;
+  if (('A' <= c) && (c <= 'Z'))
+    OK |= true;
+  if ('_' == c)
+    OK |= true;
+  if ('-' == c)
+    OK |= true;
+  if ('.' == c)
+    OK |= true;
+  return OK;
+}
+
+static bool
+id_char (char c)
+{
+  bool OK = false;
+  if (('0' <= c) && (c <= '9'))
+    OK |= true;
+  OK |= id_start_char (c);
+  return OK;
+}
+
+const char *
+lang_get_label (const char *label, bool *big_endian)
+{
+  char *newlabel;
+  const char *p = &label[1];
+  char c;
+
+  *big_endian = false;		/* unless told otherwise */
+  if (command_line.endian == ENDIAN_BIG)
+    {
+      *big_endian = true;
+    }
+  if (command_line.endian == ENDIAN_LITTLE)
+    {
+      *big_endian = false;
+    }
+  c = *label;
+
+  if (!id_start_char (c))
+    {
+      einfo (_("%X%P: Illegal label \"%s\" in digest command\n"), label);
+      return "__CRC_LABEL__";
+    }
+
+  for (uint32_t i = 1; *p; i++)	/* ignore '.' in first character */
+    {
+      c = *p;
+      if (c == '#')
+	{
+	  bool bad_endian = false;
+	  newlabel = strndup (label, i);	/* Memory leak */
+	  p++;
+	  if (strlen (p) == 2)
+	    {
+	      char c0 = *p++;
+	      char c1 = *p;
+	      bool be = ((c0 == 'B') || (c0 == 'b')) &
+		((c1 == 'E') || (c1 == 'e'));
+	      bool le = ((c0 == 'L') || (c0 == 'l')) &
+		((c1 == 'E') || (c1 == 'e'));
+	      if (be)
+		{
+		  *big_endian = true;
+		}
+	      else if (le)
+		{
+		  *big_endian = false;
+		}
+	      else
+		{
+		  bad_endian = true;
+		}
+	    }
+	  else
+	    {
+	      bad_endian = true;
+	    }
+	  if (bad_endian)
+	    {
+	      einfo (_("%X%P: bad 'endian' \"%s\" in digest label\n"), label);
+	    }
+	  return newlabel;
+	}
+      else if (!id_char (c))
+	{
+	  einfo (_("%X%P: Illegal label \"%s\" in digest command\n"), label);
+	  return "__CRC_LABEL__";
+	}
+      else
+	{
+	  p++;
+	}
+    }
+  return label;
+}
+
+bool
+lang_set_digest (char *digest)
+{
+  if (algorithm.crc_algo != no_algo)	/* We only allow one CRC <polynom> */
+    {
+      einfo (_("%X%P: Duplicate digest \"%s\"\n"), digest);
+      return false;
+    }
+
+  for (poly_t a = (poly_t) 0; a < MAXALGO; a++)
+    {
+#if (DEBUG_CRC == 1)
+      printf ("Comparing \"%s\" with \"%s\": ", digest, algorithms[a].name);
+#endif
+      if (!strcmp (digest, algorithms[a].name))
+	{
+#if (DEBUG_CRC == 1)
+	  printf ("OK\n");
+#endif
+	  memcpy (&algorithm, &algorithms[a], sizeof (algorithm_desc_t));
+	  algorithm.big_endian = digest_big_endian;
+	  if (algorithm.crc_size == 64)
+	    {
+	      lang_add_crc64_syndrome (&algorithm);
+	    }
+	  else if (algorithm.crc_size == 32)
+	    {
+	      lang_add_crc32_syndrome (&algorithm);
+	    }
+
+	  return true;
+	}
+#if (DEBUG_CRC == 1)
+      else
+	{
+	  printf ("FAIL\n");
+	}
+#endif
+    }
+  einfo (_("%X%P: Unknown digest \"%s\"\n"), digest);
+  return false;
+}
+
+void
+lang_add_digest_table (bool big_endian)
+{
+  if (algorithm.crc_algo == crc_algo_32)
+    {
+      lang_add_crc32_table (big_endian);
+    }
+  else if (algorithm.crc_algo == crc_algo_64)
+    {
+      lang_add_crc64_table (big_endian);
+    }
+}
+
+/* ============ CRC DEBUG functions ==========================================*/
+
+#if (DEBUG_CRC == 1)
+static void
+debug_hex (char *prompt, unsigned char *section, bfd_vma address, bfd_vma sz)
+{
+  bfd_vma *vma_section = (bfd_vma *) section;
+  bfd_vma size = (sz) / sizeof (bfd_vma);
+  printf ("%s:\n", prompt);
+  for (bfd_vma i = 0; i < size; i += 8)
+    {
+      printf ("0x%08lx: 0x%016lx 0x%016lx 0x%016lx 0x%016lx\n",
+	      address + (i * sizeof (bfd_vma)),
+	      vma_section[i + 0],
+	      vma_section[i + 1], vma_section[i + 2], vma_section[i + 3]);
+    }
+}
+
+static void
+debug_crc_header (char *prompt)
+{
+  debug_hex (prompt, text_contents, text_section->vma, 64);
+}
+
+static void
+debug_crc_update (bfd_vma crc, bfd_vma crc_addr)
+{
+  printf ("CRC [0x%016lx] update at 0x%08lx succeeded\n", crc, crc_addr);
+}
+
+static bool get_text_section_contents (void);
+static void
+debug_full_textsection (void)
+{
+
+  /* In order to see the updated content, we have to fetch it again */
+
+  if (!get_text_section_contents ())
+    {
+      debug_crc_header ("After CRC");
+      debug_hex ("Full Section After CRC",
+		 text_contents, text_section->vma, text_section->size);
+      free (text_contents);
+    }
+}
+
+
+static void
+print_crc64_algorithm (algorithm_desc_t * a, const unsigned char *crc_data,
+		       uint64_t crc)
+{
+  printf ("64:%-16s, data=\"%s\", ", a->name, crc_data);
+  printf ("poly=0x%016lx i=0x%1x xor=0x%1x .ir=%u .or=%u .rp=%u ",
+	  a->poly.d64,
+	  a->initial.d32._0 & 0xF,
+	  a->xor_val.d32._0 & 0xF, a->ireflect, a->oreflect, a->reciprocal);
+  printf ("checksum=0x%016lx, expected=0x%016lx\n", crc, a->expected.d64);
+}
+
+static void
+print_section (asection * a)
+{
+  uint32_t len = strlen (a->name);
+  char *name = malloc (len + 4);
+  char *p = name;
+  if (p != NULL)
+    {
+      *p++ = '"';
+      for (uint32_t i = 0; i < len; i++)
+	{
+	  *p++ = a->name[i];
+	}
+      *p++ = '"';
+      *p++ = ':';
+      *p++ = '\0';
+    }
+  else
+    {
+      p = "\"?\"";
+    }
+  printf ("%-20s [0x%08lx .. 0x%08lx]\n", name, a->lma, a->lma + a->size - 1);
+  free (name);
+}
+
+static void
+print_section_list (void)
+{
+  bfd *list = link_info.output_bfd;
+  asection *elem;
+  if (strcmp (digest_section, ".foo"))
+    return;
+
+  for (elem = list->sections; elem != NULL; elem = elem->next)
+    {
+      if (elem->name != NULL)
+	{
+	  print_section (elem);
+	}
+    }
+}
+
+#else
+#define	debug_hex(p,s,a,sz)
+#define debug_crc_header(p)
+#define debug_crc_update(c, a)
+#define debug_full_textsection()
+#define print_section(a)
+#define print_section_list()
+#endif
+
+/* ============ Access functions for inserting checksum in text section=======*/
+
+static bool
+get_section_by_address (bfd_vma addr)
+{
+  bfd *list = link_info.output_bfd;
+  for (asection * elem = list->sections; elem != NULL; elem = elem->next)
+    {
+      bfd_vma lma = elem->lma;
+      bfd_vma end = lma + elem->size;
+
+      if ((addr >= lma) && (addr < end))
+	{
+	  digest_section = elem->name;
+	  return true;
+	}
+    }
+  return false;
+}
+
+static bool
+get_text_section_contents (void)
+{
+  /*
+   * Get the '.text' section
+   * Is there a risk that CRC needs to be calculated on more than .text?
+   * We do not support that...
+   */
+  print_section_list ();
+
+  text_section =
+    bfd_get_section_by_name (link_info.output_bfd, digest_section);
+  if (text_section == NULL)
+    {
+      einfo (_("%X%P: cannot retrieve '%s' section for CRC calculation\n"),
+	     digest_section);
+      return false;
+    }
+
+  /* Get the contents of the '.text' area so we can calculate the CRC */
+  if (!bfd_malloc_and_get_section (link_info.output_bfd,
+				   text_section->output_section,
+				   (bfd_byte **) & text_contents))
+    {
+      einfo (_("%X%P: '&s' section contents unavailable\n"
+	       "CRC generation aborted\n"), digest_section);
+      return false;
+    }
+
+#if (DEBUG_CRC == 1)
+  print_section (text_section);
+/*
+  printf ("%s: [0x%08lx .. 0x%08lx]\n",
+	  text_section->name,
+	  text_section->lma, text_section->lma + text_section->size - 1);
+ */
+#endif
+  return true;
+}
+
+/* Set variable in the '.text' area */
+static bool
+set_crc32_checksum (uint32_t crc, bfd_vma addr)
+{
+  uint32_t real_crc = crc;
+  if (big_endian_host ())
+    {
+      if (algorithm.big_endian)
+	{
+	  /* We are OK */
+	}
+      else
+	{
+	  real_crc = __builtin_bswap32 (crc);
+	}
+    }
+  else
+    {
+      if (algorithm.big_endian)
+	{
+	  real_crc = __builtin_bswap32 (crc);
+	}
+      else
+	{
+	  /* We are OK */
+	}
+    }
+
+  return (bfd_set_section_contents (link_info.output_bfd,
+				    text_section->output_section,
+				    &real_crc, addr, sizeof (uint32_t)));
+}
+
+static bool
+set_crc64_checksum (uint64_t crc, bfd_vma addr)
+{
+  uint64_t real_crc = crc;
+  if (big_endian_host ())
+    {
+      if (algorithm.big_endian)
+	{
+	  /* We are OK */
+	}
+      else
+	{
+	  real_crc = __builtin_bswap64 (crc);
+	}
+    }
+  else
+    {
+      if (algorithm.big_endian)
+	{
+	  real_crc = __builtin_bswap64 (crc);
+	}
+      else
+	{
+	  /* We are OK */
+	}
+    }
+  /* True if OK */
+  return (bfd_set_section_contents (link_info.output_bfd,
+				    text_section->output_section,
+				    &real_crc, addr, sizeof (uint64_t)));
+}
+
+static bool
+set_crc_checksum (bfd_vma crc, bfd_vma addr, bfd_vma size)
+{
+  bool status;
+  if (size == 64)
+    {
+      status = set_crc64_checksum (crc, addr);
+    }
+  else
+    {
+      status = set_crc32_checksum ((uint32_t) crc, addr);
+    }
+  return status;
+}
+
+static bool
+symbol_lookup (char *name, bfd_vma * val)
+{
+  struct bfd_link_hash_entry *h;
+  *val = 0ull;
+  h = bfd_link_hash_lookup (link_info.hash, name, false, false, true);
+  if (h != NULL)
+    {
+      if (((h->type == bfd_link_hash_defined) ||
+	   (h->type == bfd_link_hash_defweak)) &&
+	  (h->u.def.section->output_section != NULL))
+	{
+	  *val = (h->u.def.value
+		  + bfd_section_vma (h->u.def.section->output_section)
+		  + h->u.def.section->output_offset);
+	  return true;
+	}
+    }
+  return false;
+}
+
+/* ============ CRC common functions =========================================*/
+/*
+ * Multiplexing function for calculating CRC with different algorithms
+ * 'algorithm.crc_algo'
+ */
+static bfd_vma
+calculate_crc (const unsigned char *input_str, size_t num_bytes)
+{
+  if (algorithm.crc_algo == crc_algo_64)
+    {
+      if (algorithm.crc_tab != NULL)
+	{
+	  return calc_crc64 (&algorithm, input_str, num_bytes);
+	}
+    }
+  else if (algorithm.crc_algo == crc_algo_32)
+    {
+      if (algorithm.crc_tab != NULL)
+	{
+	  return calc_crc32 (&algorithm, input_str, num_bytes);
+	}
+    }
+  /* This should never happen */
+  return 0;
+}
+
+static bool
+invalid_crc_parameters (bfd_vma crc_addr,
+			bfd_vma crc_area_start, bfd_vma crc_area_end)
+{
+  bool crc_in_section;
+  bfd_vma crc_size = algorithm.crc_size / 8;
+  /* Get limits of '.text' section */
+  bfd_vma text_start = text_section->lma;
+  bfd_vma text_end = text_section->lma + text_section->size;
+
+  /* All three symbols must be inside the '.text' section */
+  crc_in_section =
+    ((crc_addr >= text_start) && ((crc_addr + crc_size) <= text_end)) &&
+    ((crc_area_start >= text_start) && (crc_area_start <= text_end)) &&
+    ((crc_area_end >= text_start) && (crc_area_end <= text_end));
+
+  if (!crc_in_section)
+    {
+      einfo (_("%X%P: The CRC digest and table should be inside the '%s' "
+	       "section\n"), digest_section);
+      /*
+       * Maybe we should printout the text section start and end
+       * as well as the boundaries of the CRC check area.
+       */
+      return true;
+    }
+
+  /*
+   * CRC checksum must be outside the checked area
+   * We must check that they do not overlap in the beginning
+   */
+  {
+    bool crc_valid = false;
+    if ((crc_addr + crc_size) < crc_area_start)
+      {
+	crc_valid = true;
+      }
+    else if (crc_addr >= crc_area_end)
+      {
+	crc_valid = true;
+      }
+    if (!crc_valid)
+      {
+	einfo (_("%X%P: CRC located inside checked area\n"), NULL);
+	return true;
+      }
+  }
+
+  if (crc_area_start > crc_area_end)
+    {
+      einfo (_("%X%P: CRC area starts after its end location\n"), NULL);
+      return true;
+    }
+
+  return false;
+}
+
+void
+lang_generate_crc (void)
+{
+  bfd_vma crc_addr, crc_area_start, crc_area_end;
+  bfd_vma crc;
+  bool can_do_crc;
+
+  /* Return immediately, if CRC is not requested */
+  if (algorithm.crc_algo == no_algo)
+    return;
+
+  /*
+   * These symbols must be present, for CRC to be generated
+   * They should all have been defined in a CRC## <syndrome> statement
+   * If they are not defined, then there is an internal error.
+   * Should we consider using symbols which cannot be parsed by the linker?
+   * I.E. CRC-64 is never an identifier
+   */
+  can_do_crc = symbol_lookup (CRC_ADDRESS, &crc_addr) &&
+    symbol_lookup (CRC_START, &crc_area_start) &&
+    symbol_lookup (CRC_END, &crc_area_end);
+
+  if (!can_do_crc)
+    {
+      einfo (_("%X%P: Internal Error - __CRC#___ symbols not defined\n"),
+	     NULL);
+      return;
+    }
+
+  if (!get_section_by_address (crc_addr))	/* update digest_section, if needed */
+    {
+      einfo (_("%X%P: The CRC digest and table must be inside the '%s' "
+	       "section\n"), digest_section);
+    }
+
+  if (!get_text_section_contents ())
+    {
+      /* Error messages inside check */
+      return;
+    }
+
+  /* Check that the addresses make sense */
+  if (invalid_crc_parameters (crc_addr, crc_area_start, crc_area_end))
+    {
+      /* Error messages inside check */
+      return;
+    }
+
+  /* Calculate and set the CRC */
+  {
+    /*
+     * The '.text' area does not neccessarily start at 0x00000000,
+     * so we have to shift the indices.
+     */
+    bfd_vma _crc_addr = crc_addr - text_section->vma;
+    bfd_vma _crc_area_start = crc_area_start - text_section->vma;
+    bfd_vma _crc_area_end = crc_area_end - text_section->vma;
+
+
+    /* This is the CRC calculation which we worked so hard for */
+    debug_crc_header ("Before CRC");
+
+    print_hash64_table (&algorithm);
+
+#if (DEBUG_CRC == 1)
+    crc = calculate_crc ((const unsigned char *) "123456789", 9);
+#else
+    crc = calculate_crc (&text_contents[_crc_area_start],
+			 _crc_area_end - _crc_area_start);
+#endif
+
+#if (DEBUG_CRC == 1)
+    printf ("size  = 0x%08u\n", (uint32_t) (_crc_area_end - _crc_area_start));
+    printf ("start = 0x%016lx\n", _crc_area_start);
+    printf ("end   = 0x%016lx\n", _crc_area_end);
+    printf ("crc   = 0x%016lx\n", crc);
+
+    print_crc64_algorithm (&algorithm, &text_contents[_crc_area_start], crc);
+#endif
+
+    /*
+     * The contents of the '.text' section are no longer needed.
+     * It is a copy of the section contents, and will therefore be stale
+     * after we updated the section with the CRC checksum.
+     * Remove it before we set the CRC checksum, to simplify the code logic.
+     */
+    free (text_contents);
+    if (set_crc_checksum (crc, _crc_addr, algorithm.crc_size))
+      {
+	debug_crc_update (crc, crc_addr);
+      }
+    else
+      {
+	einfo (_("%X%P: updating CRC in section '%s' failed\n"),
+	       digest_section);
+      }
+  }
+
+  debug_full_textsection ();
+}
+
+/* ============ END CRC common functions =====================================*/
+
+void
+lang_generate_digest (void)
+{
+  /* Return immediately, if CRC is not requested */
+#if (DEBUG_CRC == 1)
+  printf ("%s: BEGIN\n", __FUNCTION__);
+#endif
+  if (algorithm.crc_algo == no_algo)
+    return;
+
+  /* Handle 32/64-bit CRCs */
+  if ((algorithm.crc_algo == crc_algo_32)
+      || (algorithm.crc_algo == crc_algo_64))
+    {
+      lang_generate_crc ();
+    }
+#if (DEBUG_CRC == 1)
+  printf ("%s: END\n", __FUNCTION__);
+#endif
+}
diff --git a/ld/lddigest.h b/ld/lddigest.h
new file mode 100755
index 00000000000..9f5e5f3fbda
--- /dev/null
+++ b/ld/lddigest.h
@@ -0,0 +1,183 @@
+/*
+ * Library: libcrc
+ * Author:  Lammert Bies, Ulf Samuelsson
+ *
+ * This file is licensed under the MIT License as stated below
+ *
+ * Copyright (c) 2016 Lammert Bies
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef LDDIGEST_H
+#define LDDIGEST_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "bfd.h"
+
+#define	CRC_POLY_64_ECMA	0x42F0E1EBA9EA3693ull	/* Normal */
+#define	CRC_POLY_64_ECMA_EXP	0x6C40DF5F0B497347ull	/* CRC when testing "123456789" */
+#define	CRC_POLY_64_ECMA_R	0xC96C5795D7870F42ull	/* Reversed */
+
+#define	CRC_POLY_64_ISO		0x000000000000001Bull	/* Normal */
+#define	CRC_POLY_64_ISO_EXP	0xB90956C775A41001ull	/* CRC when testing "123456789" */
+#define	CRC_POLY_64_ISO_R	0xD800000000000000ull	/* Reversed */
+
+#define	CRC_POLY_64_WE		0x42F0E1EBA9EA3693ull	/* Normal */
+#define	CRC_POLY_64_WE_EXP	0x62EC59E3F1A4F00Aull	/* CRC when testing "123456789" */
+
+#define	CRC_POLY_64_XZ		0x42F0E1EBA9EA3693ull	/* Normal */
+#define	CRC_POLY_64_XZ_EXP	0x995DC9BBDF1939FAull	/* CRC when testing "123456789" */
+
+#define	CRC_START_64		0x0000000000000000ull
+#define	CRC_START_64_ECMA	0x0000000000000000ull
+#define	CRC_START_64_WE		0xFFFFFFFFFFFFFFFFull
+#define	CRC_START_64_INV	0xFFFFFFFFFFFFFFFFull
+#define	CRC_END_64		0x0000000000000000ull
+#define	CRC_END_64_INV		0xFFFFFFFFFFFFFFFFull
+
+#define	CRC_START_32		0xFFFFFFFFul
+#define	CRC_END_32		0xFFFFFFFFul
+
+#define	CRC64_ADDRESS		"___CRC64___"
+#define	CRC64_START		"___CRC64_START___"
+#define	CRC64_END		"___CRC64_END___"
+#define	CRC64_TABLE		"___CRC64_TABLE___"
+
+#define	CRC_POLY_32		0x04C11DB7ul	/* Normal */
+#define	CRC_POLY_32_R		0xEDB88320ul	/* Reversed */
+
+#define	CRC_START_32_INV	0xFFFFFFFFul
+#define	CRC_END_32_INV    0xFFFFFFFFul
+
+#define	CRC32_ADDRESS		"___CRC32___"
+#define	CRC32_START		"___CRC32_START___"
+#define	CRC32_END		"___CRC32_END___"
+#define	CRC32_TABLE		"___CRC32_TABLE___"
+
+typedef enum algorithm
+{
+  no_algo = 0,
+  sha_algo_1 = 1,
+  crc_algo_32 = 4,
+  crc_algo_64 = 8,
+  sha_algo_256 = 256,
+  sha_algo_512
+} algo_t;
+
+typedef enum
+{
+  CRC64_ECMA,
+  CRC64_WE,
+  CRC64_XZ,
+  CRC64_ISO,
+  CRC64_ISO_R,
+  CRC32,
+  MAXALGO
+} poly_t;
+
+typedef struct
+{
+  uint8_t _0;
+  uint8_t _1;
+  uint8_t _2;
+  uint8_t _3;
+  uint8_t _4;
+  uint8_t _5;
+  uint8_t _6;
+  uint8_t _7;
+} uint8_ut;
+
+typedef struct
+{
+  uint16_t _0;
+  uint16_t _1;
+  uint16_t _2;
+  uint16_t _3;
+} uint16_ut;
+
+typedef struct
+{
+  uint32_t _0;
+  uint32_t _1;
+} uint32_ut;
+
+typedef union
+{
+  uint64_t d64;
+  uint32_ut d32;
+  uint16_ut d16;
+  uint8_ut d8;
+} int_t;
+
+typedef struct
+{
+  algo_t crc_algo;
+  uint32_t crc_size;
+  const char *name;
+  int_t poly;
+  int_t initial;
+  int_t xor_val;
+  bool ireflect;
+  bool oreflect;
+  bool reciprocal;
+  void *crc_tab;
+  int_t expected;
+  bool big_endian;
+} algorithm_desc_t;
+
+extern char *CRC_ADDRESS;
+extern char *CRC_START;
+extern char *CRC_END;
+extern char *CRC_TABLE;
+extern const algorithm_desc_t algorithms[];
+extern algorithm_desc_t algorithm;
+
+extern const char *digest_label;
+extern bool digest_big_endian;
+extern bool polynome_valid;
+
+/* CRC-32 */
+extern uint32_t *init_crc32_tab (algorithm_desc_t * dsc);
+extern uint32_t calc_crc32
+  (algorithm_desc_t * dsc, const unsigned char *input_str, size_t num_bytes);
+extern void lang_add_crc32_syndrome (algorithm_desc_t * a);
+
+/* CR-64 */
+extern bfd_vma *init_crc64_tab (algorithm_desc_t * dsc);
+extern bfd_vma calc_crc64
+  (algorithm_desc_t * dsc, const unsigned char *input_str, size_t num_bytes);
+extern void lang_add_crc64_syndrome (algorithm_desc_t * a);
+
+extern void lang_add_digest (bfd_vma size,
+			     bfd_vma poly,
+			     bfd_vma initial,
+			     bfd_vma xor_val,
+			     bfd_vma ireflect,
+			     bfd_vma oreflect, bfd_vma reciprocal);
+extern bool lang_set_digest (char *digest);
+extern void lang_add_digest_table (bool big_endian);
+extern const char *lang_get_label (const char *label, bool *big_endian);
+extern void lang_generate_crc (void);
+extern void lang_generate_digest (void);
+
+#endif /* LDDIGEST_H */
diff --git a/ld/lddigest_tab.c b/ld/lddigest_tab.c
new file mode 100644
index 00000000000..4f5db10c997
--- /dev/null
+++ b/ld/lddigest_tab.c
@@ -0,0 +1,136 @@
+/* Linker command language support.
+   Copyright (C) 1991-2023 Ulf Samuelsson <ulf@emagii.com>
+
+   This file is part of the GNU Binutils.
+
+   This program 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 of the License, or
+   (at your option) any later version.
+
+   This program 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 this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "safe-ctype.h"
+#include "obstack.h"
+#include "bfdlink.h"
+#include "ctf-api.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include <ldgram.h>
+#include "ldlex.h"
+#include "ldmisc.h"
+#include "lddigest.h"
+
+const algorithm_desc_t algorithms[MAXALGO+1] =
+{
+  [CRC64_ECMA] =
+	{
+		crc_algo_64, 64, "CRC64-ECMA",
+		.poly.d64 = CRC_POLY_64_ECMA,
+		.initial.d64 = CRC_START_64,
+		.xor_val.d64 = CRC_END_64,
+		.ireflect = false,
+		.oreflect = false,
+		.reciprocal = false,
+		.crc_tab = NULL,
+		.expected.d64 = 0x6c40df5f0b497347
+	},
+  [CRC64_WE] =
+	{
+		crc_algo_64, 64, "CRC64-WE",
+		.poly.d64 = CRC_POLY_64_WE,
+		.initial.d64 = CRC_START_64_INV,
+		.xor_val.d64 = CRC_END_64_INV,
+		.ireflect = false,
+		.oreflect = false,
+		.reciprocal = false,
+		.crc_tab = NULL,
+		.expected.d64 = 0x62ec59e3f1a4f00a
+	},
+  [CRC64_XZ] =
+	{
+		crc_algo_64, 64, "CRC64-XZ",
+		.poly.d64 = CRC_POLY_64_XZ,
+		.initial.d64 = CRC_START_64_INV,
+		.xor_val.d64 = CRC_END_64_INV,
+		.ireflect = true,
+		.oreflect = true,
+		.reciprocal = false,
+		.crc_tab = NULL,
+		.expected.d64 = 0x995dc9bbdf1939fa
+	},
+  [CRC64_ISO] =
+	{
+		crc_algo_64, 64, "CRC64-GO-ISO",
+		.poly.d64 = CRC_POLY_64_ISO,
+		.initial.d64 = CRC_START_64_INV,
+		.xor_val.d64 = CRC_END_64_INV,
+		.ireflect = true,
+		.oreflect = true,
+		.reciprocal = false,
+		.crc_tab = NULL,
+		.expected.d64 = 0xb90956c775a41001
+	},
+  [CRC64_ISO_R] =
+	{
+		crc_algo_64, 64, "CRC64-GO-ISO-R",
+		.poly.d64 = CRC_POLY_64_ISO,
+		.initial.d64 = CRC_START_64_INV,
+		.xor_val.d64 = CRC_END_64_INV,
+		.ireflect = false,
+		.oreflect = false,
+		.reciprocal = true,
+		.crc_tab = NULL,
+		.expected.d64 = 0xb90956c775a41001
+	},
+  [CRC32] =
+	{
+		crc_algo_32, 32, "CRC32",
+		.poly.d32._0 = CRC_POLY_32,
+		.initial.d64 = CRC_START_32_INV,
+		.xor_val.d32._0 = CRC_END_32_INV,
+		.ireflect = true,
+		.oreflect = true,
+		.reciprocal = false,
+		.crc_tab = NULL,
+		.expected.d64 = 0xCBF43926
+	},
+  [MAXALGO] =
+	{
+		no_algo, 0, "",
+		.poly.d64 = 0,
+		.initial.d64 = 0,
+		.xor_val.d64 = 0,
+		.ireflect = false,
+		.oreflect = false,
+		.reciprocal = false,
+		.crc_tab = NULL,
+		.expected.d64 = 0
+	}
+};
+
+algorithm_desc_t algorithm =
+{
+		no_algo, 0, "",
+		.poly.d64 = 0,
+		.initial.d64 = 0,
+		.xor_val.d64 = 0,
+		.ireflect = false,
+		.oreflect = false,
+		.reciprocal = false,
+		.crc_tab = NULL,
+		.expected.d64 = 0
+};
diff --git a/ld/ldreflect.c b/ld/ldreflect.c
new file mode 100644
index 00000000000..0601e2a8c1b
--- /dev/null
+++ b/ld/ldreflect.c
@@ -0,0 +1,99 @@
+/* Linker command language support.
+   Copyright (C) 1991-2023 Ulf Samuelsson <ulf@emagii.com>
+
+   This file is part of the GNU Binutils.
+
+   This program 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 of the License, or
+   (at your option) any later version.
+
+   This program 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 this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include "ldreflect.h"
+
+uint8_t reflect_tab[256] = {
+  0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
+  0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
+  0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+  0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
+  0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+  0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
+  0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
+  0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+  0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+  0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+  0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
+  0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
+  0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+  0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+  0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
+  0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
+  0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+  0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+  0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+  0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
+  0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+  0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
+  0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+  0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+  0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
+  0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
+  0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+};
+
+uint8_t
+reflect8 (uint8_t val)
+{
+  return reflect_tab[val];
+}
+
+uint16_t
+reflect16 (uint16_t val)
+{
+  uint16_t result;
+  result = ((uint16_t) reflect_tab[(val >> 0) & 0xFF]) << 8;
+  result |= ((uint16_t) reflect_tab[(val >> 8) & 0xFF]) << 0;
+  return result;
+}
+
+uint32_t
+reflect32 (uint32_t val)
+{
+  uint32_t result;
+  result = ((uint32_t) reflect_tab[(val >> 0) & 0xFF]) << 24;
+  result |= ((uint32_t) reflect_tab[(val >> 8) & 0xFF]) << 16;
+  result |= ((uint32_t) reflect_tab[(val >> 16) & 0xFF]) << 8;
+  result |= ((uint32_t) reflect_tab[(val >> 24) & 0xFF]) << 0;
+  return result;
+}
+
+uint64_t
+reflect64 (uint64_t val)
+{
+  uint64_t result;
+  result = ((uint64_t) reflect_tab[(val >> 0) & 0xFF]) << 56;
+  result |= ((uint64_t) reflect_tab[(val >> 8) & 0xFF]) << 48;
+  result |= ((uint64_t) reflect_tab[(val >> 16) & 0xFF]) << 40;
+  result |= ((uint64_t) reflect_tab[(val >> 24) & 0xFF]) << 32;
+  result |= ((uint64_t) reflect_tab[(val >> 32) & 0xFF]) << 24;
+  result |= ((uint64_t) reflect_tab[(val >> 40) & 0xFF]) << 16;
+  result |= ((uint64_t) reflect_tab[(val >> 48) & 0xFF]) << 8;
+  result |= ((uint64_t) reflect_tab[(val >> 56) & 0xFF]) << 0;
+  return result;
+}
diff --git a/ld/ldreflect.h b/ld/ldreflect.h
new file mode 100644
index 00000000000..a3f834d0acc
--- /dev/null
+++ b/ld/ldreflect.h
@@ -0,0 +1,37 @@
+/*
+ * File:    reflect.h
+ * Author:  Ulf Samuelsson <ulf@emagii.com>
+ *
+ * This file is licensed under the MIT License as stated below
+ *
+ * Copyright (c) 2013 Ulf Samuelsson (ulf@emagii.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#ifndef REFLECT_H
+#define REFLECT_H
+
+uint8_t reflect8 (uint8_t val);
+uint16_t reflect16 (uint16_t val);
+uint32_t reflect32 (uint32_t val);
+uint64_t reflect64 (uint64_t val);
+
+#endif /* REFLECT_H */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v12 10/11] DIGEST: Makefile.*
  2023-03-06 13:31 [PATCH v12 0/11 Add support for CRC64 generation in linker binutils
                   ` (8 preceding siblings ...)
  2023-03-06 13:31 ` [PATCH v12 09/11] DIGEST: calculation binutils
@ 2023-03-06 13:31 ` binutils
  2023-03-06 13:31 ` [PATCH v12 11/11] Build ldint binutils
  2023-03-07 13:59 ` [PATCH v12 0/11 Add support for CRC64 generation in linker Nick Clifton
  11 siblings, 0 replies; 22+ messages in thread
From: binutils @ 2023-03-06 13:31 UTC (permalink / raw)
  To: binutils; +Cc: nickc, Ulf Samuelsson

From: Ulf Samuelsson <ulf@emagii.com>

The Makefile.in was generated using automake
after adding a few files.

When adding the ldreflect.* files, the autotools
versions were wrong.
After upgrading the host OS, autotools were upgraded to 2.71
reinstalling the desired 2.69 still generates a lot of changes.

Makefile.ini has therefore been manually edited.

Signed-off-by: Ulf Samuelsson <ulf@emagii.com>
---
 ld/Makefile.am |  5 +++++
 ld/Makefile.in | 13 +++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/ld/Makefile.am b/ld/Makefile.am
index 760225c5b88..813f19b354a 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -479,12 +479,14 @@ CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \
 	ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \
 	mri.c ldcref.c pe-dll.c pep-dll.c ldlex-wrapper.c \
 	plugin.c ldbuildid.c ldelf.c ldelfgen.c \
+	lddigest.c lddigest_tab.c ldcrc32.c ldcrc64.c ldreflect.c \
 	pdb.c
 
 HFILES = ld.h ldctor.h ldemul.h ldexp.h ldfile.h \
 	ldlang.h ldlex.h ldmain.h ldmisc.h ldver.h \
 	ldwrite.h mri.h deffile.h pe-dll.h pep-dll.h \
 	elf-hints-local.h plugin.h ldbuildid.h ldelf.h ldelfgen.h \
+	lddigest.h ldreflect.h \
 	pdb.h
 
 GENERATED_CFILES = ldgram.c ldlex.c deffilep.c
@@ -495,6 +497,8 @@ GENERATED_HFILES = ldgram.h ldemul-list.h deffilep.h
 BUILT_SOURCES = $(GENERATED_HFILES)
 
 OFILES = ldgram.@OBJEXT@ ldlex-wrapper.@OBJEXT@ lexsup.@OBJEXT@ ldlang.@OBJEXT@ \
+	lddigest.@OBJEXT@ lddigest_tab.@OBJEXT@ \
+	ldcrc32.@OBJEXT@ ldcrc64.@OBJEXT@ ldreflect.@OBJEXT@ \
 	mri.@OBJEXT@ ldctor.@OBJEXT@ ldmain.@OBJEXT@ plugin.@OBJEXT@ \
 	ldwrite.@OBJEXT@ ldexp.@OBJEXT@  ldemul.@OBJEXT@ ldver.@OBJEXT@ ldmisc.@OBJEXT@ \
 	ldfile.@OBJEXT@ ldcref.@OBJEXT@ ${EMULATION_OFILES} ${EMUL_EXTRA_OFILES} \
@@ -962,6 +966,7 @@ EXTRA_ld_new_SOURCES = deffilep.y ldlex.l
 EXTRA_ld_new_SOURCES += ldelf.c ldelfgen.c pdb.c pep-dll.c pe-dll.c
 
 ld_new_SOURCES = ldgram.y ldlex-wrapper.c lexsup.c ldlang.c mri.c ldctor.c ldmain.c \
+	lddigest.c lddigest_tab.c ldcrc32.c ldcrc64.c ldreflect.c \
 	ldwrite.c ldexp.c ldemul.c ldver.c ldmisc.c ldfile.c ldcref.c plugin.c \
 	ldbuildid.c
 ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) \
diff --git a/ld/Makefile.in b/ld/Makefile.in
index d4dddf2f629..6ec916aa629 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -210,6 +210,8 @@ PROGRAMS = $(bin_PROGRAMS)
 am_ld_new_OBJECTS = ldgram.$(OBJEXT) ldlex-wrapper.$(OBJEXT) \
 	lexsup.$(OBJEXT) ldlang.$(OBJEXT) mri.$(OBJEXT) \
 	ldctor.$(OBJEXT) ldmain.$(OBJEXT) ldwrite.$(OBJEXT) \
+	lddigest.$(OBJEXT) lddigest_tab.$(OBJEXT) \
+	ldcrc32.$(OBJEXT) ldcrc64.$(OBJEXT) ldreflect.$(OBJEXT) \
 	ldexp.$(OBJEXT) ldemul.$(OBJEXT) ldver.$(OBJEXT) \
 	ldmisc.$(OBJEXT) ldfile.$(OBJEXT) ldcref.$(OBJEXT) \
 	plugin.$(OBJEXT) ldbuildid.$(OBJEXT)
@@ -533,6 +535,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -978,12 +981,14 @@ CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \
 	ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \
 	mri.c ldcref.c pe-dll.c pep-dll.c ldlex-wrapper.c \
 	plugin.c ldbuildid.c ldelf.c ldelfgen.c \
+	lddigest.c lddigest_tab.c ldcrc32.c ldcrc64.c ldreflect.c \
 	pdb.c
 
 HFILES = ld.h ldctor.h ldemul.h ldexp.h ldfile.h \
 	ldlang.h ldlex.h ldmain.h ldmisc.h ldver.h \
 	ldwrite.h mri.h deffile.h pe-dll.h pep-dll.h \
 	elf-hints-local.h plugin.h ldbuildid.h ldelf.h ldelfgen.h \
+	lddigest.h ldreflect.h \
 	pdb.h
 
 GENERATED_CFILES = ldgram.c ldlex.c deffilep.c
@@ -993,6 +998,8 @@ GENERATED_HFILES = ldgram.h ldemul-list.h deffilep.h
 # tracking will not cause them to be built beforehand.
 BUILT_SOURCES = $(GENERATED_HFILES)
 OFILES = ldgram.@OBJEXT@ ldlex-wrapper.@OBJEXT@ lexsup.@OBJEXT@ ldlang.@OBJEXT@ \
+	lddigest.@OBJEXT@ lddigest_tab.@OBJEXT@ \
+	ldcrc32.@OBJEXT@ ldcrc64.@OBJEXT@ ldreflect.@OBJEXT@ \
 	mri.@OBJEXT@ ldctor.@OBJEXT@ ldmain.@OBJEXT@ plugin.@OBJEXT@ \
 	ldwrite.@OBJEXT@ ldexp.@OBJEXT@  ldemul.@OBJEXT@ ldver.@OBJEXT@ ldmisc.@OBJEXT@ \
 	ldfile.@OBJEXT@ ldcref.@OBJEXT@ ${EMULATION_OFILES} ${EMUL_EXTRA_OFILES} \
@@ -1014,6 +1021,7 @@ EXTRA_ld_new_SOURCES = deffilep.y ldlex.l ldelf.c ldelfgen.c pdb.c \
 	pep-dll.c pe-dll.c $(ALL_EMULATION_SOURCES) \
 	$(ALL_64_EMULATION_SOURCES)
 ld_new_SOURCES = ldgram.y ldlex-wrapper.c lexsup.c ldlang.c mri.c ldctor.c ldmain.c \
+	lddigest.c lddigest_tab.c ldcrc32.c ldcrc64.c ldreflect.c \
 	ldwrite.c ldexp.c ldemul.c ldver.c ldmisc.c ldfile.c ldcref.c plugin.c \
 	ldbuildid.c
 
@@ -1560,8 +1568,12 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez8001.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ez8002.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldbuildid.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldcrc32.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldcrc64.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldcref.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldctor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lddigest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lddigest_tab.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldelf.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldelfgen.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldemul.Po@am__quote@
@@ -1573,6 +1585,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldlex.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldmain.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldmisc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldreflect.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldver.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldwrite.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lexsup.Po@am__quote@
-- 
2.34.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v12 11/11] Build ldint
  2023-03-06 13:31 [PATCH v12 0/11 Add support for CRC64 generation in linker binutils
                   ` (9 preceding siblings ...)
  2023-03-06 13:31 ` [PATCH v12 10/11] DIGEST: Makefile.* binutils
@ 2023-03-06 13:31 ` binutils
  2023-03-07 13:59 ` [PATCH v12 0/11 Add support for CRC64 generation in linker Nick Clifton
  11 siblings, 0 replies; 22+ messages in thread
From: binutils @ 2023-03-06 13:31 UTC (permalink / raw)
  To: binutils; +Cc: nickc, Ulf Samuelsson

From: Ulf Samuelsson <ulf@emagii.com>

Signed-off-by: Ulf Samuelsson <ulf@emagii.com>
---
 ld/Makefile.am | 16 +++++++++++++--
 ld/Makefile.in | 53 ++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 61 insertions(+), 8 deletions(-)

diff --git a/ld/Makefile.am b/ld/Makefile.am
index 813f19b354a..00118f8da13 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -128,7 +128,7 @@ CXXFLAGS_FOR_TARGET = `echo $(CXXFLAGS) | sed -e 's/-fsanitize=[^ ]*//g'`
 
 transform = s/^ld-new$$/$(installed_linker)/;@program_transform_name@
 bin_PROGRAMS = ld-new
-info_TEXINFOS = ld.texi
+info_TEXINFOS = ld.texi ldint.texi
 ld_TEXINFOS = configdoc.texi
 noinst_TEXINFOS = ldint.texi
 man_MANS = ld.1
@@ -1060,7 +1060,19 @@ ld.1: $(srcdir)/ld.texi configdoc.texi
 		(rm -f $@.T$$$$ && exit 1)
 	$(AM_V_at)rm -f ld.pod
 
-MAINTAINERCLEANFILES = configdoc.texi ld.1
+# Build the man page from the texinfo file
+# The sed command removes the no-adjust Nroff command so that
+# the man output looks standard.
+ldint.1: $(srcdir)/ldint.texi configdoc.texi
+	$(AM_V_GEN)touch $@
+	$(AM_V_at)-$(TEXI2POD) $(MANCONF) < $(srcdir)/ldint.texi > ldint.pod
+	$(AM_V_at)-($(POD2MAN) ldint.pod | \
+		sed -e '/^.if n .na/d' > $@.T$$$$ && \
+		mv -f $@.T$$$$ $@) || \
+		(rm -f $@.T$$$$ && exit 1)
+	$(AM_V_at)rm -f ldint.pod
+
+MAINTAINERCLEANFILES = configdoc.texi ld.1 ldint.1
 
 # We want to reconfigure if configure.host or configure.tgt changes.
 # development.sh is used to determine -Werror default.
diff --git a/ld/Makefile.in b/ld/Makefile.in
index 6ec916aa629..7bf51bffa54 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -305,11 +305,11 @@ am__v_texidevnull_0 = > /dev/null
 am__v_texidevnull_1 = 
 INFO_DEPS = ld.info
 am__TEXINFO_TEX_DIR = $(srcdir)/../texinfo
-DVIS = ld.dvi
-PDFS = ld.pdf
-PSS = ld.ps
-HTMLS = ld.html
-TEXINFOS = ld.texi
+DVIS = ld.dvi ldint.dvi
+PDFS = ld.pdf ldint.pdf
+PSS = ld.ps ldint.ps
+HTMLS = ld.html ldint.html
+TEXINFOS = ld.texi ldint.texi
 TEXI2PDF = $(TEXI2DVI) --pdf --batch
 MAKEINFOHTML = $(MAKEINFO) --html
 AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
@@ -1682,18 +1682,48 @@ ld.info: ld.texi $(ld_TEXINFOS)
 	fi; \
 	rm -rf $$backupdir; exit $$rc
 
+ldint.info: ld.texi $(ld_TEXINFOS)
+	$(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+	rm -rf $$backupdir && mkdir $$backupdir && \
+	if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
+	  for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+	    if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
+	  done; \
+	else :; fi && \
+	if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+	 -o $@ `test -f 'ldint.texi' || echo '$(srcdir)/'`ldint.texi; \
+	then \
+	  rc=0; \
+	else \
+	  rc=$$?; \
+	  $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+	fi; \
+	rm -rf $$backupdir; exit $$rc
+
 ld.dvi: ld.texi $(ld_TEXINFOS) 
 	$(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
 	MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
 	$(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \
 	`test -f 'ld.texi' || echo '$(srcdir)/'`ld.texi
 
-ld.pdf: ld.texi $(ld_TEXINFOS) 
+ldint.dvi: ldint.texi $(ld_TEXINFOS)
+	$(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+	MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+	$(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \
+	`test -f 'ldint.texi' || echo '$(srcdir)/'`ldint.texi
+
+ld.pdf: ld.texi $(ld_TEXINFOS)
 	$(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
 	MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
 	$(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \
 	`test -f 'ld.texi' || echo '$(srcdir)/'`ld.texi
 
+ldint.pdf: ldint.texi $(ld_TEXINFOS)
+	$(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+	MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+	$(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \
+	`test -f 'ldint.texi' || echo '$(srcdir)/'`ldint.texi
+
 ld.html: ld.texi $(ld_TEXINFOS) 
 	$(AM_V_MAKEINFO)rm -rf $(@:.html=.htp)
 	$(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
@@ -1703,6 +1733,17 @@ ld.html: ld.texi $(ld_TEXINFOS)
 	else \
 	  rm -rf $(@:.html=.htp); exit 1; \
 	fi
+
+ldint.html: ldint.texi $(ld_TEXINFOS)
+	$(AM_V_MAKEINFO)rm -rf $(@:.html=.htp)
+	$(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+	 -o $(@:.html=.htp) `test -f 'ldint.texi' || echo '$(srcdir)/'`ldint.texi; \
+	then \
+	  rm -rf $@ && mv $(@:.html=.htp) $@; \
+	else \
+	  rm -rf $(@:.html=.htp); exit 1; \
+	fi
+
 .dvi.ps:
 	$(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
 	$(DVIPS) $(AM_V_texinfo) -o $@ $<
-- 
2.34.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v12 0/11 Add support for CRC64 generation in linker
  2023-03-06 13:31 [PATCH v12 0/11 Add support for CRC64 generation in linker binutils
                   ` (10 preceding siblings ...)
  2023-03-06 13:31 ` [PATCH v12 11/11] Build ldint binutils
@ 2023-03-07 13:59 ` Nick Clifton
  2023-03-07 18:03   ` Ulf Samuelsson
  2023-03-07 18:08   ` Ulf Samuelsson
  11 siblings, 2 replies; 22+ messages in thread
From: Nick Clifton @ 2023-03-07 13:59 UTC (permalink / raw)
  To: binutils, binutils

Hi Ulf,

> Patchset XII
> testsuite fixed to skip some tests.

Thanks.  I have now applied your patch set.

I made some small changes, mostly code formatting and correcting
some of the error messages.

Thank you very much for persisting with this patch contribution.

Cheers
   Nick



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v12 0/11 Add support for CRC64 generation in linker
  2023-03-07 13:59 ` [PATCH v12 0/11 Add support for CRC64 generation in linker Nick Clifton
@ 2023-03-07 18:03   ` Ulf Samuelsson
  2023-03-07 18:08   ` Ulf Samuelsson
  1 sibling, 0 replies; 22+ messages in thread
From: Ulf Samuelsson @ 2023-03-07 18:03 UTC (permalink / raw)
  To: Nick Clifton, binutils


On 2023-03-07 14:59, Nick Clifton wrote:
> Hi Ulf,
>
>> Patchset XII
>> testsuite fixed to skip some tests.
>
> Thanks.  I have now applied your patch set.
>
> I made some small changes, mostly code formatting and correcting
> some of the error messages.
>
> Thank you very much for persisting with this patch contribution.
>
Super GREAT!

Best Regards
Ulf Samuelsson


>
> Cheers
>   Nick
>
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v12 0/11 Add support for CRC64 generation in linker
  2023-03-07 13:59 ` [PATCH v12 0/11 Add support for CRC64 generation in linker Nick Clifton
  2023-03-07 18:03   ` Ulf Samuelsson
@ 2023-03-07 18:08   ` Ulf Samuelsson
  2023-03-08  9:31     ` Martin Liška
  1 sibling, 1 reply; 22+ messages in thread
From: Ulf Samuelsson @ 2023-03-07 18:08 UTC (permalink / raw)
  To: Nick Clifton, binutils


On 2023-03-07 14:59, Nick Clifton wrote:
> Hi Ulf,
>
>> Patchset XII
>> testsuite fixed to skip some tests.
>
> Thanks.  I have now applied your patch set.
>
> I made some small changes, mostly code formatting and correcting
> some of the error messages.
>
> Thank you very much for persisting with this patch contribution.
>
The Buildbot reports errors though!

Best Regards

Ulf Samuelsson


> Cheers
>   Nick
>
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v12 0/11 Add support for CRC64 generation in linker
  2023-03-07 18:08   ` Ulf Samuelsson
@ 2023-03-08  9:31     ` Martin Liška
  2023-03-08 11:48       ` Ulf Samuelsson
  0 siblings, 1 reply; 22+ messages in thread
From: Martin Liška @ 2023-03-08  9:31 UTC (permalink / raw)
  To: Ulf Samuelsson, Nick Clifton, binutils

On 3/7/23 19:08, Ulf Samuelsson via Binutils wrote:
> 
> On 2023-03-07 14:59, Nick Clifton wrote:
>> Hi Ulf,
>>
>>> Patchset XII
>>> testsuite fixed to skip some tests.
>>
>> Thanks.  I have now applied your patch set.
>>
>> I made some small changes, mostly code formatting and correcting
>> some of the error messages.
>>
>> Thank you very much for persisting with this patch contribution.
>>
> The Buildbot reports errors though!
> 
> Best Regards
> 
> Ulf Samuelsson
> 
> 
>> Cheers
>>   Nick
>>
>>

Hi.

I think this patch set caused the following build failure:

[  173s] gcc -DHAVE_CONFIG_H -I. -I../../ld  -I. -I../../ld -I../bfd -I../../ld/../bfd -I../../ld/../include  -fomit-frame-pointer -O2 -Wall -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -Werror=return-type  -Wno-error     -DLOCALEDIR="\"/usr/share/locale\""  -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 -Werror -DELF_LIST_OPTIONS=true -DELF_SHLIB_LIST_OPTIONS=false -DELF_PLT_UNWIND_LIST_OPTIONS=false   -fomit-frame-pointer -O2 -Wall -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -Werror=return-type  -Wno-error     -MT ldcrc64.o -MD -MP -MF .deps/ldcrc64.Tpo -c -o ldcrc64.o ../../ld/ldcrc64.c
[  173s] ../../ld/ldcrc64.c:109:1: error: conflicting types for 'init_crc64_tab'; have 'uint64_t *(algorithm_desc_t *)' {aka 'long long unsigned int *(algorithm_desc_t *)'}
[  173s]   109 | init_crc64_tab (algorithm_desc_t * dsc)
[  173s]       | ^~~~~~~~~~~~~~
[  173s] In file included from ../../ld/ldcrc64.c:33:
[  173s] ../../ld/lddigest.h:166:17: note: previous declaration of 'init_crc64_tab' with type 'bfd_vma *(algorithm_desc_t *)' {aka 'long unsigned int *(algorithm_desc_t *)'}
[  173s]   166 | extern bfd_vma *init_crc64_tab (algorithm_desc_t * dsc);
[  173s]       |                 ^~~~~~~~~~~~~~
[  173s] ../../ld/ldcrc64.c:140:10: error: conflicting types for 'calc_crc64'; have 'uint64_t(algorithm_desc_t *, const unsigned char *, size_t)' {aka 'long long unsigned int(algorithm_desc_t *, const unsigned char *, unsigned int)'}
[  173s]   140 | uint64_t calc_crc64
[  173s]       |          ^~~~~~~~~~
[  173s] ../../ld/lddigest.h:167:16: note: previous declaration of 'calc_crc64' with type 'bfd_vma(algorithm_desc_t *, const unsigned char *, size_t)' {aka 'long unsigned int(algorithm_desc_t *, const unsigned char *, unsigned int)'}
[  173s]   167 | extern bfd_vma calc_crc64
[  173s]       |                ^~~~~~~~~~
[  173s] make[4]: *** [Makefile:1604: ldcrc64.o] Error 1
[  173s] make[4]: Leaving directory '/home/abuild/rpmbuild/BUILD/binutils-2.40.50/build-dir/ld'

that happens on i586-linux-gnu host if I configure with --target=avr

Can you please take a look?
Thanks,
Martin

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v12 0/11 Add support for CRC64 generation in linker
  2023-03-08  9:31     ` Martin Liška
@ 2023-03-08 11:48       ` Ulf Samuelsson
  2023-03-08 12:52         ` Nick Clifton
  2023-03-08 12:57         ` Alan Modra
  0 siblings, 2 replies; 22+ messages in thread
From: Ulf Samuelsson @ 2023-03-08 11:48 UTC (permalink / raw)
  To: Martin Liška, Nick Clifton, binutils, schwab

Copying Andreas Schwab, since he ran into the same problem...

=======================================================

Sorry about causing problems.

I was under the impression that bfd_vma was always 64-bit. That was 
obviously wrong.

 From the error message, it looks like it it is 32-bit on 32-bit hosts, 
and 64-bit on 64-bit hosts.

Checking "bfd/bfd-in2.h" shows that this is indeed the case.

==================

#if BFD_ARCH_SIZE >= 64
#define BFD64
#endif

and later:
#ifdef BFD64
typedef uint64_t bfd_vma;
...
#else /* not BFD64  */
typedef unsigned long bfd_vma;
...
#endif /* not BFD64  */

============================================

TEMPORARY WORKAROUND:

There is (according to comments in bfd/bfd-in2.h) a workaround by
configuring with "--enable-64-bit-bfd".

I do not know if that has any other side effects.

QUESTION: Can You guys, test "./configure --enable-64-bit-bfd" ?

QUESTION: What are the main drawbacks to this workaround?

============================================

PERMANENT FIX:

Building using 32-bit bfd_vma makes life a lot more difficult since a 
lot of the code uses the bfd_vma type.

The expression calculator implemented in ldexp.c stores all integers in 
a "bigint".

   struct big_int
     {
       bfd_vma integer;
       char *str;
     } bigint;

So if you do DIGEST POLY (64,0xD800000000000000ULL,x,y,z,v,w)
the expression calculator will return the wrong value for the all the 64 bit
constants larger than 0xFFFFFFFF.

You  do not get around this, except by redesigning a **lot**.

CONCLUSION: I do not see a permanent fix that allows the DIGEST feature
to work when building with a 32-bit BFD.

============================================

PERMANENT WORKAROUND.

If the user does not want to build with a 64-bit BFD
then the only reasonable solution I see is to check BFD64.

If not defined

* Disable 64-bit CRCs

* Allow 32-bit CRCs

I am going to start looking into that.

If the CRC-64 options are disabled, the testsuite tests for this feature 
must be disabled.

QUESTION: How can you disable tests based on BFD size?
============================================

TESTING THE PERMANENT WORKAROUND.

A problem is that this is hard to test, since I do not have any 32-bit 
linux installations.

You can set "--enable-64-bit-bfd=no", but then the m4 macro in 
config/bfdm4.m4
will check the size of "void *" and reset the bfd size to 64-bit.

It should be possible to extend config/bfd64.m4 with an 
"--enable-32-bit-bfd"
for testing purposes. I do not know if anyone ever tried to build 32-bit
on a 64-bit machine.

QUESTION: Does anyone think it is useful to build a 32-bit BFD on a 
64-bit machine?

Best Regards

Ulf Samuelsson

On 2023-03-08 10:31, Martin Liška wrote:
> On 3/7/23 19:08, Ulf Samuelsson via Binutils wrote:
>> On 2023-03-07 14:59, Nick Clifton wrote:
>>> Hi Ulf,
>>>
>>>> Patchset XII
>>>> testsuite fixed to skip some tests.
>>> Thanks.  I have now applied your patch set.
>>>
>>> I made some small changes, mostly code formatting and correcting
>>> some of the error messages.
>>>
>>> Thank you very much for persisting with this patch contribution.
>>>
>> The Buildbot reports errors though!
>>
>> Best Regards
>>
>> Ulf Samuelsson
>>
>>
>>> Cheers
>>>    Nick
>>>
>>>
> Hi.
>
> I think this patch set caused the following build failure:
>
> [  173s] gcc -DHAVE_CONFIG_H -I. -I../../ld  -I. -I../../ld -I../bfd -I../../ld/../bfd -I../../ld/../include  -fomit-frame-pointer -O2 -Wall -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -Werror=return-type  -Wno-error     -DLOCALEDIR="\"/usr/share/locale\""  -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 -Werror -DELF_LIST_OPTIONS=true -DELF_SHLIB_LIST_OPTIONS=false -DELF_PLT_UNWIND_LIST_OPTIONS=false   -fomit-frame-pointer -O2 -Wall -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -Werror=return-type  -Wno-error     -MT ldcrc64.o -MD -MP -MF .deps/ldcrc64.Tpo -c -o ldcrc64.o ../../ld/ldcrc64.c
> [  173s] ../../ld/ldcrc64.c:109:1: error: conflicting types for 'init_crc64_tab'; have 'uint64_t *(algorithm_desc_t *)' {aka 'long long unsigned int *(algorithm_desc_t *)'}
> [  173s]   109 | init_crc64_tab (algorithm_desc_t * dsc)
> [  173s]       | ^~~~~~~~~~~~~~
> [  173s] In file included from ../../ld/ldcrc64.c:33:
> [  173s] ../../ld/lddigest.h:166:17: note: previous declaration of 'init_crc64_tab' with type 'bfd_vma *(algorithm_desc_t *)' {aka 'long unsigned int *(algorithm_desc_t *)'}
> [  173s]   166 | extern bfd_vma *init_crc64_tab (algorithm_desc_t * dsc);
> [  173s]       |                 ^~~~~~~~~~~~~~
> [  173s] ../../ld/ldcrc64.c:140:10: error: conflicting types for 'calc_crc64'; have 'uint64_t(algorithm_desc_t *, const unsigned char *, size_t)' {aka 'long long unsigned int(algorithm_desc_t *, const unsigned char *, unsigned int)'}
> [  173s]   140 | uint64_t calc_crc64
> [  173s]       |          ^~~~~~~~~~
> [  173s] ../../ld/lddigest.h:167:16: note: previous declaration of 'calc_crc64' with type 'bfd_vma(algorithm_desc_t *, const unsigned char *, size_t)' {aka 'long unsigned int(algorithm_desc_t *, const unsigned char *, unsigned int)'}
> [  173s]   167 | extern bfd_vma calc_crc64
> [  173s]       |                ^~~~~~~~~~
> [  173s] make[4]: *** [Makefile:1604: ldcrc64.o] Error 1
> [  173s] make[4]: Leaving directory '/home/abuild/rpmbuild/BUILD/binutils-2.40.50/build-dir/ld'
>
> that happens on i586-linux-gnu host if I configure with --target=avr
>
> Can you please take a look?
> Thanks,
> Martin

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v12 0/11 Add support for CRC64 generation in linker
  2023-03-08 11:48       ` Ulf Samuelsson
@ 2023-03-08 12:52         ` Nick Clifton
  2023-03-08 13:23           ` Ulf Samuelsson
  2023-03-08 12:57         ` Alan Modra
  1 sibling, 1 reply; 22+ messages in thread
From: Nick Clifton @ 2023-03-08 12:52 UTC (permalink / raw)
  To: Ulf Samuelsson, Martin Liška, binutils, schwab

Hi Ulf,

>  From the error message, it looks like it it is 32-bit on 32-bit hosts, and 64-bit on 64-bit hosts.

Weel, it can be 64-bit on 32-bit hosts, provided that
   a) they support 64-bit arithmetic in the compiler
   b) the binutils are configured with --enable-64-bit-bfd

> TEMPORARY WORKAROUND:
> 
> There is (according to comments in bfd/bfd-in2.h) a workaround by
> configuring with "--enable-64-bit-bfd".
> 
> I do not know if that has any other side effects.
> 
> QUESTION: Can You guys, test "./configure --enable-64-bit-bfd" ?

Yes, and it does "fix" the problem, but ...

> QUESTION: What are the main drawbacks to this workaround?

Most 32-bit versions of the binutils are not built with --enable-64-bit-bfd
so there will still be an issue.

> Building using 32-bit bfd_vma makes life a lot more difficult since a lot of the code uses the bfd_vma type.

Actually not so much.  It is still safe to use the bfd_vma type for
addresses.  The only real change is to use uint64_t instead of bfd_vma
when talking about 64-bit crc values.


> So if you do DIGEST POLY (64,0xD800000000000000ULL,x,y,z,v,w)
> the expression calculator will return the wrong value for the all the 64 bit
> constants larger than 0xFFFFFFFF.
> 
> You  do not get around this, except by redesigning a **lot**.
> 
> CONCLUSION: I do not see a permanent fix that allows the DIGEST feature
> to work when building with a 32-bit BFD.

I am testing a local patch which solves (most of) the problem
by using uin64_t.  It does not resolve the arguments to the POLY
digest issue that you describe above, but instead it adds a note
to the documentation saying that the generation of 64-bit polynomes
is not supported when the host and target are both 32-bit.  My
assumption is that for this kind of host/target combination the
user is never going to want 64-bit polynomes anyway, so the
restriction should not be too bad.

Cheers
   Nick




^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v12 0/11 Add support for CRC64 generation in linker
  2023-03-08 11:48       ` Ulf Samuelsson
  2023-03-08 12:52         ` Nick Clifton
@ 2023-03-08 12:57         ` Alan Modra
  2023-03-08 13:39           ` Ulf Samuelsson
  2023-03-09  8:48           ` Ulf Samuelsson
  1 sibling, 2 replies; 22+ messages in thread
From: Alan Modra @ 2023-03-08 12:57 UTC (permalink / raw)
  To: Ulf Samuelsson; +Cc: Martin Liška, Nick Clifton, binutils, schwab

On Wed, Mar 08, 2023 at 12:48:15PM +0100, Ulf Samuelsson via Binutils wrote:
> Building using 32-bit bfd_vma makes life a lot more difficult since a lot of
> the code uses the bfd_vma type.

Right, there are a few obvious places in lddigest.c that need to use
uint64_t rather than bfd_vma.

> The expression calculator implemented in ldexp.c stores all integers in a
> "bigint".
> 
>   struct big_int
>     {
>       bfd_vma integer;
>       char *str;
>     } bigint;
> 
> So if you do DIGEST POLY (64,0xD800000000000000ULL,x,y,z,v,w)
> the expression calculator will return the wrong value for the all the 64 bit
> constants larger than 0xFFFFFFFF.

Yes, that is a pain.

> You  do not get around this, except by redesigning a **lot**.

I think you can do it by changing lang_add_digest to take etree_type*
args.  I'm feeling generous so here's a first pass at it.  I haven't
fixed the debug functions..

It's late here so I'll commit this tomorrow after a little more
testing.

diff --git a/ld/lddigest.c b/ld/lddigest.c
index d0bb4db73ab..846ece177d3 100644
--- a/ld/lddigest.c
+++ b/ld/lddigest.c
@@ -103,10 +103,12 @@ lang_add_crc32_syndrome (algorithm_desc_t * a)
 static void
 lang_add_crc32_table (bool big_endian)
 {
-  uint32_t *crc32_table = algorithm.crc_tab;	/* Use a precomputed, if it exists */
+  /* Use a precomputed table, if it exists.  */
+  uint32_t *crc32_table = algorithm.crc_tab;
   bool local_table = false;
   if (crc32_table == NULL)
-    {				/* No luck, create a table */
+    {
+      /* No luck, create a table.  */
       crc32_table = init_crc32_tab (&algorithm);
       if (crc32_table == NULL)
 	{
@@ -115,7 +117,7 @@ lang_add_crc32_table (bool big_endian)
 	}
       local_table = true;
     }
-  for (bfd_vma i = 0; i < 256; i++)
+  for (int i = 0; i < 256; i++)
     {
       uint32_t elem = crc32_table[i];
       if (big_endian)
@@ -181,10 +183,12 @@ print_hash64_table (algorithm_desc_t * a)
 static void
 lang_add_crc64_table (bool big_endian)
 {
-  bfd_vma *crc64_table = algorithm.crc_tab;	/* Use a precomputed, if it exists */
+  /* Use a precomputed table, if it exists.  */
+  uint64_t *crc64_table = algorithm.crc_tab;
   bool local_table = false;
   if (crc64_table == NULL)
-    {				/* No luck, create a table */
+    {
+      /* No luck, create a table.  */
       crc64_table = init_crc64_tab (&algorithm);
       if (crc64_table == NULL)
 	{
@@ -194,9 +198,9 @@ lang_add_crc64_table (bool big_endian)
       local_table = true;
     }
   print_hash64_table (&algorithm);
-  for (bfd_vma i = 0; i < 256; i++)
+  for (int i = 0; i < 256; i++)
     {
-      bfd_vma elem = crc64_table[i];
+      uint64_t elem = crc64_table[i];
       if (big_endian)
 	{
 	  elem = __builtin_bswap64 (elem);
@@ -214,12 +218,42 @@ lang_add_crc64_table (bool big_endian)
 
 /* ============ DIGEST COMMON functions ======================================*/
 
+static uint64_t
+get_int (etree_type *tree, bool *err)
+{
+  if (tree != NULL)
+    {
+      exp_fold_tree_no_dot (tree);
+
+      if (expld.result.valid_p)
+	{
+	  if (expld.result.str != NULL)
+	    {
+	      char *end;
+	      uint64_t val = strtoull (expld.result.str, &end, 16);
+	      if (!*end)
+		return val;
+	    }
+	  else
+	    {
+	      if (expld.result.section != NULL)
+		expld.result.value += expld.result.section->vma;
+	      return expld.result.value;
+	    }
+	}
+    }
+  *err = true;
+  return 0;
+}
+
 void
-lang_add_digest (bfd_vma size,
-		 bfd_vma poly,
-		 bfd_vma initial,
-		 bfd_vma xor_val,
-		 bfd_vma ireflect, bfd_vma oreflect, bfd_vma reciprocal)
+lang_add_digest (etree_type *size,
+		 etree_type *poly,
+		 etree_type *initial,
+		 etree_type *xor_val,
+		 etree_type *ireflect,
+		 etree_type *oreflect,
+		 etree_type *reciprocal)
 {
   if (algorithm.crc_algo != no_algo)	/* We only allow one CRC <polynom> */
     {
@@ -227,40 +261,44 @@ lang_add_digest (bfd_vma size,
       return;
     }
 
+  bool err = false;
   algorithm.name = "CUSTOM";
   algorithm.big_endian = digest_big_endian;
-  if (size == 64)
+  algorithm.crc_size = get_int (size, &err);
+  algorithm.poly.d64 = get_int (poly, &err);
+  algorithm.initial.d64 = get_int (initial, &err);
+  algorithm.xor_val.d64 = get_int (xor_val, &err);
+  algorithm.ireflect = get_int (ireflect, &err);
+  algorithm.oreflect = get_int (oreflect, &err);
+  algorithm.crc_tab = NULL;
+  algorithm.reciprocal = get_int (reciprocal, &err);
+  algorithm.expected.d64 = 0;
+
+  if (err)
+    {
+      einfo (_("%F%P: Invalid DIGEST arg\n"));
+      return;
+    }
+
+  if (algorithm.crc_size == 64)
     {
       algorithm.crc_algo = crc_algo_64;
-      algorithm.crc_size = size;
-      algorithm.poly.d64 = poly;	/* Set the polynom */
-      algorithm.initial.d64 = initial;	/* Set seed */
-      algorithm.xor_val.d64 = xor_val;	/* final XOR value */
-      algorithm.ireflect = ireflect;
-      algorithm.oreflect = oreflect;
-      algorithm.crc_tab = NULL;
-      algorithm.reciprocal = reciprocal;
-      algorithm.expected.d64 = 0;
-
       lang_add_crc64_syndrome (&algorithm);
     }
-  else if (size == 32)
+  else if (algorithm.crc_size == 32)
     {
       algorithm.crc_algo = crc_algo_32;
-      algorithm.crc_size = size;
-      algorithm.poly.d32._0 = poly;	/* Set the polynom */
-      algorithm.initial.d32._0 = initial;	/* Set seed */
-      algorithm.xor_val.d32._0 = xor_val;	/* final XOR value */
-      algorithm.ireflect = ireflect;
-      algorithm.oreflect = oreflect;
-      algorithm.crc_tab = NULL;
-      algorithm.reciprocal = reciprocal;
-      algorithm.expected.d32._0 = 0;
+      algorithm.poly.d32._0 = algorithm.poly.d64;
+      algorithm.poly.d32._1 = 0;
+      algorithm.initial.d32._0 = algorithm.initial.d64;
+      algorithm.initial.d32._1 = 0;
+      algorithm.xor_val.d32._0 = algorithm.xor_val.d64;
+      algorithm.xor_val.d32._1 = 0;
       lang_add_crc32_syndrome (&algorithm);
     }
   else
     {
-      einfo (_("%F%P: Illegal Size in DIGEST: %E\n"));
+      einfo (_("%F%P: Invalid Size in DIGEST\n"));
       return;
     }
 }
@@ -660,7 +698,7 @@ set_crc64_checksum (uint64_t crc, bfd_vma addr)
 }
 
 static bool
-set_crc_checksum (bfd_vma crc, bfd_vma addr, bfd_vma size)
+set_crc_checksum (uint64_t crc, bfd_vma addr, int size)
 {
   bool status;
   if (size == 64)
@@ -700,7 +738,7 @@ symbol_lookup (char *name, bfd_vma * val)
  * Multiplexing function for calculating CRC with different algorithms
  * 'algorithm.crc_algo'
  */
-static bfd_vma
+static uint64_t
 calculate_crc (const unsigned char *input_str, size_t num_bytes)
 {
   if (algorithm.crc_algo == crc_algo_64)
@@ -782,7 +820,7 @@ void
 lang_generate_crc (void)
 {
   bfd_vma crc_addr, crc_area_start, crc_area_end;
-  bfd_vma crc;
+  uint64_t crc;
   bool can_do_crc;
 
   /* Return immediately, if CRC is not requested */
diff --git a/ld/lddigest.h b/ld/lddigest.h
index 9f5e5f3fbda..f5ae1ddad7e 100755
--- a/ld/lddigest.h
+++ b/ld/lddigest.h
@@ -33,6 +33,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include "bfd.h"
+#include "ldexp.h"
 
 #define	CRC_POLY_64_ECMA	0x42F0E1EBA9EA3693ull	/* Normal */
 #define	CRC_POLY_64_ECMA_EXP	0x6C40DF5F0B497347ull	/* CRC when testing "123456789" */
@@ -163,17 +164,18 @@ extern uint32_t calc_crc32
 extern void lang_add_crc32_syndrome (algorithm_desc_t * a);
 
 /* CR-64 */
-extern bfd_vma *init_crc64_tab (algorithm_desc_t * dsc);
-extern bfd_vma calc_crc64
+extern uint64_t *init_crc64_tab (algorithm_desc_t * dsc);
+extern uint64_t calc_crc64
   (algorithm_desc_t * dsc, const unsigned char *input_str, size_t num_bytes);
 extern void lang_add_crc64_syndrome (algorithm_desc_t * a);
 
-extern void lang_add_digest (bfd_vma size,
-			     bfd_vma poly,
-			     bfd_vma initial,
-			     bfd_vma xor_val,
-			     bfd_vma ireflect,
-			     bfd_vma oreflect, bfd_vma reciprocal);
+extern void lang_add_digest (etree_type *size,
+			     etree_type *poly,
+			     etree_type *initial,
+			     etree_type *xor_val,
+			     etree_type *ireflect,
+			     etree_type *oreflect,
+			     etree_type *reciprocal);
 extern bool lang_set_digest (char *digest);
 extern void lang_add_digest_table (bool big_endian);
 extern const char *lang_get_label (const char *label, bool *big_endian);
diff --git a/ld/lddigest_tab.c b/ld/lddigest_tab.c
index 4f5db10c997..b286a3c0161 100644
--- a/ld/lddigest_tab.c
+++ b/ld/lddigest_tab.c
@@ -99,9 +99,9 @@ const algorithm_desc_t algorithms[MAXALGO+1] =
   [CRC32] =
 	{
 		crc_algo_32, 32, "CRC32",
-		.poly.d32._0 = CRC_POLY_32,
+		.poly.d32 = { CRC_POLY_32, 0 },
 		.initial.d64 = CRC_START_32_INV,
-		.xor_val.d32._0 = CRC_END_32_INV,
+		.xor_val.d32 = { CRC_END_32_INV, 0 },
 		.ireflect = true,
 		.oreflect = true,
 		.reciprocal = false,
diff --git a/ld/ldgram.y b/ld/ldgram.y
index ea0c569279a..2bc2f5e24e2 100644
--- a/ld/ldgram.y
+++ b/ld/ldgram.y
@@ -747,13 +747,13 @@ polynome:
 		   mustbe_exp ',' mustbe_exp ',' mustbe_exp ')'
 		{
 		  lang_add_digest (
-			$3->value.value,	/* size			*/
-			$5->value.value,	/* polynome		*/
-			$7->value.value,	/* initial value	*/
-			$9->value.value,	/* xor     value	*/
-			$11->value.value,	/* input   reflected	*/
-			$13->value.value,	/* output  reflected	*/
-			$15->value.value	/* reciprocal		*/
+			$3,	/* size			*/
+			$5,	/* polynome		*/
+			$7,	/* initial value	*/
+			$9,	/* xor     value	*/
+			$11,	/* input   reflected	*/
+			$13,	/* output  reflected	*/
+			$15	/* reciprocal		*/
 			);
 		  polynome_valid = true;
 		}
diff --git a/ld/testsuite/ld-scripts/crc64-poly-size.d b/ld/testsuite/ld-scripts/crc64-poly-size.d
index 6a3651cbff5..1c7b3c46881 100644
--- a/ld/testsuite/ld-scripts/crc64-poly-size.d
+++ b/ld/testsuite/ld-scripts/crc64-poly-size.d
@@ -1,5 +1,5 @@
 #source: crc64-poly-size.s
 #ld: -T crc64-poly-size.t
-# error: .*: Illegal Size in DIGEST: .*
+# error: .*: Invalid Size in DIGEST
 #target: [is_elf_format] [is_coff_format]
 #skip: tic4x-*-* tic54x-*-*


-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v12 0/11 Add support for CRC64 generation in linker
  2023-03-08 12:52         ` Nick Clifton
@ 2023-03-08 13:23           ` Ulf Samuelsson
  0 siblings, 0 replies; 22+ messages in thread
From: Ulf Samuelsson @ 2023-03-08 13:23 UTC (permalink / raw)
  To: Nick Clifton, Martin Liška, binutils, schwab


On 2023-03-08 13:52, Nick Clifton wrote:
> Hi Ulf,
>
>>  From the error message, it looks like it it is 32-bit on 32-bit 
>> hosts, and 64-bit on 64-bit hosts.
>
> Weel, it can be 64-bit on 32-bit hosts, provided that
>   a) they support 64-bit arithmetic in the compiler
>   b) the binutils are configured with --enable-64-bit-bfd
>
>> TEMPORARY WORKAROUND:
>>
>> There is (according to comments in bfd/bfd-in2.h) a workaround by
>> configuring with "--enable-64-bit-bfd".
>>
>> I do not know if that has any other side effects.
>>
>> QUESTION: Can You guys, test "./configure --enable-64-bit-bfd" ?
>
> Yes, and it does "fix" the problem, but ...
>
>> QUESTION: What are the main drawbacks to this workaround?
>
> Most 32-bit versions of the binutils are not built with 
> --enable-64-bit-bfd
> so there will still be an issue.

That can change, but that is of course a hassle.

>
>> Building using 32-bit bfd_vma makes life a lot more difficult since a 
>> lot of the code uses the bfd_vma type.
>
> Actually not so much.  It is still safe to use the bfd_vma type for
> addresses.  The only real change is to use uint64_t instead of bfd_vma
> when talking about 64-bit crc values.
>
I think you have to rewrite the expression evaluator to be 64-bit for 
this to work


>
>> So if you do DIGEST POLY (64,0xD800000000000000ULL,x,y,z,v,w)
>> the expression calculator will return the wrong value for the all the 
>> 64 bit
>> constants larger than 0xFFFFFFFF.
>>
>> You  do not get around this, except by redesigning a **lot**.
>>
>> CONCLUSION: I do not see a permanent fix that allows the DIGEST feature
>> to work when building with a 32-bit BFD.
>
> I am testing a local patch which solves (most of) the problem
> by using uin64_t.  It does not resolve the arguments to the POLY
> digest issue that you describe above, but instead it adds a note
> to the documentation saying that the generation of 64-bit polynomes
> is not supported when the host and target are both 32-bit.  My
> assumption is that for this kind of host/target combination the
> user is never going to want 64-bit polynomes anyway, so the
> restriction should not be too bad.
>
Actually that is not true.

The width of the CRC is depending on the size of the area you are checking.
A larger area needs more bits.
A few kB of code are OK with a 32 bit CRC, but I think when you are
getting close to 100 kB, you should consider a 64-bit CRC.

I read about this quite some time ago, so I do not remembed the cut-off
point, but when you have 1 MByte of code, then CRC32 is not good enough.
I tried to find a statement on when to switch from 32-bit to 64-bit 
right now without success.

Texas Instruments certainly put a 64-bit H/W CRC in parts where you have 
4 MByte of flash.

In the CRC world you speak of "Hamming distance".
If I understand things correctly, that is basically the risk that you 
have two
similar images that generate the same checksum.
Another way of putting it is how many independent bit errors you can detect.

Best Regards

Ulf Samuelsson



> Cheers
>   Nick
>
>
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v12 0/11 Add support for CRC64 generation in linker
  2023-03-08 12:57         ` Alan Modra
@ 2023-03-08 13:39           ` Ulf Samuelsson
  2023-03-09  8:48           ` Ulf Samuelsson
  1 sibling, 0 replies; 22+ messages in thread
From: Ulf Samuelsson @ 2023-03-08 13:39 UTC (permalink / raw)
  To: Alan Modra; +Cc: Martin Liška, Nick Clifton, binutils, schwab


On 2023-03-08 13:57, Alan Modra wrote:
> On Wed, Mar 08, 2023 at 12:48:15PM +0100, Ulf Samuelsson via Binutils wrote:
>> Building using 32-bit bfd_vma makes life a lot more difficult since a lot of
>> the code uses the bfd_vma type.
> Right, there are a few obvious places in lddigest.c that need to use
> uint64_t rather than bfd_vma.
>
The problem is mainly with the "DIGEST POLY (64, ....)"

I guess your get_int from the string will solve that problem.



>> The expression calculator implemented in ldexp.c stores all integers in a
>> "bigint".
>>
>>    struct big_int
>>      {
>>        bfd_vma integer;
>>        char *str;
>>      } bigint;
>>
>> So if you do DIGEST POLY (64,0xD800000000000000ULL,x,y,z,v,w)
>> the expression calculator will return the wrong value for the all the 64 bit
>> constants larger than 0xFFFFFFFF.
> Yes, that is a pain.
>
>> You  do not get around this, except by redesigning a **lot**.
> I think you can do it by changing lang_add_digest to take etree_type*
> args.  I'm feeling generous so here's a first pass at it.  I haven't
> fixed the debug functions..

I appreciate it

Thumbs up!

Best Regards
Ulf Samuelsson

>
> It's late here so I'll commit this tomorrow after a little more
> testing.
>
> diff --git a/ld/lddigest.c b/ld/lddigest.c
> index d0bb4db73ab..846ece177d3 100644
> --- a/ld/lddigest.c
> +++ b/ld/lddigest.c
> @@ -103,10 +103,12 @@ lang_add_crc32_syndrome (algorithm_desc_t * a)
>   static void
>   lang_add_crc32_table (bool big_endian)
>   {
> -  uint32_t *crc32_table = algorithm.crc_tab;	/* Use a precomputed, if it exists */
> +  /* Use a precomputed table, if it exists.  */
> +  uint32_t *crc32_table = algorithm.crc_tab;
>     bool local_table = false;
>     if (crc32_table == NULL)
> -    {				/* No luck, create a table */
> +    {
> +      /* No luck, create a table.  */
>         crc32_table = init_crc32_tab (&algorithm);
>         if (crc32_table == NULL)
>   	{
> @@ -115,7 +117,7 @@ lang_add_crc32_table (bool big_endian)
>   	}
>         local_table = true;
>       }
> -  for (bfd_vma i = 0; i < 256; i++)
> +  for (int i = 0; i < 256; i++)
>       {
>         uint32_t elem = crc32_table[i];
>         if (big_endian)
> @@ -181,10 +183,12 @@ print_hash64_table (algorithm_desc_t * a)
>   static void
>   lang_add_crc64_table (bool big_endian)
>   {
> -  bfd_vma *crc64_table = algorithm.crc_tab;	/* Use a precomputed, if it exists */
> +  /* Use a precomputed table, if it exists.  */
> +  uint64_t *crc64_table = algorithm.crc_tab;
>     bool local_table = false;
>     if (crc64_table == NULL)
> -    {				/* No luck, create a table */
> +    {
> +      /* No luck, create a table.  */
>         crc64_table = init_crc64_tab (&algorithm);
>         if (crc64_table == NULL)
>   	{
> @@ -194,9 +198,9 @@ lang_add_crc64_table (bool big_endian)
>         local_table = true;
>       }
>     print_hash64_table (&algorithm);
> -  for (bfd_vma i = 0; i < 256; i++)
> +  for (int i = 0; i < 256; i++)
>       {
> -      bfd_vma elem = crc64_table[i];
> +      uint64_t elem = crc64_table[i];
>         if (big_endian)
>   	{
>   	  elem = __builtin_bswap64 (elem);
> @@ -214,12 +218,42 @@ lang_add_crc64_table (bool big_endian)
>   
>   /* ============ DIGEST COMMON functions ======================================*/
>   
> +static uint64_t
> +get_int (etree_type *tree, bool *err)
> +{
> +  if (tree != NULL)
> +    {
> +      exp_fold_tree_no_dot (tree);
> +
> +      if (expld.result.valid_p)
> +	{
> +	  if (expld.result.str != NULL)
> +	    {
> +	      char *end;
> +	      uint64_t val = strtoull (expld.result.str, &end, 16);
> +	      if (!*end)
> +		return val;
> +	    }
> +	  else
> +	    {
> +	      if (expld.result.section != NULL)
> +		expld.result.value += expld.result.section->vma;
> +	      return expld.result.value;
> +	    }
> +	}
> +    }
> +  *err = true;
> +  return 0;
> +}
> +
>   void
> -lang_add_digest (bfd_vma size,
> -		 bfd_vma poly,
> -		 bfd_vma initial,
> -		 bfd_vma xor_val,
> -		 bfd_vma ireflect, bfd_vma oreflect, bfd_vma reciprocal)
> +lang_add_digest (etree_type *size,
> +		 etree_type *poly,
> +		 etree_type *initial,
> +		 etree_type *xor_val,
> +		 etree_type *ireflect,
> +		 etree_type *oreflect,
> +		 etree_type *reciprocal)
>   {
>     if (algorithm.crc_algo != no_algo)	/* We only allow one CRC <polynom> */
>       {
> @@ -227,40 +261,44 @@ lang_add_digest (bfd_vma size,
>         return;
>       }
>   
> +  bool err = false;
>     algorithm.name = "CUSTOM";
>     algorithm.big_endian = digest_big_endian;
> -  if (size == 64)
> +  algorithm.crc_size = get_int (size, &err);
> +  algorithm.poly.d64 = get_int (poly, &err);
> +  algorithm.initial.d64 = get_int (initial, &err);
> +  algorithm.xor_val.d64 = get_int (xor_val, &err);
> +  algorithm.ireflect = get_int (ireflect, &err);
> +  algorithm.oreflect = get_int (oreflect, &err);
> +  algorithm.crc_tab = NULL;
> +  algorithm.reciprocal = get_int (reciprocal, &err);
> +  algorithm.expected.d64 = 0;
> +
> +  if (err)
> +    {
> +      einfo (_("%F%P: Invalid DIGEST arg\n"));
> +      return;
> +    }
> +
> +  if (algorithm.crc_size == 64)
>       {
>         algorithm.crc_algo = crc_algo_64;
> -      algorithm.crc_size = size;
> -      algorithm.poly.d64 = poly;	/* Set the polynom */
> -      algorithm.initial.d64 = initial;	/* Set seed */
> -      algorithm.xor_val.d64 = xor_val;	/* final XOR value */
> -      algorithm.ireflect = ireflect;
> -      algorithm.oreflect = oreflect;
> -      algorithm.crc_tab = NULL;
> -      algorithm.reciprocal = reciprocal;
> -      algorithm.expected.d64 = 0;
> -
>         lang_add_crc64_syndrome (&algorithm);
>       }
> -  else if (size == 32)
> +  else if (algorithm.crc_size == 32)
>       {
>         algorithm.crc_algo = crc_algo_32;
> -      algorithm.crc_size = size;
> -      algorithm.poly.d32._0 = poly;	/* Set the polynom */
> -      algorithm.initial.d32._0 = initial;	/* Set seed */
> -      algorithm.xor_val.d32._0 = xor_val;	/* final XOR value */
> -      algorithm.ireflect = ireflect;
> -      algorithm.oreflect = oreflect;
> -      algorithm.crc_tab = NULL;
> -      algorithm.reciprocal = reciprocal;
> -      algorithm.expected.d32._0 = 0;
> +      algorithm.poly.d32._0 = algorithm.poly.d64;
> +      algorithm.poly.d32._1 = 0;
> +      algorithm.initial.d32._0 = algorithm.initial.d64;
> +      algorithm.initial.d32._1 = 0;
> +      algorithm.xor_val.d32._0 = algorithm.xor_val.d64;
> +      algorithm.xor_val.d32._1 = 0;
>         lang_add_crc32_syndrome (&algorithm);
>       }
>     else
>       {
> -      einfo (_("%F%P: Illegal Size in DIGEST: %E\n"));
> +      einfo (_("%F%P: Invalid Size in DIGEST\n"));
>         return;
>       }
>   }
> @@ -660,7 +698,7 @@ set_crc64_checksum (uint64_t crc, bfd_vma addr)
>   }
>   
>   static bool
> -set_crc_checksum (bfd_vma crc, bfd_vma addr, bfd_vma size)
> +set_crc_checksum (uint64_t crc, bfd_vma addr, int size)
>   {
>     bool status;
>     if (size == 64)
> @@ -700,7 +738,7 @@ symbol_lookup (char *name, bfd_vma * val)
>    * Multiplexing function for calculating CRC with different algorithms
>    * 'algorithm.crc_algo'
>    */
> -static bfd_vma
> +static uint64_t
>   calculate_crc (const unsigned char *input_str, size_t num_bytes)
>   {
>     if (algorithm.crc_algo == crc_algo_64)
> @@ -782,7 +820,7 @@ void
>   lang_generate_crc (void)
>   {
>     bfd_vma crc_addr, crc_area_start, crc_area_end;
> -  bfd_vma crc;
> +  uint64_t crc;
>     bool can_do_crc;
>   
>     /* Return immediately, if CRC is not requested */
> diff --git a/ld/lddigest.h b/ld/lddigest.h
> index 9f5e5f3fbda..f5ae1ddad7e 100755
> --- a/ld/lddigest.h
> +++ b/ld/lddigest.h
> @@ -33,6 +33,7 @@
>   #include <stdint.h>
>   #include <stdbool.h>
>   #include "bfd.h"
> +#include "ldexp.h"
>   
>   #define	CRC_POLY_64_ECMA	0x42F0E1EBA9EA3693ull	/* Normal */
>   #define	CRC_POLY_64_ECMA_EXP	0x6C40DF5F0B497347ull	/* CRC when testing "123456789" */
> @@ -163,17 +164,18 @@ extern uint32_t calc_crc32
>   extern void lang_add_crc32_syndrome (algorithm_desc_t * a);
>   
>   /* CR-64 */
> -extern bfd_vma *init_crc64_tab (algorithm_desc_t * dsc);
> -extern bfd_vma calc_crc64
> +extern uint64_t *init_crc64_tab (algorithm_desc_t * dsc);
> +extern uint64_t calc_crc64
>     (algorithm_desc_t * dsc, const unsigned char *input_str, size_t num_bytes);
>   extern void lang_add_crc64_syndrome (algorithm_desc_t * a);
>   
> -extern void lang_add_digest (bfd_vma size,
> -			     bfd_vma poly,
> -			     bfd_vma initial,
> -			     bfd_vma xor_val,
> -			     bfd_vma ireflect,
> -			     bfd_vma oreflect, bfd_vma reciprocal);
> +extern void lang_add_digest (etree_type *size,
> +			     etree_type *poly,
> +			     etree_type *initial,
> +			     etree_type *xor_val,
> +			     etree_type *ireflect,
> +			     etree_type *oreflect,
> +			     etree_type *reciprocal);
>   extern bool lang_set_digest (char *digest);
>   extern void lang_add_digest_table (bool big_endian);
>   extern const char *lang_get_label (const char *label, bool *big_endian);
> diff --git a/ld/lddigest_tab.c b/ld/lddigest_tab.c
> index 4f5db10c997..b286a3c0161 100644
> --- a/ld/lddigest_tab.c
> +++ b/ld/lddigest_tab.c
> @@ -99,9 +99,9 @@ const algorithm_desc_t algorithms[MAXALGO+1] =
>     [CRC32] =
>   	{
>   		crc_algo_32, 32, "CRC32",
> -		.poly.d32._0 = CRC_POLY_32,
> +		.poly.d32 = { CRC_POLY_32, 0 },
>   		.initial.d64 = CRC_START_32_INV,
> -		.xor_val.d32._0 = CRC_END_32_INV,
> +		.xor_val.d32 = { CRC_END_32_INV, 0 },
>   		.ireflect = true,
>   		.oreflect = true,
>   		.reciprocal = false,
> diff --git a/ld/ldgram.y b/ld/ldgram.y
> index ea0c569279a..2bc2f5e24e2 100644
> --- a/ld/ldgram.y
> +++ b/ld/ldgram.y
> @@ -747,13 +747,13 @@ polynome:
>   		   mustbe_exp ',' mustbe_exp ',' mustbe_exp ')'
>   		{
>   		  lang_add_digest (
> -			$3->value.value,	/* size			*/
> -			$5->value.value,	/* polynome		*/
> -			$7->value.value,	/* initial value	*/
> -			$9->value.value,	/* xor     value	*/
> -			$11->value.value,	/* input   reflected	*/
> -			$13->value.value,	/* output  reflected	*/
> -			$15->value.value	/* reciprocal		*/
> +			$3,	/* size			*/
> +			$5,	/* polynome		*/
> +			$7,	/* initial value	*/
> +			$9,	/* xor     value	*/
> +			$11,	/* input   reflected	*/
> +			$13,	/* output  reflected	*/
> +			$15	/* reciprocal		*/
>   			);
>   		  polynome_valid = true;
>   		}
> diff --git a/ld/testsuite/ld-scripts/crc64-poly-size.d b/ld/testsuite/ld-scripts/crc64-poly-size.d
> index 6a3651cbff5..1c7b3c46881 100644
> --- a/ld/testsuite/ld-scripts/crc64-poly-size.d
> +++ b/ld/testsuite/ld-scripts/crc64-poly-size.d
> @@ -1,5 +1,5 @@
>   #source: crc64-poly-size.s
>   #ld: -T crc64-poly-size.t
> -# error: .*: Illegal Size in DIGEST: .*
> +# error: .*: Invalid Size in DIGEST
>   #target: [is_elf_format] [is_coff_format]
>   #skip: tic4x-*-* tic54x-*-*
>
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v12 0/11 Add support for CRC64 generation in linker
  2023-03-08 12:57         ` Alan Modra
  2023-03-08 13:39           ` Ulf Samuelsson
@ 2023-03-09  8:48           ` Ulf Samuelsson
  1 sibling, 0 replies; 22+ messages in thread
From: Ulf Samuelsson @ 2023-03-09  8:48 UTC (permalink / raw)
  To: Alan Modra; +Cc: Martin Liška, Nick Clifton, binutils, schwab

[-- Attachment #1: Type: text/plain, Size: 15026 bytes --]


On 2023-03-08 13:57, Alan Modra wrote:
> On Wed, Mar 08, 2023 at 12:48:15PM +0100, Ulf Samuelsson via Binutils wrote:
>> Building using 32-bit bfd_vma makes life a lot more difficult since a lot of
>> the code uses the bfd_vma type.
> Right, there are a few obvious places in lddigest.c that need to use
> uint64_t rather than bfd_vma.
>
>> The expression calculator implemented in ldexp.c stores all integers in a
>> "bigint".
>>
>>    struct big_int
>>      {
>>        bfd_vma integer;
>>        char *str;
>>      } bigint;
>>
>> So if you do DIGEST POLY (64,0xD800000000000000ULL,x,y,z,v,w)
>> the expression calculator will return the wrong value for the all the 64 bit
>> constants larger than 0xFFFFFFFF.
> Yes, that is a pain.
>
>> You  do not get around this, except by redesigning a **lot**.
> I think you can do it by changing lang_add_digest to take etree_type*
> args.  I'm feeling generous so here's a first pass at it.  I haven't
> fixed the debug functions..
>
> It's late here so I'll commit this tomorrow after a little more
> testing.

I had a further look at this.
Please be aware that I am still a newbie on the code, so I might have 
misunderstood things.


If you specify

       DIGEST POLY (64, *$*42F0E1EBA9EA3693, $FFFFFFFFFFFFFFFF, ...)

The lexical analyzer sets the "str" field to NULL and the "integer" 
field becomes ULONG_MAX.

<MRI,EXPRESSION>"$"([0-9A-Fa-f])+ {
                 yylval.integer = bfd_scan_vma (yytext + 1, 0, 16);
                 yylval.bigint.str = NULL;
                 return INT;
             }

===

Reason for ULONG_MAX is:

bfd_vma
bfd_scan_vma (const char *string, const char **end, int base)
{
   bfd_vma value;
   bfd_vma cutoff;
   unsigned int cutlim;
   int overflow;

   /* Let the host do it if possible.  */
   if (sizeof (bfd_vma) <= sizeof (unsigned long))
     return strtoul (string, (char **) end, base);

   ...

bfd_scan_vma will scan the string "42F0E1EBA9EA3693".

Since sizeof(bfd_vma) == 4, strtoul will be called.

https://cplusplus.com/reference/cstdlib/strtoul/ => if value > ULONG_MAX 
return ULONG_MAX.

Since 0x42F0E1EBA9EA3693 > 0xFFFFFFFF, strtoul will return ULONG_MAX and 
set errno to ERANGE.

Anyway bfd_scan_vma returns a 32-bit integer on a 32-bit host so 
yylval.integer will be wrong.

======================================

If you specify

       DIGEST POLY (64, *0x*42F0E1EBA9EA3693, $FFFFFFFFFFFFFFFF, ...)

then the yylval.integer will be ULONG_MAX and yylval.bigint.str will be 
"42F0E1EBA9EA3693"

Here, I think your stuff might work.

======================================

If you specify

       DIGEST POLY (64, 0x42F0E1EBA9EA3693, *~0*, ...)

which does not seem to be unreasonable,

then the third parameter become 0x0000000000000000 instead of 
0xFFFFFFFFFFFFFFFF.

======================================

When you read a number, you call "exp_bigintop"

etree_type *
exp_bigintop (bfd_vma value, char *str)
{
   etree_type *new_e = stat_alloc (sizeof (new_e->value));
   new_e->type.node_code = INT;
   new_e->type.filename = ldlex_filename ();
   new_e->type.lineno = lineno;
   new_e->value.value = value;
   new_e->value.str = str;
*  new_e->type.node_class = etree_value;*
   return new_e;
}

This sets the node_class to etree_value;

=======

"get_int" will call "exp_fold_tree_no_dot" which will call "exp_fold_tree_1"

void
exp_fold_tree_no_dot (etree_type *tree)
{
   ...
   exp_fold_tree_1 (tree);
}

"exp_fold_tree" will find an "etree_value"  and call new_abs or new_number
which sets the expld.result.str to NULL, but it is immediately 
afterwards set to tree->value.str.

static void
exp_fold_tree_1 (etree_type *tree)
{
   ...
   switch (tree->type.node_class)
     {
         case etree_value:
            if (expld.section == bfd_abs_section_ptr && !config.sane_expr)
               new_abs (tree->value.value);
            else
               new_number (tree->value.value);
            expld.result.str = tree->value.str;
            break;

            ...
         case etree_unary:
           fold_unary (tree);
           break;

}

static void
fold_unary (etree_type *tree)
{
   exp_fold_tree_1 (tree->unary.child);
   if (expld.result.valid_p)
     {
       switch (tree->type.node_code)
         {
            case '~':
            expld.result.value = ~expld.result.value;
            break;

            ...

         }
       }
}

so fold_unary will result in

expld.result.value = 0x00000000 == ~ULONG_MAX  (due to overflow of 
0x42F0E1EBA9EA3693)

expld.result.str = "42F0E1EBA9EA3693" and not ~0x42F0E1EBA9EA3693

so get_int will get the wrong result.

=============

Since expld.result.value is a bfd_vma, the computation will fail,

typedef struct {
   bfd_vma value;
   char *str;
   ...
   bool valid_p;
} etree_value_type;

struct ldexp_control {

   ...
   etree_value_type result;
   ...
};

extern struct ldexp_control expld;

================================================

Conclusion.

Some parameters to POLY should not be expressions,
they must be valid integers using the "0xFFFF_FFFF_FFFF_FFFF" style

The parameters affected are:

* polynome
* initial value
* xor     value

The range of addresses covered can be expressions as long as they are 
below 4 GB.

I guess that if the documentation adds those restrictions, the patch 
will work


Best Regards
Ulf Samuelsson


>
> diff --git a/ld/lddigest.c b/ld/lddigest.c
> index d0bb4db73ab..846ece177d3 100644
> --- a/ld/lddigest.c
> +++ b/ld/lddigest.c
> @@ -103,10 +103,12 @@ lang_add_crc32_syndrome (algorithm_desc_t * a)
>   static void
>   lang_add_crc32_table (bool big_endian)
>   {
> -  uint32_t *crc32_table = algorithm.crc_tab;	/* Use a precomputed, if it exists */
> +  /* Use a precomputed table, if it exists.  */
> +  uint32_t *crc32_table = algorithm.crc_tab;
>     bool local_table = false;
>     if (crc32_table == NULL)
> -    {				/* No luck, create a table */
> +    {
> +      /* No luck, create a table.  */
>         crc32_table = init_crc32_tab (&algorithm);
>         if (crc32_table == NULL)
>   	{
> @@ -115,7 +117,7 @@ lang_add_crc32_table (bool big_endian)
>   	}
>         local_table = true;
>       }
> -  for (bfd_vma i = 0; i < 256; i++)
> +  for (int i = 0; i < 256; i++)
>       {
>         uint32_t elem = crc32_table[i];
>         if (big_endian)
> @@ -181,10 +183,12 @@ print_hash64_table (algorithm_desc_t * a)
>   static void
>   lang_add_crc64_table (bool big_endian)
>   {
> -  bfd_vma *crc64_table = algorithm.crc_tab;	/* Use a precomputed, if it exists */
> +  /* Use a precomputed table, if it exists.  */
> +  uint64_t *crc64_table = algorithm.crc_tab;
>     bool local_table = false;
>     if (crc64_table == NULL)
> -    {				/* No luck, create a table */
> +    {
> +      /* No luck, create a table.  */
>         crc64_table = init_crc64_tab (&algorithm);
>         if (crc64_table == NULL)
>   	{
> @@ -194,9 +198,9 @@ lang_add_crc64_table (bool big_endian)
>         local_table = true;
>       }
>     print_hash64_table (&algorithm);
> -  for (bfd_vma i = 0; i < 256; i++)
> +  for (int i = 0; i < 256; i++)
>       {
> -      bfd_vma elem = crc64_table[i];
> +      uint64_t elem = crc64_table[i];
>         if (big_endian)
>   	{
>   	  elem = __builtin_bswap64 (elem);
> @@ -214,12 +218,42 @@ lang_add_crc64_table (bool big_endian)
>   
>   /* ============ DIGEST COMMON functions ======================================*/
>   
> +static uint64_t
> +get_int (etree_type *tree, bool *err)
> +{
> +  if (tree != NULL)
> +    {
> +      exp_fold_tree_no_dot (tree);
> +
> +      if (expld.result.valid_p)
> +	{
> +	  if (expld.result.str != NULL)
> +	    {
> +	      char *end;
> +	      uint64_t val = strtoull (expld.result.str, &end, 16);
> +	      if (!*end)
> +		return val;
> +	    }
> +	  else
> +	    {
> +	      if (expld.result.section != NULL)
> +		expld.result.value += expld.result.section->vma;
> +	      return expld.result.value;
> +	    }
> +	}
> +    }
> +  *err = true;
> +  return 0;
> +}
> +
>   void
> -lang_add_digest (bfd_vma size,
> -		 bfd_vma poly,
> -		 bfd_vma initial,
> -		 bfd_vma xor_val,
> -		 bfd_vma ireflect, bfd_vma oreflect, bfd_vma reciprocal)
> +lang_add_digest (etree_type *size,
> +		 etree_type *poly,
> +		 etree_type *initial,
> +		 etree_type *xor_val,
> +		 etree_type *ireflect,
> +		 etree_type *oreflect,
> +		 etree_type *reciprocal)
>   {
>     if (algorithm.crc_algo != no_algo)	/* We only allow one CRC <polynom> */
>       {
> @@ -227,40 +261,44 @@ lang_add_digest (bfd_vma size,
>         return;
>       }
>   
> +  bool err = false;
>     algorithm.name = "CUSTOM";
>     algorithm.big_endian = digest_big_endian;
> -  if (size == 64)
> +  algorithm.crc_size = get_int (size, &err);
> +  algorithm.poly.d64 = get_int (poly, &err);
> +  algorithm.initial.d64 = get_int (initial, &err);
> +  algorithm.xor_val.d64 = get_int (xor_val, &err);
> +  algorithm.ireflect = get_int (ireflect, &err);
> +  algorithm.oreflect = get_int (oreflect, &err);
> +  algorithm.crc_tab = NULL;
> +  algorithm.reciprocal = get_int (reciprocal, &err);
> +  algorithm.expected.d64 = 0;
> +
> +  if (err)
> +    {
> +      einfo (_("%F%P: Invalid DIGEST arg\n"));
> +      return;
> +    }
> +
> +  if (algorithm.crc_size == 64)
>       {
>         algorithm.crc_algo = crc_algo_64;
> -      algorithm.crc_size = size;
> -      algorithm.poly.d64 = poly;	/* Set the polynom */
> -      algorithm.initial.d64 = initial;	/* Set seed */
> -      algorithm.xor_val.d64 = xor_val;	/* final XOR value */
> -      algorithm.ireflect = ireflect;
> -      algorithm.oreflect = oreflect;
> -      algorithm.crc_tab = NULL;
> -      algorithm.reciprocal = reciprocal;
> -      algorithm.expected.d64 = 0;
> -
>         lang_add_crc64_syndrome (&algorithm);
>       }
> -  else if (size == 32)
> +  else if (algorithm.crc_size == 32)
>       {
>         algorithm.crc_algo = crc_algo_32;
> -      algorithm.crc_size = size;
> -      algorithm.poly.d32._0 = poly;	/* Set the polynom */
> -      algorithm.initial.d32._0 = initial;	/* Set seed */
> -      algorithm.xor_val.d32._0 = xor_val;	/* final XOR value */
> -      algorithm.ireflect = ireflect;
> -      algorithm.oreflect = oreflect;
> -      algorithm.crc_tab = NULL;
> -      algorithm.reciprocal = reciprocal;
> -      algorithm.expected.d32._0 = 0;
> +      algorithm.poly.d32._0 = algorithm.poly.d64;
> +      algorithm.poly.d32._1 = 0;
> +      algorithm.initial.d32._0 = algorithm.initial.d64;
> +      algorithm.initial.d32._1 = 0;
> +      algorithm.xor_val.d32._0 = algorithm.xor_val.d64;
> +      algorithm.xor_val.d32._1 = 0;
>         lang_add_crc32_syndrome (&algorithm);
>       }
>     else
>       {
> -      einfo (_("%F%P: Illegal Size in DIGEST: %E\n"));
> +      einfo (_("%F%P: Invalid Size in DIGEST\n"));
>         return;
>       }
>   }
> @@ -660,7 +698,7 @@ set_crc64_checksum (uint64_t crc, bfd_vma addr)
>   }
>   
>   static bool
> -set_crc_checksum (bfd_vma crc, bfd_vma addr, bfd_vma size)
> +set_crc_checksum (uint64_t crc, bfd_vma addr, int size)
>   {
>     bool status;
>     if (size == 64)
> @@ -700,7 +738,7 @@ symbol_lookup (char *name, bfd_vma * val)
>    * Multiplexing function for calculating CRC with different algorithms
>    * 'algorithm.crc_algo'
>    */
> -static bfd_vma
> +static uint64_t
>   calculate_crc (const unsigned char *input_str, size_t num_bytes)
>   {
>     if (algorithm.crc_algo == crc_algo_64)
> @@ -782,7 +820,7 @@ void
>   lang_generate_crc (void)
>   {
>     bfd_vma crc_addr, crc_area_start, crc_area_end;
> -  bfd_vma crc;
> +  uint64_t crc;
>     bool can_do_crc;
>   
>     /* Return immediately, if CRC is not requested */
> diff --git a/ld/lddigest.h b/ld/lddigest.h
> index 9f5e5f3fbda..f5ae1ddad7e 100755
> --- a/ld/lddigest.h
> +++ b/ld/lddigest.h
> @@ -33,6 +33,7 @@
>   #include <stdint.h>
>   #include <stdbool.h>
>   #include "bfd.h"
> +#include "ldexp.h"
>   
>   #define	CRC_POLY_64_ECMA	0x42F0E1EBA9EA3693ull	/* Normal */
>   #define	CRC_POLY_64_ECMA_EXP	0x6C40DF5F0B497347ull	/* CRC when testing "123456789" */
> @@ -163,17 +164,18 @@ extern uint32_t calc_crc32
>   extern void lang_add_crc32_syndrome (algorithm_desc_t * a);
>   
>   /* CR-64 */
> -extern bfd_vma *init_crc64_tab (algorithm_desc_t * dsc);
> -extern bfd_vma calc_crc64
> +extern uint64_t *init_crc64_tab (algorithm_desc_t * dsc);
> +extern uint64_t calc_crc64
>     (algorithm_desc_t * dsc, const unsigned char *input_str, size_t num_bytes);
>   extern void lang_add_crc64_syndrome (algorithm_desc_t * a);
>   
> -extern void lang_add_digest (bfd_vma size,
> -			     bfd_vma poly,
> -			     bfd_vma initial,
> -			     bfd_vma xor_val,
> -			     bfd_vma ireflect,
> -			     bfd_vma oreflect, bfd_vma reciprocal);
> +extern void lang_add_digest (etree_type *size,
> +			     etree_type *poly,
> +			     etree_type *initial,
> +			     etree_type *xor_val,
> +			     etree_type *ireflect,
> +			     etree_type *oreflect,
> +			     etree_type *reciprocal);
>   extern bool lang_set_digest (char *digest);
>   extern void lang_add_digest_table (bool big_endian);
>   extern const char *lang_get_label (const char *label, bool *big_endian);
> diff --git a/ld/lddigest_tab.c b/ld/lddigest_tab.c
> index 4f5db10c997..b286a3c0161 100644
> --- a/ld/lddigest_tab.c
> +++ b/ld/lddigest_tab.c
> @@ -99,9 +99,9 @@ const algorithm_desc_t algorithms[MAXALGO+1] =
>     [CRC32] =
>   	{
>   		crc_algo_32, 32, "CRC32",
> -		.poly.d32._0 = CRC_POLY_32,
> +		.poly.d32 = { CRC_POLY_32, 0 },
>   		.initial.d64 = CRC_START_32_INV,
> -		.xor_val.d32._0 = CRC_END_32_INV,
> +		.xor_val.d32 = { CRC_END_32_INV, 0 },
>   		.ireflect = true,
>   		.oreflect = true,
>   		.reciprocal = false,
> diff --git a/ld/ldgram.y b/ld/ldgram.y
> index ea0c569279a..2bc2f5e24e2 100644
> --- a/ld/ldgram.y
> +++ b/ld/ldgram.y
> @@ -747,13 +747,13 @@ polynome:
>   		   mustbe_exp ',' mustbe_exp ',' mustbe_exp ')'
>   		{
>   		  lang_add_digest (
> -			$3->value.value,	/* size			*/
> -			$5->value.value,	/* polynome		*/
> -			$7->value.value,	/* initial value	*/
> -			$9->value.value,	/* xor     value	*/
> -			$11->value.value,	/* input   reflected	*/
> -			$13->value.value,	/* output  reflected	*/
> -			$15->value.value	/* reciprocal		*/
>
>   			);
>   		  polynome_valid = true;
>   		}
> diff --git a/ld/testsuite/ld-scripts/crc64-poly-size.d b/ld/testsuite/ld-scripts/crc64-poly-size.d
> index 6a3651cbff5..1c7b3c46881 100644
> --- a/ld/testsuite/ld-scripts/crc64-poly-size.d
> +++ b/ld/testsuite/ld-scripts/crc64-poly-size.d
> @@ -1,5 +1,5 @@
>   #source: crc64-poly-size.s
>   #ld: -T crc64-poly-size.t
> -# error: .*: Illegal Size in DIGEST: .*
> +# error: .*: Invalid Size in DIGEST
>   #target: [is_elf_format] [is_coff_format]
>   #skip: tic4x-*-* tic54x-*-*
>
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2023-03-09  8:48 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-06 13:31 [PATCH v12 0/11 Add support for CRC64 generation in linker binutils
2023-03-06 13:31 ` [PATCH v12 01/11] DIGEST: LICENSING binutils
2023-03-06 13:31 ` [PATCH v12 02/11] DIGEST: NEWS binutils
2023-03-06 13:31 ` [PATCH v12 03/11] DIGEST: Documentation binutils
2023-03-06 13:31 ` [PATCH v12 04/11] DIGEST: testsuite binutils
2023-03-06 13:31 ` [PATCH v12 05/11] DIGEST: ldlex.l binutils
2023-03-06 13:31 ` [PATCH v12 06/11] DIGEST: ldgram.y binutils
2023-03-06 13:31 ` [PATCH v12 07/11] DIGEST: ldmain.c binutils
2023-03-06 13:31 ` [PATCH v12 08/11] DIGEST: ldlang.*: add timestamp binutils
2023-03-06 13:31 ` [PATCH v12 09/11] DIGEST: calculation binutils
2023-03-06 13:31 ` [PATCH v12 10/11] DIGEST: Makefile.* binutils
2023-03-06 13:31 ` [PATCH v12 11/11] Build ldint binutils
2023-03-07 13:59 ` [PATCH v12 0/11 Add support for CRC64 generation in linker Nick Clifton
2023-03-07 18:03   ` Ulf Samuelsson
2023-03-07 18:08   ` Ulf Samuelsson
2023-03-08  9:31     ` Martin Liška
2023-03-08 11:48       ` Ulf Samuelsson
2023-03-08 12:52         ` Nick Clifton
2023-03-08 13:23           ` Ulf Samuelsson
2023-03-08 12:57         ` Alan Modra
2023-03-08 13:39           ` Ulf Samuelsson
2023-03-09  8:48           ` Ulf Samuelsson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).