From: binutils@emagii.com
To: binutils@sourceware.org
Cc: nickc@redhat.com, Ulf Samuelsson <ulf@emagii.com>
Subject: [PATCH v1 5/7] SECTOR: language additions
Date: Fri, 10 Mar 2023 01:08:15 +0100 [thread overview]
Message-ID: <20230310000817.751962-6-binutils@emagii.com> (raw)
In-Reply-To: <20230310000817.751962-1-binutils@emagii.com>
From: Ulf Samuelsson <ulf@emagii.com>
Signed-off-by: Ulf Samuelsson <ulf@emagii.com>
---
ld/lddigest.h | 7 ++
ld/ldsectors.c | 309 +++++++++++++++++++++++++++++++++++++++++++++++++
ld/sysdep.h | 2 +
3 files changed, 318 insertions(+)
create mode 100644 ld/ldsectors.c
diff --git a/ld/lddigest.h b/ld/lddigest.h
index 8f2889f1846..95e442006ef 100755
--- a/ld/lddigest.h
+++ b/ld/lddigest.h
@@ -189,4 +189,11 @@ extern void lang_generate_crc
extern void lang_generate_digest
(void);
+extern void lang_add_bank
+ (const char *name);
+extern void lang_add_sector
+ (const char *size);
+extern void lang_align_sector
+ (void);
+
#endif /* LDDIGEST_H */
diff --git a/ld/ldsectors.c b/ld/ldsectors.c
new file mode 100644
index 00000000000..c9e1fcb8756
--- /dev/null
+++ b/ld/ldsectors.c
@@ -0,0 +1,309 @@
+/* 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 _GNU_SOURCE
+#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"
+
+typedef struct
+{
+ const char *name;
+ int count;
+ int location;
+} bank_t;
+
+typedef struct symbol
+{
+ uint64_t value;
+ char *str;
+} symbol_t;
+
+typedef struct sector
+{
+ symbol_t begin;
+ symbol_t end;
+ symbol_t size;
+ const char *name;
+} sector_t;
+
+typedef struct list list_t;
+struct list
+{
+ list_t *next;
+ void *data;
+};
+
+typedef struct
+{
+ list_t *first;
+ list_t *last;
+ char *name;
+} head_t;
+
+bank_t dummy_bank = {.name = "dummy",.count = 0 };
+list_t dummy_bank_l = {.next = NULL,.data = (void *) &dummy_bank };
+head_t banks = { &dummy_bank_l, &dummy_bank_l, "banks" };
+
+sector_t dummy_sector = {
+ .begin = {0, NULL},
+ .end = {0, NULL},
+ .size = {0, NULL},
+ .name = NULL
+};
+list_t dummy_sector_l = {.next = NULL,.data = (void *) &dummy_sector };
+head_t sectors = { &dummy_sector_l, &dummy_sector_l, "sectors" };
+
+#if 0
+static void
+print_symbol (symbol_t * s)
+{
+ if (s != NULL)
+ {
+ printf ("%-32s= 0x%016lx;\n", s->str, s->value);
+ }
+}
+
+static void
+print_sector (sector_t * s)
+{
+ print_symbol (&s->begin);
+ print_symbol (&s->end);
+ print_symbol (&s->size);
+}
+#endif
+
+static list_t *
+list_add_to_end (head_t * h, void *element)
+{
+ list_t *e = (list_t *) malloc (sizeof (list_t));
+ if (e != NULL)
+ {
+ e->next = NULL;
+ e->data = element;
+ if (h->first == NULL)
+ {
+ h->first = e;
+ }
+ h->last->next = (void *) e;
+ h->last = (void *) e;
+ }
+ return e;
+}
+
+void
+lang_add_bank (const char *name)
+{
+ bank_t *b = malloc (sizeof (bank_t));
+ list_t *l;
+ if (b == NULL)
+ {
+ einfo (_("%F%P: can not allocate memory for memory bank list: %E\n"));
+ return;
+ }
+ b->name = name;
+ b->count = 0;
+ l = list_add_to_end (&banks, (void *) b);
+ if (l == NULL)
+ {
+ einfo (_("%F%P: can not allocate memory for memory bank: %E\n"));
+ }
+}
+
+void
+lang_add_sector (const char *size)
+{
+ char *p, c;
+ bank_t *b;
+ uint64_t val = strtoull (size, &p, 10);
+ if (errno == ERANGE)
+ return;
+ /* Skip whitespace */
+ while ((c = *p) != 0)
+ {
+ if (c <= ' ')
+ {
+ p++;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* Translate to upper case */
+ {
+ char *tmpp = p;
+
+ while ((c = *tmpp) != 0)
+ {
+ if ((c >= 'a') && (c <= 'z'))
+ {
+ c = c - 'a' + 'A';
+ *tmpp = c;
+ }
+ tmpp++;
+ }
+ }
+
+ /* check for multipliers */
+ if (!strcmp (p, "BYTES"))
+ {
+ val *= 1;
+ }
+ else if (!strcmp (p, "KB"))
+ {
+ val *= 1024;
+ }
+ else if (!strcmp (p, "MB"))
+ {
+ val *= 1024 * 1024;
+ }
+
+ /* Create a sector record - unless dummy sector */
+ b = banks.last->data;
+ if (strncmp (b->name, "dummy", 5))
+ {
+ size_t len;
+ list_t *l;
+ sector_t *s = malloc (sizeof (sector_t));
+ if (s == NULL)
+ {
+ einfo (_("%F%P: can not allocate memory for sector list: %E\n"));
+ return;
+ }
+
+ s->begin.value = b->location;
+ len = asprintf (&s->begin.str, "%s#%02d#begin", b->name, b->count);
+ s->end.value = b->location + val;
+ len += asprintf (&s->end.str, "%s#%02d#end", b->name, b->count);
+ s->size.value = val;
+ len += asprintf (&s->size.str, "%s#%02d#size", b->name, b->count);
+ if (len <= 1)
+ {
+ }; /* 'Use' "len" to avoid warnings */
+ l = list_add_to_end (§ors, (void *) s);
+ if (l == NULL)
+ {
+ einfo (_("%F%P: can not allocate memory for sector: %E\n"));
+ }
+ }
+ b->location += val;
+ b->count++;
+}
+
+static etree_type *
+dot (void)
+{
+ return exp_nameop (NAME, ".");
+}
+
+static etree_type *
+begin_s (sector_t * s)
+{
+ return exp_nameop (NAME, s->begin.str);
+}
+
+static etree_type *
+end_s (sector_t * s)
+{
+ return exp_nameop (NAME, s->end.str);
+}
+
+static etree_type *
+size_s (sector_t * s)
+{
+ return exp_nameop (NAME, s->size.str);
+}
+
+static void
+define_symbol (symbol_t * symbol)
+{
+ etree_type *value = exp_bigintop ((bfd_vma) symbol->value, NULL);
+ lang_add_assignment (exp_assign (symbol->str, value, true));
+}
+
+static void
+define_sector (sector_t * s)
+{
+ define_symbol (&s->begin);
+ define_symbol (&s->end);
+ define_symbol (&s->size);
+}
+
+static bool
+define_sectors (void)
+{
+ sector_t *s;
+ bool present = false;
+ for (list_t * sl = sectors.first->next; sl != NULL; sl = sl->next)
+ {
+ s = (sector_t *) sl->data;
+ define_sector (s);
+ present = true;
+ }
+ return present;
+}
+
+static void
+cond_align_to_sector (sector_t * s)
+{
+ /*
+ * Align, if location is within the sector
+ * . = ( (. <= begin) && (. <= end) ) ? ALIGN(size) : . ;
+ */
+ etree_type *lower = exp_binop (GE, dot (), begin_s (s));
+ etree_type *upper = exp_binop (LE, dot (), end_s (s));
+ etree_type *in_range = exp_binop (ANDAND, lower, upper);
+ etree_type *align = exp_unop (ALIGN_K, size_s (s));
+ etree_type *expr = exp_trinop ('?', in_range, align, dot ());
+ lang_add_assignment (exp_assign (".", expr, false));
+}
+
+void
+lang_align_sector (void)
+{
+ static bool defined = false;
+ if (!defined)
+ {
+ defined = define_sectors ();
+ }
+ if (!defined)
+ {
+ einfo (_("%F%P: 'ALIGN_SECTOR' needs to be preceeded by a"
+ " 'BANK' command\n"));
+ }
+ for (list_t * sl = sectors.first->next; sl != NULL; sl = sl->next)
+ {
+ cond_align_to_sector ((sector_t *) sl->data);
+ }
+}
diff --git a/ld/sysdep.h b/ld/sysdep.h
index 3601a59a6ac..7d25e83ef53 100644
--- a/ld/sysdep.h
+++ b/ld/sysdep.h
@@ -41,6 +41,8 @@
#include <unistd.h>
#endif
+#include <errno.h>
+
#ifdef HAVE_REALPATH
# define REALPATH(a,b) realpath (a, b)
#else
--
2.34.1
next prev parent reply other threads:[~2023-03-10 0:09 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-10 0:08 [PATCH v1 0/7 SECTOR: Support aligning to flash sector boundary binutils
2023-03-10 0:08 ` [PATCH v1 1/7] SECTOR: NEWS binutils
2023-03-10 0:08 ` [PATCH v1 2/7] SECTOR: ld.texi binutils
2023-03-10 0:08 ` [PATCH v1 3/7] SECTOR: ldlex.l binutils
2023-03-10 0:08 ` [PATCH v1 4/7] SECTOR: ldgram.y binutils
2023-03-10 0:08 ` binutils [this message]
2023-03-10 0:08 ` [PATCH v1 6/7] SECTOR: add testsuite binutils
2023-03-10 0:08 ` [PATCH v1 7/7] SECTOR: Makefile.* binutils
2023-03-10 3:46 ` [PATCH v1 0/7 SECTOR: Support aligning to flash sector boundary Alan Modra
2023-03-10 14:13 ` Michael Matz
2023-03-10 17:01 ` Ulf Samuelsson
2023-03-10 17:30 ` Michael Matz
2023-03-10 17:57 ` Ulf Samuelsson
2023-03-13 13:12 ` Michael Matz
2023-03-13 15:29 ` Ulf Samuelsson
2023-03-13 15:54 ` Michael Matz
2023-03-13 17:26 ` Ulf Samuelsson
2023-03-13 17:35 ` Michael Matz
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=20230310000817.751962-6-binutils@emagii.com \
--to=binutils@emagii.com \
--cc=binutils@sourceware.org \
--cc=nickc@redhat.com \
--cc=ulf@emagii.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).