ASCIZ Command for output section

Adds a new directive to the linker script syntax: ASCIZ.
This inserts a zero-terminated string into the output at the place where it is used.
This commit is contained in:
Ulf Samuelsson 2023-02-14 10:13:28 +00:00 committed by Nick Clifton
parent 12ef683055
commit 0d79a2a8e2
10 changed files with 157 additions and 3 deletions

View File

@ -1,5 +1,8 @@
-*- text -*- -*- text -*-
* The linker script syntax has a new command for output sections: ASCIZ "string"
This will insert a zero-terminated string at the current location.
Changes in 2.40: Changes in 2.40:
* The linker has a new command line option to suppress the generation of any * The linker has a new command line option to suppress the generation of any

View File

@ -5308,6 +5308,7 @@ C identifiers because they contain a @samp{.} character.
@cindex data @cindex data
@cindex section data @cindex section data
@cindex output section data @cindex output section data
@kindex ASCIZ ``@var{string}''
@kindex BYTE(@var{expression}) @kindex BYTE(@var{expression})
@kindex SHORT(@var{expression}) @kindex SHORT(@var{expression})
@kindex LONG(@var{expression}) @kindex LONG(@var{expression})
@ -5344,6 +5345,18 @@ When the object file format does not have an explicit endianness, as is
true of, for example, S-records, the value will be stored in the true of, for example, S-records, the value will be stored in the
endianness of the first input object file. endianness of the first input object file.
You can include a zero-terminated string in an output section by using
@code{ASCIZ}. The keyword is followed by a string which is stored at
the current value of the location counter adding a zero byte at the
end. If the string includes spaces it must be enclosed in double
quotes. The string may contain '\n', '\r', '\t' and octal numbers.
Hex numbers are not supported.
For example, this string of 16 characters will create a 17 byte area
@smallexample
ASCIZ "This is 16 bytes"
@end smallexample
Note---these commands only work inside a section description and not Note---these commands only work inside a section description and not
between them, so the following will produce an error from the linker: between them, so the following will produce an error from the linker:
@smallexample @smallexample

View File

