public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
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 (&sectors, (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


  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).