From: binutils@emagii.com
To: binutils@sourceware.org
Cc: nickc@redhat.com, Ulf Samuelsson <binutils@emagii.com>
Subject: [PATCH v4 5/5] Calculate CRC64 over the .text area
Date: Sun, 19 Feb 2023 20:45:49 +0100 [thread overview]
Message-ID: <20230219194549.22554-6-binutils@emagii.com> (raw)
In-Reply-To: <20230219194549.22554-1-binutils@emagii.com>
From: Ulf Samuelsson <binutils@emagii.com>
Signed-off-by: Ulf Samuelsson <binutils@emagii.com>
---
ld/Makefile.am | 2 +-
ld/checksum.h | 62 +++++
ld/ldlang.c | 648 ++++++++++++++++++++++++++++++++++++++++++++++++-
ld/ldlang.h | 12 +
ld/ldmain.c | 1 +
5 files changed, 721 insertions(+), 4 deletions(-)
create mode 100755 ld/checksum.h
diff --git a/ld/Makefile.am b/ld/Makefile.am
index 760225c5b88..91b024d1cba 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -481,7 +481,7 @@ CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \
plugin.c ldbuildid.c ldelf.c ldelfgen.c \
pdb.c
-HFILES = ld.h ldctor.h ldemul.h ldexp.h ldfile.h \
+HFILES = checksum.h 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 \
diff --git a/ld/checksum.h b/ld/checksum.h
new file mode 100755
index 00000000000..6dcb1bf738d
--- /dev/null
+++ b/ld/checksum.h
@@ -0,0 +1,62 @@
+/*
+ * Library: libcrc
+ * 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.
+ *
+ */
+
+#ifndef CHECKSUM_H
+#define CHECKSUM_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define CRC_POLY_64 0x42F0E1EBA9EA3693ull
+#define CRC_POLY_64_ISO 0xD800000000000000ull
+#define CRC_START_64 0x0000000000000000ull
+#define CRC_START_64_INV 0xFFFFFFFFFFFFFFFFull
+
+#define CRC64_ADDRESS "___CRC64___"
+#define CRC64_START "___CRC64_START___"
+#define CRC64_END "___CRC64_END___"
+#define CRC64_TABLE "___CRC64_TABLE___"
+
+#define CRC_POLY_32 0xEDB88320ul
+#define CRC_START_32_INV 0xFFFFFFFFul
+
+#define CRC32_ADDRESS "___CRC32___"
+#define CRC32_START "___CRC32_START___"
+#define CRC32_END "___CRC32_END___"
+#define CRC32_TABLE "___CRC32_TABLE___"
+
+enum crc_alg {
+ crc_algo_none=0,
+ crc_algo_32=4,
+ crc_algo_64=8
+};
+
+bfd_vma crc_64 (const unsigned char *input_str, size_t num_bytes);
+bfd_vma crc_64_inv(const unsigned char *input_str, size_t num_bytes);
+
+#endif /* CHECKSUM_H */
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 2852a4222d3..180511d2d8a 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -18,8 +18,11 @@
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
+#define DEBUG_CRC 0
+
#include "sysdep.h"
#include <limits.h>
+#include <time.h>
#include "bfd.h"
#include "libiberty.h"
#include "filenames.h"
@@ -42,6 +45,8 @@
#include "demangle.h"
#include "hashtab.h"
#include "elf-bfd.h"
+#include "checksum.h"
+
#if BFD_SUPPORTS_PLUGINS
#include "plugin.h"
#endif /* BFD_SUPPORTS_PLUGINS */
@@ -145,6 +150,25 @@ int lang_statement_iteration = 0;
/* Count times through one_lang_size_sections_pass after mark phase. */
static int lang_sizing_iteration = 0;
+/* CRC calculation on output section */
+asection *text_section;
+unsigned char *text_contents = NULL;
+
+enum crc_alg crc_algo = crc_algo_none;
+bfd_vma crc_size = 0; /* Size of syndrome */
+bool crc_invert = false;
+
+bfd_vma crc64_poly = CRC_POLY_64; /* Default Polynome is CRC64 ECMA */
+bfd_vma *crc64_tab = NULL;
+
+uint32_t crc32_poly = CRC_POLY_32; /* Default Polynome is CRC-32 */
+bool crc32_invert = true;
+uint32_t *crc32_tab = NULL;
+
+char *CRC_ADDRESS = NULL;
+char *CRC_START = NULL;
+char *CRC_END = NULL;
+
/* Return TRUE if the PATTERN argument is a wildcard pattern.
Although backslashes are treated specially if a pattern contains
wildcards, we do not consider the mere presence of a backslash to
@@ -8389,7 +8413,7 @@ convert_string (const char * s)
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
-
+
case '0':
case '1':
case '2':
@@ -8409,7 +8433,7 @@ convert_string (const char * s)
value += (c - '0');
i++;
s++;
-
+
c = *s;
if ((c >= '0') && (c <= '7'))
{
@@ -8427,7 +8451,7 @@ convert_string (const char * s)
i--;
s--;
}
-
+
c = value;
}
break;
@@ -8524,6 +8548,624 @@ lang_add_attribute (enum statement_enum attribute)
new_statement (attribute, sizeof (lang_statement_header_type), stat_ptr);
}
+/* ============ CRC-32 LIBCRC functions ======================================*/
+
+/*
+ * 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.
+ * init_crc32_tab is copyright (c) 2016 Lammert Bies
+ */
+static
+uint32_t *init_crc32_tab( uint32_t poly )
+{
+ uint32_t i;
+ uint32_t j;
+ uint32_t crc;
+ uint32_t *crc_tab;
+
+ crc_tab = malloc(256 * sizeof(uint32_t));
+ if (crc_tab == NULL)
+ return NULL;
+
+ for (i=0; i<256; i++)
+ {
+
+ crc = i;
+
+ for (j=0; j<8; j++)
+ {
+
+ if ( crc & 0x00000001L )
+ {
+ crc = ( crc >> 1 ) ^ poly;
+ }
+ else
+ {
+ crc = crc >> 1;
+ }
+ }
+
+ crc_tab[i] = crc;
+ }
+ return crc_tab;
+} /* init_crc32_tab */
+
+/*
+ * uint32_t calc_crc32_inv( const unsigned char *input_str, size_t num_bytes );
+ *
+ * The function calc_crc32_inv() 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.
+ */
+static
+uint32_t calc_crc32_inv( const unsigned char *input_str, size_t num_bytes )
+{
+ uint32_t crc;
+ const unsigned char *ptr;
+ size_t a;
+
+ crc = CRC_START_32_INV;
+ ptr = input_str;
+
+ if ( ptr != NULL )
+ {
+ for (a=0; a<num_bytes; a++)
+ {
+ crc = (crc >> 8) ^
+ crc32_tab[(crc ^ (uint32_t) *ptr++) & 0x000000FFul ];
+ }
+ }
+
+ return (crc ^ 0xFFFFFFFFul);
+
+} /* calc_crc32_inv */
+
+/*
+ * uint32_t calc_crc32( 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.
+ */
+static
+uint32_t calc_crc32( const unsigned char *input_str, size_t num_bytes )
+{
+ uint32_t crc;
+ const unsigned char *ptr;
+ size_t a;
+ if (crc_invert)
+ return calc_crc32_inv(input_str, num_bytes);
+
+ crc = 0;
+ ptr = input_str;
+
+ if ( ptr != NULL )
+ {
+ for (a=0; a<num_bytes; a++)
+ {
+ crc = (crc >> 8) ^
+ crc32_tab[(crc ^ (uint32_t) *ptr++) & 0x000000FFul ];
+ }
+ }
+
+ return (crc);
+
+} /* calc_crc32 */
+
+/* ============ CRC-32 public functions ======================================*/
+
+extern void lang_add_crc32_syndrome(bool invert, bfd_vma poly)
+{
+
+ if (crc_algo == crc_algo_none) /* We only allow one CRC64 <polynom> */
+ {
+ crc_algo = crc_algo_32;
+ crc_size = sizeof(uint32_t);
+ crc32_invert = invert;
+ crc32_poly = (uint32_t) (poly & 0xFFFFFFFF); /* Set the polynom */
+ CRC_ADDRESS = CRC32_ADDRESS;
+ CRC_START = CRC32_START;
+ CRC_END = CRC32_END;
+
+#if (DEBUG_CRC == 1)
+ printf("Adding Syndrome: 0x%08lx\n", poly);
+#endif
+ lang_add_data (LONG, exp_intop (0)); /* Reserve room for the ECC value */
+ crc32_tab = init_crc32_tab(crc32_poly);
+ if (crc32_tab == NULL)
+ {
+ einfo (_("%F%P: can not allocate memory for CRC table: %E\n"));
+ return;
+ }
+ }
+ else
+ {
+ einfo (_("%P:%pS: warning: Only the first CRC polynome is used\n"),
+ NULL);
+ }
+}
+
+extern void lang_add_crc32_table(void)
+{
+ uint32_t *crc32_table = crc32_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(crc32_poly);
+ 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++)
+ {
+ lang_add_data (LONG, exp_intop (crc32_table[i]));
+ }
+ if (local_table)
+ free(crc32_table);
+}
+
+/* ============ CRC-64 LIBCRC functions ======================================*/
+
+/*
+ * bfd_vma *init_crc64_tab( bfd_vma 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_tab is copyright (c) 2016 Lammert Bies
+ */
+static
+bfd_vma *init_crc64_tab( bfd_vma poly )
+{
+ bfd_vma i;
+ bfd_vma j;
+ bfd_vma c;
+ bfd_vma crc;
+ bfd_vma *crc_tab;
+
+ crc_tab = malloc(256 * sizeof(bfd_vma));
+ if (crc_tab == NULL)
+ return NULL;
+
+ for (i=0; i<256; i++)
+ {
+ crc = 0;
+ c = i << 56;
+ for (j=0; j<8; j++)
+ {
+ if ( ( crc ^ c ) & 0x8000000000000000ull )
+ crc = ( crc << 1 ) ^ poly;
+ else
+ crc = crc << 1;
+ c = c << 1;
+ }
+ crc_tab[i] = crc;
+ }
+ return crc_tab;
+
+} /* init_crc64_tab */
+
+/*
+ * The function calc_crc64_inv() calculates in one pass the CRC64 64 bit CRC
+ * value for a byte string that is passed to the function together with a
+ * parameter indicating the length.
+ * This is used for CRC64-WE
+ * calc_crc64_inv is copyright (c) 2016 Lammert Bies
+ */
+static
+bfd_vma calc_crc64_inv( const unsigned char *input_str, size_t num_bytes )
+{
+ bfd_vma crc;
+ const unsigned char *ptr;
+ size_t a;
+
+ crc = CRC_START_64_INV;
+ ptr = input_str;
+
+ if ( ptr != NULL )
+ {
+ for (a=0; a<num_bytes; a++)
+ {
+ crc = (crc << 8) ^
+ crc64_tab[
+ ((crc >> 56) ^ (bfd_vma) *ptr++) &
+ 0x00000000000000FFull
+ ];
+ }
+ }
+ return crc ^ 0xFFFFFFFFFFFFFFFFull;
+} /* calc_crc64_inv */
+
+/*
+ * bfd_vma calc_crc64( 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.
+ * This is used for CRC64-ECMA and CRC64-ISO
+ * calc_crc64 is copyright (c) 2016 Lammert Bies
+ */
+static
+bfd_vma calc_crc64(const unsigned char *input_str, size_t num_bytes)
+{
+ bfd_vma crc;
+ const unsigned char *ptr;
+ size_t a;
+ if (crc_invert)
+ return calc_crc64_inv(input_str, num_bytes);
+ crc = CRC_START_64;
+ ptr = input_str;
+ if ( ptr != NULL )
+ {
+ for (a=0; a<num_bytes; a++)
+ {
+ crc = (crc << 8) ^
+ crc64_tab[
+ ((crc >> 56) ^ (bfd_vma) *ptr++) &
+ 0x00000000000000FFull
+ ];
+ }
+ }
+ return crc;
+} /* calc_crc64 */
+
+/* ============ CRC-64 public functions ======================================*/
+
+extern void lang_add_crc64_syndrome(bool invert, bfd_vma poly)
+{
+
+ if (crc_algo == crc_algo_none) /* We only allow one CRC64 <polynom> */
+ {
+ crc_algo = crc_algo_64;
+ crc_size = sizeof(bfd_vma);
+ crc_invert = invert;
+ crc64_poly = poly; /* Set the polynom */
+ CRC_ADDRESS = CRC64_ADDRESS;
+ CRC_START = CRC64_START;
+ CRC_END = CRC64_END;
+
+#if (DEBUG_CRC == 1)
+ printf("Adding Syndrome: 0x%08lx\n", poly);
+#endif
+ lang_add_data (QUAD, exp_intop (0)); /* Reserve room for the ECC value */
+ crc64_tab = init_crc64_tab(crc64_poly);
+ if (crc64_tab == NULL)
+ {
+ einfo (_("%F%P: can not allocate memory for CRC table: %E\n"));
+ return;
+ }
+ }
+ else
+ {
+ einfo (_("%P:%pS: warning: Only the first CRC polynome is used\n"),
+ NULL);
+ }
+}
+
+extern void lang_add_crc64_table(void)
+{
+ bfd_vma *crc64_table = crc64_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(crc64_poly);
+ if (crc64_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++)
+ {
+ lang_add_data (QUAD, exp_intop (crc64_table[i]));
+ }
+ if (local_table)
+ free(crc64_table);
+}
+
+/* ============ Access functions for inserting checksum in text section=======*/
+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...
+ */
+ text_section = bfd_get_section_by_name (link_info.output_bfd, entry_section);
+ if (text_section == NULL)
+ {
+ einfo (_("%P:%pS: Cannot retrieve '.text' section for CRC calc\n"), NULL);
+ 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 (_("%P:%pS: warning: '.text' section contents unavailable\n"
+ "CRC generation aborted\n"), NULL);
+ return false;
+ }
+
+#if (DEBUG_CRC == 1)
+ 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_crc_checksum(bfd_vma crc, bfd_vma addr, bfd_vma size)
+{
+ if (!bfd_set_section_contents(link_info.output_bfd,
+ text_section->output_section,
+ &crc,
+ addr,
+ size))
+ {
+ einfo (_("%P:%pS: warning: updating CRC failed\n"
+ "CRC generation aborted\n"), NULL);
+ return false;
+ }
+ return true;
+}
+
+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 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
+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);
+ }
+}
+#else
+#define debug_hex(p,s,a,sz)
+#define debug_crc_header(p)
+#define debug_crc_update(c, a)
+#define debug_full_textsection()
+#endif
+
+/* ============ CRC common functions =========================================*/
+/*
+ * Multiplexing function for calculating CRC with different algorithms
+ * 'crc_algo'
+ */
+static
+bfd_vma calculate_crc(const unsigned char *input_str, size_t num_bytes)
+{
+ if (crc_algo == crc_algo_64)
+ {
+ if (crc64_tab != NULL)
+ {
+ return calc_crc64(input_str, num_bytes);
+ }
+ }
+ else if (crc_algo == crc_algo_32)
+ {
+ if (crc32_tab != NULL)
+ {
+ return calc_crc32(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;
+ /* 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 =
+ ((text_start <= crc_addr) && (crc_addr <= text_end)) &&
+ ((text_start <= crc_area_start) && (crc_area_start <= text_end)) &&
+ ((text_start <= crc_area_end) && (crc_area_end <= text_end));
+
+ if (!crc_in_section)
+ {
+ einfo (_("%P:%pS: warning: CRC area outside the '.text' section\n"
+ "CRC generation aborted\n"), NULL);
+ /*
+ * 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_area_start)
+ {
+ 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 (_("%P:%pS: warning: CRC located inside checked area\n"
+ "CRC generation aborted\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 (crc_algo == crc_algo_none)
+ return;
+
+ if (!get_text_section_contents())
+ {
+ /* Error messages inside check */
+ 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 (_("%P:%pS: Internal Error - __CRC#___ symbols not defined\n"
+ "CRC generation aborted\n"), NULL);
+ 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");
+ crc = calculate_crc(&text_contents[_crc_area_start] ,
+ _crc_area_end - _crc_area_start);
+
+
+ /*
+ * 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, crc_size))
+ {
+ debug_crc_update(crc, crc_addr);
+ }
+ }
+
+ debug_full_textsection();
+}
+
+/* ============ END CRC common functions =====================================*/
+
+/* ============ TIMESTAMP common functions ===================================*/
+
+/* Store the time of linking in the image */
+void lang_add_timestamp (void)
+{
+ lang_add_data (QUAD, exp_intop ((bfd_vma) time(0)));
+}
+
+/* ===========================================================================*/
+
void
lang_startup (const char *name)
{
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 2300fa5b2a3..3d514909cae 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -632,6 +632,18 @@ extern lang_output_section_statement_type *lang_output_section_statement_lookup
(const char *, int, int);
extern lang_output_section_statement_type *next_matching_output_section_statement
(lang_output_section_statement_type *, int);
+extern void lang_add_crc32_syndrome
+ (bool, bfd_vma);
+extern void lang_add_crc32_table
+ (void);
+extern void lang_add_crc64_syndrome
+ (bool, bfd_vma);
+extern void lang_add_crc64_table
+ (void);
+extern void lang_add_timestamp
+ (void);
+extern void lang_generate_crc
+ (void);
extern void ldlang_add_undef
(const char *const, bool);
extern void ldlang_add_require_defined
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 25cc89b72f9..8b57b2dc5fc 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -527,6 +527,7 @@ main (int argc, char **argv)
ldwrite ();
+ lang_generate_crc(); /* Calculate and store CRC on request */
if (config.map_file != NULL)
lang_map ();
if (command_line.cref)
--
2.17.1
next prev parent reply other threads:[~2023-02-20 10:30 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-19 19:45 [PATCH v4 0/5 Add support for CRC64 generation in linker binutils
2023-02-19 19:45 ` [PATCH v4 1/5] CRC64 commands documentation binutils
2023-02-19 19:50 ` [PATCH v4 0/5] Add support for CRC64 generation in linker Ulf Samuelsson
2023-02-21 12:02 ` Nick Clifton
2023-02-21 13:10 ` Ulf Samuelsson
2023-02-21 13:30 ` Ulf Samuelsson
2023-02-21 12:53 ` [PATCH v4 1/5] CRC64 commands documentation Nick Clifton
2023-02-21 13:24 ` Ulf Samuelsson
2023-02-19 19:45 ` [PATCH v4 2/5] CRC64 testsuite binutils
2023-02-21 12:42 ` Nick Clifton
2023-02-21 15:13 ` Ulf Samuelsson
2023-02-23 10:10 ` Nick Clifton
2023-02-23 10:53 ` Ulf Samuelsson
2023-02-23 11:01 ` Nick Clifton
2023-02-28 11:11 ` Ulf Samuelsson
2023-02-28 12:37 ` Nick Clifton
2023-02-28 13:01 ` Ulf Samuelsson
2023-02-28 13:06 ` Nick Clifton
2023-02-28 14:24 ` Ulf Samuelsson
2023-02-28 13:45 ` Ulf Samuelsson
2023-02-19 19:45 ` [PATCH v4 3/5] ldlex.l: CRC64 binutils
2023-02-19 19:45 ` [PATCH v4 4/5] ldgram.y: CRC64 binutils
2023-02-19 19:45 ` binutils [this message]
2023-02-21 13:26 ` [PATCH v4 5/5] Calculate CRC64 over the .text area Nick Clifton
2023-02-23 8:36 ` Ulf Samuelsson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230219194549.22554-6-binutils@emagii.com \
--to=binutils@emagii.com \
--cc=binutils@sourceware.org \
--cc=nickc@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).