[PATCH v4 3/7] ldlang.*: process ASCII command
binutils@emagii.com
binutils@emagii.com
Mon Jul 8 17:49:25 GMT 2024
From: Ulf Samuelsson <ulf@emagii.com>
Signed-off-by: Ulf Samuelsson <ulf@emagii.com>
---
ld/ldlang.c | 65 +++++++++++++++++++++++++++++++++++++++++------------
ld/ldlang.h | 2 +-
2 files changed, 52 insertions(+), 15 deletions(-)
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 9e8cc224f4d..902e82ecf59 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -8663,15 +8663,20 @@ lang_add_data (int type, union etree_union *exp)
new_stmt->type = type;
}
-void
-lang_add_string (const char *s)
+/* Convert escape codes in S.
+ Supports \n, \r, \t and \NNN octals.
+ Returns a copy of S in a malloc'ed buffer. */
+
+static char *
+convert_string (const char * s)
{
- bfd_vma len = strlen (s);
- bfd_vma i;
- bool escape = false;
+ size_t len = strlen (s);
+ size_t i;
+ bool escape = false;
+ char * buffer = xmalloc (len + 1);
+ char * b;
- /* Add byte expressions until end of string. */
- for (i = 0 ; i < len; i++)
+ for (i = 0, b = buffer; i < len; i++)
{
char c = *s++;
@@ -8729,21 +8734,53 @@ lang_add_string (const char *s)
}
break;
}
-
- lang_add_data (BYTE, exp_intop (c));
escape = false;
}
else
{
if (c == '\\')
- escape = true;
- else
- lang_add_data (BYTE, exp_intop (c));
+ {
+ escape = true;
+ continue;
+ }
}
+
+ * b ++ = c;
+ }
+
+ * b = 0;
+ return buffer;
+}
+
+void
+lang_add_string (size_t size, const char *s)
+{
+ size_t len;
+ size_t i;
+ char * string;
+
+ string = convert_string (s);
+ len = strlen (string);
+
+ /* Check if it is ASCIZ command (len == 0) */
+ if (size == 0)
+ /* Make sure that we include the terminating NUL byte. */
+ size = len + 1;
+ else if (len > size)
+ {
+ len = size - 1;
+
+ einfo (_("%P:%pS: warning: ASCII string does not fit in allocated space,"
+ " truncated, terminating with NUL.\n"), NULL);
}
- /* Remeber to terminate the string. */
- lang_add_data (BYTE, exp_intop (0));
+ for (i = 0; i < len; i++)
+ lang_add_data (BYTE, exp_intop (string[i]));
+
+ while (i++ < size)
+ lang_add_data (BYTE, exp_intop ('\0'));
+
+ free (string);
}
/* Create a new reloc statement. RELOC is the BFD relocation type to
diff --git a/ld/ldlang.h b/ld/ldlang.h
index f36e04c586a..bf1b602799c 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -656,7 +656,7 @@ extern void pop_stat_ptr
extern void lang_add_data
(int, union etree_union *);
extern void lang_add_string
- (const char *);
+ (size_t, const char *s);
extern void lang_add_reloc
(bfd_reloc_code_real_type, reloc_howto_type *, asection *, const char *,
union etree_union *);
--
2.17.1
More information about the Binutils
mailing list