Skip to content

Commit bcbba25

Browse files
committed
elf symbol size
This changes elf_obj_sy.size from being malloc'd to being on the notes obstack. That means no code needs to free these expressions, which in turn means that the size expression can be shared when cloning symbols. Nothing modifies the size expressions except when resolving. In all cases I could see, if the size changes the entire expression is replaced. The patch also extracts code from elf_copy_symbol_attributes into a separate function for use by riscv and aarch64. * config/obj-elf.c (elf_obj_symbol_clone_hook): Delete. (elf_copy_symbol_size): New function, extracted and modified from.. (elf_copy_symbol_attributes): ..here. (obj_elf_size): Don't free size and use notes_alloc. (elf_frob_symbol): Don't free size. (elf_format_ops): Zero symbol_clone_hook. * config/obj-elf.h (elf_obj_symbol_clone_hook): Delete. (obj_symbol_clone_hook): Don't define. (elf_copy_symbol_size): Declare. * config/tc-aarch64.c (aarch64_elf_copy_symbol_attributes): Delete. * config/tc-aarch64.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Define as elf_copy_symbol_size. * config/tc-alpha.c (s_alpha_end): notes_alloc symbol size exp. * config/tc-ia64.c (dot_endp): Likewise. * config/tc-kvx.c (kvx_endp): Likewise. * config/tc-mips.c (s_mips_end): Likewise. * config/tc-riscv.c (riscv_elf_copy_symbol_attributes): Delete. * config/tc-riscv.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Define as elf_copy_symbol_size.
1 parent da79d62 commit bcbba25

File tree

10 files changed

+43
-111
lines changed

10 files changed

+43
-111
lines changed

gas/config/obj-elf.c

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2273,39 +2273,25 @@ elf_obj_symbol_new_hook (symbolS *symbolP)
22732273
#endif
22742274
}
22752275

2276-
/* Deduplicate size expressions. We might get into trouble with
2277-
multiple freeing or use after free if we leave them pointing to the
2278-
same expressionS. */
2279-
2276+
/* If size is unset, copy size from src. Because we don't track whether
2277+
.size has been used, we can't differentiate .size dest, 0 from the case
2278+
where dest's size is unset. */
22802279
void
2281-
elf_obj_symbol_clone_hook (symbolS *newsym, symbolS *orgsym ATTRIBUTE_UNUSED)
2280+
elf_copy_symbol_size (symbolS *dest, symbolS *src)
22822281
{
2283-
struct elf_obj_sy *newelf = symbol_get_obj (newsym);
2284-
if (newelf->size)
2282+
struct elf_obj_sy *srcelf = symbol_get_obj (src);
2283+
struct elf_obj_sy *destelf = symbol_get_obj (dest);
2284+
if (!destelf->size && S_GET_SIZE (dest) == 0)
22852285
{
2286-
expressionS *exp = XNEW (expressionS);
2287-
*exp = *newelf->size;
2288-
newelf->size = exp;
2286+
destelf->size = srcelf->size;
2287+
S_SET_SIZE (dest, S_GET_SIZE (src));
22892288
}
22902289
}
22912290

22922291
void
22932292
elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
22942293
{
2295-
struct elf_obj_sy *srcelf = symbol_get_obj (src);
2296-
struct elf_obj_sy *destelf = symbol_get_obj (dest);
2297-
/* If size is unset, copy size from src. Because we don't track whether
2298-
.size has been used, we can't differentiate .size dest, 0 from the case
2299-
where dest's size is unset. */
2300-
if (!destelf->size && S_GET_SIZE (dest) == 0)
2301-
{
2302-
if (srcelf->size)
2303-
{
2304-
destelf->size = XNEW (expressionS);
2305-
*destelf->size = *srcelf->size;
2306-
}
2307-
S_SET_SIZE (dest, S_GET_SIZE (src));
2308-
}
2294+
elf_copy_symbol_size (dest, src);
23092295
/* Don't copy visibility. */
23102296
S_SET_OTHER (dest, (ELF_ST_VISIBILITY (S_GET_OTHER (dest))
23112297
| (S_GET_OTHER (src) & ~ELF_ST_VISIBILITY (-1))));
@@ -2404,12 +2390,11 @@ obj_elf_size (int ignore ATTRIBUTE_UNUSED)
24042390
if (exp.X_op == O_constant)
24052391
{
24062392
S_SET_SIZE (sym, exp.X_add_number);
2407-
xfree (symbol_get_obj (sym)->size);
24082393
symbol_get_obj (sym)->size = NULL;
24092394
}
24102395
else
24112396
{
2412-
symbol_get_obj (sym)->size = XNEW (expressionS);
2397+
symbol_get_obj (sym)->size = notes_alloc (sizeof (exp));
24132398
*symbol_get_obj (sym)->size = exp;
24142399
}
24152400

@@ -2805,7 +2790,6 @@ elf_frob_symbol (symbolS *symp, int *puntp)
28052790
as_warn (_(".size expression for %s "
28062791
"does not evaluate to a constant"), S_GET_NAME (symp));
28072792
}
2808-
free (sy_obj->size);
28092793
sy_obj->size = NULL;
28102794
}
28112795

