diff options
author | Nick Clifton <nickc@redhat.com> | 2023-02-16 16:27:08 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2023-02-16 16:27:08 +0000 |
commit | 9fe129a4105bb59398f73ce96938a94f19265b79 (patch) | |
tree | 33772b47038b290b37158f78813bab4ce8360958 /ld/ldlang.c | |
parent | 6f63b61dd116becf96f47bb2dec61edd59f88a08 (diff) | |
download | binutils-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.c | 69 |
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 |