@ -125,7 +125,7 @@ static int error_index;
%right UNARY %right UNARY
%token END %token END
%left <token> '(' %left <token> '('
%token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE %token <token> ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE ASCIZ
%token SECTIONS PHDRS INSERT_K AFTER BEFORE %token SECTIONS PHDRS INSERT_K AFTER BEFORE
%token DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END %token DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END
%token SORT_BY_NAME SORT_BY_ALIGNMENT SORT_NONE %token SORT_BY_NAME SORT_BY_ALIGNMENT SORT_NONE
@ -668,7 +668,10 @@ statement:
{ {
lang_add_data ((int) $1, $3); lang_add_data ((int) $1, $3);
} }
| ASCIZ NAME
{
lang_add_string ($2);
}
| FILL '(' fill_exp ')' | FILL '(' fill_exp ')'
{ {
lang_add_fill ($3); lang_add_fill ($3);

View File

@ -8361,6 +8361,89 @@ lang_add_data (int type, union etree_union *exp)
new_stmt->type = type; new_stmt->type = type;
} }
void
lang_add_string (const char *s)
{
bfd_vma len = strlen (s);
bfd_vma i;
bool escape = false;
/* Add byte expressions until end of string. */
for (i = 0 ; i < len; i++)
{
char c = *s++;
if (escape)
{
switch (c)
{
default:
/* Ignore the escape. */
break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
/* We have an octal number. */
{
unsigned int value = c - '0';
c = *s;
if ((c >= '0') && (c <= '7'))
{
value <<= 3;
value += (c - '0');
i++;
s++;
c = *s;
if ((c >= '0') && (c <= '7'))
{
value <<= 3;
value += (c - '0');
i++;
s++;
}
}
if (value > 0xff)
{
/* octal: \777 is treated as '\077' + '7' */
value >>= 3;
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));
}
}
/* Remeber to terminate the string. */
lang_add_data (BYTE, exp_intop (0));
}
/* Create a new reloc statement. RELOC is the BFD relocation type to /* Create a new reloc statement. RELOC is the BFD relocation type to
generate. HOWTO is the corresponding howto structure (we could generate. HOWTO is the corresponding howto structure (we could
look this up, but the caller has already done so). SECTION is the look this up, but the caller has already done so). SECTION is the

View File

@ -645,7 +645,9 @@ extern void push_stat_ptr
extern void pop_stat_ptr extern void pop_stat_ptr
(void); (void);
extern void lang_add_data extern void lang_add_data
(int type, union etree_union *); (int, union etree_union *);
extern void lang_add_string
(const char *);
extern void lang_add_reloc extern void lang_add_reloc
(bfd_reloc_code_real_type, reloc_howto_type *, asection *, const char *, (bfd_reloc_code_real_type, reloc_howto_type *, asection *, const char *,
union etree_union *); union etree_union *);

View File

@ -309,6 +309,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
<WILD>"LONG" { RTOKEN(LONG); } <WILD>"LONG" { RTOKEN(LONG); }
<WILD>"SHORT" { RTOKEN(SHORT); } <WILD>"SHORT" { RTOKEN(SHORT); }
<WILD>"BYTE" { RTOKEN(BYTE); } <WILD>"BYTE" { RTOKEN(BYTE); }
<WILD>"ASCIZ" { RTOKEN(ASCIZ); }
<SCRIPT>"NOFLOAT" { RTOKEN(NOFLOAT); } <SCRIPT>"NOFLOAT" { RTOKEN(NOFLOAT); }
<SCRIPT,EXPRESSION>"NOCROSSREFS" { RTOKEN(NOCROSSREFS); } <SCRIPT,EXPRESSION>"NOCROSSREFS" { RTOKEN(NOCROSSREFS); }
<SCRIPT,EXPRESSION>"NOCROSSREFS_TO" { RTOKEN(NOCROSSREFS_TO); } <SCRIPT,EXPRESSION>"NOCROSSREFS_TO" { RTOKEN(NOCROSSREFS_TO); }

View File

@ -0,0 +1,17 @@
#source: asciz.s
#ld: -T asciz.t
#objdump: -s -j .text
#target: [is_elf_format]
#skip: mips*-*-*
#skip: tilegx*-*-* tilepro-*-*
# COFF, PE and MIPS targets align code to a 16 byte boundary
# tilegx andtilepro aligns code to a 8 byte boundary.
.*: file format .*
Contents of section .text:
.... 01010101 54686973 20697320 61207374 ....This is a st
.... 72696e67 00...... ........ ........ ring............
.... 54686973 20697320 616e6f74 68657220 This is another
.... 0a737472 696e6753 00 .stringS........
#pass

View File

@ -0,0 +1,8 @@
.section .text
.long 0x01010101
.section .data
.long 0x9abcdef0
.section .bss
.long 0

View File

@ -0,0 +1,23 @@
MEMORY {
rom : ORIGIN = 0x00000, LENGTH = 0x10000
ram : ORIGIN = 0x10000, LENGTH = 0x10000
}
_start = 0x000000;
SECTIONS
{
. = 0x1000 + SIZEOF_HEADERS;
.text ALIGN (0x20) :
{
*(.text)
ASCIZ "This is a string"
. = ALIGN(0x20);
align_label = .;
ASCIZ "This is another \nstring\123"
unalign_label = .;
}
.data : AT (0x10000) { *(.data) } >ram /* NO default AT>rom */
. = ALIGN(0x20);
.bss : { *(.bss) } >ram /* NO default AT>rom */
/DISCARD/ : { *(*) }
}

View File

@ -227,6 +227,7 @@ foreach test_script $test_script_list {
run_dump_test [string range $test_script 0 end-2] run_dump_test [string range $test_script 0 end-2]
} }
run_dump_test "asciz"
run_dump_test "align-with-input" run_dump_test "align-with-input"
run_dump_test "pr20302" run_dump_test "pr20302"
run_dump_test "output-section-types" run_dump_test "output-section-types"