aboutsummaryrefslogtreecommitdiff
path: root/ld/ldlang.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2023-02-16 16:27:08 +0000
committerNick Clifton <nickc@redhat.com>2023-02-16 16:27:08 +0000
commit9fe129a4105bb59398f73ce96938a94f19265b79 (patch)
tree33772b47038b290b37158f78813bab4ce8360958 /ld/ldlang.c
parent6f63b61dd116becf96f47bb2dec61edd59f88a08 (diff)
downloadbinutils-9fe129a4105bb59398f73ce96938a94f19265b79.zip
binutils-9fe129a4105bb59398f73ce96938a94f19265b79.tar.gz
binutils-9fe129a4105bb59398f73ce96938a94f19265b79.tar.bz2
Add support for the ASCII directive inside linker scripts.
* ldlex.l: Add ASCII token. * ldgram.y: Add parsing of the ASCII command. * ldlang.c (lang_add_string): Add maximum size parameter. Move escape character handling code into separate function. * ldlang.h (lang_add_string): Update prototype. * NEWS: Mention the new feature. * ld.texi (Output Section Data): Document the new directives. * testsuite/ld-scripts/asciz.t: Adjust to work on more architectures and to test more aspects of the ASCIZ directive. * testsuite/ld-scripts/asciz.d: Adjust to match the changes to the test linker script. * testsuite/ld-scripts/ascii.d: New test driver. * testsuite/ld-scripts/ascii.s: New test assembler source. * testsuite/ld-scripts/ascii.t: New test script. * testsuite/ld-scripts/script.exp: Run the new test.
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r--ld/ldlang.c69
1 files changed, 53 insertions, 16 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c
index b20455c..2852a42 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -8361,15 +8361,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 = malloc (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++;
@@ -8404,7 +8409,7 @@ lang_add_string (const char *s)
value += (c - '0');
i++;
s++;
-
+
c = *s;
if ((c >= '0') && (c <= '7'))
{
@@ -8422,26 +8427,58 @@ lang_add_string (const char *s)
i--;
s--;
}
-
+
c = value;
}
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\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