@@ -3336,7 +3320,7 @@ const struct format_ops elf_format_ops =
33363320
#endif
33373321
elf_obj_read_begin_hook,
33383322
elf_obj_symbol_new_hook,
3339-
elf_obj_symbol_clone_hook,
3323+
0,
33403324
elf_adjust_symtab
33413325
};
33423326

gas/config/obj-elf.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,11 +224,7 @@ void elf_obj_symbol_new_hook (symbolS *);
224224
#define obj_symbol_new_hook elf_obj_symbol_new_hook
225225
#endif
226226

227-
void elf_obj_symbol_clone_hook (symbolS *, symbolS *);
228-
#ifndef obj_symbol_clone_hook
229-
#define obj_symbol_clone_hook elf_obj_symbol_clone_hook
230-
#endif
231-
227+
void elf_copy_symbol_size (symbolS *, symbolS *);
232228
void elf_copy_symbol_attributes (symbolS *, symbolS *);
233229
#ifndef OBJ_COPY_SYMBOL_ATTRIBUTES
234230
#define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST, SRC) \

gas/config/tc-aarch64.c

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11277,34 +11277,3 @@ aarch64_copy_symbol_attributes (symbolS * dest, symbolS * src)
1127711277
{
1127811278
AARCH64_GET_FLAG (dest) = AARCH64_GET_FLAG (src);
1127911279
}
11280-
11281-
#ifdef OBJ_ELF
11282-
/* Same as elf_copy_symbol_attributes, but without copying st_other.
11283-
This is needed so AArch64 specific st_other values can be independently
11284-
specified for an IFUNC resolver (that is called by the dynamic linker)
11285-
and the symbol it resolves (aliased to the resolver). In particular,
11286-
if a function symbol has special st_other value set via directives,
11287-
then attaching an IFUNC resolver to that symbol should not override
11288-
the st_other setting. Requiring the directive on the IFUNC resolver
11289-
symbol would be unexpected and problematic in C code, where the two
11290-
symbols appear as two independent function declarations. */
11291-
11292-
void
11293-
aarch64_elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
11294-
{
11295-
struct elf_obj_sy *srcelf = symbol_get_obj (src);
11296-
struct elf_obj_sy *destelf = symbol_get_obj (dest);
11297-
/* If size is unset, copy size from src. Because we don't track whether
11298-
.size has been used, we can't differentiate .size dest, 0 from the case
11299-
where dest's size is unset. */
11300-
if (!destelf->size && S_GET_SIZE (dest) == 0)
11301-
{
11302-
if (srcelf->size)
11303-
{
11304-
destelf->size = XNEW (expressionS);
11305-
*destelf->size = *srcelf->size;
11306-
}
11307-
S_SET_SIZE (dest, S_GET_SIZE (src));
11308-
}
11309-
}
11310-
#endif

gas/config/tc-aarch64.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,17 @@ void aarch64_copy_symbol_attributes (symbolS *, symbolS *);
133133
#endif
134134

135135
#ifdef OBJ_ELF
136-
void aarch64_elf_copy_symbol_attributes (symbolS *, symbolS *);
136+
/* Don't copy st_other.
137+
This is needed so AArch64 specific st_other values can be independently
138+
specified for an IFUNC resolver (that is called by the dynamic linker)
139+
and the symbol it resolves (aliased to the resolver). In particular,
140+
if a function symbol has special st_other value set via directives,
141+
then attaching an IFUNC resolver to that symbol should not override
142+
the st_other setting. Requiring the directive on the IFUNC resolver
143+
symbol would be unexpected and problematic in C code, where the two
144+
symbols appear as two independent function declarations. */
137145
#define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST, SRC) \
138-
aarch64_elf_copy_symbol_attributes (DEST, SRC)
146+
elf_copy_symbol_size (DEST, SRC)
139147
#endif
140148

141149
#define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR) \

gas/config/tc-alpha.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3789,7 +3789,7 @@ s_alpha_end (int dummy ATTRIBUTE_UNUSED)
37893789
if (sym && cur_frame_data)
37903790
{
37913791
OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
3792-
expressionS *exp = XNEW (expressionS);
3792+
expressionS *exp = notes_alloc (sizeof (*exp));
37933793

37943794
obj->size = exp;
37953795
exp->X_op = O_subtract;

gas/config/tc-ia64.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4476,13 +4476,14 @@ dot_endp (int dummy ATTRIBUTE_UNUSED)
44764476
S_SET_SIZE (sym, frag_now_fix () - S_GET_VALUE (sym));
44774477
else
44784478
{
4479-
symbol_get_obj (sym)->size = XNEW (expressionS);
4480-
symbol_get_obj (sym)->size->X_op = O_subtract;
4481-
symbol_get_obj (sym)->size->X_add_symbol
4479+
OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
4480+
obj->size = notes_alloc (sizeof (*obj->size));
4481+
obj->size->X_op = O_subtract;
4482+
obj->size->X_add_symbol
44824483
= symbol_new (FAKE_LABEL_NAME, now_seg,
44834484
frag_now, frag_now_fix ());
4484-
symbol_get_obj (sym)->size->X_op_symbol = sym;
4485-
symbol_get_obj (sym)->size->X_add_number = 0;
4485+
obj->size->X_op_symbol = sym;
4486+
obj->size->X_add_number = 0;
44864487
}
44874488
}
44884489
}

