mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-25 04:49:54 +08:00
x86: relax when/how @size can be used
Allow a few more expression forms when the entire expression can be resolved at assembly time. For this, i386_validate_fix() needs to arrange for all processing of the relocation to be deferred to tc_gen_reloc().
This commit is contained in:
@ -1,3 +1,17 @@
|
||||
2021-04-29 Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
* config/tc-i386.c (i386_validate_fix): Change return type to
|
||||
int. Short-circuit BFD_RELOC_SIZE* handling.
|
||||
(tc_gen_reloc): New local variable sym. Extend logic when
|
||||
processing BFD_RELOC_SIZE*.
|
||||
* config/tc-i386.f (i386_validate_fix): Change return type to
|
||||
int.
|
||||
(TC_VALIDATE_FIX): Proceed to SKIP when i386_validate_fix()
|
||||
returns zero.
|
||||
* testsuite/gas/i386/size-5.s, testsuite/gas/i386/size-5a.d,
|
||||
testsuite/gas/i386/size-5b.d: New.
|
||||
* testsuite/gas/i386/i386.exp: Run new tests.
|
||||
|
||||
2021-04-29 Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
* config/tc-i386.c (tc_gen_reloc): Use section size for section
|
||||
|
@ -14173,9 +14173,17 @@ i386_cons_align (int ignore ATTRIBUTE_UNUSED)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
i386_validate_fix (fixS *fixp)
|
||||
{
|
||||
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
||||
if (fixp->fx_r_type == BFD_RELOC_SIZE32
|
||||
|| fixp->fx_r_type == BFD_RELOC_SIZE64)
|
||||
return IS_ELF && fixp->fx_addsy
|
||||
&& (!S_IS_DEFINED (fixp->fx_addsy)
|
||||
|| S_IS_EXTERNAL (fixp->fx_addsy));
|
||||
#endif
|
||||
|
||||
if (fixp->fx_subsy)
|
||||
{
|
||||
if (fixp->fx_subsy == GOT_symbol)
|
||||
@ -14222,6 +14230,8 @@ i386_validate_fix (fixS *fixp)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
arelent *
|
||||
@ -14233,18 +14243,38 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
|
||||
switch (fixp->fx_r_type)
|
||||
{
|
||||
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
|
||||
symbolS *sym;
|
||||
|
||||
case BFD_RELOC_SIZE32:
|
||||
case BFD_RELOC_SIZE64:
|
||||
if (IS_ELF
|
||||
&& S_IS_DEFINED (fixp->fx_addsy)
|
||||
&& !S_IS_EXTERNAL (fixp->fx_addsy))
|
||||
if (fixp->fx_addsy
|
||||
&& !bfd_is_abs_section (S_GET_SEGMENT (fixp->fx_addsy))
|
||||
&& (!fixp->fx_subsy
|
||||
|| bfd_is_abs_section (S_GET_SEGMENT (fixp->fx_subsy))))
|
||||
sym = fixp->fx_addsy;
|
||||
else if (fixp->fx_subsy
|
||||
&& !bfd_is_abs_section (S_GET_SEGMENT (fixp->fx_subsy))
|
||||
&& (!fixp->fx_addsy
|
||||
|| bfd_is_abs_section (S_GET_SEGMENT (fixp->fx_addsy))))
|
||||
sym = fixp->fx_subsy;
|
||||
else
|
||||
sym = NULL;
|
||||
if (IS_ELF && sym && S_IS_DEFINED (sym) && !S_IS_EXTERNAL (sym))
|
||||
{
|
||||
/* Resolve size relocation against local symbol to size of
|
||||
the symbol plus addend. */
|
||||
valueT value = S_GET_SIZE (fixp->fx_addsy);
|
||||
valueT value = S_GET_SIZE (sym);
|
||||
|
||||
if (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_SECTION_SYM)
|
||||
value = bfd_section_size (S_GET_SEGMENT (fixp->fx_addsy));
|
||||
if (symbol_get_bfdsym (sym)->flags & BSF_SECTION_SYM)
|
||||
value = bfd_section_size (S_GET_SEGMENT (sym));
|
||||
if (sym == fixp->fx_subsy)
|
||||
{
|
||||
value = -value;
|
||||
if (fixp->fx_addsy)
|
||||
value += S_GET_VALUE (fixp->fx_addsy);
|
||||
}
|
||||
else if (fixp->fx_subsy)
|
||||
value -= S_GET_VALUE (fixp->fx_subsy);
|
||||
value += fixp->fx_offset;
|
||||
if (fixp->fx_r_type == BFD_RELOC_SIZE32
|
||||
&& object_64bit
|
||||
@ -14256,6 +14286,12 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
|
||||
md_apply_fix (fixp, (valueT *) &value, NULL);
|
||||
return NULL;
|
||||
}
|
||||
if (!fixp->fx_addsy || fixp->fx_subsy)
|
||||
{
|
||||
as_bad_where (fixp->fx_file, fixp->fx_line,
|
||||
"unsupported expression involving @size");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
/* Fall through. */
|
||||
|
||||
|
@ -143,8 +143,10 @@ extern int x86_address_bytes (void);
|
||||
|
||||
#define NO_RELOC BFD_RELOC_NONE
|
||||
|
||||
void i386_validate_fix (struct fix *);
|
||||
#define TC_VALIDATE_FIX(FIX,SEGTYPE,SKIP) i386_validate_fix(FIX)
|
||||
int i386_validate_fix (struct fix *);
|
||||
#define TC_VALIDATE_FIX(FIX,SEGTYPE,SKIP) do { \
|
||||
if (!i386_validate_fix(FIX)) goto SKIP; \
|
||||
} while (0)
|
||||
|
||||
#define tc_fix_adjustable(X) tc_i386_fix_adjustable(X)
|
||||
extern int tc_i386_fix_adjustable (struct fix *);
|
||||
|
@ -637,6 +637,8 @@ if [gas_32_check] then {
|
||||
run_dump_test "size-2"
|
||||
run_dump_test "size-3"
|
||||
run_dump_test "size-4"
|
||||
run_dump_test "size-5a"
|
||||
run_dump_test "size-5b"
|
||||
|
||||
run_dump_test "note"
|
||||
|
||||
|
32
gas/testsuite/gas/i386/size-5.s
Normal file
32
gas/testsuite/gas/i386/size-5.s
Normal file
@ -0,0 +1,32 @@
|
||||
.text
|
||||
size:
|
||||
mov $size@size, %eax
|
||||
mov $size@size + val, %eax
|
||||
mov $-size@size, %ecx
|
||||
mov $0 - size@size, %ecx
|
||||
mov $0x100 - size@size, %edx
|
||||
mov $val - size@size, %edx
|
||||
|
||||
lea size@size, %eax
|
||||
lea size@size + val, %eax
|
||||
lea -size@size, %ecx
|
||||
lea 0 - size@size, %ecx
|
||||
lea 0x100 - size@size, %edx
|
||||
lea val - size@size, %edx
|
||||
|
||||
ret
|
||||
.size size, . - size
|
||||
|
||||
.data
|
||||
.p2align 2
|
||||
.long size@size
|
||||
.long size@size + val
|
||||
.long -size@size
|
||||
.long 0 - size@size
|
||||
.long 0x100 - size@size
|
||||
.long val - size@size
|
||||
|
||||
.long ext@size
|
||||
.long ext@size + val
|
||||
|
||||
.equ val, 0x1000
|
28
gas/testsuite/gas/i386/size-5a.d
Normal file
28
gas/testsuite/gas/i386/size-5a.d
Normal file
@ -0,0 +1,28 @@
|
||||
#name: i386 size 5 (text)
|
||||
#source: size-5.s
|
||||
#objdump: -dtwr
|
||||
|
||||
.*: +file format .*
|
||||
|
||||
SYMBOL TABLE:
|
||||
0*0 l +\.text 0*43 size
|
||||
0*1000 l +\*ABS\* 0*0 val
|
||||
0*0 +\*UND\* 0*0 ext
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0+ <size>:
|
||||
[ ]*[a-f0-9]+: b8 43 00 00 00 mov \$0x43,%eax
|
||||
[ ]*[a-f0-9]+: b8 43 10 00 00 mov \$0x1043,%eax
|
||||
[ ]*[a-f0-9]+: b9 bd ff ff ff mov \$0xffffffbd,%ecx
|
||||
[ ]*[a-f0-9]+: b9 bd ff ff ff mov \$0xffffffbd,%ecx
|
||||
[ ]*[a-f0-9]+: ba bd 00 00 00 mov \$0xbd,%edx
|
||||
[ ]*[a-f0-9]+: ba bd 0f 00 00 mov \$0xfbd,%edx
|
||||
[ ]*[a-f0-9]+: 8d 05 43 00 00 00 lea 0x43,%eax
|
||||
[ ]*[a-f0-9]+: 8d 05 43 10 00 00 lea 0x1043,%eax
|
||||
[ ]*[a-f0-9]+: 8d 0d bd ff ff ff lea 0xffffffbd,%ecx
|
||||
[ ]*[a-f0-9]+: 8d 0d bd ff ff ff lea 0xffffffbd,%ecx
|
||||
[ ]*[a-f0-9]+: 8d 15 bd 00 00 00 lea 0xbd,%edx
|
||||
[ ]*[a-f0-9]+: 8d 15 bd 0f 00 00 lea 0xfbd,%edx
|
||||
[ ]*[a-f0-9]+: c3 ret *
|
||||
#pass
|
15
gas/testsuite/gas/i386/size-5b.d
Normal file
15
gas/testsuite/gas/i386/size-5b.d
Normal file
@ -0,0 +1,15 @@
|
||||
#name: i386 size 5 (data)
|
||||
#source: size-5.s
|
||||
#objdump: -rsj .data
|
||||
|
||||
.*: +file format .*
|
||||
|
||||
RELOCATION RECORDS FOR \[\.data\]:
|
||||
|
||||
OFFSET +TYPE +VALUE *
|
||||
0*18 R_386_SIZE32 *ext
|
||||
0*1c R_386_SIZE32 *ext
|
||||
|
||||
Contents of section .data:
|
||||
0+00 43 ?00 ?00 ?00 43 ?10 ?00 ?00 bd ?ff ?ff ?ff bd ?ff ?ff ?ff .*
|
||||
0+10 bd ?00 ?00 ?00 bd ?0f ?00 ?00 00 ?00 ?00 ?00 00 ?10 ?00 ?00 .*
|
Reference in New Issue
Block a user