@@ -6178,6 +6178,12 @@ enum bfd_reloc_code_real
for virtually every function. */
BFD_RELOC_XTENSA_PDIFF_ULEB128,
+ /* Xtensa 32-bit absolute address, computed as S + A with the addend taken
+ only from the r_addend field. Unlike R_XTENSA_32, to which BFD_RELOC_32
+ maps and which is partial_inplace, the contents of the relocated word do
+ not contribute to the result. */
+ BFD_RELOC_XTENSA_32_ABS,
+
/* 8 bit signed offset in (ix+d) or (iy+d). */
BFD_RELOC_Z80_DISP8,
@@ -348,6 +348,13 @@ static reloc_howto_type elf_howto_table[] =
bfd_elf_xtensa_reloc, "R_XTENSA_NDIFF32", false, 0, 0xffffffff, false),
HOWTO (R_XTENSA_PDIFF_ULEB128, 0, 0, 0, false, 0, complain_overflow_dont,
bfd_elf_xtensa_reloc, "R_XTENSA_PDIFF_ULEB128", false, 0, 0, false),
+
+ /* Absolute 32-bit address with the addend taken only from r_addend.
+ Unlike R_XTENSA_32 this is not partial_inplace, so the contents of
+ the relocated word do not contribute to the result. */
+ HOWTO (R_XTENSA_32_ABS, 0, 4, 32, false, 0, complain_overflow_bitfield,
+ bfd_elf_xtensa_reloc, "R_XTENSA_32_ABS",
+ false, 0, 0xffffffff, false),
};
#if DEBUG_GEN_RELOC
@@ -415,6 +422,10 @@ elf_xtensa_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
TRACE ("BFD_RELOC_XTENSA_PDIFF_ULEB128");
return &elf_howto_table[(unsigned) R_XTENSA_PDIFF_ULEB128 ];
+ case BFD_RELOC_XTENSA_32_ABS:
+ TRACE ("BFD_RELOC_XTENSA_32_ABS");
+ return &elf_howto_table[(unsigned) R_XTENSA_32_ABS ];
+
case BFD_RELOC_XTENSA_RTLD:
TRACE ("BFD_RELOC_XTENSA_RTLD");
return &elf_howto_table[(unsigned) R_XTENSA_RTLD ];
@@ -854,6 +865,23 @@ property_table_matches (const void *ap, const void *bp)
}
+/* Addend of relocation IREL. R_XTENSA_32 is the only partial_inplace
+ relocation, so only for it does the relocated word in CONTENTS
+ contribute. Other relocations, such as R_XTENSA_32_ABS, take the
+ addend from r_addend alone. */
+
+static bfd_vma
+xtensa_reloc_addend (bfd *abfd, bfd_byte *contents,
+ const Elf_Internal_Rela *irel)
+{
+ bfd_vma addend = irel->r_addend;
+
+ if (ELF32_R_TYPE (irel->r_info) == R_XTENSA_32)
+ addend += bfd_get_32 (abfd, contents + irel->r_offset);
+ return addend;
+}
+
+
/* Get the literal table or property table entries for the given
section. Sets TABLE_P and returns the number of entries. On
error, returns a negative value. */
@@ -952,14 +980,16 @@ xtensa_read_table_entries (bfd *abfd,
{
bfd_vma sym_off;
unsigned long r_symndx = ELF32_R_SYM (irel->r_info);
- BFD_ASSERT (ELF32_R_TYPE (irel->r_info) == R_XTENSA_32);
+ BFD_ASSERT (ELF32_R_TYPE (irel->r_info) == R_XTENSA_32
+ || ELF32_R_TYPE (irel->r_info) == R_XTENSA_32_ABS);
if (get_elf_r_symndx_section (abfd, r_symndx) != section)
continue;
sym_off = get_elf_r_symndx_offset (abfd, r_symndx);
BFD_ASSERT (sym_off == 0);
- address += (section_addr + sym_off + irel->r_addend);
+ address = (section_addr + sym_off
+ + xtensa_reloc_addend (abfd, table_data, irel));
}
else
{
@@ -1148,6 +1178,7 @@ elf_xtensa_check_relocs (bfd *abfd,
break;
case R_XTENSA_32:
+ case R_XTENSA_32_ABS:
tls_type = GOT_NORMAL;
is_got = true;
break;
@@ -1951,6 +1982,7 @@ elf_xtensa_do_reloc (reloc_howto_type *howto,
bfd_put_32 (abfd, relocation - self_address, contents + address);
return bfd_reloc_ok;
+ case R_XTENSA_32_ABS:
case R_XTENSA_PLT:
case R_XTENSA_TLSDESC_FN:
case R_XTENSA_TLSDESC_ARG:
@@ -2783,6 +2815,7 @@ elf_xtensa_relocate_section (struct bfd_link_info *info,
switch (r_type)
{
case R_XTENSA_32:
+ case R_XTENSA_32_ABS:
case R_XTENSA_PLT:
if (elf_hash_table (info)->dynamic_sections_created
&& (input_section->flags & SEC_ALLOC) != 0
@@ -2828,7 +2861,7 @@ elf_xtensa_relocate_section (struct bfd_link_info *info,
outrel.r_addend = rel->r_addend;
rel->r_addend = 0;
- if (r_type == R_XTENSA_32)
+ if (r_type == R_XTENSA_32 || r_type == R_XTENSA_32_ABS)
{
outrel.r_info =
ELF32_R_INFO (h->dynindx, R_XTENSA_GLOB_DAT);
@@ -5202,6 +5235,19 @@ init_literal_value (literal_value *lit,
}
+/* R_XTENSA_32 and R_XTENSA_32_ABS literals with the same target_offset hold
+ the same address, because r_reloc_init folds the in-place addend of
+ R_XTENSA_32 into target_offset. */
+
+static unsigned
+literal_reloc_type (const r_reloc *r_rel)
+{
+ unsigned r_type = ELF32_R_TYPE (r_rel->rela.r_info);
+
+ return r_type == R_XTENSA_32_ABS ? R_XTENSA_32 : r_type;
+}
+
+
static bool
literal_value_equal (const literal_value *src1,
const literal_value *src2,
@@ -5215,8 +5261,7 @@ literal_value_equal (const literal_value *src1,
if (r_reloc_is_const (&src1->r_rel))
return (src1->value == src2->value);
- if (ELF32_R_TYPE (src1->r_rel.rela.r_info)
- != ELF32_R_TYPE (src2->r_rel.rela.r_info))
+ if (literal_reloc_type (&src1->r_rel) != literal_reloc_type (&src2->r_rel))
return false;
if (src1->r_rel.target_offset != src2->r_rel.target_offset)
@@ -8847,10 +8892,11 @@ compute_removed_literals (bfd *abfd,
irel = get_irel_at_offset (sec, internal_relocs,
rel->r_rel.target_offset);
- /* If the relocation on this is not a simple R_XTENSA_32 or
- R_XTENSA_PLT then do not consider it. This may happen when
- the difference of two symbols is used in a literal. */
+ /* If the relocation on this is not a simple R_XTENSA_32,
+ R_XTENSA_32_ABS or R_XTENSA_PLT then do not consider it. This may
+ happen when the difference of two symbols is used in a literal. */
if (irel && (ELF32_R_TYPE (irel->r_info) != R_XTENSA_32
+ && ELF32_R_TYPE (irel->r_info) != R_XTENSA_32_ABS
&& ELF32_R_TYPE (irel->r_info) != R_XTENSA_PLT))
continue;
@@ -10321,7 +10367,8 @@ shrink_dynamic_reloc_sections (struct bfd_link_info *info,
dynamic_symbol = elf_xtensa_dynamic_symbol_p (h, info);
- if ((r_type == R_XTENSA_32 || r_type == R_XTENSA_PLT)
+ if ((r_type == R_XTENSA_32 || r_type == R_XTENSA_32_ABS
+ || r_type == R_XTENSA_PLT)
&& (input_section->flags & SEC_ALLOC) != 0
&& (dynamic_symbol
|| (bfd_link_pic (info)
@@ -10787,19 +10834,18 @@ relax_property_section (bfd *abfd,
remove_this_rel = true;
}
else if (offset_rel
- && ELF32_R_TYPE (offset_rel->r_info) == R_XTENSA_32)
+ && (ELF32_R_TYPE (offset_rel->r_info) == R_XTENSA_32
+ || ELF32_R_TYPE (offset_rel->r_info) == R_XTENSA_32_ABS))
{
if (last_irel)
{
flagword old_flags;
bfd_vma old_size =
bfd_get_32 (abfd, &contents[last_irel->r_offset + 4]);
- bfd_vma old_address =
- (last_irel->r_addend
- + bfd_get_32 (abfd, &contents[last_irel->r_offset]));
- bfd_vma new_address =
- (offset_rel->r_addend
- + bfd_get_32 (abfd, &contents[actual_offset]));
+ bfd_vma old_address = xtensa_reloc_addend (abfd, contents,
+ last_irel);
+ bfd_vma new_address = xtensa_reloc_addend (abfd, contents,
+ offset_rel);
if (is_full_prop_section)
old_flags = bfd_get_32
(abfd, &contents[last_irel->r_offset + 8]);
@@ -2797,6 +2797,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_XTENSA_NDIFF16",
"BFD_RELOC_XTENSA_NDIFF32",
"BFD_RELOC_XTENSA_PDIFF_ULEB128",
+ "BFD_RELOC_XTENSA_32_ABS",
"BFD_RELOC_Z80_DISP8",
"BFD_RELOC_Z80_BYTE0",
"BFD_RELOC_Z80_BYTE1",
@@ -6043,6 +6043,14 @@ ENUMDOC
by such a difference, which DWARF 5 location and range lists produce
for virtually every function.
+ENUM
+ BFD_RELOC_XTENSA_32_ABS
+ENUMDOC
+ Xtensa 32-bit absolute address, computed as S + A with the addend taken
+ only from the r_addend field. Unlike R_XTENSA_32, to which BFD_RELOC_32
+ maps and which is partial_inplace, the contents of the relocated word do
+ not contribute to the result.
+
ENUM
BFD_RELOC_Z80_DISP8
ENUMDOC
@@ -15700,7 +15700,8 @@ is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
return reloc_type == 1; /* R_XSTROMY16_32. */
case EM_XTENSA_OLD:
case EM_XTENSA:
- return reloc_type == 1; /* R_XTENSA_32. */
+ /* R_XTENSA_32 or R_XTENSA_32_ABS. */
+ return reloc_type == 1 || reloc_type == 64;
case EM_Z80:
return reloc_type == 6; /* R_Z80_32. */
default:
@@ -57,6 +57,10 @@
/* Define default value for RISC-V -mpriv-spec */
#undef DEFAULT_RISCV_PRIV_SPEC
+/* Define to 1 if you want to emit R_XTENSA_32_ABS for 32-bit absolute data
+ by default. */
+#undef DEFAULT_R_XTENSA_32_ABS
+
/* Define to 1 if you want to emit SFrames by default. */
#undef DEFAULT_SFRAME
@@ -494,6 +494,10 @@ static fixS *xg_append_jump (fragS *fragP, symbolS *sym, offsetT offset);
static void xtensa_maybe_create_literal_pool_frag (bool, bool);
static bool auto_litpools = false;
static int auto_litpool_limit = 0;
+/* Loaders of relocatable objects, such as kernel module loaders, may only
+ know R_XTENSA_32, so R_XTENSA_32_ABS is the default only when configured
+ with --enable-r-xtensa-32-abs. */
+static bool use_abs32_rela = DEFAULT_R_XTENSA_32_ABS;
static bool xtensa_is_init_fini (segT seg);
/* Alignment Functions. */
@@ -733,6 +737,9 @@ enum
option_abi_windowed,
option_abi_call0,
+
+ option_abs32_rela,
+ option_no_abs32_rela,
};
const char md_shortopts[] = "";
@@ -817,6 +824,9 @@ const struct option md_longopts[] =
{ "abi-windowed", no_argument, NULL, option_abi_windowed },
{ "abi-call0", no_argument, NULL, option_abi_call0 },
+ { "abs32-rela", no_argument, NULL, option_abs32_rela },
+ { "no-abs32-rela", no_argument, NULL, option_no_abs32_rela },
+
{ NULL, no_argument, NULL, 0 }
};
@@ -1052,6 +1062,14 @@ md_parse_option (int c, const char *arg)
elf32xtensa_abi = XTHAL_ABI_CALL0;
return 1;
+ case option_abs32_rela:
+ use_abs32_rela = true;
+ return 1;
+
+ case option_no_abs32_rela:
+ use_abs32_rela = false;
+ return 1;
+
default:
return 0;
}
@@ -1086,7 +1104,12 @@ Xtensa options:\n\
--[no-]separate-prop-tables\n\
[Do not] place Xtensa property records into\n\
individual property sections for each section.\n\
- Default is to generate single property section.\n", stream);
+ Default is to generate single property section.\n\
+ --[no-]abs32-rela [Do not] emit R_XTENSA_32_ABS rather than\n\
+ R_XTENSA_32 for 32-bit absolute data.\n", stream);
+ fprintf (stream, "\
+ Default is %s.\n",
+ DEFAULT_R_XTENSA_32_ABS ? "R_XTENSA_32_ABS" : "R_XTENSA_32");
}
@@ -6160,6 +6183,7 @@ arelent *
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
{
arelent *reloc;
+ bfd_reloc_code_real_type r_type;
reloc = notes_alloc (sizeof (arelent));
reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
@@ -6172,18 +6196,22 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
reloc->addend = fixp->fx_offset;
- reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
+ r_type = fixp->fx_r_type;
+ if (r_type == BFD_RELOC_32 && use_abs32_rela)
+ r_type = BFD_RELOC_XTENSA_32_ABS;
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, r_type);
if (reloc->howto == NULL)
{
as_bad_where (fixp->fx_file, fixp->fx_line,
_("cannot represent `%s' relocation in object file"),
- bfd_get_reloc_code_name (fixp->fx_r_type));
+ bfd_get_reloc_code_name (r_type));
return NULL;
}
if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
as_fatal (_("internal error; cannot generate `%s' relocation"),
- bfd_get_reloc_code_name (fixp->fx_r_type));
+ bfd_get_reloc_code_name (r_type));
return reloc;
}
@@ -826,6 +826,7 @@ enable_generate_build_notes
enable_mips_fix_loongson3_llsc
enable_x86_used_note
enable_default_riscv_attribute
+enable_r_xtensa_32_abs
enable_werror
enable_build_warnings
with_cpu
@@ -1507,6 +1508,9 @@ Optional Features:
--enable-x86-used-note generate GNU x86 used ISA and feature properties
--enable-default-riscv-attribute
generate RISC-V arch attribute by default
+ --enable-r-xtensa-32-abs
+ emit R_XTENSA_32_ABS for 32-bit absolute data by
+ default
--enable-werror treat compile warnings as errors
--enable-build-warnings enable build-time compiler warnings
--disable-nls do not use Native Language Support
@@ -11152,7 +11156,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11155 "configure"
+#line 11159 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11258,7 +11262,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11261 "configure"
+#line 11265 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12034,6 +12038,18 @@ if test "${enable_default_riscv_attribute+set}" = set; then :
esac
fi
+# Decide if the Xtensa assembler should default to emitting R_XTENSA_32_ABS
+# rather than R_XTENSA_32 for 32-bit absolute data.
+ac_default_r_xtensa_32_abs=unset
+# Provide a configuration option to override the default.
+# Check whether --enable-r-xtensa-32-abs was given.
+if test "${enable_r_xtensa_32_abs+set}" = set; then :
+ enableval=$enable_r_xtensa_32_abs; case "${enableval}" in
+ yes) ac_default_r_xtensa_32_abs=1 ;;
+ no) ac_default_r_xtensa_32_abs=0 ;;
+esac
+fi
+
using_cgen=no
@@ -13127,6 +13143,15 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+if test ${ac_default_r_xtensa_32_abs} = unset; then
+ ac_default_r_xtensa_32_abs=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_R_XTENSA_32_ABS $ac_default_r_xtensa_32_abs
+_ACEOF
+
+
if test ${ac_default_mips_fix_loongson3_llsc} = unset; then
ac_default_mips_fix_loongson3_llsc=0
fi
@@ -172,6 +172,18 @@ AC_ARG_ENABLE(default-riscv-attribute,
no) ac_default_generate_riscv_attr=0 ;;
esac])dnl
+# Decide if the Xtensa assembler should default to emitting R_XTENSA_32_ABS
+# rather than R_XTENSA_32 for 32-bit absolute data.
+ac_default_r_xtensa_32_abs=unset
+# Provide a configuration option to override the default.
+AC_ARG_ENABLE(r-xtensa-32-abs,
+ AS_HELP_STRING([--enable-r-xtensa-32-abs],
+ [emit R_XTENSA_32_ABS for 32-bit absolute data by default]),
+[case "${enableval}" in
+ yes) ac_default_r_xtensa_32_abs=1 ;;
+ no) ac_default_r_xtensa_32_abs=0 ;;
+esac])dnl
+
using_cgen=no
AM_BINUTILS_WARNINGS
@@ -778,6 +790,14 @@ AC_DEFINE_UNQUOTED(DEFAULT_RISCV_ATTR,
$ac_default_generate_riscv_attr,
[Define to 1 if you want to generate RISC-V arch attribute by default.])
+if test ${ac_default_r_xtensa_32_abs} = unset; then
+ ac_default_r_xtensa_32_abs=0
+fi
+AC_DEFINE_UNQUOTED(DEFAULT_R_XTENSA_32_ABS,
+ $ac_default_r_xtensa_32_abs,
+ [Define to 1 if you want to emit R_XTENSA_32_ABS for 32-bit absolute data
+ by default.])
+
if test ${ac_default_mips_fix_loongson3_llsc} = unset; then
ac_default_mips_fix_loongson3_llsc=0
fi
@@ -651,6 +651,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
[@b{--rename-section} @var{oldname}=@var{newname}]
[@b{--[no-]trampolines}]
[@b{--abi-windowed}|@b{--abi-call0}]
+ [@b{--[no-]abs32-rela}]
@end ifset
@ifset Z80
@@ -130,6 +130,17 @@ Choose ABI tag written to the @code{.xtensa.info} section. ABI tag
indicates ABI of the assembly code. A warning is issued by the linker
on an attempt to link object files with inconsistent ABI tags.
Default ABI is chosen by the Xtensa core configuration.
+
+@item --abs32-rela | --no-abs32-rela
+@kindex --abs32-rela
+@kindex --no-abs32-rela
+Choose the relocation emitted for 32-bit absolute data.
+@samp{--abs32-rela} emits @code{R_XTENSA_32_ABS}, which keeps the whole
+addend in the relocation and is the form produced by LLVM.
+@samp{--no-abs32-rela} emits @code{R_XTENSA_32}, which may also keep the
+addend in the relocated word and is understood by older linkers and by
+loaders of relocatable objects. The default is @samp{--no-abs32-rela},
+unless the assembler was configured with @samp{--enable-r-xtensa-32-abs}.
@end table
@c man end
@@ -11,7 +11,7 @@
RELOCATION RECORDS FOR \[.xt.prop\]:
OFFSET +TYPE +VALUE
-0+ R_XTENSA_32 +.text.*
+0+ R_XTENSA_32(_ABS)? +.text.*
Contents of section .debug_info:
0000 c801.*
new file mode 100644
@@ -0,0 +1,20 @@
+#as: --no-abs32-rela
+#source: reloc-abs32.s
+#objdump: -r -s -j .rodata
+#name: 32-bit absolute relocations with --no-abs32-rela
+
+# R_XTENSA_32 is partial_inplace, so the addends of references to the
+# section symbol are held in the relocated words. Both byte orders are
+# accepted.
+
+.*: +file format .*xtensa.*
+
+RELOCATION RECORDS FOR \[\.rodata\]:
+OFFSET +TYPE +VALUE
+0+00 R_XTENSA_32 +\.text
+0+04 R_XTENSA_32 +\.text
+0+08 R_XTENSA_32 +gsym
+0+0c R_XTENSA_32 +gsym\+0x0+8
+
+Contents of section \.rodata:
+ 0000 (00000002 00000012|02000000 12000000) 00000000 00000000 .*
new file mode 100644
@@ -0,0 +1,18 @@
+#as: --abs32-rela
+#objdump: -r -s -j .rodata
+#name: 32-bit absolute relocations with --abs32-rela
+
+# R_XTENSA_32_ABS keeps the addend in r_addend and leaves the relocated word
+# zero.
+
+.*: +file format .*xtensa.*
+
+RELOCATION RECORDS FOR \[\.rodata\]:
+OFFSET +TYPE +VALUE
+0+00 R_XTENSA_32_ABS +\.text\+0x0+2
+0+04 R_XTENSA_32_ABS +\.text\+0x0+12
+0+08 R_XTENSA_32_ABS +gsym
+0+0c R_XTENSA_32_ABS +gsym\+0x0+8
+
+Contents of section \.rodata:
+ 0000 00000000 00000000 00000000 00000000 .*
new file mode 100644
@@ -0,0 +1,13 @@
+ .text
+ .global gsym
+ .skip 2
+lsym:
+ .skip 2
+gsym:
+ .skip 2
+
+ .section .rodata
+ .word lsym
+ .word lsym + 16
+ .word gsym
+ .word gsym + 8
new file mode 100644
@@ -0,0 +1,15 @@
+ .text
+ .global _start
+ .global target
+_start:
+ .skip 2
+target:
+ .skip 2
+
+ # Relocations as LLVM emits them: R_XTENSA_32_ABS with the addend in
+ # r_addend and a zero relocated word.
+ .section .rodata
+ .reloc ., R_XTENSA_32_ABS, target
+ .word 0
+ .reloc ., R_XTENSA_32_ABS, target + 8
+ .word 0
new file mode 100644
@@ -0,0 +1,6 @@
+ # GNU as emits R_XTENSA_32, which is partial_inplace, so the addend
+ # may be held in the relocated word rather than in r_addend.
+ .section .rodata
+legacy:
+ .word 8
+ .reloc legacy, R_XTENSA_32, target
new file mode 100644
@@ -0,0 +1,11 @@
+ # A local label is referenced through the section symbol, so a
+ # relocatable link must rebase the addend by the output offset of
+ # this .text and keep the result in r_addend.
+ .text
+ .skip 4
+.Llocal:
+ .skip 4
+
+ .section .rodata
+ .reloc ., R_XTENSA_32_ABS, .Llocal + 4
+ .word 0
new file mode 100644
@@ -0,0 +1,23 @@
+#source: reloc-abs32-1.s
+#source: reloc-abs32-2.s
+#source: reloc-abs32-3.s
+#ld: -r
+#objdump: -r -s -j .rodata
+#name: 32-bit absolute relocations, relocatable link
+
+# R_XTENSA_32_ABS keeps its addend in r_addend and leaves the relocated word
+# zero, including the reference to .text whose addend is rebased by the 4
+# bytes of .text that precede it. The partial_inplace R_XTENSA_32 keeps its
+# addend of 8 in the relocated word. Both byte orders are accepted.
+
+.*: +file format .*xtensa.*
+
+RELOCATION RECORDS FOR \[\.rodata\]:
+OFFSET +TYPE +VALUE
+0+00 R_XTENSA_32_ABS +target
+0+04 R_XTENSA_32_ABS +target\+0x0+8
+0+08 R_XTENSA_32 +target
+0+0c R_XTENSA_32_ABS +\.text\+0x0+c
+
+Contents of section \.rodata:
+ 0000 00000000 00000000 (00000008|08000000) 00000000 .*
new file mode 100644
@@ -0,0 +1,16 @@
+#source: reloc-abs32-1.s
+#source: reloc-abs32-2.s
+#source: reloc-abs32-3.s
+#ld: -T reloc-abs32.t
+#objdump: -s -j .rodata
+#name: 32-bit absolute relocations
+
+# target is at 0x1002 and local at 0x1008. The first two words and the
+# last one use R_XTENSA_32_ABS and take their addends from r_addend; the
+# third uses the partial_inplace R_XTENSA_32 and takes its addend of 8 from
+# the relocated word. Both byte orders are accepted.
+
+.*: +file format .*xtensa.*
+
+Contents of section \.rodata:
+ 100c (00001002 0000100a 0000100a 0000100c|02100000 0a100000 0a100000 0c100000).*
new file mode 100644
@@ -0,0 +1,5 @@
+SECTIONS
+{
+ .text 0x00001000 : { *(.literal .text) }
+ .rodata : { *(.rodata) }
+}
new file mode 100644
@@ -0,0 +1,18 @@
+ .global foo
+ .data
+ .global g_name
+ .align 4
+g_name:
+.Lg_name:
+ .word 0xffffffff
+ .text
+ .global main
+ .align 4
+main:
+ entry a5,16
+ movi a5,20000
+ # Through the section symbol, so R_XTENSA_32 holds the addend in the
+ # literal word.
+ movi a6,.Lg_name+4
+ call8 foo
+ ret
new file mode 100644
@@ -0,0 +1,14 @@
+ # A literal as LLVM emits it: R_XTENSA_32_ABS with the addend in
+ # r_addend and a zero literal word.
+ .text
+ .global foo
+ .global g_name
+ .align 4
+ .literal .Lg_name, 0
+ .reloc .Lg_name, R_XTENSA_32_ABS, g_name + 4
+foo:
+ entry a5,16
+ movi a5,20000
+ l32r a6,.Lg_name
+ movi a7,50000
+ ret
new file mode 100644
@@ -0,0 +1,21 @@
+#source: reloc-coalesce-abs32-1.s
+#source: reloc-coalesce-abs32-2.s
+#as: --no-abs32-rela
+#ld: -T coalesce.t
+#objdump: -d
+#name: coalesce R_XTENSA_32 and R_XTENSA_32_ABS literals
+
+# Both objects load g_name + 4, one through R_XTENSA_32 with the addend in
+# the literal word and one through R_XTENSA_32_ABS with the addend in
+# r_addend. The two literals must be coalesced, leaving three literals
+# before main, and both loads must still see g_name + 4.
+
+#...
+0000000c <main>:
+#...
+ +[0-9a-f]+: [0-9a-f]+ + l32r a6, 4 <main-0x8> \([0-9a-f]+ <g_name\+0x4>\)
+#...
+[0-9a-f]+ <foo>:
+#...
+ +[0-9a-f]+: [0-9a-f]+ + l32r a6, 4 <main-0x8> \([0-9a-f]+ <g_name\+0x4>\)
+#pass
new file mode 100644
@@ -0,0 +1,13 @@
+#source: reloc-prop-abs32.s
+#ld: -T reloc-prop-abs32.t
+#objdump: -s -j .xt.prop
+#name: R_XTENSA_32_ABS property merge ignores relocated word
+
+# The addends alone place the ranges at .text+0 and .text+4, so they are
+# adjacent and must merge into one entry of size 8 at 0x1000. Both byte
+# orders are accepted.
+
+.*: +file format .*xtensa.*
+
+Contents of section \.xt\.prop:
+ 1008 (00001000 00000008 00000002|00100000 08000000 02000000).*
new file mode 100644
@@ -0,0 +1,19 @@
+ # Two adjacent instruction ranges. R_XTENSA_32_ABS keeps the address in
+ # r_addend; the relocated words are non-zero and must not be added.
+ # Adding them makes the ranges non-adjacent, so the linker will not
+ # merge the entries.
+ .section .xt.prop
+ .reloc ., R_XTENSA_32_ABS, .text
+ .word 0x10
+ .word 4
+ .word 2 # XTENSA_PROP_INSN
+
+ .reloc ., R_XTENSA_32_ABS, .text + 4
+ .word 0x20
+ .word 4
+ .word 2 # XTENSA_PROP_INSN
+
+ .text
+ .global _start
+_start:
+ .skip 8
new file mode 100644
@@ -0,0 +1,5 @@
+SECTIONS
+{
+ .text 0x1000 : { *(.text) }
+ .xt.prop : { *(.xt.prop) }
+}
@@ -44,4 +44,9 @@ run_dump_test "relax-undef-weak-local-pie"
run_dump_test "relax-undef-weak-shared"
run_dump_test "relax-undef-weak-local-shared"
+run_dump_test "reloc-abs32"
+run_dump_test "reloc-abs32-r"
+run_dump_test "reloc-coalesce-abs32"
+run_dump_test "reloc-prop-abs32"
+
run_dump_test "startstop"