mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-03 04:12:10 +08:00
gas: fold symbol table entries generated for .startof.() / .sizeof.()
When the same such construct is used multiple times in a source file, there's still no need to emit a separate symbol each time. Under the assumption that there won't be many of these, use a simple array lookup method to record previously used symbols.
This commit is contained in:
parent
1fef66b0dc
commit
162c6aef1f
@ -1,3 +1,10 @@
|
||||
2021-06-18 Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
* expr.c (symbol_lookup_or_make): New.
|
||||
(operand): Use it.
|
||||
* testsuite/gas/elf/startof.s, testsuite/gas/elf/startof.d: New.
|
||||
* testsuite/gas/elf/elf.exp: Run new test.
|
||||
|
||||
2021-06-17 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 27904
|
||||
|
55
gas/expr.c
55
gas/expr.c
@ -127,6 +127,52 @@ expr_symbol_where (symbolS *sym, const char **pfile, unsigned int *pline)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Look up a previously used .startof. / .sizeof. symbol, or make a fresh
|
||||
one. */
|
||||
|
||||
static symbolS *
|
||||
symbol_lookup_or_make (const char *name, bool start)
|
||||
{
|
||||
static symbolS **seen[2];
|
||||
static unsigned int nr_seen[2];
|
||||
char *buf = concat (start ? ".startof." : ".sizeof.", name, NULL);
|
||||
symbolS *symbolP;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < nr_seen[start]; ++i)
|
||||
{
|
||||
symbolP = seen[start][i];
|
||||
|
||||
if (! symbolP)
|
||||
break;
|
||||
|
||||
name = S_GET_NAME (symbolP);
|
||||
if ((symbols_case_sensitive
|
||||
? strcasecmp (buf, name)
|
||||
: strcmp (buf, name)) == 0)
|
||||
{
|
||||
free (buf);
|
||||
return symbolP;
|
||||
}
|
||||
}
|
||||
|
||||
symbolP = symbol_make (buf);
|
||||
free (buf);
|
||||
|
||||
if (i >= nr_seen[start])
|
||||
{
|
||||
unsigned int nr = (i + 1) * 2;
|
||||
|
||||
seen[start] = XRESIZEVEC (symbolS *, seen[start], nr);
|
||||
nr_seen[start] = nr;
|
||||
memset (&seen[start][i + 1], 0, (nr - i - 1) * sizeof(seen[0][0]));
|
||||
}
|
||||
|
||||
seen[start][i] = symbolP;
|
||||
|
||||
return symbolP;
|
||||
}
|
||||
|
||||
/* Utilities for building expressions.
|
||||
Since complex expressions are recorded as symbols for use in other
|
||||
@ -1159,8 +1205,6 @@ operand (expressionS *expressionP, enum expr_mode mode)
|
||||
as_bad (_("syntax error in .startof. or .sizeof."));
|
||||
else
|
||||
{
|
||||
char *buf;
|
||||
|
||||
++input_line_pointer;
|
||||
SKIP_WHITESPACE ();
|
||||
c = get_symbol_name (& name);
|
||||
@ -1175,13 +1219,8 @@ operand (expressionS *expressionP, enum expr_mode mode)
|
||||
break;
|
||||
}
|
||||
|
||||
buf = concat (start ? ".startof." : ".sizeof.", name,
|
||||
(char *) NULL);
|
||||
symbolP = symbol_make (buf);
|
||||
free (buf);
|
||||
|
||||
expressionP->X_op = O_symbol;
|
||||
expressionP->X_add_symbol = symbolP;
|
||||
expressionP->X_add_symbol = symbol_lookup_or_make (name, start);
|
||||
expressionP->X_add_number = 0;
|
||||
|
||||
*input_line_pointer = c;
|
||||
|
@ -309,6 +309,7 @@ if { [is_elf_format] } then {
|
||||
run_dump_test "pr27355"
|
||||
|
||||
run_dump_test "syms"
|
||||
run_dump_test "startof"
|
||||
|
||||
run_dump_test "missing-build-notes"
|
||||
|
||||
|
10
gas/testsuite/gas/elf/startof.d
Normal file
10
gas/testsuite/gas/elf/startof.d
Normal file
@ -0,0 +1,10 @@
|
||||
#name: .startof. / .sizeof.
|
||||
#readelf: -s
|
||||
|
||||
Symbol table .*
|
||||
Num: .*
|
||||
0: 0+ .*
|
||||
#...
|
||||
[1-8]: 0+ .* UND \.startof\.\.text
|
||||
[2-9]: 0+ .* UND \.sizeof\.\.text
|
||||
#pass
|
6
gas/testsuite/gas/elf/startof.s
Normal file
6
gas/testsuite/gas/elf/startof.s
Normal file
@ -0,0 +1,6 @@
|
||||
.data
|
||||
.dc.a .startof.(.text)
|
||||
.dc.a .sizeof.(.text)
|
||||
.dc.a 0
|
||||
.dc.a .sizeof.(.text)
|
||||
.dc.a .startof.(.text)
|
Loading…
Reference in New Issue
Block a user