+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
}
}
-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)
}
}
#endif
+
+ return 1;
}
arelent *
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
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. */
#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 *);
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"
--- /dev/null
+ .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
--- /dev/null
+#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
--- /dev/null
+#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 .*