gas/config/tc-kvx.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2355,16 +2355,11 @@ kvx_endp (int start ATTRIBUTE_UNUSED)
23552355
if (exp.X_op == O_constant)
23562356
{
23572357
S_SET_SIZE (last_proc_sym, exp.X_add_number);
2358-
if (symbol_get_obj (last_proc_sym)->size)
2359-
{
2360-
xfree (symbol_get_obj (last_proc_sym)->size);
2361-
symbol_get_obj (last_proc_sym)->size = NULL;
2362-
}
2358+
symbol_get_obj (last_proc_sym)->size = NULL;
23632359
}
23642360
else
23652361
{
2366-
symbol_get_obj (last_proc_sym)->size =
2367-
(expressionS *) xmalloc (sizeof (expressionS));
2362+
symbol_get_obj (last_proc_sym)->size = notes_alloc (sizeof (exp));
23682363
*symbol_get_obj (last_proc_sym)->size = exp;
23692364
}
23702365

gas/config/tc-mips.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19809,7 +19809,7 @@ s_mips_end (int x ATTRIBUTE_UNUSED)
1980919809
if (p && cur_proc_ptr)
1981019810
{
1981119811
OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (p);
19812-
expressionS *exp = XNEW (expressionS);
19812+
expressionS *exp = notes_alloc (sizeof (*exp));
1981319813

1981419814
obj->size = exp;
1981519815
exp->X_op = O_subtract;

gas/config/tc-riscv.c

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5889,35 +5889,6 @@ s_variant_cc (int ignored ATTRIBUTE_UNUSED)
58895889
elfsym->internal_elf_sym.st_other |= STO_RISCV_VARIANT_CC;
58905890
}
58915891

5892-
/* Same as elf_copy_symbol_attributes, but without copying st_other.
5893-
This is needed so RISC-V specific st_other values can be independently
5894-
specified for an IFUNC resolver (that is called by the dynamic linker)
5895-
and the symbol it resolves (aliased to the resolver). In particular,
5896-
if a function symbol has special st_other value set via directives,
5897-
then attaching an IFUNC resolver to that symbol should not override
5898-
the st_other setting. Requiring the directive on the IFUNC resolver
5899-
symbol would be unexpected and problematic in C code, where the two
5900-
symbols appear as two independent function declarations. */
5901-
5902-
void
5903-
riscv_elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
5904-
{
5905-
struct elf_obj_sy *srcelf = symbol_get_obj (src);
5906-
struct elf_obj_sy *destelf = symbol_get_obj (dest);
5907-
/* If size is unset, copy size from src. Because we don't track whether
5908-
.size has been used, we can't differentiate .size dest, 0 from the case
5909-
where dest's size is unset. */
5910-
if (!destelf->size && S_GET_SIZE (dest) == 0)
5911-
{
5912-
if (srcelf->size)
5913-
{
5914-
destelf->size = XNEW (expressionS);
5915-
*destelf->size = *srcelf->size;
5916-
}
5917-
S_SET_SIZE (dest, S_GET_SIZE (src));
5918-
}
5919-
}
5920-
59215892
/* RISC-V pseudo-ops table. */
59225893
static const pseudo_typeS riscv_pseudo_table[] =
59235894
{

gas/config/tc-riscv.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,16 @@ extern void riscv_init_frag (struct frag *, int);
175175
#define obj_adjust_symtab() riscv_adjust_symtab ()
176176
extern void riscv_adjust_symtab (void);
177177

178-
void riscv_elf_copy_symbol_attributes (symbolS *, symbolS *);
178+
/* Don't copy st_other.
179+
This is needed so RISC-V specific st_other values can be independently
180+
specified for an IFUNC resolver (that is called by the dynamic linker)
181+
and the symbol it resolves (aliased to the resolver). In particular,
182+
if a function symbol has special st_other value set via directives,
183+
then attaching an IFUNC resolver to that symbol should not override
184+
the st_other setting. Requiring the directive on the IFUNC resolver
185+
symbol would be unexpected and problematic in C code, where the two
186+
symbols appear as two independent function declarations. */
179187
#define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST, SRC) \
180-
riscv_elf_copy_symbol_attributes (DEST, SRC)
188+
elf_copy_symbol_size (DEST, SRC)
181189

182190
#endif /* TC_RISCV */

0 commit comments

Comments
 (0)